Source code for oioioi.submitservice.views

import os
import random
import string

from django.core.exceptions import PermissionDenied
from django.shortcuts import redirect
from django.template.response import TemplateResponse
from django.urls import reverse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST

from oioioi.base.permissions import enforce_condition, not_anonymous
from oioioi.base.utils import jsonify
from oioioi.contests.forms import SubmissionForm
from oioioi.contests.utils import (
    can_enter_contest,
    contest_exists,
    visible_problem_instances,
)
from oioioi.programs.problem_instance_utils import get_allowed_languages_extensions
from oioioi.submitservice.models import SubmitServiceToken


[docs]class SubmitServiceException(Exception): pass
[docs]def match_problem(problem_instances, problem): problem_id = None for pi in problem_instances: if pi.short_name == problem: return pi elif pi.short_name.find(problem) != -1: if problem_id is None: problem_id = pi else: # matched more than one available problem return None return problem_id
@jsonify @csrf_exempt @require_POST @enforce_condition(contest_exists)
[docs]def submit_view(request): try: token = request.POST['token'] current_token = SubmitServiceToken.objects.filter(token=token) if not current_token.exists(): raise PermissionDenied('AUTHORIZATION_FAILED') request.user = current_token[0].user if not can_enter_contest(request): raise PermissionDenied('AUTHORIZATION_FAILED') task_name = request.POST['task'] file_name, file_extension = os.path.splitext(request.FILES['file'].name) if task_name: file_name = task_name pi = match_problem(visible_problem_instances(request), file_name) if not pi: raise SubmitServiceException( 'NO_SUCH_PROBLEM', ', '.join([x.short_name for x in visible_problem_instances(request)]), ) lang_exts = get_allowed_languages_extensions(pi) if file_extension[1:] not in lang_exts: raise ValueError('UNSUPPORTED_EXTENSION') form = SubmissionForm( request, {'problem_instance_id': pi.id, 'user': request.user, 'kind': 'NORMAL'}, request.FILES, ) if not form.is_valid(): raise SubmitServiceException('INVALID_SUBMISSION', form.errors) submission = request.contest.controller.create_submission( request, pi, form.cleaned_data ) result_url = reverse( 'submission', kwargs={'contest_id': request.contest.id, 'submission_id': submission.id}, ) result = {'result_url': result_url, 'submission_id': submission.id} except SubmitServiceException as exception_info: result = { 'error_code': exception_info.args[0], 'error_data': exception_info.args[1] if len(exception_info.args) == 2 else '', } except Exception as e: result = {'error_code': 'UNKNOWN_ERROR', 'error_data': str(e)} return result
@enforce_condition(not_anonymous & contest_exists)
[docs]def view_user_token(request): current_token = SubmitServiceToken.objects.filter(user=request.user) if not current_token.exists(): current_token = SubmitServiceToken() current_token.token = generate_token() current_token.user = request.user current_token.save() else: current_token = current_token[0] return TemplateResponse( request, 'submitservice/view-user-token.html', { 'token': current_token.token, 'contest_url': request.build_absolute_uri( reverse( 'default_contest_view', kwargs={'contest_id': request.contest.id} ) ), }, )
[docs]def generate_token(): new_token = ''.join( random.choice(string.ascii_uppercase + string.digits) for _ in range(32) ) # It is very improbable, but it could happen that the generated token # is already present in the dictionary. Let's generate new one. if SubmitServiceToken.objects.filter(token=new_token).exists(): return generate_token() return new_token
@enforce_condition(not_anonymous & contest_exists) @require_POST
[docs]def clear_user_token(request): current_token = SubmitServiceToken.objects.filter(user=request.user) if current_token.exists(): current_token.delete() return redirect( reverse( 'submitservice_view_user_token', kwargs={'contest_id': request.contest.id} ) )