From adbe78bd82ea5197ccb0224245a77c4ddcccaf24 Mon Sep 17 00:00:00 2001 From: Timur Date: Mon, 3 Mar 2025 21:01:04 +0300 Subject: [PATCH 1/9] add task admin validators --- services/backend/apps/task/models.py | 32 ++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/services/backend/apps/task/models.py b/services/backend/apps/task/models.py index a23b315..ffb3c08 100644 --- a/services/backend/apps/task/models.py +++ b/services/backend/apps/task/models.py @@ -1,7 +1,9 @@ +from sys import stdout from uuid import uuid4 from django.db import models from django.db.models import Count, Q +from django.core.exceptions import ValidationError from mdeditor.fields import MDTextField from apps.competition.models import Competition @@ -78,6 +80,36 @@ class CompetitionTask(BaseModel): verbose_name="кол-во проверяющих для зачета задачи", ) + def clean(self): + super().clean() + if self.correct_answer_file and self.type not in ["checker", "input"]: + raise ValidationError({ + "type": "Если загружен файл правильного ответа, то тип проверки не может быть ручным" + }) + elif not self.correct_answer_file and self.type == "review": + raise ValidationError({ + "correct_answer_file": "Загрузите правильный ответ" + }) + + if self.answer_file_path and not self.type == "checker": + raise ValidationError({ + "type": "Укажите другой тип задания: этот не совместим с путем правильного ответа" + }) + elif not self.answer_file_path and self.type == "checker": + raise ValidationError({ + "answer_file_path": "Введите путь правильного ответа - это нужно для корректной работы чекера" + }) + + if not self.reviewers and self.type == "review": + raise ValidationError({ + "reviewers": "Загрузите ревьюверов - кто будет проверять задания, если не они?" + }) + elif self.reviewers and not self.type == "review": + raise ValidationError({ + "type": "Проверьте тип - вы ввели ревьюверов, но задание не является ручным" + }) + + def __str__(self): return self.title From 74a8e7662b4df68d0730a537a2b3f635e5e8ab00 Mon Sep 17 00:00:00 2001 From: Timur Date: Mon, 3 Mar 2025 21:19:41 +0300 Subject: [PATCH 2/9] add postman tests --- img/postman_e2e.json | 768 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 768 insertions(+) create mode 100644 img/postman_e2e.json diff --git a/img/postman_e2e.json b/img/postman_e2e.json new file mode 100644 index 0000000..9c14a52 --- /dev/null +++ b/img/postman_e2e.json @@ -0,0 +1,768 @@ +{ + "info": { + "_postman_id": "fd33ed4f-84b5-4045-b926-22d989876fb0", + "name": "Datarush tests", + "schema": "https://schema.getpostman.com/json/collection/v2.0.0/collection.json", + "_exporter_id": "29887339" + }, + "item": [ + { + "name": "User", + "item": [ + { + "name": "Correct registration", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "// Генерация случайных данных\r", + "const randomNamePrefix = `company_${Math.random().toString(36).substring(2, 8)}`;\r", + "const randomUsername = `${Math.random().toString(36).substring(3, 9)}`\r", + "const randomEmail = `${Math.random().toString(36).substring(2, 8)}@timka.test`;\r", + "const randomPassword = `${Math.random().toString(36).substring(2, 12)}!A1`;\r", + "\r", + "// Формирование тела запроса\r", + "const requestData = {\r", + " username: randomUsername,\r", + " email: randomEmail,\r", + " password: randomPassword\r", + "};\r", + "\r", + "// Сохранение данных в переменные окружения\r", + "pm.environment.set(\"randomNamePrefix\", randomNamePrefix);\r", + "pm.environment.set(\"randomEmail\", randomEmail);\r", + "pm.environment.set(\"randomPassword\", randomPassword);\r", + "pm.environment.set(\"randomUsername\", randomUsername)\r", + "\r", + "// Сохранение JSON-объекта в переменную для дальнейшего использования\r", + "pm.environment.set(\"requestData\", JSON.stringify(requestData));\r", + "pm.environment.set(\"requestNameREGISTRATION\", JSON.stringify(randomNamePrefix));\r", + "pm.environment.set(\"requestEmailREGISTRATION\", JSON.stringify(randomEmail));\r", + "pm.environment.set(\"requestusernameREGISTRATION\", JSON.stringify(randomUsername))\r", + "pm.environment.set(\"requestPasswordREGISTRATION\", JSON.stringify(randomPassword));" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 201', function () {\r", + " pm.response.to.have.status(201);\r", + "});\r", + "\r", + "pm.test('Response has token', function () {\r", + " const jsonData = pm.response.json();\r", + " pm.expect(jsonData.token).to.be.a('string');\r", + "});" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{{requestData}}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": "{{BASE_HOST}}/v1/sign-up" + }, + "response": [] + }, + { + "name": "Correct sign in", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "const email = pm.environment.get(\"randomEmail\")\r", + "const password = pm.environment.get(\"randomPassword\")\r", + "\r", + "const requestData = {\r", + " email: email,\r", + " password: password\r", + "}\r", + "pm.environment.set(\"requestData\", JSON.stringify(requestData));\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});\r", + "\r", + "pm.test('Response has token', function () {\r", + " const jsonData = pm.response.json();\r", + " pm.expect(jsonData.token).to.be.a('string');\r", + " pm.environment.set(\"token\", jsonData.token)\r", + "});" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{{requestData}}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": "{{BASE_HOST}}/v1/sign-in" + }, + "response": [] + }, + { + "name": "Duplicated reg data", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "const email = pm.environment.get(\"randomEmail\")\r", + "const password = pm.environment.get(\"randomPassword\")\r", + "const username = pm.environment.get(\"randomUsername\")\r", + "\r", + "const requestData = {\r", + " email: email,\r", + " password: password,\r", + " username: username\r", + "}\r", + "pm.environment.set(\"requestData\", JSON.stringify(requestData));\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 409', function () {\r", + " pm.response.to.have.status(409);\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{{requestData}}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": "{{BASE_HOST}}/v1/sign-up" + }, + "response": [] + }, + { + "name": "Reg without username", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "const email = pm.environment.get(\"randomEmail\")\r", + "const password = pm.environment.get(\"randomPassword\")\r", + "\r", + "const requestData = {\r", + " email: email,\r", + " password: password\r", + "}\r", + "pm.environment.set(\"requestData\", JSON.stringify(requestData));\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{{requestData}}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": "{{BASE_HOST}}/v1/sign-up" + }, + "response": [] + } + ] + }, + { + "name": "Competitions", + "item": [ + { + "name": "Get competition with no partipication", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});\r", + "\r", + "pm.test('Response has only 2 elements', function () {\r", + " const jsonData = pm.response.json();\r", + " pm.expect(jsonData).to.has.length(2,\"Response has non-2 length, try to reset to only test data state\");\r", + " pm.environment.set(\"competition_id\", jsonData[0].id)\r", + "});" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": { + "token": "{{token}}" + } + }, + "method": "GET", + "header": [], + "url": { + "raw": "{{BASE_HOST}}/v1/competitions?is_participating=false", + "host": [ + "{{BASE_HOST}}" + ], + "path": [ + "v1", + "competitions" + ], + "query": [ + { + "key": "is_participating", + "value": "false" + } + ] + } + }, + "response": [] + }, + { + "name": "Get competition with partipication", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});\r", + "\r", + "pm.test('Response has only 2 elements', function () {\r", + " const jsonData = pm.response.json();\r", + " pm.expect(jsonData).to.has.length(0,\"Response has non-0 length, try to reset to only test data state\");\r", + "});" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": { + "token": "{{token}}" + } + }, + "method": "GET", + "header": [], + "url": { + "raw": "{{BASE_HOST}}/v1/competitions?is_participating=true", + "host": [ + "{{BASE_HOST}}" + ], + "path": [ + "v1", + "competitions" + ], + "query": [ + { + "key": "is_participating", + "value": "true" + } + ] + } + }, + "response": [] + }, + { + "name": "Get tasks without partipicating in test", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + "});" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": { + "token": "{{token}}" + } + }, + "method": "GET", + "header": [], + "url": "{{BASE_HOST}}/v1/competitions/{{competition_id}}/tasks" + }, + "response": [] + }, + { + "name": "Submit task sol without partipicaating", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": { + "token": "{{token}}" + } + }, + "method": "POST", + "header": [], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "file", + "type": "file", + "src": "/C:/Users/timka/AppData/Local/Postman/app-11.33.4/libGLESv2.dll" + } + ] + }, + "url": "{{BASE_HOST}}/v1/competitions/{{competition_id}}/tasks/{{task_id}}/submit" + }, + "response": [] + }, + { + "name": "Partipicate in competition", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": { + "token": "{{token}}" + } + }, + "method": "POST", + "header": [], + "url": "{{BASE_HOST}}/v1/competitions/{{competition_id}}/start" + }, + "response": [] + }, + { + "name": "Get competition tasks", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});\r", + "\r", + "pm.test('Response has tasks', function () {\r", + " const jsonData = pm.response.json();\r", + " pm.environment.set(\"task_id\", jsonData[0].id)\r", + " pm.expect(jsonData).to.has.length(9)\r", + "});" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": { + "token": "{{token}}" + } + }, + "method": "GET", + "header": [], + "url": "{{BASE_HOST}}/v1/competitions/{{competition_id}}/tasks" + }, + "response": [] + }, + { + "name": "Get task history", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});\r", + "\r", + "pm.test('Response has token', function () {\r", + " const jsonData = pm.response.json();\r", + " pm.expect(jsonData).to.has.length(0);\r", + "});" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": { + "token": "{{token}}" + } + }, + "method": "GET", + "header": [], + "url": "{{BASE_HOST}}/v1/competitions/{{competition_id}}/tasks/{{task_id}}/history" + }, + "response": [] + }, + { + "name": "Submit task sol", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});\r", + "\r", + "pm.test('Response has submission id', function () {\r", + " const jsonData = pm.response.json();\r", + " pm.expect(jsonData.submission_id).to.be.a('string');\r", + " pm.environment.set(\"sub_id\", jsonData.submission_id)\r", + "});" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": { + "token": "{{token}}" + } + }, + "method": "POST", + "header": [], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "file", + "type": "file", + "src": "/C:/Users/timka/AppData/Local/Postman/app-11.33.4/libGLESv2.dll" + } + ] + }, + "url": "{{BASE_HOST}}/v1/competitions/{{competition_id}}/tasks/{{task_id}}/submit" + }, + "response": [] + }, + { + "name": "Get task attachments", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});\r", + "\r", + "pm.test('Response has empty array', function () {\r", + " const jsonData = pm.response.json();\r", + " pm.expect(jsonData).to.has.length(0);\r", + "});" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": { + "token": "{{token}}" + } + }, + "method": "GET", + "header": [], + "url": "{{BASE_HOST}}/v1/competitions/{{competition_id}}/tasks/{{task_id}}/attachments" + }, + "response": [] + } + ] + }, + { + "name": "Revieews", + "item": [ + { + "name": "Get reviewer profile", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});\r", + "\r", + "pm.test('Response has correct data', function () {\r", + " const jsonData = pm.response.json();\r", + " pm.expect(jsonData.name).to.eq(pm.environment.get(\"reviewer_name\"));\r", + " pm.expect(jsonData.surname).to.eq(pm.environment.get(\"reviewer_surname\"))\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": "{{BASE_HOST}}/v1/review/{{reviewer_key}}" + }, + "response": [] + }, + { + "name": "Get submissions", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});\r", + "\r", + "pm.test('Response has correct data', function () {\r", + " const jsonData = pm.response.json();\r", + " pm.expect(jsonData).to.has.length(0)\r", + "});\r", + "\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": "{{BASE_HOST}}/v1/review/{{reviewer_key}}/submissions/{{sub_id}}" + }, + "response": [] + } + ] + }, + { + "name": "Healthcheck", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{BASE_HOST}}/health?format=json", + "host": [ + "{{BASE_HOST}}" + ], + "path": [ + "health" + ], + "query": [ + { + "key": "format", + "value": "json" + } + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "packages": {}, + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "packages": {}, + "exec": [ + "" + ] + } + } + ], + "variable": [ + { + "key": "BASE_HOST", + "value": "https://prod-team-15-2pc0i3lc.final.prodcontest.ru/api", + "type": "string" + }, + { + "key": "requestData", + "value": "", + "type": "string" + }, + { + "key": "token", + "value": "", + "type": "string" + }, + { + "key": "competition_id", + "value": "", + "type": "string" + }, + { + "key": "task_id", + "value": "", + "type": "string" + }, + { + "key": "reviewer_key", + "value": "", + "type": "string" + }, + { + "key": "reviewer_name", + "value": "", + "type": "string" + }, + { + "key": "reviewer_surname", + "value": "", + "type": "string" + }, + { + "key": "sub_id", + "value": "", + "type": "string" + } + ] +} \ No newline at end of file From afd65629fadd6a984206a87e910bd49816961c6e Mon Sep 17 00:00:00 2001 From: moolcoov Date: Mon, 3 Mar 2025 22:00:24 +0300 Subject: [PATCH 3/9] fix --- services/frontend/src/pages/Profile/widgets/user-info.tsx | 2 +- services/frontend/src/pages/Review/modules/review-dialog.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/services/frontend/src/pages/Profile/widgets/user-info.tsx b/services/frontend/src/pages/Profile/widgets/user-info.tsx index 808619b..e0ddc94 100644 --- a/services/frontend/src/pages/Profile/widgets/user-info.tsx +++ b/services/frontend/src/pages/Profile/widgets/user-info.tsx @@ -2,7 +2,7 @@ import { User } from "@/shared/types/user"; export const UserInfo = ({ user }: { user: User }) => { return ( -
+
{user.avatar && (
{

Ответ

-
+
{extension === "txt" ? ( content ) : ( From 312ade9b562ec02b4b9ab5fc6ed78f8dbc3d61be Mon Sep 17 00:00:00 2001 From: ITQ Date: Mon, 3 Mar 2025 22:12:40 +0300 Subject: [PATCH 4/9] (scope): [body] [footer(s)] --- services/checker/main.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/services/checker/main.py b/services/checker/main.py index a1d05fa..8fea2e8 100644 --- a/services/checker/main.py +++ b/services/checker/main.py @@ -88,7 +88,9 @@ async def download_file( session: aiohttp.ClientSession, url: str, dest_path: str ) -> None: try: - async with session.get(url, timeout=aiohttp.ClientTimeout(total=30)) as resp: + async with session.get( + url, timeout=aiohttp.ClientTimeout(total=30) + ) as resp: if resp.status != 200: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, @@ -266,15 +268,18 @@ async def execute_code(request: ExecutionRequest) -> ExecutionResponse: result_hash = hashlib.sha256(output.encode()).hexdigest() - return ExecutionResponse( + response = ExecutionResponse( success=success, hash_match=( - result_hash == request.expected_hash if request.expected_hash else None + result_hash == request.expected_hash + if request.expected_hash + else None ), output=output[:5000], result_hash=result_hash, error=error[:5000], ) + return response @app.get("/health", response_model=HealthCheckResponse) From d853a01053976a5b73dc3e37319e5dc67e1a0f23 Mon Sep 17 00:00:00 2001 From: ITQ Date: Mon, 3 Mar 2025 19:22:24 +0000 Subject: [PATCH 5/9] Update file README.md --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 3659497..4a18e94 100644 --- a/README.md +++ b/README.md @@ -5,21 +5,21 @@ ## Запуск -Склонируйте репозиторий и пропишите +Склонируйте репозиторий и пропишите. ```bash docker compose up ``` -## Основные ручки +## Важные эндпоинты -* `/` - основное приложение +* `/` - интерфейс * `/api/v1/docs` - swagger-ui документация -* `/admin` - админка +* `/admin/` - админка * `/admin/grafana` - графана -* `/docs` - гайд по анализу данных +* `/docs` - обучающие материалы по анализу данных -После запуска по методу выше создается пользователь в админке (`/admin`) с данными ниже:`admin` +После запуска по методу выше создается пользователь в админке (`/admin/`) с данными ниже:`admin` - `admin` - логин - `proooooood` - пароль From 2b73dde85f5faa39b4ecdf8b64f82dbb67150558 Mon Sep 17 00:00:00 2001 From: ITQ Date: Mon, 3 Mar 2025 22:30:54 +0300 Subject: [PATCH 6/9] (scope): [body] [footer(s)] --- services/checker/main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/services/checker/main.py b/services/checker/main.py index 8fea2e8..a4a0381 100644 --- a/services/checker/main.py +++ b/services/checker/main.py @@ -279,6 +279,7 @@ async def execute_code(request: ExecutionRequest) -> ExecutionResponse: result_hash=result_hash, error=error[:5000], ) + print(response) return response From 87b73e804b4e828a7fdf4aa8214864183332c417 Mon Sep 17 00:00:00 2001 From: ITQ Date: Mon, 3 Mar 2025 22:41:12 +0300 Subject: [PATCH 7/9] (scope): [body] [footer(s)] --- services/checker/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/checker/main.py b/services/checker/main.py index a4a0381..e77f7f5 100644 --- a/services/checker/main.py +++ b/services/checker/main.py @@ -279,7 +279,7 @@ async def execute_code(request: ExecutionRequest) -> ExecutionResponse: result_hash=result_hash, error=error[:5000], ) - print(response) + print(response.model_dump_json()) return response From 43b89acb461536f3e7481d3d643967f5e4938f03 Mon Sep 17 00:00:00 2001 From: ITQ Date: Mon, 3 Mar 2025 22:58:19 +0300 Subject: [PATCH 8/9] (scope): [body] [footer(s)] --- services/backend/apps/task/tasks.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/backend/apps/task/tasks.py b/services/backend/apps/task/tasks.py index 568602a..b217cce 100644 --- a/services/backend/apps/task/tasks.py +++ b/services/backend/apps/task/tasks.py @@ -15,7 +15,6 @@ def analyze_data_task(self, submission_id): submission = CompetitionTaskSubmission.objects.get(id=submission_id) try: code = submission.content.read() - print("YA SSF") files = [ { "url": ( @@ -43,7 +42,7 @@ def analyze_data_task(self, submission_id): ) response.raise_for_status() result = response.json() - print("HOHOHO") + print(result, response.request) submission.stdout.save("output.txt", ContentFile(result["output"])) submission.result = { @@ -59,6 +58,7 @@ def analyze_data_task(self, submission_id): except httpx.RequestError: self.retry(countdown=2**self.request.retries) except Exception as e: + print(e) submission.result = {"error": str(e), "success": False} submission.status = CompetitionTaskSubmission.StatusChoices.CHECKED submission.earned_points = 0 From 40f65e5e553ca2499ff70bdd293be7861427d6d3 Mon Sep 17 00:00:00 2001 From: Timur Date: Mon, 3 Mar 2025 23:12:57 +0300 Subject: [PATCH 9/9] make checker simplier --- services/backend/apps/task/models.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/services/backend/apps/task/models.py b/services/backend/apps/task/models.py index ffb3c08..435f5b3 100644 --- a/services/backend/apps/task/models.py +++ b/services/backend/apps/task/models.py @@ -82,20 +82,20 @@ class CompetitionTask(BaseModel): def clean(self): super().clean() - if self.correct_answer_file and self.type not in ["checker", "input"]: - raise ValidationError({ - "type": "Если загружен файл правильного ответа, то тип проверки не может быть ручным" - }) - elif not self.correct_answer_file and self.type == "review": + # if self.correct_answer_file and self.type not in ["checker", "input"]: + # raise ValidationError({ + # "type": "Если загружен файл правильного ответа, то тип проверки не может быть ручным" + # }) + if not self.correct_answer_file and self.type != "review": raise ValidationError({ "correct_answer_file": "Загрузите правильный ответ" }) - if self.answer_file_path and not self.type == "checker": - raise ValidationError({ - "type": "Укажите другой тип задания: этот не совместим с путем правильного ответа" - }) - elif not self.answer_file_path and self.type == "checker": + # if self.answer_file_path and not self.type == "checker": + # raise ValidationError({ + # "type": "Укажите другой тип задания: этот не совместим с путем правильного ответа" + # }) + if not self.answer_file_path and self.type == "checker": raise ValidationError({ "answer_file_path": "Введите путь правильного ответа - это нужно для корректной работы чекера" }) @@ -104,10 +104,10 @@ class CompetitionTask(BaseModel): raise ValidationError({ "reviewers": "Загрузите ревьюверов - кто будет проверять задания, если не они?" }) - elif self.reviewers and not self.type == "review": - raise ValidationError({ - "type": "Проверьте тип - вы ввели ревьюверов, но задание не является ручным" - }) + # elif self.reviewers and not self.type == "review": + # raise ValidationError({ + # "type": "Проверьте тип - вы ввели ревьюверов, но задание не является ручным" + # }) def __str__(self):