Browse Source

Merge branch 'data_migrations' of gimli.ms.mff.cuni.cz:/akce/mam/git/mamweb into data_migrations

export_seznamu_prednasek
Aneta Pokorná 4 years ago
parent
commit
8169b19e00
  1. 249
      data/auth_groups.json
  2. 2441
      data/auth_permissions.json
  3. 72
      data/sitetree.json
  4. 33
      mamweb/static/css/mamweb.css
  5. 7
      seminar/admin.py
  6. 41
      seminar/templates/seminar/archiv/cislo.html
  7. 18
      seminar/templates/seminar/clanky/resitelske_clanky.html
  8. 29
      seminar/templates/seminar/zadani/AktualniZadani.html
  9. 137
      seminar/views/views_all.py

249
data/auth_groups.json

@ -0,0 +1,249 @@
[
{
"fields": {
"name": "org",
"permissions": [
23,
24,
25,
1,
26,
72,
73,
74,
75,
76,
77,
78,
79,
51,
55,
52,
53,
54,
56,
57,
58,
59,
60,
61,
62,
63,
43,
44,
45,
46,
228,
229,
230,
231,
232,
233,
234,
235,
260,
261,
262,
263,
264,
265,
266,
267,
244,
245,
246,
247,
236,
237,
238,
239,
240,
241,
242,
243,
248,
249,
250,
251,
252,
253,
254,
255,
256,
257,
258,
259,
212,
213,
214,
215,
80,
81,
82,
83,
180,
181,
182,
183,
172,
173,
174,
175,
168,
169,
170,
171,
132,
133,
134,
135,
224,
225,
226,
227,
184,
185,
186,
187,
112,
113,
114,
115,
120,
121,
122,
123,
164,
165,
166,
167,
124,
125,
126,
127,
216,
217,
218,
219,
136,
137,
138,
139,
152,
153,
154,
155,
208,
209,
210,
211,
140,
141,
142,
143,
108,
109,
110,
111,
84,
85,
86,
87,
104,
105,
106,
107,
160,
161,
162,
163,
220,
221,
222,
223,
88,
89,
90,
91,
92,
93,
94,
95,
188,
189,
190,
191,
96,
97,
98,
99,
100,
101,
102,
103,
128,
129,
130,
131,
116,
117,
118,
119,
156,
157,
158,
159,
192,
193,
194,
195,
144,
145,
146,
147,
196,
197,
198,
199,
176,
177,
178,
179,
148,
149,
150,
151,
200,
201,
202,
203,
204,
205,
206,
207,
64,
65,
66,
67,
68,
69,
70,
71,
35,
36,
37,
38,
39,
40,
41,
42,
47,
48,
49,
50
]
},
"model": "auth.group",
"pk": 1
}
]

2441
data/auth_permissions.json

File diff suppressed because it is too large

72
data/sitetree_new.json → data/sitetree.json

@ -343,30 +343,6 @@
"model": "sitetree.treeitem", "model": "sitetree.treeitem",
"pk": 16 "pk": 16
}, },
{
"fields": {
"access_guest": false,
"access_loggedin": false,
"access_perm_type": 1,
"access_permissions": [],
"access_restricted": false,
"alias": null,
"description": "",
"hidden": false,
"hint": "",
"inbreadcrumbs": true,
"inmenu": true,
"insitetree": true,
"parent": 3,
"sort_order": 34,
"title": "Články",
"tree": 1,
"url": "clanky_resitel",
"urlaspattern": true
},
"model": "sitetree.treeitem",
"pk": 17
},
{ {
"fields": { "fields": {
"access_guest": false, "access_guest": false,
@ -659,30 +635,6 @@
"model": "sitetree.treeitem", "model": "sitetree.treeitem",
"pk": 33 "pk": 33
}, },
{
"fields": {
"access_guest": false,
"access_loggedin": false,
"access_perm_type": 1,
"access_permissions": [],
"access_restricted": false,
"alias": null,
"description": "",
"hidden": false,
"hint": "",
"inbreadcrumbs": true,
"inmenu": true,
"insitetree": true,
"parent": 3,
"sort_order": 17,
"title": "Témata",
"tree": 1,
"url": "seminar_temata",
"urlaspattern": true
},
"model": "sitetree.treeitem",
"pk": 34
},
{ {
"fields": { "fields": {
"access_guest": false, "access_guest": false,
@ -806,5 +758,29 @@
}, },
"model": "sitetree.treeitem", "model": "sitetree.treeitem",
"pk": 39 "pk": 39
},
{
"fields": {
"access_guest": false,
"access_loggedin": false,
"access_perm_type": 1,
"access_permissions": [],
"access_restricted": false,
"alias": null,
"description": "",
"hidden": false,
"hint": "",
"inbreadcrumbs": true,
"inmenu": true,
"insitetree": true,
"parent": 5,
"sort_order": 40,
"title": "Řešitelské články",
"tree": 1,
"url": "/archiv/clanky",
"urlaspattern": false
},
"model": "sitetree.treeitem",
"pk": 40
} }
] ]

33
mamweb/static/css/mamweb.css

@ -326,11 +326,7 @@ div.novinky_name {
font-style: italic; font-style: italic;
} }
div.zadani_azad_termin {
text-align: center;
font-size: large;
font-weight: bold
}
/********** /**********
* Footer * Footer
@ -906,6 +902,33 @@ div.cislo_odkazy ul {
padding: 0px; padding: 0px;
} }
/* aktuální zadání */
.stranka_aktualni_zadani {
text-align: center;
}
#azad_obrazek {
margin-top: 10px;
}
div.zadani_termin {
text-align: center;
font-size: large;
font-weight: bold;
}
@media (max-width: 420px) {
div.zadani_termin {
font-size: small;
}
}
div.zadani_termin .datum {
color:#e84e10;
margin:0px;
}
/* galerie */ /* galerie */

7
seminar/admin.py

@ -1,5 +1,5 @@
from django.contrib import admin from django.contrib import admin
from django.contrib.auth.models import Permission from django.contrib.auth.models import Group
from django.db import models from django.db import models
from django.forms import widgets from django.forms import widgets
@ -32,11 +32,12 @@ class OsobaAdmin(admin.ModelAdmin):
synchronizuj_maily.short_description = "Synchronizuj vybraným osobám e-maily do uživatelů" synchronizuj_maily.short_description = "Synchronizuj vybraným osobám e-maily do uživatelů"
def udelej_orgem(self,request,queryset): def udelej_orgem(self,request,queryset):
org_perm = Permission.objects.filter(codename__exact='org').first() org_group = Group.objects.get(name='org')
print(queryset) print(queryset)
for o in queryset: for o in queryset:
user = o.user user = o.user
user.user_permissions.add(org_perm) print(user)
user.groups.add(org_group)
user.is_staff = True user.is_staff = True
user.save() user.save()
org = m.Organizator.objects.create(osoba=o) org = m.Organizator.objects.create(osoba=o)

41
seminar/templates/seminar/archiv/cislo.html

@ -74,9 +74,24 @@
<th class='border-r'># <th class='border-r'>#
<th class='border-r'>Jméno <th class='border-r'>Jméno
{% 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' id="problem{{ p.kod_v_rocniku }}"><a href="{{ p.verejne_url }}">{{ p.kod_v_rocniku }}</a>
{# TODELETE #}
{% for podproblemy in podproblemy_iter.next %}
<th class='border-r podproblem{{ forloop.parentloop.counter }}'><a href="{{ podproblemy.verejne_url }}">{{ podproblemy.kod_v_rocniku }}</a>
{% endfor %}
{# TODELETE #}
{% endfor %} {% endfor %}
{% if ostatni %}<th class='border-r'>Ostatní {% endif %} {% if ostatni %}<th class='border-r'>Ostatní {% endif %}
{# TODELETE #}
{% for podproblemy in podproblemy_iter.next %}
<th class='border-r podproblem{{ problemy.len }}'><a href="{{ podproblemy.verejne_url }}">{{ podproblemy.kod_v_rocniku }}</a>
{% endfor %}
{# TODELETE #}
<th class='border-r'>Za číslo <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
@ -90,6 +105,13 @@
{{ rv.resitel.osoba.plne_jmeno }} {{ rv.resitel.osoba.plne_jmeno }}
{% for b in rv.body_problemy_sezn %} {% for b in rv.body_problemy_sezn %}
<td class='border-r'>{{ b }} <td class='border-r'>{{ b }}
{# TODELETE #}
{% for body_podproblemu in rv.body_podproblemy_iter.next %}
<td class='border-r podproblem{{ forloop.parentloop.counter }}'>{{ body_podproblemu }}
{% endfor %}
{# TODELETE #}
{% endfor %} {% endfor %}
<td class='border-r'>{{ rv.body_cislo }} <td class='border-r'>{{ rv.body_cislo }}
<td class='border-r'><b>{{ rv.body_rocnik }}</b> <td class='border-r'><b>{{ rv.body_rocnik }}</b>
@ -97,6 +119,23 @@
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>
{# TODELETE #}
<script>
{% for p in problemy %}
$(".podproblem{{ forloop.counter }}").css("display", "none")
$("#problem{{ forloop.counter }}")[0].addEventListener('mouseover', podproblem{{ forloop.counter }})
$("#problem{{ forloop.counter }}")[0].addEventListener('mouseout', podproblem{{ forloop.counter }}end)
function podproblem{{ forloop.counter }}(event) {
$(".podproblem{{ forloop.counter }}").css("display", "")
}
function podproblem{{ forloop.counter }}end(event) {
$(".podproblem{{ forloop.counter }}").css("display", "none")
}
{% endfor %}
</script>
{# TODELETE #}
{% endif %} {% endif %}
{% if not cislo.verejna_vysledkovka and user.je_org %} {% if not cislo.verejna_vysledkovka and user.je_org %}

18
seminar/templates/seminar/clanky/resitelske_clanky.html

@ -16,7 +16,23 @@
<ul> <ul>
{% endifchanged %} {% endifchanged %}
<li> <li>
<a href="{{ clanek.verejne_url }}">{{ clanek.nazev }}</a> {% if clanek.cislo.pdf %}
<a href="{{ clanek.cislo.pdf.url }}">
{{ clanek.nazev }}
({% for r in clanek.reseni_set.first.resitele.all %}
{{r}}
{% if not forloop.last %},{% endif %}
{% endfor %}
</a>
)
{% else %}
{{ clanek.nazev }}
({% for r in clanek.reseni_set.first.resitele.all %}
{{r}},
{% endfor %}
vyšlo v čísle {{clanek.cislo}})
{% endif %}
</li>
{% endwith %} {% endwith %}
{% endfor %} {% endfor %}
</ul> </ul>

29
seminar/templates/seminar/zadani/AktualniZadani.html

@ -5,7 +5,7 @@
{% endblock %}{% endblock %} {% endblock %}{% endblock %}
{% block content %} {% block content %}
<div> <div class="stranka_aktualni_zadani">
{% with nastaveni.aktualni_cislo as ac %} {% with nastaveni.aktualni_cislo as ac %}
@ -13,26 +13,27 @@
{% if user.je_org or verejne %} {% if user.je_org or verejne %}
{% if user.je_org and not verejne %}<div class="mam-org-only">{% endif %} {% if user.je_org and not verejne %}<div class="mam-org-only">{% endif %}
<div class="zadani_termin">
Termíny pro odeslání řešení {{ac.poradi}}. série:<br>
{% if ac.datum_deadline_soustredeni %} {% if ac.datum_deadline_soustredeni %}
<div class="zadani_azad_termin"> <span class="datum">{{ac.datum_deadline_soustredeni}}</span> pro účast na soustředění<br>
Termín odeslání {{ac.poradi}}. série pro účast na soustředění: {% endif %}
{{ac.datum_deadline_soustredeni}}
</div> {% if ac.datum_preddeadline %}
<span class="datum">{{ac.datum_preddeadline}}</span> pro otištění v dalším čísle<br>
{% endif %} {% endif %}
{% if ac.datum_deadline %} {% if ac.datum_deadline %}
<div class="zadani_azad_termin"> <span class="datum">{{ac.datum_deadline}}</span> definitivní deadline<br>
Termín odeslání {{ac.poradi}}. série: {{ac.datum_deadline}}
</div>
{% endif %} {% endif %}
{% if ac.datum_preddeadline %}
<div class="zadani_azad_termin">
Termín odeslání řešení {{ac.poradi}}. série, která mohou být otištěna v dalším čísle:
{{ac.datum_preddeadline}}
</div> </div>
{% endif %}
<hr>
{% if ac.titulka_nahled and ac.pdf %} {% if ac.titulka_nahled and ac.pdf %}
<a href="{{ac.pdf.url}}"><img src="{{ac.titulka_nahled.url}}" alt=Titulní strana {{ac.poradi}}. čísla></img></a> <a href="{{ac.pdf.url}}"><img id="azad_obrazek" src="{{ac.titulka_nahled.url}}" alt=Titulní strana {{ac.poradi}}. čísla></img></a>
{% endif %} {% endif %}
{% if ac.pdf %} {% if ac.pdf %}

137
seminar/views/views_all.py

@ -721,8 +721,9 @@ def hlavni_problemy_rocniku(rocnik, jen_verejne=True):
return hlavni_problemy return hlavni_problemy
def hlavni_problemy_cisla(cislo):
""" Vrátí seznam všech problémů s body v daném čísle, které již nemají nadproblém. """ def problemy_cisla(cislo):
""" Vrátí seznam všech problémů s body v daném čísle. """
hodnoceni = cislo.hodnoceni.select_related('problem', 'reseni').all() hodnoceni = cislo.hodnoceni.select_related('problem', 'reseni').all()
# hodnocení, která se vážou k danému číslu # hodnocení, která se vážou k danému číslu
@ -731,6 +732,14 @@ def hlavni_problemy_cisla(cislo):
problemy_set = set(problemy) # chceme každý problém unikátně, problemy_set = set(problemy) # chceme každý problém unikátně,
problemy = (list(problemy_set)) # převedení na množinu a zpět to zaručí problemy = (list(problemy_set)) # převedení na množinu a zpět to zaručí
return problemy
def hlavni_problemy_cisla(cislo, problemy=None):
""" Vrátí seznam všech problémů s body v daném čísle, které již nemají nadproblém. """
if problemy is None:
problemy = problemy_cisla(cislo)
# hlavní problémy čísla # hlavní problémy čísla
# (mají vlastní sloupeček ve výsledkovce, nemají nadproblém) # (mají vlastní sloupeček ve výsledkovce, nemají nadproblém)
hlavni_problemy = [] hlavni_problemy = []
@ -744,6 +753,27 @@ def hlavni_problemy_cisla(cislo):
return hlavni_problemy return hlavni_problemy
def podproblemy_v_cislu(cislo, problemy=None, hlavni_problemy=None):
""" Vrátí seznam všech problémů s body v daném čísle v poli 'indexovaném' tématy. """
if problemy is None:
problemy = problemy_cisla(cislo)
if hlavni_problemy is None:
hlavni_problemy = hlavni_problemy_cisla(cislo, problemy)
podproblemy = dict((hp.id, []) for hp in hlavni_problemy)
hlavni_problemy = set(hlavni_problemy)
podproblemy[-1] = []
for problem in problemy:
h_problem = hlavni_problem(problem)
if h_problem in hlavni_problemy:
podproblemy[h_problem.id].append(problem)
else:
podproblemy[-1].append(problem)
return podproblemy
def body_resitelu(resitele, za, odjakziva=True): def body_resitelu(resitele, za, odjakziva=True):
""" Funkce počítající počty bodů pro zadané řešitele, """ Funkce počítající počty bodů pro zadané řešitele,
buď odjakživa do daného ročníku/čísla anebo za daný ročník/číslo. buď odjakživa do daného ročníku/čísla anebo za daný ročník/číslo.
@ -941,7 +971,7 @@ class RadekVysledkovkyCisla(object):
Umožňuje snazší práci v templatu (lepší, než seznam).""" Umožňuje snazší práci v templatu (lepší, než seznam)."""
def __init__(self, poradi, resitel, body_problemy_sezn, def __init__(self, poradi, resitel, body_problemy_sezn,
body_cislo, body_rocnik, body_odjakziva, rok): body_cislo, body_rocnik, body_odjakziva, rok, body_podproblemy, body_podproblemy_iter):
self.resitel = resitel self.resitel = resitel
self.rocnik_resitele = resitel.rocnik(rok) self.rocnik_resitele = resitel.rocnik(rok)
self.body_cislo = body_cislo self.body_cislo = body_cislo
@ -950,6 +980,8 @@ class RadekVysledkovkyCisla(object):
self.poradi = poradi self.poradi = poradi
self.body_problemy_sezn = body_problemy_sezn self.body_problemy_sezn = body_problemy_sezn
self.titul = resitel.get_titul(body_odjakziva) self.titul = resitel.get_titul(body_odjakziva)
self.body_podproblemy = body_podproblemy
self.body_podproblemy_iter = body_podproblemy_iter # TODELETE
def pricti_body(slovnik, resitel, body): def pricti_body(slovnik, resitel, body):
@ -1039,11 +1071,81 @@ def secti_body_za_cislo(cislo, aktivni_resitele, hlavni_problemy=None):
pricti_body(nadproblem_slovnik, resitel, body) pricti_body(nadproblem_slovnik, resitel, body)
return hlavni_problemy_slovnik, cislobody return hlavni_problemy_slovnik, cislobody
def secti_body_za_cislo_podle_temat(cislo, aktivni_resitele, podproblemy=None, temata=None):
""" Spočítá u řešitelů body za číslo za úlohy v jednotlivých hlavních problémech (témata)."""
if temata is None:
temata = hlavni_problemy_cisla(cislo)
if podproblemy is None:
podproblemy_v_cislu(cislo, hlavni_problemy=temata)
body_slovnik = {}
for tema in temata:
body_slovnik[tema.id] = {}
for problem in podproblemy[tema.id]:
body_slovnik[tema.id][problem.id] = {}
body_slovnik[-1] = {}
for problem in podproblemy[-1]:
body_slovnik[-1][problem.id] = {}
# zakládání prázdných záznamů pro řešitele
for ar in aktivni_resitele:
for tema in temata:
for problem in podproblemy[tema.id]:
body_slovnik[tema.id][problem.id][ar.id] = ""
for problem in podproblemy[-1]:
body_slovnik[-1][problem.id][ar.id] = ""
temata = set(t.id for t in temata)
# vezmeme všechna řešení s body do daného čísla
reseni_do_cisla = Reseni.objects.prefetch_related('problem', 'resitele',
'hodnoceni_set').filter(hodnoceni__cislo_body=cislo)
# projdeme všechna řešení do čísla a přičteme body každému řešiteli do celkových
# bodů i do bodů za problém
for reseni in reseni_do_cisla:
# řešení může řešit více problémů
for prob in list(reseni.problem.all()):
nadproblem = hlavni_problem(prob)
if nadproblem.id in temata:
nadproblem_slovnik = body_slovnik[nadproblem.id]
else:
nadproblem_slovnik = body_slovnik[-1]
problem_slovnik = nadproblem_slovnik[prob.id]
# a mít více hodnocení
for hodn in list(reseni.hodnoceni_set.all()):
body = hodn.body
# a mít více řešitelů
for resitel in list(reseni.resitele.all()):
if resitel not in aktivni_resitele:
print("Skipping {}".format(resitel.id))
continue
pricti_body(problem_slovnik, resitel, body)
return body_slovnik
# TODELETE
class FixedIterator:
def next(self):
return self.niter.__next__()
def __init__(self, niter):
self.niter = niter
# TODELETE
def vysledkovka_cisla(cislo, context=None): def vysledkovka_cisla(cislo, context=None):
if context is None: if context is None:
context = {} context = {}
problemy = problemy_cisla(cislo)
hlavni_problemy = hlavni_problemy_cisla(cislo) hlavni_problemy = hlavni_problemy_cisla(cislo, problemy)
## TODO možná chytřeji vybírat aktivní řešitele ## TODO možná chytřeji vybírat aktivní řešitele
# aktivní řešitelé - chceme letos něco poslal, TODO později vyfiltrujeme ty, kdo mají # aktivní řešitelé - chceme letos něco poslal, TODO později vyfiltrujeme ty, kdo mají
# u alespoň jedné hodnoty něco jiného než NULL # u alespoň jedné hodnoty něco jiného než NULL
@ -1075,6 +1177,10 @@ def vysledkovka_cisla(cislo, context=None):
temata_a_spol = list(filter(ne_clanek_ne_konfera, hlavni_problemy)) temata_a_spol = list(filter(ne_clanek_ne_konfera, hlavni_problemy))
# získáme body u jednotlivých témat
podproblemy = podproblemy_v_cislu(cislo, problemy, temata_a_spol)
problemy_slovnik = secti_body_za_cislo_podle_temat(cislo, aktivni_resitele, podproblemy, temata_a_spol)
# def not_empty(value): # def not_empty(value):
# return value != '' # return value != ''
# #
@ -1084,20 +1190,26 @@ def vysledkovka_cisla(cislo, context=None):
for ar_id in setrizeni_resitele_id: for ar_id in setrizeni_resitele_id:
# získáme seznam bodů za problémy pro daného řešitele # získáme seznam bodů za problémy pro daného řešitele
problemy = [] body_problemy = []
body_podproblemy = []
for hp in temata_a_spol: for hp in temata_a_spol:
problemy.append(hlavni_problemy_slovnik[hp.id][ar_id]) body_problemy.append(hlavni_problemy_slovnik[hp.id][ar_id])
body_podproblemy.append([problemy_slovnik[hp.id][it.id][ar_id] for it in podproblemy[hp.id]])
if je_nejake_ostatni: if je_nejake_ostatni:
problemy.append(hlavni_problemy_slovnik[-1][ar_id]) body_problemy.append(hlavni_problemy_slovnik[-1][ar_id])
body_podproblemy.append([problemy_slovnik[-1][it.id][ar_id] for it in podproblemy[-1]])
# vytáhneme informace pro daného řešitele # vytáhneme informace pro daného řešitele
radek = RadekVysledkovkyCisla( radek = RadekVysledkovkyCisla(
poradi[i], # pořadí poradi[i], # pořadí
Resitel.objects.get(id=ar_id), # řešitel (z id) Resitel.objects.get(id=ar_id), # řešitel (z id)
problemy, # seznam bodů za hlavní problémy čísla body_problemy, # seznam bodů za hlavní problémy čísla
cislobody[ar_id], # body za číslo cislobody[ar_id], # body za číslo
setrizeni_resitele_body[i], # body za ročník (spočítané výše s pořadím) setrizeni_resitele_body[i], # body za ročník (spočítané výše s pořadím)
resitel_odjakzivabody_slov[ar_id], # body odjakživa resitel_odjakzivabody_slov[ar_id], # body odjakživa
cislo.rocnik) # ročník semináře pro zjištění ročníku řešitele cislo.rocnik,
body_podproblemy, # body všech podproblémů
FixedIterator(body_podproblemy.__iter__()) # TODELETE
) # ročník semináře pro zjištění ročníku řešitele
radky_vysledkovky.append(radek) radky_vysledkovky.append(radek)
i += 1 i += 1
@ -1106,6 +1218,9 @@ def vysledkovka_cisla(cislo, context=None):
context['radky_vysledkovky'] = radky_vysledkovky context['radky_vysledkovky'] = radky_vysledkovky
context['problemy'] = temata_a_spol context['problemy'] = temata_a_spol
context['ostatni'] = je_nejake_ostatni context['ostatni'] = je_nejake_ostatni
pt = [podproblemy[it.id] for it in temata_a_spol]+[podproblemy[-1]]
context['podproblemy'] = pt
context['podproblemy_iter'] = FixedIterator(pt.__iter__()) # TODELETE
#context['v_cisle_zadane'] = TODO #context['v_cisle_zadane'] = TODO
#context['resene_problemy'] = resene_problemy #context['resene_problemy'] = resene_problemy
return context return context
@ -1382,7 +1497,7 @@ class ClankyResitelView(generic.ListView):
# FIXME: QuerySet není pole! # FIXME: QuerySet není pole!
def get_queryset(self): def get_queryset(self):
clanky = Clanek.objects.filter(stav=Problem.STAV_ZADANY).select_related('cislo__rocnik').order_by('-cislo__rocnik__rocnik') clanky = Clanek.objects.filter(stav=Problem.STAV_VYRESENY).select_related('cislo__rocnik').order_by('-cislo__rocnik__rocnik')
queryset = [] queryset = []
skupiny_clanku = group_by_rocnik(clanky) skupiny_clanku = group_by_rocnik(clanky)
for skupina in skupiny_clanku: for skupina in skupiny_clanku:

Loading…
Cancel
Save