diff --git a/.travis.yml b/.travis.yml index 93bdf9dcb..d36712184 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,9 @@ python: - "3.6" cache: "pip" script: - - "python pyladies_cz.py freeze" + - "python -m pip install -r test-requirements.txt && pytest -v tests/ && + flake8 --ignore=E266,F811 --max-line-length=100 --exclude=original/ && + python pyladies_cz.py freeze" env: global: - secure: "N+iAAkw+nVaPyI/yPUr3LeHRlLgbmjcn58768zKdeHqBYjJGB+wLe54yE4a6ed5evT5wabHV6fc2XfYbjkjmWNh7XLbEYqzU1HfelhZogo7VZEL2txkpjx8MM37XDFb2BxXieDuX/Gs0myCJj+eoVNWmD9ia6Y3lKgryJmtdR+qRDrxvLpHrDhJ3bpbd0nk14O6LKQI5SW7fMm9wLx62xb9F94H5hWx/TPRuKq/txuda7eATbiWvsDGfH6TDmJD89DKmMiLdJkVms1BA9wi5fAetf8orsAD+CUdm0QZm368MexIxeRbIUDUkqsFgyQk3UOUny7sc4HyXxO6WBaAE7qsxFeiSTzBvAY0ZH+OfTG8QW26tZy7aGBwcbDWvsFUoZ7egX5GLJ83g14xd2tY63S0iNbKuQUAhz3FEUoCrLCzOeY3kP2q6X12BCYqJkcPw4ylUnQYnHKloeacw52ae1KCwm/JE3wq0/9yQ2NwlEY5QYAAi895Say/BIxMkIdJp8qXa0bIRmKLJlgArtoCEXOdwlMckP2aYS0YLF8dsOQpdvTp0+32dcfeaL8W3Cg9SAgic9yOq0GWH0L6kMkYLQRDj6iZU9mgpuMFkEebuV06BwO0795HB0QrqC2mW+EgpvY0kuSjsDGmloozSx0h4wWGHKQ6i+Ai6tgXxGSvO3Jw=" diff --git a/README.md b/README.md index c36bf72c9..0449fa6c2 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ podstránky. ### Instalace -Ve virtuálním prostředí s Pythhonem 3.6 (nebo vyšším) spusť: +Ve virtuálním prostředí s Pythonem 3.6 (nebo vyšším) spusť: $ python -m pip install -r requirements.txt @@ -69,6 +69,16 @@ a pak (na všech systémech): Stránky se zpřístupní na adrese `http://127.0.0.1:8003/`. Změny v kódu se projeví po obnovení stránky v prohlížeči. +### Testování + +Ve virtuálním prostředí s Pythonem 3.6 (nebo vyšším) spusť: + + $ python -m pip install -r test-requirements.txt + +V hlavním adresáři projektu spusť `pytest` nad adresářem `tests/`: + + $ pytest -v tests/ + ### Úprava souborů * Soubory html jsou ve složce ``templates`` diff --git a/__init__.py b/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/cities.yml b/cities.yml deleted file mode 100644 index 16d61a672..000000000 --- a/cities.yml +++ /dev/null @@ -1,78 +0,0 @@ -praha: - title: Praha - team-name: Tým pražských PyLadies - contacts: - Facebook PyLadies Praha: - icon: facebook - url: https://www.facebook.com/groups/PyLadiesPraha/ - PyWorking Praha: - icon: facebook - url: https://www.facebook.com/groups/PyWorkingPraha/ - Google Group PyLadies Praha: - icon: google-group - url: https://groups.google.com/forum/#!forum/pyladies-praha - Napiš organizátorkám: - icon: coach - url: mailto:praha@pyladies.cz - -brno: - title: Brno - team-name: Tým brněnských PyLadies - contacts: - Facebook PyLadies Brno: - icon: facebook - url: https://www.facebook.com/groups/pyladiesBrno - Google Group PyLadies Brno: - icon: google-group - url: https://groups.google.com/forum/#!forum/pyladies-brno - Napiš organizátorkám: - icon: coach - url: mailto:brno@pyladies.cz - newsletter: - url: https://pyladies.us4.list-manage.com/subscribe/post?u=d18802c49f8d98ac411c260b7&id=b569c163bb - text: "Horké novinky (nejen) z dění PyLadies komunity! Jednou měsíčně ti mailem pošleme zprávu o chystaných akcích, kurzech a workshopech v Brně. Vše na jednom místě, bez spamu. Přihlaš se k odběru." - input-name: b_d18802c49f8d98ac411c260b7_b569c163bb -ostrava: - title: Ostrava - team-name: Tým ostravských PyLadies - contacts: - Facebook PyLadies Ostrava: - icon: facebook - url: https://www.facebook.com/pyladiesostrava/ - Google Group PyLadies Ostrava: - icon: google-group - url: https://groups.google.com/forum/#!forum/pyladies-ostrava - Napiš organizátorům: - icon: coach - url: mailto:ostrava@pyladies.cz -plzen: - title: Plzeň - team-name: Tým plzeňských PyLadies - contacts: - Facebook PyLadies Plzeň: - icon: facebook - url: https://www.facebook.com/groups/2235479259799633 - Napiš koučovi: - icon: coach - url: mailto:plzen@pyladies.cz - -olomouc: - title: Olomouc - team-name: Tým olomouckých PyLadies - contacts: - Google Group PyLadies Olomouc: - icon: google-group - url: https://groups.google.com/forum/#!forum/pyladies-olomouc - Napiš koučovi: - icon: coach - url: mailto:filip.valder@gmail.com -hradec: - title: Hradec Králové - team-name: Tým hradeckých PyLadies - contacts: - Napiš organizátorce: - icon: coach - url: mailto:brabcova.ivana@gmail.com - -ostatni: - title: Tvoje město diff --git a/cities/brno/about.html b/cities/brno/about.html new file mode 100644 index 000000000..b97c5d22e --- /dev/null +++ b/cities/brno/about.html @@ -0,0 +1,18 @@ +
+

Jak to v Brně vzniklo?

+

Bylo nebylo, přijela jednou do Brna na návštěvu Lynn Root, která vede PyLadies v San Franciscu. Zrovna probíhala konference RuPy 2012, a v rámci ní Lynn uspořádala půldenní workshop pod hlavičkou PyLadies. Ale potom odjela, než našla dostatečně akční Pythonistku, která by to po ní převzala.

+
+
+
+ +
+
+ +
+
+ +
+
+
+

Až po více než roce se na Facebooku ozvaly tři studentky, které se Python učily na škole a potřebovaly doučování. Vzpomněli jsme si na balíček samolepek PyLadies, co tu nechala Lynn, a rozhodli se to doučování udělat pod touto značkou. A odtud byl už jen krůček k začátečnickým kurzům i jiným srazům.

+
diff --git a/cities/brno/city.yml b/cities/brno/city.yml new file mode 100644 index 000000000..47d2b0773 --- /dev/null +++ b/cities/brno/city.yml @@ -0,0 +1,22 @@ +title: Brno +order: 20 +contacts: + Facebook PyLadies Brno: + icon: facebook + url: https://www.facebook.com/groups/pyladiesBrno + Google Group PyLadies Brno: + icon: google-group + url: https://groups.google.com/forum/#!forum/pyladies-brno + Napiš organizátorkám: + icon: coach + url: mailto:brno@pyladies.cz +newsletter: + url: https://pyladies.us4.list-manage.com/subscribe/post?u=d18802c49f8d98ac411c260b7&id=b569c163bb + text: | + Horké novinky (nejen) z dění PyLadies komunity! Jednou měsíčně ti mailem pošleme zprávu + o chystaných akcích, kurzech a workshopech v Brně. Vše na jednom místě, bez spamu. Přihlaš + se k odběru. + input-name: b_d18802c49f8d98ac411c260b7_b569c163bb +static-materials: + - name: Linuxová administrace + url: https://naucse.python.cz/2020/linux-admin/ diff --git a/meetups/brno.yml b/cities/brno/meetups.yml similarity index 100% rename from meetups/brno.yml rename to cities/brno/meetups.yml diff --git a/teams/brno.yml b/cities/brno/team.yml similarity index 99% rename from teams/brno.yml rename to cities/brno/team.yml index 73d5b7702..85bc7a243 100644 --- a/teams/brno.yml +++ b/cities/brno/team.yml @@ -1,3 +1,5 @@ +name: Tým brněnských PyLadies +members: - name: Sabina Chovancová img: img/brno/team/blank.png role: Organizátorka - pondělí diff --git a/cities/hradec/city.yml b/cities/hradec/city.yml new file mode 100644 index 000000000..0dc33973c --- /dev/null +++ b/cities/hradec/city.yml @@ -0,0 +1,7 @@ +title: Hradec Králové +order: 60 +contacts: + Napiš organizátorce: + icon: coach + url: mailto:brabcova.ivana@gmail.com +static-materials: [] diff --git a/meetups/hradec.yml b/cities/hradec/meetups.yml similarity index 100% rename from meetups/hradec.yml rename to cities/hradec/meetups.yml diff --git a/teams/hradec.yml b/cities/hradec/team.yml similarity index 95% rename from teams/hradec.yml rename to cities/hradec/team.yml index 67492831f..fe976fc21 100644 --- a/teams/hradec.yml +++ b/cities/hradec/team.yml @@ -1,3 +1,5 @@ +name: Tým hradeckých PyLadies +members: - name: Ivana Brabcová img: img/plzen/team/blank.png role: Organizátorka diff --git a/cities/olomouc/city.yml b/cities/olomouc/city.yml new file mode 100644 index 000000000..15d3f7b5f --- /dev/null +++ b/cities/olomouc/city.yml @@ -0,0 +1,10 @@ +title: Olomouc +order: 50 +contacts: + Google Group PyLadies Olomouc: + icon: google-group + url: https://groups.google.com/forum/#!forum/pyladies-olomouc + Napiš koučovi: + icon: coach + url: mailto:filip.valder@gmail.com +static-materials: [] diff --git a/cities/olomouc/feedbacks.yml b/cities/olomouc/feedbacks.yml new file mode 100644 index 000000000..5641fc624 --- /dev/null +++ b/cities/olomouc/feedbacks.yml @@ -0,0 +1,74 @@ +- author: Hana B. + meetup: + name: Začátečnický kurz + start: 2020-01-09 + content: | + Kurz Pyladies hodnotím velice kladně a všem, kteří se chtějí naučit základy + programování, mohu jen doporučit. Nejsou potřeba žádné předchozí znalosti. Do kurzu + jsem se přihlásila jako úplný začátečník a kurz se mi podařilo s podporou + a pomocí koučů dokončit. Věřím, že získané znalosti v budoucnosti využiji + a ráda bych se programování věnovala i nadále. + # the original non truncated content + original-content: "" + # 0 = worst, 5 = best + score: null + +- author: Věrka F. + meetup: + name: Začátečnický kurz + start: 2020-01-09 + content: | + Při nabalování nových a nových znalostí i praktických zkušeností se účastnice/i + mohou těšit na spoustu „aha“ momentů, v nichž si začnou uvědomovat nejrůznější + návaznosti mezi učební látkou jednotlivých lekcí. Je to jako puzzle, jehož jednotlivé + dílky do sebe pomalu, ale jistě zapadají. Zvažujete-li svou účast v kurzu PyLadies, + vězte, že jeho absolvováním nezískáte jenom certifikát a nějaký teoretický IT + background, ale také mnoho cenných praktických zkušeností. Navíc poznáte partu + zapálených nadšenců... + # the original non truncated content + original-content: | + Kurz PyLadies je určený pro ženy a skutečně koncipován tak, aby jej bez znalosti + složité matematiky zvládli všichni, kdo mají zájem do IT hlouběji proniknout. Pojetí + vzdělávacího obsahu základů programovacího jazyka Python je ryze orientované na + dobře představitelné praktické příklady. Délka kurzu je dostačující pro pochopení + elementárních souvislostí a jejich utužení do té míry, aby na ně bylo možné + navázat následným samostudiem a pracovat tak na vlastním rozvoji v IT oblasti. Vše, + co se zde účastníce/i naučí, lze překlopit do praxe a pomocí programování si + tak neustále zjednodušovat nejrůznější aspekty nejen svého života (osobního i + pracovního). Pro ty nejambicióznější se absolvováním kurzu zároveň otevírají + dveře nových pracovních příležitostí v IT. + + Četnost kurzu konající se jedenkrát za týden v délce dvou hodin je nutné rozšířit o + vlastní studium doma, při němž účastnice/i plní domácí projekty nejrůznějšího + charakteru (programování jednoduchých her, práce se soubory, apod.). Nikdy však + nejsou nechávány/i bez podpory. Neustále se mohou obracet na tým koučů, který je + jim během kurzu k dispozici a nápomocen. S odstupem času při nabalování nových a + nových znalostí i praktických zkušeností se účastnice/i mohou těšit na spoustu + „aha“ momentů, v nichž si začnou uvědomovat nejrůznější návaznosti mezi + učební látkou jednotlivých lekcí. Je to jako puzzle, jehož jednotlivé dílky do + sebe pomalu, ale jistě zapadají. + + Zvažujete-li svou účast v kurzu PyLadies, vězte, že jeho absolvováním nezískáte + jenom certifikát a nějaký teoretický IT background, ale také mnoho cenných + praktických zkušeností. Navíc poznáte partu zapálených nadšenců, jejichž + vnitřním motorem je neustále objevovat něco nového a své poznatky sdílet a pomáhat + si navzájem. Absolvováním kurzu totiž slovy hlavního kouče olomouckého PyLadies + Filipa Valdera „příběh nekončí“. Právě jemu a jeho týmu koučů patří velké + poděkování za to, že i přes nejrůznější překážky vč. koronavirové pandemie + úspěšně zrealizovali a dovedli do zdárného konce 1. běh kurzu olomouckého PyLydies + a já jsem měla tu čest být u toho! :-) + + Nepřísluší mi mluvit za ostatní města, ale za Olomouc mohu kvitovat lidský přístup, + obětavost, schopnost hlavního kouče předávat informace takovým způsobem, že pro + všechny z nás byla učební látka pochopena povětšinou napoprvé. Vzpomíná-li + někdo na hodiny angličtiny s hrůzou, v nichž se bál promluvit, tak tady se bát + opravdu nemusí. Chyby jsou brány jako běžná součást vzdělávacího procesu a bez + nich se snad ani nelze programátorsky vyvíjet. Domácí projekty nemusíte vypracovat + napoprvé, ale za pomoci koučů jste ke správnému řešení dovedeni. Je to jen o + tom to zkoušet a nevzdat to. Navíc programování nabízí tolik cest, jak zkoumaný + problém vyřešit, že je jen na osobnosti a zkušenostech programátora, kterou z nich + si zvolí. Na programování nikdy nemusíte být sami a nejen při jeho objevování ve + svých začátcích Vám u toho může být oporou právě PyLadies. + + # 0 = worst, 5 = best + score: null diff --git a/meetups/olomouc.yml b/cities/olomouc/meetups.yml similarity index 72% rename from meetups/olomouc.yml rename to cities/olomouc/meetups.yml index e1cdaab22..2d5a259f6 100644 --- a/meetups/olomouc.yml +++ b/cities/olomouc/meetups.yml @@ -1,18 +1,17 @@ # Pozor, nové meetupy se přidávají na konec souboru -- name: PyLadies Olomouc
začátečnický kurz +- name: Začátečnický kurz
Leden 2020 materials: https://naucse.python.cz/2020/pyladies-olomouc-jaro/ registration: url: https://forms.gle/74qRf346E7YRT1Kr5 end: 2019-12-19 start: 2020-01-09 - end: 2020-04-30 + end: 2020-05-28 place: &zs-holeckova name: ZŠ Holečkova address: Holečkova 10, 779 00 Olomouc url: https://goo.gl/maps/iHKueXfExciQ1tZ9A -- name: PyLadies Olomouc
začátečnický kurz - materials: https://naucse.python.cz/2020/pyladies-olomouc-podzim/ +- name: Začátečnický kurz
Září 2020 registration: url: https://forms.gle/g4eUFfF3x79c2Axd8 end: 2020-08-16 diff --git a/teams/olomouc.yml b/cities/olomouc/team.yml similarity index 95% rename from teams/olomouc.yml rename to cities/olomouc/team.yml index df3c99f3d..987cc1d5f 100644 --- a/teams/olomouc.yml +++ b/cities/olomouc/team.yml @@ -1,3 +1,5 @@ +name: Tým olomouckých PyLadies +members: - name: Filip Valder img: img/olomouc/team/filip_valder.jpg role: Organizátor/Hlavní kouč diff --git a/cities/ostatni/about.html b/cities/ostatni/about.html new file mode 100644 index 000000000..198829f4e --- /dev/null +++ b/cities/ostatni/about.html @@ -0,0 +1,30 @@ +
+

Jak založit Pyladies ve tvém městě?

+

+ Nenašla jsi žádný plánovaný workshop nebo kurz ve svém městě? Zorganizuj si vlastní! :-) +

+

+ Nejsnažší cesta je obrátit se na některou z organizátorek PyLadies kurzů. Kontakt najdeš zde pod jednotlivými městy, nebo napiš do FB skupiny + Pyladies Praha, + Pyladies Brno, nebo + Pyladies Ostrava. + Určitě ti poradí s organizací. +

+

+ Nebo prostě zajdi na Pyvo. + Ve větších městech pravidelně probíhají setkání příznivců programovacího jazyka Python. + Najdeš zde spoustu nadšenců a třeba i nějaké ochotné budoucí kouče. +

+

+ Pokud neznáš nikoho, kdo Python učí, zkus najít kouče ve skupině + Učíme Python, která je určena pro kouče/učitele Pythonu a pro ty, co je shánějí. +

+

+ Praktické rady k organizaci jsou sepsané i + v Příručce pro pořadatele kurzů pro začátečníky. +

+

+ Podporu jistě najdeš i na Facebookové skupině Python komunity + a na stránkách Python.cz. +

+

diff --git a/cities/ostatni/city.yml b/cities/ostatni/city.yml new file mode 100644 index 000000000..c022636b2 --- /dev/null +++ b/cities/ostatni/city.yml @@ -0,0 +1,2 @@ +title: null +order: 999 diff --git a/cities/ostatni/feedbacks.yml b/cities/ostatni/feedbacks.yml new file mode 100644 index 000000000..b46675478 --- /dev/null +++ b/cities/ostatni/feedbacks.yml @@ -0,0 +1,44 @@ +- author: Pavlína F. + meetup: + name: null + start: null + content: | + Kurz byl pro mě ohromně přínosný. S pomocí koučů a lidí ve skupině jsem + si po kurzu zvládla napsat pár krátkých prográmků, které mi zjednodušují každodenní práci + a to jsem před pyladies o Pythonu sotva slyšela. Všichni jsou až neuvěřitelně ochotní + pomoci. Rozhodně doporučuji! + # the original non truncated content + original-content: "" + # 0 = worst, 5 = best + score: null + +- author: Verča G. + meetup: + name: null + start: null + content: | + Dříve jsem vyhledávala krátké jednodenní či víkendové kurzy programování pro slečny. + Ale díky PyLadies srazům jsem zjistila, že scházet se každý týden, učit se postupně a více + do detailů je jednoduše super a velmi přínosné! Odcházela jsem s pocitem, že umím + informace ze srazů využít při psaní kódu. Oblíbila jsem si programovací jazyk Python + a především komunitu kolem Pythonu. Nyní pokračuji na vlastních projektech dál a na PyLadies + srazy se vracím jako koučka pro další slečny! + # the original non truncated content + original-content: "" + # 0 = worst, 5 = best + score: null + +- author: Verča Š. + meetup: + name: null + start: null + content: | + Kurz Pythonu u pražských Pyladies byl skvělý - komplexní, dobře vystavěný + a srozumitelně prezentovaný. Vyžadoval pozornou účast a aktivní domácí práci, ale nikdy + jsme v tom nebyly samy; k dispozici byli koučové, kteří ochotně zodpověděli + všechny dotazy a pomohli překonat nástrahy učení, online i offline. Super způsob, + jak se seznámit se základy programování a začlenit se do místní pythonovské komunity. + # the original non truncated content + original-content: "" + # 0 = worst, 5 = best + score: null diff --git a/meetups/ostatni.yml b/cities/ostatni/meetups.yml similarity index 100% rename from meetups/ostatni.yml rename to cities/ostatni/meetups.yml diff --git a/cities/ostrava/about.html b/cities/ostrava/about.html new file mode 100644 index 000000000..8f29a54fe --- /dev/null +++ b/cities/ostrava/about.html @@ -0,0 +1,5 @@ +
+

Jak to vzniklo v Ostravě?

+

Chtěly jsme umět něco, co nás ve škole nenaučí. A tak jednoho dne nás na cestu Pythonu přivedl bratr jedné z nás. Začaly jsme hledat možnost, jak nejlépe se ho naučit. Po dlouhém rozmýšlení a hledání jsme se rozhodly pro Pyladies. Dojíždění do Prahy či Brna nepřicházelo v úvahu a tak jsme se prostě rozhodly založit kurz v Ostravě.

+

Věříme, že i vy se chcete naučit něco víc, a že to víc najdete právě u nás. Doufáme, že vám naše lekce nebudou přinášet jen ponaučení a vědomosti, ale i zábavu a nové přátele. Můžete se také těšit na jiné akce, které pro vás chystáme v průběhu roku.

+
diff --git a/cities/ostrava/city.yml b/cities/ostrava/city.yml new file mode 100644 index 000000000..51af4a401 --- /dev/null +++ b/cities/ostrava/city.yml @@ -0,0 +1,13 @@ +title: Ostrava +order: 30 +contacts: + Facebook PyLadies Ostrava: + icon: facebook + url: https://www.facebook.com/pyladiesostrava/ + Google Group PyLadies Ostrava: + icon: google-group + url: https://groups.google.com/forum/#!forum/pyladies-ostrava + Napiš organizátorům: + icon: coach + url: mailto:ostrava@pyladies.cz +static-materials: [] diff --git a/meetups/ostrava.yml b/cities/ostrava/meetups.yml similarity index 100% rename from meetups/ostrava.yml rename to cities/ostrava/meetups.yml diff --git a/teams/ostrava.yml b/cities/ostrava/team.yml similarity index 97% rename from teams/ostrava.yml rename to cities/ostrava/team.yml index af591964e..eac992129 100644 --- a/teams/ostrava.yml +++ b/cities/ostrava/team.yml @@ -1,3 +1,5 @@ +name: Tým ostravských PyLadies +members: - name: Lumír Balhar role: Organizátor/Hlavní Kouč img: img/ostrava/team/lumir.jpg diff --git a/cities/plzen/city.yml b/cities/plzen/city.yml new file mode 100644 index 000000000..756bdba80 --- /dev/null +++ b/cities/plzen/city.yml @@ -0,0 +1,10 @@ +title: Plzeň +order: 40 +contacts: + Facebook PyLadies Plzeň: + icon: facebook + url: https://www.facebook.com/groups/2235479259799633 + Napiš koučovi: + icon: coach + url: mailto:plzen@pyladies.cz +static-materials: [] diff --git a/meetups/plzen.yml b/cities/plzen/meetups.yml similarity index 100% rename from meetups/plzen.yml rename to cities/plzen/meetups.yml diff --git a/teams/plzen.yml b/cities/plzen/team.yml similarity index 98% rename from teams/plzen.yml rename to cities/plzen/team.yml index 0c4f6b038..3b4aedbd7 100644 --- a/teams/plzen.yml +++ b/cities/plzen/team.yml @@ -1,3 +1,5 @@ +name: Tým plzeňských PyLadies +members: - name: Líba Poustková img: img/plzen/team/blank.png role: Organizátorka, lektorka diff --git a/cities/praha/about.html b/cities/praha/about.html new file mode 100644 index 000000000..4faa9f96c --- /dev/null +++ b/cities/praha/about.html @@ -0,0 +1,19 @@ +
+

Jak to vzniklo v Praze?

+

PyLadies v Praze vznikly v roce 2015 díky iniciativě pražské Python komunity a organizačním schopnostem pár akčních holek, které měly zájem se kurzu samy účastnit. Spouštěcím impulsem byl i úspěch jednodenního workshopu Django Girls Prague, rovněž zaměřeného na programování v Pythonu. Vytvořili jsme pražskou pilotní skupinu PyLadies a během prvního kurzu společně vylaďovali organizaci i náplň pražských srazů do současné podoby. Nyní kurz PyLadies představuje zhruba 13 dvouhodinových lekcí, které jsou doplněny i samostatnou prací na domácích projektech.

+

Na kurz pro začátečnice jsme v roce 2016 navázaly pravidelnými pondělními srazy (PyWorking sessions) pro pokročilejší začátečnice, kde mohou absolventky našeho kurzu pracovat na svých vlastních projektech pod vedením zkušených mentorů.

+
+
+
+ +
+
+ +
+
+ +
+
+
+

Společné setkávání v rámci PyLadies má velkou výhodu v tom, že se můžou holky navzájem průběžně motivovat a podporovat. Začátky bývají těžké, ale komunita kolem PyLadies vždy ochotně pomůže počáteční překážky překonávat. Díky týmu nadšenců fungují PyLadies čistě na dobrovolné a nezištné bázi.

+
diff --git a/cities/praha/city.yml b/cities/praha/city.yml new file mode 100644 index 000000000..ab3b85b31 --- /dev/null +++ b/cities/praha/city.yml @@ -0,0 +1,18 @@ +title: Praha +order: 10 +contacts: + Facebook PyLadies Praha: + icon: facebook + url: https://www.facebook.com/groups/PyLadiesPraha/ + PyWorking Praha: + icon: facebook + url: https://www.facebook.com/groups/PyWorkingPraha/ + Google Group PyLadies Praha: + icon: google-group + url: https://groups.google.com/forum/#!forum/pyladies-praha + Napiš organizátorkám: + icon: coach + url: mailto:praha@pyladies.cz +static-materials: + - name: Datový kurz + url: https://naucse.python.cz/2020/pydata-praha-jaro/ diff --git a/meetups/praha.yml b/cities/praha/meetups.yml similarity index 100% rename from meetups/praha.yml rename to cities/praha/meetups.yml diff --git a/teams/praha.yml b/cities/praha/team.yml similarity index 99% rename from teams/praha.yml rename to cities/praha/team.yml index 6cec7805e..488aabaab 100644 --- a/teams/praha.yml +++ b/cities/praha/team.yml @@ -1,3 +1,5 @@ +name: Tým pražských PyLadies +members: - name: Tereza Vaňková img: img/praha/team/terezavan.png role: Organizátorka - kurz NTK diff --git a/partners.yml b/partners.yml new file mode 100644 index 000000000..39a0f72af --- /dev/null +++ b/partners.yml @@ -0,0 +1,34 @@ +- url: https://www.python.org/psf/ + logo-file: psf.svg +- url: http://pyvec.org/ + logo-file: pyvec.svg +- url: http://www.redhat.com/en/global/czech-republic + logo-file: redhat.svg +- url: https://www.nic.cz/ + logo-file: cznic.svg +- url: https://www.tieto.cz/ + logo-file: tieto.svg +- url: http://www.kinali.cz/en/ + logo-file: kinali.svg +- url: https://www.techlib.cz/ + logo-file: ntk.svg +- url: https://apiary.io/ + logo-file: apiary.svg +- url: https://usertechnologies.com/ + logo-file: usertech.svg +- url: https://www.nekavarna.cz/ + logo-file: mergado.svg +- url: https://www.uhk.cz/cs-CZ/PRF + logo-file: uhk_prf.svg +- url: https://search.jobs.barclays/barclays-developers-prague + logo-file: barclays.svg +- url: https://www.solarwinds.com/ + logo-file: solarwinds.svg +- url: https://www.olc.cz + logo-file: olc.svg +- url: https://msdit.cz/ + logo-file: msd.svg +- url: https://www.kiwi.com/jobs + logo-file: kiwi.svg +- url: https://www.fi.muni.cz/ + logo-file: fimuni.svg diff --git a/pyladies_cz.py b/pyladies_cz.py index aa2333a92..83d83d78a 100755 --- a/pyladies_cz.py +++ b/pyladies_cz.py @@ -4,30 +4,38 @@ """ import sys -if sys.version_info < (3, 0): - raise RuntimeError('You need Python 3.') - import os import fnmatch +import time import datetime import collections -from urllib.parse import urlencode - -from flask import Flask, render_template, url_for, send_from_directory -from flask_frozen import Freezer import yaml import jinja2 import markdown +import random +import json +import hashlib + +from functools import lru_cache +from urllib.parse import urlencode +from flask import Flask, render_template, url_for, send_from_directory, abort +from flask_frozen import Freezer from elsa import cli +if sys.version_info < (3, 0): + raise RuntimeError('You need Python 3.') + + app = Flask('pyladies_cz') app.config['TEMPLATES_AUTO_RELOAD'] = True +app.jinja_loader = jinja2.FileSystemLoader(['cities/', 'templates/']) orig_path = os.path.join(app.root_path, 'original/') v1_path = os.path.join(orig_path, 'v1/') MISSING = object() + def redirect(url): """Return a response with a Meta redirect""" @@ -47,90 +55,122 @@ def redirect(url): @app.route('/') def index(): news = read_news_yaml('news.yml') - return render_template('index.html', news=news) + partners = read_yaml('partners.yml') + return render_template( + 'index.html', news=news, partners=partners, + feedbacks=get_random_feedbacks(ttl=round(time.time() / 30))) # cache for 30 secs + @app.route('//') def city(city_slug): - cities = read_yaml('cities.yml') + cities = get_cities() city = cities.get(city_slug) if city is None: abort(404) - meetups = read_meetups_yaml('meetups/' + city_slug + '.yml') + meetups = read_meetups_yaml(os.path.join('cities', city_slug, 'meetups.yml')) current_meetups = [m for m in meetups if m['current']] past_meetups = [m for m in meetups if not m['current']] registration_meetups = [ - m for m in current_meetups if m.get('registration_status')=='running'] + m for m in current_meetups if m.get('registration_status') == 'running'] return render_template( 'city.html', city_slug=city_slug, city_title=city['title'], - team_name=city.get('team-name'), newsletter=city.get('newsletter'), current_meetups=current_meetups, past_meetups=past_meetups, registration_meetups=registration_meetups, contacts=city.get('contacts'), - team=read_yaml('teams/' + city_slug + '.yml', default=()), + team=read_yaml(os.path.join('cities', city_slug, 'team.yml'), default=()), ) + @app.route('/_course/') def course_redirect(city): return redirect(url_for('city', city_slug=city, _anchor='meetups')) + @app.route('/_info/') def info_redirect(city): return redirect(url_for('city', city_slug=city, _anchor='city-info')) + @app.route('/praha-cznic/') def praha_cznic(): return redirect('https://naucse.python.cz/2018/pyladies-praha-jaro-cznic/') + @app.route('/praha-ntk/') def praha_ntk(): return redirect('https://naucse.python.cz/2018/pyladies-praha-jaro-ntk/') + @app.route('/stan_se/') def stan_se(): return render_template('stan_se.html') + @app.route('/faq/') def faq(): return render_template('faq.html') + @app.route('/v1/') def v1(path): if path in REDIRECTS: return redirect(REDIRECTS[path]) return send_from_directory(v1_path, path) + @app.route('/index.html') def index_html(): return redirect(url_for('index')) + @app.route('/course.html') def course_html(): return send_from_directory(orig_path, 'course.html') + @app.route('/googlecc704f0f191eda8f.html') def google_verification(): # Verification page for GMail on our domain return send_from_directory(app.root_path, 'google-verification.html') +@app.route('/feedbacks.json') +def feedbacks_json(): + return (json.dumps([(f['id'], render_template('feedbacks.html', feedback=f)) + for f in get_random_feedbacks(n=-1, ttl=round(time.time() / 3600))], + ensure_ascii=False), 200, {'Content-Type': 'application/json; charset=utf-8'}) + + ########## ## Template variables @app.context_processor def inject_cities(): cities = {} - for city_name, city_info in read_yaml('cities.yml').items(): - meetups = read_meetups_yaml(f'meetups/{city_name}.yml') + materials = list() + for city_name, city_info in get_cities().items(): + meetups = read_meetups_yaml(f'cities/{city_name}/meetups.yml') + current_meetups = [m for m in meetups if m['current']] + past_meetups = [m for m in meetups if not m['current']][:3] + recent_meetups = current_meetups + past_meetups + materials.extend((city_info['title'] + ' / ' + m['name'], m['materials']) + for m in recent_meetups + if 'materials' in m) + if 'static-materials' in city_info: + materials.extend((city_info['title'] + ' / ' + m['name'], m['url']) + for m in city_info['static-materials']) meetups_nonpermanent = [m for m in meetups if m.get('start')] cities[city_name] = { **city_info, - 'active_registration': any(m.get('registration_status') == 'running' for m in meetups_nonpermanent), + 'active_registration': any(m.get('registration_status') == 'running' + for m in meetups_nonpermanent), } - return dict(cities=cities) + return dict(cities=cities, + materials=materials) ########## @@ -138,6 +178,7 @@ def inject_cities(): md = markdown.Markdown(extensions=['meta', 'markdown.extensions.toc']) + @app.template_filter('markdown') def convert_markdown(text, inline=False): result = jinja2.Markup(md.convert(text)) @@ -145,6 +186,7 @@ def convert_markdown(text, inline=False): result = result[3:-4] return result + @app.template_filter('date_range') def date_range(dates, sep='–'): start, end = dates @@ -162,6 +204,56 @@ def date_range(dates, sep='–'): return ' '.join(pieces) +@app.template_filter('datetimeformat') +def datetimeformat(value, format='%Y'): + return value.strftime(format) + + +def get_cities(): + """ + Returns {'cityY': , + 'cityX': , + ...} + by order specified in the YAML + """ + + cities_yamls = {d: os.path.join('cities', d, 'city.yml') + for d in os.listdir('cities') + if os.path.isdir(os.path.join('cities', d))} + cities = {d: read_yaml(y) for d, y in cities_yamls.items()} + cities_sorted = collections.OrderedDict(sorted(cities.items(), key=lambda x: x[1]['order'])) + return cities_sorted + + +@lru_cache(maxsize=10) +def get_random_feedbacks(n=3, ttl=None): + """ + Returns list of n random feedbacks from various cities, randomly sorted. + If n == -1, then return all, also randomly sorted. + + This can be quite expensive when too many requests need to be handled (e.g. if used on index + page), so let's provide some simple caching feature using `ttl' which would change + e.g. once a 30 seconds or so, when calling this function. + """ + + cities = get_cities() + feedbacks_yamls = {d: os.path.join('cities', d, 'feedbacks.yml') + for d in os.listdir('cities') + if os.path.isfile(os.path.join('cities', d, 'feedbacks.yml'))} + city_feedbacks = {cities[d]['title']: read_yaml(y) for d, y in feedbacks_yamls.items()} + feedbacks = list() + for city_title, feedback_list in city_feedbacks.items(): + feedbacks.extend([(city_title, i) for i in feedback_list]) + if n == -1 or n > len(feedbacks): + n = len(feedbacks) + random_feedbacks = random.sample(feedbacks, n) + random_feedbacks = [{'city-title': f[0], + 'id': hashlib.sha256(f[1]['content'].encode()).hexdigest(), + **f[1]} + for f in random_feedbacks] + return random_feedbacks + + def read_yaml(filename, default=MISSING): try: file = open(filename, encoding='utf-8') @@ -173,6 +265,7 @@ def read_yaml(filename, default=MISSING): data = yaml.safe_load(file) return data + def read_lessons_yaml(filename): data = read_yaml(filename) @@ -217,8 +310,8 @@ def read_meetups_yaml(filename): # Derive a URL for places that don't have one from the location if 'place' in meetup: - if ('url' not in meetup['place'] - and {'latitude', 'longitude'} <= meetup['place'].keys()): + if ('url' not in meetup['place'] and {'latitude', + 'longitude'} <= meetup['place'].keys()): place = meetup['place'] place['url'] = 'http://mapy.cz/zakladni?' + urlencode({ 'y': place['latitude'], @@ -242,6 +335,7 @@ def read_meetups_yaml(filename): return list(reversed(data)) + def read_news_yaml(filename): data = read_yaml(filename) today = datetime.date.today() @@ -253,6 +347,7 @@ def read_news_yaml(filename): return news + def pathto(name, static=False): if static: prefix = '_static/' @@ -290,8 +385,9 @@ def inject_context(): freezer = Freezer(app) + @freezer.register_generator -def v1(): +def v1(): # noqa: F811 IGNORE = ['*.aux', '*.out', '*.log', '*.scss', '.travis.yml', '.gitignore'] for name, dirs, files in os.walk(v1_path): if '.git' in dirs: @@ -305,17 +401,21 @@ def v1(): for path in REDIRECTS: yield url_for('v1', path=path) + OLD_CITIES = 'praha', 'brno', 'ostrava' + @freezer.register_generator -def course_redirect(): +def course_redirect(): # noqa: F811 for city in OLD_CITIES: yield {'city': city} + @freezer.register_generator -def info_redirect(): +def info_redirect(): # noqa: F811 for city in OLD_CITIES: yield {'city': city} + if __name__ == '__main__': cli(app, freezer=freezer, base_url='http://pyladies.cz') diff --git a/static/css/custom.css b/static/css/custom.css index 1e78a20ed..8d45608ec 100755 --- a/static/css/custom.css +++ b/static/css/custom.css @@ -530,11 +530,19 @@ HOMEPAGE max-height: 50%; color: #fff; text-align: left; + margin-bottom: 20px; } .ref-p { float: left; font-style: italic; } +.ref-name { + clear: both; + margin-bottom: 0; +} +.ref-details { + color: #d3d3d3; +} .head li { list-style-type: none; text-align: center; diff --git a/templates/city.html b/templates/city.html index 372611744..bd140bd16 100644 --- a/templates/city.html +++ b/templates/city.html @@ -104,7 +104,7 @@

{{ meetup.name | markdown(inline=True) }}

{% block content %}
-

{{ city_title | upper }}

+

{{ city_title | default('Tvoje město', true) | upper }}

@@ -227,83 +227,7 @@

Newsletter

- {% if city_slug == 'brno' %} -
-

Jak to v Brně vzniklo?

-

Bylo nebylo, přijela jednou do Brna na návštěvu Lynn Root, která vede PyLadies v San Franciscu. Zrovna probíhala konference RuPy 2012, a v rámci ní Lynn uspořádala půldenní workshop pod hlavičkou PyLadies. Ale potom odjela, než našla dostatečně akční Pythonistku, která by to po ní převzala.

-
-
-
- -
-
- -
-
- -
-
-
-

Až po více než roce se na Facebooku ozvaly tři studentky, které se Python učily na škole a potřebovaly doučování. Vzpomněli jsme si na balíček samolepek PyLadies, co tu nechala Lynn, a rozhodli se to doučování udělat pod touto značkou. A odtud byl už jen krůček k začátečnickým kurzům i jiným srazům.

-
- {% elif city_slug == 'ostrava' %} -
-

Jak to vzniklo v Ostravě?

-

Chtěly jsme umět něco, co nás ve škole nenaučí. A tak jednoho dne nás na cestu Pythonu přivedl bratr jedné z nás. Začaly jsme hledat možnost, jak nejlépe se ho naučit. Po dlouhém rozmýšlení a hledání jsme se rozhodly pro Pyladies. Dojíždění do Prahy či Brna nepřicházelo v úvahu a tak jsme se prostě rozhodly založit kurz v Ostravě.

-

Věříme, že i vy se chcete naučit něco víc, a že to víc najdete právě u nás. Doufáme, že vám naše lekce nebudou přinášet jen ponaučení a vědomosti, ale i zábavu a nové přátele. Můžete se také těšit na jiné akce, které pro vás chystáme v průběhu roku.

-
- {% elif city_slug == 'praha' %} -
-

Jak to vzniklo v Praze?

-

PyLadies v Praze vznikly v roce 2015 díky iniciativě pražské Python komunity a organizačním schopnostem pár akčních holek, které měly zájem se kurzu samy účastnit. Spouštěcím impulsem byl i úspěch jednodenního workshopu Django Girls Prague, rovněž zaměřeného na programování v Pythonu. Vytvořili jsme pražskou pilotní skupinu PyLadies a během prvního kurzu společně vylaďovali organizaci i náplň pražských srazů do současné podoby. Nyní kurz PyLadies představuje zhruba 13 dvouhodinových lekcí, které jsou doplněny i samostatnou prací na domácích projektech.

-

Na kurz pro začátečnice jsme v roce 2016 navázaly pravidelnými pondělními srazy (PyWorking sessions) pro pokročilejší začátečnice, kde mohou absolventky našeho kurzu pracovat na svých vlastních projektech pod vedením zkušených mentorů.

-
-
-
- -
-
- -
-
- -
-
-
-

Společné setkávání v rámci PyLadies má velkou výhodu v tom, že se můžou holky navzájem průběžně motivovat a podporovat. Začátky bývají těžké, ale komunita kolem PyLadies vždy ochotně pomůže počáteční překážky překonávat. Díky týmu nadšenců fungují PyLadies čistě na dobrovolné a nezištné bázi.

-
- {% elif city_slug == 'ostatni' %} -
-

Jak založit Pyladies ve tvém městě?

-

- Nenašla jsi žádný plánovaný workshop nebo kurz ve svém městě? Zorganizuj si vlastní! :-) -

-

- Nejsnažší cesta je obrátit se na některou z organizátorek PyLadies kurzů. Kontakt najdeš zde pod jednotlivými městy, nebo napiš do FB skupiny - Pyladies Praha, - Pyladies Brno, nebo - Pyladies Ostrava. - Určitě ti poradí s organizací. -

-

- Nebo prostě zajdi na Pyvo. - Ve větších městech pravidelně probíhají setkání příznivců programovacího jazyka Python. - Najdeš zde spoustu nadšenců a třeba i nějaké ochotné budoucí kouče. -

-

- Pokud neznáš nikoho, kdo Python učí, zkus najít kouče ve skupině - Učíme Python, která je určena pro kouče/učitele Pythonu a pro ty, co je shánějí. -

-

- Praktické rady k organizaci jsou sepsané i - v Příručce pro pořadatele kurzů pro začátečníky. -

-

- Podporu jistě najdeš i na Facebookové skupině Python komunity - a na stránkách Python.cz. -

-

- {% endif %} + {% include city_slug + "/about.html" ignore missing with context %}
@@ -311,9 +235,9 @@

Jak založit Pyladies ve tvém městě?

{% if team %}
-

{{ team_name }}

+

{{ team.name }}

- {% for member in team %} + {% for member in team.members %}
diff --git a/templates/feedbacks.html b/templates/feedbacks.html new file mode 100644 index 000000000..7855c8b6d --- /dev/null +++ b/templates/feedbacks.html @@ -0,0 +1,6 @@ +{% if 'score' in feedback and feedback.score is not none %}
{{ feedback.score * '★ ' | safe }}{{ (5 - feedback.score) * '☆ ' | safe }}
{% endif %} +

+ "{{ feedback.content | safe | trim }}" +

{{ feedback.author }}{% if feedback['city-title'] %}, {{ feedback['city-title'] }}{% endif %}

+ {% if feedback.meetup.name and feedback.meetup.start %}

{{ feedback.meetup.name }}, {{ feedback.meetup.start | datetimeformat }}

{% endif %} +

diff --git a/templates/index.html b/templates/index.html index 36dea8951..54d52ba47 100644 --- a/templates/index.html +++ b/templates/index.html @@ -91,118 +91,53 @@

Neformální srazy

- + + +

PyLadies pro PyLadies

-
-

- "Kurz byl pro mě ohromně přínosný. S pomocí koučů a lidí ve skupině jsem si po kurzu zvládla napsat pár krátkých prográmků, které mi zjednodušují každodenní práci a to jsem před pyladies o Pythonu sotva slyšela. Všichni jsou až neuvěřitelně ochotní pomoci. Rozhodně doporučuji!" -

Pavlína F.

-

-
-
-

- "Dříve jsem vyhledávala krátké jednodenní či víkendové kurzy programování pro slečny. Ale díky PyLadies srazům jsem zjistila, že scházet se každý týden, učit se postupně a více do detailů je jednoduše super a velmi přínosné! Odcházela jsem s pocitem, že umím informace ze srazů využít při psaní kódu. Oblíbila jsem si programovací jazyk Python a především komunitu kolem Pythonu. Nyní pokračuji na vlastních projektech dál a na PyLadies srazy se vracím jako koučka pro další slečny!" -

Verča G.

-

-
-
-

- "Kurz Pythonu u pražských Pyladies byl skvělý - komplexní, dobře vystavěný a srozumitelně prezentovaný. Vyžadoval pozornou účast a aktivní domácí práci, ale nikdy jsme v tom nebyly samy; k dispozici byli koučové, kteří ochotně zodpověděli všechny dotazy a pomohli překonat nástrahy učení, online i offline. Super způsob, jak se seznámit se základy programování a začlenit se do místní pythonovské komunity." -

Verča Š.

-

-
+ {% for feedback in feedbacks %} +
+ {% include "feedbacks.html" with context %} +
+ {% endfor %}

Naši partneři

-
- - - -
-
- - - -
-
- - - -
-
- - - -
-
- - - -
-
- - - -
-
- - - -
-
- - - -
-
- - - -
-
- - - -
-
- - - -
-
- - - -
-
- - - -
-
- - - -
-
- - - -
-
- - - -
-
- - - -
+ {% for partner in partners %} +
+ + + +
+ {% endfor %}
{% endblock content %} diff --git a/templates/layout.html b/templates/layout.html index 083b87c09..576388051 100644 --- a/templates/layout.html +++ b/templates/layout.html @@ -47,7 +47,12 @@ n.async=1;n.src=c;g.parentNode.insertBefore(n,g) })(window,document,'script','//cdn.zeerat.com/track.js','Zeerat','R3c4yUSA'); - + + + @@ -67,35 +72,10 @@
  • Materiály
      - {% for name, url in ( - ('Brno – začátečnický kurz (pondělí)', - 'https://naucse.python.cz/2020/brno-jaro-pondeli/'), - ('Brno – začátečnický kurz (úterý)', - 'https://naucse.python.cz/2020/brno-jaro-2020-ut/'), - ('Brno – Linuxová administrace', - 'https://naucse.python.cz/2020/linux-admin/'), - ('Praha – začátečnický kurz (Olšanka)', - 'https://naucse.python.cz/2020/pyladies-praha-jaro-cznic/'), - ('Praha – začátečnický kurz (Barclays)', - 'https://naucse.python.cz/2020/pyladies-praha-jaro2020-barclays/'), - ('Praha – Datový kurz', - 'https://naucse.python.cz/2020/pydata-praha-jaro/'), - ('Ostrava – začátečnický kurz', - 'https://naucse.python.cz/2020/pyladies-ostrava-jaro/'), - ('Ostrava – kurz datové analýzy', - 'https://naucse.python.cz/2020/pydata-ostrava-jaro/'), - ('Plzeň – začátečnický kurz', - 'https://naucse.python.cz/2020/plzen-jaro-2020/'), - ('Hradec Králové – začátečnický kurz', - 'https://naucse.python.cz/2020/pyladies-hradec-leden/'), - ('Olomouc – začátečnický kurz', - 'https://naucse.python.cz/2020/pyladies-olomouc-jaro/'), - ('Chci se učit doma sama', - 'https://naucse.python.cz/course/pyladies/'), - ) %} + {% for name, url in materials + [('Chci se učit doma sama', 'https://naucse.python.cz/course/pyladies/')] %}
    • - {{ name }} + {{ name|striptags }}
    • @@ -119,7 +99,7 @@
      - {{ city['title'] }} + {{ city['title'] | default('Tvoje město', true) }}
      {% if city.active_registration %} diff --git a/templates/meta_redirect.html b/templates/meta_redirect.html index 48e1b8f19..dc2b68d32 100644 --- a/templates/meta_redirect.html +++ b/templates/meta_redirect.html @@ -13,7 +13,7 @@

      Přesměrování

      Obsah této stránky byl přesunut na novou adresu: - {{ url }}. + {{ url }}.

      diff --git a/test-requirements.txt b/test-requirements.txt new file mode 100644 index 000000000..8a4da7de9 --- /dev/null +++ b/test-requirements.txt @@ -0,0 +1,5 @@ +pytest +flake8 +requests +lxml +cssselect diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 000000000..b1cbc1433 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,58 @@ +import os +import yaml + +import pytest + +from pyladies_cz import app, REDIRECTS + +cities = {d: (os.path.join('cities', d, 'city.yml'), + os.path.join('cities', d, 'meetups.yml'), + os.path.join('cities', d, 'team.yml')) + for d in os.listdir('cities') + if os.path.isdir(os.path.join('cities', d))} +feedbacks = {d: os.path.join('cities', d, 'feedbacks.yml') + for d in os.listdir('cities') + if os.path.isfile(os.path.join('cities', d, 'feedbacks.yml'))} +simple_urls = [u.rule for u in app.url_map.iter_rules() if not u.arguments] +v1_redirects = ['/v1/{}'.format(r) for r in REDIRECTS] + +with open('partners.yml') as f: + partners = yaml.load(f.read(), Loader=yaml.SafeLoader) + + +@pytest.fixture +def client(): + app.config['TESTING'] = True + + with app.test_client() as client: + yield client + + +@pytest.fixture +def feedbacks_all(): + return feedbacks + + +@pytest.fixture(params=feedbacks.items(), ids=feedbacks.keys()) +def feedbacks_for_city(request): + return request.param + + +@pytest.fixture(params=cities.items(), ids=cities.keys()) +def city(request): + return request.param + + +@pytest.fixture(params=simple_urls) +def simple_url(request): + return request.param + + +@pytest.fixture(params=v1_redirects) +def v1_redirect(request): + return request.param + + +@pytest.fixture(params=partners, ids=lambda x: x['url']) +def partner(request): + return request.param diff --git a/tests/test_app.py b/tests/test_app.py new file mode 100644 index 000000000..6fd5ff90b --- /dev/null +++ b/tests/test_app.py @@ -0,0 +1,31 @@ +import requests + +from lxml.html import fromstring + + +def test_simple_url(client, simple_url): + rv = client.get(simple_url) + assert rv.status_code == 200 + + +def test_about_section_content(client): + rv = client.get('/ostatni/') + assert 'Jak založit Pyladies ve tvém městě?' in rv.data.decode('utf-8') + + +def test_city_urls(client, city): + rv = client.get(f'/{city[0]}/') + rv_course = client.get(f'/{city[0]}_course/') + rv_info = client.get(f'/{city[0]}_info/') + assert rv.status_code == 200 + assert rv_course.status_code == 200 + assert rv_info.status_code == 200 + + +def test_materials_dropdown_menu_urls(client): + rv = client.get('/') + a_elements = fromstring(rv.data).cssselect('ul.navbar-other li.materials-dropdown ul li a') + assert len(a_elements) + for a in a_elements: + r = requests.get(a.get('href')) + r.raise_for_status() diff --git a/tests/test_cities.py b/tests/test_cities.py new file mode 100644 index 000000000..97f30a52d --- /dev/null +++ b/tests/test_cities.py @@ -0,0 +1,30 @@ +import os +import yaml + +import pytest + + +def test_mandatory_yml_files(city): + city_yml, meetups_yml, _ = city[1] + assert os.path.isfile(city_yml) + assert os.path.isfile(meetups_yml) + + +def test_mandatory_city_yml_loading(city): + city_yml, _, _ = city[1] + with open(city_yml) as f: + yaml.load(f.read(), Loader=yaml.SafeLoader) + + +def test_mandatory_meetups_yml_loading(city): + _, meetups_yml, _ = city[1] + with open(meetups_yml) as f: + yaml.load(f.read(), Loader=yaml.SafeLoader) + + +def test_team_yml_loading(city): + _, _, team_yml = city[1] + if not os.path.isfile(team_yml): + pytest.skip("missing team.yml") + with open(team_yml) as f: + yaml.load(f.read(), Loader=yaml.SafeLoader) diff --git a/tests/test_feedbacks.py b/tests/test_feedbacks.py new file mode 100644 index 000000000..2f9a35b56 --- /dev/null +++ b/tests/test_feedbacks.py @@ -0,0 +1,27 @@ +import yaml + + +def test_feedbacks_yml_loading(feedbacks_for_city): + city, feedback_yml = feedbacks_for_city + with open(feedback_yml) as f: + yaml.load(f.read(), Loader=yaml.SafeLoader) + + +def test_min_number_of_feedbacks(feedbacks_all, n=3): + """ + Check that we have at least n feedbacks to be able to display + index page properly. + """ + feedbacks = [] + for feedback_yml in feedbacks_all.values(): + with open(feedback_yml) as f: + feedbacks.extend(yaml.load(f.read(), Loader=yaml.SafeLoader)) + assert len(feedbacks) >= n + + +def test_max_content_length_of_feedbacks(feedbacks_for_city): + city, feedback_yml = feedbacks_for_city + with open(feedback_yml) as f: + feedbacks = yaml.load(f.read(), Loader=yaml.SafeLoader) + for f in feedbacks: + assert len(f['content']) < 1000 diff --git a/tests/test_meetups.py b/tests/test_meetups.py new file mode 100644 index 000000000..fc4b3f369 --- /dev/null +++ b/tests/test_meetups.py @@ -0,0 +1,23 @@ +import requests + +import pytest + +from pyladies_cz import read_meetups_yaml + + +def test_materials_urls_for_recent_meetups(city): + _, meetups_yml, _ = city[1] + meetups = read_meetups_yaml(meetups_yml) + current_meetups = [m for m in meetups if m['current']] + past_meetups = [m for m in meetups if not m['current']][:3] + recent_meetups = current_meetups + past_meetups + missing_materials_urls = [] + for m in recent_meetups: + if 'materials' not in m: + missing_materials_urls.append(m['name']) + continue + r = requests.get(m['materials']) + r.raise_for_status() + if missing_materials_urls: + pytest.skip("Missing materials url for: {} / {}".format(city[0], + ", ".join(missing_materials_urls))) diff --git a/tests/test_partners.py b/tests/test_partners.py new file mode 100644 index 000000000..0fad0b277 --- /dev/null +++ b/tests/test_partners.py @@ -0,0 +1,8 @@ +import os +import requests + + +def test_partner_url_and_logo(partner): + r = requests.get(partner['url']) + r.raise_for_status() + assert os.path.isfile(os.path.join('static/img/logo/', partner['logo-file'])) diff --git a/tests/test_redirects.py b/tests/test_redirects.py new file mode 100644 index 000000000..8738ebfb3 --- /dev/null +++ b/tests/test_redirects.py @@ -0,0 +1,10 @@ +import requests + +from lxml.html import fromstring + + +def test_v1_redirect(client, v1_redirect): + rv = client.get(v1_redirect) + redir_element = fromstring(rv.data).cssselect('a.meta-redirect')[0] + r = requests.get(redir_element.get('href')) + assert r.status_code == 200