Source code for oioioi.livedata.views

import datetime
import functools

from django.conf import settings
from django.core.cache import cache
from django.db.models import F, OuterRef, Q, Subquery
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from django.utils import dateformat
from django.utils.translation import get_language
from oioioi.base.permissions import enforce_condition
from oioioi.base.utils import allow_cross_origin, jsonify
from oioioi.contests.models import SubmissionReport
from oioioi.contests.utils import contest_exists, is_contest_admin, is_contest_observer
from oioioi.livedata.utils import can_see_livedata, get_display_name
from oioioi.problems.models import ProblemName

[docs]RESULT_FOR_FROZEN_SUBMISSION = 'FROZEN'
[docs]def cache_unless_admin_or_observer(view): @functools.wraps(view) def inner(request, round_id): should_cache = not is_contest_admin(request) and not is_contest_observer( request ) if not should_cache: return view(request, round_id) cache_key = '%s/%s/%s' % (view.__name__, request.contest.id, round_id) result = cache.get(cache_key) if result is None: result = view(request, round_id) assert isinstance(result, HttpResponse) cache.set( cache_key, { 'content': str(result.content), 'content_type': result['Content-Type'], }, settings.LIVEDATA_CACHE_TIMEOUT, ) else: result = HttpResponse( result['content'], content_type=result['content_type'] ) return result return inner
@allow_cross_origin @enforce_condition(contest_exists & can_see_livedata) @cache_unless_admin_or_observer @jsonify
[docs]def livedata_teams_view(request, round_id): return [ { 'id': participant.user.id, 'login': participant.user.username, 'name': get_display_name(participant.user), } for participant in request.contest.participant_set.all() ]
@allow_cross_origin @enforce_condition(contest_exists & can_see_livedata) @cache_unless_admin_or_observer @jsonify
[docs]def livedata_tasks_view(request, round_id): round = get_object_or_404(request.contest.round_set.all(), pk=round_id) if not request.contest.controller.can_see_round(request, round): return [] pis = ( round.probleminstance_set.all() .prefetch_related('problem__names') .annotate( problem_localized_name=Subquery( ProblemName.objects.filter( problem=OuterRef('problem__pk'), language=get_language() ).values('name') ) ) ) problem_localized_name = F('problem_localized_name') return [ {'id': pi.id, 'shortName': pi.short_name, 'name': pi.problem.name} for pi in pis.order_by(problem_localized_name.asc(nulls_first=True)) ]
@allow_cross_origin @enforce_condition(contest_exists & can_see_livedata) @cache_unless_admin_or_observer @jsonify
[docs]def livedata_events_view(request, round_id): user_is_participant = Q( submission__user__participant__contest_id=request.contest.id, submission__user__participant__status='ACTIVE', ) submission_ignored = Q(submission__kind='IGNORED') reports = ( SubmissionReport.objects.filter(user_is_participant) .exclude(submission_ignored) .exclude(kind='TESTRUN') .select_related('submission') .prefetch_related('scorereport_set') ) if ( is_contest_admin(request) or is_contest_observer(request) ) and 'from' in request.GET: # Only admin/observer is allowed to specify 'from' parameter. start_time = datetime.datetime.utcfromtimestamp( int(request.GET['from']) ).replace(tzinfo=datetime.timezone.utc) reports = reports.filter(creation_date__gte=start_time) round = get_object_or_404(request.contest.round_set.all(), pk=round_id) contest_start = round.start_date reports = reports.filter(submission__problem_instance__round=round) if is_contest_admin(request): freeze_time = None else: freeze_time = request.contest.controller.get_round_freeze_time(round) if round.results_date is not None and request.timestamp > round.results_date: freeze_time = None return [ { 'submissionId': 'START', 'reportId': 'START', 'teamId': 'START', 'taskId': 'START', 'submissionTimestamp': int(dateformat.format(request.timestamp, 'U')), 'judgingTimestamp': int(dateformat.format(contest_start, 'U')), 'result': 'CTRL', } ] + [ { 'submissionId': report.submission_id, 'reportId': report.pk, 'teamId': report.submission.user_id, 'taskId': report.submission.problem_instance_id, 'submissionTimestamp': int(dateformat.format(report.submission.date, 'U')), 'judgingTimestamp': int(dateformat.format(report.creation_date, 'U')), 'result': report.score_report.status if freeze_time is None or report.submission.date < freeze_time else RESULT_FOR_FROZEN_SUBMISSION, } for report in reports.order_by('creation_date') if report.score_report is not None ]