diff --git a/helios/stats_urls.py b/helios/stats_urls.py index e96909f8192d301c2556a567534c8b9c81649b31..9e6e2703c33f4c7c96050034193c805099d48ea6 100644 --- a/helios/stats_urls.py +++ b/helios/stats_urls.py @@ -12,4 +12,5 @@ urlpatterns = patterns( '', (r'^$', home), (r'^elections$', elections), + (r'^recent-votes$', recent_votes), ) diff --git a/helios/stats_views.py b/helios/stats_views.py index 30c2b95554e583b5866a22d76c370678ceb5d6f2..b9af7c8b7a2da38e4601a8a50c5091c800725c1d 100644 --- a/helios/stats_views.py +++ b/helios/stats_views.py @@ -7,9 +7,12 @@ from django.core.mail import send_mail from django.core.paginator import Paginator from django.http import * from django.db import transaction +from django.db.models import * from security import * from auth.security import get_user, save_in_session_across_logouts +from view_utils import * + def require_admin(request): user = get_user(request) @@ -19,7 +22,8 @@ def require_admin(request): return user def home(request): - return HttpResponse("foo") + user = require_admin(request) + return render_template(request, 'stats', {}) def elections(request): user = require_admin(request) @@ -31,6 +35,14 @@ def elections(request): elections_paginator = Paginator(elections, limit) elections_page = elections_paginator.page(page) - return render_template(request, "stats", {'elections' : elections_page.object_list, 'elections_page': elections_page, - 'limit' : limit}) + return render_template(request, "stats_elections", {'elections' : elections_page.object_list, 'elections_page': elections_page, + 'limit' : limit}) +def recent_votes(request): + user = require_admin(request) + + # elections with a vote in the last 24 hours, ordered by most recent cast vote time + # also annotated with number of votes cast in last 24 hours + elections_with_votes_in_24hours = Election.objects.filter(voter__castvote__cast_at__gt= datetime.datetime.utcnow() - datetime.timedelta(days=1)).annotate(last_cast_vote = Max('voter__castvote__cast_at'), num_recent_cast_votes = Count('voter__castvote')).order_by('-last_cast_vote') + + return render_template(request, "stats_recent_votes", {'elections' : elections_with_votes_in_24hours}) diff --git a/helios/templates/stats.html b/helios/templates/stats.html index 498e2e4a97a1a7f29b49988a6c440b59bbe2477d..feffa252fb47aa027a4709073852e2e3e0f9df53 100644 --- a/helios/templates/stats.html +++ b/helios/templates/stats.html @@ -4,22 +4,9 @@ {% block content %} <h1>Statistics</h1> -<p> -{% if elections_page.has_previous %} -<a href="?page={{elections_page.previous_page_number}}&limit={{limit}}">previous {{limit}}</a> -{% endif %} - -Elections {{elections_page.start_index}} - {{elections_page.end_index}} - -{% if elections_page.has_next %} -<a href="?page={{elections_page.next_page_number}}&limit={{limit}}">next {{limit}}</a> -{% endif %} -</p> - -{% for election in elections %} -<p> -<b><a href="{% url helios.views.one_election_view election.uuid %}">{{election.name}}</a></b> -- {{election.num_voters}} voters -</p> -{% endfor %} +<ul> +<li> <a href="{% url helios.stats_views.elections %}">elections</a></li> +<li> <a href="{% url helios.stats_views.recent_votes %}">recent votes</a></li> +</ul> {% endblock %} diff --git a/helios/templates/stats_elections.html b/helios/templates/stats_elections.html new file mode 100644 index 0000000000000000000000000000000000000000..55a52523b1b131feb7a91c4b788eda207fc84a2f --- /dev/null +++ b/helios/templates/stats_elections.html @@ -0,0 +1,25 @@ +{% extends TEMPLATE_BASE %} +{% block title %}Statistics{% endblock %} + +{% block content %} +<h1>Elections</h1> + +<p> +{% if elections_page.has_previous %} +<a href="?page={{elections_page.previous_page_number}}&limit={{limit}}">previous {{limit}}</a> +{% endif %} + +Elections {{elections_page.start_index}} - {{elections_page.end_index}} + +{% if elections_page.has_next %} +<a href="?page={{elections_page.next_page_number}}&limit={{limit}}">next {{limit}}</a> +{% endif %} +</p> + +{% for election in elections %} +<p> +<b><a href="{% url helios.views.one_election_view election.uuid %}">{{election.name}}</a></b> -- {{election.num_voters}} voters / {{election.num_cast_votes}} cast votes +</p> +{% endfor %} + +{% endblock %} diff --git a/helios/templates/stats_recent_votes.html b/helios/templates/stats_recent_votes.html new file mode 100644 index 0000000000000000000000000000000000000000..d68bbd451a1de32beff39ecb24f1a5880dfae593 --- /dev/null +++ b/helios/templates/stats_recent_votes.html @@ -0,0 +1,15 @@ +{% extends TEMPLATE_BASE %} +{% block title %}Statistics{% endblock %} + +{% block content %} +<h1>Recent Votes</h1> + +Last 24 hours + +{% for election in elections %} +<p> +<b><a href="{% url helios.views.one_election_view election.uuid %}">{{election.name}}</a></b> -- {{election.last_cast_vote}} {{election.num_recent_cast_votes}} recently cast votes +</p> +{% endfor %} + +{% endblock %} diff --git a/server_ui/templates/base.html b/server_ui/templates/base.html index 9e7df746af951140e2430821dced277ef43d2d84..6299b716e224c3fffe27221d15acd9c6a7f4d28b 100644 --- a/server_ui/templates/base.html +++ b/server_ui/templates/base.html @@ -60,7 +60,9 @@ not logged in. [<a href="{{settings.SECURE_URL_HOST}}{% url auth.views.index %}? | <a href="{{ footer_link.url }}">{{footer_link.text}}</a> {% endfor %} | <a href="mailto:help@heliosvoting.org">Help!</a> - +{% if user and user.admin_p %} +| <a href="{% url helios.stats_views.home %}">Statistics</a> +{% endif %} <br clear="right" /> </div> </div>