From 654fe90c100b6453a8448e37e1a6127f44771461 Mon Sep 17 00:00:00 2001 From: Anton Laktionov Date: Mon, 15 Jun 2026 14:18:53 +0300 Subject: [PATCH] init commit --- .gitignore | 55 ++++++ check_problem/__init__.py | 0 check_problem/admin.py | 3 + check_problem/apps.py | 6 + check_problem/forms.py | 5 + check_problem/migrations/0001_initial.py | 21 ++ .../migrations/0002_alter_resolvs_image.py | 18 ++ ...resolvs_image_resolvs_datetime_and_more.py | 61 ++++++ ..._resolvs_datetime_alter_resolvs_srcfile.py | 23 +++ ...ge_resolvs_status_alter_resolvs_srcfile.py | 29 +++ .../0006_resolvs_codelen_resolvs_time.py | 23 +++ check_problem/migrations/__init__.py | 0 check_problem/models.py | 35 ++++ check_problem/templates/details.html | 25 +++ check_problem/templates/index.html | 104 ++++++++++ check_problem/templates/login.html | 37 ++++ check_problem/templates/register.html | 42 ++++ check_problem/tests.py | 3 + check_problem/views.py | 185 ++++++++++++++++++ manage.py | 22 +++ olimp/__init__.py | 0 olimp/asgi.py | 16 ++ olimp/settings.py | 128 ++++++++++++ olimp/urls.py | 30 +++ olimp/wsgi.py | 16 ++ tests.py | 67 +++++++ 26 files changed, 954 insertions(+) create mode 100644 .gitignore create mode 100644 check_problem/__init__.py create mode 100644 check_problem/admin.py create mode 100644 check_problem/apps.py create mode 100644 check_problem/forms.py create mode 100644 check_problem/migrations/0001_initial.py create mode 100644 check_problem/migrations/0002_alter_resolvs_image.py create mode 100644 check_problem/migrations/0003_problems_remove_resolvs_image_resolvs_datetime_and_more.py create mode 100644 check_problem/migrations/0004_alter_resolvs_datetime_alter_resolvs_srcfile.py create mode 100644 check_problem/migrations/0005_resolvs_message_resolvs_status_alter_resolvs_srcfile.py create mode 100644 check_problem/migrations/0006_resolvs_codelen_resolvs_time.py create mode 100644 check_problem/migrations/__init__.py create mode 100644 check_problem/models.py create mode 100644 check_problem/templates/details.html create mode 100644 check_problem/templates/index.html create mode 100644 check_problem/templates/login.html create mode 100644 check_problem/templates/register.html create mode 100644 check_problem/tests.py create mode 100644 check_problem/views.py create mode 100644 manage.py create mode 100644 olimp/__init__.py create mode 100644 olimp/asgi.py create mode 100644 olimp/settings.py create mode 100644 olimp/urls.py create mode 100644 olimp/wsgi.py create mode 100644 tests.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bc59f06 --- /dev/null +++ b/.gitignore @@ -0,0 +1,55 @@ +# Python bytecode and cache +__pycache__/ +*.py[cod] +*$py.class + +# Virtual environments +venv/ +.venv/ +env/ +.env-env/ +ENV/ + +# Django local settings & secrets +*.env +.env +db.sqlite3 +db.sqlite3-journal +local_settings.py + +# Django media & static deployment folders +media/ +staticfiles/ +static-cdn/ + +# Logs +*.log +logs/ + +# Testing & coverage +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# OS-specific files +.DS_Store +Thumbs.db + +# IDEs & Editors +.vscode/ +.idea/ +*.suo +*.ntvs* +*.njsproj +*.sln +*.swp + +#temp +temp/ \ No newline at end of file diff --git a/check_problem/__init__.py b/check_problem/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/check_problem/admin.py b/check_problem/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/check_problem/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/check_problem/apps.py b/check_problem/apps.py new file mode 100644 index 0000000..c6294a1 --- /dev/null +++ b/check_problem/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class CheckProblemConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'check_problem' diff --git a/check_problem/forms.py b/check_problem/forms.py new file mode 100644 index 0000000..9eba8a2 --- /dev/null +++ b/check_problem/forms.py @@ -0,0 +1,5 @@ +from django import forms + +class UploadFileForm(forms.Form): + title = forms.CharField(max_length=50) + newfile = forms.FileField() \ No newline at end of file diff --git a/check_problem/migrations/0001_initial.py b/check_problem/migrations/0001_initial.py new file mode 100644 index 0000000..41ed31c --- /dev/null +++ b/check_problem/migrations/0001_initial.py @@ -0,0 +1,21 @@ +# Generated by Django 5.1.2 on 2024-12-17 14:35 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Resolvs', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('image', models.ImageField(upload_to='static/images/')), + ], + ), + ] diff --git a/check_problem/migrations/0002_alter_resolvs_image.py b/check_problem/migrations/0002_alter_resolvs_image.py new file mode 100644 index 0000000..1e53762 --- /dev/null +++ b/check_problem/migrations/0002_alter_resolvs_image.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.2 on 2024-12-17 14:40 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('check_problem', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='resolvs', + name='image', + field=models.FileField(upload_to='media/images/'), + ), + ] diff --git a/check_problem/migrations/0003_problems_remove_resolvs_image_resolvs_datetime_and_more.py b/check_problem/migrations/0003_problems_remove_resolvs_image_resolvs_datetime_and_more.py new file mode 100644 index 0000000..c165e3c --- /dev/null +++ b/check_problem/migrations/0003_problems_remove_resolvs_image_resolvs_datetime_and_more.py @@ -0,0 +1,61 @@ +# Generated by Django 5.1.2 on 2024-12-17 17:26 + +import datetime +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('check_problem', '0002_alter_resolvs_image'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Problems', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('Name', models.CharField(max_length=100)), + ('Description', models.CharField(max_length=1000)), + ('Image', models.FileField(default='images/blank.png', upload_to='images/')), + ('Price', models.IntegerField(default=1)), + ('TimeLimit', models.IntegerField(default=1)), + ], + ), + migrations.RemoveField( + model_name='resolvs', + name='image', + ), + migrations.AddField( + model_name='resolvs', + name='DateTime', + field=models.DateField(default=datetime.datetime(2024, 12, 17, 17, 26, 46, 327422, tzinfo=datetime.timezone.utc)), + ), + migrations.AddField( + model_name='resolvs', + name='SrcFile', + field=models.FileField(default=None, upload_to='Resolvs/'), + ), + migrations.AddField( + model_name='resolvs', + name='User', + field=models.ForeignKey(default=None, on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='resolvs', + name='Problem', + field=models.ForeignKey(default=None, on_delete=django.db.models.deletion.PROTECT, to='check_problem.problems'), + ), + migrations.CreateModel( + name='Tests', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('Input', models.CharField(max_length=1000)), + ('Output', models.CharField(max_length=1000)), + ('Problem', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='check_problem.problems')), + ], + ), + ] diff --git a/check_problem/migrations/0004_alter_resolvs_datetime_alter_resolvs_srcfile.py b/check_problem/migrations/0004_alter_resolvs_datetime_alter_resolvs_srcfile.py new file mode 100644 index 0000000..7f73607 --- /dev/null +++ b/check_problem/migrations/0004_alter_resolvs_datetime_alter_resolvs_srcfile.py @@ -0,0 +1,23 @@ +# Generated by Django 5.1.2 on 2024-12-17 18:15 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('check_problem', '0003_problems_remove_resolvs_image_resolvs_datetime_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='resolvs', + name='DateTime', + field=models.DateTimeField(auto_now_add=True), + ), + migrations.AlterField( + model_name='resolvs', + name='SrcFile', + field=models.FileField(default=None, upload_to='resolvs/'), + ), + ] diff --git a/check_problem/migrations/0005_resolvs_message_resolvs_status_alter_resolvs_srcfile.py b/check_problem/migrations/0005_resolvs_message_resolvs_status_alter_resolvs_srcfile.py new file mode 100644 index 0000000..d128ad0 --- /dev/null +++ b/check_problem/migrations/0005_resolvs_message_resolvs_status_alter_resolvs_srcfile.py @@ -0,0 +1,29 @@ +# Generated by Django 5.1.2 on 2024-12-19 17:00 + +import check_problem.models +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('check_problem', '0004_alter_resolvs_datetime_alter_resolvs_srcfile'), + ] + + operations = [ + migrations.AddField( + model_name='resolvs', + name='Message', + field=models.CharField(default='', max_length=100), + ), + migrations.AddField( + model_name='resolvs', + name='Status', + field=models.IntegerField(default=0), + ), + migrations.AlterField( + model_name='resolvs', + name='SrcFile', + field=models.FileField(default=None, upload_to=check_problem.models.upload_path), + ), + ] diff --git a/check_problem/migrations/0006_resolvs_codelen_resolvs_time.py b/check_problem/migrations/0006_resolvs_codelen_resolvs_time.py new file mode 100644 index 0000000..dfc4afd --- /dev/null +++ b/check_problem/migrations/0006_resolvs_codelen_resolvs_time.py @@ -0,0 +1,23 @@ +# Generated by Django 5.1.4 on 2025-01-03 05:31 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('check_problem', '0005_resolvs_message_resolvs_status_alter_resolvs_srcfile'), + ] + + operations = [ + migrations.AddField( + model_name='resolvs', + name='CodeLen', + field=models.IntegerField(default=0), + ), + migrations.AddField( + model_name='resolvs', + name='Time', + field=models.IntegerField(default=0), + ), + ] diff --git a/check_problem/migrations/__init__.py b/check_problem/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/check_problem/models.py b/check_problem/models.py new file mode 100644 index 0000000..4030e7f --- /dev/null +++ b/check_problem/models.py @@ -0,0 +1,35 @@ +from django.db import models +from django.contrib.auth.models import User +from django.utils import timezone +import os + +class Problems(models.Model): + Name = models.CharField(max_length=100) + Description = models.CharField(max_length=1000) + Image = models.FileField(upload_to='images/',default='images/blank.png') + Price = models.IntegerField(default=1) + TimeLimit = models.IntegerField(default=1) + +def upload_path(self,filename): + if self.User and self.Problem: + file_ext =filename[filename.rindex('.')+1:] + return f"resolvs/{self.User.id}/{self.Problem.id}.{file_ext}" + else: + return f"resolvs/{filename}" + +class Resolvs(models.Model): + SrcFile = models.FileField(upload_to=upload_path, default=None) + User = models.ForeignKey(User, on_delete=models.PROTECT, default=None) + DateTime = models.DateTimeField(auto_now_add=True) + Problem = models.ForeignKey(Problems, on_delete=models.PROTECT, default=None) + Status = models.IntegerField(default=0) + Message = models.CharField(max_length=100,default="") + Time = models.IntegerField(default=0) + CodeLen = models.IntegerField(default=0) + def filename(self): + return self.SrcFile.name + +class Tests(models.Model): + Problem = models.ForeignKey(Problems, on_delete=models.PROTECT) + Input = models.CharField(max_length=1000) + Output = models.CharField(max_length=1000) \ No newline at end of file diff --git a/check_problem/templates/details.html b/check_problem/templates/details.html new file mode 100644 index 0000000..cac21ef --- /dev/null +++ b/check_problem/templates/details.html @@ -0,0 +1,25 @@ + + + + + Document + + + + {{ user.username }} Выход на главную + + {% for r in resolvs %} + + + + {% endfor %} +
{{u_list|dict_key:r}}{{ext|dict_key:r}}
+ + \ No newline at end of file diff --git a/check_problem/templates/index.html b/check_problem/templates/index.html new file mode 100644 index 0000000..31ed03c --- /dev/null +++ b/check_problem/templates/index.html @@ -0,0 +1,104 @@ + + + + + Tavres: Решение задач + + + + + + + + +
+
+ {% for p in problems %} +
+

+ +

+
+
+ подробнее + {% autoescape off %} +

{{ p.Description }}

+ {% endautoescape %} + + + {% if resolved|dict_key:p.id == 1 %} +

Задача успешно решена

+

Скачать решение

+ +

{{ message|dict_key:p.id }}

+ {% else %} +
+ {% csrf_token %} + + + +
+ {% endif %} +
+
+
+ {% endfor %} +
+
+ + \ No newline at end of file diff --git a/check_problem/templates/login.html b/check_problem/templates/login.html new file mode 100644 index 0000000..ac1ea85 --- /dev/null +++ b/check_problem/templates/login.html @@ -0,0 +1,37 @@ + + + + + Tavres:Login user + + + + + + + \ No newline at end of file diff --git a/check_problem/templates/register.html b/check_problem/templates/register.html new file mode 100644 index 0000000..0334d4a --- /dev/null +++ b/check_problem/templates/register.html @@ -0,0 +1,42 @@ + + + + + + + Tavres + + + + + + \ No newline at end of file diff --git a/check_problem/tests.py b/check_problem/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/check_problem/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/check_problem/views.py b/check_problem/views.py new file mode 100644 index 0000000..bb12dd2 --- /dev/null +++ b/check_problem/views.py @@ -0,0 +1,185 @@ +from django.shortcuts import render +from django.http import HttpResponse, HttpResponseRedirect +from django.contrib.auth import authenticate, login, logout +from django.template.defaultfilters import register +from .forms import UploadFileForm +from .models import * +import os +from subprocess import Popen, PIPE, STDOUT, call +import shutil +from django.conf import settings +import time + +@register.filter(name='dict_key') +def dict_key(d, k): + return d[k] + +def Index(request): + if request.user.is_authenticated: + user = User.objects.get(id = request.user.id) + else: + return HttpResponseRedirect('login/') + + if request.method == 'POST': + p_id = request.POST.get('problem') + problem = Problems.objects.get(id=p_id) + resolved = Resolvs.objects.filter(Problem=problem, Status=1, User=user).last() + if not problem or resolved: + return HttpResponseRedirect('/') + + file = Resolvs( + SrcFile = request.FILES['resolve'], + User = user, + Problem = problem, + ) + file.save() + file_ext =file.SrcFile.path[file.SrcFile.path.rindex('.')+1:] + if file_ext in ['py','cpp']: + #Запускаю проверку решения на корректность + tests = Tests.objects.filter(Problem=problem) + rt_dir = os.path.join(settings.TEMP_DIR,str(user.id)) + if not os.path.exists(rt_dir): + os.mkdir(rt_dir) + shutil.copy(file.SrcFile.path, rt_dir+'/resolv.'+file_ext) + status = 1 + message = '' + dt = 0 + test_num = 0 + for t in tests: + test_num += 1 + stdout_data = '' + stderr_data = '' + + with open(rt_dir+'/INPUT.TXT','w') as f: + f.write(t.Input) + #Запускаем отдельный процесс для проверки задачи + try: + startt = time.time() + if file_ext == 'py': + proc = Popen(['python',f'{rt_dir}\\resolv.py'], stdout=PIPE, stdin=PIPE, stderr=PIPE, text=True) + print(t.Input,f'{rt_dir}\\resolv.py') + stdout_data, stderr_data = proc.communicate(input=t.Input, timeout=20) + print(stdout_data, stderr_data) + elif file_ext == 'cpp': + if test_num == 1: + proc = call(f"g++ {rt_dir}/resolv.cpp", + cwd=rt_dir, + timeout=20, + shell=True) + proc = call(f"{rt_dir}/a.out", + cwd=rt_dir, + timeout=problem.TimeLimit, + shell=True) + endt = time.time() + tm = endt - startt + dt = tm if dt < tm else dt + except Exception as e: + print(e) + status = 3 + message = f"Выбили по таймауту" + break + #Проверяем корректность решения + if os.path.exists(rt_dir+'/OUTPUT.TXT'): + with open(rt_dir+'/OUTPUT.TXT','r') as f: + st = f.read() + if st != t.Output: + status = 3 + message=f'Решение не верно. Тест {test_num}.' + break + else: + if stdout_data.strip() != t.Output: + status = 3 + message=f'Решение не верно. Тест {test_num}.' + break + else: + status = 9 + message = "Неизвесный формат файла" + + #Записываем результат в БД + file.Status = status + file.Message = message + file.Time = dt + file.save() + + problems = Problems.objects.all() + dr = {} + dmessage = {} + link = {} + for p in problems: + resolv = Resolvs.objects.filter(User=user, Problem=p).last() + if resolv: + if resolv.Status == 1: + dr[p.id] = 1 + dmessage[p.id] = '' + link[p.id] = resolv.SrcFile.url + else: + dr[p.id] = 0 + dmessage[p.id] = resolv.Message + else: + dr[p.id] = 0 + dmessage[p.id] = '' + return render(request,'index.html',{'problems':problems, + 'user':user, + 'resolved':dr, + 'message':dmessage, + 'link':link,}) +def Details(request,p_id): + if request.user.is_authenticated: + user = User.objects.get(id = request.user.id) + else: + return HttpResponseRedirect('login/') + problem = Problems.objects.get(id=p_id) + resolvs = Resolvs.objects.filter(Problem=problem, Status=1) + res = [] + usrs = {} + ext = {} + for r in resolvs: + res.append(r.id) + usrs[r.id] = r.User.username + ext[r.id] = os.path.splitext(r.SrcFile.name)[1][1:].upper() + return render(request,'details.html',{ + 'problem':problem, + 'user':user, + 'resolvs':res, + 'u_list':usrs, + 'ext':ext, + }) + + +def Login(request): + if request.method == 'POST': + username = request.POST.get('login') + pwd = request.POST.get('password') + user = authenticate(request,username=username, password=pwd) + if user is not None: + login(request, user) + request.session['username'] = username + request.session.save() + return HttpResponseRedirect('/') + return render(request, 'login.html') + +def Logout(request): + logout(request) + return HttpResponseRedirect('/') + +def Registration(request): + if request.method == 'POST': + name = request.POST.get('name') + pwd = request.POST.get('password') + email = request.POST.get('email') + user = User.objects.filter(username = name).first() + if user: + print('Имя занято') + return render(request,'register.html') + user = User.objects.filter(email = email).first() + if user: + print('Email уже есть') + return render(request,'register.html') + user = User.objects.create_user( + name, + email, + pwd, + is_staff = True + ) + return HttpResponseRedirect('/') + return render(request,'register.html') diff --git a/manage.py b/manage.py new file mode 100644 index 0000000..17710bd --- /dev/null +++ b/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + """Run administrative tasks.""" + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'olimp.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == '__main__': + main() diff --git a/olimp/__init__.py b/olimp/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/olimp/asgi.py b/olimp/asgi.py new file mode 100644 index 0000000..5c3548a --- /dev/null +++ b/olimp/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for olimp project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/5.1/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'olimp.settings') + +application = get_asgi_application() diff --git a/olimp/settings.py b/olimp/settings.py new file mode 100644 index 0000000..d3f81fc --- /dev/null +++ b/olimp/settings.py @@ -0,0 +1,128 @@ +""" +Django settings for olimp project. + +Generated by 'django-admin startproject' using Django 5.1.2. + +For more information on this file, see +https://docs.djangoproject.com/en/5.1/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/5.1/ref/settings/ +""" + +from pathlib import Path +import os + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + +MEDIA_URL = '/media/' +MEDIA_ROOT = os.path.join(BASE_DIR, 'media') +TEMP_DIR = os.path.join(BASE_DIR,'temp') + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'django-insecure-o2mr5%=d062g(f2&4$8mm(f4@)qm#&&6do6i7ubhp#%)10x&le' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = ['tavres.ru','127.0.0.1','localhost'] + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'check_problem', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'olimp.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'olimp.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/5.1/ref/settings/#databases + +DATABASES = { + "default": { + "ENGINE": "django.db.backends.sqlite3", + "NAME": BASE_DIR / "db.sqlite3", + } +} + + +# Password validation +# https://docs.djangoproject.com/en/5.1/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/5.1/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/5.1/howto/static-files/ + +STATIC_URL = 'static/' + +# Default primary key field type +# https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' diff --git a/olimp/urls.py b/olimp/urls.py new file mode 100644 index 0000000..9ef6c95 --- /dev/null +++ b/olimp/urls.py @@ -0,0 +1,30 @@ +""" +URL configuration for olimp project. + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/5.1/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.contrib import admin +from django.urls import path +from django.conf.urls.static import static +from django.conf import settings +from check_problem.views import * + +urlpatterns = [ + path('admin/', admin.site.urls), + path('',Index), + path('pm//',Details), + path('login/',Login), + path('logout/',Logout), + path('registration/',Registration), +] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/olimp/wsgi.py b/olimp/wsgi.py new file mode 100644 index 0000000..afe48df --- /dev/null +++ b/olimp/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for olimp project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/5.1/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'olimp.settings') + +application = get_wsgi_application() diff --git a/tests.py b/tests.py new file mode 100644 index 0000000..0f39aaf --- /dev/null +++ b/tests.py @@ -0,0 +1,67 @@ +import sqlite3 +from pathlib import Path +import os +import shutil +import subprocess + +ROOT_DIR = Path(__file__).resolve().parent +MEDIA_DIR = os.path.join(ROOT_DIR,'media') +TEMP_DIR = os.path.join(ROOT_DIR,'temp') + +con = sqlite3.connect("db.sqlite3") +cur = con.cursor() +k=0 +while k<3: + k+=1 + res = cur.execute('''SELECT id,Problem_id,SrcFile + FROM check_problem_resolvs + WHERE Status='0';''') + res = res.fetchone() + if not res: + break + id = res[0] + p_id = res[1] + file_path = os.path.join(MEDIA_DIR,res[2]) + file_ext =file_path[file_path.rindex('.')+1:] + if file_ext == 'py': + rt_dir = os.path.join(TEMP_DIR,str(id)) + if not os.path.exists(rt_dir): + os.mkdir(rt_dir) + shutil.copy(file_path, rt_dir+'\\resolv.py') + res = cur.execute(f'''SELECT id,Input,Output + FROM check_problem_tests + WHERE Problem_id={p_id}''') + rows = res.fetchall() + status = 2 + message='Все хорошо' + for row in rows: + with open(rt_dir+'\\INPUT.TXT','w') as f: + f.write(row[1]) + try: + proc = subprocess.call(f"python {rt_dir}\\resolv.py", + cwd=rt_dir, + timeout=5) + except: + status = 3 + message = "Выбили по таймауту" + break + if os.path.exists(rt_dir+'\\OUTPUT.TXT'): + with open(rt_dir+'\\OUTPUT.TXT','r') as f: + if f.read() != row[2]: + status = 3 + message='Решение не верно' + break + else: + status = 3 + message = "Нет выходного файла" + break + cur.execute(f'''UPDATE check_problem_resolvs + SET Status='{status}', Message='{message}' + WHERE id='{id}';''') + con.commit() + else: + cur.execute(f'''UPDATE check_problem_resolvs + SET Status='9' + WHERE id='{id}';''') + con.commit() +con.close()