Skip to content
Permalink
Browse files

add global stats page

  • Loading branch information...
christianp committed Sep 25, 2018
1 parent 30edae8 commit 44e2971aa7bf27da5ad79c94cbe034d3956f07cf
Showing with 152 additions and 1 deletion.
  1. +22 −0 editor/static/css/global_stats.css
  2. +83 −0 editor/templates/global_stats.html
  3. +5 −1 editor/urls.py
  4. +42 −0 editor/views/__init__.py
@@ -0,0 +1,22 @@
.stat-cards {
display: flex;
flex-wrap: wrap;
}
.stat-card {
background: #acdeff;
padding: 1rem 2rem;
border-radius: 0.5em;
text-align: center;
margin: 1rem;
flex: 1 0 12em;
}
.stat-card > h4 {
margin: 0 0 1rem 0;
font-weight: bold;
}
a.stat-card {
color: inherit;
text-decoration: none;
display: block;
}

@@ -0,0 +1,83 @@
{% extends "base.html" %}
{% load humanize %}
{% load sstatic %}

{% block stylesheets %}
{{ block.super }}
<link rel="stylesheet" type="text/css" href="{% sstatic 'css/global_stats.css' %}"/>
{% endblock stylesheets %}

{% block content %}
<div class="row">
<p>This page presents some statistics about activity on {{SITE_TITLE}}.</p>
<div class="row">
<div class="col-md-6">
<div class="stat-cards">
<a class="stat-card" href="{% url 'search' %}?item_types=questions">
<h4>{{counts.questions|intcomma}}</h4>
questions, of which
<strong>{{counts.public_questions}}</strong> published.
</a>

<a class="stat-card" href="{% url 'search' %}?item_types=exams">
<h4>{{counts.exams|intcomma}}</h4>
exams, of which
<strong>{{counts.public_exams}}</strong> published.
</a>

<a class="stat-card" href="{% url 'public_projects' %}">
<h4>{{counts.projects|intcomma}}</h4>
projects, of which
<strong>{{counts.public_projects}}</strong> published.
</a>

<a class="stat-card" href="{{HELP_URL}}extensions.html">
<h4>{{counts.extensions|intcomma}}</h4>
extensions.
</a>

<a class="stat-card" href="{{HELP_URL}}themes.html">
<h4>{{counts.themes|intcomma}}</h4>
themes.
</a>

<a class="stat-card" href="{{HELP_URL}}custom-part-types/reference.html">
<h4>{{counts.custom_part_types|intcomma}}</h4>
custom part types.
</a>

<div class="stat-card">
<h4>{{counts.users|intcomma}}</h4>
users, from <strong>{{counts.user_domains}}</strong> institutions (approximately).
</div>
</div>
</div>
<div class="col-md-6">
<table class="table">
<thead>
<th></th>
<th>in the past</th>
<th>day</th>
<th>week</th>
<th>month</th>
</thead>
<tbody>
<tr>
<th>Items created</th>
<td></td>
{% for period in recent_data %}<td>{{period.created}}</td>{% endfor %}
</tr>
<tr>
<th>Items modified</th>
<td></td>
{% for period in recent_data %}<td>{{period.modified}}</td>{% endfor %}
</tr>
<tr>
<th>Users active</th>
<td></td>
{% for period in recent_data %}<td>{{period.users_active}}</td>{% endfor %}
</tr>
</tbody>
</table>
</div>
{% endblock content %}
@@ -2,14 +2,18 @@

from django.contrib.auth.decorators import login_required

from .views import project, editoritem, exam, question, HomeView, TermsOfUseView, PrivacyPolicyView, theme, extension, generic, notification, resource, basket, timeline, custom_part_type
from .views import project, editoritem, exam, question, HomeView, GlobalStatsView, TermsOfUseView, PrivacyPolicyView, theme, extension, generic, notification, resource, basket, timeline, custom_part_type

urlpatterns = [

# Home

url(r'^$', HomeView.as_view(), name='editor_index'),

# Global stats

url(r'^stats/$', GlobalStatsView.as_view(), name='global_stats'),

# Terms of use

url(r'^terms-of-use/$', TermsOfUseView.as_view(), name='terms_of_use'),
@@ -1,5 +1,10 @@
from django.views.generic import TemplateView
from django.db.models import Q
from editor.models import SiteBroadcast
from django.utils.timezone import now
from datetime import timedelta
from editor.models import EditorItem, NewQuestion, NewExam, Project, Extension, Theme, CustomPartType, TimelineItem
from django.contrib.auth.models import User

class HomeView(TemplateView):
template_name = 'index.html'
@@ -14,3 +19,40 @@ class TermsOfUseView(TemplateView):
template_name = 'terms_of_use.html'
class PrivacyPolicyView(TemplateView):
template_name = 'privacy_policy.html'

class GlobalStatsView(TemplateView):
template_name = 'global_stats.html'

def get_context_data(self, **kwargs):
context = super(GlobalStatsView, self).get_context_data(**kwargs)
t = now()
periods = [
timedelta(days=1),
timedelta(days=7),
timedelta(days=30),
]
context['recent_data'] = [
{
'created': EditorItem.objects.filter(created__gt=t-d).count(),
'modified': EditorItem.objects.filter(last_modified__gt=t-d).count(),
'users_active': User.objects.filter(timelineitems__date__gt=t-d).distinct().count(),
}
for d in periods
]

active_users = User.objects.filter(is_active=True)

context['counts'] = {
'questions': NewQuestion.objects.count(),
'public_questions': NewQuestion.objects.filter(editoritem__published=True).count(),
'exams': NewExam.objects.count(),
'public_exams': NewExam.objects.filter(editoritem__published=True).count(),
'projects': Project.objects.count(),
'public_projects': Project.objects.filter(public_view=True).count(),
'extensions': Extension.objects.count(),
'themes': Theme.objects.count(),
'custom_part_types': CustomPartType.objects.count(),
'users': active_users.count(),
'user_domains': len(set(u.email.split('@')[1] for u in active_users if '@' in u.email)),
}
return context

0 comments on commit 44e2971

Please sign in to comment.
You can’t perform that action at this time.