diff --git a/mamweb/settings_common.py b/mamweb/settings_common.py
index 54e0c6f1..baebe3b4 100644
--- a/mamweb/settings_common.py
+++ b/mamweb/settings_common.py
@@ -48,6 +48,12 @@ STATICFILES_FINDERS = (
LOGIN_URL = 'login'
LOGIN_REDIRECT_URL = 'profil'
+# Odhlášení po zavření prohlížeče
+# (pozor nefunguje na firefox se znovuotevíráním oken po startu firefoxu)
+# default je False a SESSION_COOKIE_AGE = 3600*24*14 = 2 týdny
+SESSION_EXPIRE_AT_BROWSER_CLOSE = True
+DOBA_ODHLASENI_PRI_ZASKRTNUTI_NEODHLASOVAT = 365 * 24 * 3600 # rok
+
# Modules configuration
AUTHENTICATION_BACKENDS = (
diff --git a/mamweb/static/css/mamweb.css b/mamweb/static/css/mamweb.css
index 069eb39f..fa5de880 100644
--- a/mamweb/static/css/mamweb.css
+++ b/mamweb/static/css/mamweb.css
@@ -1190,14 +1190,14 @@ div.gdpr {
/* Jak řešit */
-.jakresit img {
+.jakresit svg {
width: 33%;
padding: 10px;
filter: none;
}
@media(max-width: 860px) {
- .jakresit img {
+ .jakresit svg {
margin: auto;
display: grid;
width: 100%;
diff --git a/mamweb/static/images/jakresit_1.svg b/mamweb/templates/jakresit_1.svg
similarity index 99%
rename from mamweb/static/images/jakresit_1.svg
rename to mamweb/templates/jakresit_1.svg
index 36a6b7c7..514e3221 100644
--- a/mamweb/static/images/jakresit_1.svg
+++ b/mamweb/templates/jakresit_1.svg
@@ -1,20 +1,21 @@
diff --git a/mamweb/static/images/jakresit_2.svg b/mamweb/templates/jakresit_2.svg
similarity index 100%
rename from mamweb/static/images/jakresit_2.svg
rename to mamweb/templates/jakresit_2.svg
diff --git a/mamweb/static/images/jakresit_3.svg b/mamweb/templates/jakresit_3.svg
similarity index 100%
rename from mamweb/static/images/jakresit_3.svg
rename to mamweb/templates/jakresit_3.svg
diff --git a/seminar/templates/generic_form.html b/seminar/templates/generic_form.html
new file mode 100644
index 00000000..33e2d276
--- /dev/null
+++ b/seminar/templates/generic_form.html
@@ -0,0 +1,19 @@
+{% extends "base.html" %}
+{% load static %}
+
+
+{% block content %}
+
+ {% block nadpis1a %}
+ {{ nadpis }}
+ {% endblock %}
+
+
+
+{% endblock %}
diff --git a/seminar/templates/seminar/jak-resit.html b/seminar/templates/seminar/jak-resit.html
index 4404b53e..b418f5cc 100644
--- a/seminar/templates/seminar/jak-resit.html
+++ b/seminar/templates/seminar/jak-resit.html
@@ -8,9 +8,9 @@
-
![]({% static 'images/jakresit_1.svg' %})
-
![]({% static 'images/jakresit_2.svg' %})
-
![]({% static 'images/jakresit_3.svg' %})
+{% include 'jakresit_1.svg' %}
+{% include 'jakresit_2.svg' %}
+{% include 'jakresit_3.svg' %}
{% endblock %}
diff --git a/seminar/urls.py b/seminar/urls.py
index 58fb0335..d825b9b8 100644
--- a/seminar/urls.py
+++ b/seminar/urls.py
@@ -105,4 +105,11 @@ urlpatterns = [
path('', views.TitulniStranaView.as_view(), name='titulni_strana'),
path('jak-resit/', views.JakResitView.as_view(), name='jak_resit'),
path('stare-novinky/', views.StareNovinkyView.as_view(), name='stare_novinky'),
+
+ # Dočasné & neodladěné:
+ path(
+ 'hidden/hromadne_pridani',
+ org_required(views.HromadnePridaniView.as_view()),
+ name="hromadne_pridani"
+ ),
]
diff --git a/seminar/views/docasne.py b/seminar/views/docasne.py
index da34d2e6..d13c0016 100644
--- a/seminar/views/docasne.py
+++ b/seminar/views/docasne.py
@@ -1,4 +1,9 @@
from http import HTTPStatus
+
+from django.db import transaction
+from django.forms import Form, CharField, IntegerField
+from django.views.generic import FormView
+
import seminar.models as m
from django.shortcuts import render, get_object_or_404
@@ -14,3 +19,49 @@ def problemView(request, pk):
status_code = HTTPStatus.NOT_FOUND
return render(request, template, context=ctx, status=status_code)
+
+# FIXME Tohle možná patří do forms.py
+# FIXME Tohle není odladěné, selhává to nekontrolovaně
+# a obecně je to fujky nekomentovaný kód
+class HromadnePridaniForm(Form):
+ tema = CharField(label="Název tématu:")
+ dil = IntegerField(label="Díl:", min_value=1)
+ body = CharField(label="Počty bodů (0 pro problém) oddělené čárkami:")
+
+
+# FIXME Tohle není odladěné, selhává to nekontrolovaně
+# a obecně je to fujky nekomentovaný kód
+class HromadnePridaniView(FormView):
+ form_class = HromadnePridaniForm
+ template_name = "generic_form.html"
+ success_url = 'hromadne_pridani'
+
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data()
+ context["nadpis"] = "Hromadné přidání úloh"
+ context["form_url"] = "hromadne_pridani"
+ return context
+
+ def form_valid(self, form):
+ cd = form.cleaned_data
+ tema = cd["tema"]
+ dil = cd["dil"]
+ body = list(map(int, cd["body"].split(",")))
+
+ t = m.Problem.objects.get(nazev__exact=tema, nadproblem=None)
+ with transaction.atomic():
+ pfx = f"{t.nazev}, díl {dil}, "
+
+ for k, b in enumerate(body):
+ u = m.Uloha.objects.create(
+ nadproblem=t,
+ nazev=pfx + f"{'úloha' if b > 0 else 'problém'} {k + 1}",
+ autor=t.autor,
+ garant=t.garant,
+ max_body=b,
+ cislo_zadani=m.Cislo.get(t.rocnik.rocnik, dil),
+ kod=k,
+ stav=m.Problem.STAV_ZADANY,
+ )
+ u.opravovatele.set(t.opravovatele.all())
+ return super().form_valid(form)
diff --git a/various/autentizace/forms.py b/various/autentizace/forms.py
new file mode 100644
index 00000000..f3138d74
--- /dev/null
+++ b/various/autentizace/forms.py
@@ -0,0 +1,16 @@
+"""
+Formuláře (:class:`django.forms.Form`) umožňují jednoduchou tvorbu formulářů,
+které lze pak jednoduše dát do frontendu i zpracovat na backendu.
+
+Pro přidání políčka do formuláře je potřeba
+ - mít v modelu tu položku, kterou chci upravovat
+ - přidat do views (prihlaskaView, resitelEditView)
+ - přidat do forms
+ - includovat do html
+"""
+
+from django.contrib.auth.forms import AuthenticationForm
+from django.forms import BooleanField
+
+class LoginForm(AuthenticationForm):
+ disable_logout = BooleanField(label="Neodhlašovat", required=False)
diff --git a/various/autentizace/views.py b/various/autentizace/views.py
index 85ed3528..73b51c54 100644
--- a/various/autentizace/views.py
+++ b/various/autentizace/views.py
@@ -1,10 +1,24 @@
+from django.conf import settings
+from django.http import HttpResponseRedirect
from django.urls import reverse_lazy
from django.contrib.auth import views as auth_views
+from django.contrib.auth import login as auth_login
+
+from various.autentizace.forms import LoginForm
+
class LoginView(auth_views.LoginView):
# Jen vezmeme vestavěný a dáme mu vhodný template a přesměrovací URL
template_name = 'autentizace/login.html'
+ authentication_form = LoginForm
+
+ def form_valid(self, form):
+ """ Okopírováno z django/contrib/auth/views.py s přidáním nekonečného přihlášení """
+ auth_login(self.request, form.get_user())
+ if form.cleaned_data["disable_logout"]:
+ form.request.session.set_expiry(settings.DOBA_ODHLASENI_PRI_ZASKRTNUTI_NEODHLASOVAT)
+ return HttpResponseRedirect(self.get_success_url())
class LogoutView(auth_views.LogoutView):