Merge branch 'test' KRLEŠ!
16
.gitignore
vendored
|
@ -1,11 +1,5 @@
|
|||
# virtual env
|
||||
/bin/
|
||||
/include/
|
||||
/lib/
|
||||
/local/
|
||||
/share/
|
||||
/virtualenv/
|
||||
/pip-selfcheck.json
|
||||
/env/
|
||||
|
||||
# transient files
|
||||
/db-test.sqlite3*
|
||||
|
@ -16,7 +10,7 @@
|
|||
|
||||
# aux files
|
||||
*.pyc
|
||||
*.swp
|
||||
*.sw[mnop]
|
||||
|
||||
# secrets
|
||||
/django.secret
|
||||
|
@ -33,3 +27,9 @@ TODO
|
|||
|
||||
# .htpasswd pro AESOPa
|
||||
/.htpasswd-aesop
|
||||
|
||||
# reversion kvůli historii objektů v reversion
|
||||
**/reversion
|
||||
|
||||
# pro lidi, co programují v nástrojích od JetBrains
|
||||
.idea
|
||||
|
|
187
MIGRATIONS
Normal file
|
@ -0,0 +1,187 @@
|
|||
Jak zvládnout migrace na nový model:
|
||||
|
||||
- V mojí verzi databáze mají úlohy-Problémy typ "b'uloha'"
|
||||
|
||||
|
||||
Log migrace na nový model:
|
||||
|
||||
Operations to perform:
|
||||
Apply all migrations: admin, auth, contenttypes, django_comments, flatpages, fluent_comments, galerie, korektury, prednasky, reversion, seminar, sessions, sites, sitetree, taggit, threadedcomments
|
||||
Running migrations:
|
||||
Applying admin.0003_logentry_add_action_flag_choices... OK
|
||||
Applying auth.0009_alter_user_last_name_max_length... OK
|
||||
Applying auth.0010_alter_group_name_max_length... OK
|
||||
Applying auth.0011_update_proxy_permissions... OK
|
||||
Applying galerie.0008_auto_20190430_2340... OK
|
||||
Applying galerie.0009_auto_20190610_2358... OK
|
||||
Applying galerie.0010_auto_20200819_0947... OK
|
||||
Applying korektury.0016_auto_20190430_2340... OK
|
||||
Applying korektury.0017_auto_20190610_2358... OK
|
||||
Applying prednasky.0011_auto_20190430_2340... OK
|
||||
Applying prednasky.0012_auto_20190610_2358... OK
|
||||
Applying seminar.0049_auto_20190430_2354... OK
|
||||
Applying seminar.0050_auto_20190510_2228... OK
|
||||
Applying seminar.0051_resitel_to_osoba... OK
|
||||
Applying seminar.0052_user_to_organizator... OK
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2004-12-31 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (1998-01-01 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2017-12-31 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2017-01-01 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2014-12-31 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2011-01-01 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2013-12-31 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2004-01-01 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2013-01-01 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2012-12-31 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2007-01-01 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2011-12-31 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2009-01-01 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2009-12-31 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2008-12-31 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2005-01-01 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2015-12-31 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2001-01-01 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2010-01-01 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2008-01-01 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2006-12-31 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2002-01-01 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2005-12-31 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (1999-01-01 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2003-01-01 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2000-01-01 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2002-12-31 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2001-12-31 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (1996-01-01 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2000-12-31 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (1999-12-31 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (1996-12-31 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (1994-01-01 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2012-01-01 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2016-12-31 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2018-12-31 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2014-01-01 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2019-12-31 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2006-01-01 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (1995-01-01 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2007-12-31 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2015-01-01 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2016-01-01 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2018-01-01 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2019-01-01 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2020-01-01 00:00:00) while time zone support is active.
|
||||
RuntimeWarning)
|
||||
Applying seminar.0053_organizator_organizuje_od_do... OK
|
||||
Applying seminar.0055_smazat_nemigrovane_zastarale_veci... OK
|
||||
Applying seminar.0056_vrcholy_pro_rocniky_a_cisla... OK
|
||||
Applying seminar.0057_reseni_to_reseni_hodnoceni...!!!!!!!!!!!!!!!
|
||||
31397 Reseni object (31397)
|
||||
!!!!!!!!!!!!!!!
|
||||
!!!!!!!!!!!!!!!
|
||||
31396 Reseni object (31396)
|
||||
!!!!!!!!!!!!!!!
|
||||
!!!!!!!!!!!!!!!
|
||||
31395 Reseni object (31395)
|
||||
!!!!!!!!!!!!!!!
|
||||
!!!!!!!!!!!!!!!
|
||||
31394 Reseni object (31394)
|
||||
!!!!!!!!!!!!!!!
|
||||
!!!!!!!!!!!!!!!
|
||||
31393 Reseni object (31393)
|
||||
!!!!!!!!!!!!!!!
|
||||
OK
|
||||
Applying seminar.0058_problem_to_uloha_tema_clanek... OK
|
||||
Applying seminar.fix_0058... OK
|
||||
Applying seminar.0059_vytvorit_pohadkanode... OK
|
||||
Applying seminar.0060_spoj_stromy... OK
|
||||
Applying seminar.0061_kill_frankenstein... OK
|
||||
Applying seminar.0062_redukce_modelu_pohadky... OK
|
||||
Applying seminar.0063_procisteni_migraci... OK
|
||||
Applying seminar.0064_auto_20190610_2358... OK
|
||||
Applying seminar.0065_treenode_polymorphic_ctype... OK
|
||||
Applying seminar.0066_problem_polymorphic_ctype... OK
|
||||
Applying seminar.0067_auto_20190814_0805... OK
|
||||
Applying seminar.0068_treenode_nazev... OK
|
||||
Applying seminar.0069_auto_20191120_2115... OK
|
||||
Applying seminar.0070_auto_20191120_2357... OK
|
||||
Applying seminar.0071_remove_nastaveni_aktualni_rocnik... OK
|
||||
Applying seminar.0072_auto_20191204_2257... OK
|
||||
Applying seminar.0073_copy_osoba_email_to_user_email... OK
|
||||
Applying seminar.0074_auto_20200228_1401... OK
|
||||
Applying seminar.0075_auto_20200228_2010... OK
|
||||
Applying seminar.0076_auto_20200228_2013... OK
|
||||
Applying seminar.0077_auto_20200318_2146... OK
|
||||
Applying seminar.0078_otistenereseninode... OK
|
||||
Applying seminar.0079_clanek_resitelsky... OK
|
||||
Applying seminar.0080_zruseni_claneknode_a_konferanode... OK
|
||||
Applying seminar.0081_auto_20200408_2221... OK
|
||||
Applying seminar.0082_auto_20200506_1951... OK
|
||||
Applying seminar.0083_auto_20200506_1952... OK
|
||||
WARNING 2020-08-20 00:49:07,941 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (2215)
|
||||
WARNING 2020-08-20 00:49:07,953 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (2221)
|
||||
WARNING 2020-08-20 00:49:07,959 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (2212)
|
||||
WARNING 2020-08-20 00:49:07,965 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (1955)
|
||||
WARNING 2020-08-20 00:49:07,968 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (2027)
|
||||
WARNING 2020-08-20 00:49:07,971 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (1981)
|
||||
WARNING 2020-08-20 00:49:07,974 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (1970)
|
||||
WARNING 2020-08-20 00:49:07,978 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (2001)
|
||||
WARNING 2020-08-20 00:49:07,981 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (2004)
|
||||
WARNING 2020-08-20 00:49:07,984 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (1941)
|
||||
WARNING 2020-08-20 00:49:07,990 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (2024)
|
||||
WARNING 2020-08-20 00:49:07,993 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (2031)
|
||||
WARNING 2020-08-20 00:49:07,997 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (2211)
|
||||
WARNING 2020-08-20 00:49:08,005 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (2073)
|
||||
WARNING 2020-08-20 00:49:08,017 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (2018)
|
||||
WARNING 2020-08-20 00:49:08,022 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (2222)
|
||||
WARNING 2020-08-20 00:49:08,028 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (1953)
|
||||
WARNING 2020-08-20 00:49:08,034 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (2026)
|
||||
Applying seminar.0084_clanek_cislo... OK
|
||||
Applying seminar.0085_nepovinna_prezdivka... OK
|
||||
Applying seminar.0086_auto_20200819_0959... OK
|
||||
Applying sitetree.0001_initial... OK
|
||||
Applying taggit.0003_taggeditem_add_unique_index... OK
|
||||
|
120
Makefile
|
@ -1,68 +1,71 @@
|
|||
.PHONY: clean_env init_env clean_virtualenv install_packages clean install run all schema_seminar.pdf schema_all.pdf sync_test_media sync_test_db sync_test sync_local_media sync_local_db sync_local
|
||||
PYTHON=python2.7
|
||||
VE_VER=16.0.0
|
||||
LOCAL_PYTHON=bin/python
|
||||
PYTHON ?= python3
|
||||
VENV ?= ${PYTHON} -m venv
|
||||
# Všechny flagy, které se s venvem/virtualenvem/... mají volat patří sem. Volá se "${VENV} cesta"
|
||||
VENV_PATH ?= env
|
||||
# Musí být definovaná, i kdyby to měla být "."
|
||||
|
||||
all: install
|
||||
.PHONY: all venv_check clean install install_web install_venv clean_venv clean_schema run test deploy_test deploy_prod sync_test_media sync_test_db sync_test sync_local_media sync_local_db sync_local
|
||||
|
||||
clean: clean_env
|
||||
# activate by mělo být předpokladem ke všemu, co volá webový python (i.e. python nasazený do ${VENV}u kvůli webu, např. manage.py)
|
||||
all:
|
||||
@# Just echo:
|
||||
# Install je trochu magický:
|
||||
# Spusť následující posloupnost příkazů:
|
||||
# make install_venv
|
||||
# . ${VENV_PATH}/bin/activate
|
||||
# make install_web
|
||||
#
|
||||
# Pokud install_web říká Error: pg_config executable not found. nainstaluj si libpq-dev
|
||||
# Pokud chybová hláška obsahuje #include <Python.h>, nainstaluj si python3-dev
|
||||
#
|
||||
# Až skončíš s vývojem webu, spusť "deactivate". Tím zmizí '(${VENV_PATH})' ze začátku promptu.
|
||||
|
||||
veryclean: clean clean_virtualenv
|
||||
venv_check:
|
||||
@# Pokud org nemá zapnutý venv, poradíme mu, aby si ho zapnul a spadneme. Jinak nic.
|
||||
@expr $$PATH : ".*:*$(shell pwd)/${VENV_PATH}/bin" > /dev/null && exit 0 || echo 'Není zapnutý venv, spusť ". ${VENV_PATH}/bin/activate".\nPokud není venv nainstalovaný, spusť "make install_venv"' && false
|
||||
|
||||
install: virtualenv bin/python install_packages
|
||||
clean: clean_venv clean_schema
|
||||
|
||||
install: install_web
|
||||
|
||||
# phony, but depends on file
|
||||
make_env: ${LOCAL_PYTHON}
|
||||
install_web: venv_check
|
||||
@# venv může být příšerně starý, takže nejdříve upgradujeme venvové věci
|
||||
pip install --upgrade pip
|
||||
pip install --upgrade setuptools
|
||||
# Instalace závislostí webu
|
||||
pip install -r requirements.txt --upgrade
|
||||
# Po vygenerování testdat spusť ./manage.py loaddata data/*, ať máš menu a další modely
|
||||
# Pro synchronizaci flatpages spusť make sync_prod_flatpages
|
||||
|
||||
# phony, but fast repeated execution
|
||||
install_packages: make_env
|
||||
bin/pip install -r requirements.txt --upgrade
|
||||
install_venv:
|
||||
${VENV} ${VENV_PATH}
|
||||
|
||||
# phony
|
||||
clean_env:
|
||||
rm -rf bin/ include/ lib/ local/ share/
|
||||
clean_venv:
|
||||
# Možná není 100% foolproof...
|
||||
@test ! ${VENV_PATH} = . || ! echo "Smaž si prosím venv sám, nebudu mazat celý web"
|
||||
rm -rfv ${VENV_PATH}
|
||||
rm -f pip-selfcheck.json
|
||||
clean_schema:
|
||||
rm -f schema_seminar.pdf schema_all.pdf
|
||||
|
||||
# binary name representing set-up env
|
||||
${LOCAL_PYTHON}: virtualenv
|
||||
${PYTHON} virtualenv/virtualenv.py .
|
||||
|
||||
|
||||
|
||||
# directory name
|
||||
virtualenv:
|
||||
# I could not find a link without hash anymore. This will probably break in
|
||||
# the future.
|
||||
curl -O https://files.pythonhosted.org/packages/33/bc/fa0b5347139cd9564f0d44ebd2b147ac97c36b2403943dbee8a25fd74012/virtualenv-16.0.0.tar.gz
|
||||
tar xvfz virtualenv-${VE_VER}.tar.gz
|
||||
mv -T virtualenv-${VE_VER} virtualenv
|
||||
rm virtualenv-${VE_VER}.tar.gz
|
||||
|
||||
# phony
|
||||
clean_virtualenv:
|
||||
rm -rf virtualenv/
|
||||
rm -rf virtualenv-*.tar.gz
|
||||
|
||||
run:
|
||||
run: venv_check
|
||||
./manage.py runserver
|
||||
|
||||
test:
|
||||
test: venv_check
|
||||
./manage.py test -v2 seminar mamweb
|
||||
|
||||
# DB schemata
|
||||
|
||||
schema: schema_seminar.pdf schema_all.pdf
|
||||
|
||||
schema_seminar.pdf:
|
||||
schema_seminar.pdf: venv_check
|
||||
./manage.py graph_models seminar | dot -Tpdf > schema_seminar.pdf
|
||||
|
||||
schema_all.pdf:
|
||||
schema_all.pdf: venv_check
|
||||
./manage.py graph_models -a -g | dot -Tpdf > schema_all.pdf
|
||||
|
||||
# Deploy to current *mamweb-test* directory
|
||||
deploy_test:
|
||||
deploy_test: venv_check
|
||||
@if [ ${USER} != "mam-web" ]; then echo "Only possible by user mam-web"; exit 1; fi
|
||||
@if [ `readlink -f .` != "/aux/akce/mam/www/mamweb-test" ]; then echo "Only possible in directory mamweb-test"; exit 1; fi
|
||||
@echo "Installing version from origin/test ..."
|
||||
|
@ -78,7 +81,7 @@ deploy_test:
|
|||
@echo Done.
|
||||
|
||||
# Deploy to current *mamweb-prod* directory
|
||||
deploy_prod:
|
||||
deploy_prod: venv_check
|
||||
@if [ ${USER} != "mam-web" ]; then echo "Only possible by user mam-web"; exit 1; fi
|
||||
@if [ `readlink -f .` != "/aux/akce/mam/www/mamweb-prod" ]; then echo "Only possible in directory mamweb-prod"; exit 1; fi
|
||||
@echo "Backing up production DB ..."
|
||||
|
@ -96,6 +99,15 @@ deploy_prod:
|
|||
@echo Done.
|
||||
|
||||
|
||||
sync_prod_flatpages: venv_check
|
||||
@echo Downloading current version of flatpages from mamweb-prod.
|
||||
ssh mam-web@gimli.ms.mff.cuni.cz \
|
||||
"cd /akce/mam/www/mamweb-prod; ./manage.py dumpdata flatpages --indent=2 > flat.json"
|
||||
rsync -ave ssh mam-web@gimli.ms.mff.cuni.cz:/akce/mam/www/mamweb-prod/flat.json ./flat.json
|
||||
@echo "Applying downloaded flatpages."
|
||||
./manage.py loaddata flat.json
|
||||
@echo "Done."
|
||||
|
||||
# Sync test media directory with production
|
||||
sync_test_media:
|
||||
@if [ ${USER} != "mam-web" ]; then echo "Only possible by user mam-web"; exit 1; fi
|
||||
|
@ -107,12 +119,24 @@ sync_test_db:
|
|||
@if [ ${USER} != "mam-web" ]; then echo "Only possible by user mam-web"; exit 1; fi
|
||||
pg_dump mam_test > dump-test-`date +"%Y%m%d_%H%M"`.sql
|
||||
pg_dump -Fc mam_prod > dump-prod.sql
|
||||
pg_restore -c -d mam_test dump-prod.sql
|
||||
pg_restore -c --if-exists -d mam_test dump-prod.sql
|
||||
rm dump-prod.sql
|
||||
@echo Done.
|
||||
|
||||
# Aggresive variant: destroy original mam_test db with 'DROP OWNED BY "mam-web";'
|
||||
sync_test_db_aggressive:
|
||||
@if [ ${USER} != "mam-web" ]; then echo "Only possible by user mam-web"; exit 1; fi
|
||||
pg_dump mam_test > dump-test-`date +"%Y%m%d_%H%M"`.sql
|
||||
pg_dump -Fc mam_prod > dump-prod.sql
|
||||
@# I am not sure which shell is used, so I am calling bash to make sure
|
||||
bash -c "psql mam_test <<< 'DROP OWNED BY \"mam-web\";'"
|
||||
pg_restore -c --if-exists -d mam_test dump-prod.sql
|
||||
rm dump-prod.sql
|
||||
@echo Done.
|
||||
|
||||
# Sync test with production
|
||||
sync_test: sync_test_media sync_test_db
|
||||
# HACK ALERT: using aggressive variant, due to the schemas being too different.
|
||||
sync_test: sync_test_media sync_test_db_aggressive
|
||||
|
||||
|
||||
# Sync media directory with atrey. Useful for local development with production database
|
||||
|
@ -128,4 +152,10 @@ sync_local_db:
|
|||
pg_restore -c -d mam-prod last.pgdump
|
||||
|
||||
# Sync database and media. See above lines
|
||||
sync_local: sync_media sync_db
|
||||
sync_local: sync_local_media sync_local_db
|
||||
|
||||
# Push local compiled Vue to gimli test site
|
||||
push_compiled_vue_to_test:
|
||||
scp vue_frontend/webpack-stats.json mam-web@gimli:/akce/mam/www/mamweb-test/vue_frontend/
|
||||
rsync -ave ssh seminar/static/seminar/vue mam-web@gimli:/akce/mam/www/mamweb-test/seminar/static/seminar/
|
||||
ssh mam-web@gimli.ms.mff.cuni.cz 'cd /akce/mam/www/mamweb-test/ && . env/bin/activate && ./manage.py collectstatic --noinput'
|
||||
|
|
14
README.md
|
@ -13,12 +13,12 @@ Use git :-)
|
|||
|
||||
Quickstart
|
||||
----------
|
||||
Run the following commands:
|
||||
make install_venv
|
||||
. env/bin/activate
|
||||
make install_web
|
||||
|
||||
Install the following packages in Debian/Ubuntu: `libpq-dev python-dev python-setuptools python2.7 libjpeg-dev libpng12-dev`. Then run:
|
||||
|
||||
make
|
||||
./manage.py testdata
|
||||
make run
|
||||
After finishing development, run "deactivate".
|
||||
|
||||
Make commands
|
||||
-------------
|
||||
|
@ -41,6 +41,8 @@ Make commands
|
|||
|
||||
* `make schema` - generates graph of seminar and all schemas as PDF. Supercool!
|
||||
|
||||
* `make sync_prod_flatpages` - downloads and applies static/flat pages from mamweb-prod
|
||||
|
||||
./manage.py commands
|
||||
--------------------
|
||||
|
||||
|
@ -56,6 +58,8 @@ Make commands
|
|||
|
||||
* `./manage.py test` - run the tests.
|
||||
|
||||
* `./manage.py shell` - run commands, list elemements of database, check syntax
|
||||
by importing files, etc.
|
||||
|
||||
Configurations
|
||||
--------------
|
||||
|
|
BIN
Schema_new.dia
Normal file
637
admin_org_prava.json
Normal file
|
@ -0,0 +1,637 @@
|
|||
[
|
||||
{
|
||||
"codename": "org",
|
||||
"ct_app_label": "auth",
|
||||
"ct_model": "user"
|
||||
},
|
||||
{
|
||||
"codename": "add_flatpage",
|
||||
"ct_app_label": "flatpages",
|
||||
"ct_model": "flatpage"
|
||||
},
|
||||
{
|
||||
"codename": "change_flatpage",
|
||||
"ct_app_label": "flatpages",
|
||||
"ct_model": "flatpage"
|
||||
},
|
||||
{
|
||||
"codename": "delete_flatpage",
|
||||
"ct_app_label": "flatpages",
|
||||
"ct_model": "flatpage"
|
||||
},
|
||||
{
|
||||
"codename": "view_flatpage",
|
||||
"ct_app_label": "flatpages",
|
||||
"ct_model": "flatpage"
|
||||
},
|
||||
{
|
||||
"codename": "add_galerie",
|
||||
"ct_app_label": "galerie",
|
||||
"ct_model": "galerie"
|
||||
},
|
||||
{
|
||||
"codename": "change_galerie",
|
||||
"ct_app_label": "galerie",
|
||||
"ct_model": "galerie"
|
||||
},
|
||||
{
|
||||
"codename": "delete_galerie",
|
||||
"ct_app_label": "galerie",
|
||||
"ct_model": "galerie"
|
||||
},
|
||||
{
|
||||
"codename": "view_galerie",
|
||||
"ct_app_label": "galerie",
|
||||
"ct_model": "galerie"
|
||||
},
|
||||
{
|
||||
"codename": "add_obrazek",
|
||||
"ct_app_label": "galerie",
|
||||
"ct_model": "obrazek"
|
||||
},
|
||||
{
|
||||
"codename": "change_obrazek",
|
||||
"ct_app_label": "galerie",
|
||||
"ct_model": "obrazek"
|
||||
},
|
||||
{
|
||||
"codename": "delete_obrazek",
|
||||
"ct_app_label": "galerie",
|
||||
"ct_model": "obrazek"
|
||||
},
|
||||
{
|
||||
"codename": "view_obrazek",
|
||||
"ct_app_label": "galerie",
|
||||
"ct_model": "obrazek"
|
||||
},
|
||||
{
|
||||
"codename": "add_komentar",
|
||||
"ct_app_label": "korektury",
|
||||
"ct_model": "komentar"
|
||||
},
|
||||
{
|
||||
"codename": "change_komentar",
|
||||
"ct_app_label": "korektury",
|
||||
"ct_model": "komentar"
|
||||
},
|
||||
{
|
||||
"codename": "delete_komentar",
|
||||
"ct_app_label": "korektury",
|
||||
"ct_model": "komentar"
|
||||
},
|
||||
{
|
||||
"codename": "view_komentar",
|
||||
"ct_app_label": "korektury",
|
||||
"ct_model": "komentar"
|
||||
},
|
||||
{
|
||||
"codename": "add_korekturovanepdf",
|
||||
"ct_app_label": "korektury",
|
||||
"ct_model": "korekturovanepdf"
|
||||
},
|
||||
{
|
||||
"codename": "change_korekturovanepdf",
|
||||
"ct_app_label": "korektury",
|
||||
"ct_model": "korekturovanepdf"
|
||||
},
|
||||
{
|
||||
"codename": "delete_korekturovanepdf",
|
||||
"ct_app_label": "korektury",
|
||||
"ct_model": "korekturovanepdf"
|
||||
},
|
||||
{
|
||||
"codename": "view_korekturovanepdf",
|
||||
"ct_app_label": "korektury",
|
||||
"ct_model": "korekturovanepdf"
|
||||
},
|
||||
{
|
||||
"codename": "add_oprava",
|
||||
"ct_app_label": "korektury",
|
||||
"ct_model": "oprava"
|
||||
},
|
||||
{
|
||||
"codename": "change_oprava",
|
||||
"ct_app_label": "korektury",
|
||||
"ct_model": "oprava"
|
||||
},
|
||||
{
|
||||
"codename": "delete_oprava",
|
||||
"ct_app_label": "korektury",
|
||||
"ct_model": "oprava"
|
||||
},
|
||||
{
|
||||
"codename": "view_oprava",
|
||||
"ct_app_label": "korektury",
|
||||
"ct_model": "oprava"
|
||||
},
|
||||
{
|
||||
"codename": "add_hlasovani",
|
||||
"ct_app_label": "prednasky",
|
||||
"ct_model": "hlasovani"
|
||||
},
|
||||
{
|
||||
"codename": "change_hlasovani",
|
||||
"ct_app_label": "prednasky",
|
||||
"ct_model": "hlasovani"
|
||||
},
|
||||
{
|
||||
"codename": "delete_hlasovani",
|
||||
"ct_app_label": "prednasky",
|
||||
"ct_model": "hlasovani"
|
||||
},
|
||||
{
|
||||
"codename": "view_hlasovani",
|
||||
"ct_app_label": "prednasky",
|
||||
"ct_model": "hlasovani"
|
||||
},
|
||||
{
|
||||
"codename": "add_prednaska",
|
||||
"ct_app_label": "prednasky",
|
||||
"ct_model": "prednaska"
|
||||
},
|
||||
{
|
||||
"codename": "change_prednaska",
|
||||
"ct_app_label": "prednasky",
|
||||
"ct_model": "prednaska"
|
||||
},
|
||||
{
|
||||
"codename": "delete_prednaska",
|
||||
"ct_app_label": "prednasky",
|
||||
"ct_model": "prednaska"
|
||||
},
|
||||
{
|
||||
"codename": "view_prednaska",
|
||||
"ct_app_label": "prednasky",
|
||||
"ct_model": "prednaska"
|
||||
},
|
||||
{
|
||||
"codename": "add_seznam",
|
||||
"ct_app_label": "prednasky",
|
||||
"ct_model": "seznam"
|
||||
},
|
||||
{
|
||||
"codename": "change_seznam",
|
||||
"ct_app_label": "prednasky",
|
||||
"ct_model": "seznam"
|
||||
},
|
||||
{
|
||||
"codename": "delete_seznam",
|
||||
"ct_app_label": "prednasky",
|
||||
"ct_model": "seznam"
|
||||
},
|
||||
{
|
||||
"codename": "view_seznam",
|
||||
"ct_app_label": "prednasky",
|
||||
"ct_model": "seznam"
|
||||
},
|
||||
{
|
||||
"codename": "add_cislo",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "cislo"
|
||||
},
|
||||
{
|
||||
"codename": "change_cislo",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "cislo"
|
||||
},
|
||||
{
|
||||
"codename": "delete_cislo",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "cislo"
|
||||
},
|
||||
{
|
||||
"codename": "view_cislo",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "cislo"
|
||||
},
|
||||
{
|
||||
"codename": "add_clanek",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "clanek"
|
||||
},
|
||||
{
|
||||
"codename": "change_clanek",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "clanek"
|
||||
},
|
||||
{
|
||||
"codename": "delete_clanek",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "clanek"
|
||||
},
|
||||
{
|
||||
"codename": "view_clanek",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "clanek"
|
||||
},
|
||||
{
|
||||
"codename": "add_konfera",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "konfera"
|
||||
},
|
||||
{
|
||||
"codename": "change_konfera",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "konfera"
|
||||
},
|
||||
{
|
||||
"codename": "delete_konfera",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "konfera"
|
||||
},
|
||||
{
|
||||
"codename": "view_konfera",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "konfera"
|
||||
},
|
||||
{
|
||||
"codename": "add_konfery_ucastnici",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "konfery_ucastnici"
|
||||
},
|
||||
{
|
||||
"codename": "change_konfery_ucastnici",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "konfery_ucastnici"
|
||||
},
|
||||
{
|
||||
"codename": "delete_konfery_ucastnici",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "konfery_ucastnici"
|
||||
},
|
||||
{
|
||||
"codename": "view_konfery_ucastnici",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "konfery_ucastnici"
|
||||
},
|
||||
{
|
||||
"codename": "add_nastaveni",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "nastaveni"
|
||||
},
|
||||
{
|
||||
"codename": "change_nastaveni",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "nastaveni"
|
||||
},
|
||||
{
|
||||
"codename": "delete_nastaveni",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "nastaveni"
|
||||
},
|
||||
{
|
||||
"codename": "view_nastaveni",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "nastaveni"
|
||||
},
|
||||
{
|
||||
"codename": "add_novinky",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "novinky"
|
||||
},
|
||||
{
|
||||
"codename": "change_novinky",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "novinky"
|
||||
},
|
||||
{
|
||||
"codename": "delete_novinky",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "novinky"
|
||||
},
|
||||
{
|
||||
"codename": "view_novinky",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "novinky"
|
||||
},
|
||||
{
|
||||
"codename": "add_organizator",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "organizator"
|
||||
},
|
||||
{
|
||||
"codename": "change_organizator",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "organizator"
|
||||
},
|
||||
{
|
||||
"codename": "delete_organizator",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "organizator"
|
||||
},
|
||||
{
|
||||
"codename": "view_organizator",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "organizator"
|
||||
},
|
||||
{
|
||||
"codename": "add_osoba",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "osoba"
|
||||
},
|
||||
{
|
||||
"codename": "change_osoba",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "osoba"
|
||||
},
|
||||
{
|
||||
"codename": "delete_osoba",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "osoba"
|
||||
},
|
||||
{
|
||||
"codename": "view_osoba",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "osoba"
|
||||
},
|
||||
{
|
||||
"codename": "add_pohadka",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "pohadka"
|
||||
},
|
||||
{
|
||||
"codename": "change_pohadka",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "pohadka"
|
||||
},
|
||||
{
|
||||
"codename": "delete_pohadka",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "pohadka"
|
||||
},
|
||||
{
|
||||
"codename": "view_pohadka",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "pohadka"
|
||||
},
|
||||
{
|
||||
"codename": "add_prijemce",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "prijemce"
|
||||
},
|
||||
{
|
||||
"codename": "change_prijemce",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "prijemce"
|
||||
},
|
||||
{
|
||||
"codename": "delete_prijemce",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "prijemce"
|
||||
},
|
||||
{
|
||||
"codename": "view_prijemce",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "prijemce"
|
||||
},
|
||||
{
|
||||
"codename": "add_problem",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "problem"
|
||||
},
|
||||
{
|
||||
"codename": "change_problem",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "problem"
|
||||
},
|
||||
{
|
||||
"codename": "delete_problem",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "problem"
|
||||
},
|
||||
{
|
||||
"codename": "view_problem",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "problem"
|
||||
},
|
||||
{
|
||||
"codename": "add_resitel",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "resitel"
|
||||
},
|
||||
{
|
||||
"codename": "change_resitel",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "resitel"
|
||||
},
|
||||
{
|
||||
"codename": "delete_resitel",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "resitel"
|
||||
},
|
||||
{
|
||||
"codename": "view_resitel",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "resitel"
|
||||
},
|
||||
{
|
||||
"codename": "add_rocnik",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "rocnik"
|
||||
},
|
||||
{
|
||||
"codename": "change_rocnik",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "rocnik"
|
||||
},
|
||||
{
|
||||
"codename": "delete_rocnik",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "rocnik"
|
||||
},
|
||||
{
|
||||
"codename": "view_rocnik",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "rocnik"
|
||||
},
|
||||
{
|
||||
"codename": "add_skola",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "skola"
|
||||
},
|
||||
{
|
||||
"codename": "change_skola",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "skola"
|
||||
},
|
||||
{
|
||||
"codename": "delete_skola",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "skola"
|
||||
},
|
||||
{
|
||||
"codename": "view_skola",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "skola"
|
||||
},
|
||||
{
|
||||
"codename": "add_soustredeni",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "soustredeni"
|
||||
},
|
||||
{
|
||||
"codename": "change_soustredeni",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "soustredeni"
|
||||
},
|
||||
{
|
||||
"codename": "delete_soustredeni",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "soustredeni"
|
||||
},
|
||||
{
|
||||
"codename": "view_soustredeni",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "soustredeni"
|
||||
},
|
||||
{
|
||||
"codename": "add_soustredeni_organizatori",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "soustredeni_organizatori"
|
||||
},
|
||||
{
|
||||
"codename": "change_soustredeni_organizatori",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "soustredeni_organizatori"
|
||||
},
|
||||
{
|
||||
"codename": "delete_soustredeni_organizatori",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "soustredeni_organizatori"
|
||||
},
|
||||
{
|
||||
"codename": "view_soustredeni_organizatori",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "soustredeni_organizatori"
|
||||
},
|
||||
{
|
||||
"codename": "add_soustredeni_ucastnici",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "soustredeni_ucastnici"
|
||||
},
|
||||
{
|
||||
"codename": "change_soustredeni_ucastnici",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "soustredeni_ucastnici"
|
||||
},
|
||||
{
|
||||
"codename": "delete_soustredeni_ucastnici",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "soustredeni_ucastnici"
|
||||
},
|
||||
{
|
||||
"codename": "view_soustredeni_ucastnici",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "soustredeni_ucastnici"
|
||||
},
|
||||
{
|
||||
"codename": "add_tema",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "tema"
|
||||
},
|
||||
{
|
||||
"codename": "change_tema",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "tema"
|
||||
},
|
||||
{
|
||||
"codename": "delete_tema",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "tema"
|
||||
},
|
||||
{
|
||||
"codename": "view_tema",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "tema"
|
||||
},
|
||||
{
|
||||
"codename": "add_uloha",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "uloha"
|
||||
},
|
||||
{
|
||||
"codename": "change_uloha",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "uloha"
|
||||
},
|
||||
{
|
||||
"codename": "delete_uloha",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "uloha"
|
||||
},
|
||||
{
|
||||
"codename": "view_uloha",
|
||||
"ct_app_label": "seminar",
|
||||
"ct_model": "uloha"
|
||||
},
|
||||
{
|
||||
"codename": "add_tag",
|
||||
"ct_app_label": "taggit",
|
||||
"ct_model": "tag"
|
||||
},
|
||||
{
|
||||
"codename": "change_tag",
|
||||
"ct_app_label": "taggit",
|
||||
"ct_model": "tag"
|
||||
},
|
||||
{
|
||||
"codename": "delete_tag",
|
||||
"ct_app_label": "taggit",
|
||||
"ct_model": "tag"
|
||||
},
|
||||
{
|
||||
"codename": "view_tag",
|
||||
"ct_app_label": "taggit",
|
||||
"ct_model": "tag"
|
||||
},
|
||||
{
|
||||
"codename": "add_taggeditem",
|
||||
"ct_app_label": "taggit",
|
||||
"ct_model": "taggeditem"
|
||||
},
|
||||
{
|
||||
"codename": "change_taggeditem",
|
||||
"ct_app_label": "taggit",
|
||||
"ct_model": "taggeditem"
|
||||
},
|
||||
{
|
||||
"codename": "delete_taggeditem",
|
||||
"ct_app_label": "taggit",
|
||||
"ct_model": "taggeditem"
|
||||
},
|
||||
{
|
||||
"codename": "view_taggeditem",
|
||||
"ct_app_label": "taggit",
|
||||
"ct_model": "taggeditem"
|
||||
},
|
||||
{
|
||||
"codename": "add_fotkaheader",
|
||||
"ct_app_label": "header_fotky",
|
||||
"ct_model": "fotkaheader"
|
||||
},
|
||||
{
|
||||
"codename": "change_fotkaheader",
|
||||
"ct_app_label": "header_fotky",
|
||||
"ct_model": "fotkaheader"
|
||||
},
|
||||
{
|
||||
"codename": "view_fotkaheader",
|
||||
"ct_app_label": "header_fotky",
|
||||
"ct_model": "fotkaheader"
|
||||
},
|
||||
{
|
||||
"codename": "add_fotkaurlvazba",
|
||||
"ct_app_label": "header_fotky",
|
||||
"ct_model": "fotkaurlvazba"
|
||||
},
|
||||
{
|
||||
"codename": "change_fotkaurlvazba",
|
||||
"ct_app_label": "header_fotky",
|
||||
"ct_model": "fotkaurlvazba"
|
||||
},
|
||||
{
|
||||
"codename": "view_fotkaurlvazba",
|
||||
"ct_app_label": "header_fotky",
|
||||
"ct_model": "fotkaurlvazba"
|
||||
}
|
||||
]
|
10
checklinks.sh
Executable file
|
@ -0,0 +1,10 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Props to https://www.commandlinefu.com/commands/view/8234/check-broken-links-using-wget-as-a-spider
|
||||
set -eu
|
||||
|
||||
logfile="$(pwd)/wget.log.$(date +%FT%T)"
|
||||
tmp=$(mktemp --directory)
|
||||
cd "$tmp"
|
||||
|
||||
wget --spider -o "$logfile" -r -p -X '/soustredeni/*/fotogalerie/' "$@"
|
17
convert_spaces_to_tabs.sh
Executable file
|
@ -0,0 +1,17 @@
|
|||
#!/bin/sh
|
||||
|
||||
if test "$#" -lt 1
|
||||
then
|
||||
echo "Usage: $0 file ..."
|
||||
exit 2
|
||||
fi
|
||||
|
||||
for file in "$@"
|
||||
do
|
||||
# Do the sed magic: keep replacing 4 spaces at the begining of line
|
||||
sed -i -re '
|
||||
: loop
|
||||
s/^( *) /\1 /
|
||||
t loop
|
||||
' "$file"
|
||||
done
|
182
data/flat.json
Normal file
207
data/fotka_header.json
Normal file
|
@ -0,0 +1,207 @@
|
|||
[
|
||||
{
|
||||
"model": "header_fotky.fotkaheader",
|
||||
"pk": "baliky.jpg",
|
||||
"fields": {
|
||||
"cas": "2020-09-20T09:18:34.562Z",
|
||||
"fotka": "header/baliky.jpg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "header_fotky.fotkaheader",
|
||||
"pk": "beh.jpg",
|
||||
"fields": {
|
||||
"cas": "2020-09-20T09:18:34.562Z",
|
||||
"fotka": "header/beh.jpg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "header_fotky.fotkaheader",
|
||||
"pk": "kryptografie.jpg",
|
||||
"fields": {
|
||||
"cas": "2020-09-20T09:18:34.562Z",
|
||||
"fotka": "header/kryptografie.jpg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "header_fotky.fotkaheader",
|
||||
"pk": "mam_cernobile.jpg",
|
||||
"fields": {
|
||||
"cas": "2020-09-20T09:18:34.562Z",
|
||||
"fotka": "header/mam_cernobile.jpg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "header_fotky.fotkaheader",
|
||||
"pk": "noc.jpg",
|
||||
"fields": {
|
||||
"cas": "2020-09-20T09:18:34.562Z",
|
||||
"fotka": "header/noc.jpg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "header_fotky.fotkaheader",
|
||||
"pk": "ohen.jpg",
|
||||
"fields": {
|
||||
"cas": "2020-09-20T09:18:34.562Z",
|
||||
"fotka": "header/ohen.jpg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "header_fotky.fotkaheader",
|
||||
"pk": "snih.jpg",
|
||||
"fields": {
|
||||
"cas": "2020-09-20T09:18:34.562Z",
|
||||
"fotka": "header/snih.jpg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "header_fotky.fotkaheader",
|
||||
"pk": "spolecna.jpg",
|
||||
"fields": {
|
||||
"cas": "2020-09-20T09:18:34.562Z",
|
||||
"fotka": "header/spolecna.jpg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "header_fotky.fotkaheader",
|
||||
"pk": "stiny.jpg",
|
||||
"fields": {
|
||||
"cas": "2020-09-20T09:18:34.562Z",
|
||||
"fotka": "header/stiny.jpg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "header_fotky.fotkaheader",
|
||||
"pk": "vikendovka.jpg",
|
||||
"fields": {
|
||||
"cas": "2020-09-20T09:18:34.562Z",
|
||||
"fotka": "header/vikendovka.jpg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "header_fotky.fotkaheader",
|
||||
"pk": "vylet.jpg",
|
||||
"fields": {
|
||||
"cas": "2020-09-20T09:18:34.562Z",
|
||||
"fotka": "header/vylet.jpg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "header_fotky.fotkaurlvazba",
|
||||
"pk": 1,
|
||||
"fields": {
|
||||
"url": "/archiv/",
|
||||
"fotka": "stiny.jpg",
|
||||
"denni_doba": "oboji"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "header_fotky.fotkaurlvazba",
|
||||
"pk": 2,
|
||||
"fields": {
|
||||
"url": "/clanky/",
|
||||
"fotka": "kryptografie.jpg",
|
||||
"denni_doba": "den"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "header_fotky.fotkaurlvazba",
|
||||
"pk": 3,
|
||||
"fields": {
|
||||
"url": "/clanky/",
|
||||
"fotka": "ohen.jpg",
|
||||
"denni_doba": "noc"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "header_fotky.fotkaurlvazba",
|
||||
"pk": 4,
|
||||
"fields": {
|
||||
"url": "/aktualni/",
|
||||
"fotka": "baliky.jpg",
|
||||
"denni_doba": "den"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "header_fotky.fotkaurlvazba",
|
||||
"pk": 5,
|
||||
"fields": {
|
||||
"url": "/aktualni/",
|
||||
"fotka": "stiny.jpg",
|
||||
"denni_doba": "noc"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "header_fotky.fotkaurlvazba",
|
||||
"pk": 6,
|
||||
"fields": {
|
||||
"url": "/o-nas/",
|
||||
"fotka": "vikendovka.jpg",
|
||||
"denni_doba": "den"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "header_fotky.fotkaurlvazba",
|
||||
"pk": 7,
|
||||
"fields": {
|
||||
"url": "/o-nas/",
|
||||
"fotka": "noc.jpg",
|
||||
"denni_doba": "noc"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "header_fotky.fotkaurlvazba",
|
||||
"pk": 8,
|
||||
"fields": {
|
||||
"url": "/soustredeni/",
|
||||
"fotka": "beh.jpg",
|
||||
"denni_doba": "den"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "header_fotky.fotkaurlvazba",
|
||||
"pk": 9,
|
||||
"fields": {
|
||||
"url": "/soustredeni/",
|
||||
"fotka": "vylet.jpg",
|
||||
"denni_doba": "noc"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "header_fotky.fotkaurlvazba",
|
||||
"pk": 10,
|
||||
"fields": {
|
||||
"url": "/prihlasit/",
|
||||
"fotka": "baliky.jpg",
|
||||
"denni_doba": "den"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "header_fotky.fotkaurlvazba",
|
||||
"pk": 11,
|
||||
"fields": {
|
||||
"url": "/prihlasit/",
|
||||
"fotka": "stiny.jpg",
|
||||
"denni_doba": "noc"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "header_fotky.fotkaurlvazba",
|
||||
"pk": 12,
|
||||
"fields": {
|
||||
"url": "/profil/",
|
||||
"fotka": "baliky.jpg",
|
||||
"denni_doba": "den"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "header_fotky.fotkaurlvazba",
|
||||
"pk": 13,
|
||||
"fields": {
|
||||
"url": "/profil/",
|
||||
"fotka": "stiny.jpg",
|
||||
"denni_doba": "noc"
|
||||
}
|
||||
}
|
||||
]
|
860
data/sitetree.json
Normal file
|
@ -0,0 +1,860 @@
|
|||
[
|
||||
{
|
||||
"fields": {
|
||||
"alias": "main_menu",
|
||||
"title": "Hlavní menu"
|
||||
},
|
||||
"model": "sitetree.tree",
|
||||
"pk": 1
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [],
|
||||
"access_restricted": false,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": null,
|
||||
"sort_order": 1,
|
||||
"title": "Co je M&M",
|
||||
"tree": 1,
|
||||
"url": "/o-nas/uvod/",
|
||||
"urlaspattern": false
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 1
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [],
|
||||
"access_restricted": false,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": null,
|
||||
"sort_order": 2,
|
||||
"title": "Jak řešit",
|
||||
"tree": 1,
|
||||
"url": "/jak-resit/",
|
||||
"urlaspattern": false
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 2
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [],
|
||||
"access_restricted": false,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": null,
|
||||
"sort_order": 3,
|
||||
"title": "Aktuální<br/> ročník",
|
||||
"tree": 1,
|
||||
"url": "seminar_aktualni_zadani",
|
||||
"urlaspattern": true
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 3
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [],
|
||||
"access_restricted": false,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": null,
|
||||
"sort_order": 4,
|
||||
"title": "Soustředění",
|
||||
"tree": 1,
|
||||
"url": "/soustredeni/",
|
||||
"urlaspattern": false
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 4
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [],
|
||||
"access_restricted": false,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": null,
|
||||
"sort_order": 5,
|
||||
"title": "Archiv",
|
||||
"tree": 1,
|
||||
"url": "seminar_archiv_rocniky",
|
||||
"urlaspattern": true
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 5
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": true,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [],
|
||||
"access_restricted": false,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": null,
|
||||
"sort_order": 6,
|
||||
"title": "Přihlásit",
|
||||
"tree": 1,
|
||||
"url": "login",
|
||||
"urlaspattern": true
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 6
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [],
|
||||
"access_restricted": false,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": 1,
|
||||
"sort_order": 7,
|
||||
"title": "Úvod",
|
||||
"tree": 1,
|
||||
"url": "/o-nas/uvod/",
|
||||
"urlaspattern": false
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 7
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [],
|
||||
"access_restricted": false,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": 1,
|
||||
"sort_order": 8,
|
||||
"title": "Organizátoři",
|
||||
"tree": 1,
|
||||
"url": "organizatori",
|
||||
"urlaspattern": true
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 8
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [],
|
||||
"access_restricted": false,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": 1,
|
||||
"sort_order": 10,
|
||||
"title": "Kontakt",
|
||||
"tree": 1,
|
||||
"url": "/o-nas/kontakt/",
|
||||
"urlaspattern": false
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 10
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [],
|
||||
"access_restricted": false,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": 2,
|
||||
"sort_order": 11,
|
||||
"title": "Úvod",
|
||||
"tree": 1,
|
||||
"url": "/jak-resit/",
|
||||
"urlaspattern": false
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 11
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [],
|
||||
"access_restricted": false,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": 2,
|
||||
"sort_order": 45,
|
||||
"title": "Jak psát článek",
|
||||
"tree": 1,
|
||||
"url": "/jak-resit/jak-psat-clanek/",
|
||||
"urlaspattern": false
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 12
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [],
|
||||
"access_restricted": false,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": 3,
|
||||
"sort_order": 43,
|
||||
"title": "Výsledková listina",
|
||||
"tree": 1,
|
||||
"url": "seminar_aktualni_vysledky",
|
||||
"urlaspattern": true
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 16
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [],
|
||||
"access_restricted": false,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": 4,
|
||||
"sort_order": 18,
|
||||
"title": "Úvod",
|
||||
"tree": 1,
|
||||
"url": "/soustredeni/",
|
||||
"urlaspattern": false
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 18
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [],
|
||||
"access_restricted": false,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": 4,
|
||||
"sort_order": 19,
|
||||
"title": "Připravujeme",
|
||||
"tree": 1,
|
||||
"url": "/soustredeni/pripravujeme/",
|
||||
"urlaspattern": false
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 19
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [],
|
||||
"access_restricted": false,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": 4,
|
||||
"sort_order": 20,
|
||||
"title": "Proběhlo",
|
||||
"tree": 1,
|
||||
"url": "seminar_seznam_soustredeni",
|
||||
"urlaspattern": true
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 20
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": true,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [],
|
||||
"access_restricted": false,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": null,
|
||||
"sort_order": 21,
|
||||
"title": "Profil",
|
||||
"tree": 1,
|
||||
"url": "profil",
|
||||
"urlaspattern": true
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 21
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [],
|
||||
"access_restricted": false,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": 21,
|
||||
"sort_order": 23,
|
||||
"title": "Osobní údaje",
|
||||
"tree": 1,
|
||||
"url": "seminar_resitel_edit",
|
||||
"urlaspattern": true
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 22
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [
|
||||
2
|
||||
],
|
||||
"access_restricted": true,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": 21,
|
||||
"sort_order": 36,
|
||||
"title": "Poslat řešení",
|
||||
"tree": 1,
|
||||
"url": "seminar_nahraj_reseni",
|
||||
"urlaspattern": true
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 23
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [],
|
||||
"access_restricted": false,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": 5,
|
||||
"sort_order": 35,
|
||||
"title": "Témata",
|
||||
"tree": 1,
|
||||
"url": "seminar_archiv_temata",
|
||||
"urlaspattern": true
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 24
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [
|
||||
1
|
||||
],
|
||||
"access_restricted": true,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": null,
|
||||
"sort_order": 28,
|
||||
"title": "HIDDEN",
|
||||
"tree": 1,
|
||||
"url": "/korektury/",
|
||||
"urlaspattern": false
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 28
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [],
|
||||
"access_restricted": false,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": 28,
|
||||
"sort_order": 30,
|
||||
"title": "Aktuální",
|
||||
"tree": 1,
|
||||
"url": "korektury_list",
|
||||
"urlaspattern": true
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 30
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [],
|
||||
"access_restricted": false,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": 28,
|
||||
"sort_order": 31,
|
||||
"title": "Zastaralé",
|
||||
"tree": 1,
|
||||
"url": "korektury_stare_list",
|
||||
"urlaspattern": true
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 31
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [],
|
||||
"access_restricted": false,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": 28,
|
||||
"sort_order": 32,
|
||||
"title": "Nápověda",
|
||||
"tree": 1,
|
||||
"url": "/korektury/help/",
|
||||
"urlaspattern": false
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 32
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [],
|
||||
"access_restricted": false,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": 3,
|
||||
"sort_order": 15,
|
||||
"title": "Aktuální číslo",
|
||||
"tree": 1,
|
||||
"url": "seminar_aktualni_zadani",
|
||||
"urlaspattern": true
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 33
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [],
|
||||
"access_restricted": false,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": 5,
|
||||
"sort_order": 24,
|
||||
"title": "Čísla",
|
||||
"tree": 1,
|
||||
"url": "seminar_archiv_rocniky",
|
||||
"urlaspattern": true
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 35
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [],
|
||||
"access_restricted": false,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": 21,
|
||||
"sort_order": 22,
|
||||
"title": "Úvod",
|
||||
"tree": 1,
|
||||
"url": "profil",
|
||||
"urlaspattern": true
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 36
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [
|
||||
1
|
||||
],
|
||||
"access_restricted": true,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "To, co ŘEŠITELÉ poslali",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": 21,
|
||||
"sort_order": 38,
|
||||
"title": "Došlá řešení",
|
||||
"tree": 1,
|
||||
"url": "odevzdavatko_tabulka",
|
||||
"urlaspattern": true
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 37
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": true,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [],
|
||||
"access_restricted": false,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": 21,
|
||||
"sort_order": 42,
|
||||
"title": "Odhlásit se",
|
||||
"tree": 1,
|
||||
"url": "logout",
|
||||
"urlaspattern": true
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 38
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [
|
||||
1
|
||||
],
|
||||
"access_restricted": true,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": 21,
|
||||
"sort_order": 36,
|
||||
"title": "Nahrát řešení",
|
||||
"tree": 1,
|
||||
"url": "seminar_vloz_reseni",
|
||||
"urlaspattern": true
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 39
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [],
|
||||
"access_restricted": false,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": 5,
|
||||
"sort_order": 40,
|
||||
"title": "Řešitelské články",
|
||||
"tree": 1,
|
||||
"url": "/archiv/clanky",
|
||||
"urlaspattern": false
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 40
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [],
|
||||
"access_restricted": false,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": 1,
|
||||
"sort_order": 41,
|
||||
"title": "Odměny",
|
||||
"tree": 1,
|
||||
"url": "/o-nas/odmeny/",
|
||||
"urlaspattern": false
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 41
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [
|
||||
2
|
||||
],
|
||||
"access_restricted": true,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "To, co jsem JÁ odevzdal",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": 21,
|
||||
"sort_order": 37,
|
||||
"title": "Odevzdaná řešení",
|
||||
"tree": 1,
|
||||
"url": "seminar_resitel_odevzdana_reseni",
|
||||
"urlaspattern": true
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 42
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [],
|
||||
"access_restricted": false,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": 3,
|
||||
"sort_order": 33,
|
||||
"title": "Aktuální ročník",
|
||||
"tree": 1,
|
||||
"url": "seminar_aktualni_rocnik",
|
||||
"urlaspattern": true
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 43
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [],
|
||||
"access_restricted": false,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": 1,
|
||||
"sort_order": 44,
|
||||
"title": "Další aktivity",
|
||||
"tree": 1,
|
||||
"url": "/o-nas/dalsi-akce/",
|
||||
"urlaspattern": false
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 44
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"access_guest": false,
|
||||
"access_loggedin": false,
|
||||
"access_perm_type": 1,
|
||||
"access_permissions": [],
|
||||
"access_restricted": false,
|
||||
"alias": null,
|
||||
"description": "",
|
||||
"hidden": false,
|
||||
"hint": "",
|
||||
"inbreadcrumbs": true,
|
||||
"inmenu": true,
|
||||
"insitetree": true,
|
||||
"parent": 2,
|
||||
"sort_order": 12,
|
||||
"title": "Podrobněji",
|
||||
"tree": 1,
|
||||
"url": "/jak-resit/podrobneji/",
|
||||
"urlaspattern": false
|
||||
},
|
||||
"model": "sitetree.treeitem",
|
||||
"pk": 45
|
||||
}
|
||||
]
|
513
db_compare.py
Executable file
|
@ -0,0 +1,513 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import psycopg2
|
||||
import psycopg2.extras
|
||||
|
||||
OLD_DB = "mam_old"
|
||||
NEW_DB = "mamweb"
|
||||
|
||||
oldconn = psycopg2.connect(f"dbname={OLD_DB}")
|
||||
newconn = psycopg2.connect(f"dbname={NEW_DB}")
|
||||
|
||||
oldcur = oldconn.cursor(cursor_factory=psycopg2.extras.DictCursor)
|
||||
newcur = newconn.cursor(cursor_factory=psycopg2.extras.DictCursor)
|
||||
|
||||
|
||||
# Uses global variables oldcur, newcur!
|
||||
def execute_simple(old_query, new_query=None):
|
||||
if new_query is None:
|
||||
new_query = old_query
|
||||
|
||||
oldcur.execute(old_query)
|
||||
newcur.execute(new_query)
|
||||
|
||||
if oldcur.rowcount != newcur.rowcount:
|
||||
raise ValueError(f"Queries '{old_query}' and '{new_query}' returned different number of rows ({oldcur.rowcount} and {newcur.rowcount})")
|
||||
|
||||
return(oldcur.fetchall(), newcur.fetchall())
|
||||
|
||||
def check_same(old_row, new_row, old_fields, new_fields=None):
|
||||
if type(old_fields) != list:
|
||||
old_fields = [old_fields]
|
||||
|
||||
if new_fields is None:
|
||||
new_fields = old_fields
|
||||
|
||||
fields = zip(old_fields, new_fields)
|
||||
|
||||
for old_field, new_field in fields:
|
||||
if old_row[old_field] == new_row[new_field]:
|
||||
continue
|
||||
raise ValueError(f"Fields '{old_field}'({old_row[old_field]}) and '{new_field}'({new_row[new_field]}) differs for rows \n'{old_row}' and \n'{new_row}'")
|
||||
return True
|
||||
|
||||
def get_user_id_for_org_id(org_id):
|
||||
query = """SELECT auth_user.id FROM auth_user
|
||||
INNER JOIN seminar_osoby ON seminar_osoby.user_id = auth_user.id
|
||||
INNER JOIN seminar_organizator ON seminar_organizator.osoba_id = seminar_osoby.id
|
||||
WHERE seminar_organizator.id = %s """
|
||||
|
||||
newcur.execute(query,(org_id,))
|
||||
return newcur.fetchone()['id']
|
||||
|
||||
|
||||
|
||||
|
||||
def check_skola():
|
||||
old_query = "SELECT * FROM seminar_skoly ORDER BY id"
|
||||
|
||||
old_res, new_res = execute_simple(old_query)
|
||||
res = zip(old_res,new_res)
|
||||
|
||||
for o,n in res:
|
||||
check_same(o,n,['id','aesop_id','izo','nazev','kratky_nazev','ulice','mesto','psc','stat','je_zs','je_ss','poznamka'])
|
||||
|
||||
def check_resitel():
|
||||
old_query = 'SELECT * FROM seminar_resitele ORDER BY id'
|
||||
new_query = '''SELECT seminar_resitele.id, skola_id, rok_maturity, zasilat, seminar_resitele.poznamka,
|
||||
o.jmeno AS jmeno, o.prijmeni AS prijmeni, o.user_id AS user_id, o.pohlavi_muz AS pohlavi_muz, o.email AS email, o.telefon AS telefon, o.datum_narozeni AS datum_narozeni,
|
||||
o.datum_souhlasu_udaje AS datum_souhlasu_udaje, o.datum_souhlasu_zasilani AS datum_souhlasu_zasilani, o.datum_registrace AS datum_prihlaseni, o.ulice AS ulice, o.mesto AS mesto, o.psc AS psc, o.stat AS stat
|
||||
FROM seminar_resitele JOIN seminar_osoby AS o ON seminar_resitele.osoba_id = o.id ORDER BY seminar_resitele.id'''
|
||||
|
||||
old_res, new_res = execute_simple(old_query,new_query)
|
||||
|
||||
res = zip(old_res,new_res)
|
||||
|
||||
fields_osoba = [
|
||||
'jmeno',
|
||||
'prijmeni',
|
||||
'user_id',
|
||||
'pohlavi_muz',
|
||||
#'email', #vyreseno separatne
|
||||
'telefon',
|
||||
'datum_narozeni',
|
||||
'datum_souhlasu_udaje',
|
||||
'datum_souhlasu_zasilani',
|
||||
'datum_prihlaseni',
|
||||
'ulice',
|
||||
'mesto',
|
||||
'psc',
|
||||
'stat',
|
||||
]
|
||||
fields_keep = [
|
||||
'id',
|
||||
'skola_id',
|
||||
'rok_maturity',
|
||||
'zasilat',
|
||||
'poznamka',
|
||||
]
|
||||
fields = fields_keep+fields_osoba
|
||||
for o,n in res:
|
||||
check_same(o,n,fields)
|
||||
if o['email'] != n['email'] and o['email'] != '':
|
||||
print(f"WARNING: Emails differ: old: {o['email']}, new: {n['email']}")
|
||||
|
||||
def check_reseni():
|
||||
# Migrace 0058 zamerne meni (zmensuje) pocet reseni, aby kazdy clanek mel
|
||||
# jen jedno reseni (s vice resiteli, coz postaru neslo)
|
||||
# Kvuli tomu je potreba kontrolovat dve veci:
|
||||
# 1) Ze kazdy resitel dostal za kazdy problem spravne bodu
|
||||
# 2) Ze detaily reseni zustaly zachovany
|
||||
|
||||
# Cast 1)
|
||||
old_query = 'SELECT * FROM seminar_reseni ORDER BY problem_id, resitel_id, body, timestamp'
|
||||
new_query = '''SELECT seminar_reseni.id, forma, seminar_reseni.poznamka, cas_doruceni, hodnoceni.problem_id AS problem_id, hodnoceni.body AS body, hodnoceni.cislo_body_id AS cislo_body_id, res.id AS resitel_id
|
||||
FROM seminar_reseni
|
||||
JOIN seminar_hodnoceni AS hodnoceni ON seminar_reseni.id = hodnoceni.reseni_id
|
||||
JOIN seminar_reseni_resitele AS rr ON seminar_reseni.id = rr.reseni_id
|
||||
JOIN seminar_resitele AS res ON res.id = rr.resitele_id
|
||||
ORDER BY problem_id, resitel_id, body, cas_doruceni'''
|
||||
|
||||
# Po spojeni nekterych problemu se lisi casy doruceni a poznamky, proto je nebudeme kontrolovat (jde v podstate o triviality, tak je to snad jedno)
|
||||
same_fields = ['forma', 'problem_id', 'body', 'cislo_body_id', 'resitel_id']
|
||||
renamed_fields = [
|
||||
#('timestamp', 'cas_doruceni'),
|
||||
]
|
||||
old_fields = same_fields + [f[0] for f in renamed_fields]
|
||||
new_fields = same_fields + [f[1] for f in renamed_fields]
|
||||
|
||||
old_res, new_res = execute_simple(old_query, new_query)
|
||||
|
||||
res = zip(old_res,new_res)
|
||||
|
||||
for o,n in res:
|
||||
check_same(o,n,old_fields, new_fields)
|
||||
|
||||
# Cast 2)
|
||||
# Query se lisi tim, ze uz nejoinujeme resitele.
|
||||
old_query = 'SELECT * FROM seminar_reseni ORDER BY id'
|
||||
new_query = '''SELECT seminar_reseni.id, forma, poznamka, cas_doruceni AS timestamp, h.problem_id AS problem_id, h.body AS body, h.cislo_body_id AS cislo_body_id
|
||||
FROM seminar_reseni
|
||||
JOIN seminar_hodnoceni AS h ON h.reseni_id = seminar_reseni.id
|
||||
ORDER BY id'''
|
||||
|
||||
# execute_simple kontroluje stejnost poctu radku, to nechceme.
|
||||
oldcur.execute(old_query)
|
||||
newcur.execute(new_query)
|
||||
old_res, new_res = oldcur.fetchall(), newcur.fetchall()
|
||||
# Zkontrolujeme, ze pro kazde nove reseni ma stare reseni spravna data.
|
||||
new_ids = [n['id'] for n in new_res]
|
||||
spravna_old = list(filter(lambda o: o['id'] in new_ids, old_res))
|
||||
res = zip(spravna_old,new_res)
|
||||
for o,n in res:
|
||||
# Tady by se poznamky i timestampy mely zachovat
|
||||
# Z nejakeho duvodu se ale poznamky lisi ve whitespace, tak je zkontrolujeme separatne
|
||||
check_same(o,n,['id', 'forma', 'timestamp', 'problem_id', 'body', 'cislo_body_id'])
|
||||
old_pozn = o['poznamka'].strip()
|
||||
new_pozn = n['poznamka'].strip()
|
||||
if old_pozn != new_pozn:
|
||||
raise ValueError('Poznamky se lisi pro radky {dict(o)} a {dict(n)}')
|
||||
|
||||
|
||||
|
||||
def check_organizator():
|
||||
old_query = 'SELECT * FROM seminar_organizator ORDER BY id'
|
||||
new_query = '''SELECT seminar_organizator.id AS id, studuje, strucny_popis_organizatora, users.id AS uid, osoba.prezdivka AS o_prezdivka, osoba.foto AS o_foto, organizuje_od, organizuje_do
|
||||
FROM seminar_organizator
|
||||
JOIN seminar_osoby AS osoba ON osoba_id = osoba.id
|
||||
JOIN auth_user AS users ON osoba.user_id = users.id
|
||||
ORDER BY seminar_organizator.id'''
|
||||
|
||||
same_fields = ['studuje', 'strucny_popis_organizatora']
|
||||
renamed_fields = [
|
||||
('user_id', 'uid'),
|
||||
#('prezdivka', 'o_prezdivka'),
|
||||
('foto', 'o_foto'),
|
||||
]
|
||||
old_fields = same_fields + [f[0] for f in renamed_fields]
|
||||
new_fields = same_fields + [f[1] for f in renamed_fields]
|
||||
|
||||
old_res, new_res = execute_simple(old_query,new_query)
|
||||
res = zip(old_res, new_res)
|
||||
for o,n in res:
|
||||
check_same(o,n,old_fields, new_fields)
|
||||
# organizuje od, do:
|
||||
# Migrace prirazuje aktualni casovou zonu, takze chceme tady rucne vynutit CET.
|
||||
from datetime import timedelta, timezone
|
||||
cet = timezone(timedelta(hours=1))
|
||||
if o['organizuje_od_roku'] is None and n['organizuje_od'] is None:
|
||||
pass
|
||||
elif o['organizuje_od_roku'] != n['organizuje_od'].astimezone(cet).year:
|
||||
raise ValueError(f'Not matching organizuje_od for org id={o["id"]}: old {o["organizuje_od_roku"]}, new {n["organizuje_od"]}')
|
||||
if o['organizuje_do_roku'] is None and n['organizuje_do'] is None:
|
||||
pass
|
||||
elif o['organizuje_do_roku'] != n['organizuje_do'].astimezone(cet).year:
|
||||
raise ValueError(f'Not matching organizuje_do for org id={o["id"]}: old {o["organizuje_do_roku"]}, new {n["organizuje_do"]}')
|
||||
if o['prezdivka'] == n['o_prezdivka']:
|
||||
continue
|
||||
if o['prezdivka'] is None and n['o_prezdivka'] == '':
|
||||
continue
|
||||
raise ValueError(f'Not matching prezdivka for org id={o["id"]}: old {o["prezdivka"]}, new {n["o_prezdivka"]}')
|
||||
|
||||
|
||||
def check_rocnik():
|
||||
old_query = "SELECT * FROM seminar_rocniky ORDER BY id"
|
||||
|
||||
old_res, new_res = execute_simple(old_query)
|
||||
res = zip(old_res,new_res)
|
||||
|
||||
for o,n in res:
|
||||
check_same(o,n,['id','prvni_rok', 'rocnik', 'exportovat'])
|
||||
|
||||
def check_cislo():
|
||||
old_query = "SELECT * FROM seminar_cisla ORDER BY id"
|
||||
|
||||
old_res, new_res = execute_simple(old_query)
|
||||
res = zip(old_res,new_res)
|
||||
|
||||
for o,n in res:
|
||||
check_same(o,n, ['id','rocnik_id','cislo', 'datum_vydani','datum_deadline','verejne','poznamka','pdf'],
|
||||
['id','rocnik_id','poradi','datum_vydani','datum_deadline','verejne','poznamka','pdf'])
|
||||
|
||||
def check_priloha_reseni():
|
||||
old_query = "SELECT * FROM seminar_priloha_reseni"
|
||||
|
||||
old_res, new_res = execute_simple(old_query)
|
||||
res = zip(old_res,new_res)
|
||||
|
||||
for o,n in res:
|
||||
check_same(o,n, ['id','reseni_id', 'timestamp', 'soubor', 'poznamka'],
|
||||
['id','reseni_id', 'vytvoreno', 'soubor', 'poznamka'])
|
||||
|
||||
def check_soustredeni():
|
||||
old_query = "SELECT * FROM seminar_soustredeni ORDER BY id"
|
||||
|
||||
old_res, new_res = execute_simple(old_query)
|
||||
res = zip(old_res,new_res)
|
||||
|
||||
for o,n in res:
|
||||
check_same(o,n,['id','rocnik_id','datum_zacatku','datum_konce','verejne','misto','text','typ','exportovat'])
|
||||
#Kontrola ucasnici, organizatori v samostatnych funkcich
|
||||
|
||||
def check_soustredeni_ucastnici():
|
||||
old_query = "SELECT * FROM seminar_soustredeni_ucastnici ORDER BY id"
|
||||
|
||||
old_res, new_res = execute_simple(old_query)
|
||||
res = zip(old_res,new_res)
|
||||
|
||||
for o,n in res:
|
||||
check_same(o,n,['id','resitel_id','soustredeni_id','poznamka'])
|
||||
|
||||
def check_soustredeni_organizatori():
|
||||
old_query = "SELECT * FROM seminar_soustredeni_organizatori ORDER BY id"
|
||||
|
||||
old_res, new_res = execute_simple(old_query)
|
||||
res = zip(old_res,new_res)
|
||||
|
||||
for o,n in res:
|
||||
check_same(o,n,['id','organizator_id','soustredeni_id','poznamka'])
|
||||
|
||||
def check_nastaveni():
|
||||
old_query = "SELECT * FROM seminar_nastaveni ORDER BY id"
|
||||
|
||||
old_res, new_res = execute_simple(old_query)
|
||||
res = zip(old_res,new_res)
|
||||
|
||||
for o,n in res:
|
||||
check_same(o,n,['id','aktualni_cislo_id'])
|
||||
|
||||
def check_novinky():
|
||||
old_query = "SELECT * FROM seminar_novinky ORDER BY id"
|
||||
|
||||
old_res, new_res = execute_simple(old_query)
|
||||
res = zip(old_res,new_res)
|
||||
|
||||
for o,n in res:
|
||||
check_same(o,n,['id','datum','text','obrazek','zverejneno'])
|
||||
if get_user_id_for_org_id(n['autor_id']) != o['autor_id']:
|
||||
raise ValueError("Nesedi autori u novinek")
|
||||
|
||||
def check_pohadka():
|
||||
old_query = "SELECT * FROM seminar_pohadky ORDER BY id"
|
||||
new_query = """SELECT sp.id AS id, sp.autor_id AS autor_id, sp.vytvoreno AS vytvoreno, snp.treenode_ptr_id AS treenode_ptr_id, st.na_web AS text,
|
||||
zn_pred.uloha_id AS uloha_pred, zn_po.uloha_id AS uloha_po
|
||||
FROM seminar_pohadky AS sp
|
||||
-- Text pohádky
|
||||
INNER JOIN seminar_nodes_pohadka AS snp ON sp.id = snp.pohadka_id
|
||||
INNER JOIN seminar_nodes_treenode AS snt ON snt.id = snp.treenode_ptr_id
|
||||
INNER JOIN seminar_nodes_obsah AS sno ON sno.treenode_ptr_id = snt.first_child_id
|
||||
INNER JOIN seminar_texty AS st ON sno.text_id = st.id
|
||||
-- Predchozí úloha
|
||||
LEFT OUTER JOIN seminar_nodes_treenode AS ztn_pred ON ztn_pred.succ_id = snt.id
|
||||
LEFT OUTER JOIN seminar_nodes_uloha_zadani AS zn_pred ON zn_pred.treenode_ptr_id = ztn_pred.id
|
||||
-- Následující úloha
|
||||
LEFT OUTER JOIN seminar_nodes_uloha_zadani AS zn_po ON zn_po.treenode_ptr_id = snt.succ_id
|
||||
|
||||
ORDER BY sp.id"""
|
||||
|
||||
old_res, new_res = execute_simple(old_query,new_query)
|
||||
res = zip(old_res,new_res)
|
||||
|
||||
for o,n in res:
|
||||
check_same(o,n,['id','timestamp','text'],['id','vytvoreno','text'])
|
||||
if o['autor_id'] is not None:
|
||||
if get_user_id_for_org_id(n['autor_id']) != o['autor_id']:
|
||||
raise ValueError("Nesedi autori u pohadky")
|
||||
# Správné úlohy
|
||||
# NOTE: o['pred'] rika, zda je pohadka pred ulohou, nikoliv zda je relevantni uloha pred pohadkou!
|
||||
spravny_klic = 'uloha_po' if o['pred'] else 'uloha_pred'
|
||||
if o['uloha_id'] != n[spravny_klic]:
|
||||
raise ValueError(f"Pohádka přidružená ke špatné úloze! old: {o['uloha_id']}, new: {n[spravny_klic]}, pozice: {spravny_klic}")
|
||||
|
||||
|
||||
# Problémy jsou rozdělené podle typů:
|
||||
def check_problem_common():
|
||||
old_query = "SELECT id, nazev, stav, kod, autor_id, text_org, timestamp, typ FROM seminar_problemy ORDER BY id"
|
||||
new_query = """SELECT sp.id AS id, sp.nazev AS nazev, sp.stav AS stav, sp.kod AS kod, au.id AS autor_id, sp.poznamka AS poznamka, sp.vytvoreno AS vytvoreno
|
||||
FROM seminar_problemy AS sp
|
||||
LEFT OUTER JOIN seminar_organizator AS so ON sp.autor_id = so.id
|
||||
LEFT OUTER JOIN seminar_osoby AS sos ON so.osoba_id = sos.id
|
||||
LEFT OUTER JOIN auth_user AS au ON sos.user_id = au.id
|
||||
ORDER BY sp.id"""
|
||||
|
||||
same_fields = ['id', 'nazev', 'stav', 'autor_id', 'kod']
|
||||
renamed_fields = [
|
||||
('text_org', 'poznamka'),
|
||||
('timestamp', 'vytvoreno'),
|
||||
]
|
||||
old_fields = same_fields + [f[0] for f in renamed_fields]
|
||||
new_fields = same_fields + [f[1] for f in renamed_fields]
|
||||
|
||||
old_res, new_res = execute_simple(old_query,new_query)
|
||||
res = zip(old_res,new_res)
|
||||
|
||||
for o,n in res:
|
||||
check_same(o,n, old_fields, new_fields)
|
||||
|
||||
# Opravovatelé
|
||||
# Po staru byli opravovatele organizatori, takze je potreba je dohledat.
|
||||
old_query = """SELECT seminar_problemy.id, org.id AS opravovatel_id FROM seminar_problemy
|
||||
JOIN seminar_organizator AS org ON seminar_problemy.opravovatel_id = org.user_id;"""
|
||||
new_query = "SELECT problem_id, organizator_id FROM seminar_problemy_opravovatele"
|
||||
|
||||
# Simple cursors
|
||||
#oldcur = oldconn.cursor()
|
||||
oldcur.execute(old_query)
|
||||
old_results = oldcur.fetchall()
|
||||
#newcur = newconn.cursor()
|
||||
newcur.execute(new_query)
|
||||
new_results = newcur.fetchall()
|
||||
|
||||
for oldr in old_results:
|
||||
if oldr not in new_results:
|
||||
raise ValueError(f'Opravovatel pair {oldr} not found in new db.')
|
||||
|
||||
# Zaměření se vyřeší okometricky (#1186)
|
||||
|
||||
|
||||
def check_uloha():
|
||||
old_query = "SELECT * FROM seminar_problemy WHERE typ = 'uloha' ORDER BY id"
|
||||
new_query = """SELECT cislo_zadani_id, cislo_reseni_id, problem_ptr_id, max_body, COALESCE(uzt.na_web, '') AS text_zadani, COALESCE(uvt.na_web, '') AS text_reseni, cislo_deadline_id
|
||||
FROM seminar_ulohy
|
||||
-- Problém:
|
||||
JOIN seminar_problemy AS problem ON problem_ptr_id = problem.id
|
||||
-- Text zadání:
|
||||
-- ZadaniNode a VzorakNode maji existovat vzdy, ale obsah nemusi (pokud ho nemaji)
|
||||
INNER JOIN seminar_nodes_uloha_zadani AS uzn ON problem.id = uzn.uloha_id
|
||||
INNER JOIN seminar_nodes_treenode AS uztn ON uztn.id = uzn.treenode_ptr_id
|
||||
LEFT OUTER JOIN seminar_nodes_obsah AS uzo ON uzo.treenode_ptr_id = uztn.first_child_id
|
||||
LEFT OUTER JOIN seminar_texty AS uzt ON uzo.text_id = uzt.id
|
||||
-- Text vzoráku:
|
||||
INNER JOIN seminar_nodes_uloha_vzorak AS uvn ON problem.id = uvn.uloha_id
|
||||
INNER JOIN seminar_nodes_treenode AS uvtn ON uvtn.id = uvn.treenode_ptr_id
|
||||
LEFT OUTER JOIN seminar_nodes_obsah AS uvo ON uvo.treenode_ptr_id = uvtn.first_child_id
|
||||
LEFT OUTER JOIN seminar_texty AS uvt ON uvo.text_id = uvt.id
|
||||
|
||||
ORDER BY problem_ptr_id"""
|
||||
|
||||
same_fields = ['cislo_zadani_id', 'cislo_reseni_id', 'text_zadani', 'text_reseni']
|
||||
renamed_fields = [
|
||||
('id', 'problem_ptr_id'),
|
||||
('body', 'max_body'),
|
||||
]
|
||||
old_fields = same_fields + [f[0] for f in renamed_fields]
|
||||
new_fields = same_fields + [f[1] for f in renamed_fields]
|
||||
|
||||
old_res, new_res = execute_simple(old_query, new_query)
|
||||
res = zip(old_res,new_res)
|
||||
|
||||
for o,n in res:
|
||||
check_same(o,n, old_fields, new_fields)
|
||||
# Datum deadline vypadá prázdně, tak to budeme předpokládat.
|
||||
if n['cislo_deadline_id'] is not None:
|
||||
raise ValueError("Úloha má deadline.")
|
||||
|
||||
def check_tema():
|
||||
old_query = """SELECT text_zadani, text_reseni, typ, c.rocnik_id AS rocnik_id
|
||||
FROM seminar_problemy
|
||||
LEFT OUTER JOIN seminar_cisla AS c ON c.id = cislo_zadani_id
|
||||
WHERE typ IN ('tema', 'serial')
|
||||
ORDER BY seminar_problemy.id"""
|
||||
new_query = """SELECT tema_typ, COALESCE(zad_text.na_web, '') AS text_zadani, COALESCE(res_text.na_web, '') AS text_reseni, rn.rocnik_id AS rocnik_id
|
||||
FROM seminar_temata
|
||||
-- Problém:
|
||||
JOIN seminar_problemy AS problem ON problem_ptr_id = problem.id
|
||||
-- Text:
|
||||
-- TvCNode má dva potomky, oba TextNode. První drží původní text zadání, druhý řešení.
|
||||
INNER JOIN seminar_nodes_temavcisle AS tvcn ON tvcn.tema_id = id
|
||||
INNER JOIN seminar_nodes_treenode AS ttn ON tvcn.treenode_ptr_id = ttn.id
|
||||
LEFT OUTER JOIN seminar_nodes_treenode AS zad_tn ON ttn.first_child_id = zad_tn.id -- jen 33 z nich ma zadani
|
||||
LEFT OUTER JOIN seminar_nodes_treenode AS res_tn ON zad_tn.succ_id = res_tn.id -- jen 4 z nich ma reseni
|
||||
LEFT OUTER JOIN seminar_nodes_obsah AS zad_on ON zad_on.treenode_ptr_id = zad_tn.id
|
||||
LEFT OUTER JOIN seminar_nodes_obsah AS res_on ON res_on.treenode_ptr_id = res_tn.id
|
||||
LEFT OUTER JOIN seminar_texty AS zad_text ON zad_on.text_id = zad_text.id
|
||||
LEFT OUTER JOIN seminar_texty AS res_text ON res_on.text_id = res_text.id -- vsechny 4
|
||||
-- Ročník tématu:
|
||||
-- Podle rootu TvCN
|
||||
LEFT OUTER JOIN seminar_nodes_rocnik AS rn ON ttn.root_id = rn.treenode_ptr_id
|
||||
|
||||
ORDER BY problem_ptr_id"""
|
||||
same_fields = ['text_zadani', 'text_reseni', 'rocnik_id']
|
||||
renamed_fields = [
|
||||
('typ', 'tema_typ'),
|
||||
]
|
||||
old_fields = same_fields + [f[0] for f in renamed_fields]
|
||||
new_fields = same_fields + [f[1] for f in renamed_fields]
|
||||
|
||||
old_res, new_res = execute_simple(old_query, new_query)
|
||||
res = zip(old_res,new_res)
|
||||
|
||||
for o,n in res:
|
||||
check_same(o,n, old_fields, new_fields)
|
||||
|
||||
def check_konfera():
|
||||
old_query = "SELECT * FROM seminar_problemy WHERE typ = 'konfera'"
|
||||
new_query = "SELECT * FROM seminar_konfera"
|
||||
|
||||
oldcur.execute(old_query)
|
||||
newcur.execute(new_query)
|
||||
|
||||
if oldcur.rowcount != 0 or newcur.rowcount != 0:
|
||||
raise ValueError('There exists a Konfera!')
|
||||
|
||||
def check_org_clanek():
|
||||
old_query = "SELECT * FROM seminar_problemy WHERE typ = 'org-clanek'"
|
||||
|
||||
oldcur.execute(old_query)
|
||||
|
||||
if oldcur.rowcount != 0:
|
||||
raise ValueError('There exists a Org-clanek!')
|
||||
|
||||
def check_res_clanek():
|
||||
# Dva(!) články mají text (zadání), který se má zachovat.
|
||||
old_query = "SELECT * FROM seminar_problemy WHERE typ = 'res-clanek' ORDER BY id"
|
||||
new_query = """SELECT cislo_id, text.na_web AS text_zadani
|
||||
FROM seminar_clanky
|
||||
JOIN seminar_problemy AS problem ON problem_ptr_id = problem.id
|
||||
INNER JOIN seminar_hodnoceni AS hodn ON problem.id = hodn.problem_id
|
||||
INNER JOIN seminar_reseni AS rese ON rese.id = hodn.reseni_id
|
||||
INNER JOIN seminar_nodes_otistene_reseni AS rn ON rese.text_cely_id = rn.treenode_ptr_id -- Tenhle radek neni potreba, ale ujistuje se mj. o spravnem typu TreeNode.
|
||||
INNER JOIN seminar_nodes_treenode AS tn ON rn.treenode_ptr_id = tn.id
|
||||
-- Nektere clanky vubec nemely text, tak jim migr 0058 nevyrobila dalsi treenody
|
||||
LEFT OUTER JOIN seminar_nodes_obsah AS son ON son.treenode_ptr_id = tn.first_child_id
|
||||
LEFT OUTER JOIN seminar_texty AS text ON text.id = son.text_id
|
||||
|
||||
ORDER BY problem_ptr_id"""
|
||||
same_fields = ['text_zadani']
|
||||
renamed_fields = [
|
||||
('cislo_zadani_id', 'cislo_id'),
|
||||
]
|
||||
old_fields = same_fields + [f[0] for f in renamed_fields]
|
||||
new_fields = same_fields + [f[1] for f in renamed_fields]
|
||||
|
||||
old_res, new_res = execute_simple(old_query, new_query)
|
||||
res = zip(old_res,new_res)
|
||||
|
||||
for o,n in res:
|
||||
# text_zadani po novu mohl byt None
|
||||
if n['text_zadani'] is None:
|
||||
n['text_zadani'] = ''
|
||||
check_same(o,n, old_fields, new_fields)
|
||||
assert(o['text_reseni'] == '')
|
||||
|
||||
def check_untyped_problem():
|
||||
old_query = "SELECT * FROM seminar_problemy WHERE typ NOT IN ('uloha', 'tema', 'serial', 'konfera', 'org-clanek', 'res-clanek')"
|
||||
|
||||
oldcur.execute(old_query)
|
||||
|
||||
if oldcur.rowcount != 0:
|
||||
raise ValueError('There exists a Problem without type!')
|
||||
|
||||
|
||||
|
||||
check_skola()
|
||||
check_resitel()
|
||||
check_reseni()
|
||||
check_organizator()
|
||||
check_rocnik()
|
||||
check_cislo()
|
||||
check_priloha_reseni()
|
||||
check_soustredeni()
|
||||
check_soustredeni_ucastnici()
|
||||
check_soustredeni_organizatori()
|
||||
check_nastaveni()
|
||||
check_novinky()
|
||||
check_pohadka()
|
||||
|
||||
check_problem_common()
|
||||
check_uloha()
|
||||
check_tema()
|
||||
check_konfera()
|
||||
check_org_clanek()
|
||||
check_res_clanek()
|
||||
check_untyped_problem()
|
3
deploy_v2/README
Normal file
|
@ -0,0 +1,3 @@
|
|||
Tahle slozka obsahuje vsechny detaily a popisy, jak nasadit "druhou verzi" M&M webu.
|
||||
|
||||
TODO: chybi tu popis na zprovozneni flatpages, na loaddata &c.
|
22
deploy_v2/full_redeploy.sh
Normal file
|
@ -0,0 +1,22 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -u
|
||||
|
||||
deactivate || true
|
||||
|
||||
cd /akce/mam/www/mamweb-test/
|
||||
make sync_test
|
||||
systemctl --user stop mamweb-test.service
|
||||
rm -rvf env
|
||||
make install_venv
|
||||
. env/bin/activate
|
||||
make install
|
||||
deploy_v2/pre_migration.py
|
||||
make deploy_test
|
||||
./manage.py load_org_permissions admin_org_prava.json
|
||||
./manage.py loaddata data/*
|
||||
systemctl --user start mamweb-test.service
|
||||
./manage.py generate_thumbnails
|
||||
|
||||
echo 'Et voilá!'
|
||||
echo 'Nezapomeň opravit práva pro sitetree!'
|
3
deploy_v2/post_deploy.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
Jsou špatně práva k sitetree (protože se používají primární klíče, které jsou jiné :-()
|
||||
Špatné položky se dají najít pomocí následujícího příkazu:
|
||||
grep -E 'access_permissions": \[$' data/sitetree.json -A17 | grep -E 'acc|tit' -A2
|
42
deploy_v2/pre_migration.py
Executable file
|
@ -0,0 +1,42 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import django
|
||||
|
||||
#### Inicializace Djanga
|
||||
sys.path.append(os.path.dirname(os.path.realpath(__file__))+'/..')
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mamweb.settings')
|
||||
django.setup()
|
||||
|
||||
## Pozor, nejde pouzit ORM, protoze kod je na jine verzi nez databaze a nejde namigrovat.
|
||||
from django.db import connection
|
||||
|
||||
|
||||
def smaz_zle_clanky():
|
||||
# Tyhle clanky vubec nejsou clanky, bude potreba je udelat cele jinak a spravne.
|
||||
#m.Problem.objects.filter(id__in=[1981, 1970, 2222]).delete()
|
||||
## with connection.cursor() as cursor:
|
||||
## # Nejdriv musime smazat reseni:
|
||||
## cursor.execute('DELETE FROM seminar_reseni WHERE problem_id IN (1981, 1970, 2222);')
|
||||
## # Nakonec i ty clanky samotne
|
||||
## cursor.execute('DELETE FROM seminar_problemy WHERE id IN (1981, 1970, 2222);')
|
||||
|
||||
# Update: stejně je v DB bordel, tak z nich prostě jen udělám témata a všechno zhruba přežije…
|
||||
with connection.cursor() as cursor:
|
||||
cursor.execute("UPDATE seminar_problemy SET typ = 'tema' WHERE id IN (1981, 1970, 2222);")
|
||||
|
||||
def smaz_divne_uzivatele():
|
||||
# U techto uzivatelu neexistuje Organizator s nimi spojeny
|
||||
# Takze pak delaji akorat neporadek
|
||||
with connection.cursor() as cursor:
|
||||
# Jeste je potreba zrusit vazby
|
||||
cursor.execute('UPDATE django_comments SET user_id = NULL WHERE user_id = 34;')
|
||||
cursor.execute('UPDATE seminar_problemy SET autor_id = NULL WHERE autor_id = 34;')
|
||||
cursor.execute('DELETE FROM django_admin_log WHERE user_id = 34;')
|
||||
cursor.execute('DELETE FROM auth_user_groups WHERE user_id = 34;')
|
||||
cursor.execute('DELETE FROM auth_user WHERE id IN (34, 40, 30, 50, 54, 58, 43);')
|
||||
|
||||
smaz_zle_clanky()
|
||||
smaz_divne_uzivatele()
|
12
fix_json.py
Executable file
|
@ -0,0 +1,12 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
import json
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("input", type=argparse.FileType('r', encoding='utf-8'))
|
||||
parser.add_argument('output', type=argparse.FileType('w', encoding='utf-8'))
|
||||
args = parser.parse_args()
|
||||
|
||||
data = json.load(args.input)
|
||||
json.dump(data, args.output, ensure_ascii=False, sort_keys=True, indent='\t')
|
|
@ -5,50 +5,50 @@ from django.contrib import admin
|
|||
from django.http import HttpResponseRedirect
|
||||
from django import forms
|
||||
from django.db import models
|
||||
from autocomplete_light import shortcuts as autocomplete_light
|
||||
|
||||
# akction
|
||||
|
||||
def zverejnit_fotogalerii(modeladmin, request, queryset):
|
||||
'''zverejni vybranou fotogalerii i jeji vsechny podgalerie'''
|
||||
for galerie in queryset:
|
||||
galerie.zobrazit = 0
|
||||
galerie.save()
|
||||
zverejnit_fotogalerii(modeladmin, request,
|
||||
Galerie.objects.filter(galerie_up = galerie))
|
||||
zverejnit_fotogalerii.short_description = 'Zveřejnit fotogalerie'
|
||||
'''zverejni vybranou fotogalerii i jeji vsechny podgalerie'''
|
||||
for galerie in queryset:
|
||||
galerie.zobrazit = 0
|
||||
galerie.save()
|
||||
zverejnit_fotogalerii(modeladmin, request,
|
||||
Galerie.objects.filter(galerie_up = galerie))
|
||||
zverejnit_fotogalerii.short_description = 'Zveřejnit fotogalerie'
|
||||
|
||||
|
||||
def prepnout_fotogalerii_do_org_rezimu(modeladmin, request, queryset):
|
||||
'''zneverjni vybranou fotogalerii i jeji vsechny podgalerie'''
|
||||
for galerie in queryset:
|
||||
galerie.zobrazit = 1
|
||||
galerie.save()
|
||||
prepnout_fotogalerii_do_org_rezimu(modeladmin, request,
|
||||
Galerie.objects.filter(galerie_up = galerie))
|
||||
prepnout_fotogalerii_do_org_rezimu.short_description = \
|
||||
'Přepnout do režimu úprav (zneveřejní galerii)'
|
||||
'''zneverjni vybranou fotogalerii i jeji vsechny podgalerie'''
|
||||
for galerie in queryset:
|
||||
galerie.zobrazit = 1
|
||||
galerie.save()
|
||||
prepnout_fotogalerii_do_org_rezimu(modeladmin, request,
|
||||
Galerie.objects.filter(galerie_up = galerie))
|
||||
prepnout_fotogalerii_do_org_rezimu.short_description = \
|
||||
'Přepnout do režimu úprav (zneveřejní galerii)'
|
||||
|
||||
class GalerieInline(admin.TabularInline):
|
||||
model = Obrazek
|
||||
fields = ['obrazek_velky', 'nazev', 'popis', 'obrazek_maly_tag', 'poradi']
|
||||
readonly_fields = ['nazev', 'obrazek_maly_tag']
|
||||
formfield_overrides = {
|
||||
models.TextField: {'widget': forms.TextInput},
|
||||
}
|
||||
model = Obrazek
|
||||
fields = ['obrazek_velky', 'nazev', 'popis', 'obrazek_maly_tag', 'poradi']
|
||||
readonly_fields = ['nazev', 'obrazek_maly_tag']
|
||||
formfield_overrides = {
|
||||
models.TextField: {'widget': forms.TextInput},
|
||||
}
|
||||
|
||||
class ObrazekAdmin(admin.ModelAdmin):
|
||||
list_display = ('obrazek_velky', 'nazev', 'popis', 'obrazek_maly_tag', 'poradi')
|
||||
|
||||
list_display = ('obrazek_velky', 'nazev', 'popis', 'obrazek_maly_tag', 'poradi')
|
||||
search_fields = ['nazev','popis']
|
||||
|
||||
class GalerieAdmin(admin.ModelAdmin):
|
||||
form = autocomplete_light.modelform_factory(Galerie, autocomplete_fields=['titulni_obrazek'], fields=['titulni_obrazek'])
|
||||
model = Galerie
|
||||
fields = ('zobrazit', 'nazev', 'titulni_obrazek', 'popis', 'galerie_up', 'soustredeni', 'poradi')
|
||||
list_display = ('nazev', 'soustredeni', 'galerie_up', 'poradi', 'zobrazit', 'datum_zmeny')
|
||||
inlines = [GalerieInline]
|
||||
actions = [zverejnit_fotogalerii, prepnout_fotogalerii_do_org_rezimu]
|
||||
save_on_top = True
|
||||
ordering = ['galerie_up__nazev', 'poradi']
|
||||
model = Galerie
|
||||
fields = ('zobrazit', 'nazev', 'titulni_obrazek', 'popis', 'galerie_up', 'soustredeni', 'poradi')
|
||||
autocomplete_fields = ['titulni_obrazek']
|
||||
list_display = ('nazev', 'soustredeni', 'galerie_up', 'poradi', 'zobrazit', 'datum_zmeny')
|
||||
inlines = [GalerieInline]
|
||||
actions = [zverejnit_fotogalerii, prepnout_fotogalerii_do_org_rezimu]
|
||||
save_on_top = True
|
||||
ordering = ['galerie_up__nazev', 'poradi']
|
||||
|
||||
admin.site.register(Obrazek, ObrazekAdmin)
|
||||
admin.site.register(Galerie, GalerieAdmin)
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from autocomplete_light import shortcuts as autocomplete_light
|
||||
|
||||
from models import Obrazek, Galerie
|
||||
from views import cesta_od_korene
|
||||
from .models import Obrazek, Galerie
|
||||
from .views import cesta_od_korene
|
||||
|
||||
|
||||
class ObrazekAutocomplete(autocomplete_light.AutocompleteModelBase):
|
|
@ -4,8 +4,8 @@ from django import forms
|
|||
from seminar.models import Soustredeni
|
||||
|
||||
class KomentarForm(forms.Form):
|
||||
komentar = forms.CharField(label = "Komentář:", max_length = 300, required=False)
|
||||
komentar = forms.CharField(label = "Komentář:", max_length = 300, required=False)
|
||||
|
||||
class NewGalerieForm(forms.Form):
|
||||
nazev = forms.CharField(label = "Název galerie", max_length = 100)
|
||||
#popis = forms.CharField(label = "Popis", required = False, max_length = 2000, widget = forms.Textarea)
|
||||
nazev = forms.CharField(label = "Název galerie", max_length = 100)
|
||||
#popis = forms.CharField(label = "Popis", required = False, max_length = 2000, widget = forms.Textarea)
|
||||
|
|
|
@ -21,8 +21,8 @@ class Migration(migrations.Migration):
|
|||
('datum_zmeny', models.DateTimeField(auto_now=True, verbose_name=b'Datum posledn\xc3\xad zm\xc4\x9bny')),
|
||||
('popis', models.TextField(null=True, verbose_name=b'Popis', blank=True)),
|
||||
('zobrazit', models.IntegerField(default=1, verbose_name=b'Zobrazit?', choices=[(0, b'V\xc5\xbedy'), (1, b'Organiz\xc3\xa1tor\xc5\xafm'), (2, b'Nikdy')])),
|
||||
('galerie_up', models.ForeignKey(blank=True, to='galerie.Galerie', null=True)),
|
||||
('soustredeni', models.ForeignKey(blank=True, to='seminar.Soustredeni', null=True)),
|
||||
('galerie_up', models.ForeignKey(blank=True, to='galerie.Galerie', null=True, on_delete=models.CASCADE)),
|
||||
('soustredeni', models.ForeignKey(blank=True, to='seminar.Soustredeni', null=True, on_delete=models.CASCADE)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Galerie',
|
||||
|
@ -42,7 +42,7 @@ class Migration(migrations.Migration):
|
|||
('datum_vlozeni', models.DateTimeField(auto_now_add=True, verbose_name=b'Datum vlo\xc5\xbeen\xc3\xad')),
|
||||
('datum', models.DateTimeField(verbose_name=b'Datum po\xc5\x99\xc3\xadzen\xc3\xad fotografie')),
|
||||
('poradi', models.IntegerField(null=True, verbose_name=b'Po\xc5\x99ad\xc3\xad', blank=True)),
|
||||
('galerie', models.ForeignKey(to='galerie.Galerie')),
|
||||
('galerie', models.ForeignKey(to='galerie.Galerie', on_delete=models.CASCADE)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Obr\xe1zek',
|
||||
|
|
|
@ -14,7 +14,7 @@ class Migration(migrations.Migration):
|
|||
migrations.AlterField(
|
||||
model_name='obrazek',
|
||||
name='galerie',
|
||||
field=models.ForeignKey(blank=True, to='galerie.Galerie', null=True),
|
||||
field=models.ForeignKey(blank=True, to='galerie.Galerie', null=True, on_delete=models.CASCADE),
|
||||
preserve_default=True,
|
||||
),
|
||||
]
|
||||
|
|
71
galerie/migrations/0008_auto_20190430_2340.py
Normal file
|
@ -0,0 +1,71 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.20 on 2019-04-30 21:40
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import galerie.models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('galerie', '0007_obrazek_odstranen_datum'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='galerie',
|
||||
name='datum_vytvoreni',
|
||||
field=models.DateTimeField(auto_now_add=True, verbose_name='Datum vytvoření'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='galerie',
|
||||
name='datum_zmeny',
|
||||
field=models.DateTimeField(auto_now=True, verbose_name='Datum poslední změny'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='galerie',
|
||||
name='nazev',
|
||||
field=models.CharField(max_length=100, verbose_name='Název'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='galerie',
|
||||
name='popis',
|
||||
field=models.TextField(blank=True, null=True, verbose_name='Popis'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='galerie',
|
||||
name='poradi',
|
||||
field=models.IntegerField(blank=True, null=True, verbose_name='Pořadí'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='galerie',
|
||||
name='zobrazit',
|
||||
field=models.IntegerField(choices=[(0, 'Vždy'), (1, 'Organizátorům'), (2, 'Nikdy')], default=1, verbose_name='Zobrazit?'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='obrazek',
|
||||
name='datum_vlozeni',
|
||||
field=models.DateTimeField(auto_now_add=True, verbose_name='Datum vložení'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='obrazek',
|
||||
name='nazev',
|
||||
field=models.CharField(blank=True, max_length=50, null=True, verbose_name='Název'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='obrazek',
|
||||
name='obrazek_velky',
|
||||
field=models.ImageField(help_text='Lze vložit libovolně velký obrázek. Ideální je, aby alespoň jeden rozměr měl alespoň 500px.', upload_to=galerie.models.obrazek_filename),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='obrazek',
|
||||
name='popis',
|
||||
field=models.TextField(blank=True, null=True, verbose_name='Popis'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='obrazek',
|
||||
name='poradi',
|
||||
field=models.IntegerField(blank=True, null=True, verbose_name='Pořadí'),
|
||||
),
|
||||
]
|
31
galerie/migrations/0009_auto_20190610_2358.py
Normal file
|
@ -0,0 +1,31 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.21 on 2019-06-10 21:58
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('galerie', '0008_auto_20190430_2340'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='galerie',
|
||||
name='galerie_up',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='galerie.Galerie'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='galerie',
|
||||
name='soustredeni',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Soustredeni'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='obrazek',
|
||||
name='galerie',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='galerie.Galerie'),
|
||||
),
|
||||
]
|
|
@ -1,6 +1,4 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.26 on 2019-12-09 22:26
|
||||
from __future__ import unicode_literals
|
||||
# Generated by Django 2.2.15 on 2020-08-19 07:47
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
@ -8,13 +6,13 @@ from django.db import migrations, models
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('galerie', '0007_obrazek_odstranen_datum'),
|
||||
('galerie', '0009_auto_20190610_2358'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='galerie',
|
||||
name='poradi',
|
||||
field=models.IntegerField(blank=True, default=0, verbose_name=b'Po\xc5\x99ad\xc3\xad'),
|
||||
field=models.IntegerField(blank=True, default=0, verbose_name='Pořadí'),
|
||||
),
|
||||
]
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
from django.db import models
|
||||
#from django.db.models import Q
|
||||
from django.utils.encoding import force_unicode
|
||||
from django.utils.encoding import force_text
|
||||
from imagekit.models import ImageSpecField
|
||||
from imagekit.processors import ResizeToFit, Transpose
|
||||
|
||||
|
@ -14,109 +14,112 @@ VZDY=0
|
|||
ORG=1
|
||||
NIKDY=2
|
||||
VIDITELNOST = (
|
||||
(VZDY, 'Vždy'),
|
||||
(ORG, 'Organizátorům'),
|
||||
(NIKDY, 'Nikdy'),
|
||||
(VZDY, 'Vždy'),
|
||||
(ORG, 'Organizátorům'),
|
||||
(NIKDY, 'Nikdy'),
|
||||
)
|
||||
|
||||
# tyhle funkce jsou tady jen kvůli starým migracím, které se na ně odkazují
|
||||
# až se ty migrace někdy squashnou, tak by mělo být možné funkce smazat
|
||||
def obrazek_filename_maly():
|
||||
pass
|
||||
pass
|
||||
def obrazek_filename_stredni():
|
||||
pass
|
||||
pass
|
||||
def obrazek_filename_velky():
|
||||
pass
|
||||
pass
|
||||
|
||||
def obrazek_filename(self, filename):
|
||||
gal = self.galerie
|
||||
cislo_gal = force_unicode(gal.pk)
|
||||
gal = self.galerie
|
||||
cislo_gal = gal.pk
|
||||
|
||||
# najdi kořenovou galerii
|
||||
while (gal.galerie_up):
|
||||
gal = gal.galerie_up
|
||||
# najdi kořenovou galerii
|
||||
while (gal.galerie_up):
|
||||
gal = gal.galerie_up
|
||||
|
||||
# soustředění je v cestě jen pokud galerie pod nějaké patří
|
||||
cesta = (
|
||||
['Galerie'] +
|
||||
(["soustredeni_" + force_unicode(gal.soustredeni.pk)] if gal.soustredeni else []) +
|
||||
["galerie_" + cislo_gal, force_unicode(self.nazev)]
|
||||
)
|
||||
# soustředění je v cestě jen pokud galerie pod nějaké patří
|
||||
cesta = (
|
||||
['Galerie'] +
|
||||
(["soustredeni_{}".format(gal.soustredeni.pk)] if gal.soustredeni else []) +
|
||||
["galerie_{}".format(cislo_gal), self.nazev]
|
||||
)
|
||||
|
||||
return os.path.join(*cesta)
|
||||
return os.path.join(*cesta)
|
||||
|
||||
class Obrazek(models.Model):
|
||||
obrazek_velky = models.ImageField(upload_to=obrazek_filename,
|
||||
help_text = "Lze vložit libovolně velký obrázek. Ideální je, aby alespoň jeden rozměr měl alespoň 500px.")
|
||||
obrazek_stredni = ImageSpecField(source='obrazek_velky',
|
||||
processors=[Transpose(Transpose.AUTO), ResizeToFit(900, 675, upscale=False)],
|
||||
options={'quality': 95})
|
||||
obrazek_maly = ImageSpecField(source='obrazek_velky',
|
||||
processors=[Transpose(Transpose.AUTO), ResizeToFit(167, 167, upscale=False)],
|
||||
options={'quality': 95})
|
||||
nazev = models.CharField('Název', max_length=50, blank=True, null=True)
|
||||
popis = models.TextField('Popis', blank=True, null=True)
|
||||
datum_vlozeni = models.DateTimeField('Datum vložení', auto_now_add=True)
|
||||
galerie = models.ForeignKey('Galerie', blank=True, null=True)
|
||||
poradi = models.IntegerField('Pořadí', blank=True, null=True)
|
||||
obrazek_velky = models.ImageField(upload_to=obrazek_filename,
|
||||
help_text = "Lze vložit libovolně velký obrázek. Ideální je, aby alespoň jeden rozměr měl alespoň 500px.")
|
||||
obrazek_stredni = ImageSpecField(source='obrazek_velky',
|
||||
processors=[Transpose(Transpose.AUTO), ResizeToFit(900, 675, upscale=False)],
|
||||
options={'quality': 95})
|
||||
obrazek_maly = ImageSpecField(source='obrazek_velky',
|
||||
processors=[Transpose(Transpose.AUTO), ResizeToFit(167, 167, upscale=False)],
|
||||
options={'quality': 95})
|
||||
nazev = models.CharField('Název', max_length=50, blank=True, null=True)
|
||||
popis = models.TextField('Popis', blank=True, null=True)
|
||||
datum_vlozeni = models.DateTimeField('Datum vložení', auto_now_add=True)
|
||||
galerie = models.ForeignKey('Galerie', blank=True, null=True, on_delete=models.SET_NULL)
|
||||
poradi = models.IntegerField('Pořadí', blank=True, null=True)
|
||||
|
||||
def __unicode__(self):
|
||||
return unicode(self.obrazek_velky.name)
|
||||
def __str__(self):
|
||||
return self.obrazek_velky.name
|
||||
|
||||
class Meta:
|
||||
verbose_name = 'Obrázek'
|
||||
verbose_name_plural = 'Obrázky'
|
||||
ordering = ['nazev']
|
||||
class Meta:
|
||||
verbose_name = 'Obrázek'
|
||||
verbose_name_plural = 'Obrázky'
|
||||
ordering = ['nazev']
|
||||
|
||||
def obrazek_maly_tag(self):
|
||||
return u'<img src="{}">'.format(self.obrazek_maly.url)
|
||||
obrazek_maly_tag.short_description = "Náhled"
|
||||
obrazek_maly_tag.allow_tags = True
|
||||
def obrazek_maly_tag(self):
|
||||
if not self.obrazek_maly:
|
||||
return ''
|
||||
return u'<img src="{}">'.format(self.obrazek_maly.url)
|
||||
obrazek_maly_tag.short_description = "Náhled"
|
||||
obrazek_maly_tag.allow_tags = True
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
# obrázek potřebuje název, protože se z něj generuje cesta pro jeho uložení
|
||||
# (a pak se podle něj taky řadí)
|
||||
if self.nazev is None:
|
||||
self.nazev = os.path.basename(self.obrazek_velky.name)
|
||||
super(Obrazek, self).save(*args, **kwargs)
|
||||
def save(self, *args, **kwargs):
|
||||
# obrázek potřebuje název, protože se z něj generuje cesta pro jeho uložení
|
||||
# (a pak se podle něj taky řadí)
|
||||
if self.nazev is None:
|
||||
self.nazev = os.path.basename(self.obrazek_velky.name)
|
||||
super(Obrazek, self).save(*args, **kwargs)
|
||||
|
||||
|
||||
|
||||
class Galerie(models.Model):
|
||||
nazev = models.CharField('Název', max_length=100)
|
||||
datum_vytvoreni = models.DateTimeField('Datum vytvoření', auto_now_add = True)
|
||||
datum_zmeny = models.DateTimeField('Datum poslední změny', auto_now = True)
|
||||
popis = models.TextField('Popis', blank = True, null = True)
|
||||
titulni_obrazek = models.ForeignKey(Obrazek, blank = True, null = True, related_name = "+", on_delete = models.SET_NULL)
|
||||
zobrazit = models.IntegerField('Zobrazit?', default = ORG, choices = VIDITELNOST)
|
||||
galerie_up = models.ForeignKey('Galerie', blank = True, null = True)
|
||||
soustredeni = models.ForeignKey(Soustredeni, blank = True, null = True)
|
||||
poradi = models.IntegerField('Pořadí', blank = True, null = False, default = 0)
|
||||
nazev = models.CharField('Název', max_length=100)
|
||||
datum_vytvoreni = models.DateTimeField('Datum vytvoření', auto_now_add = True)
|
||||
datum_zmeny = models.DateTimeField('Datum poslední změny', auto_now = True)
|
||||
popis = models.TextField('Popis', blank = True, null = True)
|
||||
titulni_obrazek = models.ForeignKey(Obrazek, blank = True, null = True, related_name = "+", on_delete = models.SET_NULL)
|
||||
zobrazit = models.IntegerField('Zobrazit?', default = ORG, choices = VIDITELNOST)
|
||||
galerie_up = models.ForeignKey('Galerie', blank = True, null = True,
|
||||
on_delete=models.SET_NULL)
|
||||
soustredeni = models.ForeignKey(Soustredeni, blank = True, null = True,
|
||||
on_delete=models.PROTECT)
|
||||
poradi = models.IntegerField('Pořadí', blank = True, null = False, default = 0)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.nazev
|
||||
class Meta:
|
||||
verbose_name = 'Galerie'
|
||||
verbose_name_plural = 'Galerie'
|
||||
def __str__(self):
|
||||
return self.nazev
|
||||
class Meta:
|
||||
verbose_name = 'Galerie'
|
||||
verbose_name_plural = 'Galerie'
|
||||
|
||||
#def link_na_preview(self):
|
||||
#"""Odkaz na galerii, používá se v admin rozhranní. """
|
||||
#return '<a href="/fotogalerie/galerie/%s/">Preview</a>' % self.id
|
||||
#link_na_preview.allow_tags = True
|
||||
#link_na_preview.short_description = 'Zobrazit galerii'
|
||||
#def link_na_preview(self):
|
||||
#"""Odkaz na galerii, používá se v admin rozhranní. """
|
||||
#return '<a href="/fotogalerie/galerie/%s/">Preview</a>' % self.id
|
||||
#link_na_preview.allow_tags = True
|
||||
#link_na_preview.short_description = 'Zobrazit galerii'
|
||||
#
|
||||
#def je_publikovano(self):
|
||||
#"""Vraci True, pokud je tato galerie publikovana. """
|
||||
#if self.zobrazit == VZDY:
|
||||
#return True
|
||||
#if self.zobrazit == PODLE_CLANKU:
|
||||
#for clanek in self.clanek_set.all():
|
||||
#if clanek.je_publikovano():
|
||||
#return True
|
||||
#return False
|
||||
#def je_publikovano(self):
|
||||
#"""Vraci True, pokud je tato galerie publikovana. """
|
||||
#if self.zobrazit == VZDY:
|
||||
#return True
|
||||
#if self.zobrazit == PODLE_CLANKU:
|
||||
#for clanek in self.clanek_set.all():
|
||||
#if clanek.je_publikovano():
|
||||
#return True
|
||||
#return False
|
||||
#
|
||||
#@staticmethod
|
||||
#def publikovane_galerie():
|
||||
#"""Vraci galerie, ktere uz maji byt publikovane."""
|
||||
#clanky = Blog.models.Clanek.publikovane_clanky()
|
||||
#return Galerie.objects.filter(Q(zobrazit=VZDY) | (Q(clanek__in=clanky) & Q(zobrazit=PODLE_CLANKU))).distinct()
|
||||
#@staticmethod
|
||||
#def publikovane_galerie():
|
||||
#"""Vraci galerie, ktere uz maji byt publikovane."""
|
||||
#clanky = Blog.models.Clanek.publikovane_clanky()
|
||||
#return Galerie.objects.filter(Q(zobrazit=VZDY) | (Q(clanek__in=clanky) & Q(zobrazit=PODLE_CLANKU))).distinct()
|
||||
|
|
Before Width: | Height: | Size: 15 KiB |
65
galerie/static/galerie/prvky/dalsi.svg
Normal file
|
@ -0,0 +1,65 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="25.135418mm"
|
||||
height="42.333332mm"
|
||||
viewBox="0 0 25.135418 42.333331"
|
||||
version="1.1"
|
||||
id="svg851"
|
||||
sodipodi:docname="dalsi.svg"
|
||||
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1850"
|
||||
inkscape:window-height="1136"
|
||||
id="namedview7"
|
||||
showgrid="true"
|
||||
inkscape:zoom="23.600001"
|
||||
inkscape:cx="18.587131"
|
||||
inkscape:cy="74.924864"
|
||||
inkscape:window-x="70"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg851">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid833" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs845" />
|
||||
<metadata
|
||||
id="metadata848">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
transform="matrix(-1.0282842,0,0,1,111.4545,-88.415317)">
|
||||
<path
|
||||
d="m 98.096584,101.64448 1.286528,1.32292 -5.660724,5.82083 h 13.379892 v 1.5875 H 93.722388 l 5.660724,5.82083 -1.286528,1.32292 -7.719171,-7.9375 z"
|
||||
style="fill:#e84e10;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.23177969"
|
||||
id="path44-3"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccccc" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 15 KiB |
65
galerie/static/galerie/prvky/predchozi.svg
Normal file
|
@ -0,0 +1,65 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="25.135418mm"
|
||||
height="42.333332mm"
|
||||
viewBox="0 0 25.135418 42.333331"
|
||||
version="1.1"
|
||||
id="svg851"
|
||||
sodipodi:docname="predchozi.svg"
|
||||
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1850"
|
||||
inkscape:window-height="1136"
|
||||
id="namedview7"
|
||||
showgrid="true"
|
||||
inkscape:zoom="4.1719301"
|
||||
inkscape:cx="124.03002"
|
||||
inkscape:cy="97.874031"
|
||||
inkscape:window-x="70"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg851">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid833" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs845" />
|
||||
<metadata
|
||||
id="metadata848">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
transform="matrix(1.0282842,0,0,1,-86.319083,-88.415315)">
|
||||
<path
|
||||
d="m 98.096584,101.64448 1.286528,1.32292 -5.660724,5.82083 h 13.379892 v 1.5875 H 93.722388 l 5.660724,5.82083 -1.286528,1.32292 -7.719171,-7.9375 z"
|
||||
style="fill:#e84e10;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.23177969"
|
||||
id="path44-3"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccccc" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2 KiB |
|
@ -1,6 +0,0 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{# TODO predelat pres context processor #}
|
||||
{% block header %}soustredeni{% endblock %}
|
||||
{% block menu_soustredeni %}selected{% endblock %}
|
||||
{% block submenu %}{% include 'seminar/soustredeni/submenu.html' %}{% endblock %}
|
|
@ -1,4 +1,4 @@
|
|||
{% extends "galerie/Base.html" %}
|
||||
{% extends "base.html" %}
|
||||
|
||||
|
||||
{% block nadpis1a %}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% extends "galerie/Base.html" %}
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block nadpis1a %}
|
||||
Galerie {{galerie.nazev}}
|
||||
|
@ -61,7 +61,7 @@ Galerie {{galerie.nazev}}
|
|||
{{ galerie|truncatechars:max_delka_nazvu }}
|
||||
</div>
|
||||
</a>
|
||||
{% if user.is_staff and galerie.zobrazit > 0 %}
|
||||
{% if user.je_org and galerie.zobrazit > 0 %}
|
||||
<div class="mam-org-only-galerie">
|
||||
({{galerie.poradi}})
|
||||
<span class="plus"><a href="plus/{{galerie.pk}}/">+</a></span>
|
||||
|
@ -73,7 +73,7 @@ Galerie {{galerie.nazev}}
|
|||
{% endwith %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if user.is_staff and galerie.zobrazit > 0 %}
|
||||
{% if user.je_org and galerie.zobrazit > 0 %}
|
||||
<div class="mam-org-only">
|
||||
<a href="./new">Vytvořit novou podgalerii </a>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% extends "galerie/Base.html" %}
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}{% block nadpis1a %}
|
||||
Vytvářím novou galerii
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
# coding: utf-8
|
||||
|
||||
from django.conf.urls import include, url
|
||||
from django.urls import path
|
||||
from seminar.utils import org_required
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^(?P<pk>\d+)/$', views.nahled),
|
||||
url(r'^(?P<pk>\d+)/(?P<fotka>\d+)/$', views.detail),
|
||||
url(r'^(?P<galerie>\d+)/new/$', views.new_galerie),
|
||||
url(r'^(?P<galerie>\d+)/plus/(?P<subgalerie>\d+)/$', views.plus_galerie),
|
||||
url(r'^(?P<galerie>\d+)/minus/(?P<subgalerie>\d+)/$', views.minus_galerie),
|
||||
path('<int:pk>/', views.nahled),
|
||||
path('<int:pk>/<int:fotka>/', views.detail),
|
||||
path('<int:galerie>/new/', org_required(views.new_galerie)),
|
||||
path('<int:galerie>/plus/<int:subgalerie>/', org_required(views.plus_galerie)),
|
||||
path('<int:galerie>/minus/<int:subgalerie>/', org_required(views.minus_galerie)),
|
||||
]
|
||||
|
||||
|
|
375
galerie/views.py
|
@ -12,226 +12,225 @@ from seminar.models import Soustredeni
|
|||
from galerie.forms import KomentarForm, NewGalerieForm
|
||||
|
||||
def zobrazit(galerie, request):
|
||||
preview = False
|
||||
if galerie.zobrazit >= 1:
|
||||
if request.user.is_staff:
|
||||
preview = True;
|
||||
else:
|
||||
raise Http404
|
||||
return preview
|
||||
preview = False
|
||||
if galerie.zobrazit >= 1:
|
||||
if request.user.je_org:
|
||||
preview = True;
|
||||
else:
|
||||
raise Http404
|
||||
return preview
|
||||
|
||||
|
||||
def cesta_od_korene(g):
|
||||
"""Vrátí seznam galerií od kořene ke g"""
|
||||
cesta = []
|
||||
while g != None:
|
||||
cesta.append(g)
|
||||
g = g.galerie_up
|
||||
return reversed(cesta)
|
||||
"""Vrátí seznam galerií od kořene ke g"""
|
||||
cesta = []
|
||||
while g != None:
|
||||
cesta.append(g)
|
||||
g = g.galerie_up
|
||||
return reversed(cesta)
|
||||
|
||||
|
||||
def nahled(request, pk, soustredeni):
|
||||
"""Zobrazeni nahledu vsech fotek ve skupine."""
|
||||
galerie = get_object_or_404(Galerie, pk=pk)
|
||||
"""Zobrazeni nahledu vsech fotek ve skupine."""
|
||||
galerie = get_object_or_404(Galerie, pk=pk)
|
||||
|
||||
podgalerie = Galerie.objects.filter(galerie_up = galerie).order_by('poradi')
|
||||
if not request.user.is_staff:
|
||||
podgalerie = podgalerie.filter(zobrazit__lt=1)
|
||||
podgalerie = Galerie.objects.filter(galerie_up = galerie).order_by('poradi')
|
||||
if not request.user.je_org:
|
||||
podgalerie = podgalerie.filter(zobrazit__lt=1)
|
||||
|
||||
obrazky = Obrazek.objects.filter(galerie = galerie).order_by('poradi', 'nazev')
|
||||
preview = zobrazit(galerie, request)
|
||||
obrazky = Obrazek.objects.filter(galerie = galerie).order_by('poradi', 'nazev')
|
||||
preview = zobrazit(galerie, request)
|
||||
|
||||
sourozenci = []
|
||||
if galerie.galerie_up:
|
||||
sourozenci = galerie.galerie_up.galerie_set.all().order_by('poradi')
|
||||
if not request.user.is_staff:
|
||||
sourozenci = sourozenci.filter(zobrazit__lt=1)
|
||||
sourozenci = []
|
||||
if galerie.galerie_up:
|
||||
sourozenci = galerie.galerie_up.galerie_set.all().order_by('poradi')
|
||||
if not request.user.je_org:
|
||||
sourozenci = sourozenci.filter(zobrazit__lt=1)
|
||||
|
||||
predchozi = None
|
||||
nasledujici = None
|
||||
minuly = None
|
||||
for g in sourozenci:
|
||||
if g.pk == galerie.pk:
|
||||
predchozi = minuly
|
||||
if minuly != None and minuly.pk == galerie.pk:
|
||||
nasledujici = g
|
||||
break
|
||||
minuly = g
|
||||
predchozi = None
|
||||
nasledujici = None
|
||||
minuly = None
|
||||
for g in sourozenci:
|
||||
if g.pk == galerie.pk:
|
||||
predchozi = minuly
|
||||
if minuly != None and minuly.pk == galerie.pk:
|
||||
nasledujici = g
|
||||
break
|
||||
minuly = g
|
||||
|
||||
cesta = cesta_od_korene(galerie)
|
||||
cesta = cesta_od_korene(galerie)
|
||||
|
||||
return render(request, 'galerie/GalerieNahled.html',
|
||||
{'galerie' : galerie,
|
||||
'podgalerie' : podgalerie,
|
||||
'obrazky' : obrazky,
|
||||
'preview' : preview,
|
||||
'cesta': cesta,
|
||||
'sourozenci': sourozenci,
|
||||
'predchozi': predchozi,
|
||||
'nasledujici': nasledujici,
|
||||
})
|
||||
return render(request, 'galerie/GalerieNahled.html',
|
||||
{'galerie' : galerie,
|
||||
'podgalerie' : podgalerie,
|
||||
'obrazky' : obrazky,
|
||||
'preview' : preview,
|
||||
'cesta': cesta,
|
||||
'sourozenci': sourozenci,
|
||||
'predchozi': predchozi,
|
||||
'nasledujici': nasledujici,
|
||||
})
|
||||
|
||||
def detail(request, pk, fotka, soustredeni):
|
||||
"""Zobrazeni nahledu fotky s id 'fotka'."""
|
||||
MAX_VYSKA = 900
|
||||
MAX_SIRKA = 900
|
||||
MAX_VYSKA_MALA = 100
|
||||
MAX_SIRKA_MALA = 200
|
||||
NAHLEDU = 1
|
||||
"""Zobrazeni nahledu fotky s id 'fotka'."""
|
||||
MAX_VYSKA = 900
|
||||
MAX_SIRKA = 900
|
||||
MAX_VYSKA_MALA = 100
|
||||
MAX_SIRKA_MALA = 200
|
||||
NAHLEDU = 1
|
||||
|
||||
galerie = get_object_or_404(Galerie, pk=pk)
|
||||
preview = zobrazit(galerie, request)
|
||||
obrazek = get_object_or_404(Obrazek, pk=fotka)
|
||||
obrazky = galerie.obrazek_set.all().order_by('poradi', 'nazev')
|
||||
galerie = get_object_or_404(Galerie, pk=pk)
|
||||
preview = zobrazit(galerie, request)
|
||||
obrazek = get_object_or_404(Obrazek, pk=fotka)
|
||||
obrazky = galerie.obrazek_set.all().order_by('poradi', 'nazev')
|
||||
|
||||
# vytvoreni a obslouzeni formulare
|
||||
if request.method == 'POST':
|
||||
form = KomentarForm(request.POST)
|
||||
if form.is_valid():
|
||||
obrazek.popis = form.cleaned_data['komentar']
|
||||
obrazek.save()
|
||||
else:
|
||||
form = KomentarForm({'komentar': obrazek.popis})
|
||||
# vytvoreni a obslouzeni formulare
|
||||
if request.method == 'POST':
|
||||
form = KomentarForm(request.POST)
|
||||
if form.is_valid():
|
||||
obrazek.popis = form.cleaned_data['komentar']
|
||||
obrazek.save()
|
||||
else:
|
||||
form = KomentarForm({'komentar': obrazek.popis})
|
||||
|
||||
# Poradi aktualniho obrazku v galerii/stitku.
|
||||
for i in range(len(obrazky)):
|
||||
if obrazky[i] == obrazek:
|
||||
poradi = i
|
||||
break
|
||||
else:
|
||||
# Obrazek neni v galerii/stitku.
|
||||
raise Http404
|
||||
# Poradi aktualniho obrazku v galerii/stitku.
|
||||
for i in range(len(obrazky)):
|
||||
if obrazky[i] == obrazek:
|
||||
poradi = i
|
||||
break
|
||||
else:
|
||||
# Obrazek neni v galerii/stitku.
|
||||
raise Http404
|
||||
|
||||
|
||||
# Nacteni okolnich obrazku a galerii
|
||||
# TODO vyjmout zjisteni predchozich a nasledujicich galerii
|
||||
# a udelat z toho funkci, ktera se pouzije u nahledu
|
||||
predchozi_galerie = None
|
||||
nasledujici_galerie = None
|
||||
obrazky_dalsi = obrazky[poradi+1:poradi+NAHLEDU+1]
|
||||
if (poradi+1) > NAHLEDU:
|
||||
obrazky_predchozi = obrazky[poradi-NAHLEDU:poradi]
|
||||
else:
|
||||
obrazky_predchozi = obrazky[0:poradi]
|
||||
if galerie.poradi > 1:
|
||||
predchozi_galerie = Galerie.objects.\
|
||||
filter(galerie_up=galerie.galerie_up).\
|
||||
filter(poradi=(galerie.poradi-1))
|
||||
if predchozi_galerie:
|
||||
predchozi_galerie = predchozi_galerie[0]
|
||||
else:
|
||||
predchozi_galerie = None
|
||||
if (poradi+1) == len(obrazky): # Tohle je poslední obrázek
|
||||
if (galerie.poradi is not None
|
||||
and galerie.galerie_up is not None):
|
||||
nasledujici_galerie = Galerie.objects.\
|
||||
filter(galerie_up=galerie.galerie_up).\
|
||||
filter(poradi=(galerie.poradi+1))
|
||||
else:
|
||||
nasledujici_galerie = None
|
||||
if nasledujici_galerie:
|
||||
nasledujici_galerie = nasledujici_galerie[0]
|
||||
else:
|
||||
nasledujici_galerie = None
|
||||
|
||||
# Nacteni okolnich obrazku a galerii
|
||||
# TODO vyjmout zjisteni predchozich a nasledujicich galerii
|
||||
# a udelat z toho funkci, ktera se pouzije u nahledu
|
||||
predchozi_galerie = None
|
||||
nasledujici_galerie = None
|
||||
obrazky_dalsi = obrazky[poradi+1:poradi+NAHLEDU+1]
|
||||
if (poradi+1) > NAHLEDU:
|
||||
obrazky_predchozi = obrazky[poradi-NAHLEDU:poradi]
|
||||
else:
|
||||
obrazky_predchozi = obrazky[0:poradi]
|
||||
if galerie.poradi > 1:
|
||||
predchozi_galerie = Galerie.objects.\
|
||||
filter(galerie_up=galerie.galerie_up).\
|
||||
filter(poradi=(galerie.poradi-1))
|
||||
if predchozi_galerie:
|
||||
predchozi_galerie = predchozi_galerie[0]
|
||||
else:
|
||||
predchozi_galerie = None
|
||||
if (poradi+1) == len(obrazky): # Tohle je poslední obrázek
|
||||
if (galerie.poradi is not None
|
||||
and galerie.galerie_up is not None):
|
||||
nasledujici_galerie = Galerie.objects.\
|
||||
filter(galerie_up=galerie.galerie_up).\
|
||||
filter(poradi=(galerie.poradi+1))
|
||||
else:
|
||||
nasledujici_galerie = None
|
||||
if nasledujici_galerie:
|
||||
nasledujici_galerie = nasledujici_galerie[0]
|
||||
else:
|
||||
nasledujici_galerie = None
|
||||
|
||||
|
||||
|
||||
# Preskalovani obrazku do vybraneho prostoru.
|
||||
vyska = obrazek.obrazek_stredni.height
|
||||
sirka = obrazek.obrazek_stredni.width
|
||||
if vyska > MAX_VYSKA:
|
||||
sirka = sirka * MAX_VYSKA / vyska
|
||||
vyska = MAX_VYSKA
|
||||
if sirka > MAX_SIRKA:
|
||||
vyska = vyska * MAX_SIRKA / sirka
|
||||
sirka = MAX_SIRKA
|
||||
|
||||
return render(request, 'galerie/Galerie.html',
|
||||
{'galerie' : galerie,
|
||||
'predchozi_galerie' : predchozi_galerie,
|
||||
'nasledujici_galerie' : nasledujici_galerie,
|
||||
'obrazek' : obrazek,
|
||||
'vyska' : vyska,
|
||||
'sirka' : sirka,
|
||||
'obrazky_predchozi' : obrazky_predchozi,
|
||||
'obrazky_dalsi' : obrazky_dalsi,
|
||||
'preview' : preview,
|
||||
'form' : form,
|
||||
'cesta': cesta_od_korene(galerie),
|
||||
})
|
||||
|
||||
# Preskalovani obrazku do vybraneho prostoru.
|
||||
vyska = obrazek.obrazek_stredni.height
|
||||
sirka = obrazek.obrazek_stredni.width
|
||||
if vyska > MAX_VYSKA:
|
||||
sirka = sirka * MAX_VYSKA / vyska
|
||||
vyska = MAX_VYSKA
|
||||
if sirka > MAX_SIRKA:
|
||||
vyska = vyska * MAX_SIRKA / sirka
|
||||
sirka = MAX_SIRKA
|
||||
|
||||
return render(request, 'galerie/Galerie.html',
|
||||
{'galerie' : galerie,
|
||||
'predchozi_galerie' : predchozi_galerie,
|
||||
'nasledujici_galerie' : nasledujici_galerie,
|
||||
'obrazek' : obrazek,
|
||||
'vyska' : vyska,
|
||||
'sirka' : sirka,
|
||||
'obrazky_predchozi' : obrazky_predchozi,
|
||||
'obrazky_dalsi' : obrazky_dalsi,
|
||||
'preview' : preview,
|
||||
'form' : form,
|
||||
'cesta': cesta_od_korene(galerie),
|
||||
})
|
||||
|
||||
def new_galerie(request, galerie, soustredeni):
|
||||
|
||||
# zjistime k jakemu soustredeni se vaze nove vytvarena galerie
|
||||
soustredeni = get_object_or_404(Soustredeni, pk = soustredeni)
|
||||
# pokud je parametr galerie 0, pak jde o hlavni galerii
|
||||
# kdyz je nejaky jiny, pak je pk galerie pod kterou tu dalsi vytvarim
|
||||
if int(galerie) == 0:
|
||||
galerie_up = False
|
||||
galerie_text = "Hlavní fotogalerie soustředění"
|
||||
else:
|
||||
galerie_up = get_object_or_404(Galerie, pk = int(galerie))
|
||||
galerie_text = "podgalerii ke galerii " + str(galerie_up)
|
||||
# zjistime k jakemu soustredeni se vaze nove vytvarena galerie
|
||||
soustredeni = get_object_or_404(Soustredeni, pk = soustredeni)
|
||||
# pokud je parametr galerie 0, pak jde o hlavni galerii
|
||||
# kdyz je nejaky jiny, pak je pk galerie pod kterou tu dalsi vytvarim
|
||||
if int(galerie) == 0:
|
||||
galerie_up = False
|
||||
galerie_text = "Hlavní fotogalerie soustředění"
|
||||
else:
|
||||
galerie_up = get_object_or_404(Galerie, pk = int(galerie))
|
||||
galerie_text = "podgalerii ke galerii " + str(galerie_up)
|
||||
|
||||
# obsluha formulare umoznujiciho multiple nahravani fotek
|
||||
if request.method == 'POST':
|
||||
form = NewGalerieForm(request.POST, request.FILES)
|
||||
if form.is_valid():
|
||||
# vytvoreni nove galerie
|
||||
gal = Galerie()
|
||||
gal.nazev = form.cleaned_data['nazev']
|
||||
#gal.popis = form.cleaned_data['popis'] # popis nepouzivame
|
||||
gal.zobrazit = 1 # galerie je v procesu vytvareni
|
||||
''' pokud je to podgalerie pridej nadrazenou galerii
|
||||
a nadrazene soustredeni nechej volne,
|
||||
pokud je to hlavni galerie, tak nadrazena galerie neexistuje,
|
||||
ale v takovem pripade musi byt nadrazene soustredeni a ne jinak '''
|
||||
if galerie_up:
|
||||
gal.galerie_up = galerie_up
|
||||
else:
|
||||
gal.soustredeni = soustredeni
|
||||
if gal.galerie_up:
|
||||
gal.poradi = int(len(gal.galerie_up.galerie_set.all())) + 1
|
||||
gal.save()
|
||||
# obsluha formulare umoznujiciho multiple nahravani fotek
|
||||
if request.method == 'POST':
|
||||
form = NewGalerieForm(request.POST, request.FILES)
|
||||
if form.is_valid():
|
||||
# vytvoreni nove galerie
|
||||
gal = Galerie()
|
||||
gal.nazev = form.cleaned_data['nazev']
|
||||
#gal.popis = form.cleaned_data['popis'] # popis nepouzivame
|
||||
gal.zobrazit = 1 # galerie je v procesu vytvareni
|
||||
''' pokud je to podgalerie pridej nadrazenou galerii
|
||||
a nadrazene soustredeni nechej volne,
|
||||
pokud je to hlavni galerie, tak nadrazena galerie neexistuje,
|
||||
ale v takovem pripade musi byt nadrazene soustredeni a ne jinak '''
|
||||
if galerie_up:
|
||||
gal.galerie_up = galerie_up
|
||||
else:
|
||||
gal.soustredeni = soustredeni
|
||||
if gal.galerie_up:
|
||||
gal.poradi = int(len(gal.galerie_up.galerie_set.all())) + 1
|
||||
gal.save()
|
||||
|
||||
# zpracovani obrazku v galerii
|
||||
for obr in request.FILES.getlist('obr'):
|
||||
o = Obrazek()
|
||||
o.obrazek_velky = obr
|
||||
o.nazev = str(obr)
|
||||
o.galerie = gal
|
||||
o.save()
|
||||
# zpracovani obrazku v galerii
|
||||
for obr in request.FILES.getlist('obr'):
|
||||
o = Obrazek()
|
||||
o.obrazek_velky = obr
|
||||
o.nazev = str(obr)
|
||||
o.galerie = gal
|
||||
o.save()
|
||||
|
||||
# presmerovani na prave vzniklou galerii
|
||||
return HttpResponseRedirect('../../' + str(gal.pk))
|
||||
# presmerovani na prave vzniklou galerii
|
||||
return HttpResponseRedirect('../../' + str(gal.pk))
|
||||
|
||||
else:
|
||||
form = NewGalerieForm()
|
||||
else:
|
||||
form = NewGalerieForm()
|
||||
|
||||
|
||||
return render(request, 'galerie/GalerieNew.html',
|
||||
{
|
||||
'form' : form,
|
||||
'soustredeni' : soustredeni,
|
||||
'galerie_text' : galerie_text,
|
||||
})
|
||||
return render(request, 'galerie/GalerieNew.html',
|
||||
{
|
||||
'form' : form,
|
||||
'soustredeni' : soustredeni,
|
||||
'galerie_text' : galerie_text,
|
||||
})
|
||||
|
||||
def plus_galerie(request, galerie, soustredeni, subgalerie):
|
||||
galerie = get_object_or_404(Galerie, pk=subgalerie)
|
||||
if galerie.poradi:
|
||||
galerie.poradi += 1
|
||||
else:
|
||||
galerie.poradi = int(len(galerie.galerie_up.galerie_set.all()))
|
||||
galerie.save()
|
||||
return HttpResponseRedirect('../../')
|
||||
galerie = get_object_or_404(Galerie, pk=subgalerie)
|
||||
if galerie.poradi:
|
||||
galerie.poradi += 1
|
||||
else:
|
||||
galerie.poradi = int(len(galerie.galerie_up.galerie_set.all()))
|
||||
galerie.save()
|
||||
return HttpResponseRedirect('../../')
|
||||
|
||||
def minus_galerie(request, galerie, soustredeni, subgalerie):
|
||||
galerie = get_object_or_404(Galerie, pk=subgalerie)
|
||||
if galerie.poradi:
|
||||
galerie.poradi -= 1
|
||||
else:
|
||||
galerie.poradi = 1
|
||||
galerie.save()
|
||||
return HttpResponseRedirect('../../')
|
||||
galerie = get_object_or_404(Galerie, pk=subgalerie)
|
||||
if galerie.poradi:
|
||||
galerie.poradi -= 1
|
||||
else:
|
||||
galerie.poradi = 1
|
||||
galerie.save()
|
||||
return HttpResponseRedirect('../../')
|
||||
|
||||
|
|
0
header_fotky/__init__.py
Normal file
10
header_fotky/admin.py
Normal file
|
@ -0,0 +1,10 @@
|
|||
from django.contrib import admin
|
||||
from django.contrib.admin import ModelAdmin
|
||||
import header_fotky.models as m
|
||||
|
||||
|
||||
class FotkaPozadiAdmin(ModelAdmin):
|
||||
readonly_fields = ['cas']
|
||||
|
||||
admin.site.register(m.FotkaHeader, FotkaPozadiAdmin)
|
||||
admin.site.register(m.FotkaUrlVazba)
|
5
header_fotky/apps.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class HeaderFotkyConfig(AppConfig):
|
||||
name = 'header_fotky'
|
45
header_fotky/context_processors.py
Normal file
|
@ -0,0 +1,45 @@
|
|||
|
||||
from datetime import datetime, date
|
||||
import random
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
from header_fotky.models import FotkaUrlVazba
|
||||
|
||||
|
||||
def vzhled(request):
|
||||
''' Podle casu prida do templatu, zdali je nebo neni noc '''
|
||||
hodin = datetime.now().hour
|
||||
if (hodin <= 6) or (hodin >= 20):
|
||||
noc = True
|
||||
nedoba = 'den'
|
||||
doba = 'noc'
|
||||
else:
|
||||
noc = False
|
||||
nedoba = 'noc'
|
||||
doba = 'den'
|
||||
url = request.path
|
||||
|
||||
fotky = FotkaUrlVazba.objects.exclude(denni_doba=nedoba)
|
||||
fotka = None
|
||||
|
||||
# TODO rychlejší patternmatch?
|
||||
while (fotka is None) and (url != ''):
|
||||
presne = fotky.filter(url__exact=url)
|
||||
if presne.count() > 0:
|
||||
presne_doba = presne.filter(denni_doba=doba)
|
||||
if presne_doba.count() > 0:
|
||||
fotka = random.choice(presne_doba).url_fotky()
|
||||
else:
|
||||
fotka = random.choice(presne).url_fotky()
|
||||
|
||||
url = url[:-1]
|
||||
index = url.rfind('/')
|
||||
if index != -1:
|
||||
url = url[:index+1]
|
||||
|
||||
if fotka is None:
|
||||
fotka = settings.STATIC_URL + "images/header/vikendovka.jpg"
|
||||
|
||||
return {'noc': noc, 'fotka': fotka}
|
||||
|
63
header_fotky/migrations/0001_initial.py
Normal file
|
@ -0,0 +1,63 @@
|
|||
# Generated by Django 2.2.15 on 2020-09-20 09:14
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
|
||||
from shutil import copytree
|
||||
|
||||
|
||||
def zkopiruj_fotky(apps, schema_editor):
|
||||
try:
|
||||
copytree("mamweb/static/images/header/", "media/header/") # FIXME: bylo tu dirs_exists_ok=True, nekompatibilní s Py 3.7
|
||||
except FileExistsError:
|
||||
pass
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='FotkaHeader',
|
||||
fields=[
|
||||
('cas', models.DateTimeField(default=django.utils.timezone.now, help_text='Čas vložení fotky',
|
||||
verbose_name='čas vložení fotky')),
|
||||
('nazev',
|
||||
models.CharField(help_text='Název např. archiv_noc', max_length=50, primary_key=True, serialize=False,
|
||||
unique=True, verbose_name='název fotky')),
|
||||
('fotka', models.ImageField(upload_to='header')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'fotka do pozadí menu',
|
||||
'verbose_name_plural': 'fotky do pozadí menu',
|
||||
'db_table': 'fotky_header',
|
||||
'ordering': ['-cas'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='FotkaUrlVazba',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('url',
|
||||
models.CharField(blank=True, help_text='url prefix stránek např: /archiv/ nebo /', max_length=100,
|
||||
verbose_name='URL')),
|
||||
('denni_doba', models.CharField(choices=[('den', 'Zobrazit jen ve dne'), ('noc', 'Zobrazit jen v noci'),
|
||||
('oboji', 'Zobrazovat pořád')], default='oboji', max_length=16,
|
||||
verbose_name='denní doba')),
|
||||
('fotka', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='header_fotky.FotkaHeader',
|
||||
verbose_name='fotka')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'vazba url a fotky do pozadí menu',
|
||||
'verbose_name_plural': 'vazby url a fotek do pozadí menu',
|
||||
'db_table': 'fotky_url_vazby',
|
||||
'ordering': ['url'],
|
||||
},
|
||||
|
||||
),
|
||||
migrations.RunPython(zkopiruj_fotky, migrations.RunPython.noop),
|
||||
]
|
0
header_fotky/migrations/__init__.py
Normal file
65
header_fotky/models.py
Normal file
|
@ -0,0 +1,65 @@
|
|||
from django.core.exceptions import ValidationError
|
||||
from django.db import models
|
||||
from django.utils import timezone
|
||||
|
||||
|
||||
class FotkaHeader(models.Model):
|
||||
class Meta:
|
||||
ordering = ['-cas']
|
||||
db_table = 'fotky_header'
|
||||
verbose_name = u'fotka do pozadí menu'
|
||||
verbose_name_plural = u'fotky do pozadí menu'
|
||||
|
||||
cas = models.DateTimeField(u'čas vložení fotky', default=timezone.now, help_text='Čas vložení fotky')
|
||||
|
||||
nazev = models.CharField(
|
||||
u'název fotky', null=False, blank=False, unique=True, primary_key=True,
|
||||
max_length=50, help_text='Název např. archiv_noc'
|
||||
)
|
||||
|
||||
fotka = models.ImageField(upload_to='header', null=False, blank=False)
|
||||
|
||||
def __str__(self):
|
||||
return self.nazev
|
||||
|
||||
def clean(self):
|
||||
if not self.fotka:
|
||||
raise ValidationError("Chybí obrázek")
|
||||
""" Kontroluje, zda sedí poměr stran """
|
||||
if abs(self.fotka.width - (self.fotka.height * 970 / 350)) > 2:
|
||||
raise ValidationError("Obrázek by měl mít rozměry 970w na 350h, nebo alespoň podobný poměr stran.")
|
||||
super().clean()
|
||||
|
||||
|
||||
class FotkaUrlVazba(models.Model):
|
||||
class Meta:
|
||||
ordering = ['url']
|
||||
db_table = 'fotky_url_vazby'
|
||||
verbose_name = u'vazba url a fotky do pozadí menu'
|
||||
verbose_name_plural = u'vazby url a fotek do pozadí menu'
|
||||
|
||||
url = models.CharField(
|
||||
u'URL', blank=True, null=False, max_length=100,
|
||||
help_text='url prefix stránek např: /archiv/ nebo /'
|
||||
)
|
||||
|
||||
fotka = models.ForeignKey(
|
||||
FotkaHeader, blank=False, null=False, verbose_name='fotka',
|
||||
on_delete=models.CASCADE
|
||||
)
|
||||
|
||||
DOBA_DEN = 'den'
|
||||
DOBA_NOC = 'noc'
|
||||
DOBA_OBOJI = 'oboji'
|
||||
DOBA_CHOICES = [
|
||||
(DOBA_DEN, 'Zobrazit jen ve dne'),
|
||||
(DOBA_NOC, 'Zobrazit jen v noci'),
|
||||
(DOBA_OBOJI, 'Zobrazovat pořád')]
|
||||
|
||||
denni_doba = models.CharField('denní doba', max_length=16, choices=DOBA_CHOICES, blank=False, default=DOBA_OBOJI)
|
||||
|
||||
def __str__(self):
|
||||
return self.url
|
||||
|
||||
def url_fotky(self):
|
||||
return self.fotka.fotka.url
|
7
ilustrace_odmeny/jak_nahrat_do_flatpage
Normal file
|
@ -0,0 +1,7 @@
|
|||
Přidání obrázků do odměn:
|
||||
admin -> flatpage odměn -> ikona přidat obrázek
|
||||
záložka odeslat, vybrat obrázek, odeslat
|
||||
přespočí to zpět, velikost nechat, jen ok
|
||||
přepnout na html zdroj, k obrázku (dovnitř img tagu) nahradit style za:
|
||||
style="display:block; margin-left: auto; margin-right: auto; width: 70%;"
|
||||
pro dort méně než 70%, asi 60% či 55%, okometricky
|
16
init_local.sh
Executable file
|
@ -0,0 +1,16 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -e # Spadni pokud něco spadne
|
||||
|
||||
# Check venvu
|
||||
# NOTE: zkontroluje i správnou složku -- existencí Makefilu
|
||||
make venv_check
|
||||
|
||||
# Vygenerujeme testdata
|
||||
./manage.py testdata
|
||||
|
||||
# Nahrajeme statický obsah modelů
|
||||
./manage.py loaddata flat.json sitetree_new.json
|
||||
|
||||
# Posbíráme statické soubory
|
||||
./manage.py collectstatic
|
|
@ -6,21 +6,21 @@ from korektury.models import KorekturovanePDF
|
|||
# Register your models here.
|
||||
class KorekturovanePDFAdmin(VersionAdmin):
|
||||
|
||||
readonly_fields = ['cas', 'stran']
|
||||
readonly_fields = ['cas', 'stran']
|
||||
|
||||
def get_readonly_fields(self, request, obj=None):
|
||||
if obj:
|
||||
return self.readonly_fields + ['pdf']
|
||||
return self.readonly_fields
|
||||
def get_readonly_fields(self, request, obj=None):
|
||||
if obj:
|
||||
return self.readonly_fields + ['pdf']
|
||||
return self.readonly_fields
|
||||
|
||||
fieldsets = [
|
||||
(None,
|
||||
{'fields':
|
||||
['pdf', 'cas', 'org', 'stran', 'nazev', 'komentar']}),
|
||||
# (u'PDF', {'fields': ['pdf']}),
|
||||
]
|
||||
list_display = ['nazev', 'cas', 'stran', 'org']
|
||||
list_filter = []
|
||||
search_fields = []
|
||||
fieldsets = [
|
||||
(None,
|
||||
{'fields':
|
||||
['pdf', 'cas', 'org', 'stran', 'nazev', 'komentar']}),
|
||||
# (u'PDF', {'fields': ['pdf']}),
|
||||
]
|
||||
list_display = ['nazev', 'cas', 'stran', 'org']
|
||||
list_filter = []
|
||||
search_fields = []
|
||||
|
||||
admin.site.register(KorekturovanePDF, KorekturovanePDFAdmin)
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
from django import forms
|
||||
|
||||
class OpravaForm(forms.Form):
|
||||
text = forms.CharField(max_length=256)
|
||||
autor = forms.CharField(max_length=20)
|
||||
x = forms.IntegerField()
|
||||
y = forms.IntegerField()
|
||||
scroll = forms.CharField(max_length=256)
|
||||
pdf = forms.CharField(max_length=256)
|
||||
img_id = forms.CharField(max_length=256)
|
||||
id = forms.CharField(max_length=256)
|
||||
action = forms.CharField(max_length=256)
|
||||
text = forms.CharField(max_length=256)
|
||||
autor = forms.CharField(max_length=20)
|
||||
x = forms.IntegerField()
|
||||
y = forms.IntegerField()
|
||||
scroll = forms.CharField(max_length=256)
|
||||
pdf = forms.CharField(max_length=256)
|
||||
img_id = forms.CharField(max_length=256)
|
||||
id = forms.CharField(max_length=256)
|
||||
action = forms.CharField(max_length=256)
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ class Migration(migrations.Migration):
|
|||
('cas', models.DateTimeField(help_text=b'\xc4\x8cas zad\xc3\xa1n\xc3\xad koment\xc3\xa1\xc5\x99e', verbose_name='\u010das koment\xe1\u0159e')),
|
||||
('autor', models.TextField(help_text=b'Autor koment\xc3\xa1\xc5\x99e', verbose_name='autor koment\xe1\u0159e', blank=True)),
|
||||
('text', models.TextField(help_text=b'Text koment\xc3\xa1\xc5\x99e', verbose_name='text koment\xe1\u0159e', blank=True)),
|
||||
('oprava', models.ForeignKey(to='korektury.Oprava')),
|
||||
('oprava', models.ForeignKey(to='korektury.Oprava', on_delete=models.CASCADE)),
|
||||
],
|
||||
options={
|
||||
'ordering': ['cas'],
|
||||
|
|
|
@ -19,7 +19,7 @@ class Migration(migrations.Migration):
|
|||
('cas', models.DateTimeField(default=django.utils.timezone.now, help_text=b'\xc4\x8cas zad\xc3\xa1n\xc3\xad koment\xc3\xa1\xc5\x99e', verbose_name='\u010das koment\xe1\u0159e')),
|
||||
('autor', models.TextField(help_text=b'Autor koment\xc3\xa1\xc5\x99e', verbose_name='autor koment\xe1\u0159e', blank=True)),
|
||||
('text', models.TextField(help_text=b'Text koment\xc3\xa1\xc5\x99e', verbose_name='text koment\xe1\u0159e', blank=True)),
|
||||
('oprava', models.ForeignKey(to='korektury.Oprava')),
|
||||
('oprava', models.ForeignKey(to='korektury.Oprava', on_delete=models.CASCADE)),
|
||||
],
|
||||
options={
|
||||
'ordering': ['cas'],
|
||||
|
|
|
@ -14,7 +14,7 @@ class Migration(migrations.Migration):
|
|||
migrations.AddField(
|
||||
model_name='oprava',
|
||||
name='pdf',
|
||||
field=models.ForeignKey(default=-1, to='korektury.KorekturovanePDF'),
|
||||
field=models.ForeignKey(default=-1, to='korektury.KorekturovanePDF', on_delete=models.CASCADE),
|
||||
preserve_default=True,
|
||||
),
|
||||
]
|
||||
|
|
|
@ -15,11 +15,11 @@ class Migration(migrations.Migration):
|
|||
migrations.AddField(
|
||||
model_name='komentar',
|
||||
name='autor_org',
|
||||
field=models.ForeignKey(blank=True, to='seminar.Organizator', help_text='Autor koment\xe1\u0159e', null=True),
|
||||
field=models.ForeignKey(blank=True, to='seminar.Organizator', help_text='Autor koment\xe1\u0159e', null=True, on_delete=models.CASCADE),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='oprava',
|
||||
name='autor_org',
|
||||
field=models.ForeignKey(blank=True, to='seminar.Organizator', help_text=b'Autor opravy', null=True),
|
||||
field=models.ForeignKey(blank=True, to='seminar.Organizator', help_text=b'Autor opravy', null=True, on_delete=models.CASCADE),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -18,10 +18,10 @@ def transform_autor(apps, schema_editor):
|
|||
oprava.autor_org = org
|
||||
oprava.save()
|
||||
except:
|
||||
print "Org nenalezen -- mažu korekturu"
|
||||
print("Org nenalezen -- mažu korekturu")
|
||||
# oprava.delete()
|
||||
else:
|
||||
print "Org nenalezen -- mažu korekturu"
|
||||
print("Org nenalezen -- mažu korekturu")
|
||||
oprava.delete()
|
||||
|
||||
# preorgovani komentaru
|
||||
|
@ -35,10 +35,10 @@ def transform_autor(apps, schema_editor):
|
|||
komentar.autor_org = org
|
||||
komentar.save()
|
||||
except:
|
||||
print "Org nenalezen -- mažu korekturu"
|
||||
print("Org nenalezen -- mažu korekturu")
|
||||
# oprava.delete()
|
||||
else:
|
||||
print "Org nenalezen -- mažu korekturu"
|
||||
print("Org nenalezen -- mažu korekturu")
|
||||
komentar.delete()
|
||||
|
||||
def back(apps, schema_editor):
|
||||
|
|
|
@ -16,10 +16,10 @@ class Migration(migrations.Migration):
|
|||
model_name='korekturovanepdf',
|
||||
name='org',
|
||||
field=models.ForeignKey(default=None,
|
||||
blank=True,
|
||||
to='seminar.Organizator',
|
||||
help_text=b'Zodpov\xc4\x9bdn\xc3\xbd\
|
||||
organiz\xc3\xa1tor za obsah',
|
||||
null=True),
|
||||
blank=True,
|
||||
to='seminar.Organizator',
|
||||
help_text=b'Zodpov\xc4\x9bdn\xc3\xbd\
|
||||
organiz\xc3\xa1tor za obsah',
|
||||
null=True, on_delete=models.CASCADE),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -14,6 +14,6 @@ class Migration(migrations.Migration):
|
|||
migrations.AlterField(
|
||||
model_name='korekturovanepdf',
|
||||
name='org',
|
||||
field=models.ForeignKey(default=None, blank=True, to='seminar.Organizator', help_text=b'Zodpov\xc4\x9bdn\xc3\xbd organiz\xc3\xa1tor za obsah', null=True),
|
||||
field=models.ForeignKey(default=None, blank=True, to='seminar.Organizator', help_text=b'Zodpov\xc4\x9bdn\xc3\xbd organiz\xc3\xa1tor za obsah', null=True, on_delete=models.CASCADE),
|
||||
),
|
||||
]
|
||||
|
|
77
korektury/migrations/0016_auto_20190430_2340.py
Normal file
|
@ -0,0 +1,77 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.20 on 2019-04-30 21:40
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('korektury', '0015_auto_20161004_2005'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='komentar',
|
||||
name='cas',
|
||||
field=models.DateTimeField(default=django.utils.timezone.now, help_text='Čas zadání komentáře', verbose_name='čas komentáře'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='komentar',
|
||||
name='text',
|
||||
field=models.TextField(blank=True, help_text='Text komentáře', verbose_name='text komentáře'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='korekturovanepdf',
|
||||
name='cas',
|
||||
field=models.DateTimeField(default=django.utils.timezone.now, help_text='Čas vložení PDF', verbose_name='čas vložení PDF'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='korekturovanepdf',
|
||||
name='komentar',
|
||||
field=models.TextField(blank=True, help_text='Komentář ke korekturovanému PDF (např. na co se zaměřit)', verbose_name='komentář k PDF'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='korekturovanepdf',
|
||||
name='nazev',
|
||||
field=models.CharField(blank=True, help_text='Název (např. 22.1 verze 4) korekturovaného PDF', max_length=50, verbose_name='název PDF'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='korekturovanepdf',
|
||||
name='org',
|
||||
field=models.ForeignKey(blank=True, default=None, help_text='Zodpovědný organizátor za obsah', null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Organizator'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='korekturovanepdf',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('pridavani', 'Přidávání korektur'), ('zanaseni', 'Korektury jsou zanášeny'), ('zastarale', 'Stará verze, nekorigovat')], default='pridavani', max_length=16, verbose_name='stav PDF'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='korekturovanepdf',
|
||||
name='stran',
|
||||
field=models.IntegerField(default=0, help_text='Počet stran PDF', verbose_name='počet stran'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='oprava',
|
||||
name='autor',
|
||||
field=models.ForeignKey(blank=True, help_text='Autor opravy', null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Organizator'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='oprava',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('k_oprave', 'K opravě'), ('opraveno', 'Opraveno'), ('neni_chyba', 'Není chyba'), ('k_zaneseni', 'K zanesení do TeXu')], default='k_oprave', max_length=16, verbose_name='stav opravy'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='oprava',
|
||||
name='strana',
|
||||
field=models.IntegerField(help_text='Strana s opravou (od 0)', verbose_name='strana s opravou'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='oprava',
|
||||
name='text',
|
||||
field=models.TextField(blank=True, help_text='Text opravy', verbose_name='text opravy'),
|
||||
),
|
||||
]
|
36
korektury/migrations/0017_auto_20190610_2358.py
Normal file
|
@ -0,0 +1,36 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.21 on 2019-06-10 21:58
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('korektury', '0016_auto_20190430_2340'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='komentar',
|
||||
name='autor',
|
||||
field=models.ForeignKey(blank=True, help_text='Autor komentáře', null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Organizator'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='korekturovanepdf',
|
||||
name='org',
|
||||
field=models.ForeignKey(blank=True, default=None, help_text='Zodpovědný organizátor za obsah', null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Organizator'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='oprava',
|
||||
name='autor',
|
||||
field=models.ForeignKey(blank=True, help_text='Autor opravy', null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Organizator'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='oprava',
|
||||
name='pdf',
|
||||
field=models.ForeignKey(default=-1, on_delete=django.db.models.deletion.PROTECT, to='korektury.KorekturovanePDF'),
|
||||
),
|
||||
]
|
|
@ -3,8 +3,7 @@ import os
|
|||
from django.db import models
|
||||
from django.utils import timezone
|
||||
from django.conf import settings
|
||||
from django.utils.encoding import python_2_unicode_compatible
|
||||
from django.utils.encoding import force_unicode
|
||||
from django.utils.encoding import force_text
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.utils.text import get_valid_filename
|
||||
|
||||
|
@ -17,180 +16,176 @@ from unidecode import unidecode
|
|||
|
||||
|
||||
def generate_filename(self, filename):
|
||||
clean = get_valid_filename(
|
||||
unidecode(
|
||||
filename.replace('/', '-').replace('\0', '').replace(":", "_")
|
||||
)
|
||||
)
|
||||
fname = "%s_%s" % (
|
||||
timezone.now().strftime('%Y-%m-%d-%H_%M'),
|
||||
clean)
|
||||
return os.path.join(settings.KOREKTURY_PDF_DIR, fname)
|
||||
clean = get_valid_filename(
|
||||
unidecode(
|
||||
filename.replace('/', '-').replace('\0', '').replace(":", "_")
|
||||
)
|
||||
)
|
||||
fname = "%s_%s" % (
|
||||
timezone.now().strftime('%Y-%m-%d-%H_%M'),
|
||||
clean)
|
||||
return os.path.join(settings.KOREKTURY_PDF_DIR, fname)
|
||||
|
||||
|
||||
#@reversion.register(ignore_duplicates=True)
|
||||
#@python_2_unicode_compatible
|
||||
class KorekturovanePDF(models.Model):
|
||||
class Meta:
|
||||
ordering = ['-cas']
|
||||
db_table = 'korekturovane_cislo'
|
||||
verbose_name = u'PDF k opravám'
|
||||
verbose_name_plural = u'PDF k opravám'
|
||||
|
||||
#Interní ID
|
||||
id = models.AutoField(primary_key = True)
|
||||
class Meta:
|
||||
ordering = ['-cas']
|
||||
db_table = 'korekturovane_cislo'
|
||||
verbose_name = u'PDF k opravám'
|
||||
verbose_name_plural = u'PDF k opravám'
|
||||
|
||||
#Interní ID
|
||||
id = models.AutoField(primary_key = True)
|
||||
|
||||
cas = models.DateTimeField(u'čas vložení PDF',default=timezone.now,help_text = 'Čas vložení PDF')
|
||||
cas = models.DateTimeField(u'čas vložení PDF',default=timezone.now,help_text = 'Čas vložení PDF')
|
||||
|
||||
nazev = models.CharField(u'název PDF',blank = True,max_length=50, help_text='Název (např. 22.1 verze 4) korekturovaného PDF')
|
||||
nazev = models.CharField(u'název PDF',blank = True,max_length=50, help_text='Název (např. 22.1 verze 4) korekturovaného PDF')
|
||||
|
||||
komentar = models.TextField(u'komentář k PDF',blank = True, help_text='Komentář ke korekturovanému PDF (např. na co se zaměřit)')
|
||||
komentar = models.TextField(u'komentář k PDF',blank = True, help_text='Komentář ke korekturovanému PDF (např. na co se zaměřit)')
|
||||
|
||||
pdf = models.FileField(u'PDF', upload_to = generate_filename)
|
||||
pdf = models.FileField(u'PDF', upload_to = generate_filename)
|
||||
|
||||
org = models.ForeignKey(Organizator, blank=True,
|
||||
help_text='Zodpovědný organizátor za obsah',
|
||||
null=True,
|
||||
default=None)
|
||||
org = models.ForeignKey(Organizator, blank=True,
|
||||
help_text='Zodpovědný organizátor za obsah',
|
||||
null=True, default=None, on_delete=models.SET_NULL)
|
||||
|
||||
stran = models.IntegerField(u'počet stran', help_text='Počet stran PDF',
|
||||
default=0)
|
||||
STATUS_PRIDAVANI = 'pridavani'
|
||||
STATUS_ZANASENI = 'zanaseni'
|
||||
STATUS_ZASTARALE = 'zastarale'
|
||||
STATUS_CHOICES = (
|
||||
(STATUS_PRIDAVANI, u'Přidávání korektur'),
|
||||
(STATUS_ZANASENI, u'Korektury jsou zanášeny'),
|
||||
(STATUS_ZASTARALE, u'Stará verze, nekorigovat'),
|
||||
)
|
||||
status = models.CharField(u'stav PDF',max_length=16, choices=STATUS_CHOICES, blank=False,
|
||||
default = STATUS_PRIDAVANI)
|
||||
|
||||
|
||||
#TODO Nepovinný foreign key k číslu
|
||||
stran = models.IntegerField(u'počet stran', help_text='Počet stran PDF',
|
||||
default=0)
|
||||
STATUS_PRIDAVANI = 'pridavani'
|
||||
STATUS_ZANASENI = 'zanaseni'
|
||||
STATUS_ZASTARALE = 'zastarale'
|
||||
STATUS_CHOICES = (
|
||||
(STATUS_PRIDAVANI, u'Přidávání korektur'),
|
||||
(STATUS_ZANASENI, u'Korektury jsou zanášeny'),
|
||||
(STATUS_ZASTARALE, u'Stará verze, nekorigovat'),
|
||||
)
|
||||
status = models.CharField(u'stav PDF',max_length=16, choices=STATUS_CHOICES, blank=False,
|
||||
default = STATUS_PRIDAVANI)
|
||||
|
||||
def get_prefix(self):
|
||||
"""Vrať řetězec, ke kterému se připojí číslo a .png"""
|
||||
# vrátíme jméno souboru bez cesty
|
||||
return os.path.basename(self.pdf.file.name)
|
||||
|
||||
def convert(self):
|
||||
"""Vytvoří jedno png za každou stranu pdf a uloží se"""
|
||||
dirname = os.path.join(settings.MEDIA_ROOT, settings.KOREKTURY_IMG_DIR)
|
||||
if not os.path.exists(dirname):
|
||||
os.mkdir(dirname)
|
||||
self.stran = 0
|
||||
while True:
|
||||
res = subprocess.call([
|
||||
#Parametry inspirovány chybovou hláškou imagemagicku
|
||||
"gs",
|
||||
"-sstdout=%stderr",
|
||||
"-dSAFER",
|
||||
"-dNOPAUSE",
|
||||
"-dBATCH",
|
||||
"-dNOPROMPT",
|
||||
"-sDEVICE=pngalpha",
|
||||
"-r180x180",
|
||||
"-dFirstPage=%d" % (self.stran+1),
|
||||
"-dLastPage=%d" % (self.stran+1),
|
||||
"-sOutputFile="+os.path.join(
|
||||
dirname,
|
||||
"%s-%d.png" % (self.get_prefix(), self.stran)),
|
||||
"-f%s" % (self.pdf.path)
|
||||
])
|
||||
if not os.path.exists(os.path.join(
|
||||
dirname,
|
||||
"%s-%d.png" % (self.get_prefix(), self.stran))):
|
||||
break
|
||||
self.stran += 1
|
||||
# Změnil se počet stran, ukládáme
|
||||
super(KorekturovanePDF, self).save()
|
||||
#TODO Nepovinný foreign key k číslu
|
||||
|
||||
def save(self):
|
||||
# Pokud se nezmenilo PDF, tak nepregenerovavej nahledy
|
||||
try:
|
||||
original = KorekturovanePDF.objects.get(pk=self.pk)
|
||||
if original.pdf == self.pdf:
|
||||
super(KorekturovanePDF, self).save()
|
||||
return
|
||||
except ObjectDoesNotExist:
|
||||
pass
|
||||
# uložíme nahrávané pdf
|
||||
super(KorekturovanePDF, self).save()
|
||||
def get_prefix(self):
|
||||
"""Vrať řetězec, ke kterému se připojí číslo a .png"""
|
||||
# vrátíme jméno souboru bez cesty
|
||||
return os.path.basename(self.pdf.file.name)
|
||||
|
||||
# uložíme png a změněný počet stran
|
||||
self.convert()
|
||||
def convert(self):
|
||||
"""Vytvoří jedno png za každou stranu pdf a uloží se"""
|
||||
dirname = os.path.join(settings.MEDIA_ROOT, settings.KOREKTURY_IMG_DIR)
|
||||
if not os.path.exists(dirname):
|
||||
os.mkdir(dirname)
|
||||
self.stran = 0
|
||||
while True:
|
||||
res = subprocess.call([
|
||||
#Parametry inspirovány chybovou hláškou imagemagicku
|
||||
"gs",
|
||||
"-sstdout=%stderr",
|
||||
"-dSAFER",
|
||||
"-dNOPAUSE",
|
||||
"-dBATCH",
|
||||
"-dNOPROMPT",
|
||||
"-sDEVICE=pngalpha",
|
||||
"-r180x180",
|
||||
"-dFirstPage=%d" % (self.stran+1),
|
||||
"-dLastPage=%d" % (self.stran+1),
|
||||
"-sOutputFile="+os.path.join(
|
||||
dirname,
|
||||
"%s-%d.png" % (self.get_prefix(), self.stran)),
|
||||
"-f%s" % (self.pdf.path)
|
||||
])
|
||||
if not os.path.exists(os.path.join(
|
||||
dirname,
|
||||
"%s-%d.png" % (self.get_prefix(), self.stran))):
|
||||
break
|
||||
self.stran += 1
|
||||
# Změnil se počet stran, ukládáme
|
||||
super(KorekturovanePDF, self).save()
|
||||
|
||||
def save(self, **kwargs):
|
||||
# Pokud se nezmenilo PDF, tak nepregenerovavej nahledy
|
||||
try:
|
||||
original = KorekturovanePDF.objects.get(pk=self.pk)
|
||||
if original.pdf == self.pdf:
|
||||
super(KorekturovanePDF, self).save()
|
||||
return
|
||||
except ObjectDoesNotExist:
|
||||
pass
|
||||
# uložíme nahrávané pdf
|
||||
super(KorekturovanePDF, self).save(kwargs)
|
||||
|
||||
# uložíme png a změněný počet stran
|
||||
self.convert()
|
||||
|
||||
@reversion.register(ignore_duplicates=True)
|
||||
@python_2_unicode_compatible
|
||||
class Oprava(models.Model):
|
||||
class Meta:
|
||||
db_table = 'opravy'
|
||||
verbose_name = u'Oprava'
|
||||
verbose_name_plural = u'Opravy'
|
||||
ordering = ['y','x']
|
||||
|
||||
#Interní ID
|
||||
id = models.AutoField(primary_key = True)
|
||||
class Meta:
|
||||
db_table = 'opravy'
|
||||
verbose_name = u'Oprava'
|
||||
verbose_name_plural = u'Opravy'
|
||||
ordering = ['y','x']
|
||||
|
||||
#Interní ID
|
||||
id = models.AutoField(primary_key = True)
|
||||
|
||||
pdf = models.ForeignKey(KorekturovanePDF, default=-1)
|
||||
pdf = models.ForeignKey(KorekturovanePDF, default=-1, on_delete=models.PROTECT)
|
||||
|
||||
strana = models.IntegerField(u'strana s opravou', help_text='Strana s opravou (od 0)')
|
||||
strana = models.IntegerField(u'strana s opravou', help_text='Strana s opravou (od 0)')
|
||||
|
||||
x = models.IntegerField(u'x-ová souřadnice bugu')
|
||||
y = models.IntegerField(u'y-ová souřadnice bugu')
|
||||
x = models.IntegerField(u'x-ová souřadnice bugu')
|
||||
y = models.IntegerField(u'y-ová souřadnice bugu')
|
||||
|
||||
STATUS_K_OPRAVE = 'k_oprave'
|
||||
STATUS_OPRAVENO = 'opraveno'
|
||||
STATUS_NENI_CHYBA = 'neni_chyba'
|
||||
STATUS_K_ZANESENI = 'k_zaneseni'
|
||||
STATUS_CHOICES = (
|
||||
(STATUS_K_OPRAVE, u'K opravě'),
|
||||
(STATUS_OPRAVENO, u'Opraveno'),
|
||||
(STATUS_NENI_CHYBA, u'Není chyba'),
|
||||
(STATUS_K_ZANESENI, u'K zanesení do TeXu'),
|
||||
)
|
||||
status = models.CharField(u'stav opravy',max_length=16, choices=STATUS_CHOICES, blank=False,
|
||||
default = STATUS_K_OPRAVE)
|
||||
STATUS_K_OPRAVE = 'k_oprave'
|
||||
STATUS_OPRAVENO = 'opraveno'
|
||||
STATUS_NENI_CHYBA = 'neni_chyba'
|
||||
STATUS_K_ZANESENI = 'k_zaneseni'
|
||||
STATUS_CHOICES = (
|
||||
(STATUS_K_OPRAVE, u'K opravě'),
|
||||
(STATUS_OPRAVENO, u'Opraveno'),
|
||||
(STATUS_NENI_CHYBA, u'Není chyba'),
|
||||
(STATUS_K_ZANESENI, u'K zanesení do TeXu'),
|
||||
)
|
||||
status = models.CharField(u'stav opravy',max_length=16, choices=STATUS_CHOICES, blank=False,
|
||||
default = STATUS_K_OPRAVE)
|
||||
|
||||
autor = models.ForeignKey(Organizator, blank = True,
|
||||
help_text='Autor opravy',
|
||||
null = True)
|
||||
|
||||
text = models.TextField(u'text opravy',blank = True, help_text='Text opravy')
|
||||
autor = models.ForeignKey(Organizator, blank = True,
|
||||
help_text='Autor opravy',
|
||||
null = True, on_delete=models.SET_NULL)
|
||||
|
||||
text = models.TextField(u'text opravy',blank = True, help_text='Text opravy')
|
||||
|
||||
# def __init__(self,dictionary):
|
||||
# for k,v in dictionary.items():
|
||||
# setattr(self,k,v)
|
||||
# def __init__(self,dictionary):
|
||||
# for k,v in dictionary.items():
|
||||
# setattr(self,k,v)
|
||||
|
||||
def __str__(self):
|
||||
return force_unicode(u'%s od %s: %s'%(self.status,self.autor,self.text))
|
||||
def __str__(self):
|
||||
return '{} od {}: {}'.format(self.status,self.autor,self.text)
|
||||
|
||||
|
||||
|
||||
@reversion.register(ignore_duplicates=True)
|
||||
@python_2_unicode_compatible
|
||||
class Komentar(models.Model):
|
||||
class Meta:
|
||||
db_table = 'komentare'
|
||||
verbose_name = u'Komentář k opravě'
|
||||
verbose_name_plural = u'Komentáře k opravě'
|
||||
ordering = ['cas']
|
||||
|
||||
#Interní ID
|
||||
id = models.AutoField(primary_key = True)
|
||||
class Meta:
|
||||
db_table = 'komentare'
|
||||
verbose_name = u'Komentář k opravě'
|
||||
verbose_name_plural = u'Komentáře k opravě'
|
||||
ordering = ['cas']
|
||||
|
||||
#Interní ID
|
||||
id = models.AutoField(primary_key = True)
|
||||
|
||||
cas = models.DateTimeField(u'čas komentáře',default=timezone.now,help_text = 'Čas zadání komentáře')
|
||||
cas = models.DateTimeField(u'čas komentáře',default=timezone.now,help_text = 'Čas zadání komentáře')
|
||||
|
||||
oprava = models.ForeignKey(Oprava)
|
||||
autor = models.ForeignKey(Organizator, blank = True,
|
||||
help_text = u'Autor komentáře',
|
||||
null = True)
|
||||
|
||||
text = models.TextField(u'text komentáře',blank = True, help_text='Text komentáře')
|
||||
oprava = models.ForeignKey(Oprava, on_delete=models.CASCADE)
|
||||
autor = models.ForeignKey(Organizator, blank = True,
|
||||
help_text = u'Autor komentáře',
|
||||
null = True, on_delete=models.SET_NULL)
|
||||
|
||||
text = models.TextField(u'text komentáře',blank = True, help_text='Text komentáře')
|
||||
|
||||
def __str__(self):
|
||||
return force_unicode(u'%s od %s: %s'%(self.cas,self.autor,self.text))
|
||||
def __str__(self):
|
||||
return '{} od {}: {}'.format(self.cas,self.autor,self.text)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -13,72 +13,46 @@ body,
|
|||
|
||||
img{background:white;}
|
||||
|
||||
/* Barvy korektur */
|
||||
.k_oprave {
|
||||
--rgb: 255, 0, 0;
|
||||
}
|
||||
.opraveno {
|
||||
--rgb: 0, 0, 255;
|
||||
}
|
||||
.neni_chyba {
|
||||
--rgb: 128, 128, 128;
|
||||
}
|
||||
.k_zaneseni {
|
||||
--rgb: 0, 255, 0;
|
||||
}
|
||||
|
||||
.pointer-hi,
|
||||
.pointer,
|
||||
.pointer-wontfix,
|
||||
.pointer-wontfix-hi,
|
||||
.pointer-ready,
|
||||
.pointer-ready-hi,
|
||||
.pointer-done,
|
||||
.pointer-done-hi {
|
||||
.pointer{
|
||||
position:absolute;
|
||||
/*border-bottom-left-radius: 10px; */
|
||||
border-left: 2px solid yellow;
|
||||
border-bottom: 2px solid yellow;
|
||||
border-color: rgb(var(--rgb),var(--alpha));
|
||||
}
|
||||
|
||||
.pointer {
|
||||
border-width: 1px;
|
||||
--alpha: 0.35;
|
||||
}
|
||||
|
||||
.pointer-done-hi,
|
||||
.pointer-wontfix-hi,
|
||||
.pointer-ready-hi,
|
||||
.pointer-hi {
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.pointer {
|
||||
border-color: #F00; /*IE*/
|
||||
border-color: rgba(255, 0, 0, 0.35);
|
||||
}
|
||||
.pointer-hi {
|
||||
border-color: #F00; /*IE*/
|
||||
border-color: rgba(255, 0, 0, 1);
|
||||
}
|
||||
.pointer-done {
|
||||
border-color: #00F; /*IE*/
|
||||
border-color: rgba(0, 0, 255, 0.2);
|
||||
}
|
||||
.pointer-done-hi {
|
||||
border-color: #00F; /*IE*/
|
||||
border-color: rgba(0, 0, 255, 1);
|
||||
}
|
||||
.pointer-wontfix {
|
||||
border-color: #000; /*IE*/
|
||||
border-color: rgba(128, 128, 128, 0.2);
|
||||
}
|
||||
.pointer-wontfix-hi {
|
||||
border-color: #000; /*IE*/
|
||||
border-color: rgba(128, 128, 128, 1);
|
||||
}
|
||||
.pointer-ready {
|
||||
border-color: #0F0; /*IE*/
|
||||
border-color: rgba(0, 255, 0, 0.2);
|
||||
}
|
||||
.pointer-ready-hi {
|
||||
border-color: #0F0; /*IE*/
|
||||
border-color: rgba(0, 255, 0, 1);
|
||||
--alpha: 1;
|
||||
}
|
||||
|
||||
|
||||
.box:hover,
|
||||
.box-done:hover,
|
||||
.box-ready:hover,
|
||||
.box-wontfix:hover{
|
||||
|
||||
.box:hover{
|
||||
border-width:3px;
|
||||
margin: 0px;
|
||||
}
|
||||
.box,
|
||||
.box-done,
|
||||
.box-ready,
|
||||
.box-wontfix {
|
||||
.box {
|
||||
margin: 1px;
|
||||
background-color: white;
|
||||
width:300px;
|
||||
|
@ -86,18 +60,7 @@ img{background:white;}
|
|||
padding: 3px;
|
||||
border: 2px solid black;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.box {
|
||||
border-color: red;
|
||||
}
|
||||
.box-done {
|
||||
border-color: blue;
|
||||
}
|
||||
.box-ready {
|
||||
border-color: rgba(0,255,0,1);
|
||||
}
|
||||
.box-wontfix {
|
||||
border-color: grey;
|
||||
border-color: rgb(var(--rgb));
|
||||
}
|
||||
form {
|
||||
display:inline;
|
||||
|
|
|
@ -65,6 +65,12 @@ function place_comments_one_div(img_id, comments)
|
|||
}
|
||||
}
|
||||
|
||||
function place_comments() {
|
||||
for (var i=0; i < comments.length-1; i++) {
|
||||
place_comments_one_div(comments[i][0], comments[i][1])
|
||||
}
|
||||
}
|
||||
|
||||
// ctrl-enter submits form
|
||||
function textarea_onkey(ev)
|
||||
{
|
||||
|
@ -212,45 +218,22 @@ function show_form(img_id, dx, dy, id, text, action) {
|
|||
textarea.focus();
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
function box_onmouseover(box, stat)
|
||||
function box_onmouseover(box)
|
||||
{
|
||||
var id = box.id;
|
||||
var pointer = document.getElementById(box.id + '-pointer');
|
||||
switch (stat){
|
||||
case 'done':
|
||||
pointer.className = 'pointer-done-hi';
|
||||
break;
|
||||
case 'wontfix':
|
||||
pointer.className = 'pointer-wontfix-hi';
|
||||
break;
|
||||
case 'ready':
|
||||
pointer.className = 'pointer-ready-hi';
|
||||
break;
|
||||
default:
|
||||
pointer.className = 'pointer-hi';
|
||||
}
|
||||
pointer.classList.remove('pointer');
|
||||
pointer.classList.add('pointer-hi');
|
||||
}
|
||||
|
||||
function box_onmouseout(box, stat)
|
||||
function box_onmouseout(box)
|
||||
{
|
||||
var id = box.id;
|
||||
var pointer = document.getElementById(box.id + '-pointer');
|
||||
switch (stat){
|
||||
case 'done':
|
||||
pointer.className = 'pointer-done';
|
||||
break;
|
||||
case 'wontfix':
|
||||
pointer.className = 'pointer-wontfix';
|
||||
break;
|
||||
case 'ready':
|
||||
pointer.className = 'pointer-ready';
|
||||
break;
|
||||
default:
|
||||
pointer.className = 'pointer';
|
||||
}
|
||||
pointer.classList.remove('pointer-hi');
|
||||
pointer.classList.add('pointer');
|
||||
}
|
||||
|
||||
function save_scroll(form)
|
||||
|
@ -261,6 +244,33 @@ function save_scroll(form)
|
|||
return true;
|
||||
}
|
||||
|
||||
function toggle_corrections(aclass)
|
||||
{
|
||||
var stylesheets = document.styleSheets;
|
||||
var ssheet = null;
|
||||
for (var i=0;i<stylesheets.length; i++){
|
||||
if (stylesheets[i].title === "opraf-css"){
|
||||
ssheet = stylesheets[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (! ssheet){
|
||||
return;
|
||||
}
|
||||
for (var i=0;i<ssheet.cssRules.length;i++){
|
||||
var rule = ssheet.cssRules[i];
|
||||
if (rule.selectorText === '.'+aclass){
|
||||
if (rule.style.display === ""){
|
||||
rule.style.display = "none";
|
||||
} else {
|
||||
rule.style.display = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
place_comments();
|
||||
|
||||
}
|
||||
|
||||
|
||||
String.prototype.unescapeHTML = function () {
|
||||
return(
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block submenu %}
|
||||
{% include "korektury/submenu.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{# blok do kterého se nacita text, v pripade jinyhc templatu obalit vlastnim blokem #}
|
||||
{% endblock %}
|
||||
|
||||
{% block title %}
|
||||
{# blok pro titulek stranky #}
|
||||
{% endblock %}
|
|
@ -1,10 +1,4 @@
|
|||
{% extends "korektury/base.html" %}
|
||||
|
||||
{% block submenu %}
|
||||
{% with "help" as selected %}
|
||||
{% include "korektury/submenu.html" %}
|
||||
{% endwith %}
|
||||
{% endblock %}
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% load staticfiles %}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" type="text/css" media="screen, projection" href="{% static "korektury/opraf.css"%}" />
|
||||
<link rel="stylesheet" title="opraf-css" type="text/css" media="screen, projection" href="{% static "korektury/opraf.css"%}" />
|
||||
<script src="{% static "korektury/opraf.js"%}"></script>
|
||||
<title>Korektury {{pdf.nazev}}</title>
|
||||
</head>
|
||||
|
@ -20,6 +20,29 @@
|
|||
|
|
||||
<a href="/">hlavní stránka</a> |
|
||||
<a href="https://mam.mff.cuni.cz/wiki">wiki</a> |
|
||||
<hr />
|
||||
Zobrazit:
|
||||
<input type="checkbox"
|
||||
id="k_oprave_checkbox"
|
||||
name="k_oprave_checkbox"
|
||||
onchange="toggle_corrections('k_oprave')" checked>
|
||||
<label for="k_oprave_checkbox">K opravě ({{k_oprave_cnt}})</label>
|
||||
<input type="checkbox"
|
||||
id="opraveno_checkbox"
|
||||
name="opraveno_checkbox"
|
||||
onchange="toggle_corrections('opraveno')" checked>
|
||||
<label for="opraveno_checkbox">Opraveno ({{opraveno_cnt}})</label>
|
||||
<input type="checkbox"
|
||||
id="neni_chyba_checkbox"
|
||||
name="neni_chyba_checkbox"
|
||||
onchange="toggle_corrections('neni_chyba')" checked>
|
||||
<label for="neni_chyba_checkbox">Není chyba ({{neni_chyba_cnt}})</label>
|
||||
<input type="checkbox"
|
||||
id="k_zaneseni_checkbox"
|
||||
name="k_zaneseni_checkbox"
|
||||
onchange="toggle_corrections('k_zaneseni')" checked>
|
||||
<label for="k_zaneseni_checkbox">K zanesení ({{k_zaneseni_cnt}})</label>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div id="commform-div">
|
||||
|
@ -81,12 +104,12 @@
|
|||
{% for o in opravy %}
|
||||
<div onclick='img_click(this,event)'
|
||||
id='op{{o.id}}-pointer'
|
||||
class='pointer{%if o.status == 'opraveno' %}-done{% elif o.status == 'neni_chyba' %}-wontfix{% elif o.status == 'k_zaneseni' %}-ready{% endif %}'>
|
||||
class='pointer {{o.status}}'>
|
||||
</div>
|
||||
<div name='op{{o.id}}' id='op{{o.id}}'
|
||||
class='box{%if o.status == 'opraveno' %}-done{% elif o.status == 'neni_chyba' %}-wontfix{% elif o.status == 'k_zaneseni' %}-ready{% endif %}'
|
||||
onmouseover='box_onmouseover(this,{% if o.status == 'opraveno' %}"done"{% elif o.status == 'neni_chyba' %}"wontfix"{% elif o.status == 'k_zaneseni' %}"ready"{% else %}""{% endif %})'
|
||||
onmouseout='box_onmouseout(this, {% if o.status == 'opraveno' %}"done"{% elif o.status == 'neni_chyba' %}"wontfix"{% elif o.status == 'k_zaneseni' %}"ready"{% else %}""{% endif %})'>
|
||||
class='box {{o.status}}'
|
||||
onmouseover='box_onmouseover(this)'
|
||||
onmouseout='box_onmouseout(this)'>
|
||||
|
||||
<div class='corr-header'>
|
||||
<span class='author' id='op{{o.id}}-autor'>{{o.autor}}</span>
|
||||
|
@ -211,11 +234,6 @@
|
|||
["img-{{s.strana}}", [{% for o in s.op_id %}["op{{o.id}}",{{o.x}},{{o.y}}],{% endfor %}[]]],
|
||||
{% endfor %}
|
||||
[]]
|
||||
function place_comments() {
|
||||
for (var i=0; i < comments.length-1; i++) {
|
||||
place_comments_one_div(comments[i][0], comments[i][1])
|
||||
}
|
||||
}
|
||||
{% if scroll %}
|
||||
window.scrollTo(0,{{scroll}});
|
||||
{% endif %}
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
{% extends "korektury/base.html" %}
|
||||
{% extends "base.html" %}
|
||||
{% load staticfiles %}
|
||||
|
||||
{% block submenu %}
|
||||
{% include "korektury/submenu.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block script%}
|
||||
<link rel="stylesheet" type="text/css" media="screen, projection" href="{% static "korektury/opraf-list.css" %}" />
|
||||
{% endblock %}
|
||||
|
@ -21,7 +17,14 @@
|
|||
|
||||
<ul>
|
||||
{% for pdf in object_list %}
|
||||
<li><span {% if pdf.status == 'zanaseni'%} class="comitting-text" {% elif pdf.status == 'zastarale' %} class="deprecated-text" {% endif %}> <b>{{ pdf.nazev }}</b> <i>{{pdf.komentar}}</i> <a href="/korektury/{{pdf.id}}">{{pdf.pdf.name}}</a> </span> </li>
|
||||
<li><span {% if pdf.status == 'zanaseni'%} class="comitting-text" {% elif pdf.status == 'zastarale' %} class="deprecated-text" {% endif %}>
|
||||
<b>{{ pdf.nazev }}</b>
|
||||
<i>{{pdf.komentar}}</i>
|
||||
<a href="/korektury/{{pdf.id}}">{{pdf.pdf.name}}</a>
|
||||
(k opravě: {{pdf.k_oprave_cnt}},
|
||||
opraveno: {{pdf.opraveno_cnt}},
|
||||
není chyba: {{pdf.neni_chyba_cnt}},
|
||||
k zanesení: {{pdf.k_zaneseni_cnt}}) </span> </li>
|
||||
{% empty %}
|
||||
<li> Nejsou žádné dokumenty ke korekturování.
|
||||
{% endfor %}
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
{% with "/korektury" as cesta %}
|
||||
|
||||
<div id='submenu'>
|
||||
<ul>
|
||||
<li class="{% if selected == "aktualni" %}selected{% endif %}"><a href="{{cesta}}/">Aktuální</a>
|
||||
<li class="{% if selected == "zastarale" %}selected{% endif %}"><a href="{{cesta}}/zastarale/">Zastaralé</a>
|
||||
<li class="{% if selected == "help" %}selected{% endif %}"><a href="{{cesta}}/help/">Nápověda</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{% endwith %}
|
||||
|
||||
|
BIN
korektury/testpdfs/A.pdf
Normal file
5125
korektury/testpdfs/B.pdf
Normal file
69
korektury/testutils.py
Normal file
|
@ -0,0 +1,69 @@
|
|||
import logging
|
||||
import os
|
||||
from shutil import copyfile, rmtree
|
||||
|
||||
from django.db import transaction
|
||||
from django.conf import settings
|
||||
|
||||
from korektury.models import KorekturovanePDF, generate_filename
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@transaction.atomic
|
||||
def create_test_pdf(rnd, organizatori):
|
||||
logger.info('Vyrábím testovací pdf ke korekturovani')
|
||||
try:
|
||||
testpdfs = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'testpdfs')
|
||||
|
||||
# smaže minulé pdfka a obrázky k nim a vytvoří (znovu) jejich složky
|
||||
pdf_dir = os.path.join(settings.BASE_DIR, os.path.join('media', settings.KOREKTURY_PDF_DIR))
|
||||
img_dir = os.path.join(settings.BASE_DIR, os.path.join('media', settings.KOREKTURY_IMG_DIR))
|
||||
rmtree(pdf_dir, ignore_errors=True)
|
||||
os.makedirs(pdf_dir)
|
||||
rmtree(img_dir, ignore_errors=True)
|
||||
os.makedirs(img_dir)
|
||||
|
||||
def gen_filename(filename):
|
||||
name = generate_filename(None, filename)
|
||||
print(name)
|
||||
copyfile(os.path.join(testpdfs, filename), os.path.join(settings.BASE_DIR, os.path.join('media', name)))
|
||||
return name
|
||||
|
||||
# TODO silent ghostscript (vypisuje odstavec za každou stránku…)
|
||||
|
||||
KorekturovanePDF.objects.create(
|
||||
nazev='B', komentar='Neuronové sítě', org=rnd.choice(organizatori), pdf=gen_filename(filename='B.pdf')
|
||||
)
|
||||
|
||||
KorekturovanePDF.objects.create(
|
||||
nazev='A', komentar='M&M: Jak řešit?', org=rnd.choice(organizatori), pdf=gen_filename(filename='A.pdf')
|
||||
)
|
||||
|
||||
korekturovane_pdf = KorekturovanePDF.objects.create(
|
||||
nazev='A', komentar='M&M: Jak řešit?', org=rnd.choice(organizatori), pdf=gen_filename(filename='A.pdf'),
|
||||
status='zanaseni'
|
||||
)
|
||||
|
||||
KorekturovanePDF.objects.create(
|
||||
nazev='A', komentar='M&M: Jak řešit?', org=rnd.choice(organizatori), pdf=gen_filename(filename='A.pdf'),
|
||||
status='zastarale'
|
||||
)
|
||||
except (FileNotFoundError, Exception) as e:
|
||||
# TODO najít správné chyby, které vyhazují různé systémy při neexistenci ImageMagick, nebo knihoven
|
||||
logger.error(str(e))
|
||||
logger.error(
|
||||
'Chyba vytváření testovacích korektur, pravděpodobně není nainstalován ImageMagick nebo některá z knihoven'
|
||||
'pro práci se soubory pdf (ghostscript) nebo png (libpng?).\n'
|
||||
'''
|
||||
Instalaci na linux provedete např. příkazy:
|
||||
sudo apt-get build-dep imagemagick
|
||||
git clone https://github.com/ImageMagick/ImageMagick.git
|
||||
cd ImageMagick/
|
||||
./configure
|
||||
make
|
||||
sudo make install
|
||||
sudo ldconfig /usr/local/lib
|
||||
cd ..
|
||||
rm -r ImageMagick/
|
||||
'''
|
||||
)
|
|
@ -1,13 +1,10 @@
|
|||
from django.conf.urls import * # NOQA
|
||||
from django.conf.urls import url
|
||||
from django.contrib.auth.decorators import user_passes_test
|
||||
from django.urls import path
|
||||
from seminar.utils import org_required
|
||||
from . import views
|
||||
|
||||
staff_member_required = user_passes_test(lambda u: u.is_staff)
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^korektury/$', staff_member_required(views.KorekturyAktualniListView.as_view()), name='korektury-list'),
|
||||
url(r'^korektury/zastarale/$', staff_member_required(views.KorekturyZastaraleListView.as_view()), name='korektury-list-zastarale'),
|
||||
url(r'^korektury/(?P<pdf>\d+)/$', staff_member_required(views.KorekturyView.as_view()), name='korektury'),
|
||||
url(r'^korektury/help/', staff_member_required(views.KorekturyHelpView.as_view()), name='korektury-help'),
|
||||
path('korektury/', org_required(views.KorekturyAktualniListView.as_view()), name='korektury_list'),
|
||||
path('korektury/zastarale/', org_required(views.KorekturyZastaraleListView.as_view()), name='korektury_stare_list'),
|
||||
path('korektury/<int:pdf>/', org_required(views.KorekturyView.as_view()), name='korektury'),
|
||||
path('korektury/help/', org_required(views.KorekturyHelpView.as_view()), name='korektury-help'),
|
||||
]
|
||||
|
|
|
@ -5,6 +5,7 @@ from django.utils.translation import ugettext as _
|
|||
from django.conf import settings
|
||||
from django.http import HttpResponseForbidden
|
||||
from django.core.mail import send_mail
|
||||
from django.db.models import Count,Q
|
||||
|
||||
from .models import Oprava,Komentar,KorekturovanePDF, Organizator
|
||||
from .forms import OpravaForm
|
||||
|
@ -12,14 +13,21 @@ from .forms import OpravaForm
|
|||
import subprocess
|
||||
import shutil
|
||||
import os
|
||||
import unicodedata
|
||||
|
||||
class KorekturyHelpView(generic.TemplateView):
|
||||
template_name = 'korektury/help.html'
|
||||
template_name = 'korektury/help.html'
|
||||
|
||||
|
||||
class KorekturyListView(generic.ListView):
|
||||
model = KorekturovanePDF
|
||||
template_name = 'korektury/seznam.html'
|
||||
model = KorekturovanePDF
|
||||
# Nefunguje, filtry se vubec nepouziji
|
||||
queryset = KorekturovanePDF.objects.annotate(
|
||||
k_oprave_cnt=Count('oprava',distinct=True,filter=Q(oprava__status='k_oprave')),
|
||||
opraveno_cnt=Count('oprava',distinct=True,filter=Q(oprava__status='opraveno')),
|
||||
neni_chyba_cnt=Count('oprava',distinct=True,filter=Q(oprava__status='neni_chyba')),
|
||||
k_zaneseni_cnt=Count('oprava',distinct=True,filter=Q(oprava__status='k_zaneseni')),
|
||||
)
|
||||
template_name = 'korektury/seznam.html'
|
||||
|
||||
class KorekturyAktualniListView(KorekturyListView):
|
||||
def get_queryset(self, *args, **kwargs):
|
||||
|
@ -45,178 +53,185 @@ class KorekturyZastaraleListView(KorekturyListView):
|
|||
|
||||
### Korektury
|
||||
class KorekturyView(generic.TemplateView):
|
||||
model = Oprava
|
||||
template_name = 'korektury/opraf.html'
|
||||
form_class = OpravaForm
|
||||
model = Oprava
|
||||
template_name = 'korektury/opraf.html'
|
||||
form_class = OpravaForm
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
form = self.form_class(request.POST)
|
||||
q = request.POST
|
||||
scroll = q.get('scroll')
|
||||
def post(self, request, *args, **kwargs):
|
||||
form = self.form_class(request.POST)
|
||||
q = request.POST
|
||||
scroll = q.get('scroll')
|
||||
|
||||
# prirazeni autora podle prihlaseni
|
||||
autor_user = request.user
|
||||
# pokud existuje ucet (user), ale neni to organizator = 403
|
||||
autor = Organizator.objects.filter(user=autor_user).first()
|
||||
if not autor:
|
||||
return HttpResponseForbidden()
|
||||
# prirazeni autora podle prihlaseni
|
||||
autor_user = request.user
|
||||
# pokud existuje ucet (user), ale neni to organizator = 403
|
||||
autor = Organizator.objects.filter(osoba__user=autor_user).first()
|
||||
if not autor:
|
||||
return HttpResponseForbidden()
|
||||
|
||||
if not scroll:
|
||||
scroll = 0
|
||||
if not scroll:
|
||||
scroll = 0
|
||||
|
||||
action = q.get('action')
|
||||
if (action == u''): # Přidej
|
||||
x = int(q.get('x'))
|
||||
y = int(q.get('y'))
|
||||
text = q.get('txt')
|
||||
strana = int(q.get('img-id')[4:])
|
||||
pdf = KorekturovanePDF.objects.get(id=q.get('pdf'))
|
||||
action = q.get('action')
|
||||
if (action == ''): # Přidej
|
||||
x = int(q.get('x'))
|
||||
y = int(q.get('y'))
|
||||
text = q.get('txt')
|
||||
strana = int(q.get('img-id')[4:])
|
||||
pdf = KorekturovanePDF.objects.get(id=q.get('pdf'))
|
||||
|
||||
op = Oprava(x=x,y=y, autor=autor, text=text, strana=strana,pdf = pdf)
|
||||
op.save()
|
||||
self.send_email_notification_komentar(op, autor, text)
|
||||
elif (action == u'del'):
|
||||
id = int(q.get('id'))
|
||||
op = Oprava.objects.get(id=id)
|
||||
op.delete()
|
||||
elif (action == u'update'):
|
||||
id = int(q.get('id'))
|
||||
op = Oprava.objects.get(id=id)
|
||||
text = q.get('txt')
|
||||
op.autor = autor
|
||||
op.text = text
|
||||
op.save()
|
||||
elif (action == u'undone'):
|
||||
id = int(q.get('id'))
|
||||
op = Oprava.objects.get(id=id)
|
||||
op.status = op.STATUS_K_OPRAVE
|
||||
op.save()
|
||||
elif (action == u'done'):
|
||||
id = int(q.get('id'))
|
||||
op = Oprava.objects.get(id=id)
|
||||
op.status = op.STATUS_OPRAVENO
|
||||
op.save()
|
||||
elif (action == u'ready'):
|
||||
id = int(q.get('id'))
|
||||
op = Oprava.objects.get(id=id)
|
||||
op.status = op.STATUS_K_ZANESENI
|
||||
op.save()
|
||||
elif (action == u'wontfix'):
|
||||
id = int(q.get('id'))
|
||||
op = Oprava.objects.get(id=id)
|
||||
op.status = op.STATUS_NENI_CHYBA
|
||||
op.save()
|
||||
elif (action == u'comment'):
|
||||
id = int(q.get('id'))
|
||||
op = Oprava.objects.get(id=id)
|
||||
text = q.get('txt')
|
||||
kom = Komentar(oprava=op,autor=autor,text=text)
|
||||
kom.save()
|
||||
self.send_email_notification_komentar(op, autor, text)
|
||||
elif (action == u'update-comment'):
|
||||
id = int(q.get('id'))
|
||||
kom = Komentar.objects.get(id=id)
|
||||
text = q.get('txt')
|
||||
kom.text = text
|
||||
kom.autor = autor
|
||||
kom.save()
|
||||
elif (action == u'del-comment'):
|
||||
id = int(q.get('id'))
|
||||
kom = Komentar.objects.get(id=id)
|
||||
kom.delete()
|
||||
elif (action == u'set-state'):
|
||||
pdf = KorekturovanePDF.objects.get(id=q.get('pdf'))
|
||||
if (q.get('state') == u'adding'):
|
||||
pdf.status = pdf.STATUS_PRIDAVANI
|
||||
elif (q.get('state') == u'comitting'):
|
||||
pdf.status = pdf.STATUS_ZANASENI
|
||||
elif (q.get('state') == u'deprecated'):
|
||||
pdf.status = pdf.STATUS_ZASTARALE
|
||||
pdf.save()
|
||||
context = self.get_context_data()
|
||||
context['scroll'] = scroll
|
||||
context['autor'] = autor
|
||||
return render(request, 'korektury/opraf.html',context)
|
||||
op = Oprava(x=x,y=y, autor=autor, text=text, strana=strana,pdf = pdf)
|
||||
op.save()
|
||||
self.send_email_notification_komentar(op, autor, text)
|
||||
elif (action == 'del'):
|
||||
id = int(q.get('id'))
|
||||
op = Oprava.objects.get(id=id)
|
||||
op.delete()
|
||||
elif (action == 'update'):
|
||||
id = int(q.get('id'))
|
||||
op = Oprava.objects.get(id=id)
|
||||
text = q.get('txt')
|
||||
op.autor = autor
|
||||
op.text = text
|
||||
op.save()
|
||||
elif (action == 'undone'):
|
||||
id = int(q.get('id'))
|
||||
op = Oprava.objects.get(id=id)
|
||||
op.status = op.STATUS_K_OPRAVE
|
||||
op.save()
|
||||
elif (action == 'done'):
|
||||
id = int(q.get('id'))
|
||||
op = Oprava.objects.get(id=id)
|
||||
op.status = op.STATUS_OPRAVENO
|
||||
op.save()
|
||||
elif (action == 'ready'):
|
||||
id = int(q.get('id'))
|
||||
op = Oprava.objects.get(id=id)
|
||||
op.status = op.STATUS_K_ZANESENI
|
||||
op.save()
|
||||
elif (action == 'wontfix'):
|
||||
id = int(q.get('id'))
|
||||
op = Oprava.objects.get(id=id)
|
||||
op.status = op.STATUS_NENI_CHYBA
|
||||
op.save()
|
||||
elif (action == 'comment'):
|
||||
id = int(q.get('id'))
|
||||
op = Oprava.objects.get(id=id)
|
||||
text = q.get('txt')
|
||||
kom = Komentar(oprava=op,autor=autor,text=text)
|
||||
kom.save()
|
||||
self.send_email_notification_komentar(op, autor, text)
|
||||
elif (action == 'update-comment'):
|
||||
id = int(q.get('id'))
|
||||
kom = Komentar.objects.get(id=id)
|
||||
text = q.get('txt')
|
||||
kom.text = text
|
||||
kom.autor = autor
|
||||
kom.save()
|
||||
elif (action == 'del-comment'):
|
||||
id = int(q.get('id'))
|
||||
kom = Komentar.objects.get(id=id)
|
||||
kom.delete()
|
||||
elif (action == 'set-state'):
|
||||
pdf = KorekturovanePDF.objects.get(id=q.get('pdf'))
|
||||
if (q.get('state') == 'adding'):
|
||||
pdf.status = pdf.STATUS_PRIDAVANI
|
||||
elif (q.get('state') == 'comitting'):
|
||||
pdf.status = pdf.STATUS_ZANASENI
|
||||
elif (q.get('state') == 'deprecated'):
|
||||
pdf.status = pdf.STATUS_ZASTARALE
|
||||
pdf.save()
|
||||
context = self.get_context_data()
|
||||
context['scroll'] = scroll
|
||||
context['autor'] = autor
|
||||
return render(request, 'korektury/opraf.html',context)
|
||||
|
||||
def send_email_notification_komentar(self, oprava, autor, text):
|
||||
''' Rozesle e-mail pri pridani komentare,
|
||||
ktery obsahuje text komentare.
|
||||
'''
|
||||
def send_email_notification_komentar(self, oprava, autor, text):
|
||||
''' Rozesle e-mail pri pridani komentare,
|
||||
ktery obsahuje text komentare.
|
||||
'''
|
||||
|
||||
# parametry e-mailu
|
||||
odkaz = "https://mam.mff.cuni.cz/korektury/{}/".format(oprava.pdf.pk)
|
||||
from_email = 'korekturovatko@mam.mff.cuni.cz'
|
||||
subject = u'Nová korektura od {} v {}'.format(autor,
|
||||
oprava.pdf.nazev)
|
||||
text = u"Text komentáře:\n\n{}\n\n=== Konec textu komentáře ===\n\
|
||||
\nodkaz do korekturovátka: {}\n\
|
||||
\nVaše korekturovátko\n".format(text, odkaz)
|
||||
# parametry e-mailu
|
||||
#odkaz = "https://mam.mff.cuni.cz/korektury/{}/".format(oprava.pdf.pk)
|
||||
from django.urls import reverse
|
||||
odkaz = self.request.build_absolute_uri(reverse('korektury', kwargs={'pdf': oprava.pdf.pk}))
|
||||
from_email = 'korekturovatko@mam.mff.cuni.cz'
|
||||
subject = 'Nová korektura od {} v {}'.format(autor,
|
||||
oprava.pdf.nazev)
|
||||
text = u"Text komentáře:\n\n{}\n\n=== Konec textu komentáře ===\n\
|
||||
\nodkaz do korekturovátka: {}\n\
|
||||
\nVaše korekturovátko\n".format(text, odkaz)
|
||||
|
||||
# Prijemci e-mailu
|
||||
emails = set()
|
||||
# e-mail autora korektury
|
||||
email = oprava.autor.user.email
|
||||
if email:
|
||||
emails.add(email)
|
||||
# Prijemci e-mailu
|
||||
emails = set()
|
||||
# e-mail autora korektury
|
||||
email = oprava.autor.osoba.email
|
||||
if email:
|
||||
emails.add(email)
|
||||
|
||||
# nalezeni e-mailu na autory komentaru
|
||||
for komentar in oprava.komentar_set.all():
|
||||
email_komentujiciho = komentar.autor.user.email
|
||||
if email_komentujiciho:
|
||||
emails.add(email_komentujiciho)
|
||||
# nalezeni e-mailu na autory komentaru
|
||||
for komentar in oprava.komentar_set.all():
|
||||
email_komentujiciho = komentar.autor.osoba.email
|
||||
if email_komentujiciho:
|
||||
emails.add(email_komentujiciho)
|
||||
|
||||
# zodpovedny org
|
||||
if oprava.pdf.org:
|
||||
email_zobpovedny = oprava.pdf.org.user.email
|
||||
if email_zobpovedny:
|
||||
emails.add(email_zobpovedny)
|
||||
# zodpovedny org
|
||||
if oprava.pdf.org:
|
||||
email_zobpovedny = oprava.pdf.org.osoba.email
|
||||
if email_zobpovedny:
|
||||
emails.add(email_zobpovedny)
|
||||
|
||||
# odstran e-mail autora opravy
|
||||
email = autor.user.email
|
||||
if email:
|
||||
emails.discard(email)
|
||||
# odstran e-mail autora opravy
|
||||
email = autor.osoba.email
|
||||
if email:
|
||||
emails.discard(email)
|
||||
|
||||
if not settings.SEND_EMAIL_NOTIFICATIONS:
|
||||
print "Poslal bych upozornění na tyto adresy: ", " ".join(emails)
|
||||
return
|
||||
if not settings.POSLI_MAILOVOU_NOTIFIKACI:
|
||||
print("Poslal bych upozornění na tyto adresy: ", " ".join(emails))
|
||||
return
|
||||
|
||||
send_mail(subject, text, from_email, list(emails))
|
||||
send_mail(subject, text, from_email, list(emails))
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(KorekturyView,self).get_context_data(**kwargs)
|
||||
pdf = get_object_or_404(KorekturovanePDF, id=self.kwargs['pdf'])
|
||||
context['pdf'] = pdf
|
||||
context['img_prefix'] = pdf.get_prefix()
|
||||
context['img_path'] = settings.KOREKTURY_IMG_DIR
|
||||
context['img_indexes'] = range(pdf.stran)
|
||||
context['form_oprava'] = OpravaForm()
|
||||
opravy = Oprava.objects.filter(pdf=self.kwargs['pdf'])
|
||||
zasluhy = {}
|
||||
for o in opravy:
|
||||
if o.autor in zasluhy:
|
||||
zasluhy[o.autor]+=1
|
||||
else:
|
||||
zasluhy[o.autor]=1
|
||||
o.komentare = o.komentar_set.all()
|
||||
for k in o.komentare:
|
||||
if k.autor in zasluhy:
|
||||
zasluhy[k.autor] += 1
|
||||
else:
|
||||
zasluhy[k.autor] = 1
|
||||
zasluhy = [
|
||||
{'autor': jmeno, 'pocet': pocet}
|
||||
for (jmeno, pocet) in zasluhy.items()
|
||||
]
|
||||
zasluhy.sort(key=lambda z: z['pocet'], reverse=True)
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(KorekturyView,self).get_context_data(**kwargs)
|
||||
pdf = get_object_or_404(KorekturovanePDF, id=self.kwargs['pdf'])
|
||||
context['pdf'] = pdf
|
||||
context['img_prefix'] = pdf.get_prefix()
|
||||
context['img_path'] = settings.KOREKTURY_IMG_DIR
|
||||
context['img_indexes'] = range(pdf.stran)
|
||||
context['form_oprava'] = OpravaForm()
|
||||
opravy = Oprava.objects.filter(pdf=self.kwargs['pdf'])
|
||||
zasluhy = {}
|
||||
for o in opravy:
|
||||
if o.autor in zasluhy:
|
||||
zasluhy[o.autor]+=1
|
||||
else:
|
||||
zasluhy[o.autor]=1
|
||||
o.komentare = o.komentar_set.all()
|
||||
for k in o.komentare:
|
||||
if k.autor in zasluhy:
|
||||
zasluhy[k.autor] += 1
|
||||
else:
|
||||
zasluhy[k.autor] = 1
|
||||
zasluhy = [
|
||||
{'autor': jmeno, 'pocet': pocet}
|
||||
for (jmeno, pocet) in zasluhy.items()
|
||||
]
|
||||
zasluhy.sort(key=lambda z: z['pocet'], reverse=True)
|
||||
|
||||
strany = set(o.strana for o in opravy)
|
||||
opravy_na_stranu = [{'strana': s, 'op_id': opravy.filter(strana=s)} for s in strany]
|
||||
context['opravy_strany'] = opravy_na_stranu
|
||||
|
||||
context['opravy'] = opravy
|
||||
context['zasluhy'] = zasluhy
|
||||
return context
|
||||
strany = set(o.strana for o in opravy)
|
||||
opravy_na_stranu = [{'strana': s, 'op_id': opravy.filter(strana=s)} for s in strany]
|
||||
context['opravy_strany'] = opravy_na_stranu
|
||||
|
||||
def form_valid(self,form):
|
||||
return super(KorekturyView,self).form_valid(form)
|
||||
context['k_oprave_cnt'] = opravy.filter(status='k_oprave').count()
|
||||
context['opraveno_cnt'] = opravy.filter(status='opraveno').count()
|
||||
context['neni_chyba_cnt'] = opravy.filter(status='neni_chyba').count()
|
||||
context['k_zaneseni_cnt'] = opravy.filter(status='k_zaneseni').count()
|
||||
|
||||
context['opravy'] = opravy
|
||||
context['zasluhy'] = zasluhy
|
||||
return context
|
||||
|
||||
def form_valid(self,form):
|
||||
return super(KorekturyView,self).form_valid(form)
|
||||
|
||||
|
|
|
@ -7,7 +7,8 @@ from django.contrib.flatpages.admin import FlatpageForm as FlatpageFormOld
|
|||
|
||||
from django import forms
|
||||
from ckeditor_uploader.widgets import CKEditorUploadingWidget
|
||||
|
||||
|
||||
|
||||
class FlatpageForm(FlatpageFormOld):
|
||||
content = forms.CharField(widget=CKEditorUploadingWidget())
|
||||
class Meta:
|
||||
|
@ -22,3 +23,4 @@ class FlatPageAdmin(FlatPageAdminOld):
|
|||
# We have to unregister the normal admin, and then reregister ours
|
||||
admin.site.unregister(FlatPage)
|
||||
admin.site.register(FlatPage, FlatPageAdmin)
|
||||
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
|
||||
from datetime import datetime, date
|
||||
|
||||
def vzhled(request):
|
||||
''' Podle casu prida do templatu, zdali je nebo neni noc '''
|
||||
hodin = datetime.now().hour
|
||||
if (hodin <= 6) or (hodin >= 20):
|
||||
noc = True
|
||||
else:
|
||||
noc = False
|
||||
return {'noc' : noc}
|
||||
|
||||
def april(req):
|
||||
if 'HTTP_X_APRIL' in req.META:
|
||||
try:
|
||||
year = int(req.META['HTTP_X_APRIL'])
|
||||
return {'april': year}
|
||||
except:
|
||||
pass # Fall-back to regular behaviour
|
||||
|
||||
import datetime
|
||||
today = datetime.date.today()
|
||||
if today.day == 1 and today.month == 4:
|
||||
return {'april': today.year}
|
||||
return {}
|
||||
|
||||
|
15
mamweb/routers.py
Normal file
|
@ -0,0 +1,15 @@
|
|||
from rest_framework import routers
|
||||
from seminar import viewsets as vs
|
||||
|
||||
router = routers.DefaultRouter()
|
||||
|
||||
router.register(r'ulohavzoraknode', vs.UlohaVzorakNodeViewSet,basename='ulohavzoraknode')
|
||||
router.register(r'reseninode', vs.ReseniNodeViewSet,basename='reseninode')
|
||||
router.register(r'text', vs.TextViewSet)
|
||||
router.register(r'textnode', vs.TextNodeViewSet)
|
||||
router.register(r'castnode', vs.CastNodeViewSet)
|
||||
router.register(r'problem', vs.ProblemViewSet, basename='problem')
|
||||
router.register(r'uloha', vs.UlohaViewSet, basename='uloha')
|
||||
router.register(r'reseni', vs.ReseniViewSet, basename='reseni')
|
||||
router.register(r'ulohazadaninode', vs.UlohaZadaniNodeViewSet)
|
||||
|
|
@ -43,7 +43,8 @@ STATICFILES_FINDERS = (
|
|||
)
|
||||
|
||||
# Where redirect for login required services
|
||||
LOGIN_URL = '/admin/login'
|
||||
LOGIN_URL = 'login'
|
||||
LOGIN_REDIRECT_URL = 'profil'
|
||||
|
||||
# Modules configuration
|
||||
|
||||
|
@ -52,14 +53,15 @@ AUTHENTICATION_BACKENDS = (
|
|||
)
|
||||
|
||||
|
||||
MIDDLEWARE_CLASSES = (
|
||||
'reversion.middleware.RevisionMiddleware',
|
||||
MIDDLEWARE = (
|
||||
# 'reversion.middleware.RevisionMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'mamweb.middleware.LoggedInHintCookieMiddleware',
|
||||
# FIXME: rozbilo se při přechodu na Django 2.0, nevím, jestli
|
||||
# se to dá zahodit bez náhrady
|
||||
# 'mamweb.middleware.LoggedInHintCookieMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware',
|
||||
|
@ -73,10 +75,11 @@ TEMPLATES = [
|
|||
'OPTIONS': {
|
||||
'context_processors': (
|
||||
'django.contrib.auth.context_processors.auth',
|
||||
'django.template.context_processors.request',
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
'sekizai.context_processors.sekizai',
|
||||
'mamweb.context_processors.vzhled',
|
||||
'mamweb.context_processors.april',
|
||||
'header_fotky.context_processors.vzhled',
|
||||
'various.context_processors.april',
|
||||
)
|
||||
},
|
||||
},
|
||||
|
@ -103,7 +106,8 @@ INSTALLED_APPS = (
|
|||
'ckeditor',
|
||||
'ckeditor_uploader',
|
||||
'taggit',
|
||||
'autocomplete_light',
|
||||
'dal',
|
||||
'dal_select2',
|
||||
|
||||
'fluent_comments',
|
||||
'crispy_forms',
|
||||
|
@ -113,14 +117,24 @@ INSTALLED_APPS = (
|
|||
'django.contrib.flatpages',
|
||||
'django.contrib.humanize',
|
||||
|
||||
'sitetree',
|
||||
|
||||
'imagekit',
|
||||
|
||||
'polymorphic',
|
||||
|
||||
'webpack_loader',
|
||||
'rest_framework',
|
||||
'rest_framework.authtoken',
|
||||
|
||||
# MaMweb
|
||||
'mamweb',
|
||||
'seminar',
|
||||
'galerie',
|
||||
'korektury',
|
||||
'prednasky',
|
||||
'header_fotky',
|
||||
'various',
|
||||
|
||||
# Admin upravy:
|
||||
|
||||
|
@ -177,6 +191,27 @@ CKEDITOR_CONFIGS = {
|
|||
},
|
||||
}
|
||||
|
||||
# Webpack loader
|
||||
VUE_FRONTEND_DIR = os.path.join(BASE_DIR, 'vue_frontend')
|
||||
|
||||
WEBPACK_LOADER = {
|
||||
'DEFAULT': {
|
||||
'CACHE': False,
|
||||
'BUNDLE_DIR_NAME': 'vue/', # must end with slash
|
||||
'STATS_FILE': os.path.join(VUE_FRONTEND_DIR, 'webpack-stats.json'),
|
||||
'POLL_INTERVAL': 0.1,
|
||||
'TIMEOUT': None,
|
||||
'IGNORE': [r'.+\.hot-update.js', r'.+\.map']
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Dajngo REST Framework
|
||||
|
||||
REST_FRAMEWORK = {
|
||||
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
|
||||
'PAGE_SIZE': 100
|
||||
}
|
||||
|
||||
# Comments
|
||||
|
||||
|
@ -212,6 +247,14 @@ LOGGING = {
|
|||
'handlers': ['console'],
|
||||
'level': 'DEBUG',
|
||||
},
|
||||
'seminar.prihlaska.form':{
|
||||
'handlers': ['console','registration_logfile'],
|
||||
'level': 'INFO'
|
||||
},
|
||||
'seminar.prihlaska.problem':{
|
||||
'handlers': ['console','mail_registration','registration_error_log'],
|
||||
'level': 'INFO'
|
||||
},
|
||||
|
||||
# Catch-all logger
|
||||
'': {
|
||||
|
@ -230,10 +273,28 @@ LOGGING = {
|
|||
},
|
||||
|
||||
'mail_admins': {
|
||||
'level': 'ERROR',
|
||||
'level': 'WARNING',
|
||||
'class': 'django.utils.log.AdminEmailHandler',
|
||||
'formatter': 'verbose',
|
||||
},
|
||||
'mail_registration': {
|
||||
'level': 'WARNING',
|
||||
'class': 'django.utils.log.AdminEmailHandler',
|
||||
'formatter': 'verbose',
|
||||
},
|
||||
'registration_logfile':{
|
||||
'level': 'INFO',
|
||||
'class': 'logging.FileHandler',
|
||||
# filename declared in specific configuration files
|
||||
'formatter': 'verbose',
|
||||
},
|
||||
'registration_error_log':{
|
||||
'level': 'INFO',
|
||||
'class': 'logging.FileHandler',
|
||||
# filename declared in specific configuration files
|
||||
'formatter': 'verbose',
|
||||
},
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -250,4 +311,4 @@ CISLO_IMG_DIR = os.path.join('cislo', 'img')
|
|||
|
||||
|
||||
# E-MAIL NOTIFICATIONS
|
||||
SEND_EMAIL_NOTIFICATIONS = False
|
||||
POSLI_MAILOVOU_NOTIFIKACI = False
|
||||
|
|
13
mamweb/settings_debug.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
# Debugovaci nastaveni settings.py
|
||||
# Pro vyber tohoto nastaveni muzete pouzit tez:
|
||||
# DJANGO_SETTINGS_MODULE=mamweb.settings_debug ./manage.py ...
|
||||
|
||||
# Import local settings
|
||||
from .settings_local import *
|
||||
|
||||
# Vypisovani databazovych dotazu do konzole
|
||||
LOGGING['loggers']['django.db.backends'] = {
|
||||
'level': 'DEBUG',
|
||||
'handlers': ['console'],
|
||||
'propagate': False,
|
||||
}
|
|
@ -10,7 +10,7 @@ import os.path
|
|||
# Import common settings
|
||||
from .settings_common import *
|
||||
|
||||
MIDDLEWARE_CLASSES += (
|
||||
MIDDLEWARE += (
|
||||
'debug_toolbar.middleware.DebugToolbarMiddleware',
|
||||
)
|
||||
|
||||
|
@ -24,10 +24,11 @@ INSTALLED_APPS += (
|
|||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = True
|
||||
INTERNAL_IPS = ['127.0.0.1']
|
||||
|
||||
TEMPLATES[0]['OPTIONS']['debug'] = True
|
||||
|
||||
ALLOWED_HOSTS = ['127.0.0.1']
|
||||
ALLOWED_HOSTS = ['127.0.0.1', '192.168.43.34']
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/1.7/ref/settings/#databases
|
||||
|
@ -47,7 +48,52 @@ DATABASES = {
|
|||
#}
|
||||
|
||||
# LOGGING
|
||||
LOGGING = {
|
||||
'version': 1,
|
||||
'disable_existing_loggers': True,
|
||||
'filters': {
|
||||
'require_debug_false': {
|
||||
'()': 'django.utils.log.RequireDebugFalse'
|
||||
}
|
||||
},
|
||||
'formatters': {
|
||||
'simple': {
|
||||
'format': '%(asctime)s - %(name)s - %(levelname)-8s - %(message)s',
|
||||
},
|
||||
},
|
||||
'handlers': {
|
||||
'dummy': {
|
||||
'class': 'logging.NullHandler',
|
||||
},
|
||||
'console': {
|
||||
'level': 'DEBUG',
|
||||
'class': 'logging.StreamHandler',
|
||||
'formatter': 'simple',
|
||||
},
|
||||
},
|
||||
'loggers': {
|
||||
# Vypisovani databazovych dotazu do konzole
|
||||
#'django.db.backends': {
|
||||
# 'level': 'DEBUG',
|
||||
# 'handlers': ['console'],
|
||||
# 'propagate': False,
|
||||
#},
|
||||
'werkzeug': {
|
||||
'handlers': ['console'],
|
||||
'level': 'DEBUG',
|
||||
'propagate': True,
|
||||
},
|
||||
'': {
|
||||
'handlers': ['console'],
|
||||
'level': 'DEBUG',
|
||||
'propagate': False,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
# set to 'DEBUG' for EXTRA verbose output
|
||||
LOGGING['handlers']['console']['level'] = 'INFO'
|
||||
# LOGGING['handlers']['console']['level'] = 'INFO'
|
||||
|
||||
# E-maily posílat chceme, ale do terminálu :-)
|
||||
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
||||
SEND_EMAIL_NOTIFICATIONS = True
|
||||
|
|
|
@ -61,7 +61,9 @@ CSRF_COOKIE_SECURE = True
|
|||
|
||||
LOGGING['loggers']['']['handlers'] = ['console', 'mail_admins']
|
||||
LOGGING['loggers']['django']['handlers'] = ['console', 'mail_admins']
|
||||
LOGGING['handlers']['registration_logfile']['filename'] = '/home/mam-web/logs/prod/registration.log'
|
||||
LOGGING['handlers']['registration_error_log']['filename'] = '/home/mam-web/logs/prod/registration_errors.log'
|
||||
|
||||
|
||||
# E-MAIL NOTIFICATIONS
|
||||
SEND_EMAIL_NOTIFICATIONS = True
|
||||
POSLI_MAILOVOU_NOTIFIKACI = True
|
||||
|
|
|
@ -12,7 +12,7 @@ import os.path
|
|||
# Import common settings
|
||||
from .settings_common import * # zatim nutne, casem snad vyresime # noqa
|
||||
|
||||
MIDDLEWARE_CLASSES += (
|
||||
MIDDLEWARE += (
|
||||
'debug_toolbar.middleware.DebugToolbarMiddleware',
|
||||
)
|
||||
|
||||
|
@ -32,7 +32,7 @@ DEBUG = True
|
|||
|
||||
TEMPLATES[0]['OPTIONS']['debug'] = True
|
||||
|
||||
ALLOWED_HOSTS = ['*.mam.mff.cuni.cz', 'atrey.karlin.mff.cuni.cz', 'mam.mff.cuni.cz', 'mam-test.kam.mff.cuni.cz', 'gimli.ms.mff.cuni.cz']
|
||||
ALLOWED_HOSTS = ['*.mam.mff.cuni.cz', 'atrey.karlin.mff.cuni.cz', 'mam.mff.cuni.cz', 'mam-test.kam.mff.cuni.cz', 'gimli.ms.mff.cuni.cz', 'mam-test.ks.matfyz.cz']
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/1.7/ref/settings/#databases
|
||||
|
@ -65,3 +65,14 @@ CSRF_COOKIE_SECURE = True
|
|||
|
||||
LOGGING['loggers']['']['handlers'] = ['console', 'mail_admins']
|
||||
LOGGING['loggers']['django']['handlers'] = ['console', 'mail_admins']
|
||||
LOGGING['handlers']['registration_logfile']['filename'] = '/home/mam-web/logs/test/registration.log'
|
||||
LOGGING['handlers']['registration_error_log']['filename'] = '/home/mam-web/logs/test/registration_errors.log'
|
||||
|
||||
FILE_UPLOAD_PERMISSIONS = 0o440
|
||||
|
||||
# Testování e-mailů
|
||||
POSLI_MAILOVOU_NOTIFIKACI = True
|
||||
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']
|
||||
|
|
38
mamweb/static/css/mamweb-dev.css
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
.pink {
|
||||
background-color: #ffc0cb;
|
||||
}
|
||||
|
||||
div.borderized {
|
||||
border-style: solid;
|
||||
border-radius: 5px;
|
||||
padding: 5px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
div.tnmenu {
|
||||
float: right;
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
|
||||
div.parent {
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
div.children {
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
div.node_type {
|
||||
background-color: #d4d4d4;
|
||||
}
|
||||
|
||||
.hidden-tn {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/*test*/
|
||||
h1 {
|
||||
color: chartreuse;
|
||||
}
|
Before Width: | Height: | Size: 218 B |
201
mamweb/static/fonts/OpenSans/Apache License.txt
Normal file
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
BIN
mamweb/static/fonts/OpenSans/OpenSans-Bold.ttf
Normal file
BIN
mamweb/static/fonts/OpenSans/OpenSans-BoldItalic.ttf
Normal file
BIN
mamweb/static/fonts/OpenSans/OpenSans-ExtraBold.ttf
Normal file
BIN
mamweb/static/fonts/OpenSans/OpenSans-ExtraBoldItalic.ttf
Normal file
BIN
mamweb/static/fonts/OpenSans/OpenSans-Italic.ttf
Normal file
BIN
mamweb/static/fonts/OpenSans/OpenSans-Light.ttf
Normal file
BIN
mamweb/static/fonts/OpenSans/OpenSans-LightItalic.ttf
Normal file
BIN
mamweb/static/fonts/OpenSans/OpenSans-Regular.ttf
Normal file
BIN
mamweb/static/fonts/OpenSans/OpenSans-Semibold.ttf
Normal file
BIN
mamweb/static/fonts/OpenSans/OpenSans-SemiboldItalic.ttf
Normal file
120
mamweb/static/images/MATFYZ_MM_barevne.svg
Normal file
|
@ -0,0 +1,120 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="svg2"
|
||||
xml:space="preserve"
|
||||
width="873.38959"
|
||||
height="697.76959"
|
||||
viewBox="0 0 873.38957 697.7696"
|
||||
sodipodi:docname="MATFYZ_MM_barevne.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"><metadata
|
||||
id="metadata8"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs6" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1853"
|
||||
inkscape:window-height="1025"
|
||||
id="namedview4"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.29733907"
|
||||
inkscape:cx="436.69495"
|
||||
inkscape:cy="348.92161"
|
||||
inkscape:window-x="67"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="g10" /><g
|
||||
id="g10"
|
||||
inkscape:groupmode="layer"
|
||||
inkscape:label="ink_ext_XXXXXX"
|
||||
transform="matrix(1.3333333,0,0,-1.3333333,-124.56506,745.70131)"><g
|
||||
id="g12"
|
||||
transform="scale(0.1)"><path
|
||||
d="M 7483.93,3086.74 6136.77,1739.57 h -1324.9 l 1347.41,1347.17 h 1324.65"
|
||||
style="fill:#e94e0f;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path14"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="m 7210.43,1001.61 v -88.579 h -308.59 v 91.489 l 179.35,190.24 H 6909.1 v 88.58 h 294.07 v -91.49 l -179.35,-190.24 h 186.61"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path16"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="M 6847.38,1283.34 6704.34,793.219 h -100.93 l 34.85,119.812 H 6578 l -108.19,370.309 h 114.72 l 73.34,-298.43 74.06,298.43 h 115.45"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path18"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="m 6437.13,1415.49 -5.08,-72.61 c -21.06,2.18 -37.76,2.9 -50.1,2.9 -52.28,0 -60.99,-6.53 -62.45,-63.17 h 94.4 v -87.85 h -94.4 V 913.031 h -108.91 v 387.009 c 0,96.57 32.67,128.52 129.24,128.52 36.31,0 74.07,-5.81 97.3,-13.07"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path20"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="M 6151.29,3087.46 C 5702.07,2638.25 5252.62,2188.79 4803.4,1739.57 h -3.15 l -0.72,0.73 1347.4,1347.16 h 4.36"
|
||||
style="fill:#e94e0f;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path22"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="m 6116.92,998.711 5.81,-78.422 c -24.69,-7.988 -67.53,-14.519 -99.48,-14.519 -80.59,0 -119.8,25.41 -119.8,124.16 v 321.66 l 108.91,30.5 v -98.75 h 87.13 v -88.58 h -87.13 V 1056.8 c 0,-54.46 6.54,-62.448 48.65,-62.448 15.98,0 37.76,1.449 55.91,4.359"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path24"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="m 5685.62,1068.41 c -26.14,1.45 -52.28,2.91 -68.26,2.91 -38.48,-0.73 -53,-15.98 -53,-44.3 0,-26.86 18.87,-44.29 56.63,-44.29 24.69,0 46.47,8.719 64.63,21.06 z m 0,67.53 v 3.63 c 0,55.91 -17.43,65.35 -74.07,65.35 -38.48,0 -80.59,-2.9 -122.71,-6.53 l -5.08,77.69 c 43.56,7.99 104.56,14.52 147.4,14.52 124.16,0 163.37,-31.95 163.37,-148.13 V 913.031 h -72.61 l -22.51,37.75 c -31.22,-27.59 -69.7,-45.011 -116.9,-45.011 -79.15,0 -124.16,47.921 -124.16,119.8 0,84.96 47.92,113.28 153.2,113.28 23.24,0.72 49.38,-0.73 74.07,-2.91"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path26"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="m 5424.22,522.629 -17.19,-154.66 h -50.58 l 31.71,231.859 h 50.1 l 51.31,-134.078 50.58,134.078 h 51.56 l 30.49,-231.859 h -50.82 l -16.7,156.351 -45.27,-119.082 h -41.62 l -43.57,117.391"
|
||||
style="fill:#e94e0f;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path28"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="m 5204.69,402.09 c 9.93,0 18.64,2.91 26.87,8.23 l -54.7,56.399 c -8.47,-7.02 -12.83,-16.457 -12.83,-28.559 0,-21.789 17.43,-36.07 40.66,-36.07 z m -88.58,30.98 c 0,25.168 13.31,48.172 35.58,61.239 -13.07,16.461 -19.61,31.953 -19.61,47.203 0,19.84 6.78,35.57 20.33,47.918 13.8,12.582 31.71,18.879 53.98,18.879 52.04,0 77.93,-20.817 81.81,-65.11 h -53.74 c -1.45,16.942 -11.13,25.903 -28.07,25.903 -13.56,0 -23.96,-8.481 -23.96,-23.243 0,-11.859 4.6,-19.847 20.09,-35.82 l 56.39,-58.09 c 3.87,13.563 5.81,27.84 5.81,43.813 h 50.83 c 0,-28.563 -7.51,-54.942 -22.76,-79.153 l 47.2,-48.64 h -67.04 l -13.07,13.07 c -17.19,-12.109 -36.07,-18.16 -57.36,-18.16 -24.21,0 -45.02,6.051 -61.72,18.402 -16.7,12.578 -24.69,29.77 -24.69,51.789"
|
||||
style="fill:#e94e0f;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path30"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="m 5130.87,1248.49 c 39.94,25.41 89.31,42.11 127.8,42.11 72.61,0 109.64,-39.94 109.64,-121.98 V 913.031 h -108.92 v 212.019 c 0,67.53 -7.26,76.97 -53,76.97 -17.43,0 -38.49,-2.18 -58.09,-6.54 0.73,-8.71 1.45,-17.43 1.45,-26.86 V 913.031 h -108.91 v 212.019 c 0,67.53 -7.26,76.97 -53.01,76.97 -17.43,0 -38.48,-2.18 -58.09,-6.54 V 913.031 h -108.91 v 370.309 h 72.61 l 19.6,-34.13 c 39.21,24.69 88.59,41.39 127.07,41.39 42.84,0 73.34,-13.79 90.76,-42.11"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path32"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="m 5019.05,524.32 -45.26,-119.082 h -41.63 l -43.56,117.391 -17.43,-154.66 h -50.34 l 31.7,231.859 h 50.1 l 51.07,-134.078 50.83,134.078 h 51.55 l 30.5,-231.859 h -50.83 l -16.7,156.351"
|
||||
style="fill:#e94e0f;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path34"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="M 6159.28,3086.74 4811.87,1739.57 h -8.47 c 449.22,449.22 898.67,898.68 1347.89,1347.89 h 1333.37 l -0.73,-0.72 H 6159.28"
|
||||
style="fill:#e94e0f;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path36"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="m 4800.25,1739.57 h -1.45 l 0.73,0.73 z"
|
||||
style="fill:#e94e0f;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path38"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="m 4782.34,1740.3 -0.24,-0.24 H 2883.34 v 1899 l 1899,-1898.76"
|
||||
style="fill:#e94e0f;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path40"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="M 4481.01,1707.38 V 359.488 H 3133.12 V 1707.38 h 1347.89"
|
||||
style="fill:#e94e0f;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path42"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="M 2850.67,5592.76 V 3710.7 l -941.27,941.03 z"
|
||||
style="fill:#e94e0f;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path44"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="m 2845.59,3672.94 -953.14,-953.13 -953.126,953.13 953.126,953.14 953.14,-953.14"
|
||||
style="fill:#e94e0f;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path46"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="M 1875.27,4651.73 934.238,3710.7 v 1882.06 z"
|
||||
style="fill:#e94e0f;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path48"
|
||||
inkscape:connector-curvature="0" /></g></g></svg>
|
After Width: | Height: | Size: 7.9 KiB |
BIN
mamweb/static/images/MSMT_logo_bez_textu_black.eps
Normal file
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 15 KiB |
BIN
mamweb/static/images/graf/adrenalinove.jpeg
Normal file
After Width: | Height: | Size: 568 KiB |
BIN
mamweb/static/images/graf/behaci.jpeg
Normal file
After Width: | Height: | Size: 203 KiB |
BIN
mamweb/static/images/graf/ceny.jpeg
Normal file
After Width: | Height: | Size: 2.4 MiB |
BIN
mamweb/static/images/graf/deskovky.jpeg
Normal file
After Width: | Height: | Size: 56 KiB |