From b201d881d568764f41ce2498900677bbf115636d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=C3=A1=C5=A1=20Havelka?= Date: Thu, 14 Oct 2021 14:44:05 +0200 Subject: [PATCH 01/41] =?UTF-8?q?P=C5=99id=C3=A1n=20filtr=20podle=20maturi?= =?UTF-8?q?ty=20u=20aktivniResitele()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dokumentace to dokonce i slibuje, jen to nebylo implementováno (ono ve skutečnosti podle toho filtruje už resi_v_rocniku, ale resi_v_rocniku(loni) filtruje podle loni, projistotu jsem to přidal na obojí) --- seminar/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/seminar/utils.py b/seminar/utils.py index 898e0843..4604245c 100644 --- a/seminar/utils.py +++ b/seminar/utils.py @@ -212,10 +212,10 @@ def aktivniResitele(cislo, pouze_letosni=False): zacatek_rocniku = False if not zacatek_rocniku: - return resi_v_rocniku(letos, cislo) + return resi_v_rocniku(letos, cislo).filter(rok_maturity__gte=letos.druhy_rok()) else: # spojíme querysety s řešiteli loni a letos do daného čísla - return (resi_v_rocniku(loni) | resi_v_rocniku(letos, cislo)).distinct() + return (resi_v_rocniku(loni) | resi_v_rocniku(letos, cislo)).distinct().filter(rok_maturity__gte=letos.druhy_rok()) def viewMethodSwitch(get, post): """ From 3e63e1c768f9abc5e134e920cb803fa9eb96908a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=C3=A1=C5=A1=20Havelka?= Date: Mon, 22 Nov 2021 22:19:06 +0100 Subject: [PATCH 02/41] =?UTF-8?q?Odli=C5=A1en=C3=AD=20web=C5=AF:=20takhle?= =?UTF-8?q?=20to=20ur=C4=8Dit=C4=9B=20jde,=20ale=20mo=C5=BEn=C3=A1=20to=20?= =?UTF-8?q?jde=20l=C3=A9pe=20(a=20v=20hez=C4=8D=C3=ADch=20barv=C3=A1ch)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mamweb/settings_common.py | 1 + mamweb/settings_local.py | 1 + mamweb/settings_prod.py | 1 + mamweb/settings_test.py | 1 + mamweb/static/css/mamweb.css | 18 ++++++++++++++++++ mamweb/templates/base.html | 2 +- various/context_processors.py | 7 +++++++ 7 files changed, 30 insertions(+), 1 deletion(-) diff --git a/mamweb/settings_common.py b/mamweb/settings_common.py index 58e8c638..ce028bc2 100644 --- a/mamweb/settings_common.py +++ b/mamweb/settings_common.py @@ -79,6 +79,7 @@ TEMPLATES = [ 'django.contrib.messages.context_processors.messages', 'sekizai.context_processors.sekizai', 'header_fotky.context_processors.vzhled', + 'various.context_processors.rozliseni', 'various.context_processors.april', ) }, diff --git a/mamweb/settings_local.py b/mamweb/settings_local.py index 0aadd27e..85058c9f 100644 --- a/mamweb/settings_local.py +++ b/mamweb/settings_local.py @@ -97,3 +97,4 @@ LOGGING = { # E-maily posílat chceme, ale do terminálu :-) EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' SEND_EMAIL_NOTIFICATIONS = True +LOCAL_TEST_PROD = "local" diff --git a/mamweb/settings_prod.py b/mamweb/settings_prod.py index 0374d88b..e674ab05 100644 --- a/mamweb/settings_prod.py +++ b/mamweb/settings_prod.py @@ -67,3 +67,4 @@ LOGGING['handlers']['registration_error_log']['filename'] = '/home/mam-web/logs/ # E-MAIL NOTIFICATIONS POSLI_MAILOVOU_NOTIFIKACI = True +LOCAL_TEST_PROD = "prod" diff --git a/mamweb/settings_test.py b/mamweb/settings_test.py index f8fd844e..365664d2 100644 --- a/mamweb/settings_test.py +++ b/mamweb/settings_test.py @@ -76,3 +76,4 @@ EMAIL_BACKEND = 'various.mail_prefixer.PrefixingMailBackend' # TODO Pouze na otestování testu… Zvolit konferu! # XXX: Je to pole, protože implementační detail backendu. TESTOVACI_EMAILOVA_KONFERENCE = ['betatest@mam.mff.cuni.cz'] +LOCAL_TEST_PROD = "test" diff --git a/mamweb/static/css/mamweb.css b/mamweb/static/css/mamweb.css index 8b19fb80..26baccbd 100644 --- a/mamweb/static/css/mamweb.css +++ b/mamweb/static/css/mamweb.css @@ -1182,3 +1182,21 @@ div.gdpr { label[for=id_skola] { font-weight: bold; } + +.localweb { + border-left: 20px solid greenyellow; + border-right: 20px solid greenyellow; +} + +.localweb .login-bar { + margin-left: -20px; +} + +.testweb { + border-left: 20px solid darkorange; + border-right: 20px solid darkorange; +} + +.testweb .login-bar { + margin-left: -20px; +} diff --git a/mamweb/templates/base.html b/mamweb/templates/base.html index 1d292f95..85cb9e12 100644 --- a/mamweb/templates/base.html +++ b/mamweb/templates/base.html @@ -36,7 +36,7 @@ {% block script %}{% endblock %} - + {% if user.is_staff %} {% endwith %} {% endif%} + {{obrazek.popis}} + class="obrazek"> {% if obrazky_dalsi %} {% with obrazky_dalsi|first as dalsi_obrazek %} diff --git a/mamweb/static/css/mamweb.css b/mamweb/static/css/mamweb.css index fd686e98..de8b5058 100644 --- a/mamweb/static/css/mamweb.css +++ b/mamweb/static/css/mamweb.css @@ -1113,6 +1113,21 @@ div.zadani_termin .datum { 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 */ + } +} /**/ From bb58f29c8636d3d5cc81cd33649e3b1ca970c34d Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Sun, 5 Dec 2021 19:57:18 +0100 Subject: [PATCH 38/41] =?UTF-8?q?Implementov=C3=A1no=20pos=C3=ADl=C3=A1n?= =?UTF-8?q?=C3=AD=20e-mail=C5=AF=20z=20korekturov=C3=A1tka?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- korektury/admin.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/korektury/admin.py b/korektury/admin.py index 79dfffb1..0842eb15 100644 --- a/korektury/admin.py +++ b/korektury/admin.py @@ -2,6 +2,8 @@ from django.contrib import admin from reversion.admin import VersionAdmin from korektury.models import KorekturovanePDF +from django.core.mail import send_mail +from django.urls import reverse # Register your models here. class KorekturovanePDFAdmin(VersionAdmin): @@ -23,4 +25,24 @@ class KorekturovanePDFAdmin(VersionAdmin): list_filter = [] search_fields = [] + def save_model(self, request, obj, form, change): + super().save_model(request, obj, form, change) + if not change: # Je nový + 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) From 62adb24a5f53696e0d195e608a51a4a3e9ee3dad Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Mon, 6 Dec 2021 00:05:57 +0100 Subject: [PATCH 39/41] =?UTF-8?q?Za=C5=A1krt=C3=A1v=C3=A1tko,=20aby=20se?= =?UTF-8?q?=20mail=20poslat=20nemusel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- korektury/admin.py | 4 ++-- .../0018_korekturovanepdf_poslat_mail.py | 18 ++++++++++++++++++ korektury/models.py | 4 ++++ 3 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 korektury/migrations/0018_korekturovanepdf_poslat_mail.py diff --git a/korektury/admin.py b/korektury/admin.py index 0842eb15..64b2032f 100644 --- a/korektury/admin.py +++ b/korektury/admin.py @@ -18,7 +18,7 @@ class KorekturovanePDFAdmin(VersionAdmin): fieldsets = [ (None, {'fields': - ['pdf', 'cas', 'org', 'stran', 'nazev', 'komentar']}), + ['pdf', 'cas', 'org', 'stran', 'nazev', 'komentar', 'poslat_mail']}), # (u'PDF', {'fields': ['pdf']}), ] list_display = ['nazev', 'cas', 'stran', 'org'] @@ -27,7 +27,7 @@ class KorekturovanePDFAdmin(VersionAdmin): def save_model(self, request, obj, form, change): super().save_model(request, obj, form, change) - if not change: # Je nový + 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' diff --git a/korektury/migrations/0018_korekturovanepdf_poslat_mail.py b/korektury/migrations/0018_korekturovanepdf_poslat_mail.py new file mode 100644 index 00000000..c93b957e --- /dev/null +++ b/korektury/migrations/0018_korekturovanepdf_poslat_mail.py @@ -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'), + ), + ] diff --git a/korektury/models.py b/korektury/models.py index f22c6874..240323a8 100644 --- a/korektury/models.py +++ b/korektury/models.py @@ -63,6 +63,10 @@ class KorekturovanePDF(models.Model): status = models.CharField(u'stav PDF',max_length=16, choices=STATUS_CHOICES, blank=False, 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 From d60d2eee6e27f9f9cf7dd3760bc10aaa06d6429a Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Tue, 7 Dec 2021 00:10:28 +0100 Subject: [PATCH 40/41] DAL v 3.9.cokoliv, aby fungoval autocomplete i v Safari Ref: https://github.com/yourlabs/django-autocomplete-light/issues/1226 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 3a411faa..796e9f97 100644 --- a/requirements.txt +++ b/requirements.txt @@ -23,7 +23,7 @@ django-solo django-ckeditor django-flat-theme django-taggit -django-autocomplete-light +django-autocomplete-light>=3.9.0rc1 django-crispy-forms django-imagekit django-polymorphic From 5a6a2eee9362051202e22e7ec1cce76ad2c5a6e5 Mon Sep 17 00:00:00 2001 From: "Pavel \"LEdoian\" Turinsky" Date: Tue, 7 Dec 2021 01:27:09 +0100 Subject: [PATCH 41/41] =?UTF-8?q?P=C5=99id=C3=A1n=20z=C3=A1pis=20o=20zkr?= =?UTF-8?q?=C3=A1=C5=A1lov=C3=A1n=C3=AD=20k=C3=B3du=20(testy,=20doku,=20CI?= =?UTF-8?q?,=20code=20review,=20=E2=80=A6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Je v náhodné složce, ale někde být musí :-) --- ...-12-06-testovani_dokumentace_codereview.md | 173 ++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 docs/zapisy/2021-12-06-testovani_dokumentace_codereview.md diff --git a/docs/zapisy/2021-12-06-testovani_dokumentace_codereview.md b/docs/zapisy/2021-12-06-testovani_dokumentace_codereview.md new file mode 100644 index 00000000..224ea529 --- /dev/null +++ b/docs/zapisy/2021-12-06-testovani_dokumentace_codereview.md @@ -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 (, 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.