diff --git a/src/agenda_culturel/views.py b/src/agenda_culturel/views.py index 70878a8..6ab3cd5 100644 --- a/src/agenda_culturel/views.py +++ b/src/agenda_culturel/views.py @@ -2805,117 +2805,6 @@ def view_tag(request, t, past=False): return render(request, "agenda_culturel/tag.html", context) -def statistics(request, pk=None): - if pk is not None: - rimport = RecurrentImport.objects.filter(pk=pk) - source = rimport.values("source").first()["source"] - qs = Event.objects.filter(import_sources__contains=[source]) - else: - rimport = None - qs = Event.objects - - stats = {} - stats_months = {} - first = {} - last = {} - - ev_published = qs.filter( - Q(status=Event.STATUS.PUBLISHED) - & ( - Q(other_versions__isnull=True) - | Q(other_versions__representative=F("pk")) - | Q(other_versions__representative__isnull=True) - ) - ) - - for v in ["start_day", "created_date__date"]: - after = 24 - last[v] = ( - date.today() - if v == "created_date__date" - else date.today() + timedelta(weeks=after) - ) - last[v] = last[v].replace( - day=_calendar.monthrange(last[v].year, last[v].month)[1] - ) - - r = 8 * 30 - if v == "start_day": - r += after * 7 - first[v] = (last[v] - timedelta(days=r)).replace(day=1) - - ev_days = ev_published.annotate(day=F(v)).filter( - Q(day__lte=last[v]) & Q(day__gte=first[v]) - ) - - stats[v] = ev_days.values("day").annotate(total=Count("day")).order_by("day") - - stats_months[v] = ( - ev_days.annotate(month=TruncMonth("day")) - .values("month") - .annotate(total=Count("month")) - .order_by("month") - ) - - nb_by_city = ( - ev_published.annotate(city=F("exact_location__city")) - .filter(city__isnull=False) - .values("city") - .annotate(total=Count("city")) - .order_by("-total") - ) - - limit = datetime.now() + timedelta(days=-30) - - stat_qs = qs.filter(start_day__gte=F("created_date")).annotate( - foresight=ExtractDay(F("start_day") - F("created_date")) - ) - - statsa = stat_qs.filter().aggregate( - minimum=Min("foresight"), - maximum=Max("foresight"), - mean=Avg("foresight"), - median=Median("foresight"), - stdev=StdDev("foresight"), - ) - - statsm = stat_qs.filter(created_date__gte=limit).aggregate( - minimum=Min("foresight"), - maximum=Max("foresight"), - mean=Avg("foresight"), - median=Median("foresight"), - stdev=StdDev("foresight"), - ) - - stats_foresight = [ - [ - _(x), - round(statsa[x], 2) if statsa[x] is not None else "-", - round(statsm[x], 2) if statsm[x] is not None else "-", - ] - for x in statsa - ] - - context = { - "stats_by_startday": stats["start_day"], - "stats_by_creation": stats["created_date__date"], - "stats_months_by_startday": stats_months["start_day"], - "stats_months_by_creation": stats_months["created_date__date"], - "first_by_startday": first["start_day"], - "last_by_startday": last["start_day"], - "first_by_creation": first["created_date__date"], - "last_by_creation": last["created_date__date"], - "nb_by_city": nb_by_city, - "stats_foresight": stats_foresight, - "object": rimport.first() if rimport else None, - } - - if pk is None: - return render(request, "agenda_culturel/statistics.html", context) - else: - return render(request, "agenda_culturel/rimport-statistics.html", context) - - def tag_list(request): tags = Event.get_all_tags() r_tags = [t["tag"] for t in tags] @@ -3081,6 +2970,127 @@ def delete_tag(request, t): ) +######################### +## Statistics +######################### + + +def statistics(request, pk=None): + if pk is not None: + rimport = RecurrentImport.objects.filter(pk=pk) + source = rimport.values("source").first()["source"] + qs = Event.objects.filter(import_sources__contains=[source]) + else: + rimport = None + qs = Event.objects + + stats = {} + stats_months = {} + first = {} + last = {} + + ev_published = qs.filter( + Q(status=Event.STATUS.PUBLISHED) + & ( + Q(other_versions__isnull=True) + | Q(other_versions__representative=F("pk")) + | Q(other_versions__representative__isnull=True) + ) + ) + + for v in ["start_day", "created_date__date"]: + after = 24 + last[v] = ( + date.today() + if v == "created_date__date" + else date.today() + timedelta(weeks=after) + ) + last[v] = last[v].replace( + day=_calendar.monthrange(last[v].year, last[v].month)[1] + ) + + r = 8 * 30 + if v == "start_day": + r += after * 7 + first[v] = (last[v] - timedelta(days=r)).replace(day=1) + + ev_days = ev_published.annotate(day=F(v)).filter( + Q(day__lte=last[v]) & Q(day__gte=first[v]) + ) + + stats[v] = ev_days.values("day").annotate(total=Count("day")).order_by("day") + + stats_months[v] = ( + ev_days.annotate(month=TruncMonth("day")) + .values("month") + .annotate(total=Count("month")) + .order_by("month") + ) + + nb_by_city = ( + ev_published.annotate(city=F("exact_location__city")) + .filter(city__isnull=False) + .values("city") + .annotate(total=Count("city")) + .order_by("-total") + ) + + limit = datetime.now() + timedelta(days=-30) + + stat_qs = qs.filter(start_day__gte=F("created_date")).annotate( + foresight=ExtractDay(F("start_day") - F("created_date")) + ) + + statsa = stat_qs.filter().aggregate( + minimum=Min("foresight"), + maximum=Max("foresight"), + mean=Avg("foresight"), + median=Median("foresight"), + stdev=StdDev("foresight"), + ) + + statsm = stat_qs.filter(created_date__gte=limit).aggregate( + minimum=Min("foresight"), + maximum=Max("foresight"), + mean=Avg("foresight"), + median=Median("foresight"), + stdev=StdDev("foresight"), + ) + + stats_foresight = [ + [ + _(x), + round(statsa[x], 2) if statsa[x] is not None else "-", + round(statsm[x], 2) if statsm[x] is not None else "-", + ] + for x in statsa + ] + + context = { + "stats_by_startday": stats["start_day"], + "stats_by_creation": stats["created_date__date"], + "stats_months_by_startday": stats_months["start_day"], + "stats_months_by_creation": stats_months["created_date__date"], + "first_by_startday": first["start_day"], + "last_by_startday": last["start_day"], + "first_by_creation": first["created_date__date"], + "last_by_creation": last["created_date__date"], + "nb_by_city": nb_by_city, + "stats_foresight": stats_foresight, + "object": rimport.first() if rimport else None, + } + + if pk is None: + return render(request, "agenda_culturel/statistics.html", context) + else: + return render(request, "agenda_culturel/rimport-statistics.html", context) + + +######################### +## Cache Management +######################### + + def clear_cache(request): if request.method == "POST": cache.clear()