Merge branch 'develop' into django3.2
This commit is contained in:
commit
882f8e2228
27 changed files with 359 additions and 66 deletions
|
@ -16,7 +16,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fields": {
|
"fields": {
|
||||||
"content": "<h1 id=\"co-je-mm\">Co je M&M?</h1>\r\n\r\n<h3 id=\"mm-je-mezioborový-korespondenční-seminář-pro-středoškoláky\">M&M je mezioborový korespondenční seminář pro středoškoláky</h3>\r\n\r\n<p style=\"text-align: justify;\">Ptáš se, co že je to ten korespondenční seminář? Je to jednoduché, zamysli se nad <a href=\"/aktualni/zadani/\">zadanou úlohou či problémem</a>, <a href=\"/resitel/nahraj_reseni\">odevzdej řešení</a>, my ti jej opravíme a pošleme zpět. Nabízíme témata z různých oblastí matematiky, fyziky, informatiky i dalších oborů, takže si u nás určitě najdeš to svoje. Při řešení si můžeš vyzkoušet, jak vypadá vědecká práce, a mnoho zajímavého se naučit. Podívej se na tipy v sekci <a href=\"/jak-resit/\">Jak řešit</a> a pusť se do toho! Můžeš se připojit kdykoliv během roku.</p>\r\n\r\n<h3 id=\"mm-jsou-témata\">M&M jsou témata</h3>\r\n\r\n<p style=\"text-align: justify;\">Jádro M&M tvoří takzvaná témata, tedy texty doplněné o úlohy a náměty vyzývající k přemýšlení a experimentování. Přijímáme i originální přístup k problémům, takže můžeš například vyřešit fyzikální problém naprogramováním simulace. v minulých letech řešitelé sestavovali spektrometry, pomocí laserových ukazovátek měřili index lomu různých látek, zkoumali křivky popisující vývoj počtu cestujících v tramvaji v průběhu cesty nebo programovali strategie v jednoduché hře a pak je nechávali soupeřit v turnajích. Podívej se, jaká témata nabízíme <a href=\"/aktualni/zadani/\">právě teď</a>.</p>\r\n\r\n<h3 id=\"mm-je-časopis\">M&M je časopis</h3>\r\n\r\n<p style=\"text-align: justify;\">Zadání a texty od organizátorů vydáváme formou časopisu. Kromě toho zde rovněž otiskujeme řešení a příspěvky našich řešitelů k tématům, články shrnující výsledky <a href=\"/soustredeni/\">konfer</a> – projektů, kterými se zabývali na soustředění, i výsledky jejich vlastního výzkumu. Díky tomu jsme si například mohli přečíst o <a href=\"https://mam.mff.cuni.cz/media/cislo/pdf/25/25-6.pdf#page=45\">Lichtenbergových obrazcích</a> či <a href=\"https://mam.mff.cuni.cz/media/cislo/pdf/23/23-6.pdf#page=19\">gravitaci v placatém světě</a>. Během ročníku obvykle vyjde šest čísel časopisu, prohlédnout si je můžeš v <a href=\"/archiv/rocniky/\">Archivu</a>.</p>\r\n\r\n<h3 id=\"mm-je-soutěž\">M&M je soutěž</h3>\r\n\r\n<p style=\"text-align: justify;\">Ke všem příspěvkům posíláme řešitelům zpětnou vazbu a udělujeme za ně body. Vítězové semináře se mohou těšit na zajímavé knihy a deskové hry, autora nejlepšího otištěného článku každoročně odměňujeme dortem. <a href=\"/o-nas/odmeny/\">Úspěšným řešitelům</a> jsou navíc prominuty přijímací zkoušky na MFF UK.</p>\r\n\r\n<h3 id=\"mm-jsou-soustředění\">M&M jsou soustředění</h3>\r\n\r\n<p style=\"text-align: justify;\">Aktivní řešitelé mají možnost s námi za odměnu jet dvakrát do roka na soustředění. Pojeď taky! Budeš mít možnost strávit týden v přírodě plný odborného programu a nejrůznější zábavy s partou kamarádů. Čekají tě malé vědecké projekty, přednášky, workshopy, šifrovačka, výlet a mnoho dalšího. Chceš-li se dozvědět víc, přečti si stránku <a href=\"/soustredeni/\">Soustředění</a> nebo se podívej na <a href=\"/soustredeni/probehlo/\">fotky</a>.</p>\r\n\r\n<h3 id=\"mm-jsme-my\">M&M jsme my</h3>\r\n\r\n<p style=\"text-align: justify;\">Spolu s řešiteli jsme tu i my, organizátoři. Většina z nás jsou studenti Matfyzu, tedy Matematicko-fyzikální fakulty Univerzity Karlovy. Společně se snažíme předávat dál radost z poznávání zajímavých zákoutí matematiky, fyziky a informatiky a budovat komunitu aktivních lidí, kteří se budou rádi scházet, ať už na soustředěních, víkendovkách či jiných akcích. Chceš nás poznat blíž? Podívej se na stránku <a href=\"/o-nas/organizatori/\">Organizátoři</a> nebo rovnou něco vyřeš a pojeď s námi na soustředění!</p>\r\n\r\n<h3 id=\"zaujali-jsme-tě-zapoj-se-přečti-si-jak-řešit-a-podívej-se-na-aktuální-zadání.-už-se-těšíme-na-tvé-příspěvky\" style=\"text-align: center;\">Zaujali jsme tě? Zapoj se! Přečti si <a href=\"/jak-resit/podrobneji/\">jak řešit</a> a podívej se na <a href=\"/aktualni/zadani/\">aktuální zadání</a>. Už se těšíme na tvé příspěvky!</h3>",
|
"content": "<h1 id=\"co-je-mm\">Co je M&M?</h1>\r\n\r\n<h3 id=\"mm-je-mezioborový-korespondenční-seminář-pro-středoškoláky\">M&M je mezioborový korespondenční seminář pro středoškoláky</h3>\r\n\r\n<p style=\"text-align: justify;\">Ptáš se, co že je to ten korespondenční seminář? Je to jednoduché, zamysli se nad <a href=\"/aktualni/zadani/\">zadanou úlohou či problémem</a>, <a href=\"/resitel/nahraj_reseni\">odevzdej řešení</a>, my ti jej opravíme a pošleme zpět. Nabízíme témata z různých oblastí matematiky, fyziky, informatiky i dalších oborů, takže si u nás určitě najdeš to svoje. Při řešení si můžeš vyzkoušet, jak vypadá vědecká práce, a mnoho zajímavého se naučit. Podívej se na tipy v sekci <a href=\"/jak-resit/\">Jak řešit</a> a pusť se do toho! Můžeš se připojit kdykoliv během roku.</p>\r\n\r\n<h3 id=\"mm-jsou-témata\">M&M jsou témata</h3>\r\n\r\n<p style=\"text-align: justify;\">Jádro M&M tvoří takzvaná témata, tedy texty doplněné o úlohy a náměty vyzývající k přemýšlení a experimentování. Přijímáme i originální přístup k problémům, takže můžeš například vyřešit fyzikální problém naprogramováním simulace. V minulých letech řešitelé sestavovali spektrometry, pomocí laserových ukazovátek měřili index lomu různých látek, zkoumali křivky popisující vývoj počtu cestujících v tramvaji v průběhu cesty nebo programovali strategie v jednoduché hře a pak je nechávali soupeřit v turnajích. Podívej se, jaká témata nabízíme <a href=\"/aktualni/zadani/\">právě teď</a>.</p>\r\n\r\n<h3 id=\"mm-je-časopis\">M&M je časopis</h3>\r\n\r\n<p style=\"text-align: justify;\">Zadání a texty od organizátorů vydáváme formou časopisu. Kromě toho zde rovněž otiskujeme řešení a příspěvky našich řešitelů k tématům, články shrnující výsledky <a href=\"/soustredeni/\">konfer</a> – projektů, kterými se zabývali na soustředění, i výsledky jejich vlastního výzkumu. Díky tomu jsme si například mohli přečíst o <a href=\"https://mam.mff.cuni.cz/media/cislo/pdf/25/25-6.pdf#page=45\">Lichtenbergových obrazcích</a> či <a href=\"https://mam.mff.cuni.cz/media/cislo/pdf/23/23-6.pdf#page=19\">gravitaci v placatém světě</a>. Během ročníku obvykle vyjde šest čísel časopisu, prohlédnout si je můžeš v <a href=\"/archiv/rocniky/\">Archivu</a>.</p>\r\n\r\n<h3 id=\"mm-je-soutěž\">M&M je soutěž</h3>\r\n\r\n<p style=\"text-align: justify;\">Ke všem příspěvkům posíláme řešitelům zpětnou vazbu a udělujeme za ně body. Vítězové semináře se mohou těšit na zajímavé knihy a deskové hry, autora nejlepšího otištěného článku každoročně odměňujeme dortem. <a href=\"/o-nas/odmeny/\">Úspěšným řešitelům</a> jsou navíc prominuty přijímací zkoušky na MFF UK.</p>\r\n\r\n<h3 id=\"mm-jsou-soustředění\">M&M jsou soustředění</h3>\r\n\r\n<p style=\"text-align: justify;\">Aktivní řešitelé mají možnost s námi za odměnu jet dvakrát do roka na soustředění. Pojeď taky! Budeš mít možnost strávit týden v přírodě plný odborného programu a nejrůznější zábavy s partou kamarádů. Čekají tě malé vědecké projekty, přednášky, workshopy, šifrovačka, výlet a mnoho dalšího. Chceš-li se dozvědět víc, přečti si stránku <a href=\"/soustredeni/\">Soustředění</a> nebo se podívej na <a href=\"/soustredeni/probehlo/\">fotky</a>.</p>\r\n\r\n<h3 id=\"mm-jsme-my\">M&M jsme my</h3>\r\n\r\n<p style=\"text-align: justify;\">Spolu s řešiteli jsme tu i my, organizátoři. Většina z nás jsou studenti Matfyzu, tedy Matematicko-fyzikální fakulty Univerzity Karlovy. Společně se snažíme předávat dál radost z poznávání zajímavých zákoutí matematiky, fyziky a informatiky a budovat komunitu aktivních lidí, kteří se budou rádi scházet, ať už na soustředěních, víkendovkách či jiných akcích. Chceš nás poznat blíž? Podívej se na stránku <a href=\"/o-nas/organizatori/\">Organizátoři</a> nebo rovnou něco vyřeš a pojeď s námi na soustředění!</p>\r\n\r\n<h3 id=\"zaujali-jsme-tě-zapoj-se-přečti-si-jak-řešit-a-podívej-se-na-aktuální-zadání.-už-se-těšíme-na-tvé-příspěvky\" style=\"text-align: center;\">Zaujali jsme tě? Zapoj se! Přečti si <a href=\"/jak-resit/podrobneji/\">jak řešit</a> a podívej se na <a href=\"/aktualni/zadani/\">aktuální zadání</a>. Už se těšíme na tvé příspěvky!</h3>",
|
||||||
"enable_comments": false,
|
"enable_comments": false,
|
||||||
"registration_required": false,
|
"registration_required": false,
|
||||||
"sites": [
|
"sites": [
|
||||||
|
|
173
docs/zapisy/2021-12-06-testovani_dokumentace_codereview.md
Normal file
173
docs/zapisy/2021-12-06-testovani_dokumentace_codereview.md
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
# Postup zkrášlení kódu M&Mího webu
|
||||||
|
|
||||||
|
## Obecně o webu
|
||||||
|
|
||||||
|
- Python, Django, spousta nějakých rozšíření, frontend HTML + CSS + trocha JS
|
||||||
|
- Velké břímě historie, kterou nejspíš nechceme zahodit
|
||||||
|
- Změny v M&M někdy dost zamotají potřebný kód (tituly)
|
||||||
|
- Občas je potřeba dělat opravy rychle
|
||||||
|
|
||||||
|
## Aktuální stav
|
||||||
|
|
||||||
|
- Zběsile zbastlený kód
|
||||||
|
- „Co je to ‚single responsibility principle‘?“ ☺
|
||||||
|
- Dost netriviální množství objektů a jejich vazeb
|
||||||
|
- Dost možná do velké míry inherentní složitost
|
||||||
|
- Webaři aktuálně relativně zběhlí v programování (ale je potřeba myslet na to, že to tak být nemusí)
|
||||||
|
- Webaři stárnou (Jethro, Kristý, Anet) a mizí (Pavel, Káťa), je potřeba web připravit na předání
|
||||||
|
- Kód je rozdělený mezi orgy a jeden „nerozumí“ tomu, co druhý napsal (musí to vyčíst z kódu, nezná souvislosti, …)
|
||||||
|
- Noví orgové se aktuálně musí ptát, což je jim nepříjemné a nutí je umět formulovat dotazy
|
||||||
|
|
||||||
|
### Invarianty
|
||||||
|
|
||||||
|
- Není to práce, ale zábava-ish → libovolný proces nesmí být (moc) na obtíž.
|
||||||
|
- I malé nepohodlí je potřeba vyvážit relativně velkým přínosem
|
||||||
|
- nebo dostatečně zřejmou vidinou budoucího pohodlí / minimalizace nepohodlí
|
||||||
|
- Nejsme programátoři, spíš jsme bastlíři kódu (kteří znají rozumnou podmnožinu syntaxe Pythonu)
|
||||||
|
- Zvlášť noví orgové
|
||||||
|
- Nechceme cílit na mega-profi kód, je to nedosažitelný cíl
|
||||||
|
- Nejspíš to do nějaké míry ubastlené bude pořád, ta míra závisí na zkušenosti aktuálních webařů
|
||||||
|
- Nástroje nás nesmí moc mást.
|
||||||
|
- Děláme to zadarmo jeden večer v týdnu
|
||||||
|
- Vývoj jde pomalu, často pomaleji než vývoj knihoven
|
||||||
|
- → kód se rozbíjí i sám
|
||||||
|
- Běží to na Gimlim
|
||||||
|
- Debian (old)stable → nemůžeme používat moc nové featury Pythonu
|
||||||
|
- Aktuálně Python 3.7.3
|
||||||
|
- Webaři jsou náhodně vzniklá skupina lidí.
|
||||||
|
- Různé nástroje, různé operační systémy
|
||||||
|
- Nechceme vynucovat konkrétní metody, multiplatformní nástroje asi požadovat můžeme
|
||||||
|
- Na serveru může běžet cokoliv, co tam jde rozběhnout
|
||||||
|
- Kód by neměl být moc složitý / matoucí / kompaktní (?)
|
||||||
|
- případně fakt hodně okomentovaný
|
||||||
|
|
||||||
|
## O co se snažíme
|
||||||
|
|
||||||
|
- Zpřístupnit vývoj novým webařům
|
||||||
|
- Umožnit chápání i cizího kódu co nejjednodušeji
|
||||||
|
- Nevzít si s sebou implementační tajemství ~~do hrobu~~ pryč z M&Mka
|
||||||
|
|
||||||
|
```graphviz
|
||||||
|
digraph "Závislosti věcí" {
|
||||||
|
ss -> sdil -> doku -> cs;
|
||||||
|
ss -> cit ->ref -> cs;
|
||||||
|
ref -> nrt -> tst -> cs;
|
||||||
|
sdil -> cr -> cs
|
||||||
|
ss -> nrt;
|
||||||
|
ss[label="Současný stav",shape=box];
|
||||||
|
cit[label="čitelný kód"];
|
||||||
|
cs[label="Cílový stav",shape=box];
|
||||||
|
ref[label="refactoring"];
|
||||||
|
nrt[label="nerozbít to"];
|
||||||
|
tst[label="testy"];
|
||||||
|
doku[label="dokumentace (vývojářská)"];
|
||||||
|
sdil[label="chápání kódu ostatních / stávajícího"];
|
||||||
|
cr[label="code review"];
|
||||||
|
nrt,sdil,cit[shape=hexagon];
|
||||||
|
tst,doku,cr[color=blue];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Code review
|
||||||
|
|
||||||
|
Aktuálně: Pavel občas z rozmaru čte diffy; párkrát jsme zkoušeli [programovat v páru](https://mam.mff.cuni.cz/wiki/Web/Tipy/PairProgramming), je to relativně časově náročné.
|
||||||
|
|
||||||
|
- Nevynucovat
|
||||||
|
- Primární motivace je umožnit nějak vidět změny a případně k nim dávat komentáře, jak stylu „tohle mi není jasné“, tak i „tohle by chtělo přepsat“.
|
||||||
|
- Chceme hlavně vytvořit příležitost ke čtení cizího kódu a seznamování se s ním (i v zájmu zaučování nových webařů)
|
||||||
|
|
||||||
|
### Názory
|
||||||
|
|
||||||
|
- spíš post-hoc
|
||||||
|
- Možná code-review toho, co jde na produkci
|
||||||
|
- Chceme umět komentovat konkrétní řádky kódu
|
||||||
|
|
||||||
|
- Gitea/gitlab?
|
||||||
|
- Klikátko a barevný řádky a vyhledávání jsou fajn (gitlab, gitea)
|
||||||
|
- Jethro: je fajn umět skočit na definici
|
||||||
|
- Kombinace s CI
|
||||||
|
- Pokud bude gitea v něčem nedostatečná, tak hrozí, že bude potřeba migrovat znovu, což je nepraktické
|
||||||
|
- Gitlab je asi častější než gitea → je lepší názor si na to zvyknout
|
||||||
|
|
||||||
|
__Závěr:__ Zkusíme to hodit do GitLabu (nejspíš veřejného\*), zavedeme pull-requesty do `master` větve, náhodně se budeme přiřazovat a používat ho nějak intuitivně.
|
||||||
|
|
||||||
|
\*: Ve fakultním neumíme přidávat další uživatele, v KAMím zas možná není CI.
|
||||||
|
|
||||||
|
## Testy
|
||||||
|
|
||||||
|
Aktuálně: pár testů na dohromady řádově 4 funkce, drobný pokus o TDD, jenž narazil na úskalí reálného světa. Lokální spuštění testů trvá relativně dlouho, nejspíš kvůli spoustě migrací.
|
||||||
|
|
||||||
|
- Potřebujeme ověřit, že to funguje a že to _pořád_ funguje
|
||||||
|
|
||||||
|
- CI? Coverage?
|
||||||
|
|
||||||
|
### Názory
|
||||||
|
|
||||||
|
- PyTest je fajn
|
||||||
|
- Testovat frontend?
|
||||||
|
- Jethro: při nasazení by se mohly dělat screenshoty celých vybraných stránek přes Selenium (nebo obdobné) a hlásit rozdíly
|
||||||
|
|
||||||
|
__Závěr:__ Backend testujeme PyTestem (`./manage.py test`), u frontendu výhledově zkusíme ty vizuální diffy a pak se uvidí, CI podle webového klikátka na code review. Bylo by dobré mít rozumná testdata, ať se nemusí mockovat moc věcí.
|
||||||
|
|
||||||
|
## Formát kódu
|
||||||
|
|
||||||
|
Aktuálně: Jakýsi coding style zhruba existuje, není popsaný, šíří se lidovou slovesností.
|
||||||
|
|
||||||
|
- Nesmí být striktně vynucovaný
|
||||||
|
- Musel by být hodně nastavitelný
|
||||||
|
- Nechceme mít kód plný `#NOQA: WTF42`
|
||||||
|
- Nejspíš vždycky bude mít false positives (`seminar.utils.roman_numerals`) i false negatives (`seminar.models.tvorba.Cislo.posli_cislo_mailem`)
|
||||||
|
- Možná dobrý sluha, ale určitě špatný pán (also: špatná zkušenost ☺)
|
||||||
|
- __Důsledek:__ Hrozí, že těch falešných varování bude moc, čímž to ztratí smysl úplně
|
||||||
|
- Potenciálně by šlo aplikovat jen lokálně na změny?
|
||||||
|
|
||||||
|
### Názory
|
||||||
|
|
||||||
|
- P: nemyslím si, že zvládneme mít „průhledný kód“ (dostatečně konzistentní kód, aby ho člověk přestal vnímat a spíš viděl myšlenky).
|
||||||
|
|
||||||
|
- P: Kecadla do kódu trochu zavání větším peklem než užitkem (takže black a flake8 jsou ze hry); isort možná dává smysl; je otázka, jestli použít mypy, ale typové značky v kódu spíš chceme (zvlášť u věcí, které nejsou prostě django view – typicky utils.)
|
||||||
|
- J: Divné (=Pavlovo) groupování importů je spíš matoucí, spíš moc nepomáhalo
|
||||||
|
|
||||||
|
- P (doplněno zpětně): pydocstyle vynucuje PEP-257, který se možná tluče se sphinxem…
|
||||||
|
- P (též zpětně): Možná by se mohl dát použít pylint, tomu jde aspoň vysvětlit coding style a nerazí tupě PEP-8, ale nastavovat ho je asi větší porod, než jak moc pomůže…
|
||||||
|
|
||||||
|
__Závěr:__ Kecadla na formát spíš nechceme; isort by mohl být fajn, ale bylo by dobré mít rozdělené bloky „náš kód“, „standardní knihovna“ a „Django a další balíčky z PyPA“; u našeho kódu (utils, obecně ne-Django věci) chceme držet záměr (na úrovni dohody) psát signatury funkcí a v případě jejich přítomnosti se nechat varovat při porušení signatury.
|
||||||
|
|
||||||
|
- P (večerní prokrastinace): Bandit vypadá, že hlásí jen strašně obvious věci by default, nepřijde mi jako moc úžasné vylepšení. Do CI možná dobrý
|
||||||
|
|
||||||
|
## Dokumentace
|
||||||
|
|
||||||
|
Aktuálně: něco málo je na wiki (`/Web/`), občas má nějaká funkce docstring, obecně je toho málo
|
||||||
|
|
||||||
|
### Požadavky
|
||||||
|
|
||||||
|
- Jedno autoritativní místo a dá se najít
|
||||||
|
- Dostatečně „blízko“ kódu
|
||||||
|
- nastavit mindset na psaní dokumentace „rovnou“?
|
||||||
|
- Umožnit i obecný text, ne jen komentáře kódu (modulů, funkcí)
|
||||||
|
|
||||||
|
|
||||||
|
### Bonusy
|
||||||
|
|
||||||
|
- Zajišťování konzistence s uživatelskou dokumentací
|
||||||
|
- aktuálně wiki
|
||||||
|
- Podpora i dalších jazyků (Vue, Javascript, CSS, možná django-templates)
|
||||||
|
|
||||||
|
### Názory
|
||||||
|
|
||||||
|
- Jde to dělat sphinxem
|
||||||
|
- Stínovlas by mohl vědět v CZ.NICu se sphinx jede. Případně zkusit zjistit, co umí jejich Akademie
|
||||||
|
- Free-textová dokumentace (architektura ap.) má být nezávislá na dokumentaci konkrétního kódu, ale je fajn, když se to pak spojí dohromady, jde-li to.
|
||||||
|
- Lepší, když se obojí dá dělat stejným nástrojem
|
||||||
|
- Káťa má někdy pocit, že tráví spoustu času tím, že hledá který soubor vůbec upravit; to má v naší dokumentaci být.
|
||||||
|
|
||||||
|
__Závěr:__ Zkusíme použít sphinx (z nedostatku vlastních zkušeností a kvůli jeho popularitě), když se nám to nebude líbit, tak budeme řešit dál. Bylo by fajn najít nějaký workshop, bude to rychlejší nalejvárna než číst dokumentaci. V krátkodobém výhledu stáhneme vývojovou dokumentaci z webu do repozitáře a zprovozníme někde automatické buildy (aby se dala číst jako člověk a ne jako stroj).
|
||||||
|
|
||||||
|
## Uživatelská dokumentace
|
||||||
|
|
||||||
|
- K: Dělat ji ve spolupráci s těma uživatelema
|
||||||
|
- P: Dávný Hedgedoc může případně sloužit jako základ osnovy
|
||||||
|
- K: Dost možná nevíme, co bolí víc a co míň
|
||||||
|
- Jethro: Musí být na wiki, jinak tím zmateme oržstvo
|
||||||
|
|
||||||
|
__Závěr:__ Dokumentace bude na wiki (<https://mam.mff.cuni.cz/wiki/Web_user/Dokumentace>, výhledově možná ve stejné složce v dalších souborech), bude vznikat podle našich pocitů a dotazů od ostatních; výhledově bude schůzka na ukázání featur nového webu a tam se dosbírají náměty na to, co sepsat.
|
|
@ -62,11 +62,12 @@
|
||||||
</div>
|
</div>
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
{% endif%}
|
{% endif%}
|
||||||
|
<span id="nahoru" class="kotva_obrazku"></span>
|
||||||
<img src="{{obrazek.obrazek_stredni.url}}"
|
<img src="{{obrazek.obrazek_stredni.url}}"
|
||||||
height="{{vyska}}"
|
height="{{vyska}}"
|
||||||
width="{{sirka}}"
|
width="{{sirka}}"
|
||||||
alt="{{obrazek.popis}}"
|
alt="{{obrazek.popis}}"
|
||||||
class="obrazek" id="nahoru">
|
class="obrazek">
|
||||||
|
|
||||||
{% if obrazky_dalsi %}
|
{% if obrazky_dalsi %}
|
||||||
{% with obrazky_dalsi|first as dalsi_obrazek %}
|
{% with obrazky_dalsi|first as dalsi_obrazek %}
|
||||||
|
|
|
@ -2,6 +2,8 @@ from django.contrib import admin
|
||||||
from reversion.admin import VersionAdmin
|
from reversion.admin import VersionAdmin
|
||||||
from korektury.models import KorekturovanePDF
|
from korektury.models import KorekturovanePDF
|
||||||
|
|
||||||
|
from django.core.mail import send_mail
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
# Register your models here.
|
# Register your models here.
|
||||||
class KorekturovanePDFAdmin(VersionAdmin):
|
class KorekturovanePDFAdmin(VersionAdmin):
|
||||||
|
@ -16,11 +18,31 @@ class KorekturovanePDFAdmin(VersionAdmin):
|
||||||
fieldsets = [
|
fieldsets = [
|
||||||
(None,
|
(None,
|
||||||
{'fields':
|
{'fields':
|
||||||
['pdf', 'cas', 'org', 'stran', 'nazev', 'komentar']}),
|
['pdf', 'cas', 'org', 'stran', 'nazev', 'komentar', 'poslat_mail']}),
|
||||||
# (u'PDF', {'fields': ['pdf']}),
|
# (u'PDF', {'fields': ['pdf']}),
|
||||||
]
|
]
|
||||||
list_display = ['nazev', 'cas', 'stran', 'org']
|
list_display = ['nazev', 'cas', 'stran', 'org']
|
||||||
list_filter = []
|
list_filter = []
|
||||||
search_fields = []
|
search_fields = []
|
||||||
|
|
||||||
|
def save_model(self, request, obj, form, change):
|
||||||
|
super().save_model(request, obj, form, change)
|
||||||
|
if not change and obj.poslat_mail: # Je nový a má se poslat mail
|
||||||
|
odkaz = request.build_absolute_uri(reverse('korektury', kwargs={'pdf': obj.id}))
|
||||||
|
odesilatel = 'korekturovatko-nove-pdf@mam.mff.cuni.cz'
|
||||||
|
prijemce = 'org@mam.mff.cuni.cz'
|
||||||
|
predmet = f'Nové korektury: {obj.nazev}'
|
||||||
|
text = f'''\
|
||||||
|
V korekturovátku se objevil nový soubor: {obj.nazev}
|
||||||
|
{odkaz}
|
||||||
|
|
||||||
|
Popis souboru:
|
||||||
|
{obj.komentar}
|
||||||
|
|
||||||
|
---
|
||||||
|
S pozdravem a korekturám zdar!
|
||||||
|
Korekturovátko
|
||||||
|
'''
|
||||||
|
send_mail(predmet,text,odesilatel,[prijemce])
|
||||||
|
|
||||||
admin.site.register(KorekturovanePDF, KorekturovanePDFAdmin)
|
admin.site.register(KorekturovanePDF, KorekturovanePDFAdmin)
|
||||||
|
|
18
korektury/migrations/0018_korekturovanepdf_poslat_mail.py
Normal file
18
korektury/migrations/0018_korekturovanepdf_poslat_mail.py
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 2.2.24 on 2021-12-05 23:09
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('korektury', '0017_auto_20190610_2358'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='korekturovanepdf',
|
||||||
|
name='poslat_mail',
|
||||||
|
field=models.BooleanField(default=True, help_text='Určuje, zda se má o nově nahraném PDF poslat e-mail do mam-org. Při upravování existujícího souboru už nemá žádný vliv.', verbose_name='Poslat mail o novém PDF'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -63,6 +63,10 @@ class KorekturovanePDF(models.Model):
|
||||||
status = models.CharField(u'stav PDF',max_length=16, choices=STATUS_CHOICES, blank=False,
|
status = models.CharField(u'stav PDF',max_length=16, choices=STATUS_CHOICES, blank=False,
|
||||||
default = STATUS_PRIDAVANI)
|
default = STATUS_PRIDAVANI)
|
||||||
|
|
||||||
|
poslat_mail = models.BooleanField('Poslat mail o novém PDF', default=True,
|
||||||
|
help_text='Určuje, zda se má o nově nahraném PDF poslat e-mail do mam-org. Při upravování existujícího souboru už nemá žádný vliv.',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
#TODO Nepovinný foreign key k číslu
|
#TODO Nepovinný foreign key k číslu
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
<i>{{pdf.komentar}}</i>
|
<i>{{pdf.komentar}}</i>
|
||||||
<br>
|
<br>
|
||||||
<i>Klikni na chybu, napiš komentář</i> |
|
<i>Klikni na chybu, napiš komentář</i> |
|
||||||
|
<a href="{{pdf.pdf.url}}">stáhnout PDF (bez korektur)</a> |
|
||||||
<a href="../">seznam souborů</a> |
|
<a href="../">seznam souborů</a> |
|
||||||
<a href="/admin/korektury/korekturovanepdf/">Spravovat PDF</a> |
|
<a href="/admin/korektury/korekturovanepdf/">Spravovat PDF</a> |
|
||||||
<a href="../help">nápověda</a> |
|
<a href="../help">nápověda</a> |
|
||||||
|
|
|
@ -22,9 +22,8 @@
|
||||||
<ul>
|
<ul>
|
||||||
{% for pdf in skupina.list %}
|
{% for pdf in skupina.list %}
|
||||||
<li><span {% if pdf.status == 'zanaseni'%} class="comitting-text" {% elif pdf.status == 'zastarale' %} class="deprecated-text" {% endif %}>
|
<li><span {% if pdf.status == 'zanaseni'%} class="comitting-text" {% elif pdf.status == 'zastarale' %} class="deprecated-text" {% endif %}>
|
||||||
<b>{{ pdf.nazev }}</b>
|
<b><a href="/korektury/{{pdf.id}}">{{ pdf.nazev }}</a></b>
|
||||||
<i>{{pdf.komentar}}</i>
|
<i>{{pdf.komentar}}</i>
|
||||||
<a href="/korektury/{{pdf.id}}">{{pdf.pdf.name}}</a>
|
|
||||||
(k opravě: {{pdf.k_oprave_cnt}},
|
(k opravě: {{pdf.k_oprave_cnt}},
|
||||||
opraveno: {{pdf.opraveno_cnt}},
|
opraveno: {{pdf.opraveno_cnt}},
|
||||||
není chyba: {{pdf.neni_chyba_cnt}},
|
není chyba: {{pdf.neni_chyba_cnt}},
|
||||||
|
|
|
@ -166,7 +166,7 @@ class KorekturyView(generic.TemplateView):
|
||||||
texty = [(oprava.autor.osoba.plne_jmeno(),oprava.text)]
|
texty = [(oprava.autor.osoba.plne_jmeno(),oprava.text)]
|
||||||
for kom in Komentar.objects.filter(oprava=oprava):
|
for kom in Komentar.objects.filter(oprava=oprava):
|
||||||
texty.append((kom.autor.osoba.plne_jmeno(),kom.text))
|
texty.append((kom.autor.osoba.plne_jmeno(),kom.text))
|
||||||
optext = "\n".join([": ".join(t) for t in texty])
|
optext = "\n\n\n".join([": ".join(t) for t in texty])
|
||||||
text = u"Text komentáře:\n\n{}\n\n=== Konec textu komentáře ===\n\
|
text = u"Text komentáře:\n\n{}\n\n=== Konec textu komentáře ===\n\
|
||||||
\nodkaz do korekturovátka: {}\n\
|
\nodkaz do korekturovátka: {}\n\
|
||||||
\nVaše korekturovátko\n".format(optext, odkaz)
|
\nVaše korekturovátko\n".format(optext, odkaz)
|
||||||
|
|
|
@ -336,3 +336,16 @@ CISLO_IMG_DIR = os.path.join('cislo', 'img')
|
||||||
|
|
||||||
# E-MAIL NOTIFICATIONS
|
# E-MAIL NOTIFICATIONS
|
||||||
POSLI_MAILOVOU_NOTIFIKACI = False
|
POSLI_MAILOVOU_NOTIFIKACI = False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Logování chyb
|
||||||
|
class InvalidTemplateVariable(str):
|
||||||
|
def __mod__(self, variable):
|
||||||
|
import logging
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
logger.warning("Proměnná '%s' neexistuje" % variable)
|
||||||
|
return ''
|
||||||
|
TEMPLATES[0]['OPTIONS']['string_if_invalid'] = InvalidTemplateVariable('%s')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,10 @@ src: url("../fonts/OpenSans/OpenSans-Regular.ttf");
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
text-align: justify;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: 'OpenSans';
|
font-family: 'OpenSans';
|
||||||
background-color: #fffbf6;
|
background-color: #fffbf6;
|
||||||
|
@ -1113,6 +1117,21 @@ div.zadani_termin .datum {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* posune kotvu obrázku v galerii o oranžový pruh dolu, aby se pod ním obrázek neschovával */
|
||||||
|
/* https://stackoverflow.com/questions/10732690/offsetting-an-html-anchor-to-adjust-for-fixed-header */
|
||||||
|
.kotva_obrazku {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
width: 0;
|
||||||
|
height: 55px; /* viz #title */
|
||||||
|
margin-top: -55px; /* viz #title */
|
||||||
|
}
|
||||||
|
@media(max-width: 860px) {
|
||||||
|
.kotva_obrazku {
|
||||||
|
height: 3em; /* #FIXME nemám páru, jak zjistit výšku toho elementu */
|
||||||
|
margin-top: -3em; /* #FIXME */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,16 @@
|
||||||
{% extends "base.html" %}
|
{% extends "error_base.html" %}
|
||||||
|
|
||||||
{% load staticfiles %}
|
{% load staticfiles %}
|
||||||
|
|
||||||
{% block content %}
|
{% block errorheading %}
|
||||||
<h2>
|
|
||||||
{% block nadpis1a %}{% block nadpis1b %}
|
|
||||||
O-jo-jo-jo-joj
|
O-jo-jo-jo-joj
|
||||||
{% endblock %}{% endblock %}
|
{% endblock %}
|
||||||
</h2>
|
|
||||||
|
|
||||||
<p>
|
{% block errortext %}
|
||||||
Chybička se vloudila.
|
Chybička se vloudila.
|
||||||
Zkuste přejít na <a href="/">titulní stránku</a>
|
{% endblock %}
|
||||||
nebo se podívat na <a href="{% url 'seminar_aktualni_zadani' %}">aktuální zadání</a>.
|
|
||||||
</p>
|
{% block errorimage %}
|
||||||
<img src="{% static '500.png' %}">
|
<img src="{% static '500.png' %}">
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,16 @@
|
||||||
{% extends "base.html" %}
|
{% extends "error_base.html" %}
|
||||||
|
|
||||||
{% load staticfiles %}
|
{% load staticfiles %}
|
||||||
|
|
||||||
{% block content %}
|
{% block errorheading %}
|
||||||
<h2>
|
|
||||||
{% block nadpis1a %}{% block nadpis1b %}
|
|
||||||
Vrrrrrrrrr
|
Vrrrrrrrrr
|
||||||
{% endblock %}{% endblock %}
|
{% endblock %}
|
||||||
</h2>
|
|
||||||
|
|
||||||
<p>
|
{% block errortext %}
|
||||||
Tady pravděpodobně nemáte co dělat.
|
Tady pravděpodobně nemáte co dělat.
|
||||||
Zkuste přejít na <a href="/">titulní stránku</a>
|
{% endblock %}
|
||||||
nebo se podívat na <a href="{% url 'seminar_aktualni_zadani' %}">aktuální zadání</a>.
|
|
||||||
</p>
|
{% block errorimage %}
|
||||||
<img src="{% static '500.png' %}">
|
<img src="{% static '500.png' %}">
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,16 @@
|
||||||
{% extends "base.html" %}
|
{% extends "error_base.html" %}
|
||||||
|
|
||||||
{% load staticfiles %}
|
{% load staticfiles %}
|
||||||
|
|
||||||
{% block content %}
|
{% block errorheading %}
|
||||||
<h2>
|
Požadovaná stránka nenalezena
|
||||||
{% block nadpis1a %}{% block nadpis1b %}
|
{% endblock %}
|
||||||
Požadovaná stránka nenalezena
|
|
||||||
{% endblock %}{% endblock%}
|
{% block errortext %}
|
||||||
</h2>
|
Tuto stránku jsme na našem serveru nenalezli.
|
||||||
|
{% endblock %}
|
||||||
<p>
|
|
||||||
Tuto stránku jsme na našem serveru nenalezli.
|
{% block errorimage %}
|
||||||
Zkuste přejít na <a href="/">titulní stránku</a>
|
<img src="{% static '404.png' %}">
|
||||||
nebo se podívat na <a href="{% url 'seminar_aktualni_zadani' %}">aktuální zadání</a>.
|
|
||||||
</p>
|
|
||||||
<img src="{% static '404.png' %}">
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,16 @@
|
||||||
{% extends "base.html" %}
|
{% extends "error_base.html" %}
|
||||||
|
|
||||||
{% load staticfiles %}
|
{% load staticfiles %}
|
||||||
|
|
||||||
{% block content %}
|
{% block errorheading %}
|
||||||
<h2>
|
|
||||||
{% block nadpis1a %}{% block nadpis1b %}
|
|
||||||
O-jo-jo-jo-joj
|
O-jo-jo-jo-joj
|
||||||
{% endblock %}{% endblock %}
|
{% endblock %}
|
||||||
</h2>
|
|
||||||
|
|
||||||
<p>
|
{% block errortext %}
|
||||||
Chybička se vloudila.
|
Chybička se vloudila.
|
||||||
Zkuste přejít na <a href="/">titulní stránku</a>
|
{% endblock %}
|
||||||
{# Při pádu webu nechceme, aby se rozbily odkazy, nevěříme URLconfu. #}
|
|
||||||
nebo se podívat na <a href="/aktualni/zadani/">aktuální zadání</a>.
|
{% block errorimage %}
|
||||||
</p>
|
|
||||||
<img src="{% static '500.png' %}">
|
<img src="{% static '500.png' %}">
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<title>{% block title %}{% block nadpis1a %}{% endblock %} – Korespondenční seminář M&M{% endblock title %}</title>
|
<title>{% block title %}{% block nadpis1a %}{% endblock %} – Korespondenční seminář M&M{% endblock title %}</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<link rel="shortcut icon" href="{% static 'images/MATFYZ_MM_barevne.svg' %}" type="image/x-icon">
|
<link rel="shortcut icon" href="{% static 'images/MATFYZ_MM_barevne.svg' %}" type="image/x-icon">
|
||||||
{% render_block css %}
|
{# {% render_block css %}#}
|
||||||
{% block custom_css %}{% endblock %}
|
{% block custom_css %}{% endblock %}
|
||||||
<link href="{% static 'css/bootstrap-theme.css' %}" rel="stylesheet">
|
<link href="{% static 'css/bootstrap-theme.css' %}" rel="stylesheet">
|
||||||
<link href="{% static 'css/bootstrap.css' %}" rel="stylesheet">
|
<link href="{% static 'css/bootstrap.css' %}" rel="stylesheet">
|
||||||
|
|
19
mamweb/templates/error_base.html
Normal file
19
mamweb/templates/error_base.html
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h2>
|
||||||
|
{% block nadpis1a %}{% block nadpis1b %}
|
||||||
|
{% block errorheading %}
|
||||||
|
{% endblock %}
|
||||||
|
{% endblock %}{% endblock%}
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
{% block errortext %}
|
||||||
|
{% endblock %}
|
||||||
|
Zkuste přejít na <a href="/">titulní stránku</a>.
|
||||||
|
</p>
|
||||||
|
{% block errorimage %}
|
||||||
|
{% endblock %}
|
||||||
|
{% endblock %}
|
||||||
|
|
|
@ -59,6 +59,10 @@ if settings.DEBUG:
|
||||||
urlpatterns += [
|
urlpatterns += [
|
||||||
path('media/<path:path>', views.static.serve, # NOQA
|
path('media/<path:path>', views.static.serve, # NOQA
|
||||||
{'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),
|
{'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),
|
||||||
path('__debug__/', include(debug_toolbar.urls)),
|
path('__debug__/', include(debug_toolbar.urls)),
|
||||||
|
path('400.html', TemplateView.as_view(template_name="400.html")),
|
||||||
|
path('403.html', TemplateView.as_view(template_name="403.html")),
|
||||||
|
path('404.html', TemplateView.as_view(template_name="404.html")),
|
||||||
|
path('500.html', TemplateView.as_view(template_name="500.html")),
|
||||||
]
|
]
|
||||||
urlpatterns += staticfiles_urlpatterns()
|
urlpatterns += staticfiles_urlpatterns()
|
||||||
|
|
|
@ -119,7 +119,7 @@ $(document).ready(function(){
|
||||||
<td>{{ form.empty_form.problem }}</td>
|
<td>{{ form.empty_form.problem }}</td>
|
||||||
<td>{{ form.empty_form.body }}</td>
|
<td>{{ form.empty_form.body }}</td>
|
||||||
<td>{{ form.empty_form.cislo_body }}</td>
|
<td>{{ form.empty_form.cislo_body }}</td>
|
||||||
<td><a href="#" class="smazat_hodnoceni" id="id_{{subform.prefix}}-jsremove"><img src="{% static "odevzdavatko/cross.png" %}" alt="Smazat"></a></td>
|
<td><a href="#" class="smazat_hodnoceni" id="id_{{form.empty_form.prefix}}-jsremove"><img src="{% static "odevzdavatko/cross.png" %}" alt="Smazat"></a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import seminar.models as m
|
||||||
@admin.register(m.Osoba)
|
@admin.register(m.Osoba)
|
||||||
class OsobaAdmin(admin.ModelAdmin):
|
class OsobaAdmin(admin.ModelAdmin):
|
||||||
actions = ['synchronizuj_maily', 'udelej_orgem']
|
actions = ['synchronizuj_maily', 'udelej_orgem']
|
||||||
|
search_fields = ['jmeno', 'prijmeni', 'prezdivka']
|
||||||
|
|
||||||
def synchronizuj_maily(self, request, queryset):
|
def synchronizuj_maily(self, request, queryset):
|
||||||
for o in queryset:
|
for o in queryset:
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
|
{% if id %}
|
||||||
<tr id="{{ id }}" >
|
<tr id="{{ id }}" >
|
||||||
|
{% else %}
|
||||||
|
<tr>
|
||||||
|
{% endif %}
|
||||||
<td>
|
<td>
|
||||||
<label class="field-label{% if field.field.required %} field-required{% endif %}" for="{{ field.id_for_label }}">
|
<label class="field-label{% if field.field.required %} field-required{% endif %}" for="{{ field.id_for_label }}">
|
||||||
{{ field.label }}:
|
{{ field.label }}:
|
||||||
|
|
|
@ -23,7 +23,7 @@ django-solo
|
||||||
django-ckeditor
|
django-ckeditor
|
||||||
django-flat-theme
|
django-flat-theme
|
||||||
django-taggit
|
django-taggit
|
||||||
django-autocomplete-light
|
django-autocomplete-light>=3.9.0rc1
|
||||||
django-crispy-forms
|
django-crispy-forms
|
||||||
django-imagekit
|
django-imagekit
|
||||||
django-polymorphic
|
django-polymorphic
|
||||||
|
|
24
seminar/migrations/0101_auto_20211213_2306.py
Normal file
24
seminar/migrations/0101_auto_20211213_2306.py
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# Generated by Django 2.2.24 on 2021-12-13 22:06
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('seminar', '0100_auto_20211129_2354'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='nastaveni',
|
||||||
|
name='aktualni_cislo',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Cislo', verbose_name='Aktuální číslo'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='soustredeni',
|
||||||
|
name='typ',
|
||||||
|
field=models.CharField(choices=[('jarni', 'Jarní soustředění'), ('podzimni', 'Podzimní soustředění'), ('vikend', 'Víkendový sraz'), ('vylet', 'Výlet')], default='podzimni', max_length=16, verbose_name='typ akce'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -55,10 +55,12 @@ class Soustredeni(SeminarModelBase):
|
||||||
TYP_JARNI = 'jarni'
|
TYP_JARNI = 'jarni'
|
||||||
TYP_PODZIMNI = 'podzimni'
|
TYP_PODZIMNI = 'podzimni'
|
||||||
TYP_VIKEND = 'vikend'
|
TYP_VIKEND = 'vikend'
|
||||||
|
TYP_VYLET = 'vylet'
|
||||||
TYP_CHOICES = [
|
TYP_CHOICES = [
|
||||||
(TYP_JARNI, 'Jarní soustředění'),
|
(TYP_JARNI, 'Jarní soustředění'),
|
||||||
(TYP_PODZIMNI, 'Podzimní soustředění'),
|
(TYP_PODZIMNI, 'Podzimní soustředění'),
|
||||||
(TYP_VIKEND, 'Víkendový sraz'),
|
(TYP_VIKEND, 'Víkendový sraz'),
|
||||||
|
(TYP_VYLET, 'Výlet'),
|
||||||
]
|
]
|
||||||
typ = models.CharField('typ akce', max_length=16, choices=TYP_CHOICES, blank=False, default=TYP_PODZIMNI)
|
typ = models.CharField('typ akce', max_length=16, choices=TYP_CHOICES, blank=False, default=TYP_PODZIMNI)
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ import tempfile
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from django.contrib.sites.shortcuts import get_current_site
|
from django.contrib.sites.shortcuts import get_current_site
|
||||||
from django.core.files.storage import FileSystemStorage
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
@ -646,7 +645,7 @@ class Nastaveni(SingletonModel):
|
||||||
# aktualni_rocnik = models.ForeignKey(Rocnik, verbose_name='aktuální ročník',
|
# aktualni_rocnik = models.ForeignKey(Rocnik, verbose_name='aktuální ročník',
|
||||||
# null=False, on_delete=models.PROTECT)
|
# null=False, on_delete=models.PROTECT)
|
||||||
|
|
||||||
aktualni_cislo = models.ForeignKey(Cislo, verbose_name='poslední vydané číslo',
|
aktualni_cislo = models.ForeignKey(Cislo, verbose_name='Aktuální číslo',
|
||||||
null=False, on_delete=models.PROTECT)
|
null=False, on_delete=models.PROTECT)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -72,7 +72,7 @@
|
||||||
\ifx \skola \empty
|
\ifx \skola \empty
|
||||||
{}
|
{}
|
||||||
\else
|
\else
|
||||||
\hbox{\tofont{\skola}}
|
\predsunout{\hbox{\tofont{\skola}}} %FIXME Vyřešit jinak (škola bývá dlouhá a tak se nevejde do konce řádku, tak jsem ji hodil doleva)
|
||||||
\fi
|
\fi
|
||||||
\vskip .2 em
|
\vskip .2 em
|
||||||
\hbox{\tofont{\ulice}}
|
\hbox{\tofont{\ulice}}
|
||||||
|
@ -98,24 +98,22 @@
|
||||||
|
|
||||||
{% for r in resitele %}
|
{% for r in resitele %}
|
||||||
{% with o=r.osoba %}
|
{% with o=r.osoba %}
|
||||||
{% with s=r.osoba.skola %}
|
{% with s=r.skola %}
|
||||||
{% spaceless %}
|
{% spaceless %}
|
||||||
{% if r.zasilat == "do_skoly" %}
|
{% if r.zasilat == "do_skoly" %}
|
||||||
{% if r.stat == "CZ" %}
|
{% if o.stat == "CZ" %}
|
||||||
\obalka{{o.jmeno|sloz}}{{o.prijmeni|sloz}}{{s.nazev|sloz}}{{s.ulice|sloz}}{{s.psc|sloz}}{{s.mesto|sloz}}{{''|sloz}}
|
\obalka{{o.jmeno|sloz}}{{o.prijmeni|sloz}}{{s.nazev|sloz}}{{s.ulice|sloz}}{{s.psc|sloz}}{{s.mesto|sloz}}{{''|sloz}}
|
||||||
{% else %}
|
{% else %}
|
||||||
\obalka{{o.jmeno|sloz}}{{o.prijmeni|sloz}}{{s.nazev|sloz}}{{s.ulice|sloz}}{{s.psc|sloz}}{{s.mesto|sloz}}{{o.stat.name|sloz}}
|
\obalka{{o.jmeno|sloz}}{{o.prijmeni|sloz}}{{s.nazev|sloz}}{{s.ulice|sloz}}{{s.psc|sloz}}{{s.mesto|sloz}}{{o.stat.name|sloz}}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% elif r.zasilat == "domu" %}
|
{% elif r.zasilat == "domu" %}
|
||||||
{% if r.stat == "CZ" %}
|
{% if o.stat == "CZ" %}
|
||||||
\obalka{{o.jmeno|sloz}}{{o.prijmeni|sloz}}{{''|sloz}}{{o.ulice|sloz}}{{o.psc|sloz}}{{o.mesto|sloz}}{{''|sloz}}
|
\obalka{{o.jmeno|sloz}}{{o.prijmeni|sloz}}{{''|sloz}}{{o.ulice|sloz}}{{o.psc|sloz}}{{o.mesto|sloz}}{{''|sloz}}
|
||||||
{% else %}
|
{% else %}
|
||||||
\obalka{{o.jmeno|sloz}}{{o.prijmeni|sloz}}{{''|sloz}}{{o.ulice|sloz}}{{o.psc|sloz}}{{o.mesto|sloz}}{{o.stat.name|sloz}}
|
\obalka{{o.jmeno|sloz}}{{o.prijmeni|sloz}}{{''|sloz}}{{o.ulice|sloz}}{{o.psc|sloz}}{{o.mesto|sloz}}{{o.stat.name|sloz}}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
% zasilat: {{r.zasilat}}
|
|
||||||
%\obalka{{r.jmeno|sloz}}{{r.prijmeni|sloz}}{{''|sloz}}{{r.ulice|sloz}}{{r.psc|sloz}}{{r.mesto|sloz}}{{r.stat.name|sloz}}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endspaceless %}
|
{% endspaceless %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
|
|
|
@ -292,8 +292,14 @@ def gen_reseni_ulohy(rnd, cisla, uloha, pocet_resitelu, poradi_cisla, resitele_c
|
||||||
res_vyber.remove(resitele[0])
|
res_vyber.remove(resitele[0])
|
||||||
|
|
||||||
# Vytvoření řešení.
|
# Vytvoření řešení.
|
||||||
res = Reseni.objects.create(forma=rnd.choice(Reseni.FORMA_CHOICES)[0])
|
if uloha.cislo_zadani.datum_deadline is not None:
|
||||||
# Problím a řešitele přiřadíme později, ManyToManyField
|
# combine, abychom dostali plný čas a ne jen datum
|
||||||
|
cas_doruceni = datetime.datetime.combine(uloha.cislo_zadani.datum_deadline, datetime.datetime.min.time()) - datetime.timedelta(days=random.randint(0, 40)) - datetime.timedelta(minutes=random.randint(0, 60*24))
|
||||||
|
# astimezone, protože jinak vyhazuje warning o nenastavené TZ
|
||||||
|
res = Reseni.objects.create(forma=rnd.choice(Reseni.FORMA_CHOICES)[0], cas_doruceni=cas_doruceni.astimezone(datetime.timezone.utc))
|
||||||
|
else:
|
||||||
|
res = Reseni.objects.create(forma=rnd.choice(Reseni.FORMA_CHOICES)[0])
|
||||||
|
# Problém a řešitele přiřadíme později, ManyToManyField
|
||||||
# se nedá vyplnit v create().
|
# se nedá vyplnit v create().
|
||||||
res.resitele.set(res_vyber)
|
res.resitele.set(res_vyber)
|
||||||
res.save()
|
res.save()
|
||||||
|
|
Loading…
Reference in a new issue