|
|
|
|
@ -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 = [
|
|
|
|
|
|