diff --git a/aesop/ovvpfile.py b/aesop/ovvpfile.py index 471c06c6..4d58af35 100644 --- a/aesop/ovvpfile.py +++ b/aesop/ovvpfile.py @@ -1,81 +1,30 @@ -# -*- coding: utf-8 -*- - -try: - from django.http import HttpResponse - from django.utils.encoding import force_text -except: - force_text = str - - -class OvvpFile(object): - def __init__(self): - # { header: value, ... } - self.headers = {} - # [ 'column-name', ... ] - self.columns = [] - # [ { column: value, ...}, ...] - self.rows = [] - - def to_lines(self): - # header - for hk in sorted(self.headers.keys()): - yield '%s\t%s\n' % (hk, self.headers[hk]) - yield '\n' - # columns - yield '\t'.join([c for c in self.columns]) + '\n' - # rows - for r in self.rows: - yield '\t'.join([force_text(r[c]) for c in self.columns]) + '\n' - - def to_string(self): - return ''.join(self.to_lines()) - - def to_HttpResponse(self): - return HttpResponse(self.to_string(), content_type='text/plain; charset=utf-8') - - def parse_from(self, source, with_headers=True): - "Parse data from file, string or line iterator, overwriting self" - if isinstance(source, str) or isinstance(source, unicode): - return self.parse_from(source.split('\n')) - - it = iter(source) - - # header - self.headers = {} - if with_headers: - for r in it: - if isinstance(r, str): - r = r.decode('utf8') - assert isinstance(r, unicode) - r = r.rstrip('\n') - if r == u"": - break - k, v = r.split(u'\t', 1) - self.headers[k] = v - - # columns - r = it.next() - if isinstance(r, str): - r = r.decode('utf8') - self.columns = [cn.strip() for cn in r.split(u'\t') if cn.strip() != ""] - - # rows - self.rows = [] - for r in it: - if isinstance(r, str): - r = r.decode('utf8') - r = r.rstrip('\n') - if not r: - break - rtup = r.split(u'\t') - rdict = {} - for ci in range(len(self.columns)): - rdict[self.columns[ci]] = rtup[ci] - self.rows.append(rdict) - - - -def parse(source, with_headers=True): - o = OvvpFile() - o.parse_from(source, with_headers=with_headers) - return o +from django.http import HttpResponse +from django.utils.encoding import force_text + + +class OvvpFile: + def __init__(self): + # { header: value, ... } + self.headers = {} + # [ 'column-name', ... ] + self.columns = [] + # [ { column: value, ...}, ...] + self.rows = [] + + def to_lines(self): + # header + for hk in sorted(self.headers.keys()): + yield f'{hk}\t{self.headers[hk]}\n' + yield '\n' + # columns + yield '\t'.join(self.columns) + '\n' + # rows + for r in self.rows: + yield '\t'.join([force_text(r[c]) for c in self.columns]) + '\n' + + def to_string(self): + return ''.join(self.to_lines()) + + # Pozn: tohle je ta jediná funkce, která se reálně používá… + def to_HttpResponse(self): + return HttpResponse(self.to_string(), content_type='text/plain; charset=utf-8') diff --git a/checklinks.sh b/checklinks.sh index 63898075..71b218f2 100755 --- a/checklinks.sh +++ b/checklinks.sh @@ -3,8 +3,16 @@ # Props to https://www.commandlinefu.com/commands/view/8234/check-broken-links-using-wget-as-a-spider set -eu +if test "$#" -lt 1; then + echo >&2 "Usage: $0 " + exit 1 +fi + logfile="$(pwd)/wget.log.$(date +%FT%T)" tmp=$(mktemp --directory) cd "$tmp" -wget --spider -o "$logfile" -r -p -X '/soustredeni/*/fotogalerie/' "$@" +wget --spider -o "$logfile" -r -p -X '/soustredeni/*/fotogalerie/' "$@" || true # wget nejspíš skončí s chybou, že něco nestáhl… + +echo "Result: (a last few lines of the file $logfile)" +sed -ne '/^Found [0-9]* broken links/,$ p' "$logfile" diff --git a/galerie/views.py b/galerie/views.py index 4570b8fb..f0d9b53b 100644 --- a/galerie/views.py +++ b/galerie/views.py @@ -24,7 +24,7 @@ def zobrazit(galerie, request): def cesta_od_korene(g): """Vrátí seznam galerií od kořene ke g""" cesta = [] - while g != None: + while g is not None: cesta.append(g) g = g.galerie_up return reversed(cesta) @@ -53,7 +53,7 @@ def nahled(request, pk, soustredeni): for g in sourozenci: if g.pk == galerie.pk: predchozi = minuly - if minuly != None and minuly.pk == galerie.pk: + if minuly is not None and minuly.pk == galerie.pk: nasledujici = g break minuly = g diff --git a/korektury/migrations/0011_prevod_autora_z_charField_na_Organizator.py b/korektury/migrations/0011_prevod_autora_z_charField_na_Organizator.py index 9f64bbd5..53082df9 100644 --- a/korektury/migrations/0011_prevod_autora_z_charField_na_Organizator.py +++ b/korektury/migrations/0011_prevod_autora_z_charField_na_Organizator.py @@ -4,7 +4,6 @@ from __future__ import unicode_literals from django.db import migrations, models def transform_autor(apps, schema_editor): - print Organizator = apps.get_model('seminar', 'Organizator') # preorgovani oprav diff --git a/seminar/management/commands/auth.py b/seminar/management/commands/auth.py deleted file mode 100644 index 71757418..00000000 --- a/seminar/management/commands/auth.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- - -from django.core.management.base import BaseCommand -from django.contrib.sessions.models import Session -from django.contrib.auth.models import User - -class Command(BaseCommand): - u"""Vypiš username přihlášeného orga s daným session_key. - - Příkaz pro manage.py, který ze vstupu přečte session_key (tak, jak je - uložen v cookie sessionid) a pokud session existuje a příslušný přihlášený - uživatel má právo přihlásit se do admina, vypíše jeho username. - """ - def handle(self, *args, **options): - session_key = raw_input() - s = Session.objects.get(pk=session_key).get_decoded() - user_id = s['_auth_user_id'] - user = User.objects.get(pk=user_id) - if user.is_staff: - print(user.username) diff --git a/seminar/models.py b/seminar/models.py index d4c3ad81..daef62e6 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -1139,6 +1139,7 @@ class Reseni(SeminarModelBase): # má ForeignKey s: # Hodnoceni + # ReseniNode def sum_body(self): return self.hodnoceni_set.all().aggregate(Sum('body'))["body__sum"] diff --git a/seminar/testutils.py b/seminar/testutils.py index 8fe8fe0c..019f66ac 100644 --- a/seminar/testutils.py +++ b/seminar/testutils.py @@ -77,8 +77,8 @@ def gen_osoby(rnd, size): prezdivka = rnd.choice(prezdivky) email = "@".join([unidecode.unidecode(jmeno), rnd.choice(domain)]) telefon = "".join([str(rnd.choice([k for k in range(10)])) for i in range(9)]) - narozeni = datetime.date(rnd.randint(1980, 2020), rnd.randint(1, 12), - rnd.randint(1, 28)) + narozeni = datetime.date(rnd.randint(1980, datetime.datetime.now().year), + rnd.randint(1, 12), rnd.randint(1, 28)) ulic = rnd.choice(seznam_ulic) cp = rnd.randint(1, 99) ulice = " ".join([ulic, str(cp)]) @@ -142,7 +142,7 @@ def gen_resitele(rnd, osoby, skoly): os.save() os.user.user_permissions.add(resitel_perm) resitele.append(Resitel.objects.create(osoba=os, skola=rnd.choice(skoly), - rok_maturity=rnd.randint(2019, 2029), + rok_maturity=os.datum_narozeni.year + rnd.randint(18, 21), zasilat=rnd.choice(Resitel.ZASILAT_CHOICES)[0])) return resitele @@ -890,6 +890,9 @@ def create_test_data(size = 6, rnd = None): # Dohackované vytvoření jednoho článku gen_clanek(rnd, organizatori, resitele) + # TODO: přidat články včetně zařazení do struktury treenodů, + # a následně otestovat konsistency check databáze z utils.py + # pomocí stránky /stav # obecné nastavení semináře, musí být už přidané ročníky a čísla, jinak se nastaví divně nastaveni = Nastaveni.objects.create( diff --git a/seminar/utils.py b/seminar/utils.py index 4604245c..01469a1f 100644 --- a/seminar/utils.py +++ b/seminar/utils.py @@ -88,6 +88,11 @@ def from_roman(rom): def seznam_problemu(): + """Funkce pro hledání nekonzistencí v databázi a dalších nežádoucích stavů webu/databáze. + + Nijak nesouvisí s Problémy zadanými řešitelům.""" + # FIXME: přejmenovat funkci? + # FIXME: Tak, jak je napsaná, asi spíš patří někam k views a ne do utils (?) problemy = [] # Pomocna fce k formatovani problemovych hlasek diff --git a/seminar/views/views_all.py b/seminar/views/views_all.py index 56e2aaae..9392f49a 100644 --- a/seminar/views/views_all.py +++ b/seminar/views/views_all.py @@ -891,7 +891,7 @@ def TitulyView(request, rocnik, cislo): asciijmena = [] jmenovci = False # detekuje, zda jsou dva řešitelé jmenovci (modulo nabodeníčka), # pokud ano, vrátí se jako true - slovnik_s_body = body_resitelu(resitele, rocnik_obj) + slovnik_s_body = body_resitelu(resitele, cislo_obj) for resitel in resitele: resitel.titul = resitel.get_titul(slovnik_s_body[resitel.id]) diff --git a/setup/README b/setup/README new file mode 100644 index 00000000..3b736cdc --- /dev/null +++ b/setup/README @@ -0,0 +1,3 @@ +Tato složka obsahuje různé konfiguráky potřebné k rozběhnutí webu na serveru. + +TODO: Napsat sem i přehled toho, jak to funguje. diff --git a/setup/nginx/mam-test.ks.matfyz.cz b/setup/nginx/mam-test.ks.matfyz.cz new file mode 100644 index 00000000..46f9b2ec --- /dev/null +++ b/setup/nginx/mam-test.ks.matfyz.cz @@ -0,0 +1,50 @@ +server { + listen 195.113.20.177:80; + listen [2001:718:1e03:801::b1]:80; + server_name mam-test.ks.matfyz.cz; + return 301 https://$server_name$request_uri; + +} +server { + # SSL configuration + listen 195.113.20.177:443 ssl; + listen [2001:718:1e03:801::b1]:443 ssl; + + # SSL keys + ssl on; + ssl_certificate /etc/letsencrypt/live/mam-test.ks.matfyz.cz/fullchain.pem; # managed by Certbot + ssl_certificate_key /etc/letsencrypt/live/mam-test.ks.matfyz.cz/privkey.pem; # managed by Certbot + ssl_dhparam /etc/ssl/dhparams.pem; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 5m; + + server_name mam-test.ks.matfyz.cz; + + client_max_body_size 50M; + + auth_basic "MaMweb test - access restricted"; + auth_basic_user_file /akce/mam/www/mamweb-test/.htpasswd; + + location /static/ { + root /akce/mam/www/mamweb-test/; + } + + location /media/ { + root /akce/mam/www/mamweb-test/; + } + + location /aesop-export/ { + auth_basic "AESOP API"; + auth_basic_user_file /akce/mam/www/mamweb-test/.htpasswd-aesop; + try_files $uri @mamweb_test; + } + + + location / { try_files $uri @mamweb_test; } + + location @mamweb_test { + include uwsgi_params; + uwsgi_pass unix:/tmp/uwsgi-mamweb_test.sock; + } + +} diff --git a/setup/nginx/mam.mff.cuni.cz b/setup/nginx/mam.mff.cuni.cz new file mode 100644 index 00000000..99292a67 --- /dev/null +++ b/setup/nginx/mam.mff.cuni.cz @@ -0,0 +1,65 @@ + +server { + listen 195.113.20.177:80; + listen [2001:718:1e03:801::b1]:80; + server_name mam.mff.cuni.cz; + return 301 https://$server_name$request_uri; + +} +server { + # SSL configuration + # + listen 195.113.20.177:443 ssl; + listen [2001:718:1e03:801::b1]:443 ssl; + + # SSL keys + ssl on; + ssl_certificate /etc/ssl/domains/mam.mff.cuni.cz/bundle.pem; + ssl_certificate_key /etc/ssl/domains/mam.mff.cuni.cz/privkey.pem; + ssl_dhparam /etc/ssl/dhparams.pem; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 5m; + + + server_name mam.mff.cuni.cz; + # server_name mamweb.bezva.org; + + client_max_body_size 50M; + + location /aesop-export/ { + auth_basic "AESOP API"; + auth_basic_user_file /akce/mam/www/mamweb-prod/.htpasswd-aesop; + try_files $uri @mamweb_prod; + } + + location /static/ { + root /akce/mam/www/mamweb-prod/; + } + + location /media/ { + root /akce/mam/www/mamweb-prod/; + } + + location /wiki/ { + proxy_pass http://127.0.0.1:5001/; + proxy_set_header X-Real_IP $remote_addr; + proxy_redirect / /wiki/; + #rewrite '/' '/wiki'; + sub_filter_once off; + sub_filter 'href="/' 'href="/wiki/'; + sub_filter 'src="/' 'src="/wiki/'; + sub_filter 'action="/' 'action="/wiki/'; + # Overkill: + #sub_filter '="/' '="/wiki/'; + #sub_filter ':5001/' '/wiki/'; + #sub_filter 'Location: /' 'Location: /wiki/'; + #sub_filter '_login' '_test'; + } + + location / { try_files $uri @mamweb_prod; } + + location @mamweb_prod { + include uwsgi_params; + uwsgi_pass unix:/tmp/uwsgi-mamweb_prod.sock; + } +} diff --git a/setup/systemd/mamweb-prod.service b/setup/systemd/mamweb-prod.service new file mode 100644 index 00000000..89af2a5c --- /dev/null +++ b/setup/systemd/mamweb-prod.service @@ -0,0 +1,10 @@ +[Unit] +Description=uWSGI instance to serve mam.mff.cuni.cz +After=network.target + +[Service] +WorkingDirectory=/akce/mam/www/mamweb-prod +ExecStart=/usr/bin/uwsgi --ini mamweb_prod.ini + +[Install] +WantedBy=default.target diff --git a/setup/systemd/mamweb-test.service b/setup/systemd/mamweb-test.service new file mode 100644 index 00000000..616605bb --- /dev/null +++ b/setup/systemd/mamweb-test.service @@ -0,0 +1,10 @@ +[Unit] +Description=uWSGI instance to serve mam-test.kam.mff.cuni.cz +After=network.target + +[Service] +WorkingDirectory=/akce/mam/www/mamweb-test +ExecStart=/usr/bin/uwsgi --ini mamweb_test.ini + +[Install] +WantedBy=default.target diff --git a/mamweb_prod.ini b/setup/uwsgi/mamweb_prod.ini similarity index 100% rename from mamweb_prod.ini rename to setup/uwsgi/mamweb_prod.ini diff --git a/mamweb_test.ini b/setup/uwsgi/mamweb_test.ini similarity index 100% rename from mamweb_test.ini rename to setup/uwsgi/mamweb_test.ini