Skip to content
This repository has been archived by the owner on Jan 3, 2024. It is now read-only.

[feature request] Envio de arquivos executáveis ao enviar submissões #113

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion apps/submissions/forms.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from django.forms import Form
from django.forms import CharField, FileField, Form
from djangocodemirror.fields import CodeMirrorField


Expand All @@ -9,3 +9,8 @@ class SubmissionForm(Form):
required=True,
config_name="python",
)


class UploadFileForm(Form):
title = CharField(max_length=255)
file = FileField()
37 changes: 35 additions & 2 deletions apps/tasks/tests.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import os
from datetime import timedelta
from io import BytesIO

from django.contrib.admin.sites import AdminSite
from django.core.files.uploadedfile import InMemoryUploadedFile
from django.core.files.uploadedfile import (
InMemoryUploadedFile,
SimpleUploadedFile,
)
from django.test import TestCase
from django.test.client import RequestFactory
from django.urls import resolve, reverse
Expand All @@ -13,7 +17,11 @@
from apps.submissions.models import Submission, SubmissionStatus
from apps.tasks.admin import TaskAdmin, TaskModelForm
from apps.tasks.models import Task
from apps.tasks.views import DetailView, handle_submission
from apps.tasks.views import (
DetailView,
handle_submission,
handle_uploaded_file,
)
from apps.users.models import User


Expand Down Expand Up @@ -348,6 +356,7 @@ def setUp(self) -> None:
self.url = reverse("tasks:detail", args=[self.task.id])
self.view = DetailView()
self.view.object = self.task
self.factory = RequestFactory()

def test_send_submission_successfully(self) -> None:
self.client.force_login(self.user)
Expand Down Expand Up @@ -510,6 +519,30 @@ def test_invalid_form_submission(self) -> None:
self.assertTemplateUsed(response, "tasks/detail.html")
self.assertFalse(response.context["form"].is_valid())

def test_handle_uploaded_file(self) -> None:
file_content = b"Test file content"
uploaded_file = SimpleUploadedFile("test_file.txt", file_content)

request = self.factory.post(self.url, data={"file": uploaded_file})
request.user = self.user

submission = Submission._default_manager.create(
author=self.user,
task=self.task,
code="print('Hello, World!')",
status=SubmissionStatus.WAITING_JUDGE,
)

handle_uploaded_file(request, self.task.id, submission.id)

destination_path = os.path.join("apps/tasks/uploads/", "test_file.txt")
self.assertTrue(os.path.exists(destination_path))

submission.refresh_from_db()
self.assertEqual(submission.status, SubmissionStatus.WAITING_JUDGE)

os.remove(destination_path)


class BackgroundJobTaskTest(TestCase):
def setUp(self) -> None:
Expand Down
28 changes: 25 additions & 3 deletions apps/tasks/views.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import os
import sys
from io import StringIO
from typing import TYPE_CHECKING, Any, Dict
Expand Down Expand Up @@ -66,6 +67,26 @@ def handle_submission(code: str, task_id: int, submission_id: int) -> None:
submission.author.save()


def handle_uploaded_file(
request: HttpRequest, task_id: int, submission_id: int
) -> None:
submission: Submission = Submission._default_manager.get(id=submission_id)
destination_dir = "apps/tasks/uploads/"
os.makedirs(destination_dir, exist_ok=True)

uploaded_file = request.FILES.get("file")

if uploaded_file:
with open(
os.path.join(destination_dir, uploaded_file.name or ""), "wb+"
) as destination:
for chunk in uploaded_file.chunks():
destination.write(chunk)

submission.status = SubmissionStatus.WAITING_JUDGE
submission.save()


class DetailView(FormMixinBase, DetailViewBase):
model = Task
template_name = "tasks/detail.html"
Expand Down Expand Up @@ -103,18 +124,19 @@ def post(self, request: HttpRequest, *, pk: int) -> HttpResponse:

self.object = self.get_object()
form = self.get_form()
uploaded_file = request.FILES.get("file")

if not form.is_valid():
if not form.is_valid() and not uploaded_file:
return self.form_invalid(form)

submission = Submission._default_manager.create(
code=form.cleaned_data["code"],
code=form.cleaned_data.get("code", ""),
task=self.object,
author=request.user,
)

handle_submission.delay(
form.cleaned_data["code"],
form.cleaned_data.get("code", ""),
self.object.id,
submission.id,
)
Expand Down
7 changes: 7 additions & 0 deletions server/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,3 +177,10 @@
CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5"

CRISPY_TEMPLATE_PACK = "bootstrap5"

####################
# Media Settings #
####################

MEDIA_URL = "/media/"
MEDIA_ROOT = BASE_DIR / "media"
12 changes: 5 additions & 7 deletions templates/tasks/detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,6 @@
{% block content %}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.63.1/codemirror.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.63.1/theme/dracula.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.63.1/theme/monokai.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.63.1/theme/3024-day.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.63.1/theme/3024-night.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.63.1/theme/cobalt.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.63.1/theme/eclipse.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.63.1/theme/rubyblue.min.css">

<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.63.1/codemirror.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.63.1/mode/python/python.min.js"></script>
Expand Down Expand Up @@ -68,11 +62,15 @@ <h4>Constraints</h4>

<hr>

<form method="post">
<form method="post" enctype="multipart/form-data">
{% csrf_token %}

<h4>Submit</h4>

<p>
File: <input type="file" name="file"/>
</p>

<div style="display: flex; flex-direction: column; gap: 20px; justify-content: center;">
<div style="display: flex; flex-direction: column; gap: 25px; font-size: 0.8rem;">
<textarea
Expand Down