Compare commits

..

2 Commits
54.4 ... 54.5

Author SHA1 Message Date
0f1882b21f [release] Bump to version 54.5
All checks were successful
build / test (push) Successful in 2m7s
deploy / build-and-deploy (push) Has been skipped
deploy / test (push) Successful in 1m58s
- Fix bug in generating mood trends
2026-06-17 21:46:21 -04:00
e819a2db0d [trends] Fix bug in mood trend generation 2026-06-17 21:45:45 -04:00
3 changed files with 32 additions and 17 deletions

View File

@ -590,6 +590,12 @@ We should rename `email_scrobble_board_game` to reflect the fact that it's just
a helper method to create board game scrobbles given a json blob. It's
independent of the email flow it was originally creatdd for
* Version 54.5 [1/1]
** DONE Fix bug in generating mood trends :trends:
:PROPERTIES:
:ID: 8e75abfa-8e70-d85b-00a4-a4813bbce879
:END:
* Version 54.4 [2/2]
** DONE [#A] Remove all-time trends :trends:
:PROPERTIES:

View File

@ -1,6 +1,6 @@
[tool.poetry]
name = "vrobbler"
version = "54.4"
version = "54.5"
description = ""
authors = ["Colin Powell <colin@unbl.ink>"]

View File

@ -1,13 +1,10 @@
from collections import Counter, defaultdict
from datetime import timedelta
from django.db.models import Count, Q
from django.db.models.functions import Extract
from django.utils import timezone
from django.db.models import Q
from scrobbles.models import Scrobble
def _mood_scrobbles(user, period="all_time"):
def _mood_scrobbles(user, period="last_30"):
from trends.utils import get_date_range
start, end = get_date_range(period)
@ -19,17 +16,25 @@ def _mood_scrobbles(user, period="all_time"):
return Scrobble.objects.filter(filters).select_related("mood")
def _parse_quality(raw):
try:
return int(raw)
except (TypeError, ValueError):
return None
def _avg_quality(values):
if not values:
nums = [v for v in values if v is not None]
if not nums:
return 0.0
return round(sum(values) / len(values), 2)
return round(sum(nums) / len(nums), 2)
def compute_mood_trajectory(user, period="all_time"):
def compute_mood_trajectory(user, period="last_30"):
scrobbles = _mood_scrobbles(user, period).order_by("timestamp")
by_date = defaultdict(list)
for s in scrobbles:
quality = s.log.get("mood_quality")
quality = _parse_quality(s.log.get("mood_quality"))
if quality is not None:
day_key = s.timestamp.strftime("%Y-%m-%d")
by_date[day_key].append(quality)
@ -48,13 +53,13 @@ def compute_mood_trajectory(user, period="all_time"):
return {"trajectory": trajectory}
def compute_mood_by_time(user, period="all_time"):
def compute_mood_by_time(user, period="last_30"):
scrobbles = _mood_scrobbles(user, period)
by_hour = defaultdict(list)
by_day = defaultdict(list)
for s in scrobbles:
quality = s.log.get("mood_quality")
quality = _parse_quality(s.log.get("mood_quality"))
if quality is not None and s.timestamp:
by_hour[s.timestamp.hour].append(quality)
by_day[s.timestamp.isoweekday()].append(quality)
@ -94,7 +99,7 @@ def compute_mood_by_time(user, period="all_time"):
return {"hours": hours, "days": days}
def compute_mood_distribution(user, period="all_time"):
def compute_mood_distribution(user, period="last_30"):
scrobbles = _mood_scrobbles(user, period)
mood_counts = Counter()
type_counts = Counter()
@ -120,7 +125,7 @@ def compute_mood_distribution(user, period="all_time"):
}
def compute_mood_streaks(user, period="all_time"):
def compute_mood_streaks(user, period="last_30"):
scrobbles = list(
_mood_scrobbles(user, period).order_by("timestamp")
)
@ -169,13 +174,13 @@ def compute_mood_streaks(user, period="all_time"):
return {"streaks": streaks[:10], "current_streak": current_streak}
def compute_mood_weather(user, period="all_time"):
def compute_mood_weather(user, period="last_30"):
scrobbles = _mood_scrobbles(user, period)
by_condition = defaultdict(list)
by_temp_range = defaultdict(list)
for s in scrobbles:
quality = s.log.get("mood_quality")
quality = _parse_quality(s.log.get("mood_quality"))
if quality is None:
continue
desc = s.log.get("weather_description")
@ -183,7 +188,11 @@ def compute_mood_weather(user, period="all_time"):
if desc:
by_condition[desc].append(quality)
if temp is not None:
bucket = f"{(int(temp) // 10) * 10}-{(int(temp) // 10) * 10 + 9}F"
try:
temp_f = float(temp)
except (TypeError, ValueError):
continue
bucket = f"{(int(temp_f) // 10) * 10}-{(int(temp_f) // 10) * 10 + 9}F"
by_temp_range[bucket].append(quality)
conditions = [