This commit is contained in:
Egor Matveev 2022-02-23 00:15:58 +03:00
parent cdb5157471
commit 4e9c195d9d
4 changed files with 172 additions and 12 deletions

View File

@ -3,19 +3,30 @@ from random import sample
from django.db.models import Count, Max, Q
from django.utils import timezone
from Checker.models import Checker
from Main.models import Task, UserInfo, Solution, Group
from SprintLib.BaseView import BaseView
from SprintLib.BaseView import BaseView, AccessError
from SprintLib.language import languages
class MainView(BaseView):
view_file = "main.html"
required_login = True
endpoint = ""
def get(self):
self.context['top_tasks_today'] = Task.objects.filter(public=True, solution__time_sent__date=timezone.now().date()).annotate(count=Count('solution__task_id')).order_by('-count')[:5]
@property
def view_file(self):
if self.request.user.is_authenticated:
return "main.html"
return "landing.html"
def get_main(self):
self.context['top_tasks_today'] = Task.objects.filter(public=True,
solution__time_sent__date=timezone.now().date()).annotate(
count=Count('solution__task_id')).order_by('-count')[:5]
if len(self.context['top_tasks_today']) < 5:
self.context['top_tasks_today'] = Task.objects.filter(public=True, solution__time_sent__isnull=False).annotate(time_sent=Max('solution__time_sent'), count=Count('solution__task_id')).order_by('-count', '-time_sent')[:5]
self.context['top_tasks_today'] = Task.objects.filter(public=True,
solution__time_sent__isnull=False).annotate(
time_sent=Max('solution__time_sent'), count=Count('solution__task_id')).order_by('-count',
'-time_sent')[:5]
if len(self.context['top_tasks_today']) < 5:
self.context['top_tasks_today'] = Task.objects.filter(public=True).order_by('name')[:5]
for task in self.context['top_tasks_today']:
@ -29,8 +40,25 @@ class MainView(BaseView):
setattr(task, 'solution', Solution.objects.filter(user=self.request.user, task=task).last())
new_tasks = set(Task.objects.filter(public=True)) - set(all_tasks)
self.context['new_tasks'] = sample(new_tasks, k=min(5, len(new_tasks)))
self.context['groups'] = Group.objects.filter(Q(editors__in=self.request.user.username) | Q(creator=self.request.user) | Q(users=self.request.user)).distinct()
self.context['groups'] = Group.objects.filter(
Q(editors__in=self.request.user.username) | Q(creator=self.request.user) | Q(
users=self.request.user)).distinct()
def get_landing(self):
self.context['solutions'] = len(Solution.objects.all())
self.context['tasks'] = len(Task.objects.all())
self.context['users'] = len(UserInfo.objects.all())
self.context['languages'] = len(languages)
self.context['groups'] = len(Group.objects.all())
self.context['runners'] = len(Checker.objects.all())
def get(self):
if self.request.user.is_authenticated:
return self.get_main()
return self.get_landing()
def post(self):
if not self.request.user.userinfo.teacher:
raise AccessError()
group = Group.objects.create(name=self.request.POST['name'], creator=self.request.user)
return '/group?group_id=' + str(group.id)

View File

@ -20,9 +20,10 @@ class BaseView:
view_file: Optional[str] = None
endpoint: Optional[str] = None
def __init__(self):
def __init__(self, request):
self.context = {}
self.entities = EntityStorage()
self.request = request
@classmethod
def as_view(cls):
@ -31,14 +32,13 @@ class BaseView:
user_info = request.user.userinfo
user_info.last_request = timezone.now()
user_info.save()
c = cls()
c = cls(request)
if c.required_login is not None:
if c.required_login and not request.user.is_authenticated:
return HttpResponseRedirect("/enter")
if not c.required_login and request.user.is_authenticated:
return HttpResponseRedirect("/")
request_method = request.method.lower()
c.request = request
exec("from Main.models import *")
for key in request.GET.keys():
if key.endswith("_id"):

View File

@ -1,6 +1,5 @@
from os import listdir, mkdir, chmod
from os import listdir, mkdir
from os.path import join, exists
from shutil import copyfile
from subprocess import call, TimeoutExpired
from Main.management.commands.bot import bot

133
templates/landing.html Normal file
View File

@ -0,0 +1,133 @@
{% load static %}
<html lang="en"><head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors">
<meta name="generator" content="Hugo 0.88.1">
<title>Sprint welcome</title>
<link rel="canonical" href="https://getbootstrap.com/docs/5.1/examples/product/">
<!-- Bootstrap core CSS -->
<link href="https://getbootstrap.com/docs/5.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<!-- Favicons -->
<link rel="shortcut icon" href="{% static "img/icon.svg" %}" />
<style>
.bd-placeholder-img {
font-size: 1.125rem;
text-anchor: middle;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
@media (min-width: 768px) {
.bd-placeholder-img-lg {
font-size: 3.5rem;
}
}
.container {
max-width: 960px;
}
/*
* Extra utilities
*/
.flex-equal > * {
flex: 1;
}
@media (min-width: 768px) {
.flex-md-equal > * {
flex: 1;
}
}
</style>
</head>
<body>
<main>
<div class="position-relative overflow-hidden p-3 p-md-5 m-md-3 text-center bg-light">
<div class="col-md-5 p-lg-5 mx-auto my-5">
<h1 class="display-4 fw-normal">Добро пожаловать в Sprint!</h1>
<p class="lead fw-normal">Sprint - система, позволяющая проводить олимпиады и уроки по программированию, а также обучаться этому ремеслу самостоятельно.</p>
<a class="btn btn-outline-secondary" href="/enter">Войти</a>
</div>
<div class="product-device shadow-sm d-none d-md-block"></div>
<div class="product-device product-device-2 shadow-sm d-none d-md-block"></div>
</div>
<div class="d-md-flex flex-md-equal w-100 my-md-3 ps-md-3">
<div class="bg-dark me-md-3 pt-3 px-3 pt-md-5 px-md-5 text-center text-white overflow-hidden">
<div class="my-3 py-3">
<h2 class="display-5">Sprint - это {{ users }} пользователей</h2>
<p class="lead">А с тобой будет еще больше</p>
</div>
</div>
<div class="bg-light me-md-3 pt-3 px-3 pt-md-5 px-md-5 text-center overflow-hidden">
<div class="my-3 p-3">
<h2 class="display-5">Sprint - это {{ tasks }} задач</h2>
<p class="lead">А с тобой будет еще больше</p>
</div>
</div>
</div>
<div class="d-md-flex flex-md-equal w-100 my-md-3 ps-md-3">
<div class="bg-light me-md-3 pt-3 px-3 pt-md-5 px-md-5 text-center overflow-hidden">
<div class="my-3 p-3">
<h2 class="display-5">Sprint - это {{ solutions }} решений</h2>
<p class="lead">А с тобой будет еще больше</p>
</div>
</div>
<div class="bg-dark me-md-3 pt-3 px-3 pt-md-5 px-md-5 text-center text-white overflow-hidden">
<div class="my-3 py-3">
<h2 class="display-5">Sprint - это {{ languages }} языков</h2>
<p class="lead">А с тобой будет еще больше</p>
</div>
</div>
</div>
<div class="d-md-flex flex-md-equal w-100 my-md-3 ps-md-3">
<div class="bg-dark me-md-3 pt-3 px-3 pt-md-5 px-md-5 text-center text-white overflow-hidden">
<div class="my-3 p-3">
<h2 class="display-5">Sprint - это {{ groups }} групп пользователей</h2>
<p class="lead">А с тобой будет еще больше</p>
</div>
</div>
<div class="bg-light me-md-3 pt-3 px-3 pt-md-5 px-md-5 text-center overflow-hidden">
<div class="my-3 py-3">
<h2 class="display-5">Sprint - это {{ runners }} независимых чекеров</h2>
<p class="lead">А с тобой будет еще больше</p>
</div>
</div>
</div>
<div class="position-relative overflow-hidden p-3 p-md-5 m-md-3 text-center bg-light">
<div class="col-md-5 p-lg-5 mx-auto my-5">
<h1 class="display-4 fw-normal">Попробуй Sprint сегодня и стань частью большой команды</h1>
<p class="lead fw-normal">Бесплатно, быстро и просто.</p>
<a class="btn btn-outline-secondary" href="/enter">Войти</a>
</div>
<div class="product-device shadow-sm d-none d-md-block"></div>
<div class="product-device product-device-2 shadow-sm d-none d-md-block"></div>
</div>
</main>
<script src="https://getbootstrap.com/docs/5.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
</body></html>