From debb3bbee94b661467dea2e5b43d8bc30f3c2996 Mon Sep 17 00:00:00 2001 From: praticamentetilde Date: Tue, 11 Sep 2018 22:50:54 +0200 Subject: [PATCH] Added weekly stats --- counter/static/js/dateformat.js | 55 +++++++++++++++++++++++++++++++++ counter/templates/menu.html | 1 + counter/templates/stats.html | 52 +++++++++++++++++++++++++++++++ counter/urls.py | 1 + counter/views.py | 32 +++++++++++++++++++ 5 files changed, 141 insertions(+) create mode 100644 counter/static/js/dateformat.js create mode 100644 counter/templates/stats.html diff --git a/counter/static/js/dateformat.js b/counter/static/js/dateformat.js new file mode 100644 index 0000000..627e3a9 --- /dev/null +++ b/counter/static/js/dateformat.js @@ -0,0 +1,55 @@ +'use strict'; + +(function(globals) { + var replacements = { + 'd': 'DD', + 'D': 'ddd', + 'j': 'D', + 'l': 'dddd', + 'N': 'E', + 'S': 'o', + 'w': 'e', + 'z': 'DDD', + 'W': 'W', + 'F': 'MMMM', + 'm': 'MM', + 'M': 'MMM', + 'n': 'M', + 't': '', // no equivalent + 'L': '', // no equivalent + 'o': 'YYYY', + 'Y': 'YYYY', + 'y': 'YY', + 'a': 'a', + 'A': 'A', + 'B': '', // no equivalent + 'g': 'h', + 'G': 'H', + 'h': 'hh', + 'H': 'HH', + 'i': 'mm', + 's': 'ss', + 'u': 'SSS', + 'e': 'zz', // deprecated since version 1.6.0 of moment.js + 'I': '', // no equivalent + 'O': '', // no equivalent + 'P': '', // no equivalent + 'T': '', // no equivalent + 'Z': '', // no equivalent + 'c': '', // no equivalent + 'r': '', // no equivalent + 'U': 'X', + }; + + globals.djangoToMomentFmt = function(djangoFormat) { + djangoFormat = djangoFormat.replace(/(\w+)/g, function (f) { + return '[' + f + ']'; + }); + Object.keys(replacements).forEach(function(key) { + djangoFormat = djangoFormat.replace("[" + key + "]", replacements[key]) + }); + return djangoFormat; + }; +}(this)); + + diff --git a/counter/templates/menu.html b/counter/templates/menu.html index c6397c4..2501658 100644 --- a/counter/templates/menu.html +++ b/counter/templates/menu.html @@ -12,6 +12,7 @@ {% if user.is_authenticated %}
  • Counts
  • +
  • Weekly stats
  • {% if user.is_superuser %}
  • Admin
  • diff --git a/counter/templates/stats.html b/counter/templates/stats.html new file mode 100644 index 0000000..0246741 --- /dev/null +++ b/counter/templates/stats.html @@ -0,0 +1,52 @@ +{% extends 'base.html' %} +{% load static %} + +{% block title %}Weekly stats{% endblock %} + +{% block scripts %} + + + + + +{% endblock %} + +{% block content %} +

    Weekly stats

    + +{% endblock %} diff --git a/counter/urls.py b/counter/urls.py index 7cf462d..dc284f8 100644 --- a/counter/urls.py +++ b/counter/urls.py @@ -4,6 +4,7 @@ from . import views urlpatterns = [ path('', views.index, name='index'), + path('stats', views.count_stats, name='stats'), path('count/list', views.arrow_count_list, name='count_list'), path('count/new', login_required(views.NewArrowCount.as_view()), name='count_new'), diff --git a/counter/views.py b/counter/views.py index f22111b..04c5cce 100644 --- a/counter/views.py +++ b/counter/views.py @@ -9,11 +9,43 @@ from django.contrib.auth.decorators import login_required from django.conf import settings from django.core.exceptions import SuspiciousOperation from django.utils.translation import gettext as _ +from django.db.models.functions import Extract, ExtractWeek +from django.db.models import Sum +from datetime import datetime, timedelta, date +import json +from django.core.serializers.json import DjangoJSONEncoder + +# https://stackoverflow.com/questions/5882405 +def tofirstdayinisoweek(year, week): + ret = datetime.strptime('%04d-%02d-1' % (year, week), '%Y-%W-%w') + if date(year, 1, 4).isoweekday() > 4: + ret -= timedelta(days=7) + return ret def index(request): template = loader.get_template('index.html') return HttpResponse(template.render({}, request)) +def count_stats(request): + template = loader.get_template('stats.html') + + # Group counts by week (extract isoyear works only on psql and DB2) + weeklyArrows = ArrowCount.objects \ + .filter(user = request.user) \ + .annotate(isoyear=Extract('date', lookup_name='isoyear')) \ + .annotate(week=ExtractWeek('date')) \ + .values('isoyear', 'week') \ + .annotate(sum_count=Sum('count')) \ + .order_by('-isoyear', '-week') + + for w in weeklyArrows: + w['weekStarts'] = tofirstdayinisoweek(w['isoyear'], w['week']) + w['weekEnds'] = w['weekStarts'] + timedelta(days=6) + + return HttpResponse(template.render({ + 'weeklyArrows': json.dumps(list(weeklyArrows), cls=DjangoJSONEncoder) + }, request)) + @login_required def arrow_count_list(request): page = request.GET.get('page')