From e66510a3bbf3f76551e6d9ced5506cd0cf0eed04 Mon Sep 17 00:00:00 2001
From: Ben Adida <ben@adida.net>
Date: Sun, 7 Nov 2010 15:12:12 -0800
Subject: [PATCH] added more stats

---
 helios/stats_urls.py                     |  1 +
 helios/stats_views.py                    | 18 ++++++++++++++---
 helios/templates/stats.html              | 21 ++++----------------
 helios/templates/stats_elections.html    | 25 ++++++++++++++++++++++++
 helios/templates/stats_recent_votes.html | 15 ++++++++++++++
 server_ui/templates/base.html            |  4 +++-
 6 files changed, 63 insertions(+), 21 deletions(-)
 create mode 100644 helios/templates/stats_elections.html
 create mode 100644 helios/templates/stats_recent_votes.html

diff --git a/helios/stats_urls.py b/helios/stats_urls.py
index e96909f..9e6e270 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 30c2b95..b9af7c8 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 498e2e4..feffa25 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> &nbsp;&nbsp;
-{% endif %}
-
-Elections {{elections_page.start_index}} - {{elections_page.end_index}}&nbsp;&nbsp;
-
-{% if elections_page.has_next %}
-<a href="?page={{elections_page.next_page_number}}&limit={{limit}}">next {{limit}}</a> &nbsp;&nbsp;
-{% 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 0000000..55a5252
--- /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> &nbsp;&nbsp;
+{% endif %}
+
+Elections {{elections_page.start_index}} - {{elections_page.end_index}}&nbsp;&nbsp;
+
+{% if elections_page.has_next %}
+<a href="?page={{elections_page.next_page_number}}&limit={{limit}}">next {{limit}}</a> &nbsp;&nbsp;
+{% 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 0000000..d68bbd4
--- /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 9e7df74..6299b71 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>
-- 
GitLab