Add stat page

This commit is contained in:
cuom1999 2022-09-22 19:23:41 -05:00
parent 1258d6dc25
commit 3da6a25867
8 changed files with 213 additions and 19 deletions

View file

@ -154,7 +154,9 @@ class ProblemData(models.Model):
if self.zipfile:
self.zipfile.name = problem_directory_file_helper(new, self.zipfile.name)
if self.generator:
self.generator.name = problem_directory_file_helper(new, self.generator.name)
self.generator.name = problem_directory_file_helper(
new, self.generator.name
)
if self.custom_checker:
self.custom_checker.name = problem_directory_file_helper(
new, self.custom_checker.name

View file

@ -1,6 +1,7 @@
from itertools import chain, repeat
from operator import itemgetter
import json
import pandas as pd
from django.conf import settings
from django.db.models import Case, Count, FloatField, IntegerField, Value, When
@ -11,6 +12,7 @@ from django.utils.translation import gettext as _
from django.http import Http404
from django.views.generic import TemplateView
from django.utils.safestring import mark_safe
from django.db import connection
from judge.models import Language, Submission
from judge.utils.stats import (
@ -49,18 +51,18 @@ class StatLanguage(StatViewBase):
other_count = sum(map(itemgetter("count"), languages[num_languages:]))
return {
"labels": list(map(itemgetter("name"), languages[:num_languages]))
+ ["Other"],
"datasets": [
{
"backgroundColor": chart_colors[:num_languages] + ["#FDB45C"],
"highlightBackgroundColor": highlight_colors[:num_languages]
+ ["#FFC870"],
"data": list(map(itemgetter("count"), languages[:num_languages]))
+ [other_count],
},
],
}
"labels": list(map(itemgetter("name"), languages[:num_languages]))
+ ["Other"],
"datasets": [
{
"backgroundColor": chart_colors[:num_languages] + ["#FDB45C"],
"highlightBackgroundColor": highlight_colors[:num_languages]
+ ["#FFC870"],
"data": list(map(itemgetter("count"), languages[:num_languages]))
+ [other_count],
},
],
}
def ac_language_data(self):
return self.language_data(Language.objects.annotate(count=self.ac_count))
@ -83,10 +85,12 @@ class StatLanguage(StatViewBase):
return get_pie_chart(data)
def ac_rate(self):
rate = CombinedExpression(
self.ac_count / Count("submission"), "*", Value(100.0), output_field=FloatField()
self.ac_count / Count("submission"),
"*",
Value(100.0),
output_field=FloatField(),
)
data = (
Language.objects.annotate(total=Count("submission"), ac_rate=rate)
@ -96,7 +100,6 @@ class StatLanguage(StatViewBase):
)
return get_bar_chart(list(data))
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["title"] = _("Language statistics")
@ -105,4 +108,93 @@ class StatLanguage(StatViewBase):
context["lang_ac"] = mark_safe(json.dumps(self.ac_language_data()))
context["status_counts"] = mark_safe(json.dumps(self.status_data()))
context["ac_rate"] = mark_safe(json.dumps(self.ac_rate()))
return context
return context
def group_data_by_period(dates, data, period="1W"):
df = pd.DataFrame()
df["dates"] = pd.to_datetime(dates)
df["data"] = data
df = df.groupby([pd.Grouper(key="dates", freq=period)])["data"].mean().reset_index()
return list(df["dates"]), list(df["data"])
class StatSite(StatViewBase):
template_name = "stats/site.html"
def create_dataset(self, query, label):
labels = []
data = []
with connection.cursor() as cursor:
cursor.execute(query)
for row in cursor.fetchall():
data.append(row[0])
labels.append(row[1])
labels, data = group_data_by_period(labels, data, self.period)
res = {
"labels": labels,
"datasets": [
{
"label": label,
"data": data,
"borderColor": "rgb(75, 192, 192)",
"pointRadius": 1,
"borderWidth": 2,
}
],
}
return mark_safe(json.dumps(res, default=str))
def get_submissions(self):
query = """
SELECT COUNT(*), CAST(date AS Date) as day from judge_submission GROUP BY day;
"""
return self.create_dataset(query, _("Submissions"))
def get_comments(self):
query = """
SELECT COUNT(*), CAST(time AS Date) as day from judge_comment GROUP BY day;
"""
return self.create_dataset(query, _("Comments"))
def get_new_users(self):
query = """
SELECT COUNT(*), CAST(date_joined AS Date) as day from auth_user GROUP BY day;
"""
return self.create_dataset(query, _("New users"))
def get_chat_messages(self):
query = """
SELECT COUNT(*), CAST(time AS Date) as day from chat_box_message GROUP BY day;
"""
return self.create_dataset(query, _("Chat messages"))
def get_contests(self):
query = """
SELECT COUNT(*), CAST(start_time AS Date) as day from judge_contest GROUP BY day;
"""
return self.create_dataset(query, _("Contests"))
def get_groups(self):
query = """
SELECT COUNT(*), CAST(creation_date AS Date) as day from judge_organization GROUP BY day;
"""
return self.create_dataset(query, _("Groups"))
def get(self, request, *args, **kwargs):
self.period = request.GET.get("period", "1W")
return super().get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["tab"] = "site"
context["title"] = _("Site statistics")
context["submissions"] = self.get_submissions()
context["comments"] = self.get_comments()
context["new_users"] = self.get_new_users()
context["chat_messages"] = self.get_chat_messages()
context["contests"] = self.get_contests()
context["groups"] = self.get_groups()
return context