diff --git a/Main/models/mixins.py b/Main/models/mixins.py
index 1b3aba7..7058a2a 100644
--- a/Main/models/mixins.py
+++ b/Main/models/mixins.py
@@ -1,8 +1,10 @@
+from functools import cached_property
+
from SprintLib.utils import get_bytes, write_bytes, delete_file
class FileStorageMixin:
- @property
+ @cached_property
def text(self):
return get_bytes(self.fs_id).decode("utf-8")
diff --git a/Main/models/solution.py b/Main/models/solution.py
index 73c4fa4..dad968e 100644
--- a/Main/models/solution.py
+++ b/Main/models/solution.py
@@ -1,4 +1,5 @@
-from os.path import join, exists
+from functools import cached_property
+from os.path import exists
from shutil import rmtree
from subprocess import call
@@ -8,7 +9,7 @@ from django.utils import timezone
from Main.models.solution_file import SolutionFile
from Main.models.task import Task
-from Sprint.settings import CONSTS, SOLUTIONS_ROOT, SOLUTIONS_ROOT_EXTERNAL
+from Sprint.settings import CONSTS
from SprintLib.language import languages
@@ -28,7 +29,7 @@ class Solution(models.Model):
rmtree(self.directory)
super().delete(using=using, keep_parents=keep_parents)
- @property
+ @cached_property
def files(self):
data = []
for file in SolutionFile.objects.filter(solution=self):
diff --git a/Main/views/SolutionsTableView.py b/Main/views/SolutionsTableView.py
index 2eea685..ba4c9be 100644
--- a/Main/views/SolutionsTableView.py
+++ b/Main/views/SolutionsTableView.py
@@ -1,25 +1,58 @@
-from django.http import HttpResponse
+from django.db.models import QuerySet
from Main.models import Solution
-from Sprint.settings import CONSTS
-from SprintLib.BaseView import BaseView
+from SprintLib.BaseView import BaseView, AccessError
class SolutionsTableView(BaseView):
view_file = "solutions_table.html"
required_login = True
endpoint = "solutions_table"
+ page_size = 20
+ page = None
+
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+ self.filters = [
+ self.filter_user,
+ self.filter_task,
+ self.filter_set,
+ ]
+ self.queryset = Solution.objects.all()
+
+ def filter_user(self, queryset: QuerySet):
+ if 'username' in self.request.GET:
+ return queryset.filter(user__username=self.request.GET["username"])
+ return queryset
+
+ def filter_task(self, queryset: QuerySet):
+ if 'task_id' in self.request.GET:
+ return queryset.filter(task_id=int(self.request.GET['task_id']))
+ return queryset
+
+ def filter_set(self, queryset: QuerySet):
+ if 'set_id' in self.request.GET:
+ return queryset.filter()
+ return queryset
+
+ def pre_handle(self):
+ if 'page' not in self.request.GET:
+ raise AccessError()
+ self.page = int(self.request.GET['page'])
+ if "username" in self.request.GET and self.request.user.username == self.request.GET['username']:
+ return
+ if hasattr(self.entities, "set"):
+ if self.entities.set.creator != self.request.user:
+ raise AccessError()
+ if hasattr(self.entities, "task"):
+ if self.entities.task.creator != self.request.user:
+ raise AccessError()
def get(self):
- self.context["solutions"] = Solution.objects.filter(
- user=self.request.user, task=self.entities.task
- ).order_by("-time_sent")
- if "render" in self.request.GET.keys():
- return
- for sol in self.context["solutions"]:
- if (
- sol.result == CONSTS["testing_status"]
- or sol.result == CONSTS["in_queue_status"]
- ):
- return
- return HttpResponse("done")
+ for fltr in self.filters:
+ self.queryset = fltr(self.queryset)
+ offset = self.page_size * (self.page - 1)
+ limit = self.page_size
+ self.context["solutions"] = self.queryset.order_by("-id")[offset:offset + limit]
+ self.context["count_pages"] = range(1, (len(self.queryset) - 1) // self.page_size + 2)
+ self.context["need_pagination"] = len(self.context["count_pages"]) > 1
diff --git a/Main/views/SolutionsView.py b/Main/views/SolutionsView.py
new file mode 100644
index 0000000..bdcd86b
--- /dev/null
+++ b/Main/views/SolutionsView.py
@@ -0,0 +1,16 @@
+from SprintLib.BaseView import BaseView
+
+
+class SolutionsView(BaseView):
+ required_login = True
+ endpoint = "solutions"
+ view_file = "solutions.html"
+
+ def get(self):
+ self.context["username"] = self.request.GET.get("username")
+ self.context["task_id"] = self.request.GET.get("task_id")
+ if self.context["task_id"]:
+ self.context["task_id"] = int(self.context["task_id"])
+ self.context["set_id"] = self.request.GET.get("set_id")
+ if self.context["set_id"]:
+ self.context["set_id"] = int(self.context["set_id"])
diff --git a/Main/views/TaskRuntimeView.py b/Main/views/TaskRuntimeView.py
index 49138c2..6b9bc01 100644
--- a/Main/views/TaskRuntimeView.py
+++ b/Main/views/TaskRuntimeView.py
@@ -1,5 +1,3 @@
-from django.http import HttpResponse
-
from Main.models import Progress
from SprintLib.BaseView import BaseView
@@ -12,7 +10,3 @@ class TaskRuntimeView(BaseView):
def get(self):
progress = Progress.objects.get(task=self.entities.task, user=self.request.user)
self.context["progress"] = progress
- if "render" in self.request.GET.keys():
- return
- if progress.finished:
- return HttpResponse("done")
diff --git a/Main/views/__init__.py b/Main/views/__init__.py
index 50fc0a8..d1d6d1a 100644
--- a/Main/views/__init__.py
+++ b/Main/views/__init__.py
@@ -13,4 +13,5 @@ from Main.views.SolutionView import SolutionView
from Main.views.ImageView import ImageView
from Main.views.SendCodeView import SendCodeView
from Main.views.SetSettingsView import SetSettingsView
-from Main.views.UsersView import UsersView
\ No newline at end of file
+from Main.views.UsersView import UsersView
+from Main.views.SolutionsView import SolutionsView
diff --git a/templates/solutions.html b/templates/solutions.html
new file mode 100644
index 0000000..942ceb2
--- /dev/null
+++ b/templates/solutions.html
@@ -0,0 +1,44 @@
+{% extends 'base_main.html' %}
+
+{% block scripts %}
+ var page = 1;
+ function setPage(number) {
+ page = number;
+ }
+ function doPoll() {
+ jQuery.get('/solutions_table?task_id={{ task.id }}&page=' + page.toString(), function(data) {
+ document.getElementById('solutions').innerHTML = data;
+ const name = "page_num_" + page.toString();
+ document.getElementById(name).className = "btn btn-dark";
+ setTimeout(function() {doPoll()}, 2000);
+ })
+ }
+{% endblock %}
+
+{% block onload %}doPoll(){% endblock %}
+
+{% block main %}
+
Решения
+ Фильтр
+
+
+ Все сеты
+ {% for set in user.userinfo.available_sets %}
+ {{ set.name }}
+ {% endfor %}
+
+
+ Все таски
+ {% for task in user.userinfo.available_tasks %}
+ {{ task.name }}
+ {% endfor %}
+
+
+ Все пользователи
+ {% for u in users %}
+ {{ user.userinfo }}
+ {% endfor %}
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/templates/solutions_table.html b/templates/solutions_table.html
index c998e22..67b5eb2 100644
--- a/templates/solutions_table.html
+++ b/templates/solutions_table.html
@@ -1,8 +1,24 @@
+
+{% if need_pagination %}
+
+
+
+ {% for num in count_pages %}
+ {{ num }}
+ {% endfor %}
+
+
+
+{% endif %}
\ No newline at end of file
diff --git a/templates/task.html b/templates/task.html
index 158bd99..adf0d6f 100644
--- a/templates/task.html
+++ b/templates/task.html
@@ -19,26 +19,20 @@
document.getElementById('file-upload').value = null;
document.getElementById('input0').value = "";
}
+ var page = 1;
+ function setPage(number) {
+ page = number;
+ }
function doPoll() {
- jQuery.get('/solutions_table?task_id={{ task.id }}', function(data) {
+ jQuery.get('/solutions_table?task_id={{ task.id }}&username={{ user.username }}&page=' + page.toString(), function(data) {
+ document.getElementById('solutions').innerHTML = data;
+ const name = "page_num_" + page.toString();
+ document.getElementById(name).className = "btn btn-dark";
jQuery.get('/task_runtime?task_id={{ task.id }}', function(data1) {
- if (data == 'done' && data1 == 'done')
- return
- if (data != 'done') {
- document.getElementById('solutions').innerHTML = data;
- }
- if (data1 != 'done') {
- document.getElementById('runtime').innerHTML = data1;
- }
+ document.getElementById('runtime').innerHTML = data1;
setTimeout(function() {doPoll()}, 2000);
})
})
- jQuery.get('/solutions_table?id={{ task.id }}&render=true', function(data) {
- document.getElementById('solutions').innerHTML = data;
- })
- jQuery.get('/task_runtime?id={{ task.id }}&render=true', function(data) {
- document.getElementById('runtime').innerHTML = data;
- })
}
{% endblock %}
@@ -134,15 +128,5 @@
Решения
-
-
- id
- Время отправки
- Язык
- Результат
-
-
-
-
-
+
{% endblock %}
\ No newline at end of file
diff --git a/templates/tasks.html b/templates/tasks.html
index fd543b0..a4ec47d 100644
--- a/templates/tasks.html
+++ b/templates/tasks.html
@@ -44,6 +44,6 @@
{% for task in tasks %}
- {{ task.name }} {% if task.creator == user %} {% endif %}
+ {{ task.name }} {% if task.creator == user %} {% endif %}
{% endfor %}
{% endblock %}
\ No newline at end of file