Browse Source

Merge branch 'data_migrations' into test

middleware_test
Jonas Havelka 4 years ago
parent
commit
6cbe4cdad0
  1. 6
      .gitignore
  2. 0
      data/flat.json
  3. 207
      data/fotka_header.json
  4. 100
      data/sitetree_new.json
  5. 6
      galerie/templates/galerie/Base.html
  6. 2
      galerie/templates/galerie/Galerie.html
  7. 6
      galerie/templates/galerie/GalerieNahled.html
  8. 2
      galerie/templates/galerie/GalerieNew.html
  9. 7
      galerie/urls.py
  10. 6
      galerie/views.py
  11. 0
      header_fotky/__init__.py
  12. 10
      header_fotky/admin.py
  13. 5
      header_fotky/apps.py
  14. 45
      header_fotky/context_processors.py
  15. 63
      header_fotky/migrations/0001_initial.py
  16. 0
      header_fotky/migrations/__init__.py
  17. 65
      header_fotky/models.py
  18. 4
      korektury/models.py
  19. 13
      korektury/templates/korektury/base.html
  20. 8
      korektury/templates/korektury/help.html
  21. 4
      korektury/templates/korektury/opraf.html
  22. 6
      korektury/templates/korektury/seznam.html
  23. 13
      korektury/templates/korektury/submenu.html
  24. BIN
      korektury/testpdfs/A.pdf
  25. 5125
      korektury/testpdfs/B.pdf
  26. 69
      korektury/testutils.py
  27. 12
      korektury/urls.py
  28. 2
      mamweb/admin.py
  29. 12
      mamweb/context_processors.py
  30. 3
      mamweb/settings_common.py
  31. 36
      mamweb/static/css/mamweb.css
  32. 0
      mamweb/static/images/logo_1.svg
  33. 0
      mamweb/static/images/logo_2.svg
  34. 0
      mamweb/static/images/logo_3.svg
  35. 0
      mamweb/static/images/logo_4.svg
  36. 0
      mamweb/static/images/logo_5.svg
  37. 0
      mamweb/static/images/logo_6.svg
  38. 9
      mamweb/templates/base.html
  39. 102
      mamweb/templates/flatpages/default.html
  40. 26
      mamweb/templates/logo.html
  41. 4
      mamweb/templates/menu.html
  42. 4
      mamweb/templates/menu_mobile.html
  43. 10
      prednasky/templates/prednasky/base.html
  44. 6
      prednasky/templates/prednasky/metaseznam_prednasek.html
  45. 6
      prednasky/templates/prednasky/seznam_prednasek.html
  46. 27
      prednasky/urls.py
  47. 37
      prednasky/views.py
  48. 13
      seminar/migrations/0001_squashed_0067_auto_20190814_0805.py
  49. 3
      seminar/migrations/0019_rocnik_ciselne.py
  50. 8
      seminar/migrations/0052_user_to_organizator.py
  51. 2
      seminar/migrations/0056_vrcholy_pro_rocniky_a_cisla.py
  52. 2
      seminar/migrations/0057_reseni_to_reseni_hodnoceni.py
  53. 8
      seminar/migrations/0058_problem_to_uloha_tema_clanek.py
  54. 2
      seminar/migrations/0059_vytvorit_pohadkanode.py
  55. 2
      seminar/migrations/0060_spoj_stromy.py
  56. 2
      seminar/migrations/0068_treenode_nazev.py
  57. 6
      seminar/migrations/0080_zruseni_claneknode_a_konferanode.py
  58. 35
      seminar/migrations/0088_perm_org_a_ucastnik.py
  59. 18
      seminar/migrations/0089_cislo_datum_preddeadline.py
  60. 3
      seminar/models.py
  61. 6
      seminar/templates/seminar/archiv/base.html
  62. 2
      seminar/templates/seminar/archiv/cisla.html
  63. 24
      seminar/templates/seminar/archiv/cislo.html
  64. 2
      seminar/templates/seminar/archiv/cislo_obalkovani.html
  65. 2
      seminar/templates/seminar/archiv/prispevek.html
  66. 6
      seminar/templates/seminar/archiv/problem.html
  67. 6
      seminar/templates/seminar/archiv/rocnik.html
  68. 2
      seminar/templates/seminar/archiv/temata.html
  69. 10
      seminar/templates/seminar/clanky/base.html
  70. 6
      seminar/templates/seminar/clanky/organizatorske_clanky.html
  71. 8
      seminar/templates/seminar/clanky/resitelske_clanky.html
  72. 6
      seminar/templates/seminar/cojemam/base.html
  73. 11
      seminar/templates/seminar/cojemam/organizatori.html
  74. 6
      seminar/templates/seminar/novinky.html
  75. 2
      seminar/templates/seminar/profil/edit.html
  76. 3
      seminar/templates/seminar/profil/gdpr.html
  77. 2
      seminar/templates/seminar/profil/login.html
  78. 2
      seminar/templates/seminar/profil/logout.html
  79. 8
      seminar/templates/seminar/profil/nahraj_reseni.html
  80. 2
      seminar/templates/seminar/profil/prihlaska.html
  81. 2
      seminar/templates/seminar/profil/prihlaska_field.html
  82. 2
      seminar/templates/seminar/profil/resitel.html
  83. 6
      seminar/templates/seminar/soustredeni/base.html
  84. 23
      seminar/templates/seminar/soustredeni/seznam_soustredeni.html
  85. 1
      seminar/templates/seminar/soustredeni/seznam_ucastniku.html
  86. 2
      seminar/templates/seminar/treenode.html
  87. 11
      seminar/templates/seminar/zadani/AktualniVysledkovka.html
  88. 14
      seminar/templates/seminar/zadani/AktualniZadani.html
  89. 9
      seminar/templates/seminar/zadani/Temata.html
  90. 10
      seminar/templates/seminar/zadani/base.html
  91. 55
      seminar/testutils.py
  92. 112
      seminar/urls.py
  93. 14
      seminar/utils.py
  94. 2
      seminar/views/utils.py
  95. 16
      seminar/views/views_all.py

6
.gitignore

@ -24,3 +24,9 @@ TODO
# .htpasswd kvůli přihlášení # .htpasswd kvůli přihlášení
.htpasswd .htpasswd
# reversion kvůli historii objektů v reversion
**/reversion
# pro lidi, co programují v nástrojích od JetBrains
.idea

0
flat.json → data/flat.json

207
data/fotka_header.json

@ -0,0 +1,207 @@
[
{
"model": "header_fotky.fotkaheader",
"pk": "baliky.jpg",
"fields": {
"cas": "2020-09-20T09:18:34.562Z",
"fotka": "header/baliky.jpg"
}
},
{
"model": "header_fotky.fotkaheader",
"pk": "beh.jpg",
"fields": {
"cas": "2020-09-20T09:18:34.562Z",
"fotka": "header/beh.jpg"
}
},
{
"model": "header_fotky.fotkaheader",
"pk": "kryptografie.jpg",
"fields": {
"cas": "2020-09-20T09:18:34.562Z",
"fotka": "header/kryptografie.jpg"
}
},
{
"model": "header_fotky.fotkaheader",
"pk": "mam_cernobile.jpg",
"fields": {
"cas": "2020-09-20T09:18:34.562Z",
"fotka": "header/mam_cernobile.jpg"
}
},
{
"model": "header_fotky.fotkaheader",
"pk": "noc.jpg",
"fields": {
"cas": "2020-09-20T09:18:34.562Z",
"fotka": "header/noc.jpg"
}
},
{
"model": "header_fotky.fotkaheader",
"pk": "ohen.jpg",
"fields": {
"cas": "2020-09-20T09:18:34.562Z",
"fotka": "header/ohen.jpg"
}
},
{
"model": "header_fotky.fotkaheader",
"pk": "snih.jpg",
"fields": {
"cas": "2020-09-20T09:18:34.562Z",
"fotka": "header/snih.jpg"
}
},
{
"model": "header_fotky.fotkaheader",
"pk": "spolecna.jpg",
"fields": {
"cas": "2020-09-20T09:18:34.562Z",
"fotka": "header/spolecna.jpg"
}
},
{
"model": "header_fotky.fotkaheader",
"pk": "stiny.jpg",
"fields": {
"cas": "2020-09-20T09:18:34.562Z",
"fotka": "header/stiny.jpg"
}
},
{
"model": "header_fotky.fotkaheader",
"pk": "vikendovka.jpg",
"fields": {
"cas": "2020-09-20T09:18:34.562Z",
"fotka": "header/vikendovka.jpg"
}
},
{
"model": "header_fotky.fotkaheader",
"pk": "vylet.jpg",
"fields": {
"cas": "2020-09-20T09:18:34.562Z",
"fotka": "header/vylet.jpg"
}
},
{
"model": "header_fotky.fotkaurlvazba",
"pk": 1,
"fields": {
"url": "/archiv/",
"fotka": "stiny.jpg",
"denni_doba": "oboji"
}
},
{
"model": "header_fotky.fotkaurlvazba",
"pk": 2,
"fields": {
"url": "/clanky/",
"fotka": "kryptografie.jpg",
"denni_doba": "den"
}
},
{
"model": "header_fotky.fotkaurlvazba",
"pk": 3,
"fields": {
"url": "/clanky/",
"fotka": "ohen.jpg",
"denni_doba": "noc"
}
},
{
"model": "header_fotky.fotkaurlvazba",
"pk": 4,
"fields": {
"url": "/zadani/",
"fotka": "baliky.jpg",
"denni_doba": "den"
}
},
{
"model": "header_fotky.fotkaurlvazba",
"pk": 5,
"fields": {
"url": "/zadani/",
"fotka": "stiny.jpg",
"denni_doba": "noc"
}
},
{
"model": "header_fotky.fotkaurlvazba",
"pk": 6,
"fields": {
"url": "/co-je-MaM/",
"fotka": "vikendovka.jpg",
"denni_doba": "den"
}
},
{
"model": "header_fotky.fotkaurlvazba",
"pk": 7,
"fields": {
"url": "/co-je-MaM/",
"fotka": "noc.jpg",
"denni_doba": "noc"
}
},
{
"model": "header_fotky.fotkaurlvazba",
"pk": 8,
"fields": {
"url": "/soustredeni/",
"fotka": "beh.jpg",
"denni_doba": "den"
}
},
{
"model": "header_fotky.fotkaurlvazba",
"pk": 9,
"fields": {
"url": "/soustredeni/",
"fotka": "vylet.jpg",
"denni_doba": "noc"
}
},
{
"model": "header_fotky.fotkaurlvazba",
"pk": 10,
"fields": {
"url": "/login/",
"fotka": "baliky.jpg",
"denni_doba": "den"
}
},
{
"model": "header_fotky.fotkaurlvazba",
"pk": 11,
"fields": {
"url": "/login/",
"fotka": "stiny.jpg",
"denni_doba": "noc"
}
},
{
"model": "header_fotky.fotkaurlvazba",
"pk": 12,
"fields": {
"url": "/profil/",
"fotka": "baliky.jpg",
"denni_doba": "den"
}
},
{
"model": "header_fotky.fotkaurlvazba",
"pk": 13,
"fields": {
"url": "/profil/",
"fotka": "stiny.jpg",
"denni_doba": "noc"
}
}
]

100
sitetree_new.json → data/sitetree_new.json

@ -397,7 +397,7 @@
"fields": { "fields": {
"title": "\u00davod", "title": "\u00davod",
"hint": "", "hint": "",
"url": "/soustredeni/uvod/", "url": "/soustredeni/",
"urlaspattern": false, "urlaspattern": false,
"tree": 1, "tree": 1,
"hidden": false, "hidden": false,
@ -558,5 +558,103 @@
"sort_order": 24, "sort_order": 24,
"access_permissions": [] "access_permissions": []
} }
},
{
"model": "sitetree.treeitem",
"pk": 28,
"fields": {
"title": "HIDDEN",
"hint": "",
"url": "/korektury/",
"urlaspattern": false,
"tree": 1,
"hidden": false,
"alias": null,
"description": "",
"inmenu": true,
"inbreadcrumbs": true,
"insitetree": true,
"access_loggedin": false,
"access_guest": false,
"access_restricted": true,
"access_perm_type": 1,
"parent": null,
"sort_order": 28,
"access_permissions": [
1
]
}
},
{
"model": "sitetree.treeitem",
"pk": 30,
"fields": {
"title": "Aktu\u00e1ln\u00ed",
"hint": "",
"url": "/korektury/",
"urlaspattern": false,
"tree": 1,
"hidden": false,
"alias": null,
"description": "",
"inmenu": true,
"inbreadcrumbs": true,
"insitetree": true,
"access_loggedin": false,
"access_guest": false,
"access_restricted": false,
"access_perm_type": 1,
"parent": 28,
"sort_order": 30,
"access_permissions": []
}
},
{
"model": "sitetree.treeitem",
"pk": 31,
"fields": {
"title": "Zastaral\u00e9",
"hint": "",
"url": "/korektury/zastarale/",
"urlaspattern": false,
"tree": 1,
"hidden": false,
"alias": null,
"description": "",
"inmenu": true,
"inbreadcrumbs": true,
"insitetree": true,
"access_loggedin": false,
"access_guest": false,
"access_restricted": false,
"access_perm_type": 1,
"parent": 28,
"sort_order": 31,
"access_permissions": []
}
},
{
"model": "sitetree.treeitem",
"pk": 32,
"fields": {
"title": "N\u00e1pov\u011bda",
"hint": "",
"url": "/korektury/help/",
"urlaspattern": false,
"tree": 1,
"hidden": false,
"alias": null,
"description": "",
"inmenu": true,
"inbreadcrumbs": true,
"insitetree": true,
"access_loggedin": false,
"access_guest": false,
"access_restricted": false,
"access_perm_type": 1,
"parent": 28,
"sort_order": 32,
"access_permissions": []
}
} }
] ]

6
galerie/templates/galerie/Base.html

@ -1,6 +0,0 @@
{% extends "base.html" %}
{# TODO predelat pres context processor #}
{% block header %}soustredeni{% endblock %}
{% block menu_soustredeni %}selected{% endblock %}
{% block submenu %}{% include 'seminar/soustredeni/submenu.html' %}{% endblock %}

2
galerie/templates/galerie/Galerie.html

@ -1,4 +1,4 @@
{% extends "galerie/Base.html" %} {% extends "base.html" %}
{% block nadpis1a %} {% block nadpis1a %}

6
galerie/templates/galerie/GalerieNahled.html

@ -1,4 +1,4 @@
{% extends "galerie/Base.html" %} {% extends "base.html" %}
{% block nadpis1a %} {% block nadpis1a %}
Galerie {{galerie.nazev}} Galerie {{galerie.nazev}}
@ -61,7 +61,7 @@ Galerie {{galerie.nazev}}
{{ galerie|truncatechars:max_delka_nazvu }} {{ galerie|truncatechars:max_delka_nazvu }}
</div> </div>
</a> </a>
{% if user.is_staff and galerie.zobrazit > 0 %} {% if user.je_org and galerie.zobrazit > 0 %}
<div class="mam-org-only-galerie"> <div class="mam-org-only-galerie">
({{galerie.poradi}}) ({{galerie.poradi}})
<span class="plus"><a href="plus/{{galerie.pk}}/">+</a></span> <span class="plus"><a href="plus/{{galerie.pk}}/">+</a></span>
@ -73,7 +73,7 @@ Galerie {{galerie.nazev}}
{% endwith %} {% endwith %}
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if user.is_staff and galerie.zobrazit > 0 %} {% if user.je_org and galerie.zobrazit > 0 %}
<div class="mam-org-only"> <div class="mam-org-only">
<a href="./new">Vytvořit novou podgalerii </a> <a href="./new">Vytvořit novou podgalerii </a>
</div> </div>

2
galerie/templates/galerie/GalerieNew.html

@ -1,4 +1,4 @@
{% extends "galerie/Base.html" %} {% extends "base.html" %}
{% block title %}{% block nadpis1a %} {% block title %}{% block nadpis1a %}
Vytvářím novou galerii Vytvářím novou galerii

7
galerie/urls.py

@ -1,13 +1,14 @@
# coding: utf-8 # coding: utf-8
from django.urls import path from django.urls import path
from seminar.utils import org_required
from . import views from . import views
urlpatterns = [ urlpatterns = [
path('<int:pk>/', views.nahled), path('<int:pk>/', views.nahled),
path('<int:pk>/<int:fotka>/', views.detail), path('<int:pk>/<int:fotka>/', views.detail),
path('<int:galerie>/new/', views.new_galerie), path('<int:galerie>/new/', org_required(views.new_galerie)),
path('<int:galerie>/plus/<int:subgalerie>/', views.plus_galerie), path('<int:galerie>/plus/<int:subgalerie>/', org_required(views.plus_galerie)),
path('<int:galerie>/minus/<int:subgalerie>/', views.minus_galerie), path('<int:galerie>/minus/<int:subgalerie>/', org_required(views.minus_galerie)),
] ]

6
galerie/views.py

@ -14,7 +14,7 @@ from galerie.forms import KomentarForm, NewGalerieForm
def zobrazit(galerie, request): def zobrazit(galerie, request):
preview = False preview = False
if galerie.zobrazit >= 1: if galerie.zobrazit >= 1:
if request.user.is_staff: if request.user.je_org:
preview = True; preview = True;
else: else:
raise Http404 raise Http404
@ -35,7 +35,7 @@ def nahled(request, pk, soustredeni):
galerie = get_object_or_404(Galerie, pk=pk) galerie = get_object_or_404(Galerie, pk=pk)
podgalerie = Galerie.objects.filter(galerie_up = galerie).order_by('poradi') podgalerie = Galerie.objects.filter(galerie_up = galerie).order_by('poradi')
if not request.user.is_staff: if not request.user.je_org:
podgalerie = podgalerie.filter(zobrazit__lt=1) podgalerie = podgalerie.filter(zobrazit__lt=1)
obrazky = Obrazek.objects.filter(galerie = galerie).order_by('poradi', 'nazev') obrazky = Obrazek.objects.filter(galerie = galerie).order_by('poradi', 'nazev')
@ -44,7 +44,7 @@ def nahled(request, pk, soustredeni):
sourozenci = [] sourozenci = []
if galerie.galerie_up: if galerie.galerie_up:
sourozenci = galerie.galerie_up.galerie_set.all().order_by('poradi') sourozenci = galerie.galerie_up.galerie_set.all().order_by('poradi')
if not request.user.is_staff: if not request.user.je_org:
sourozenci = sourozenci.filter(zobrazit__lt=1) sourozenci = sourozenci.filter(zobrazit__lt=1)
predchozi = None predchozi = None

0
header_fotky/__init__.py

10
header_fotky/admin.py

@ -0,0 +1,10 @@
from django.contrib import admin
from django.contrib.admin import ModelAdmin
import header_fotky.models as m
class FotkaPozadiAdmin(ModelAdmin):
readonly_fields = ['cas']
admin.site.register(m.FotkaHeader, FotkaPozadiAdmin)
admin.site.register(m.FotkaUrlVazba)

5
header_fotky/apps.py

@ -0,0 +1,5 @@
from django.apps import AppConfig
class HeaderFotkyConfig(AppConfig):
name = 'header_fotky'

45
header_fotky/context_processors.py

@ -0,0 +1,45 @@
from datetime import datetime, date
import random
from django.conf import settings
from header_fotky.models import FotkaUrlVazba
def vzhled(request):
''' Podle casu prida do templatu, zdali je nebo neni noc '''
hodin = datetime.now().hour
if (hodin <= 6) or (hodin >= 20):
noc = True
nedoba = 'den'
doba = 'noc'
else:
noc = False
nedoba = 'noc'
doba = 'den'
url = request.path
fotky = FotkaUrlVazba.objects.exclude(denni_doba=nedoba)
fotka = None
# TODO rychlejší patternmatch?
while (fotka is None) and (url != ''):
presne = fotky.filter(url__exact=url)
if presne.count() > 0:
presne_doba = presne.filter(denni_doba=doba)
if presne_doba.count() > 0:
fotka = random.choice(presne_doba).url_fotky()
else:
fotka = random.choice(presne).url_fotky()
url = url[:-1]
index = url.rfind('/')
if index != -1:
url = url[:index+1]
if fotka is None:
fotka = settings.STATIC_URL + "images/header/vikendovka.jpg"
return {'noc': noc, 'fotka': fotka}

63
header_fotky/migrations/0001_initial.py

@ -0,0 +1,63 @@
# Generated by Django 2.2.15 on 2020-09-20 09:14
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
from shutil import copytree
def zkopiruj_fotky(apps, schema_editor):
try:
copytree("mamweb/static/images/header/", "media/header/") # FIXME: bylo tu dirs_exists_ok=True, nekompatibilní s Py 3.7
except FileExistsError:
pass
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='FotkaHeader',
fields=[
('cas', models.DateTimeField(default=django.utils.timezone.now, help_text='Čas vložení fotky',
verbose_name='čas vložení fotky')),
('nazev',
models.CharField(help_text='Název např. archiv_noc', max_length=50, primary_key=True, serialize=False,
unique=True, verbose_name='název fotky')),
('fotka', models.ImageField(upload_to='header')),
],
options={
'verbose_name': 'fotka do pozadí menu',
'verbose_name_plural': 'fotky do pozadí menu',
'db_table': 'fotky_header',
'ordering': ['-cas'],
},
),
migrations.CreateModel(
name='FotkaUrlVazba',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('url',
models.CharField(blank=True, help_text='url prefix stránek např: /archiv/ nebo /', max_length=100,
verbose_name='URL')),
('denni_doba', models.CharField(choices=[('den', 'Zobrazit jen ve dne'), ('noc', 'Zobrazit jen v noci'),
('oboji', 'Zobrazovat pořád')], default='oboji', max_length=16,
verbose_name='denní doba')),
('fotka', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='header_fotky.FotkaHeader',
verbose_name='fotka')),
],
options={
'verbose_name': 'vazba url a fotky do pozadí menu',
'verbose_name_plural': 'vazby url a fotek do pozadí menu',
'db_table': 'fotky_url_vazby',
'ordering': ['url'],
},
),
migrations.RunPython(zkopiruj_fotky, migrations.RunPython.noop),
]

0
header_fotky/migrations/__init__.py

65
header_fotky/models.py

@ -0,0 +1,65 @@
from django.core.exceptions import ValidationError
from django.db import models
from django.utils import timezone
class FotkaHeader(models.Model):
class Meta:
ordering = ['-cas']
db_table = 'fotky_header'
verbose_name = u'fotka do pozadí menu'
verbose_name_plural = u'fotky do pozadí menu'
cas = models.DateTimeField(u'čas vložení fotky', default=timezone.now, help_text='Čas vložení fotky')
nazev = models.CharField(
u'název fotky', null=False, blank=False, unique=True, primary_key=True,
max_length=50, help_text='Název např. archiv_noc'
)
fotka = models.ImageField(upload_to='header', null=False, blank=False)
def __str__(self):
return self.nazev
def clean(self):
if not self.fotka:
raise ValidationError("Chybí obrázek")
""" Kontroluje, zda sedí poměr stran """
if abs(self.fotka.width - (self.fotka.height * 970 / 350)) > 2:
raise ValidationError("Obrázek by měl mít rozměry 970w na 350h, nebo alespoň podobný poměr stran.")
super().clean()
class FotkaUrlVazba(models.Model):
class Meta:
ordering = ['url']
db_table = 'fotky_url_vazby'
verbose_name = u'vazba url a fotky do pozadí menu'
verbose_name_plural = u'vazby url a fotek do pozadí menu'
url = models.CharField(
u'URL', blank=True, null=False, max_length=100,
help_text='url prefix stránek např: /archiv/ nebo /'
)
fotka = models.ForeignKey(
FotkaHeader, blank=False, null=False, verbose_name='fotka',
on_delete=models.CASCADE
)
DOBA_DEN = 'den'
DOBA_NOC = 'noc'
DOBA_OBOJI = 'oboji'
DOBA_CHOICES = [
(DOBA_DEN, 'Zobrazit jen ve dne'),
(DOBA_NOC, 'Zobrazit jen v noci'),
(DOBA_OBOJI, 'Zobrazovat pořád')]
denni_doba = models.CharField('denní doba', max_length=16, choices=DOBA_CHOICES, blank=False, default=DOBA_OBOJI)
def __str__(self):
return self.url
def url_fotky(self):
return self.fotka.fotka.url

4
korektury/models.py

@ -103,7 +103,7 @@ class KorekturovanePDF(models.Model):
# Změnil se počet stran, ukládáme # Změnil se počet stran, ukládáme
super(KorekturovanePDF, self).save() super(KorekturovanePDF, self).save()
def save(self): def save(self, **kwargs):
# Pokud se nezmenilo PDF, tak nepregenerovavej nahledy # Pokud se nezmenilo PDF, tak nepregenerovavej nahledy
try: try:
original = KorekturovanePDF.objects.get(pk=self.pk) original = KorekturovanePDF.objects.get(pk=self.pk)
@ -113,7 +113,7 @@ class KorekturovanePDF(models.Model):
except ObjectDoesNotExist: except ObjectDoesNotExist:
pass pass
# uložíme nahrávané pdf # uložíme nahrávané pdf
super(KorekturovanePDF, self).save() super(KorekturovanePDF, self).save(kwargs)
# uložíme png a změněný počet stran # uložíme png a změněný počet stran
self.convert() self.convert()

13
korektury/templates/korektury/base.html

@ -1,13 +0,0 @@
{% extends "base.html" %}
{% block submenu %}
{% include "korektury/submenu.html" %}
{% endblock %}
{% block content %}
{# blok do kterého se nacita text, v pripade jinyhc templatu obalit vlastnim blokem #}
{% endblock %}
{% block title %}
{# blok pro titulek stranky #}
{% endblock %}

8
korektury/templates/korektury/help.html

@ -1,10 +1,4 @@
{% extends "korektury/base.html" %} {% extends "base.html" %}
{% block submenu %}
{% with "help" as selected %}
{% include "korektury/submenu.html" %}
{% endwith %}
{% endblock %}
{% load staticfiles %} {% load staticfiles %}

4
korektury/templates/korektury/opraf.html

@ -36,12 +36,12 @@
id="neni_chyba_checkbox" id="neni_chyba_checkbox"
name="neni_chyba_checkbox" name="neni_chyba_checkbox"
onchange="toggle_corrections('neni_chyba')" checked> onchange="toggle_corrections('neni_chyba')" checked>
<label for="neni_chyba_checkbox">Není chyba ({{neni_chyba_cnt}})</labe> <label for="neni_chyba_checkbox">Není chyba ({{neni_chyba_cnt}})</label>
<input type="checkbox" <input type="checkbox"
id="k_zaneseni_checkbox" id="k_zaneseni_checkbox"
name="k_zaneseni_checkbox" name="k_zaneseni_checkbox"
onchange="toggle_corrections('k_zaneseni')" checked> onchange="toggle_corrections('k_zaneseni')" checked>
<label for="k_zaneseni_checkbox">K zanesení ({{k_zaneseni_cnt}})</labe> <label for="k_zaneseni_checkbox">K zanesení ({{k_zaneseni_cnt}})</label>
<hr/> <hr/>

6
korektury/templates/korektury/seznam.html

@ -1,10 +1,6 @@
{% extends "korektury/base.html" %} {% extends "base.html" %}
{% load staticfiles %} {% load staticfiles %}
{% block submenu %}
{% include "korektury/submenu.html" %}
{% endblock %}
{% block script%} {% block script%}
<link rel="stylesheet" type="text/css" media="screen, projection" href="{% static "korektury/opraf-list.css" %}" /> <link rel="stylesheet" type="text/css" media="screen, projection" href="{% static "korektury/opraf-list.css" %}" />
{% endblock %} {% endblock %}

13
korektury/templates/korektury/submenu.html

@ -1,13 +0,0 @@
{% with "/korektury" as cesta %}
<div id='submenu'>
<ul>
<li class="{% if selected == "aktualni" %}selected{% endif %}"><a href="{{cesta}}/">Aktuální</a>
<li class="{% if selected == "zastarale" %}selected{% endif %}"><a href="{{cesta}}/zastarale/">Zastaralé</a>
<li class="{% if selected == "help" %}selected{% endif %}"><a href="{{cesta}}/help/">Nápověda</a>
</ul>
</div>
{% endwith %}

BIN
korektury/testpdfs/A.pdf

Binary file not shown.

5125
korektury/testpdfs/B.pdf

File diff suppressed because one or more lines are too long

69
korektury/testutils.py

@ -0,0 +1,69 @@
import logging
import os
from shutil import copyfile, rmtree
from django.db import transaction
from django.conf import settings
from korektury.models import KorekturovanePDF, generate_filename
logger = logging.getLogger(__name__)
@transaction.atomic
def create_test_pdf(rnd, organizatori):
logger.info('Vyrábím testovací pdf ke korekturovani')
try:
testpdfs = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'testpdfs')
# smaže minulé pdfka a obrázky k nim a vytvoří (znovu) jejich složky
pdf_dir = os.path.join(settings.BASE_DIR, os.path.join('media', settings.KOREKTURY_PDF_DIR))
img_dir = os.path.join(settings.BASE_DIR, os.path.join('media', settings.KOREKTURY_IMG_DIR))
rmtree(pdf_dir, ignore_errors=True)
os.makedirs(pdf_dir)
rmtree(img_dir, ignore_errors=True)
os.makedirs(img_dir)
def gen_filename(filename):
name = generate_filename(None, filename)
print(name)
copyfile(os.path.join(testpdfs, filename), os.path.join(settings.BASE_DIR, os.path.join('media', name)))
return name
# TODO silent ghostscript (vypisuje odstavec za každou stránku…)
KorekturovanePDF.objects.create(
nazev='B', komentar='Neuronové sítě', org=rnd.choice(organizatori), pdf=gen_filename(filename='B.pdf')
)
KorekturovanePDF.objects.create(
nazev='A', komentar='M&M: Jak řešit?', org=rnd.choice(organizatori), pdf=gen_filename(filename='A.pdf')
)
korekturovane_pdf = KorekturovanePDF.objects.create(
nazev='A', komentar='M&M: Jak řešit?', org=rnd.choice(organizatori), pdf=gen_filename(filename='A.pdf'),
status='zanaseni'
)
KorekturovanePDF.objects.create(
nazev='A', komentar='M&M: Jak řešit?', org=rnd.choice(organizatori), pdf=gen_filename(filename='A.pdf'),
status='zastarale'
)
except (FileNotFoundError, Exception) as e:
# TODO najít správné chyby, které vyhazují různé systémy při neexistenci ImageMagick, nebo knihoven
logger.error(str(e))
logger.error(
'Chyba vytváření testovacích korektur, pravděpodobně není nainstalován ImageMagick nebo některá z knihoven'
'pro práci se soubory pdf (ghostscript) nebo png (libpng?).\n'
'''
Instalaci na linux provedete např. příkazy:
sudo apt-get build-dep imagemagick
git clone https://github.com/ImageMagick/ImageMagick.git
cd ImageMagick/
./configure
make
sudo make install
sudo ldconfig /usr/local/lib
cd ..
rm -r ImageMagick/
'''
)

12
korektury/urls.py

@ -1,12 +1,10 @@
from django.urls import path from django.urls import path
from django.contrib.auth.decorators import user_passes_test from seminar.utils import org_required
from . import views from . import views
staff_member_required = user_passes_test(lambda u: u.is_staff)
urlpatterns = [ urlpatterns = [
path('korektury/', staff_member_required(views.KorekturyAktualniListView.as_view()), name='korektury-list'), path('korektury/', org_required(views.KorekturyAktualniListView.as_view()), name='korektury-list'),
path('korektury/zastarale/', staff_member_required(views.KorekturyZastaraleListView.as_view()), name='korektury-list'), path('korektury/zastarale/', org_required(views.KorekturyZastaraleListView.as_view()), name='korektury-list'),
path('korektury/<int:pdf>/', staff_member_required(views.KorekturyView.as_view()), name='korektury'), path('korektury/<int:pdf>/', org_required(views.KorekturyView.as_view()), name='korektury'),
path('korektury/help/', staff_member_required(views.KorekturyHelpView.as_view()), name='korektury-help'), path('korektury/help/', org_required(views.KorekturyHelpView.as_view()), name='korektury-help'),
] ]

2
mamweb/admin.py

@ -8,6 +8,7 @@ from django.contrib.flatpages.admin import FlatpageForm as FlatpageFormOld
from django import forms from django import forms
from ckeditor_uploader.widgets import CKEditorUploadingWidget from ckeditor_uploader.widgets import CKEditorUploadingWidget
class FlatpageForm(FlatpageFormOld): class FlatpageForm(FlatpageFormOld):
content = forms.CharField(widget=CKEditorUploadingWidget()) content = forms.CharField(widget=CKEditorUploadingWidget())
class Meta: class Meta:
@ -22,3 +23,4 @@ class FlatPageAdmin(FlatPageAdminOld):
# We have to unregister the normal admin, and then reregister ours # We have to unregister the normal admin, and then reregister ours
admin.site.unregister(FlatPage) admin.site.unregister(FlatPage)
admin.site.register(FlatPage, FlatPageAdmin) admin.site.register(FlatPage, FlatPageAdmin)

12
mamweb/context_processors.py

@ -1,12 +0,0 @@
from datetime import datetime, date
def vzhled(request):
''' Podle casu prida do templatu, zdali je nebo neni noc '''
hodin = datetime.now().hour
if (hodin <= 6) or (hodin >= 20):
noc = True
else:
noc = False
return {'noc' : noc}

3
mamweb/settings_common.py

@ -77,7 +77,7 @@ TEMPLATES = [
'django.template.context_processors.request', 'django.template.context_processors.request',
'django.contrib.messages.context_processors.messages', 'django.contrib.messages.context_processors.messages',
'sekizai.context_processors.sekizai', 'sekizai.context_processors.sekizai',
'mamweb.context_processors.vzhled', 'header_fotky.context_processors.vzhled',
) )
}, },
}, },
@ -127,6 +127,7 @@ INSTALLED_APPS = (
'galerie', 'galerie',
'korektury', 'korektury',
'prednasky', 'prednasky',
'header_fotky',
# Admin upravy: # Admin upravy:

36
mamweb/static/css/mamweb.css

@ -193,38 +193,6 @@ h1 {
top: 58px; top: 58px;
} }
/*
fotky:
todo url
kryptografie
baliky
beh
mam_cernobile -pro archiv? asi ne
vylet
spolecna -spíš ne, moc lidí
snih
ohen
noc
stiny
vikendovka
*/
#header.cojemam { background-image: url("../images/header/vikendovka.jpg");}
#header.soustredeni { background-image: url("../images/header/beh.jpg");}
#header.zadani { background-image: url("../images/header/baliky.jpg");}
#header.clanky { background-image: url("../images/header/kryptografie.jpg");}
#header.archiv { background-image: url("../images/header/stiny.jpg");}
#header.NOC {background-image: url("../images/header/noc.jpg");}
#header.NOCcojemam { background-image: url("../images/header/noc.jpg");}
#header.NOCsoustredeni { background-image: url("../images/header/vylet.jpg");}
#header.NOCzadani { background-image: url("../images/header/stiny.jpg");}
#header.NOCclanky { background-image: url("../images/header/ohen.jpg");}
#header.NOCarchiv { background-image: url("../images/header/stiny.jpg");}
#header img.logo { #header img.logo {
position: absolute center; position: absolute center;
width: 100%; width: 100%;
@ -318,6 +286,10 @@ ul.submenu li>a:hover {
color: black; color: black;
} }
ul.menu li.active>a, ul.submenu li.active>a {
color: black;
}
/* konec nového menu */ /* konec nového menu */
div.novinky_name { div.novinky_name {

0
mamweb/static/images/logo_co-je-mam.svg → mamweb/static/images/logo_1.svg

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

0
mamweb/static/images/logo_jak-resit.svg → mamweb/static/images/logo_2.svg

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

0
mamweb/static/images/logo_aktualni.svg → mamweb/static/images/logo_3.svg

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

0
mamweb/static/images/logo_soustredeni.svg → mamweb/static/images/logo_4.svg

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

0
mamweb/static/images/logo_archiv.svg → mamweb/static/images/logo_5.svg

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

0
mamweb/static/images/logo_profil.svg → mamweb/static/images/logo_6.svg

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

9
mamweb/templates/base.html

@ -12,7 +12,7 @@
<link href="{% static 'css/mamweb.css' %}" rel="stylesheet"> <link href="{% static 'css/mamweb.css' %}" rel="stylesheet">
<link href="{% static 'css/prettyPhoto.css' %}" rel="stylesheet" type="text/css" media="screen" charset="utf-8" /> <link href="{% static 'css/prettyPhoto.css' %}" rel="stylesheet" type="text/css" media="screen" charset="utf-8" />
<script src="{% static 'js/jquery-1.11.1.js' %}"></script> <script src="{% static 'js/jquery-1.11.1.js' %}"></script>
<script src="{% static '/jquery-3.4.1.js' %}"></script> <script src="{% static 'js/jquery-3.4.1.js' %}"></script>
<link rel="stylesheet" type="text/css" href="{% static 'fluent_comments/css/ajaxcomments.css' %}" /> <link rel="stylesheet" type="text/css" href="{% static 'fluent_comments/css/ajaxcomments.css' %}" />
<script type="text/javascript" src="{% static 'fluent_comments/js/ajaxcomments.js' %}"></script> <script type="text/javascript" src="{% static 'fluent_comments/js/ajaxcomments.js' %}"></script>
@ -56,8 +56,9 @@
<div class='col-md-12'> <div class='col-md-12'>
<a href='/'> <a href='/'>
<div id="title" >M&M - korespondenční seminář a časopis MFF&nbspUK</div> <div id="title" >M&M - korespondenční seminář a časopis MFF&nbspUK</div>
<div id="header" class="{% if noc %}NOC{% endif %}{% block header %}{% endblock %}"> <div id="header" style="background-image: url('{{ fotka }}')">
<img class="logo" src="{% static 'images/logo.svg' %}" /> {# TODO style=… není fancy řešení, ale u <img> se bojím, že mi to rozbije vzhled #}
{% sitetree_menu from "main_menu" include "trunk" template "logo.html" %}
<img class="logo-mobile" src="{% static 'images/logo-mobile.svg' %}" /> <img class="logo-mobile" src="{% static 'images/logo-mobile.svg' %}" />
</div> </div>
</a> </a>
@ -106,7 +107,7 @@
<div id="footer"> <div id="footer">
<p class="license">S obsahem webu M&amp;M je možné nakládat dle licence <a href="https://creativecommons.org/licenses/by/3.0/cz/">Creative Commons Attribution 3.0</a>.</p> <p class="license">S obsahem webu M&amp;M je možné nakládat dle licence <a href="https://creativecommons.org/licenses/by/3.0/cz/">Creative Commons Attribution 3.0</a>.</p>
</div> </div>
<p class="license-mobile">Korespondenční seminář M&M organizují převážně studenti <a herf="https://www.mff.cuni.cz/">MFF UK</a>. Organizaci semináře a vydávání časopisu podporuje <a href="https://jcmf.cz/">Jednota českých matematiků a fyziků</a>. S obsahem webu M&amp;M je možné nakládat dle licence <a href="https://creativecommons.org/licenses/by/3.0/cz/">Creative Commons Attribution 3.0</a>.</p> <p class="license-mobile">Korespondenční seminář M&M organizují převážně studenti <a href="https://www.mff.cuni.cz/">MFF UK</a>. Organizaci semináře a vydávání časopisu podporuje <a href="https://jcmf.cz/">Jednota českých matematiků a fyziků</a>. S obsahem webu M&amp;M je možné nakládat dle licence <a href="https://creativecommons.org/licenses/by/3.0/cz/">Creative Commons Attribution 3.0</a>.</p>
</div> </div>
</div> </div>
</div> </div>

102
mamweb/templates/flatpages/default.html

@ -9,105 +9,3 @@
{{ flatpage.content }} {{ flatpage.content }}
</div> </div>
{% endblock content %} {% endblock content %}
{# nahraj spravne submenu #}
{% block submenu %}
{# co-je-MaM #}
{% if "/co-je-MaM/" in flatpage.url %}
{% if "/uvod/" in flatpage.url %}
{% with "uvod" as selected %}
{% include "seminar/cojemam/submenu.html" %}
{% endwith %}
{% elif "jak-resit" in flatpage.url %}
{% with "jak-resit" as selected %}
{% include "seminar/cojemam/submenu.html" %}
{% endwith %}
{% elif "odmeny" in flatpage.url %}
{% with "odmeny" as selected %}
{% include "seminar/cojemam/submenu.html" %}
{% endwith %}
{% elif "FAQ" in flatpage.url %}
{% with "FAQ" as selected %}
{% include "seminar/cojemam/submenu.html" %}
{% endwith %}
{% elif "kontakt" in flatpage.url %}
{% else %}
{% include "seminar/cojemam/submenu.html" %}
{% endif %}
{% endif %}
{# soustredeni #}
{% if "/soustredeni/" in flatpage.url %}
{% if "/pripravujeme/" in flatpage.url %}
{% with "pripravujeme" as selected %}
{% include "seminar/soustredeni/submenu.html" %}
{% endwith %}
{% else %}
{% with "uvod" as selected %}
{% include "seminar/soustredeni/submenu.html" %}
{% endwith %}
{% endif %}
{% endif %}
{# zadani #}
{% if "/zadani/" in flatpage.url %}
{% if "/aktualni-cislo/" in flatpage.url %}
{% with "aktualni-cislo" as selected %}
{% include "seminar/zadani/submenu.html" %}
{% endwith %}
{% elif "/vysledkova-listina/" in flatpage.url %}
{% with "vysledkova-listina" as selected %}
{% include "seminar/zadani/submenu.html" %}
{% endwith %}
{% else %}
{% include "seminar/zadani/submenu.html" %}
{% endif %}
{% endif %}
{# clanky #}
{% if "/clanky/" in flatpage.url %}
{% if "/uvod/" in flatpage.url %}
{% with "uvod" as selected %}
{% include "seminar/clanky/submenu.html" %}
{% endwith %}
{% elif "/org/" in flatpage.url %}
{% with "org" as selected %}
{% include "seminar/clanky/submenu.html" %}
{% endwith %}
{% elif "/resitel/" in flatpage.url %}
{% with "resitel" as selected %}
{% include "seminar/clanky/submenu.html" %}
{% endwith %}
{% elif "/jak-psat-vedecky-clanek/" in flatpage.url %}
{% with "jak-psat-vedecky-clanek" as selected %}
{% include "seminar/clanky/submenu.html" %}
{% endwith %}
{% else %}
{% include "seminar/clanky/submenu.html" %}
{% endif %}
{% endif %}
{# archiv #}
{% if "/archiv/" in flatpage.url %}
{% if "/ulohy/" in flatpage.url %}
{% with "ulohy" as selected %}
{% include "seminar/archiv/submenu.html" %}
{% endwith %}
{% elif "/vysledky/" in flatpage.url %}
{% with "vysledky" as selected %}
{% include "seminar/archiv/submenu.html" %}
{% endwith %}
{% else %}
{% include "seminar/archiv/submenu.html" %}
{% endif %}
{% endif %}
{% endblock %}
{# zvirazneni menu #}
{% block menu_uvod %}{% if not "/kontakt/" in flatpage.url %}{% if "/co-je-MaM/" in flatpage.url %}selected{% endif %}{% endif %}{% endblock %}
{% block menu_soustredeni %}{% if "/soustredeni/" in flatpage.url %}selected{% endif %}{% endblock %}
{% block menu_zadani %}{% if "/zadani/" in flatpage.url %}selected{% endif %}{% endblock %}
{% block menu_clanky %}{% if "/clanky/" in flatpage.url %}selected{% endif %}{% endblock %}
{% block menu_archiv %}{% if "/archiv/" in flatpage.url %}selected{% endif %}{% endblock %}
{% block menu_odevzdat %}{% if "/kontakt/" in flatpage.url %}selected{% endif %}{% endblock %}
{# zmena titulniho obrazku #}
{% block header %}{% if "/co-je-MaM/" in flatpage.url %}cojemam{% elif "/soustredeni/" in flatpage.url %}soustredeni{% elif "/zadani/" in flatpage.url %}zadani{% elif "/clanky/" in flatpage.url %}clanky{% elif "/archiv/" in flatpage.url %}archiv{% else %}odeslat{% endif %}{% endblock header %}
{# TODO zvirazneni submenu #}

26
mamweb/templates/logo.html

@ -0,0 +1,26 @@
{% load staticfiles %}
<img class="logo"
{% for item in sitetree_items %}
{% if item.is_active or item.in_current_branch %}
{% if forloop.counter == 1 %}
src="{% static 'images/logo_1.svg' %}"
{% endif %}
{% if forloop.counter == 2 %}
src="{% static 'images/logo_2.svg' %}"
{% endif %}
{% if forloop.counter == 3 %}
src="{% static 'images/logo_3.svg' %}"
{% endif %}
{% if forloop.counter == 4 %}
src="{% static 'images/logo_4.svg' %}"
{% endif %}
{% if forloop.counter == 5 %}
src="{% static 'images/logo_5.svg' %}"
{% endif %}
{% if forloop.counter == 6 %}
src="{% static 'images/logo_6.svg' %}"
{% endif %}
{% endif %}
{% endfor %}
src="{% static 'images/logo.svg' %}"
/>

4
mamweb/templates/menu.html

@ -3,7 +3,9 @@
{% autoescape off %} {% autoescape off %}
<ul class="menu"> <ul class="menu">
{% for item in sitetree_items %} {% for item in sitetree_items %}
<li class="{% if item.has_children %}dropdown{% endif %} {% if item.is_current or item.in_current_branch %}active{% endif %}" > <li class="{% if item.has_children %}dropdown{% endif %} {% if item.is_current or item.in_current_branch %}active{% endif %}"
style="{% if item.title == "HIDDEN" %}display:none{% endif %}"
>
<a href="{% sitetree_url for item %}" > <a href="{% sitetree_url for item %}" >
{{ item.title_resolved }} {{ item.title_resolved }}
</a> </a>

4
mamweb/templates/menu_mobile.html

@ -3,7 +3,9 @@
{% autoescape off %} {% autoescape off %}
<ul class="menu_mobile"> <ul class="menu_mobile">
{% for item in sitetree_items %} {% for item in sitetree_items %}
<li class="{% if item.has_children %}dropdown{% endif %} {% if item.is_current or item.in_current_branch %}active{% endif %}"> <li class="{% if item.has_children %}dropdown{% endif %} {% if item.is_current or item.in_current_branch %}active{% endif %}"
style="{% if item.title == "HIDDEN" %}display:none{% endif %}"
>
<a href="{% if item.has_children %}#{% else %}{% sitetree_url for item %}{% endif %}" {% if item.has_children %}class="dropdown-toggle" data-toggle="dropdown"{% endif %}> <a href="{% if item.has_children %}#{% else %}{% sitetree_url for item %}{% endif %}" {% if item.has_children %}class="dropdown-toggle" data-toggle="dropdown"{% endif %}>
{{ item.title_resolved }} {{ item.title_resolved }}
</a> </a>

10
prednasky/templates/prednasky/base.html

@ -17,19 +17,17 @@ Jak moc by ses chtěl(a) zúčastnit následujících přednášek?
<form enctype="multipart/form-data" action="." method="post"> <form enctype="multipart/form-data" action="." method="post">
{% csrf_token %} {% csrf_token %}
<table>{{form.as_table}}
</table>
<table> <table>
{% for p in prednasky.prednaska_set.all %} {% for p, h in prednasky %}
<tr><td><label>{{p.org}}: <span style="font-size: 175%">{{p.nazev}}</span></label></td></tr> <tr><td><label>{{p.org}}: <span style="font-size: 175%">{{p.nazev}}</span></label></td></tr>
<tr><td><p><i>{{p.anotace}}</i></p></td></tr> <tr><td><p><i>{{p.anotace}}</i></p></td></tr>
<tr><td><label>Obor: </label> {{p.obor}}</td></tr> <tr><td><label>Obor: </label> {{p.obor}}</td></tr>
<tr><td><label>Obtížnost: </label> {{p.obtiznost}}</td> </tr> <tr><td><label>Obtížnost: </label> {{p.obtiznost}}</td> </tr>
{% if p.klicova %}<tr><td><label>Klíčová slova: </label> {{p.klicova}}</td></tr>{% endif%} {% if p.klicova %}<tr><td><label>Klíčová slova: </label> {{p.klicova}}</td></tr>{% endif%}
<tr><td>Hodnocení: <tr><td>Hodnocení:
<INPUT TYPE="radio" NAME="q{{p.pk}}" VALUE="-1"> rozhodně nechci <INPUT TYPE="radio" NAME="q{{p.pk}}" VALUE="-1" {% if h == -1 %} CHECKED="checked" {% endif %} > rozhodně nechci
<INPUT TYPE="radio" NAME="q{{p.pk}}" VALUE="0" checked> je mi to jedno <INPUT TYPE="radio" NAME="q{{p.pk}}" VALUE="0" {% if h == 0 %} CHECKED="checked" {% endif %}> je mi to jedno
<INPUT TYPE="radio" NAME="q{{p.pk}}" VALUE="1"> rozhodně chci <INPUT TYPE="radio" NAME="q{{p.pk}}" VALUE="1" {% if h == 1 %} CHECKED="checked" {% endif %}> rozhodně chci
</td></tr> </td></tr>
<tr><td>&nbsp;</td></tr> <tr><td>&nbsp;</td></tr>
{% endfor %} {% endfor %}

6
prednasky/templates/prednasky/metaseznam_prednasek.html

@ -1,9 +1,5 @@
{% extends "prednasky/base.html" %} {% extends "prednasky/base.html" %}
{% block header %}hlasovani{% endblock %}
{% block content %} {% block content %}
<h1>{% block nadpis1a %}{% block nadpis1b %}Hlasování o přednáškách{% endblock %}{% endblock %}</h1> <h1>{% block nadpis1a %}{% block nadpis1b %}Hlasování o přednáškách{% endblock %}{% endblock %}</h1>
{# Projdi vsechny seznamy #} {# Projdi vsechny seznamy #}
@ -19,6 +15,8 @@
<a href="/prednasky/seznam_prednasek/{{seznam.id}}/export">Export</a> <a href="/prednasky/seznam_prednasek/{{seznam.id}}/export">Export</a>
</li> </li>
{% endfor %} {% endfor %}
</ul>
</div>
{% endblock %} {% endblock %}

6
prednasky/templates/prednasky/seznam_prednasek.html

@ -1,9 +1,5 @@
{% extends "prednasky/base.html" %} {% extends "prednasky/base.html" %}
{% block header %}seznam_prednasek{% endblock %}
{% block content %} {% block content %}
<h1>{% block nadpis1a %}Průběžné výsledky hlasování{% endblock %}</h1> <h1>{% block nadpis1a %}Průběžné výsledky hlasování{% endblock %}</h1>
<div class="mam-org-only"> <div class="mam-org-only">
@ -15,5 +11,7 @@
{{ prednaska.body }} b</i>) &ndash; {{ prednaska.org }} {{ prednaska.body }} b</i>) &ndash; {{ prednaska.org }}
</li> </li>
{% endfor %} {% endfor %}
</ul>
</div>
{% endblock %} {% endblock %}

27
prednasky/urls.py

@ -1,14 +1,25 @@
from django.urls import path from django.urls import path
from django.contrib.auth.decorators import user_passes_test from seminar.utils import org_required, resitel_required
from . import views from . import views
staff_member_required = user_passes_test(lambda u: u.is_staff)
urlpatterns = [ urlpatterns = [
path('prednasky/', views.newPrednaska), path(
'prednasky/',
resitel_required(views.newPrednaska)
),
path('prednasky/hotovo', views.Prednaska_hotovo), path('prednasky/hotovo', views.Prednaska_hotovo),
path('prednasky/metaseznam_prednasek', staff_member_required(views.MetaSeznamListView.as_view()), name='metaseznam-list'), path(
path('prednasky/seznam_prednasek/<int:seznam>/export', staff_member_required(views.SeznamExportView), name='seznam-export'), 'prednasky/metaseznam_prednasek',
path('prednasky/seznam_prednasek/<int:seznam>/', staff_member_required(views.SeznamListView.as_view()), name='seznam-list'), org_required(views.MetaSeznamListView.as_view()),
# path('korektury/help/', staff_member_required(views.KorekturyHelpView.as_view()), name='korektury-help'), name='metaseznam-list'),
path(
'prednasky/seznam_prednasek/<int:seznam>/export',
org_required(views.SeznamExportView),
name='seznam-export'
),
path(
'prednasky/seznam_prednasek/<int:seznam>/',
org_required(views.SeznamListView.as_view()),
name='seznam-list'
),
] ]

37
prednasky/views.py

@ -4,41 +4,52 @@ from django.views import generic
from django.shortcuts import HttpResponseRedirect from django.shortcuts import HttpResponseRedirect
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Sum from django.db.models import Sum
from django.forms import Form
from prednasky.models import Prednaska, Hlasovani, Seznam, STAV_NAVRH from prednasky.models import Prednaska, Hlasovani, Seznam, STAV_NAVRH
from seminar.models import Soustredeni from seminar.models import Soustredeni, Osoba
from prednasky.forms import NewPrednaskyForm
def newPrednaska(request): def newPrednaska(request):
# hlasovani se vztahuje k nejnovejsimu soustredeni # hlasovani se vztahuje k nejnovejsimu soustredeni
sous = Soustredeni.objects.first() sous = Soustredeni.objects.first()
seznam = Seznam.objects.filter(soustredeni = sous, stav = STAV_NAVRH).first() seznam = Seznam.objects.filter(soustredeni = sous, stav = STAV_NAVRH).first()
print(seznam) osoba = Osoba.objects.filter(user=request.user).first()
ucastnik = osoba.plne_jmeno() + ' ' + str(osoba.id)
# obsluha formulare # obsluha formulare
if request.method == 'POST': if request.method == 'POST':
form = NewPrednaskyForm(request.POST, request.FILES) form = Form(request.POST, request.FILES)
if form.is_valid(): if form.is_valid():
jmeno = form.cleaned_data['ucastnik'] # id z důvodu duplicitních jmen (přechod z jména na objekt Osoby nějak kape na tom,
# že všechna předchozí hlasování zde mají náhodný string…)
# TODO Změnit to na Osobu
# TODO v následujících řádcích je zbytečně mnoho dotazů na QuerySet (pokud účastník hlasoval, hlasoval u všech)
for i in request.POST: for i in request.POST:
if i[0] == 'q': if i[0] == 'q':
hlasovani = Hlasovani() prednaska = Prednaska.objects.filter(pk=int(i[1:]))[0]
print("q:"+i[1:]) hlasovani = Hlasovani.objects.filter(ucastnik=ucastnik, prednaska=prednaska).first()
hlasovani.prednaska = Prednaska.objects.filter(pk = int(i[1:]))[0] if not hlasovani:
hlasovani = Hlasovani()
hlasovani.prednaska = prednaska
hlasovani.ucastnik = ucastnik
hlasovani.seznam = seznam
hlasovani.body = int(request.POST[i]) hlasovani.body = int(request.POST[i])
hlasovani.ucastnik = jmeno
hlasovani.seznam = seznam
hlasovani.save() hlasovani.save()
# presmerovani na prave vzniklou galerii # presmerovani na prave vzniklou galerii
return HttpResponseRedirect('./hotovo') return HttpResponseRedirect('./hotovo')
else: def prednaska_hodnoceni(prednaska):
form = NewPrednaskyForm() h = Hlasovani.objects.filter(ucastnik=ucastnik, prednaska=prednaska).first()
if h:
return prednaska, h.body
else:
return prednaska, 0
return render( return render(
request, request,
'prednasky/base.html', 'prednasky/base.html',
{'form': form, 'prednasky': seznam} {'prednasky': map(prednaska_hodnoceni, seznam.prednaska_set.all())}
) )

13
seminar/migrations/0001_squashed_0067_auto_20190814_0805.py

@ -877,6 +877,7 @@ class Migration(migrations.Migration):
), ),
migrations.RunSQL( migrations.RunSQL(
sql='update seminar_rocniky set rocnik_n = cast (rocnik as integer)', sql='update seminar_rocniky set rocnik_n = cast (rocnik as integer)',
reverse_sql='update seminar_rocniky set rocnik_n = cast (rocnik as nvarchar(16))',
), ),
migrations.RemoveField( migrations.RemoveField(
model_name='rocnik', model_name='rocnik',
@ -1733,15 +1734,19 @@ class Migration(migrations.Migration):
# migr 0052 # migr 0052
migrations.RunPython( migrations.RunPython(
spoj_k_organizatorum_osoby, spoj_k_organizatorum_osoby,
reverse_code=migrations.RunPython.noop,
), ),
migrations.RunPython( migrations.RunPython(
fix_problem, fix_problem,
reverse_code=migrations.RunPython.noop,
), ),
migrations.RunPython( migrations.RunPython(
fix_pohadka, fix_pohadka,
reverse_code=migrations.RunPython.noop,
), ),
migrations.RunPython( migrations.RunPython(
fix_novinka, fix_novinka,
reverse_code=migrations.RunPython.noop,
), ),
# migr 0053 # migr 0053
@ -1795,25 +1800,31 @@ class Migration(migrations.Migration):
# migr 0056 # migr 0056
migrations.RunPython( migrations.RunPython(
generuj_RocnikNody_a_CisloNody, generuj_RocnikNody_a_CisloNody,
reverse_code=migrations.RunPython.noop,
), ),
# migr 0057 # migr 0057
migrations.RunPython( migrations.RunPython(
reseni_to_Reseni, reseni_to_Reseni,
reverse_code=migrations.RunPython.noop,
), ),
# migr 0058 # migr 0058
migrations.RunPython( migrations.RunPython(
uloha_to_Uloha, uloha_to_Uloha,
reverse_code=migrations.RunPython.noop,
), ),
migrations.RunPython( migrations.RunPython(
tema_to_Tema, tema_to_Tema,
reverse_code=migrations.RunPython.noop,
), ),
migrations.RunPython( migrations.RunPython(
clanek_to_Clanek, clanek_to_Clanek,
reverse_code=migrations.RunPython.noop,
), ),
migrations.RunPython( migrations.RunPython(
konfery_rucne, konfery_rucne,
reverse_code=migrations.RunPython.noop,
), ),
# migr "fix 0058" # migr "fix 0058"
@ -1825,11 +1836,13 @@ class Migration(migrations.Migration):
# migr 0059 # migr 0059
migrations.RunPython( migrations.RunPython(
vytvor_pohadkanode, vytvor_pohadkanode,
reverse_code=migrations.RunPython.noop,
), ),
# migr 0060 # migr 0060
migrations.RunPython( migrations.RunPython(
pokacej_les, pokacej_les,
reverse_code=migrations.RunPython.noop,
), ),
migrations.RemoveField( migrations.RemoveField(

3
seminar/migrations/0019_rocnik_ciselne.py

@ -18,7 +18,8 @@ class Migration(migrations.Migration):
preserve_default=False, preserve_default=False,
), ),
migrations.RunSQL( migrations.RunSQL(
sql="update seminar_rocniky set rocnik_n = cast (rocnik as integer)" sql="update seminar_rocniky set rocnik_n = cast (rocnik as integer)",
reverse_sql='update seminar_rocniky set rocnik_n = cast (rocnik as nvarchar(16))',
), ),
migrations.RemoveField( migrations.RemoveField(
model_name='rocnik', model_name='rocnik',

8
seminar/migrations/0052_user_to_organizator.py

@ -75,8 +75,8 @@ class Migration(migrations.Migration):
] ]
operations = [ operations = [
migrations.RunPython(spoj_k_organizatorum_osoby), migrations.RunPython(spoj_k_organizatorum_osoby, migrations.RunPython.noop),
migrations.RunPython(fix_problem), migrations.RunPython(fix_problem, migrations.RunPython.noop),
migrations.RunPython(fix_pohadka), migrations.RunPython(fix_pohadka, migrations.RunPython.noop),
migrations.RunPython(fix_novinka), migrations.RunPython(fix_novinka, migrations.RunPython.noop),
] ]

2
seminar/migrations/0056_vrcholy_pro_rocniky_a_cisla.py

@ -43,5 +43,5 @@ class Migration(migrations.Migration):
] ]
operations = [ operations = [
migrations.RunPython(generuj_RocnikNody_a_CisloNody), migrations.RunPython(generuj_RocnikNody_a_CisloNody, migrations.RunPython.noop),
] ]

2
seminar/migrations/0057_reseni_to_reseni_hodnoceni.py

@ -30,5 +30,5 @@ class Migration(migrations.Migration):
] ]
operations = [ operations = [
migrations.RunPython(reseni_to_Reseni) migrations.RunPython(reseni_to_Reseni, migrations.RunPython.noop)
] ]

8
seminar/migrations/0058_problem_to_uloha_tema_clanek.py

@ -154,8 +154,8 @@ class Migration(migrations.Migration):
operations = [ operations = [
# ashes to Ashes, dust to Dust.... # ashes to Ashes, dust to Dust....
migrations.RunPython(uloha_to_Uloha), migrations.RunPython(uloha_to_Uloha, migrations.RunPython.noop),
migrations.RunPython(tema_to_Tema), migrations.RunPython(tema_to_Tema, migrations.RunPython.noop),
migrations.RunPython(clanek_to_Clanek), migrations.RunPython(clanek_to_Clanek, migrations.RunPython.noop),
migrations.RunPython(konfery_rucne), migrations.RunPython(konfery_rucne, migrations.RunPython.noop),
] ]

2
seminar/migrations/0059_vytvorit_pohadkanode.py

@ -25,5 +25,5 @@ class Migration(migrations.Migration):
] ]
operations = [ operations = [
migrations.RunPython(vytvor_pohadkanode), migrations.RunPython(vytvor_pohadkanode, migrations.RunPython.noop),
] ]

2
seminar/migrations/0060_spoj_stromy.py

@ -108,5 +108,5 @@ class Migration(migrations.Migration):
] ]
operations = [ operations = [
migrations.RunPython(pokacej_les), migrations.RunPython(pokacej_les, migrations.RunPython.noop),
] ]

2
seminar/migrations/0068_treenode_nazev.py

@ -103,5 +103,5 @@ class Migration(migrations.Migration):
name='nazev', name='nazev',
field=models.TextField(help_text='Tento název se zobrazuje v nabídkách pro výběr vhodného TreeNode', null=True, verbose_name='název tohoto node'), field=models.TextField(help_text='Tento název se zobrazuje v nabídkách pro výběr vhodného TreeNode', null=True, verbose_name='název tohoto node'),
), ),
migrations.RunPython(fix_all_names), migrations.RunPython(fix_all_names, migrations.RunPython.noop),
] ]

6
seminar/migrations/0080_zruseni_claneknode_a_konferanode.py

@ -65,6 +65,9 @@ class Migration(migrations.Migration):
model_name='reseni', model_name='reseni',
name='text_zkraceny', name='text_zkraceny',
), ),
migrations.DeleteModel( # nejdříve musím smazat objekt ukazující na konferu,
name='KonferaNode', # pak až změnit klíč konferám (viz další operace)
),
migrations.AddField( migrations.AddField(
model_name='konfera', model_name='konfera',
name='problem_ptr', name='problem_ptr',
@ -95,9 +98,6 @@ class Migration(migrations.Migration):
migrations.DeleteModel( migrations.DeleteModel(
name='ClanekNode', name='ClanekNode',
), ),
migrations.DeleteModel(
name='KonferaNode',
),
migrations.CreateModel( migrations.CreateModel(
name='Konfery_Ucastnici', name='Konfery_Ucastnici',
fields=[ fields=[

35
seminar/migrations/0088_perm_org_a_ucastnik.py

@ -0,0 +1,35 @@
# Generated by Django 2.2.15 on 2020-09-05 10:10
from django.db import migrations
def add_perms(apps, schema_editor):
ContentType = apps.get_model('contenttypes', 'ContentType')
User = apps.get_model('auth', 'User')
Permission = apps.get_model('auth', 'Permission')
Resitel = apps.get_model('seminar', 'Resitel')
c = ContentType.objects.get_for_model(User)
org_perm = Permission.objects.filter(codename__exact='org').first()
if not org_perm:
org_perm = Permission.objects.create(codename='org', name='org', content_type=c)
resitel_perm = Permission.objects.filter(codename__exact='resitel').first()
if not resitel_perm:
resitel_perm = Permission.objects.create(codename='resitel', name='resitel', content_type=c)
for r in Resitel.objects.all():
u = r.osoba.user
if u:
u.user_permissions.add(resitel_perm)
for org in User.objects.all():
if org and org.is_staff:
org.user_permissions.add(org_perm)
class Migration(migrations.Migration):
dependencies = [
('seminar', '0087_fix_polymorphism'),
]
operations = [
migrations.RunPython(add_perms, migrations.RunPython.noop),
]

18
seminar/migrations/0089_cislo_datum_preddeadline.py

@ -0,0 +1,18 @@
# Generated by Django 2.2.16 on 2020-10-13 19:40
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('seminar', '0088_perm_org_a_ucastnik'),
]
operations = [
migrations.AddField(
model_name='cislo',
name='datum_preddeadline',
field=models.DateField(blank=True, help_text='Datum pro příjem řešení, která se otisknou v dalším čísle', null=True, verbose_name='datum předdeadline'),
),
]

3
seminar/models.py

@ -443,6 +443,9 @@ class Cislo(SeminarModelBase):
datum_deadline = models.DateField('datum deadline', blank=True, null=True, datum_deadline = models.DateField('datum deadline', blank=True, null=True,
help_text='Datum pro příjem řešení úloh zadaných v tomto čísle') help_text='Datum pro příjem řešení úloh zadaných v tomto čísle')
datum_preddeadline = models.DateField('datum předdeadline', blank=True, null=True,
help_text='Datum pro příjem řešení, která se otisknou v dalším čísle')
datum_deadline_soustredeni = models.DateField( datum_deadline_soustredeni = models.DateField(
'datum deadline soustředění', 'datum deadline soustředění',
blank=True, null=True, blank=True, null=True,

6
seminar/templates/seminar/archiv/base.html

@ -1,6 +0,0 @@
{% extends "base.html" %}
{% block menu_archiv %}selected{% endblock %}
{# zmena fotky #}{% block header %}archiv{% endblock %}

2
seminar/templates/seminar/archiv/cisla.html

@ -1,4 +1,4 @@
{% extends "seminar/archiv/base.html" %} {% extends "base.html" %}
{% block content %} {% block content %}
<div> <div>

24
seminar/templates/seminar/archiv/cislo.html

@ -1,4 +1,4 @@
{% extends "seminar/archiv/base.html" %} {% extends "base.html" %}
{% block content %} {% block content %}
<div> <div>
@ -18,9 +18,9 @@
<h2>Zadané problémy</h2> <h2>Zadané problémy</h2>
<ul> <ul>
{% for p in v_cisle_zadane %} {% for p in v_cisle_zadane %}
<li{% if user.is_staff and not cislo.verejne %} class='mam-org-only'{% endif %}> <li{% if user.je_org and not cislo.verejne %} class='mam-org-only'{% endif %}>
{% if user.is_staff or cislo.verejne %} {% if user.je_org or cislo.verejne %}
<a href='{{ p.verejne_url }}'>{% endif %}{{ p.kod_v_rocniku }} {{ p.nazev }} {{ p.body_v_zavorce }}{% if user.is_staff or cislo.verejne %}</a>{% endif %} <a href='{{ p.verejne_url }}'>{% endif %}{{ p.kod_v_rocniku }} {{ p.nazev }} {{ p.body_v_zavorce }}{% if user.je_org or cislo.verejne %}</a>{% endif %}
{% endfor %} {% endfor %}
</ul> </ul>
{% endif %} {% endif %}
@ -29,14 +29,14 @@
<h2>Řešené problémy</h2> <h2>Řešené problémy</h2>
<ul> <ul>
{% for p in resene_problemy %} {% for p in resene_problemy %}
<li{% if user.is_staff and not cislo.verejne %} class='mam-org-only'{% endif %}> <li{% if user.je_org and not cislo.verejne %} class='mam-org-only'{% endif %}>
{% if user.is_staff or cislo.verejne %} {% if user.je_org or cislo.verejne %}
<a href='{{ p.verejne_url }}'>{% endif %}{{ p.kod_v_rocniku }} {{ p.nazev }} {{ p.body_v_zavorce }}{% if user.is_staff or cislo.verejne %}</a>{% endif %} <a href='{{ p.verejne_url }}'>{% endif %}{{ p.kod_v_rocniku }} {{ p.nazev }} {{ p.body_v_zavorce }}{% if user.je_org or cislo.verejne %}</a>{% endif %}
{% endfor %} {% endfor %}
</ul> </ul>
{% endif %} {% endif %}
{% if user.is_staff %} {% if user.je_org %}
<div class="mam-org-only"> <div class="mam-org-only">
<h2> Orgovské odkazy </h2> <h2> Orgovské odkazy </h2>
<ul> <ul>
@ -52,13 +52,13 @@
<h2>Výsledkovka</h2> <h2>Výsledkovka</h2>
{% else %} {% else %}
{% if user.is_staff %} {% if user.je_org %}
<div class='mam-org-only'> <div class='mam-org-only'>
<h2>Výsledkovka (neveřejná)</h2> <h2>Výsledkovka (neveřejná)</h2>
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if cislo.verejna_vysledkovka or user.is_staff %} {% if cislo.verejna_vysledkovka or user.je_org %}
<table class='vysledkovka'> <table class='vysledkovka'>
<tr class='border-b'> <tr class='border-b'>
<th class='border-r'># <th class='border-r'>#
@ -66,7 +66,7 @@
{% for p in problemy %} {% for p in problemy %}
<th class='border-r'><a href="{{ p.verejne_url }}">{{ p.kod_v_rocniku }}</a> <th class='border-r'><a href="{{ p.verejne_url }}">{{ p.kod_v_rocniku }}</a>
{% endfor %} {% endfor %}
<th class='border-r'>Za číslo</sup> <th class='border-r'>Za číslo
<th class='border-r'>Za ročník <th class='border-r'>Za ročník
<th class='border-r'>Odjakživa <th class='border-r'>Odjakživa
{% for rv in radky_vysledkovky %} {% for rv in radky_vysledkovky %}
@ -88,7 +88,7 @@
</table> </table>
{% endif %} {% endif %}
{% if not cislo.verejna_vysledkovka and user.is_staff %} {% if not cislo.verejna_vysledkovka and user.je_org %}
</div> </div>
{% endif %} {% endif %}

2
seminar/templates/seminar/archiv/cislo_obalkovani.html

@ -1,4 +1,4 @@
{% extends "seminar/archiv/base.html" %} {% extends "base.html" %}
{% block content %} {% block content %}
<h1> <h1>

2
seminar/templates/seminar/archiv/prispevek.html

@ -1,4 +1,4 @@
{% extends "seminar/archiv/base.html" %} {% extends "base.html" %}
{% block title %} {% block title %}
{{prispevek.nazev}} {{prispevek.nazev}}

6
seminar/templates/seminar/archiv/problem.html

@ -1,13 +1,13 @@
{% extends "seminar/archiv/base.html" %} {% extends "base.html" %}
{% load comments %} {% load comments %}
{% block content %} {% block content %}
<div {% if not problem.verejne and user.is_staff %}class="mam-org-only"{% endif %}> <div {% if not problem.verejne and user.je_org %}class="mam-org-only"{% endif %}>
{% block problem %} {% block problem %}
{% endblock %} {% endblock %}
{% if user.is_staff %} {% if user.je_org %}
<div class='mam-org-only'> <div class='mam-org-only'>
<h2>Text - org</h2> <h2>Text - org</h2>

6
seminar/templates/seminar/archiv/rocnik.html

@ -1,4 +1,4 @@
{% extends "seminar/archiv/base.html" %} {% extends "base.html" %}
{% block content %} {% block content %}
<div> <div>
@ -62,7 +62,7 @@
</div> </div>
{% if vysledkovka %} {% if vysledkovka %}
{% if user.is_staff %} {% if user.je_org %}
<div class='mam-org-only'> <div class='mam-org-only'>
<a href='vysledkovka.tex'>Výsledkovka ročníku (LaTeX)</a> <a href='vysledkovka.tex'>Výsledkovka ročníku (LaTeX)</a>
</div> </div>
@ -72,7 +72,7 @@
{% include "seminar/vysledkovka_rocnik.html" %} {% include "seminar/vysledkovka_rocnik.html" %}
{% endif %} {% endif %}
{% if user.is_staff and vysledkovka_s_neverejnymi %} {% if user.je_org and vysledkovka_s_neverejnymi %}
<div class='mam-org-only'> <div class='mam-org-only'>
<h2>Výsledková listina včetně neveřejných bodů</h2> <h2>Výsledková listina včetně neveřejných bodů</h2>
{% with radky_vyledkovky_s_neverejnymi as radky_vysledkovky %} {% with radky_vyledkovky_s_neverejnymi as radky_vysledkovky %}

2
seminar/templates/seminar/archiv/temata.html

@ -1,4 +1,4 @@
{% extends "seminar/archiv/base.html" %} {% extends "base.html" %}
{% block content %} {% block content %}
<h1> <h1>

10
seminar/templates/seminar/clanky/base.html

@ -1,10 +0,0 @@
{% extends "base.html" %}
{% block menu_clanky %}selected{% endblock %}
{# zmena fotky #}{% block header %}clanky{% endblock %}
{% block submenu %}
{% include "seminar/clanky/submenu.html" %}
{% endblock %}

6
seminar/templates/seminar/clanky/organizatorske_clanky.html

@ -1,11 +1,5 @@
{% extends 'seminar/clanky/resitelske_clanky.html' %} {% extends 'seminar/clanky/resitelske_clanky.html' %}
{% block submenu %}
{% with "org" as selected %}
{% include "seminar/clanky/submenu.html" %}
{% endwith %}
{% endblock submenu %}
{% block nadpis1a %}{% block nadpis1b %} {% block nadpis1a %}{% block nadpis1b %}
Organizátorské články Organizátorské články
{% endblock %}{% endblock %} {% endblock %}{% endblock %}

8
seminar/templates/seminar/clanky/resitelske_clanky.html

@ -1,13 +1,5 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block menu_clanky %}selected{% endblock %}
{% block submenu %}
{% with "resitel" as selected %}
{% include "seminar/clanky/submenu.html" %}
{% endwith %}
{% endblock submenu %}
{% block content %} {% block content %}
<h1> <h1>

6
seminar/templates/seminar/cojemam/base.html

@ -1,6 +0,0 @@
{% extends "base.html" %}
{% block submenu %}
{% include "seminar/cojemam/submenu.html" %}
{% endblock %}

11
seminar/templates/seminar/cojemam/organizatori.html

@ -1,4 +1,4 @@
{% extends "seminar/cojemam/base.html" %} {% extends "base.html" %}
{% block nadpis1a %}{% block nadpis1b %} {% block nadpis1a %}{% block nadpis1b %}
{% if aktivni %} {% if aktivni %}
Organizátoři Organizátoři
@ -7,15 +7,6 @@
{% endif %} {% endif %}
{% endblock%}{% endblock%} {% endblock%}{% endblock%}
{# podbarveni menu a submenu #}
{% block menu_uvod %}selected{% endblock %}
{% block submenu %}
{% with "org" as selected %}
{% include "seminar/cojemam/submenu.html" %}
{% endwith %}
{% endblock %}
{# zmena fotky #}{% block header %}cojemam{% endblock %}
{% block content %} {% block content %}

6
seminar/templates/seminar/novinky.html

@ -1,13 +1,13 @@
{% for novinka in object_list %} {% for novinka in object_list %}
{# pripravene div-y na stylovani#} {# pripravene div-y na stylovani#}
<div> <div>
{% if not novinka.zverejneno and user.is_staff %} {% if not novinka.zverejneno and user.je_org %}
<div class="mam-org-only"> <div class="mam-org-only">
<ul> <ul>
<li><a href="/admin/seminar/novinky/{{novinka.pk}}">Upravit novinku</a> <li><a href="/admin/seminar/novinky/{{novinka.pk}}">Upravit novinku</a>
</ul> </ul>
{% endif %} {% endif %}
{% if novinka.zverejneno or user.is_staff %} {% if novinka.zverejneno or user.je_org %}
{# datum #} {# datum #}
<div><b>{{novinka.datum}}</b></div> <div><b>{{novinka.datum}}</b></div>
{# text #} {# text #}
@ -33,7 +33,7 @@
</p> </p>
</div> </div>
{% endif %} {% endif %}
{% if not novinka.zverejneno and user.is_staff %} {% if not novinka.zverejneno and user.je_org %}
</div> </div>
{% endif %} {% endif %}
</div> </div>

2
seminar/templates/seminar/profil/edit.html

@ -1,4 +1,4 @@
{% extends "seminar/zadani/base.html" %} {% extends "base.html" %}
{% load staticfiles %} {% load staticfiles %}
{% block script %} {% block script %}

3
seminar/templates/seminar/profil/gdpr.html

@ -36,13 +36,14 @@ Tento souhlas uděluji ze své vlastní a svobodné vůle a beru na vědomí, ž
</p> </p>
<p class="gdpr"> <p class="gdpr">
Dále máte právo: Dále máte právo:
</p>
<ul> <ul>
<li>požádat o informaci, jaké osobní údaje jsou o vás zpracovávány, <li>požádat o informaci, jaké osobní údaje jsou o vás zpracovávány,
<li>požadovat opravu osobních údajů, pokud jsou neplatné nebo zastaralé, <li>požadovat opravu osobních údajů, pokud jsou neplatné nebo zastaralé,
<li>požadovat, aby nebyly vaše osobní údaje zpracovávány do doby, než bude vyřešena oprávněnost výše uvedených požadavků, <li>požadovat, aby nebyly vaše osobní údaje zpracovávány do doby, než bude vyřešena oprávněnost výše uvedených požadavků,
<li>požadovat, aby byly vaše osobní údaje předány jinému správci, <li>požadovat, aby byly vaše osobní údaje předány jinému správci,
<li>podat stížnost u dozorového úřadu. <li>podat stížnost u dozorového úřadu.
</p> </ul>
<p class="gdpr"> <p class="gdpr">
V případě jakéhokoliv dotazu nebo uplatnění svých práv můžete kontaktovat pověřence pro ochranu osobních údajů na e-mailové adrese gdpr@cuni.cz. V případě jakéhokoliv dotazu nebo uplatnění svých práv můžete kontaktovat pověřence pro ochranu osobních údajů na e-mailové adrese gdpr@cuni.cz.
</p> </p>

2
seminar/templates/seminar/profil/login.html

@ -1,4 +1,4 @@
{% extends "seminar/zadani/base.html" %} {% extends "base.html" %}
{% load staticfiles %} {% load staticfiles %}

2
seminar/templates/seminar/profil/logout.html

@ -1,4 +1,4 @@
{% extends "seminar/zadani/base.html" %} {% extends "base.html" %}
{% load staticfiles %} {% load staticfiles %}

8
seminar/templates/seminar/profil/nahraj_reseni.html

@ -1,4 +1,4 @@
{% extends "seminar/zadani/base.html" %} {% extends "base.html" %}
{% load staticfiles %} {% load staticfiles %}
{% block script %} {% block script %}
<!--script type="text/javascript" src="{% static 'admin/js/vendor/jquery/jquery.js' %}"></script!--> <!--script type="text/javascript" src="{% static 'admin/js/vendor/jquery/jquery.js' %}"></script!-->
@ -53,7 +53,7 @@
</td> </td>
<td {% if field.help_text %} class="field-with-comment"{% endif %}> <td {% if field.help_text %} class="field-with-comment"{% endif %}>
{{ field }} {{ field }}
<span class="field-comment">{{ field.help_text|safe }} <span class="field-comment">{{ field.help_text|safe }}</span>>
</td> </td>
<td><span class="field-error">{{ field.errors }}</span></td> <td><span class="field-error">{{ field.errors }}</span></td>
@ -74,7 +74,7 @@
<div id="empty_form" style="display:none"> <div id="empty_form" style="display:none">
<div class="attachment"> <div class="attachment">
<table class='form' id="reseni" class='no_error'> <table class='form no_error' id="reseni">
<tr> <tr>
{% for field in prilohy.empty_form.visible_fields %} {% for field in prilohy.empty_form.visible_fields %}
@ -86,7 +86,7 @@
</td> </td>
<td {% if field.help_text %} class="field-with-comment"{% endif %}> <td {% if field.help_text %} class="field-with-comment"{% endif %}>
{{ field }} {{ field }}
<span class="field-comment">{{ field.help_text|safe }} <span class="field-comment">{{ field.help_text|safe }}</span>
</td> </td>
<td><span class="field-error">{{ field.errors }}</span></td> <td><span class="field-error">{{ field.errors }}</span></td>

2
seminar/templates/seminar/profil/prihlaska.html

@ -1,4 +1,4 @@
{% extends "seminar/zadani/base.html" %} {% extends "base.html" %}
{% load staticfiles %} {% load staticfiles %}
{% block script %} {% block script %}

2
seminar/templates/seminar/profil/prihlaska_field.html

@ -8,7 +8,7 @@
</td> </td>
<td {% if field.help_text %} class="field-with-comment"{% endif %}> <td {% if field.help_text %} class="field-with-comment"{% endif %}>
{{ field }} {{ field }}
<span class="field-comment">{{ field.help_text|safe }} <span class="field-comment">{{ field.help_text|safe }}</span>
</td> </td>
</tr> </tr>

2
seminar/templates/seminar/profil/resitel.html

@ -1,4 +1,4 @@
{% extends "seminar/zadani/base.html" %} {% extends "base.html" %}
{% load staticfiles %} {% load staticfiles %}

6
seminar/templates/seminar/soustredeni/base.html

@ -1,6 +0,0 @@
{% extends "base.html" %}
{% block submenu %}
{% include "seminar/soustredeni/submenu.html" %}
{% endblock %}

23
seminar/templates/seminar/soustredeni/seznam_soustredeni.html

@ -1,11 +1,4 @@
{% extends "seminar/soustredeni/base.html" %} {% extends "base.html" %}
{% block menu_soustredeni %}selected{% endblock %}
{% block submenu %}
{% with "probehlo" as selected %}
{% include "seminar/soustredeni/submenu.html" %}
{% endwith %}
{% endblock submenu %}
{# zmena fotky #}{% block header %}soustredeni{% endblock %} {# zmena fotky #}{% block header %}soustredeni{% endblock %}
@ -17,8 +10,8 @@
{# Projdi vsechna soustredeni #} {# Projdi vsechna soustredeni #}
{% for soustredeni in object_list %} {% for soustredeni in object_list %}
{# Kdyz je verejne -> zobraz #} {# Kdyz je verejne -> zobraz #}
{% if soustredeni.verejne_db or user.is_staff %} {% if soustredeni.verejne_db or user.je_org %}
{% if not soustredeni.verejne_db and user.is_staff %} {% if not soustredeni.verejne_db and user.je_org %}
<div class="mam-org-only"> <div class="mam-org-only">
<!--Groups of user: {{user.groups.all}} <br>--> <!--Groups of user: {{user.groups.all}} <br>-->
{% endif %} {% endif %}
@ -34,8 +27,8 @@
{# Zobrazeni odkazu na galerie #} {# Zobrazeni odkazu na galerie #}
{% if soustredeni.galerie_set.all %} {% if soustredeni.galerie_set.all %}
{% for galerie in soustredeni.galerie_set.all %} {% for galerie in soustredeni.galerie_set.all %}
{% if galerie.zobrazit == 0 or user.is_staff %} {% if galerie.zobrazit == 0 or user.je_org %}
<li {% if galerie.zobrazit > 0 and user.is_staff %}class="mam-org-only"{% endif %}> <li {% if galerie.zobrazit > 0 and user.je_org %}class="mam-org-only"{% endif %}>
<a href="../{{soustredeni.pk}}/fotogalerie/{{galerie.pk}}">Fotogalerie</a> <a href="../{{soustredeni.pk}}/fotogalerie/{{galerie.pk}}">Fotogalerie</a>
{# TODO kdyz je titulni obrazek, tak asi i titulni obrazek #} {# TODO kdyz je titulni obrazek, tak asi i titulni obrazek #}
</li> </li>
@ -43,7 +36,7 @@
{% endfor %} {% endfor %}
{% endif %} {% endif %}
</ul> </ul>
{% if user.is_staff %} {% if user.je_org %}
<div class="mam-org-only"> <div class="mam-org-only">
<a href="../{{soustredeni.pk}}/fotogalerie/0/new/">Vytvořit novou fotogalerii</a><br> <a href="../{{soustredeni.pk}}/fotogalerie/0/new/">Vytvořit novou fotogalerii</a><br>
<a href="../{{soustredeni.pk}}/obalky.pdf">Vygenerovat obálky pro účastníky</a><br> <a href="../{{soustredeni.pk}}/obalky.pdf">Vygenerovat obálky pro účastníky</a><br>
@ -60,7 +53,7 @@
{% if soustredeni.text %} {% if soustredeni.text %}
{% autoescape off %}{{soustredeni.text}}{% endautoescape %} {% autoescape off %}{{soustredeni.text}}{% endautoescape %}
{% endif %} {% endif %}
{% if user.is_staff %} {% if user.je_org %}
<div class="mam-org-only"> <div class="mam-org-only">
{# Účastníci #} {# Účastníci #}
<h2>Soustředění se zúčastnili tito účastníci:</h2> <h2>Soustředění se zúčastnili tito účastníci:</h2>
@ -82,7 +75,7 @@
</div> </div>
{% endif %} {% endif %}
{% if not soustredeni.verejne_db and user.is_staff %} {% if not soustredeni.verejne_db and user.je_org %}
</div> {# class="mam-org-only" #} </div> {# class="mam-org-only" #}
{% endif %} {% endif %}
{% endif %} {% endif %}

1
seminar/templates/seminar/soustredeni/seznam_ucastniku.html

@ -35,7 +35,6 @@
Žádní účastníci nebyli... Žádní účastníci nebyli...
{% endfor %} {% endfor %}
</table> </table>
</ul>
</body> </body>
</html> </html>

2
seminar/templates/seminar/treenode.html

@ -1,4 +1,4 @@
{% extends "seminar/archiv/base.html" %} {% extends "base.html" %}
{% load comments %} {% load comments %}

11
seminar/templates/seminar/zadani/AktualniVysledkovka.html

@ -1,11 +1,4 @@
{% extends "seminar/zadani/base.html" %} {% extends "base.html" %}
{% block submenu %}
{% with "vysledkova-listina" as selected %}
{% include 'seminar/zadani/submenu.html' %}
{% endwith %}
{% endblock submenu %}
{% block content %} {% block content %}
{% with nastaveni.aktualni_rocnik as rocnik %} {% with nastaveni.aktualni_rocnik as rocnik %}
@ -27,7 +20,7 @@
v&nbsp;<a href="/archiv/cisla/">archivu</a>. v&nbsp;<a href="/archiv/cisla/">archivu</a>.
</p> </p>
{% if user.is_staff and vysledkovka_s_neverejnymi %} {% if user.je_org and vysledkovka_s_neverejnymi %}
<div class='mam-org-only'> <div class='mam-org-only'>
<h1>Výsledky včetně neveřejných</h1> <h1>Výsledky včetně neveřejných</h1>
{% with vysledkovka_s_neverejnymi as vysledkovka %} {% with vysledkovka_s_neverejnymi as vysledkovka %}

14
seminar/templates/seminar/zadani/AktualniZadani.html

@ -1,10 +1,4 @@
{% extends "seminar/zadani/base.html" %} {% extends "base.html" %}
{% block submenu %}
{% with "aktualni" as selected %}
{% include 'seminar/zadani/submenu.html' %}
{% endwith %}
{% endblock submenu %}
{% block nadpis1a %}{% block nadpis1b %} {% block nadpis1a %}{% block nadpis1b %}
Aktuální zadání Aktuální zadání
@ -16,8 +10,8 @@
{% with nastaveni.aktualni_cislo as ac %} {% with nastaveni.aktualni_cislo as ac %}
{# Zobrazovani neverejnych zadani jen organizatorum #} {# Zobrazovani neverejnych zadani jen organizatorum #}
{% if user.is_staff or verejne %} {% if user.je_org or verejne %}
{% if user.is_staff and not verejne %}<div class="mam-org-only">{% endif %} {% if user.je_org and not verejne %}<div class="mam-org-only">{% endif %}
{% if ac.zadane_problemy.all %} {% if ac.zadane_problemy.all %}
{% if ac.datum_deadline_soustredeni %} {% if ac.datum_deadline_soustredeni %}
@ -60,7 +54,7 @@
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{% if user.is_staff and not verejne%}</div>{% endif %} {% if user.je_org and not verejne%}</div>{% endif %}
{% else %} {% else %}
<h2>Aktuálně nejsou zveřejněny žádné úlohy</h2> <h2>Aktuálně nejsou zveřejněny žádné úlohy</h2>
{% endif %} {% endif %}

9
seminar/templates/seminar/zadani/Temata.html

@ -1,11 +1,4 @@
{% extends "seminar/zadani/base.html" %} {% extends "base.html" %}
{% block submenu %}
{% with "temata" as selected %}
{% include 'seminar/zadani/submenu.html' %}
{% endwith %}
{% endblock submenu %}
{% block content %} {% block content %}
{% with nastaveni.aktualni_rocnik as ar %} {% with nastaveni.aktualni_rocnik as ar %}

10
seminar/templates/seminar/zadani/base.html

@ -1,10 +0,0 @@
{% extends "base.html" %}
{% block menu_zadani %}selected{% endblock %}
{# zmena fotky #}{% block header %}zadani{% endblock %}
{% block submenu %}
{% include 'seminar/zadani/submenu.html' %}
{% endblock submenu %}

55
seminar/testutils.py

@ -1,6 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import datetime import datetime
from django.contrib.auth.models import Permission
from pytz import timezone from pytz import timezone
import random import random
import lorem import lorem
@ -9,6 +11,7 @@ from django.db import transaction
import unidecode import unidecode
import logging import logging
from korektury.testutils import create_test_pdf
from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni, Nastaveni, Soustredeni, Soustredeni_Ucastnici, Soustredeni_Organizatori, Osoba, Organizator, Prijemce, Tema, Uloha, Konfera, TextNode, UlohaVzorakNode, RocnikNode, CisloNode, TemaVCisleNode, Text, Hodnoceni, UlohaZadaniNode, Novinky, TreeNode from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni, Nastaveni, Soustredeni, Soustredeni_Ucastnici, Soustredeni_Organizatori, Osoba, Organizator, Prijemce, Tema, Uloha, Konfera, TextNode, UlohaVzorakNode, RocnikNode, CisloNode, TemaVCisleNode, Text, Hodnoceni, UlohaZadaniNode, Novinky, TreeNode
import seminar.models as m import seminar.models as m
@ -70,7 +73,7 @@ def gen_osoby(rnd, size):
if pokusy >= max_pokusy: if pokusy >= max_pokusy:
print("Chyba, na danou velikost testovacích dat příliš málo možných" print("Chyba, na danou velikost testovacích dat příliš málo možných"
" jmen a příjmení") " jmen a příjmení")
exit exit()
prezdivka = rnd.choice(prezdivky) prezdivka = rnd.choice(prezdivky)
email = "@".join([unidecode.unidecode(jmeno), rnd.choice(domain)]) email = "@".join([unidecode.unidecode(jmeno), rnd.choice(domain)])
telefon = "".join([str(rnd.choice([k for k in range(10)])) for i in range(9)]) telefon = "".join([str(rnd.choice([k for k in range(10)])) for i in range(9)])
@ -124,9 +127,20 @@ def gen_resitele(rnd, osoby, skoly):
logger.info('Generuji řešitele...') logger.info('Generuji řešitele...')
resitele = [] resitele = []
x = 0
resitel_perm = Permission.objects.filter(codename__exact='resitel').first()
for os in osoby: for os in osoby:
rand = rnd.randint(0, 8) rand = rnd.randint(0, 8)
if not (rand % 8 == 0): if not (rand % 8 == 0):
if not os.user:
if x:
user = User.objects.create_user(username='r'+str(x), email=os.email, password='r')
else:
user = User.objects.create_user(username='r', email=os.email, password='r')
x += 1
os.user = user
os.save()
os.user.user_permissions.add(resitel_perm)
resitele.append(Resitel.objects.create(osoba=os, skola=rnd.choice(skoly), resitele.append(Resitel.objects.create(osoba=os, skola=rnd.choice(skoly),
rok_maturity=rnd.randint(2019, 2029), rok_maturity=rnd.randint(2019, 2029),
zasilat=rnd.choice(Resitel.ZASILAT_CHOICES)[0])) zasilat=rnd.choice(Resitel.ZASILAT_CHOICES)[0]))
@ -139,7 +153,7 @@ def gen_prijemci(rnd, osoby, kolik=10):
prijemci.append(Prijemce.objects.create(osoba=i)) prijemci.append(Prijemce.objects.create(osoba=i))
return prijemci return prijemci
def gen_organizatori(rnd, osoby, last_rocnik, users): def gen_organizatori(rnd, osoby, last_rocnik):
logger.info('Generuji organizátory...') logger.info('Generuji organizátory...')
organizatori = [] organizatori = []
@ -149,6 +163,8 @@ def gen_organizatori(rnd, osoby, last_rocnik, users):
seznam_oboru = ["matematiku", "matematiku", "matematiku", "fyziku", "literaturu", seznam_oboru = ["matematiku", "matematiku", "matematiku", "fyziku", "literaturu",
"informatiku", "informatiku", "běhání dokolečka"] "informatiku", "informatiku", "běhání dokolečka"]
x = 0
org_perm = Permission.objects.filter(codename__exact='org').first()
for os in osoby: for os in osoby:
rand = rnd.randint(0, 8) rand = rnd.randint(0, 8)
if (rand % 8 == 0): if (rand % 8 == 0):
@ -175,6 +191,15 @@ def gen_organizatori(rnd, osoby, last_rocnik, users):
if do.year > datetime.datetime.now().year: if do.year > datetime.datetime.now().year:
do = None do = None
if not os.user:
if x:
user = User.objects.create_user(username='o'+str(x), email=os.email, password='o')
else:
user = User.objects.create_user(username='o', email=os.email, password='o')
x += 1
os.user = user
os.save()
os.user.user_permissions.add(org_perm)
organizatori.append(Organizator.objects.create(osoba=os, organizatori.append(Organizator.objects.create(osoba=os,
organizuje_od=od, organizuje_do=do, strucny_popis_organizatora = popis_orga)) organizuje_od=od, organizuje_do=do, strucny_popis_organizatora = popis_orga))
return organizatori return organizatori
@ -681,14 +706,14 @@ def otec_syn(otec, syn):
syn.save() syn.save()
otec.save() otec.save()
def gen_clanek(rnd): def gen_clanek(rnd, organizatori, resitele):
logger.info("Generuji článek do čísla 22.2") logger.info("Generuji článek do čísla 22.2")
clanek = m.Clanek.objects.create( clanek = m.Clanek.objects.create(
nazev="Článek o Lorem ipsum", nazev="Článek o Lorem ipsum",
nadproblem=None, nadproblem=None,
stav='vyreseny', stav='vyreseny',
zamereni=['I'], zamereni=['I'],
garant=rnd.choice(m.Organizator.objects.all()), garant=rnd.choice(organizatori),
kod='cl', kod='cl',
) )
clanek.save() clanek.save()
@ -696,7 +721,7 @@ def gen_clanek(rnd):
reseni = m.Reseni.objects.create( reseni = m.Reseni.objects.create(
zverejneno=True, zverejneno=True,
) )
reseni.resitele.add(rnd.choice(m.Resitel.objects.all())) reseni.resitele.add(rnd.choice(resitele))
reseni.save() reseni.save()
cislo = m.Cislo.objects.get(rocnik__rocnik=22, poradi=2) cislo = m.Cislo.objects.get(rocnik__rocnik=22, poradi=2)
@ -771,11 +796,22 @@ def create_test_data(size = 6, rnd = None):
# users # users
admin = User.objects.create_superuser(username='admin', email='', password='admin') admin = User.objects.create_superuser(username='admin', email='', password='admin')
os_admin = Osoba.objects.create(
user=admin, jmeno='admin', prijmeni='admin',
prezdivka='admin', pohlavi_muz=1, email='admin@admin.admin',
telefon='123 456 789', datum_narozeni=datetime.date(2000, 1, 1),
ulice='admin', mesto='admin', psc='100 00',
datum_registrace=datetime.date(2020, 9, 6)
)
or_admin = Organizator.objects.create(
osoba=os_admin, organizuje_od=None, organizuje_do=None,
strucny_popis_organizatora="Organizátor k uživateli Admin"
)
usernames = ['anet', 'bara', 'cyril', 'david', 'eva', 'filip'] usernames = ['anet', 'bara', 'cyril', 'david', 'eva', 'filip']
users = [] users = []
for usr in usernames[:size]: for usr in usernames[:size]:
u = User.objects.create(username=usr, password=usr) u = User.objects.create_user(username=usr, password=usr)
u.first_name = usr.capitalize() u.first_name = usr.capitalize()
u.save() u.save()
users.append(u) users.append(u)
@ -789,8 +825,8 @@ def create_test_data(size = 6, rnd = None):
# resitele a organizatori # resitele a organizatori
last_rocnik = 25 last_rocnik = 25
organizatori = gen_organizatori(rnd, osoby, last_rocnik)
resitele = gen_resitele(rnd, osoby, skoly) resitele = gen_resitele(rnd, osoby, skoly)
organizatori = gen_organizatori(rnd, osoby, last_rocnik, users)
#generování novinek #generování novinek
novinky = gen_novinky(rnd, organizatori) novinky = gen_novinky(rnd, organizatori)
@ -830,6 +866,9 @@ def create_test_data(size = 6, rnd = None):
#generování konfer #generování konfer
konfery = gen_konfery(size, rnd, organizatori, resitele, soustredeni) konfery = gen_konfery(size, rnd, organizatori, resitele, soustredeni)
# vytvoreni pdf ke korekturam
create_test_pdf(rnd, organizatori)
# TODO: nastavi správně, kolik se čeho generuje, aby rozsahy přibližně odpovídaly # TODO: nastavi správně, kolik se čeho generuje, aby rozsahy přibližně odpovídaly
# FIXME: misto typu ruzne typy objektu a vnoreni do sebe (Tom nechápe, co je tímto fixme míněno) # FIXME: misto typu ruzne typy objektu a vnoreni do sebe (Tom nechápe, co je tímto fixme míněno)
# TODO: vytvorit temata s ruznymi vlakny # TODO: vytvorit temata s ruznymi vlakny
@ -840,7 +879,7 @@ def create_test_data(size = 6, rnd = None):
# TODO: přidat ke konferám řešení a dát je do čísel # TODO: přidat ke konferám řešení a dát je do čísel
# Dohackované vytvoření jednoho článku # Dohackované vytvoření jednoho článku
gen_clanek(rnd) gen_clanek(rnd, organizatori, resitele)
# obecné nastavení semináře, musí být už přidané ročníky a čísla, jinak se nastaví divně # obecné nastavení semináře, musí být už přidané ročníky a čísla, jinak se nastaví divně

112
seminar/urls.py

@ -1,11 +1,8 @@
from django.urls import path, include from django.urls import path, include
from django.contrib.auth.decorators import user_passes_test from django.contrib.auth.decorators import login_required
from . import views, export from . import views, export
from .utils import staff_member_required from .utils import org_required, resitel_required
from django.views.generic.base import RedirectView from django.views.generic.base import RedirectView
from django.contrib.auth import views as auth_views
staff_member_required = user_passes_test(lambda u: u.is_staff)
urlpatterns = [ urlpatterns = [
# path('aktualni/temata/', views.TemataRozcestnikView), # path('aktualni/temata/', views.TemataRozcestnikView),
@ -33,17 +30,17 @@ urlpatterns = [
), ),
path( path(
'soustredeni/<int:soustredeni>/seznam_ucastniku', 'soustredeni/<int:soustredeni>/seznam_ucastniku',
staff_member_required(views.SoustredeniUcastniciView.as_view()), org_required(views.SoustredeniUcastniciView.as_view()),
name='soustredeni_ucastnici' name='soustredeni_ucastnici'
), ),
path( path(
'soustredeni/<int:soustredeni>/maily_ucastniku', 'soustredeni/<int:soustredeni>/maily_ucastniku',
staff_member_required(views.SoustredeniMailyUcastnikuView.as_view()), org_required(views.SoustredeniMailyUcastnikuView.as_view()),
name='maily_ucastniku' name='maily_ucastniku'
), ),
path( path(
'soustredeni/<int:soustredeni>/export_ucastniku', 'soustredeni/<int:soustredeni>/export_ucastniku',
staff_member_required(views.soustredeniUcastniciExportView), org_required(views.soustredeniUcastniciExportView),
name='soustredeni_ucastnici_export' name='soustredeni_ucastnici_export'
), ),
path( path(
@ -62,64 +59,101 @@ urlpatterns = [
#path('clanky/org/', views.ClankyOrganizatorView.as_view(), name='clanky_organizator'), #path('clanky/org/', views.ClankyOrganizatorView.as_view(), name='clanky_organizator'),
# Aesop # Aesop
path('aesop-export/mam-rocnik-<int:prvni_rok>.csv', export.ExportRocnikView.as_view(), name='seminar_export_rocnik'), path(
path('aesop-export/mam-sous-<str:datum_zacatku>.csv', export.ExportSousView.as_view(), name='seminar_export_sous'), 'aesop-export/mam-rocnik-<int:prvni_rok>.csv',
path('aesop-export/index.csv', export.ExportIndexView.as_view(), name='seminar_export_index'), org_required(export.ExportRocnikView.as_view()),
name='seminar_export_rocnik'
),
path(
'aesop-export/mam-sous-<str:datum_zacatku>.csv',
org_required(export.ExportSousView.as_view()),
name='seminar_export_sous'
),
path(
'aesop-export/index.csv',
org_required(export.ExportIndexView.as_view()),
name='seminar_export_index'
),
# Stranky viditelne pouze pro orgy: # Stranky viditelne pouze pro orgy:
path( path(
'rocnik/<int:rocnik>/vysledkovka.tex', 'rocnik/<int:rocnik>/vysledkovka.tex',
staff_member_required(views.RocnikVysledkovkaView.as_view()), org_required(views.RocnikVysledkovkaView.as_view()),
name='seminar_rocnik_vysledkovka' name='seminar_rocnik_vysledkovka'
), ),
path('cislo/<int:rocnik>.<int:cislo>/vysledkovka.tex', path(
staff_member_required(views.CisloVysledkovkaView.as_view()), 'cislo/<int:rocnik>.<int:cislo>/vysledkovka.tex',
name='seminar_cislo_vysledkovka' org_required(views.CisloVysledkovkaView.as_view()),
name='seminar_cislo_vysledkovka'
),
path(
'cislo/<int:rocnik>.<int:cislo>/obalky.pdf',
org_required(views.cisloObalkyView),
name='seminar_cislo_obalky'
),
path(
'cislo/<int:rocnik>.<int:cislo>/tituly.tex',
org_required(views.TitulyView),
name='seminar_cislo_titul'
),
path(
'stav',
org_required(views.StavDatabazeView),
name='stav_databaze'
),
path(
'cislo/<int:rocnik>.<int:cislo>/obalkovani',
org_required(views.ObalkovaniView.as_view()),
name='seminar_cislo_resitel_obalkovani'
),
path(
'soustredeni/<int:soustredeni>/obalky.pdf',
org_required(views.soustredeniObalkyView),
name='seminar_soustredeni_obalky'
),
path(
'org/vloz_body/<int:tema>/',
org_required(views.VlozBodyView.as_view()),
name='seminar_org_vlozbody'
), ),
path('cislo/<int:rocnik>.<int:cislo>/obalky.pdf',
staff_member_required(views.cisloObalkyView), name='seminar_cislo_obalky'),
path('cislo/<int:rocnik>.<int:cislo>/tituly.tex',
staff_member_required(views.TitulyView), name='seminar_cislo_titul'),
path('stav',
staff_member_required(views.StavDatabazeView), name='stav_databaze'),
path('cislo/<int:rocnik>.<int:cislo>/obalkovani',
staff_member_required(views.ObalkovaniView.as_view()), name='seminar_cislo_resitel_obalkovani'),
path('soustredeni/<int:soustredeni>/obalky.pdf',
staff_member_required(views.soustredeniObalkyView), name='seminar_soustredeni_obalky'),
path('org/vloz_body/<int:tema>/',
staff_member_required(views.VlozBodyView.as_view()),name='seminar_org_vlozbody'),
# příprava na nestatický orgorozcestník # příprava na nestatický orgorozcestník
path('org/rozcestnik/', path(
staff_member_required(views.OrgoRozcestnikView.as_view()),name='seminar_org_rozcestnik'), 'org/rozcestnik/',
org_required(views.OrgoRozcestnikView.as_view()),
name='seminar_org_rozcestnik'
),
path('prihlaska/',views.prihlaskaView, name='seminar_prihlaska'), path('prihlaska/',views.prihlaskaView, name='seminar_prihlaska'),
path('login/', views.LoginView.as_view(), name='login'), path('login/', views.LoginView.as_view(), name='login'),
path('logout/', views.LogoutView.as_view(), name='logout'), path('logout/', views.LogoutView.as_view(), name='logout'),
path('resitel/', views.ResitelView.as_view(), name='seminar_resitel'), path('resitel/', resitel_required(views.ResitelView.as_view()), name='seminar_resitel'),
path('reset_password/', views.PasswordResetView.as_view(), name='reset_password'), path('reset_password/', views.PasswordResetView.as_view(), name='reset_password'),
path('change_password/', views.PasswordChangeView.as_view(), name='change_password'), path('change_password/', views.PasswordChangeView.as_view(), name='change_password'),
path('reset_password_done/', views.PasswordResetDoneView.as_view(), name='reset_password_done'), path('reset_password_done/', views.PasswordResetDoneView.as_view(), name='reset_password_done'),
path('reset_password_confirm/<uidb64>/<token>/', views.PasswordResetConfirmView.as_view(), name='password_reset_confirm'), path('reset_password_confirm/<uidb64>/<token>/', views.PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
path('reset_password_complete/', views.PasswordResetCompleteView.as_view(), name='reset_password_complete'), path('reset_password_complete/', views.PasswordResetCompleteView.as_view(), name='reset_password_complete'),
path('resitel_edit', views.resitelEditView, name='seminar_resitel_edit'), path(
'resitel_edit',
login_required(views.resitelEditView, login_url='/login/'),
name='seminar_resitel_edit'
),
# Obecný view na profil -- orgům dá rozcestník, řešitelům jejich stránku # Obecný view na profil -- orgům dá rozcestník, řešitelům jejich stránku
path('profil/', views.profilView, name='profil'), path('profil/', views.profilView, name='profil'),
# Autocomplete # Autocomplete
path('autocomplete/skola/',views.SkolaAutocomplete.as_view(), name='autocomplete_skola'), path('autocomplete/skola/',views.SkolaAutocomplete.as_view(), name='autocomplete_skola'),
path('autocomplete/resitel/',views.ResitelAutocomplete.as_view(), name='autocomplete_resitel'), path('autocomplete/resitel/', org_required(views.ResitelAutocomplete.as_view()), name='autocomplete_resitel'),
path('autocomplete/problem/odevzdatelny',views.OdevzdatelnyProblemAutocomplete.as_view(), name='autocomplete_problem_odevzdatelny'), path('autocomplete/problem/odevzdatelny',views.OdevzdatelnyProblemAutocomplete.as_view(), name='autocomplete_problem_odevzdatelny'),
path('temp/add_solution', views.AddSolutionView.as_view(),name='seminar_vloz_reseni'), path('temp/add_solution', org_required(views.AddSolutionView.as_view()), name='seminar_vloz_reseni'),
path('temp/nahraj_reseni', views.NahrajReseniView.as_view(),name='seminar_nahraj_reseni'), path('temp/nahraj_reseni', resitel_required(views.NahrajReseniView.as_view()), name='seminar_nahraj_reseni'),
path('', views.TitulniStranaView.as_view(), name='titulni_strana'), path('', views.TitulniStranaView.as_view(), name='titulni_strana'),
# Ceka na autocomplete v3 # Ceka na autocomplete v3
# path('autocomplete/organizatori/', # path('autocomplete/organizatori/',
# staff_member_required(views.OrganizatorAutocomplete.as_view()), # org_member_required(views.OrganizatorAutocomplete.as_view()),
# name='seminar_autocomplete_organizator') # name='seminar_autocomplete_organizator')

14
seminar/utils.py

@ -1,15 +1,25 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import datetime import datetime
from django.contrib.auth.decorators import user_passes_test
from django.contrib.auth import get_user_model
from django.contrib.auth.decorators import permission_required
from html.parser import HTMLParser from html.parser import HTMLParser
from django.contrib.auth.models import AnonymousUser
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
import seminar.models as m import seminar.models as m
import seminar.treelib as t import seminar.treelib as t
staff_member_required = user_passes_test(lambda u: u.is_staff) org_required = permission_required('auth.org', raise_exception=True)
resitel_required = permission_required('auth.resitel', raise_exception=True)
User = get_user_model()
User.je_org = lambda self: self.has_perm('auth.org')
User.je_resitel = lambda self: self.has_perm('auth.resitel')
AnonymousUser.je_org = lambda self: False
AnonymousUser.je_resitel = lambda self: False
class FirstTagParser(HTMLParser): class FirstTagParser(HTMLParser):

2
seminar/views/utils.py

@ -6,8 +6,6 @@ from html.parser import HTMLParser
import seminar.models as m import seminar.models as m
staff_member_required = user_passes_test(lambda u: u.is_staff)
class FirstTagParser(HTMLParser): class FirstTagParser(HTMLParser):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.firstTag = None self.firstTag = None

16
seminar/views/views_all.py

@ -1,6 +1,6 @@
# coding:utf-8 # coding:utf-8
from django.shortcuts import get_object_or_404, render from django.shortcuts import get_object_or_404, render, redirect
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, JsonResponse from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, JsonResponse
from django.urls import reverse,reverse_lazy from django.urls import reverse,reverse_lazy
from django.core.exceptions import PermissionDenied, ObjectDoesNotExist from django.core.exceptions import PermissionDenied, ObjectDoesNotExist
@ -13,7 +13,7 @@ from django.views.generic.edit import FormView, CreateView
from django.views.generic.base import TemplateView from django.views.generic.base import TemplateView
from django.contrib.auth import authenticate, login, get_user_model, logout from django.contrib.auth import authenticate, login, get_user_model, logout
from django.contrib.auth import views as auth_views from django.contrib.auth import views as auth_views
from django.contrib.auth.models import User from django.contrib.auth.models import User, Permission
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from django.db import transaction from django.db import transaction
@ -238,8 +238,7 @@ def spravne_novinky(request):
user = request.user user = request.user
# Využíváme líné vyhodnocování QuerySetů # Využíváme líné vyhodnocování QuerySetů
qs = Novinky.objects.all() qs = Novinky.objects.all()
# TODO: Tohle by mělo spíš kontrolovat, že je/není někdo org, než že může do Adminu. if not user.je_org:
if not user.is_staff:
qs = qs.filter(zverejneno=True) qs = qs.filter(zverejneno=True)
return qs.order_by('-datum') return qs.order_by('-datum')
@ -623,7 +622,7 @@ class ProblemView(generic.DetailView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
# Musí se používat context['object'], protože nevíme, jestli dostaneme úložku, téma, článek, .... a tyhle věci vyrábějí různé klíče. # Musí se používat context['object'], protože nevíme, jestli dostaneme úložku, téma, článek, .... a tyhle věci vyrábějí různé klíče.
if not context['object'].verejne() and not self.request.user.is_staff: if not context['object'].verejne() and not self.request.user.je_org:
raise PermissionDenied() raise PermissionDenied()
if isinstance(context['object'], Clanek): if isinstance(context['object'], Clanek):
context['reseni'] = Reseni.objects.filter(problem=context['object']).select_related('resitel').order_by('resitel__prijmeni') context['reseni'] = Reseni.objects.filter(problem=context['object']).select_related('resitel').order_by('resitel__prijmeni')
@ -1212,6 +1211,8 @@ def prihlaskaView(request):
password=fcd['password'], password=fcd['password'],
email = fcd['email']) email = fcd['email'])
u.save() u.save()
resitel_perm = Permission.objects.filter(codename__exact='resitel').first()
u.user_permissions.add(resitel_perm)
o = Osoba( o = Osoba(
jmeno = fcd['jmeno'], jmeno = fcd['jmeno'],
@ -1311,10 +1312,9 @@ class PasswordChangeView(auth_views.PasswordChangeView):
# Jen hloupé rozhazovátko # Jen hloupé rozhazovátko
def profilView(request): def profilView(request):
user = request.user user = request.user
# FIXME: správná oprávnění if user.has_perm('auth.org'):
if user.has_perm('org'):
return OrgoRozcestnikView.as_view()(request) return OrgoRozcestnikView.as_view()(request)
if user.has_perm('ucastnik'): if user.has_perm('auth.resitel'):
return ResitelView.as_view()(request) return ResitelView.as_view()(request)
else: else:
return LoginView.as_view()(request) return LoginView.as_view()(request)

Loading…
Cancel
Save