NDOJ/judge/views/internal.py
2023-08-29 18:52:24 -05:00

147 lines
5 KiB
Python

import logging
import json
from django.views.generic import ListView
from django.utils.translation import gettext as _, gettext_lazy
from django.db.models import Count, Q
from django.http import HttpResponseForbidden
from django.urls import reverse
from judge.utils.diggpaginator import DiggPaginator
from judge.models import VolunteerProblemVote, Problem
class InternalView(object):
def get(self, request, *args, **kwargs):
if request.user.is_superuser:
return super(InternalView, self).get(request, *args, **kwargs)
return HttpResponseForbidden()
class InternalProblem(InternalView, ListView):
model = Problem
title = _("Internal problems")
template_name = "internal/problem.html"
paginate_by = 100
context_object_name = "problems"
def get_paginator(
self, queryset, per_page, orphans=0, allow_empty_first_page=True, **kwargs
):
return DiggPaginator(
queryset,
per_page,
body=6,
padding=2,
orphans=orphans,
allow_empty_first_page=allow_empty_first_page,
**kwargs
)
def get_search_query(self):
return self.request.GET.get("q") or self.request.POST.get("q")
def get_queryset(self):
queryset = Problem.objects.annotate(
vote_count=Count("volunteer_user_votes")
).filter(vote_count__gte=1)
query = self.get_search_query()
if query:
queryset = queryset.filter(
Q(code__icontains=query) | Q(name__icontains=query)
)
return queryset.order_by("-vote_count")
def get_context_data(self, **kwargs):
context = super(InternalProblem, self).get_context_data(**kwargs)
context["page_type"] = "problem"
context["title"] = self.title
context["page_prefix"] = self.request.path + "?page="
context["first_page_href"] = self.request.path
context["query"] = self.get_search_query()
return context
class RequestTimeMixin(object):
def get_requests_data(self):
logger = logging.getLogger(self.log_name)
log_filename = logger.handlers[0].baseFilename
requests = []
with open(log_filename, "r") as f:
for line in f:
try:
info = json.loads(line)
requests.append(info)
except:
continue
return requests
class InternalRequestTime(InternalView, ListView, RequestTimeMixin):
title = _("Request times")
template_name = "internal/request_time.html"
context_object_name = "pages"
log_name = "judge.request_time"
detail_url_name = "internal_request_time_detail"
page_type = "request_time"
def get_queryset(self):
requests = self.get_requests_data()
table = {}
for r in requests:
url_name = r["url_name"]
if url_name not in table:
table[url_name] = {
"time": 0,
"count": 0,
"url_name": url_name,
}
old_sum = table[url_name]["time"] * table[url_name]["count"]
table[url_name]["count"] += 1
table[url_name]["time"] = (old_sum + float(r["response_time"])) / table[
url_name
]["count"]
order = self.request.GET.get("order", "time")
return sorted(table.values(), key=lambda x: x[order], reverse=True)
def get_context_data(self, **kwargs):
context = super(InternalRequestTime, self).get_context_data(**kwargs)
context["page_type"] = self.page_type
context["title"] = self.title
context["current_path"] = self.request.path
context["detail_path"] = reverse(self.detail_url_name)
return context
class InternalRequestTimeDetail(InternalRequestTime):
template_name = "internal/request_time_detail.html"
context_object_name = "requests"
def get_queryset(self):
url_name = self.request.GET.get("url_name", None)
if not url_name:
return HttpResponseForbidden()
if url_name == "None":
url_name = None
self.title = url_name
requests = self.get_requests_data()
filtered_requests = [r for r in requests if r["url_name"] == url_name]
order = self.request.GET.get("order", "response_time")
return sorted(filtered_requests, key=lambda x: x[order], reverse=True)[:200]
def get_context_data(self, **kwargs):
context = super(InternalRequestTimeDetail, self).get_context_data(**kwargs)
context["url_name"] = self.request.GET.get("url_name", None)
return context
class InternalSlowRequest(InternalRequestTime):
log_name = "judge.slow_request"
detail_url_name = "internal_slow_request_detail"
page_type = "slow_request"
class InternalSlowRequestDetail(InternalRequestTimeDetail):
log_name = "judge.slow_request"