From d45b5e9115e2dd2a7f9fef3525eb807b978cb81d Mon Sep 17 00:00:00 2001 From: Egor Matveev Date: Fri, 18 Mar 2022 22:43:13 +0300 Subject: [PATCH] move --- Main/views/CheckersView.py | 13 ++----- Main/views/DownloadFileView.py | 11 +++--- Main/views/GroupView.py | 28 ++++++++------- Main/views/SetSettingsView.py | 60 +++++++++++++++----------------- Main/views/SetView.py | 14 ++++---- Main/views/SolutionView.py | 4 ++- Main/views/SolutionsTableView.py | 13 ++++--- Main/views/TaskRuntimeView.py | 5 +-- Main/views/TaskSettingsView.py | 45 ++++++++++++------------ Main/views/TaskView.py | 34 ++++++++++-------- SprintLib/BaseView.py | 12 +++---- SprintLib/EntityStorage.py | 9 ----- templates/tasks.html | 1 + 13 files changed, 124 insertions(+), 125 deletions(-) delete mode 100644 SprintLib/EntityStorage.py diff --git a/Main/views/CheckersView.py b/Main/views/CheckersView.py index 59f8b7d..18a2de0 100644 --- a/Main/views/CheckersView.py +++ b/Main/views/CheckersView.py @@ -1,22 +1,15 @@ -import datetime -from typing import Optional - -import pytz -from django.utils import timezone - -from Checker.models import Checker -from Main.models import SetTask, Set +from Main.models import Set from SprintLib.BaseView import BaseView, AccessError -from SprintLib.language import languages class CheckersView(BaseView): required_login = True view_file = "checkers.html" endpoint = "admin/checkers" + set: Set def pre_handle(self): - self.current_set = self.entities.set + self.current_set = self.set if ( self.request.user != self.current_set.creator and self.request.user.username not in self.current_set.editors diff --git a/Main/views/DownloadFileView.py b/Main/views/DownloadFileView.py index 2f1ef85..957a397 100644 --- a/Main/views/DownloadFileView.py +++ b/Main/views/DownloadFileView.py @@ -1,5 +1,6 @@ from django.http import HttpResponse +from Main.models import Dump from SprintLib.BaseView import BaseView, AccessError from SprintLib.utils import get_bytes @@ -7,14 +8,14 @@ from SprintLib.utils import get_bytes class DownloadFileView(BaseView): endpoint = "download_file" required_login = True + dump: Dump def get(self): - dump = self.entities.dump - if dump.task: - if self.request.user == dump.task.creator or self.request.user.username in dump.task.editors: + if self.dump.task: + if self.request.user == self.dump.task.creator or self.request.user.username in self.dump.task.editors: response = HttpResponse( - get_bytes(dump.fs_id), content_type='application/force-download' + get_bytes(self.dump.fs_id), content_type='application/force-download' ) - response['Content-Disposition'] = f'inline; filename={dump.filename}' + response['Content-Disposition'] = f'inline; filename={self.dump.filename}' return response raise AccessError() diff --git a/Main/views/GroupView.py b/Main/views/GroupView.py index 854846d..f54af58 100644 --- a/Main/views/GroupView.py +++ b/Main/views/GroupView.py @@ -1,5 +1,6 @@ from django.contrib.auth.models import User +from Main.models import Group from SprintLib.BaseView import BaseView, AccessError from SprintLib.utils import generate_token @@ -9,50 +10,51 @@ class GroupView(BaseView): endpoint = 'group' view_file = 'group.html' owner = False + group: Group def pre_handle(self): - self.owner = self.entities.group.creator == self.request.user or self.request.user.username in self.entities.group.editors + self.owner = self.group.creator == self.request.user or self.request.user.username in self.group.editors def get(self): if self.owner: - self.context['possible_users'] = set(self.entities.group.users.all()) | set(self.request.user.userinfo.verified_friends) + self.context['possible_users'] = set(self.group.users.all()) | set(self.request.user.userinfo.verified_friends) def post_sets_edit(self): if not self.owner: raise AccessError() - current_sets = self.entities.group.sets.all() + current_sets = self.group.sets.all() set_ids = [set.id for set in current_sets] for key, value in self.request.POST.items(): if key.startswith("set_"): i = int(key.split("_")[1]) if i not in set_ids: - self.entities.group.sets.add(i) + self.group.sets.add(i) to_delete = [i for i in set_ids if "set_" + str(i) not in self.request.POST] for t in to_delete: - self.entities.group.sets.remove(t) - return "/group?group_id=" + str(self.entities.group.id) + self.group.sets.remove(t) + return "/group?group_id=" + str(self.group.id) def post_users_edit(self): if not self.owner: raise AccessError() - current_users = self.entities.group.users.all() + current_users = self.group.users.all() users_ids = [user.id for user in current_users] for key, value in self.request.POST.items(): if key.startswith("user_"): i = int(key.split("_")[1]) if i not in users_ids: - self.entities.group.users.add(i) + self.group.users.add(i) to_delete = [i for i in users_ids if "user_" + str(i) not in self.request.POST] for t in to_delete: - self.entities.group.users.remove(t) - return "/group?group_id=" + str(self.entities.group.id) + self.group.users.remove(t) + return "/group?group_id=" + str(self.group.id) def link_action(self, value): if not self.owner: raise AccessError() - self.entities.group.access_token = value - self.entities.group.save() - return "/group?group_id=" + str(self.entities.group.id) + self.group.access_token = value + self.group.save() + return "/group?group_id=" + str(self.group.id) def post_open_link(self): return self.link_action(generate_token()) diff --git a/Main/views/SetSettingsView.py b/Main/views/SetSettingsView.py index d7010e0..0e2c8ec 100644 --- a/Main/views/SetSettingsView.py +++ b/Main/views/SetSettingsView.py @@ -1,5 +1,4 @@ import datetime -from typing import Optional import pytz from django.utils import timezone @@ -14,28 +13,27 @@ class SetSettingsView(BaseView): required_login = True view_file = "set_settings.html" endpoint = "admin/set" - current_set: Optional[Set] = None + set: Set def pre_handle(self): - self.current_set = self.entities.set if ( - self.request.user != self.current_set.creator - and self.request.user.username not in self.current_set.editors + self.request.user != self.set.creator + and self.request.user.username not in self.set.editors ): raise AccessError() def get(self): self.context["settasks"] = SetTask.objects.filter( - set=self.current_set + set=self.set ).order_by("name") self.context["start_time"] = ( - self.current_set.start_time_format - if self.current_set.start_time + self.set.start_time_format + if self.set.start_time else timezone.now().strftime("%Y-%m-%dT%H:%M") ) self.context["end_time"] = ( - self.current_set.end_time_format - if self.current_set.end_time + self.set.end_time_format + if self.set.end_time else timezone.now().strftime("%Y-%m-%dT%H:%M") ) self.context['languages'] = languages @@ -46,61 +44,61 @@ class SetSettingsView(BaseView): st = SetTask.objects.get(id=key.split("_")[1]) st.name = value st.save() - self.current_set.name = self.request.POST["name"] - self.current_set.description = self.request.POST['description'] - self.current_set.save() - return "/admin/set?set_id=" + str(self.current_set.id) + self.set.name = self.request.POST["name"] + self.set.description = self.request.POST['description'] + self.set.save() + return "/admin/set?set_id=" + str(self.set.id) def post_edit(self): - current_tasks = self.entities.set.tasks + current_tasks = self.set.tasks task_ids = [task.id for task in current_tasks] for key, value in self.request.POST.items(): if key.startswith("task_"): i = int(key.split("_")[1]) if i not in task_ids: - SetTask.objects.create(set=self.entities.set, task_id=i) + SetTask.objects.create(set=self.set, task_id=i) to_delete = [i for i in task_ids if "task_" + str(i) not in self.request.POST] SetTask.objects.filter(task_id__in=to_delete).delete() - return "/admin/set?set_id=" + str(self.entities.set.id) + return "/admin/set?set_id=" + str(self.set.id) def post_time(self): try: tz = pytz.timezone("Europe/Moscow") if "start_time_check" in self.request.POST: - self.current_set.start_time = None + self.set.start_time = None else: - self.current_set.start_time = tz.localize( + self.set.start_time = tz.localize( datetime.datetime.strptime( self.request.POST["start_time"], "%Y-%m-%dT%H:%M" ) ) if "end_time_check" in self.request.POST: - self.current_set.end_time = None + self.set.end_time = None else: - self.current_set.end_time = tz.localize( + self.set.end_time = tz.localize( datetime.datetime.strptime( self.request.POST["end_time"], "%Y-%m-%dT%H:%M" ) ) - self.current_set.opened = 'opened' in self.request.POST.keys() - self.current_set.public = 'public' in self.request.POST.keys() + self.set.opened = 'opened' in self.request.POST.keys() + self.set.public = 'public' in self.request.POST.keys() except ValueError: - return "/admin/set?set_id=" + str(self.current_set.id) - self.current_set.save() - return "/admin/set?set_id=" + str(self.current_set.id) + return "/admin/set?set_id=" + str(self.set.id) + self.set.save() + return "/admin/set?set_id=" + str(self.set.id) def post_users_edit(self): - current_users = self.entities.set.editors + current_users = self.set.editors for key, value in self.request.POST.items(): if key.startswith("user_"): i = '_'.join(key.split("_")[1:]) if i not in current_users: - self.entities.set.editors.append(i) + self.set.editors.append(i) to_delete = [i for i in current_users if "user_" + i not in self.request.POST and i != self.request.user.username] for t in to_delete: - self.entities.set.editors.remove(t) - self.entities.set.save() - return "/admin/set?set_id=" + str(self.entities.set.id) + self.set.editors.remove(t) + self.set.save() + return "/admin/set?set_id=" + str(self.set.id) def post_languages_edit(self): current_languages = self.entities.set.languages diff --git a/Main/views/SetView.py b/Main/views/SetView.py index a89684e..948af17 100644 --- a/Main/views/SetView.py +++ b/Main/views/SetView.py @@ -1,5 +1,6 @@ from django.utils import timezone +from Main.models import Set from SprintLib.BaseView import BaseView, AccessError @@ -7,15 +8,16 @@ class SetView(BaseView): required_login = True endpoint = "set" view_file = "set.html" + set: Set def get(self): - if self.entities.set in self.request.user.userinfo.available_sets: + if self.set in self.request.user.userinfo.available_sets: return if ( - not self.entities.set.opened - or self.entities.set.start_time is not None - and self.entities.set.start_time > timezone.now() - or self.entities.set.end_time is not None - and self.entities.set.end_time < timezone.now() + not self.set.opened + or self.set.start_time is not None + and self.set.start_time > timezone.now() + or self.set.end_time is not None + and self.set.end_time < timezone.now() ): raise AccessError() diff --git a/Main/views/SolutionView.py b/Main/views/SolutionView.py index a370461..62c7ea7 100644 --- a/Main/views/SolutionView.py +++ b/Main/views/SolutionView.py @@ -1,3 +1,4 @@ +from Main.models import Solution from SprintLib.BaseView import BaseView, AccessError @@ -5,9 +6,10 @@ class SolutionView(BaseView): view_file = "solution.html" required_login = True endpoint = "solution" + solution: Solution def pre_handle(self): if self.request.user.is_superuser: return - if self.entities.solution.user != self.request.user: + if self.solution.user != self.request.user: raise AccessError() diff --git a/Main/views/SolutionsTableView.py b/Main/views/SolutionsTableView.py index 9264094..75c75a7 100644 --- a/Main/views/SolutionsTableView.py +++ b/Main/views/SolutionsTableView.py @@ -1,4 +1,4 @@ -from Main.models import Solution +from Main.models import Solution, Set, Task, SetTask from SprintLib.BaseView import BaseView, AccessError @@ -8,6 +8,9 @@ class SolutionsTableView(BaseView): endpoint = "solutions_table" page_size = 20 page = None + set: Set + task: Task + setTask: SetTask def pre_handle(self): if 'page' not in self.request.GET: @@ -18,20 +21,20 @@ class SolutionsTableView(BaseView): queryset = Solution.objects.all() if 'teacher' in self.request.GET.keys(): if 'set_id' in self.request.GET.keys(): - if self.request.user != self.entities.set.creator and self.request.user.username not in self.entities.set.editors: + if self.request.user != self.set.creator and self.request.user.username not in self.set.editors: raise AccessError() queryset = queryset.filter(set_id=self.request.GET['set_id']) elif 'task_id' in self.request.GET.keys(): - if self.request.user != self.entities.task.creator and self.request.user.username not in self.entities.task.editors: + if self.request.user != self.task.creator and self.request.user.username not in self.task.editors: raise AccessError() queryset = queryset.filter(task_id=self.request.GET['task_id'], set=None) else: raise AccessError() else: if hasattr(self.entities, 'setTask'): - queryset = queryset.filter(user=self.request.user, task=self.entities.setTask.task, set=self.entities.setTask.set) + queryset = queryset.filter(user=self.request.user, task=self.setTask.task, set=self.setTask.set) else: - queryset = queryset.filter(user=self.request.user, task=self.entities.task, set=None) + queryset = queryset.filter(user=self.request.user, task=self.task, set=None) offset = self.page_size * (self.page - 1) limit = self.page_size self.context["solutions"] = queryset.order_by("-id")[offset:offset + limit] diff --git a/Main/views/TaskRuntimeView.py b/Main/views/TaskRuntimeView.py index 6b9bc01..660afbb 100644 --- a/Main/views/TaskRuntimeView.py +++ b/Main/views/TaskRuntimeView.py @@ -1,4 +1,4 @@ -from Main.models import Progress +from Main.models import Progress, Task from SprintLib.BaseView import BaseView @@ -6,7 +6,8 @@ class TaskRuntimeView(BaseView): view_file = "task_runtime.html" required_login = True endpoint = "task_runtime" + task: Task def get(self): - progress = Progress.objects.get(task=self.entities.task, user=self.request.user) + progress = Progress.objects.get(task=self.task, user=self.request.user) self.context["progress"] = progress diff --git a/Main/views/TaskSettingsView.py b/Main/views/TaskSettingsView.py index addb2c2..e561592 100644 --- a/Main/views/TaskSettingsView.py +++ b/Main/views/TaskSettingsView.py @@ -1,6 +1,6 @@ from django.http import HttpResponse -from Main.models import ExtraFile, Dump +from Main.models import ExtraFile, Dump, Task from SprintLib.BaseView import BaseView, AccessError from SprintLib.queue import send_to_queue @@ -9,9 +9,10 @@ class TaskSettingsView(BaseView): view_file = "task_settings.html" required_login = True endpoint = "admin/task" + task: Task def pre_handle(self): - if self.request.user != self.entities.task.creator and self.request.user.username not in self.entities.task.editors: + if self.request.user != self.task.creator and self.request.user.username not in self.task.editors: raise AccessError() def get(self): @@ -19,15 +20,15 @@ class TaskSettingsView(BaseView): def post(self): for key, value in self.request.POST.items(): - setattr(self.entities.task, key, value.strip()) - self.entities.task.public = "public" in self.request.POST - self.entities.task.save() - return f"/admin/task?task_id={self.entities.task.id}" + setattr(self.task, key, value.strip()) + self.task.public = "public" in self.request.POST + self.task.save() + return f"/admin/task?task_id={self.task.id}" def post_dump(self): - dump = Dump.objects.create(executor=self.request.user, task=self.entities.task) + dump = Dump.objects.create(executor=self.request.user, task=self.task) send_to_queue("files", {"id": dump.id}) - return f"/admin/task?task_id={self.entities.task.id}" + return f"/admin/task?task_id={self.task.id}" def _upload(self, is_test): filename = self.request.FILES["file"].name @@ -35,17 +36,17 @@ class TaskSettingsView(BaseView): if is_test: name = filename.strip(".a") if not name.isnumeric(): - return f"/admin/task?task_id={self.entities.task.id}&error_message=Формат файла не соответствует тесту" + return f"/admin/task?task_id={self.task.id}&error_message=Формат файла не соответствует тесту" ef, created = ExtraFile.objects.get_or_create( - task=self.entities.task, is_test=True, filename=filename + task=self.task, is_test=True, filename=filename ) if not created: ef.is_sample = False ef.save() - return f"/admin/task?task_id={self.entities.task.id}" + return f"/admin/task?task_id={self.task.id}" if ef is None or created is None: ef, created = ExtraFile.objects.get_or_create( - task=self.entities.task, filename=filename, is_test=is_test + task=self.task, filename=filename, is_test=is_test ) ef.write(self.request.FILES["file"].read()) try: @@ -54,7 +55,7 @@ class TaskSettingsView(BaseView): except UnicodeDecodeError: ef.readable = False ef.save() - return "/admin/task?task_id=" + str(self.entities.task.id) + return "/admin/task?task_id=" + str(self.task.id) def post_file_upload(self): return self._upload(False) @@ -71,15 +72,15 @@ class TaskSettingsView(BaseView): name = self.request.POST["newfile_name"] ef, created = ExtraFile.objects.get_or_create( - filename=name, task=self.entities.task + filename=name, task=self.task ) if not created: - return f"/admin/task?task_id={self.entities.task.id}&error_message=Файл с таким именем уже существует" + return f"/admin/task?task_id={self.task.id}&error_message=Файл с таким именем уже существует" ef.write(b"") ef.is_test = is_test ef.readable = True ef.save() - return f"/admin/task?task_id={self.entities.task.id}" + return f"/admin/task?task_id={self.task.id}" def post_create_file(self): return self._create(False) @@ -93,17 +94,17 @@ class TaskSettingsView(BaseView): ef.write(self.request.POST["text"].encode("utf-8")) ef.is_sample = "is_sample" in self.request.POST.keys() ef.save() - return f"/admin/task?task_id={self.entities.task.id}" + return f"/admin/task?task_id={self.task.id}" def post_users_edit(self): - current_users = self.entities.task.editors + current_users = self.task.editors for key, value in self.request.POST.items(): if key.startswith("user_"): i = '_'.join(key.split("_")[1:]) if i not in current_users: - self.entities.task.editors.append(i) + self.task.editors.append(i) to_delete = [i for i in current_users if "user_" + i not in self.request.POST and i != self.request.user.username] for t in to_delete: - self.entities.task.editors.remove(t) - self.entities.task.save() - return "/admin/task?task_id=" + str(self.entities.task.id) + self.task.editors.remove(t) + self.task.save() + return "/admin/task?task_id=" + str(self.task.id) diff --git a/Main/views/TaskView.py b/Main/views/TaskView.py index 4e8c9ca..9e8a495 100644 --- a/Main/views/TaskView.py +++ b/Main/views/TaskView.py @@ -1,7 +1,8 @@ import io +from typing import Optional from zipfile import ZipFile -from Main.models import Solution, Progress, SolutionFile +from Main.models import Solution, Progress, SolutionFile, SetTask, Task, Set from SprintLib.BaseView import BaseView, AccessError from SprintLib.language import languages from SprintLib.queue import send_to_queue @@ -12,32 +13,37 @@ class TaskView(BaseView): required_login = True view_file = "task.html" endpoint = "task" + setTask: Optional[SetTask] = None + task: Optional[Task] = None + set: Optional[Set] = None def get(self): progress, _ = Progress.objects.get_or_create( - user=self.request.user, task=self.entities.task + user=self.request.user, task=self.task ) self.context["progress"] = progress - self.context["in_set"] = hasattr(self.entities, 'setTask') + self.context["in_set"] = self.set is not None def pre_handle(self): - if hasattr(self.entities, 'setTask'): - self.entities.add('task', self.entities.setTask.task) - self.entities.add('set', self.entities.setTask.set) - self.context['languages'] = self.entities.set.language_models + if self.setTask: + self.set = self.setTask.set + self.task = self.setTask.task + self.context['set'] = self.set + self.context['task'] = self.task + self.context['languages'] = self.set.language_models else: - if not self.entities.task.public and not self.entities.task.creator == self.request.user and not self.request.user.username in self.entities.task.editors: + if not self.task.public and self.task.creator != self.request.user and self.request.user.username not in self.task.editors: raise AccessError() self.context['languages'] = languages if self.request.method == "GET": return - if hasattr(self.entities, 'set') and int(self.request.POST["language"]) not in self.entities.set.languages: + if self.set and int(self.request.POST["language"]) not in self.set.languages: raise AccessError() self.solution = Solution.objects.create( - task=self.entities.task, + task=self.task, user=self.request.user, language_id=int(self.request.POST["language"]), - set=self.entities.set if hasattr(self.entities, 'setTask') else None, + set=self.set, extras=dict(), ) @@ -50,12 +56,12 @@ class TaskView(BaseView): fs_id=fs_id, ) self.send_testing() - return ("/task?setTask_id=" + str(self.entities.setTask.id)) if hasattr(self.entities, 'setTask') else ("/task?task_id=" + str(self.entities.task.id)) + return ("/task?setTask_id=" + str(self.setTask.id)) if self.set else ("/task?task_id=" + str(self.task.id)) def post_1(self): # отправка решения через файл if "file" not in self.request.FILES: - return "task?task_id=" + str(self.entities.task.id) + return "task?task_id=" + str(self.task.id) filename = self.request.FILES["file"].name if filename.endswith(".zip"): archive = ZipFile(io.BytesIO(self.request.FILES["file"].read())) @@ -76,7 +82,7 @@ class TaskView(BaseView): fs_id=fs_id, ) self.send_testing() - return ("/task?setTask_id=" + str(self.entities.setTask.id)) if hasattr(self.entities, 'setTask') else ("/task?task_id=" + str(self.entities.task.id)) + return ("/task?setTask_id=" + str(self.setTask.id)) if self.set else ("/task?task_id=" + str(self.task.id)) def send_testing(self): if self.solution.set is not None and len(self.solution.set.checkers.all()) != 0: diff --git a/SprintLib/BaseView.py b/SprintLib/BaseView.py index 679811d..ca5aad8 100644 --- a/SprintLib/BaseView.py +++ b/SprintLib/BaseView.py @@ -5,8 +5,6 @@ from django.http import HttpResponseRedirect, JsonResponse from django.shortcuts import render from django.utils import timezone -from SprintLib.EntityStorage import EntityStorage - class AccessError(Exception): pass @@ -15,14 +13,12 @@ class AccessError(Exception): class BaseView: request: WSGIRequest = None context: Optional[dict] = None - entities: Optional[EntityStorage] = None required_login: Optional[bool] = None view_file: Optional[str] = None endpoint: Optional[str] = None def __init__(self, request): self.context = {} - self.entities = EntityStorage() self.request = request @classmethod @@ -40,16 +36,18 @@ class BaseView: return HttpResponseRedirect("/") request_method = request.method.lower() exec("from Main.models import *") + context = {} for key in request.GET.keys(): if key.endswith("_id"): model_name = key.rstrip("_id") - c.entities.add( + setattr( + c, model_name, eval(model_name[0].upper() + model_name[1:]).objects.get( id=int(request.GET[key]) ), ) - context = c.entities.entities + context[model_name] = getattr(c, model_name) if "action" in request.POST.keys(): request_method += "_" + request.POST["action"] method = getattr(c, request_method, None) @@ -66,7 +64,7 @@ class BaseView: return data context = {**context, **c.context} res = render(request, c.view_file, context) - res.headers['X-Frame-Options'] = 'ALLOW' + res.headers["X-Frame-Options"] = "ALLOW" return res except AccessError: return HttpResponseRedirect("/") diff --git a/SprintLib/EntityStorage.py b/SprintLib/EntityStorage.py deleted file mode 100644 index b3c2e0b..0000000 --- a/SprintLib/EntityStorage.py +++ /dev/null @@ -1,9 +0,0 @@ -from django.db.models import Model - - -class EntityStorage: - entities: dict[str, Model] = {} - - def add(self, name, entity): - self.entities[name] = entity - setattr(self, name, entity) diff --git a/templates/tasks.html b/templates/tasks.html index f02b1e5..fc50ddf 100644 --- a/templates/tasks.html +++ b/templates/tasks.html @@ -34,6 +34,7 @@