Stats: pridani vypisu statistik

This commit is contained in:
Martin Rejman 2019-04-12 01:45:44 +02:00
parent 7f110a3aa7
commit 950c00d1cb
5 changed files with 193 additions and 32 deletions

View File

@ -301,37 +301,6 @@ class AppUser(AbstractUser, DataAudited):
return spc
"""
from django.db.models import Count
from django.db.models.functions import TruncMonth
from django.db.models.functions import TruncYear
import nalodeni as n
objs = n.models.USER_MODEL.objects.annotate( month=TruncMonth('createdStamp')).values('month', 'district').annotate(c=Count('id')).order_by('district','month')
district_choices = {
0 : 'PHA',
1 : 'JHC',
2 : 'JHM',
3 : 'KVK',
4 : 'VYS',
5 : 'KHK',
6 : 'LBK',
7 : 'MSK',
8 : 'OLK',
9 : 'PAK',
10 : 'PLK',
11 : 'STC',
12 : 'ULK',
13 : 'ZLK',
}
for o in objs:
print( "%s \t %s \t %s" % (district_choices[o['district']] if o['district'] is not None else "---", o['month'].strftime('%Y-%m'),o['c']))
"""

115
src/nalodeni/stats.py Normal file
View File

@ -0,0 +1,115 @@
# -*- encoding: utf-8 -*-
from datetime import date, datetime, timedelta # timeSlices
from collections import OrderedDict
import csv
import django
from django.http import HttpResponse, HttpResponseRedirect
from django.template import Template, RequestContext, loader
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from django.urls import reverse
from django.views.decorators.csrf import ensure_csrf_cookie
from django import forms
from django.forms import ModelForm
from django.contrib import messages
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import pgettext, pgettext_lazy
from django.db import transaction
from django.db.models import F
from django.db.models import Count
from django.db.models.functions import TruncMonth
from django.db.models.functions import TruncYear
from django.core.exceptions import ValidationError
import logging
from django.conf import settings as appSettings
from . import models
from . import forms
from . import auth as nalodeni_auth
# Logger instance
logger = logging.getLogger(__name__)
def role_required(roles=[]):
def decorate(func):
def call(request, *args, **kwargs):
for r in roles:
if not r in request.session['site_perms']:
messages.error(request, "Nedostatečné oprávnění pro přístup. Detaily byly zaznamenány.")
return HttpResponseRedirect('/')
result = func(request, *args, **kwargs)
return result
return call
return decorate
def get_AppUser_objects(request):
''' Zkontroluje, že všechny objekty v 'objs' vyhovují přiděleným rolím.
Nevyhovující vyřadí.
'''
sp = request.session['site_perms']
if 'sso_kodo' not in sp:
return models.AppUser.objects.none()
if 'sso_admin' in sp:
return models.AppUser.objects.all()
objs = models.AppUser.objects.filter(district__in=request.session['spc']['dist'])
return objs
def get_AppUser_districts(request):
'''Vrátí dostupné kraje podle rolí.'''
if 'sso_admin' in request.session['site_perms']:
return list(models.AppUser.DISTRICT_CHOICES)
rslt = []
for d in models.AppUser.DISTRICT_CHOICES:
if d[0] in request.session['spc']['dist']:
rslt.append(d)
return rslt
@ensure_csrf_cookie
@login_required(login_url="/prihlaseni")
@role_required(['sso_kodo'])
def reg_counts(request, dist=None):
if dist is None:
dist = int(request.POST.get('dist', -1))
objs = get_AppUser_objects(request)
districts = [(-1, ' -- vše dostupné -- ')] + get_AppUser_districts(request)
# filtrujeme jen povolene kraje, nebo vse pro adminy
if dist != -1 and (dist in request.session['spc']['dist'] or 'sso_admin' in request.session['site_perms']):
selDist = dist
objs = objs.filter(district=selDist)
else:
selDist = -1
objs = objs.annotate( month=TruncMonth('createdStamp')).values('month', 'district').annotate(c=Count('id')).order_by('district','month')
for o in objs:
o['district'] = models.AppUser.DISTRICT_CHOICES_STR[o['district']] if o['district'] is not None else "---"
#print( "%s \t %s \t %s" % (o['district'], o['month'].strftime('%Y-%m'),o['c']))
template = 'stats/reg_counts.html'
context = {
'objs' : objs,
'distAvail' : districts,
'selDist' : selDist,
}
return render(request, template, context)

View File

@ -239,6 +239,7 @@
<li class="c-top-sub-nav__item"><a href="/people/list/"{%if request.resolver_match.url_name == 'people_list'%} class="is-active"{%endif%}>Registrovaní</a>
<li class="c-top-sub-nav__item"><a href="/people/list-new/"{%if request.resolver_match.url_name == 'people_list_new'%} class="is-active"{%endif%}>Nově přihlášení</a>
<li class="c-top-sub-nav__item"><a href="/people/pending/"{%if request.resolver_match.url_name == 'people_pending'%} class="is-active"{%endif%}>Čekající registrace</a>
<li class="c-top-sub-nav__item"><a href="/stats/reg_counts/"{%if request.resolver_match.url_name == 'stats_reg_counts'%} class="is-active"{%endif%}>Statistiky</a>
</ul>
</div>
</div>

View File

@ -0,0 +1,72 @@
{% extends 'pirati_cz.html' %}
{%block head%}
<script>
$(document).ready(function(){
$("#check_all").on("change", function(){
if( $(this).prop('checked') ){
$(".people_form input[type='checkbox']").prop("checked", true);
} else {
$(".people_form input[type='checkbox']").prop("checked", false);
}
});
});
</script>
{%endblock%}
{%block body%}
<div class="row">
<div class="medium-12 large-12 columns">
<section class="o-section o-section--spaceBot">
<div class="o-section-inner">
<div class="o-section-block">
<h2>Statistiky registrací dle měsíců a krajů</h2>
<br/>
<form action="#" method="POST">
{%csrf_token%}
<div class="medium-4 large-4 columns">
<select name="dist" onChange="this.form.submit()">{% for d in distAvail%}<option value="{{d.0}}"{%if selDist == d.0%} selected="selected"{%endif%}>{{d.1}}</option>{%endfor%}</select>
</div>
<div class="medium-4 large-4 columns">
</div>
<div class="medium-4 large-4 columns">
</div>
</form>
<br/>
<br/>
<br/>
{% if objs|length > 0 %}
<table class="table-list">
<tr>
<th>Kraj</th>
<th>Rok, měsíc</th>
<th>Počet registrovaných</th>
</tr>
{% for obj in objs %}
<tr>
<td>{{obj.district}}</td>
<td>{{obj.month|date:"Y-m"}}</td>
<td>{{obj.c}}</td>
</tr>
{% endfor %}
</table>
{%else%}
<em>Žádné položky</em>
{%endif%}
</div>
</div>
</section>
</div>
</div>
<div class="row">
<div class="medium-12 large-12 columns">
<section class="o-section o-section--spaceBot">
<div class="o-section-inner">
&nbsp;
</div>
</section>
</div>
</div>
{%endblock%}

View File

@ -4,7 +4,7 @@ from django.conf.urls import include, url
from django.conf import settings as appSettings
from . import views, people, news
from . import views, people, news, stats
app_name = "nalodeni"
urlpatterns = [
@ -38,6 +38,10 @@ urlpatterns = [
url(r'^people/pending/$', people.pending, name="people_pending"),
url(r'^people/update/$', people.update, name="people_update"),
url(r'^stats/reg_counts/$', stats.reg_counts, name="stats_reg_counts"),
url(r'^news/all/$', news.news_all, name="news_all"),
url(r'^news/list/create/$', news.list_edit, name="news_list_create"),
url(r'^news/list/edit/(?P<lid>[0-9]+)/$', news.list_edit, name="news_list_edit"),