[trends] Add time periods
This commit is contained in:
80
vrobbler/apps/trends/utils.py
Normal file
80
vrobbler/apps/trends/utils.py
Normal file
@ -0,0 +1,80 @@
|
||||
import logging
|
||||
from datetime import timedelta
|
||||
|
||||
from django.utils import timezone
|
||||
from trends.models import PERIOD_CHOICES, TrendResult
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
PERIOD_DAYS = {
|
||||
"last_30": 30,
|
||||
"last_90": 90,
|
||||
"last_year": 365,
|
||||
"all_time": None,
|
||||
}
|
||||
|
||||
PERIOD_LABELS = dict(PERIOD_CHOICES)
|
||||
|
||||
TIME_BOUND_TRENDS = {
|
||||
"activity-distribution",
|
||||
"concurrent-reading",
|
||||
"concurrent-listening",
|
||||
"reading-pace-vs-activity",
|
||||
"trending-up",
|
||||
}
|
||||
|
||||
TREND_PERIOD_OVERRIDES = {
|
||||
"trending-up": ["last_30", "last_90", "last_year"],
|
||||
}
|
||||
|
||||
|
||||
def get_supported_periods(trend_slug):
|
||||
if trend_slug in TREND_PERIOD_OVERRIDES:
|
||||
slugs = TREND_PERIOD_OVERRIDES[trend_slug]
|
||||
return {s: PERIOD_LABELS[s] for s in slugs}
|
||||
if trend_slug in TIME_BOUND_TRENDS:
|
||||
return dict(PERIOD_LABELS)
|
||||
return {"all_time": PERIOD_LABELS["all_time"]}
|
||||
|
||||
|
||||
def get_period_days(period):
|
||||
return PERIOD_DAYS.get(period)
|
||||
|
||||
|
||||
def get_date_range(period):
|
||||
days = get_period_days(period)
|
||||
if days is None:
|
||||
return None, None
|
||||
now = timezone.now()
|
||||
return now - timedelta(days=days), now
|
||||
|
||||
|
||||
def get_period_nav(current_period, trend_slug):
|
||||
supported = get_supported_periods(trend_slug)
|
||||
keys = list(supported.keys())
|
||||
try:
|
||||
idx = keys.index(current_period)
|
||||
except ValueError:
|
||||
return None, None
|
||||
prev_period = keys[idx - 1] if idx > 0 else None
|
||||
next_period = keys[idx + 1] if idx < len(keys) - 1 else None
|
||||
return prev_period, next_period
|
||||
|
||||
|
||||
def compute_and_save_trend(user, slug, period="all_time"):
|
||||
"""Compute a single trend for a given period and persist the result.
|
||||
|
||||
Returns elapsed seconds on success, raises on failure.
|
||||
"""
|
||||
from trends.trends import TREND_REGISTRY
|
||||
|
||||
fn = TREND_REGISTRY[slug]
|
||||
start = timezone.now()
|
||||
data = fn(user, period=period)
|
||||
TrendResult.objects.update_or_create(
|
||||
user=user,
|
||||
trend_slug=slug,
|
||||
period=period,
|
||||
defaults={"data": data, "computed_at": timezone.now()},
|
||||
)
|
||||
return (timezone.now() - start).total_seconds()
|
||||
Reference in New Issue
Block a user