Merge branch 'develop' into test
This commit is contained in:
commit
b7463638a5
52 changed files with 246 additions and 1268 deletions
187
MIGRATIONS
187
MIGRATIONS
|
@ -1,187 +0,0 @@
|
|||
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
|
||||
|
3
aesop/__init__.py
Normal file
3
aesop/__init__.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
"""
|
||||
Obsahuje vše, co se týká aesopu (exportu, který po nás vyžaduje OPMK).
|
||||
"""
|
5
aesop/apps.py
Normal file
5
aesop/apps.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class AesopConfig(AppConfig):
|
||||
name = 'aesop'
|
20
aesop/urls.py
Normal file
20
aesop/urls.py
Normal file
|
@ -0,0 +1,20 @@
|
|||
from django.urls import path
|
||||
from aesop import views
|
||||
|
||||
urlpatterns = [
|
||||
path(
|
||||
'aesop-export/mam-rocnik-<int:prvni_rok>.csv',
|
||||
views.ExportRocnikView.as_view(),
|
||||
name='seminar_export_rocnik'
|
||||
),
|
||||
path(
|
||||
'aesop-export/mam-sous-<str:datum_zacatku>.csv',
|
||||
views.ExportSousView.as_view(),
|
||||
name='seminar_export_sous'
|
||||
),
|
||||
path(
|
||||
'aesop-export/index.csv',
|
||||
views.ExportIndexView.as_view(),
|
||||
name='seminar_export_index'
|
||||
),
|
||||
]
|
16
aesop/utils.py
Normal file
16
aesop/utils.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
import datetime
|
||||
|
||||
from django.utils.encoding import force_text
|
||||
|
||||
from aesop.ovvpfile import OvvpFile
|
||||
|
||||
|
||||
def default_ovvpfile(event, rocnik):
|
||||
of = OvvpFile()
|
||||
of.headers['version'] = '1'
|
||||
of.headers['event'] = event
|
||||
of.headers['year'] = force_text(rocnik.prvni_rok)
|
||||
of.headers['date'] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
of.headers['id-scope'] = 'mam'
|
||||
of.headers['id-generation'] = '1'
|
||||
return of
|
|
@ -1,14 +1,12 @@
|
|||
import datetime, django
|
||||
from django.shortcuts import get_object_or_404, render
|
||||
import django
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.http import HttpResponse
|
||||
from django.urls import reverse
|
||||
from django.views import generic
|
||||
from django.utils.encoding import force_text
|
||||
|
||||
from .models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni
|
||||
#from .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva
|
||||
from .ovvpfile import OvvpFile
|
||||
from seminar import views
|
||||
from .utils import default_ovvpfile
|
||||
from seminar.models import Rocnik, Soustredeni
|
||||
from seminar.views import vysledkovka
|
||||
from seminar.utils import aktivniResitele
|
||||
|
||||
|
@ -25,17 +23,6 @@ class ExportIndexView(generic.View):
|
|||
return HttpResponse('\n'.join(ls) + '\n', content_type='text/plain; charset=utf-8')
|
||||
|
||||
|
||||
def default_ovvpfile(event, rocnik):
|
||||
of = OvvpFile()
|
||||
of.headers['version'] = '1'
|
||||
of.headers['event'] = event
|
||||
of.headers['year'] = force_text(rocnik.prvni_rok)
|
||||
of.headers['date'] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
of.headers['id-scope'] = 'mam'
|
||||
of.headers['id-generation'] = '1'
|
||||
return of
|
||||
|
||||
|
||||
class ExportSousView(generic.View):
|
||||
|
||||
def get(self, request, datum_zacatku=None):
|
3
api/__init__.py
Normal file
3
api/__init__.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
"""
|
||||
Obsahuje api = autocomplete + export škol.
|
||||
"""
|
5
api/apps.py
Normal file
5
api/apps.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class ApiConfig(AppConfig):
|
||||
name = 'api'
|
0
api/migrations/__init__.py
Normal file
0
api/migrations/__init__.py
Normal file
1
api/tests/__init__.py
Normal file
1
api/tests/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
from .test_skola_autocomplete import *
|
19
api/urls.py
Normal file
19
api/urls.py
Normal file
|
@ -0,0 +1,19 @@
|
|||
from django.urls import path
|
||||
from . import views
|
||||
from seminar.utils import org_required
|
||||
|
||||
urlpatterns = [
|
||||
# Export škol
|
||||
path('api/export/skoly/', views.exportSkolView, name='export_skoly'),
|
||||
|
||||
|
||||
# Autocomplete
|
||||
path('api/autocomplete/skola/', views.SkolaAutocomplete.as_view(), name='autocomplete_skola'),
|
||||
path('api/autocomplete/resitel/', org_required(views.ResitelAutocomplete.as_view()), name='autocomplete_resitel'),
|
||||
path('api/autocomplete/problem/odevzdatelny', views.OdevzdatelnyProblemAutocomplete.as_view(), name='autocomplete_problem_odevzdatelny'),
|
||||
|
||||
# Ceka na autocomplete v3
|
||||
# path('autocomplete/organizatori/',
|
||||
# org_member_required(views.OrganizatorAutocomplete.as_view()),
|
||||
# name='seminar_autocomplete_organizator')
|
||||
]
|
2
api/views/__init__.py
Normal file
2
api/views/__init__.py
Normal file
|
@ -0,0 +1,2 @@
|
|||
from .autocomplete import *
|
||||
from .exports import *
|
|
@ -5,16 +5,20 @@ from django.db.models import Q
|
|||
import seminar.models as m
|
||||
from .helpers import LoginRequiredAjaxMixin
|
||||
|
||||
# TODO filosofie - zkratky, jak v databázi, tak ve vyhledávání (SPŠE, GASOŠ, Kpt., soukr)
|
||||
class SkolaAutocomplete(autocomplete.Select2QuerySetView):
|
||||
def get_queryset(self):
|
||||
# Don't forget to filter out results depending on the visitor !
|
||||
qs = m.Skola.objects.all()
|
||||
if self.q:
|
||||
qs = qs.filter(
|
||||
Q(nazev__istartswith=self.q)|
|
||||
Q(kratky_nazev__istartswith=self.q)|
|
||||
Q(ulice__istartswith=self.q)|
|
||||
Q(mesto__istartswith=self.q))
|
||||
words = self.q.split(' ') #TODO re split podle bileho znaku
|
||||
partq = Q()
|
||||
for w in words: # Hledej po slovech, zahoď čárky a tečky z konců.
|
||||
if w[-1] in (".",","):
|
||||
w = w[:-1]
|
||||
|
||||
partq &= (Q(nazev__icontains=w)|Q(kratky_nazev__icontains=w)|Q(ulice__icontains=w)|Q(mesto__icontains=w))
|
||||
qs = qs.filter(partq)
|
||||
|
||||
return qs
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
from dal import autocomplete
|
||||
from django.http import JsonResponse
|
||||
|
||||
|
||||
class LoginRequiredAjaxMixin(object):
|
||||
def dispatch(self, request, *args, **kwargs):
|
File diff suppressed because one or more lines are too long
|
@ -1,65 +0,0 @@
|
|||
import os
|
||||
import datetime
|
||||
import sqlite3
|
||||
|
||||
from django.utils.html import escape
|
||||
|
||||
from seminar import ovvpfile
|
||||
from seminar.models import Problem
|
||||
from seminar.utils import roman, from_roman
|
||||
|
||||
|
||||
# MM_ZADANIA.TYP
|
||||
typtable={'1': Problem.TYP_ULOHA, '2':Problem.TYP_TEMA, '3':Problem.TYP_SERIAL}
|
||||
|
||||
# MM_DOZ.ZARADENIE, MM_AZAD.ZAMERANIE
|
||||
def dectag(x):
|
||||
return ["MFIOTKPZD"[bi] for bi in range(0, 9) if (int(x) & (1 << bi))]
|
||||
|
||||
# Datum z formatu "DD.MM.YY"
|
||||
def transdate(s):
|
||||
if '.' not in s: return None
|
||||
d,m,r = map(int, s.split('.'))
|
||||
return datetime.date(r + 2000 if r < 30 else r + 1900, m, d)
|
||||
|
||||
class SQLiteRow(object):
|
||||
def __unicode__(self):
|
||||
return self.__dict__.__unicode__()
|
||||
def __str__(self):
|
||||
return self.__dict__.__str__()
|
||||
def __repr__(self):
|
||||
return self.__dict__.__str__()
|
||||
|
||||
# sqlite3 helper
|
||||
def sqget(db, sql, limit=None):
|
||||
c = db.execute(sql)
|
||||
rows = c.fetchmany(limit) if limit else c.fetchall()
|
||||
res = []
|
||||
for row in rows:
|
||||
o = SQLiteRow()
|
||||
for coli in range(len(c.description)):
|
||||
col = c.description[coli]
|
||||
o.__setattr__(col[0], row[coli])
|
||||
res.append(o)
|
||||
return res
|
||||
|
||||
## ovvpfile - based import helpers (old)
|
||||
|
||||
def read_all_tables(basedir):
|
||||
tables = {}
|
||||
for fn in os.listdir(basedir):
|
||||
if fn.endswith('.csv'):
|
||||
print "Reading %s ..." % (fn, )
|
||||
with open(os.path.join(basedir, fn), 'r') as f:
|
||||
o = ovvpfile.parse(f, with_headers=False)
|
||||
tables[fn[:-4]] = o.rows
|
||||
print " %d lines, columns: %s" % (len(o.rows), ' '.join(o.columns), )
|
||||
return tables
|
||||
|
||||
def matchrows(tab, key, val):
|
||||
return [r for r in tab if r[key]==val]
|
||||
|
||||
def onerow(tab, key, val):
|
||||
t = matchrows(tab, key, val)
|
||||
assert(len(t) == 1)
|
||||
return t[0]
|
|
@ -1,54 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# RUN AS:
|
||||
#
|
||||
# ORACLE_HOME=/nfs/nikam/sw/oracle-10.2/ora_home_10.2/ LC_ALL=C AESOP_PASSWD=<password-of-MAMOPER> perl oracle_dump
|
||||
#
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use utf8;
|
||||
|
||||
use lib '/nfs/nikam/sw/oracle-10.2/perl/lib/perl';
|
||||
use DBI;
|
||||
use DBD::Oracle qw(:ora_types);
|
||||
$ENV{'NLS_LANG'}='CZECH.UTF8';
|
||||
|
||||
|
||||
my $pass = $ENV{'AESOP_PASSWD'} // die "You must set AESOP_PASSWD\n";
|
||||
my $dbh = DBI->connect('dbi:Oracle:host=mffout.karlov.mff.cuni.cz;service_name=mffout.karlov.mff.cuni.cz;port=1521',
|
||||
'mamoper', $pass, {ora_connect_with_default_signals => [ 'INT' ], 'LongReadLen' => 1000000 }) or die;
|
||||
|
||||
$, = "\t";
|
||||
$\ = "\n";
|
||||
my $dump_directory = "oracle_dks_dump";
|
||||
mkdir $dump_directory unless -d $dump_directory;
|
||||
|
||||
sub dump_table($){
|
||||
my $name = shift;
|
||||
print $name;
|
||||
my $filename = $dump_directory."/".$name.".csv";
|
||||
open(my $fh, ">:encoding(UTF-8)", $filename);
|
||||
select $fh;
|
||||
my $query = $dbh->prepare("SELECT * FROM $name");
|
||||
$query->execute;
|
||||
print @{$query->{NAME}};
|
||||
print @{$query->{TYPE}};
|
||||
while (my @row = $query->fetchrow_array()) {
|
||||
$_//='' for @row;
|
||||
s/\t/\\t/g for @row;
|
||||
s/\n/\\n/g for @row;
|
||||
print @row;
|
||||
}
|
||||
select STDOUT;
|
||||
close $fh;
|
||||
}
|
||||
|
||||
# my $query = $dbh->prepare("SELECT table_name, TABLESPACE_NAME FROM all_tables WHERE owner='MAMOPER'");
|
||||
my $query = $dbh->prepare("SELECT table_name, owner FROM all_tables");
|
||||
$query->execute;
|
||||
while (my @row = $query->fetchrow_array()) {
|
||||
if (!( $row[1] eq 'SYS')) {
|
||||
dump_table "$row[1].$row[0]";
|
||||
}
|
||||
}
|
0
db_compare.py → deploy_v2/db_compare.py
Executable file → Normal file
0
db_compare.py → deploy_v2/db_compare.py
Executable file → Normal file
|
@ -1,16 +0,0 @@
|
|||
#!/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
|
|
@ -135,6 +135,9 @@ INSTALLED_APPS = (
|
|||
'prednasky',
|
||||
'header_fotky',
|
||||
'various',
|
||||
'various.autentizace',
|
||||
'api',
|
||||
'aesop',
|
||||
|
||||
# Admin upravy:
|
||||
|
||||
|
|
|
@ -23,6 +23,15 @@ urlpatterns = [
|
|||
# Prednaskova aplikace (ma vlastni podadresare)
|
||||
path('', include('prednasky.urls')),
|
||||
|
||||
# Autentizační aplikace (ma vlastni podadresare)
|
||||
path('', include('various.autentizace.urls')),
|
||||
|
||||
# Api (ma vlastni podadresare) (autocomplete apod.)
|
||||
path('', include('api.urls')),
|
||||
|
||||
# Aesop (ma vlastni podadresare)
|
||||
path('', include('aesop.urls')),
|
||||
|
||||
# Comments (interni i verejne)
|
||||
path('comments_dj/', include('django_comments.urls')),
|
||||
path('comments_fl/', include('fluent_comments.urls')),
|
||||
|
|
|
@ -10,9 +10,7 @@ from django_reverse_admin import ReverseModelAdmin
|
|||
from solo.admin import SingletonModelAdmin
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
from seminar.views.vysledkovka import hlavni_problem
|
||||
# TODO Přesunout do utils
|
||||
|
||||
from seminar.utils import hlavni_problem
|
||||
|
||||
# Todo: reversion
|
||||
|
||||
|
|
|
@ -27,16 +27,6 @@ class TelInput(forms.TextInput):
|
|||
input_type = 'tel'
|
||||
input_pattern="^[+]?[()/0-9. -]{9,}$"
|
||||
|
||||
class LoginForm(forms.Form):
|
||||
username = forms.CharField(label='Přihlašovací jméno',
|
||||
max_length=256,
|
||||
required=True)
|
||||
password = forms.CharField(
|
||||
label='Heslo',
|
||||
max_length=256,
|
||||
required=True,
|
||||
widget=forms.PasswordInput())
|
||||
|
||||
|
||||
class PrihlaskaForm(PasswordResetForm):
|
||||
username = forms.CharField(label='Přihlašovací jméno',
|
||||
|
|
|
@ -1,125 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import datetime
|
||||
import os
|
||||
import random
|
||||
#import argparse
|
||||
from optparse import make_option
|
||||
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.core.management import call_command
|
||||
from django.conf import settings
|
||||
from django.db import transaction
|
||||
import django.contrib.auth
|
||||
from django.utils.encoding import force_unicode
|
||||
|
||||
from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni, Nastaveni
|
||||
from seminar.testutils import create_test_data
|
||||
from seminar import ovvpfile
|
||||
|
||||
User = django.contrib.auth.get_user_model()
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Import (add / notice changes) schools from a ovvp-format file (skoly.csv)"
|
||||
|
||||
option_list = BaseCommand.option_list + (
|
||||
make_option('-n', '--dry_run', dest='dry_run', default=False,
|
||||
action='store_true', help="No changes to DB."),
|
||||
)
|
||||
# def add_arguments(self, parser):
|
||||
# parser.add_argument('file', nargs='?', type=argparse.FileType('r', encoding='utf8'), default=sys.stdin)
|
||||
# parser.add_argument('-n', '--dry_run', dest='dry_run', default=False,
|
||||
# action='store_true', type=bool, help="No changes to DB.")
|
||||
|
||||
def school_diffs(self, ovvpskola, dbskola):
|
||||
def compare(ovvpcol, dbcol, t=unicode):
|
||||
v1 = t(dbskola.__getattribute__(dbcol))
|
||||
v2 = ovvpskola[ovvpcol]
|
||||
if unicode(v1) != unicode(v2):
|
||||
return "%s: '%s'->'%s', " % (ovvpcol, v1, v2, )
|
||||
return ""
|
||||
|
||||
diff = ""
|
||||
diff += compare('name','nazev')
|
||||
diff += compare('street','ulice')
|
||||
diff += compare('town','mesto')
|
||||
diff += compare('postcode','psc')
|
||||
return diff
|
||||
|
||||
def handle(self, *args, **options):
|
||||
assert len(args) == 1
|
||||
|
||||
filename = args[0]
|
||||
self.stdout.write(
|
||||
'Parsing OVVP/OPMK-format file \'%s\' ...' % (filename, )
|
||||
)
|
||||
with open(filename, "r") as f:
|
||||
o = ovvpfile.parse(f)
|
||||
|
||||
assert o.headers['version'] == '1'
|
||||
self.stdout.write('Read %d schools with columns: %s' % (len(o.rows), o.columns, ))
|
||||
self.stdout.write('Export created: %s' % (o.headers.get('date', 'N/A'), ))
|
||||
assert 'id-aesop' in o.columns
|
||||
|
||||
same = 0
|
||||
modified = 0
|
||||
new = 0
|
||||
|
||||
with transaction.atomic():
|
||||
for skola in o.rows:
|
||||
aesop_id = 'aesop:%s' % (skola['id-aesop'], )
|
||||
found = Skola.objects.filter(aesop_id=aesop_id)
|
||||
assert len(found) <= 1
|
||||
|
||||
if found:
|
||||
fs = found[0]
|
||||
diff = self.school_diffs(skola, fs)
|
||||
if diff:
|
||||
modified += 1
|
||||
self.stdout.write(u"M %11s %s" % (aesop_id, diff, )) # TODO
|
||||
else:
|
||||
same += 1
|
||||
if int(skola['is-SS']) > int(fs.je_ss):
|
||||
fs.je_ss = True
|
||||
fs.save()
|
||||
|
||||
if int(skola['is-ZS']) > int(fs.je_zs):
|
||||
fs.je_zs = True
|
||||
fs.save()
|
||||
|
||||
else:
|
||||
new += 1
|
||||
# Name duplicates?
|
||||
by_name = Skola.objects.filter(nazev=skola['name'], mesto=skola['town'], ulice=skola['street'])
|
||||
if len(by_name) > 0:
|
||||
self.stdout.write(u"W Same [name, street, town] for %s and %s (%s, %s, %s)" % (
|
||||
by_name[0].aesop_id, aesop_id, skola['name'], skola['street'], skola['town'], ))
|
||||
else:
|
||||
self.stdout.write(u"+ %11s %s, %s, %s" % (aesop_id, skola['name'], skola['town'], skola['country'], ))
|
||||
if not options['dry_run']:
|
||||
newskola = Skola.objects.create(
|
||||
aesop_id=aesop_id, nazev=skola['name'], kratky_nazev=skola['name'], izo=skola.get('id-izo', ''),
|
||||
ulice=skola['street'], mesto=skola['town'], psc=skola['postcode'], stat=skola['country'],
|
||||
je_zs=int(skola['is-ZS']), je_ss=int(skola['is-SS']),
|
||||
)
|
||||
|
||||
self.stdout.write("Result: %d same, %d different, %d new schools" % (same, modified, new, ))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1720,83 +1720,6 @@ class ReseniNode(TreeNode):
|
|||
def getOdkazStr(self):
|
||||
return str(self.reseni)
|
||||
|
||||
## FIXME: Logiku přesunout do views.
|
||||
#class VysledkyBase(SeminarModelBase):
|
||||
#
|
||||
# class Meta:
|
||||
# verbose_name = 'Řádek výsledkovky'
|
||||
# verbose_name_plural = 'Řádky výsledkovky'
|
||||
# ordering = ['body']
|
||||
# abstract = True
|
||||
# managed = False
|
||||
#
|
||||
# dummy_id = models.CharField('dummy ID pro view', max_length=32, primary_key=True,
|
||||
# db_column='id')
|
||||
#
|
||||
# cislo = models.ForeignKey(Cislo, verbose_name='číslo pro body', db_column='cislo_id',
|
||||
# on_delete=models.DO_NOTHING)
|
||||
#
|
||||
# resitel = models.ForeignKey(Resitel, verbose_name='řešitel', db_column='resitel_id',
|
||||
# on_delete=models.DO_NOTHING)
|
||||
#
|
||||
# body = models.DecimalField(max_digits=8, decimal_places=1, db_column='body',
|
||||
# verbose_name='body za číslo')
|
||||
#
|
||||
# def __str__(self):
|
||||
# return "%s: %sb (%s)".format(self.resitel.plne_jmeno(), self.body,
|
||||
# str(self.poradi))
|
||||
# # NOTE: DB zatez pri vypisu (ale nepouzivany)
|
||||
|
||||
|
||||
## FIXME: Logiku přesunout do views.
|
||||
#class VysledkyZaCislo(VysledkyBase):
|
||||
#
|
||||
# class Meta:
|
||||
# db_table = 'seminar_body_za_cislo'
|
||||
# abstract = False
|
||||
# managed = False
|
||||
#
|
||||
#
|
||||
## FIXME: Logiku přesunout do views.
|
||||
#class VysledkyKCisluZaRocnik(VysledkyBase):
|
||||
#
|
||||
# class Meta:
|
||||
# db_table = 'seminar_body_k_cislu_rocnik'
|
||||
# abstract = False
|
||||
# managed = False
|
||||
#
|
||||
## body = models.DecimalField(max_digits=8, decimal_places=1, db_column='body',
|
||||
## verbose_name='body do čísla (za ročník)')
|
||||
#
|
||||
#
|
||||
## FIXME: Logiku přesunout do views.
|
||||
#class VysledkyKCisluOdjakziva(VysledkyBase):
|
||||
#
|
||||
# class Meta:
|
||||
# db_table = 'seminar_body_k_cislu_odjakziva'
|
||||
# abstract = False
|
||||
# managed = False
|
||||
#
|
||||
## body = models.DecimalField(max_digits=8, decimal_places=1, db_column='body',
|
||||
## verbose_name='body do čísla (i minulé ročníky)')
|
||||
#
|
||||
#
|
||||
## FIXME: Logiku přesunout do views.
|
||||
#class VysledkyCelkemKCislu(VysledkyBase):
|
||||
#
|
||||
# class Meta:
|
||||
# db_table = 'seminar_body_celkem_k_cislu'
|
||||
# abstract = False
|
||||
# managed = False
|
||||
#
|
||||
# body_celkem = models.DecimalField(max_digits=8, decimal_places=1, db_column='body_celkem',
|
||||
# verbose_name='body celkem do čísla včetně minulých ročníků')
|
||||
#
|
||||
# def __str__(self):
|
||||
# # NOTE: DB HOG (ale nepouzivany)
|
||||
# return "%s: %sb / %sb (do %s)" % (self.resitel.plne_jmeno(), self.body, self.body_celkem, str(self.poradi))
|
||||
##mozna potreba upravit
|
||||
|
||||
|
||||
@reversion.register(ignore_duplicates=True)
|
||||
class Nastaveni(SingletonModel):
|
||||
|
@ -1855,35 +1778,3 @@ class Novinky(models.Model):
|
|||
return '[' + str(self.datum) + '] ' + self.text[0:50]
|
||||
else:
|
||||
return '[' + str(self.datum) + '] '
|
||||
|
||||
|
||||
|
||||
|
||||
# FIXME: Tohle nepatří do aplikace 'seminar'
|
||||
# Nefunkční alternativa vestavěného Usera, který má jméno a mail v přidružené Osobě
|
||||
# from django.contrib.auth.models import User as Django_User
|
||||
#
|
||||
# class Uzivatel(Django_User):
|
||||
# class Meta:
|
||||
# proxy = True
|
||||
#
|
||||
# @property
|
||||
# def first_name(self):
|
||||
# osoby = Osoba.objects.filter(user=self)
|
||||
# if len(osoby) == 0:
|
||||
# return None
|
||||
# return osoby.first().krestni_jmeno
|
||||
#
|
||||
# @property
|
||||
# def last_name(self):
|
||||
# osoby = Osoba.objects.filter(user=self)
|
||||
# if len(osoby) == 0:
|
||||
# return None
|
||||
# return osoby.first().prijmeni
|
||||
#
|
||||
# @property
|
||||
# def email(self):
|
||||
# osoby = Osoba.objects.filter(user=self)
|
||||
# if len(osoby) == 0:
|
||||
# return None
|
||||
# return osoby.first().email
|
||||
|
|
|
@ -1,94 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import datetime
|
||||
import random
|
||||
import django.contrib.auth
|
||||
from unittest import TestCase
|
||||
from django.test import Client
|
||||
from django.core.urlresolvers import reverse, resolve
|
||||
from django.core.management import call_command
|
||||
|
||||
from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni, Soustredeni, Nastaveni
|
||||
from seminar.testutils import create_test_data
|
||||
from seminar import ovvpfile
|
||||
from seminar import utils
|
||||
|
||||
class SeminarBasicTests(TestCase):
|
||||
def setUp(self):
|
||||
create_test_data(size=2)
|
||||
self.client = Client()
|
||||
|
||||
def tearDown(self):
|
||||
call_command('flush', noinput=True, verbosity=0, interactive=False)
|
||||
self.cleint = None
|
||||
|
||||
def test_rocniky(self):
|
||||
r19 = Rocnik.objects.get(rocnik=21)
|
||||
self.assertEqual(r19.roman(), 'XXI')
|
||||
|
||||
def test_render_cislo_e2e(self):
|
||||
cs = Cislo.objects.all()
|
||||
for c in cs[:4]:
|
||||
url = c.verejne_url()
|
||||
r = self.client.get(url)
|
||||
assert r.status_code == 200
|
||||
assert len(r.content) >= 100
|
||||
# TODO: Validate cntent as HTML
|
||||
|
||||
def test_render_problem_e2e(self):
|
||||
ps = Problem.objects.all()
|
||||
for p in ps[:4]:
|
||||
url = p.verejne_url()
|
||||
r = self.client.get(url)
|
||||
assert r.status_code == 200
|
||||
assert len(r.content) >= 100
|
||||
# TODO: Validate cntent as HTML
|
||||
|
||||
def test_export_e2e(self):
|
||||
i_url = '/aesop-export/index.csv'
|
||||
i_r = self.client.get(i_url)
|
||||
assert i_r.status_code == 200
|
||||
ls = i_r.content.strip().split('\n')
|
||||
|
||||
for u in [ls[0], ls[-1]]:
|
||||
ex_r = self.client.get('/aesop-export/' + u)
|
||||
assert ex_r.status_code == 200
|
||||
assert len(ex_r.content) >= 100
|
||||
o = ovvpfile.parse(ex_r.content)
|
||||
assert o.headers['version'] == '1'
|
||||
|
||||
def test_admin_url(self):
|
||||
for m in [Skola, Resitel, Rocnik, Cislo, Problem, Reseni, Nastaveni]:
|
||||
o = m.objects.first()
|
||||
url = o.admin_url()
|
||||
assert url
|
||||
view = resolve(url)
|
||||
assert view
|
||||
|
||||
def test_verejne_url(self):
|
||||
for m in [Rocnik, Cislo, Problem]:
|
||||
p = Problem.objects.first()
|
||||
url = p.verejne_url()
|
||||
assert url
|
||||
view = resolve(url)
|
||||
assert view
|
||||
|
||||
def test_ovvpfile(self):
|
||||
filetext = "H1\ta\nH2\tb\tc\n\nx\ty\tz\n0\t1\t2\n3\t4\t5\n"
|
||||
o = ovvpfile.parse(filetext)
|
||||
assert len(o.headers) == 2
|
||||
assert o.headers['H2'] == 'b\tc'
|
||||
|
||||
assert o.columns == ['x','y','z']
|
||||
assert len(o.rows) == 2
|
||||
assert o.rows[0]['z'] == '2'
|
||||
|
||||
t = o.to_string()
|
||||
assert t == filetext
|
||||
|
||||
def test_roman(self):
|
||||
for i in [0, 1, 23, 2015, 1999, 42, 4, 400, 78, 4321, 8765, 999]:
|
||||
r = utils.roman(i)
|
||||
fr = utils.from_roman(r)
|
||||
assert fr == i
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
# Tento soubor slouží k odkládání aktuálně nepotřebného kódu, který by
|
||||
# se však v budoucnu mohl opět hodit.
|
||||
|
||||
###################################################################
|
||||
|
||||
## Prispevek byl zrusen, mozna ale bude podobny nahled na neco jineho.
|
||||
#class PrispevekView(generic.DetailView):
|
||||
# model = Prispevek
|
||||
# template_name = 'seminar/archiv/prispevek.html'
|
||||
#
|
||||
# # Vlastni ziskavani objektu z databaze podle prispevku
|
||||
# # pokud je prispevek neverejny zobrazi se jenom orgum
|
||||
# def get_object(self, queryset=None):
|
||||
# if queryset is None:
|
||||
# queryset = self.get_queryset()
|
||||
# problem_arg = self.kwargs.get('pk')
|
||||
# prispevek_arg = self.kwargs.get('prispevek')
|
||||
# queryset = queryset.filter(pk=prispevek_arg)
|
||||
#
|
||||
# try:
|
||||
# obj = queryset.get()
|
||||
# except queryset.model.DoesNotExist:
|
||||
# raise Http404(_("No %(verbose_name)s found matching the query") %
|
||||
# {'verbose_name': queryset.model._meta.verbose_name})
|
||||
#
|
||||
# if self.request.user.is_staff or obj.zverejnit:
|
||||
# return obj
|
||||
# else:
|
||||
# raise Http404()
|
||||
#
|
||||
# def get_context_data(self, **kwargs):
|
||||
# context = super(PrispevekView, self).get_context_data(**kwargs)
|
||||
# # snaho o ziskani titulu
|
||||
# titul = ''
|
||||
# try:
|
||||
# resitel = context['prispevek'].reseni.resitel
|
||||
# cislo = context['prispevek'].reseni.cislo_body
|
||||
# body = VysledkyKCisluOdjakziva.objects.get(resitel=resitel,
|
||||
# cislo=cislo).body
|
||||
# titul = resitel.get_titul(body)
|
||||
# except:
|
||||
# pass
|
||||
# context['titul'] = titul
|
||||
# return context
|
||||
|
||||
####################################################################
|
||||
|
||||
## Stvrzenky aktuálně nevydáváme, ale možná časem zase budeme.
|
||||
#def soustredeniStvrzenkyExportView(request,soustredeni,first_num):
|
||||
# first_num = int(first_num)
|
||||
# soustredeni = get_object_or_404(Soustredeni,id = soustredeni)
|
||||
# ucastnici = Resitel.objects.filter(soustredeni=soustredeni)
|
||||
# for (idx,u) in enumerate(ucastnici):
|
||||
# u.cislo_stvrzenky = first_num+idx;
|
||||
# tex = render(request,'seminar/soustredeni/ucastnici.tex', {'ucastnici': ucastnici, 'datum':soustredeni.datum_zacatku }).content
|
||||
#
|
||||
# tempdir = tempfile.mkdtemp()
|
||||
# with open(tempdir+"/ucastnici.tex","w") as texfile:
|
||||
# # Pokud TeX chce ISO Latin, tak se da encode nastavit
|
||||
# texfile.write(tex.decode("utf-8").encode("utf-8"))
|
||||
# shutil.copy(os.path.join(settings.STATIC_ROOT, 'seminar/stvrzenka.sty'),tempdir)
|
||||
# shutil.copy(os.path.join(settings.STATIC_ROOT, 'seminar/stvrzenky.tex'),tempdir)
|
||||
# subprocess.call(["cslatex","stvrzenky.tex"],cwd = tempdir)
|
||||
# subprocess.call(["dvipdf","stvrzenky.dvi"],cwd = tempdir)
|
||||
#
|
||||
# with open(tempdir+"/stvrzenky.pdf","rb") as pdffile:
|
||||
# response = HttpResponse(pdffile.read(),content_type='application/pdf')
|
||||
# shutil.rmtree(tempdir)
|
||||
# return response
|
||||
|
||||
|
|
@ -85,7 +85,7 @@ $(document).ready(function(){
|
|||
<p>Žádné přílohy</p>
|
||||
{% endif %}
|
||||
|
||||
<form method=post>
|
||||
<form method=post onsubmit="return zkontroluj_hodnoceni();">
|
||||
{# Poznámka #}
|
||||
<h3>Poznámka:</h3>
|
||||
<p>{{ poznamka_form.poznamka }}</p>
|
||||
|
@ -99,12 +99,14 @@ $(document).ready(function(){
|
|||
<table id="form_set">
|
||||
<tr><th>Problém</th><th>Body</th><th>Číslo pro body</th></tr>
|
||||
{% for subform in form %}
|
||||
<tbody>
|
||||
<tr class="hodnoceni">
|
||||
<td>{{ subform.problem }}</td>
|
||||
<td>{{ subform.body }}</td>
|
||||
<td>{{ subform.cislo_body }}</td>
|
||||
<td><a href="#" class="smazat_hodnoceni" id="id_{{subform.prefix}}-jsremove"><img src="{% static "seminar/cross.png" %}" alt="Smazat"></a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
|
@ -121,4 +123,19 @@ $(document).ready(function(){
|
|||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
function zkontroluj_hodnoceni() {
|
||||
const pocet = document.getElementById("form_set").childElementCount;
|
||||
if (pocet === 1) { {# vydím pouze plusko #}
|
||||
const vysledek = confirm("Odstranil jsi všechny problémy tohoto řešení. Nepůjde tedy dohledat přes problémy, co řeší, tj. například v došlých řešeních. Přesto odeslat?");
|
||||
if (!vysledek) {
|
||||
event.preventDefault();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
from django.urls import path, include, re_path
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from . import views, export
|
||||
from . import views
|
||||
from .utils import org_required, resitel_required, viewMethodSwitch, resitel_or_org_required
|
||||
from django.views.generic.base import RedirectView
|
||||
|
||||
urlpatterns = [
|
||||
# path('aktualni/temata/', views.TemataRozcestnikView),
|
||||
|
@ -68,23 +67,6 @@ urlpatterns = [
|
|||
path('archiv/clanky/', views.ClankyResitelView.as_view(), name='clanky_resitel'),
|
||||
#path('clanky/org/', views.ClankyOrganizatorView.as_view(), name='clanky_organizator'),
|
||||
|
||||
# Aesop
|
||||
path(
|
||||
'aesop-export/mam-rocnik-<int:prvni_rok>.csv',
|
||||
export.ExportRocnikView.as_view(),
|
||||
name='seminar_export_rocnik'
|
||||
),
|
||||
path(
|
||||
'aesop-export/mam-sous-<str:datum_zacatku>.csv',
|
||||
export.ExportSousView.as_view(),
|
||||
name='seminar_export_sous'
|
||||
),
|
||||
path(
|
||||
'aesop-export/index.csv',
|
||||
export.ExportIndexView.as_view(),
|
||||
name='seminar_export_index'
|
||||
),
|
||||
|
||||
# Stranky viditelne pouze pro orgy:
|
||||
path(
|
||||
'rocnik/<int:rocnik>/vysledkovka.tex',
|
||||
|
@ -133,17 +115,9 @@ urlpatterns = [
|
|||
),
|
||||
|
||||
path('prihlaska/',views.prihlaskaView, name='seminar_prihlaska'),
|
||||
path('prihlasit/', views.LoginView.as_view(), name='login'),
|
||||
path('login/', RedirectView.as_view(pattern_name='login', permanent=True, query_string=True)),
|
||||
path('odhlasit/', views.LogoutView.as_view(), name='logout'),
|
||||
path('logout/', RedirectView.as_view(pattern_name='logout', permanent=True, query_string=True)),
|
||||
path('resitel/', resitel_required(views.ResitelView.as_view()), name='seminar_resitel'),
|
||||
|
||||
path('resitel/odevzdana_reseni/', resitel_or_org_required(views.PrehledOdevzdanychReseni.as_view()), name='seminar_resitel_odevzdana_reseni'),
|
||||
path('reset-hesla/', views.PasswordResetView.as_view(), name='reset_password'),
|
||||
path('zmena-hesla/', views.PasswordChangeView.as_view(), name='change_password'),
|
||||
path('reset-hesla/2/', views.PasswordResetDoneView.as_view(), name='reset_password_done'),
|
||||
path('reset-hesla/potvrzeni/<uidb64>/<token>/', views.PasswordResetConfirmView.as_view(), name='reset_password_confirm'),
|
||||
path('reset-hesla/hotovo/', views.PasswordResetCompleteView.as_view(), name='reset_password_complete'),
|
||||
|
||||
path(
|
||||
'resitel/osobni-udaje/',
|
||||
login_required(views.resitelEditView),
|
||||
|
@ -153,14 +127,6 @@ urlpatterns = [
|
|||
# Obecný view na profil -- orgům dá rozcestník, řešitelům jejich stránku
|
||||
path('profil/', views.profilView, name='profil'),
|
||||
|
||||
# Autocomplete
|
||||
path('api/autocomplete/skola/',views.SkolaAutocomplete.as_view(), name='autocomplete_skola'),
|
||||
path('api/autocomplete/resitel/', org_required(views.ResitelAutocomplete.as_view()), name='autocomplete_resitel'),
|
||||
path('api/autocomplete/problem/odevzdatelny',views.OdevzdatelnyProblemAutocomplete.as_view(), name='autocomplete_problem_odevzdatelny'),
|
||||
|
||||
# Export škol
|
||||
path('api/export/skoly/', views.exportSkolView, name='export_skoly'),
|
||||
|
||||
path('org/add_solution', org_required(views.AddSolutionView.as_view()), name='seminar_vloz_reseni'),
|
||||
path('resitel/nahraj_reseni', resitel_required(views.NahrajReseniView.as_view()), name='seminar_nahraj_reseni'),
|
||||
|
||||
|
@ -170,11 +136,6 @@ urlpatterns = [
|
|||
path('', views.TitulniStranaView.as_view(), name='titulni_strana'),
|
||||
path('jak-resit/', views.JakResitView.as_view(), name='jak_resit'),
|
||||
|
||||
# Ceka na autocomplete v3
|
||||
# path('autocomplete/organizatori/',
|
||||
# org_member_required(views.OrganizatorAutocomplete.as_view()),
|
||||
# name='seminar_autocomplete_organizator')
|
||||
|
||||
path('org/reseni/', org_required(views.TabulkaOdevzdanychReseniView.as_view()), name='odevzdavatko_tabulka'),
|
||||
path('org/reseni/rocnik/<int:rocnik>/', org_required(views.TabulkaOdevzdanychReseniView.as_view()), name='odevzdavatko_tabulka'),
|
||||
path('org/reseni/<int:problem>/<int:resitel>/', org_required(views.ReseniProblemuView.as_view()), name='odevzdavatko_reseni_resitele_k_problemu'),
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
from .views_all import *
|
||||
from .autocomplete import *
|
||||
from .views_rest import *
|
||||
from .odevzdavatko import *
|
||||
|
||||
from .exports import *
|
||||
|
||||
# Dočsasné views
|
||||
from .docasne import *
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import datetime
|
||||
from django.contrib.auth.decorators import user_passes_test
|
||||
from html.parser import HTMLParser
|
||||
|
||||
import seminar.models as m
|
||||
|
||||
class FirstTagParser(HTMLParser):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.firstTag = None
|
||||
super().__init__(*args, **kwargs)
|
||||
def handle_data(self, data):
|
||||
if self.firstTag == None:
|
||||
self.firstTag = data
|
||||
|
||||
def histogram(seznam):
|
||||
d = {}
|
||||
for i in seznam:
|
||||
if i not in d:
|
||||
d[i] = 0
|
||||
d[i] += 1
|
||||
return d
|
||||
|
||||
|
||||
roman_numerals = zip((1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1),
|
||||
('M', 'CM', 'D', 'CD','C', 'XC','L','XL','X','IX','V','IV','I'))
|
||||
|
||||
def roman(num):
|
||||
res = ""
|
||||
for i, n in roman_numerals:
|
||||
res += n * (num // i)
|
||||
num %= i
|
||||
return res
|
||||
|
||||
def from_roman(rom):
|
||||
if not rom:
|
||||
return 0
|
||||
for i, n in roman_numerals:
|
||||
if rom.upper().startswith(n):
|
||||
return i + from_roman(rom[len(n):])
|
||||
raise Exception('Invalid roman numeral: "%s"', rom)
|
||||
|
||||
|
||||
def seznam_problemu():
|
||||
problemy = []
|
||||
|
||||
# Pomocna fce k formatovani problemovych hlasek
|
||||
def prb(cls, msg, objs=None):
|
||||
s = u'<b>%s:</b> %s' % (cls.__name__, msg)
|
||||
if objs:
|
||||
s += u' ['
|
||||
for o in objs:
|
||||
try:
|
||||
url = o.admin_url()
|
||||
except:
|
||||
url = None
|
||||
if url:
|
||||
s += u'<a href="%s">%s</a>, ' % (url, o.pk, )
|
||||
else:
|
||||
s += u'%s, ' % (o.pk, )
|
||||
s = s[:-2] + u']'
|
||||
problemy.append(s)
|
||||
|
||||
# Duplicita jmen
|
||||
jmena = {}
|
||||
for r in m.Resitel.objects.all():
|
||||
j = r.plne_jmeno()
|
||||
if j not in jmena:
|
||||
jmena[j] = []
|
||||
jmena[j].append(r)
|
||||
for j in jmena:
|
||||
if len(jmena[j]) > 1:
|
||||
prb(m.Resitel, u'Duplicitní jméno "%s"' % (j, ), jmena[j])
|
||||
|
||||
# Data maturity a narození
|
||||
for r in m.Resitel.objects.all():
|
||||
if not r.rok_maturity:
|
||||
prb(m.Resitel, u'Neznámý rok maturity', [r])
|
||||
if r.rok_maturity and (r.rok_maturity < 1990 or r.rok_maturity > datetime.date.today().year + 10):
|
||||
prb(m.Resitel, u'Podezřelé datum maturity', [r])
|
||||
if r.datum_narozeni and (r.datum_narozeni.year < 1970 or r.datum_narozeni.year > datetime.date.today().year - 12):
|
||||
prb(m.Resitel, u'Podezřelé datum narození', [r])
|
||||
# if not r.email:
|
||||
# prb(Resitel, u'Neznámý email', [r])
|
||||
|
||||
return problemy
|
||||
|
||||
|
|
@ -1,12 +1,8 @@
|
|||
from django.contrib.auth.tokens import PasswordResetTokenGenerator
|
||||
from django.contrib.sites.shortcuts import get_current_site
|
||||
from django.shortcuts import get_object_or_404, render, redirect
|
||||
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, JsonResponse
|
||||
from django.urls import reverse,reverse_lazy
|
||||
from django.core.exceptions import PermissionDenied, ObjectDoesNotExist
|
||||
from django.core.mail import send_mail
|
||||
from django.utils.encoding import force_bytes
|
||||
from django.utils.http import urlsafe_base64_encode
|
||||
from django.views import generic
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.http import Http404,HttpResponseBadRequest,HttpResponseRedirect
|
||||
|
@ -15,8 +11,6 @@ from django.views.decorators.csrf import ensure_csrf_cookie
|
|||
from django.views.decorators.debug import sensitive_post_parameters
|
||||
from django.views.generic.edit import FormView, CreateView
|
||||
from django.views.generic.base import TemplateView, RedirectView
|
||||
from django.contrib.auth import authenticate, login, get_user_model, logout
|
||||
from django.contrib.auth import views as auth_views
|
||||
from django.contrib.auth.models import User, Permission, Group
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.db import transaction
|
||||
|
@ -29,7 +23,7 @@ import seminar.models as m
|
|||
from seminar.models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni, Organizator, Resitel, Novinky, Soustredeni_Ucastnici, Pohadka, Tema, Clanek, Osoba, Skola # Tohle je stare a chceme se toho zbavit. Pouzivejte s.ToCoChci
|
||||
#from .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva
|
||||
from seminar import utils, treelib
|
||||
from seminar.forms import PrihlaskaForm, LoginForm, ProfileEditForm, PoMaturiteProfileEditForm
|
||||
from seminar.forms import PrihlaskaForm, ProfileEditForm, PoMaturiteProfileEditForm
|
||||
import seminar.forms as f
|
||||
import seminar.templatetags.treenodes as tnltt
|
||||
import seminar.views.views_rest as vr
|
||||
|
@ -54,6 +48,8 @@ import logging
|
|||
import time
|
||||
|
||||
from seminar.utils import aktivniResitele, resi_v_rocniku, problemy_rocniku, cisla_rocniku, hlavni_problemy_f
|
||||
from various.autentizace.views import LoginView
|
||||
from various.autentizace.utils import posli_reset_hesla
|
||||
|
||||
# ze starého modelu
|
||||
#def verejna_temata(rocnik):
|
||||
|
@ -1336,30 +1332,7 @@ def prihlaskaView(request):
|
|||
|
||||
if diffattrs: err_logger.warning(f'Different fields when matching Řešitel id {r.id} or Osoba id {o.id}: {diffattrs}')
|
||||
|
||||
uid = urlsafe_base64_encode(force_bytes(u.pk))
|
||||
token = PasswordResetTokenGenerator().make_token(u)
|
||||
url = "https://%s%s" % (
|
||||
str(get_current_site(request)),
|
||||
str(reverse_lazy("reset_password_confirm", args=[uid, token]))
|
||||
)
|
||||
|
||||
u.email_user(
|
||||
subject="Vítej mezi řešiteli M&M!",
|
||||
message="""Milý řešiteli, milá řešitelko,
|
||||
|
||||
tvůj e-mail byl právě zaregistrován na mam.matfyz.cz. Heslo si prosím nastav na: %s
|
||||
|
||||
Těšíme se na tvé příspěvky do našeho semináře,
|
||||
Organizátoři M&M
|
||||
|
||||
--
|
||||
|
||||
Tento e-mail byl vygenerován automaticky, chceš-li nás kontaktovat, napiš nám na adresu mam@matfyz.cz.
|
||||
""" % url,
|
||||
# TODO: templates/seminar/registrace a django/contrib/auth/forms.py říkají, jak na to lépe
|
||||
from_email="registrace@mam.mff.cuni.cz", # FIXME: Chceme to mít radši tady, nebo v nastavení?
|
||||
)
|
||||
|
||||
posli_reset_hesla(u, request)
|
||||
return formularOKView(request, text='Na tvůj e-mail jsme právě poslali odkaz pro nastavení hesla.')
|
||||
|
||||
# if a GET (or any other method) we'll create a blank form
|
||||
|
@ -1368,42 +1341,6 @@ Tento e-mail byl vygenerován automaticky, chceš-li nás kontaktovat, napiš n
|
|||
|
||||
return render(request, 'seminar/profil/prihlaska.html', {'form': form})
|
||||
|
||||
# FIXME: Tohle asi vlastně vůbec nepatří do aplikace 'seminar'
|
||||
class LoginView(auth_views.LoginView):
|
||||
# Jen vezmeme vestavěný a dáme mu vhodný template a přesměrovací URL
|
||||
template_name = 'seminar/profil/login.html'
|
||||
|
||||
class LogoutView(auth_views.LogoutView):
|
||||
# Jen vezmeme vestavěný a dáme mu vhodný template a přesměrovací URL
|
||||
template_name = 'seminar/profil/logout.html'
|
||||
# Pavel: Vůbec nevím, proč to s _lazy funguje, ale bez toho to bylo rozbité.
|
||||
next_page = reverse_lazy('titulni_strana')
|
||||
|
||||
# Nejsem si jistý, který view co dostává, tak zahazuji všechny POSTy
|
||||
class PasswordResetView(auth_views.PasswordResetView):
|
||||
""" Chci resetovat heslo. """
|
||||
template_name = 'seminar/registrace/reset_hesla.html'
|
||||
success_url = reverse_lazy('reset_password_done')
|
||||
from_email = 'login@mam.mff.cuni.cz'
|
||||
email_template_name = 'seminar/registrace/password_reset_email.html'
|
||||
subject_template_name = 'seminar/registrace/password_reset_subject.txt'
|
||||
|
||||
class PasswordResetDoneView(auth_views.PasswordResetDoneView):
|
||||
""" Poslali jsme e-mail (pokud bylo kam)). """
|
||||
template_name = 'seminar/registrace/reset_poslan.html'
|
||||
|
||||
class PasswordResetConfirmView(auth_views.PasswordResetConfirmView):
|
||||
""" Vymysli si heslo. """
|
||||
template_name = 'seminar/registrace/nove_heslo.html'
|
||||
success_url = reverse_lazy('reset_password_complete')
|
||||
|
||||
class PasswordResetCompleteView(auth_views.PasswordResetCompleteView):
|
||||
""" Heslo se asi změnilo."""
|
||||
template_name = 'seminar/registrace/nove_nastaveno.html'
|
||||
|
||||
class PasswordChangeView(auth_views.PasswordChangeView):
|
||||
#template_name = 'seminar/password_change.html'
|
||||
success_url = reverse_lazy('titulni_strana')
|
||||
|
||||
class VueTestView(generic.TemplateView):
|
||||
template_name = 'seminar/vuetest.html'
|
||||
|
|
|
@ -380,7 +380,7 @@ def vysledkovka_cisla(cislo, context=None):
|
|||
## TODO možná chytřeji vybírat aktivní řešitele
|
||||
# aktivní řešitelé - chceme letos něco poslal, TODO později vyfiltrujeme ty, kdo mají
|
||||
# u alespoň jedné hodnoty něco jiného než NULL
|
||||
aktivni_resitele = list(aktivniResitele(cislo))
|
||||
aktivni_resitele = list(resi_v_rocniku(cislo.rocnik))
|
||||
|
||||
# získáme body za číslo
|
||||
hlavni_problemy_slovnik, cislobody = secti_body_za_cislo(cislo, aktivni_resitele, hlavni_problemy)
|
||||
|
|
0
various/autentizace/__init__.py
Normal file
0
various/autentizace/__init__.py
Normal file
27
various/autentizace/models.py
Normal file
27
various/autentizace/models.py
Normal file
|
@ -0,0 +1,27 @@
|
|||
# Nefunkční alternativa vestavěného Usera, který má jméno a mail v přidružené Osobě
|
||||
# from django.contrib.auth.models import User as Django_User
|
||||
#
|
||||
# class Uzivatel(Django_User):
|
||||
# class Meta:
|
||||
# proxy = True
|
||||
#
|
||||
# @property
|
||||
# def first_name(self):
|
||||
# osoby = Osoba.objects.filter(user=self)
|
||||
# if len(osoby) == 0:
|
||||
# return None
|
||||
# return osoby.first().krestni_jmeno
|
||||
#
|
||||
# @property
|
||||
# def last_name(self):
|
||||
# osoby = Osoba.objects.filter(user=self)
|
||||
# if len(osoby) == 0:
|
||||
# return None
|
||||
# return osoby.first().prijmeni
|
||||
#
|
||||
# @property
|
||||
# def email(self):
|
||||
# osoby = Osoba.objects.filter(user=self)
|
||||
# if len(osoby) == 0:
|
||||
# return None
|
||||
# return osoby.first().email
|
15
various/autentizace/urls.py
Normal file
15
various/autentizace/urls.py
Normal file
|
@ -0,0 +1,15 @@
|
|||
from django.urls import path
|
||||
from . import views
|
||||
from django.views.generic.base import RedirectView
|
||||
|
||||
urlpatterns = [
|
||||
path('prihlasit/', views.LoginView.as_view(), name='login'),
|
||||
path('login/', RedirectView.as_view(pattern_name='login', permanent=True, query_string=True)),
|
||||
path('odhlasit/', views.LogoutView.as_view(), name='logout'),
|
||||
path('logout/', RedirectView.as_view(pattern_name='logout', permanent=True, query_string=True)),
|
||||
path('reset-hesla/', views.PasswordResetView.as_view(), name='reset_password'),
|
||||
path('zmena-hesla/', views.PasswordChangeView.as_view(), name='change_password'),
|
||||
path('reset-hesla/2/', views.PasswordResetDoneView.as_view(), name='reset_password_done'),
|
||||
path('reset-hesla/potvrzeni/<uidb64>/<token>/', views.PasswordResetConfirmView.as_view(), name='reset_password_confirm'),
|
||||
path('reset-hesla/hotovo/', views.PasswordResetCompleteView.as_view(), name='reset_password_complete'),
|
||||
]
|
31
various/autentizace/utils.py
Normal file
31
various/autentizace/utils.py
Normal file
|
@ -0,0 +1,31 @@
|
|||
from django.contrib.auth.tokens import PasswordResetTokenGenerator
|
||||
from django.contrib.sites.shortcuts import get_current_site
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils.encoding import force_bytes
|
||||
from django.utils.http import urlsafe_base64_encode
|
||||
|
||||
|
||||
def posli_reset_hesla(u, request=None):
|
||||
uid = urlsafe_base64_encode(force_bytes(u.pk))
|
||||
token = PasswordResetTokenGenerator().make_token(u)
|
||||
url = "https://%s%s" % (
|
||||
str(get_current_site(request)),
|
||||
str(reverse_lazy("reset_password_confirm", args=[uid, token]))
|
||||
)
|
||||
|
||||
u.email_user(
|
||||
subject="Vítej mezi řešiteli M&M!",
|
||||
message="""Milý řešiteli, milá řešitelko,
|
||||
|
||||
tvůj e-mail byl právě zaregistrován na mam.matfyz.cz. Heslo si prosím nastav na: %s
|
||||
|
||||
Těšíme se na tvé příspěvky do našeho semináře,
|
||||
Organizátoři M&M
|
||||
|
||||
--
|
||||
|
||||
Tento e-mail byl vygenerován automaticky, chceš-li nás kontaktovat, napiš nám na adresu mam@matfyz.cz.
|
||||
""" % url,
|
||||
# TODO: templates/autentizace a django/contrib/auth/forms.py říkají, jak na to lépe
|
||||
from_email="registrace@mam.mff.cuni.cz", # FIXME: Chceme to mít radši tady, nebo v nastavení?
|
||||
)
|
45
various/autentizace/views.py
Normal file
45
various/autentizace/views.py
Normal file
|
@ -0,0 +1,45 @@
|
|||
from django.urls import reverse_lazy
|
||||
from django.contrib.auth import views as auth_views
|
||||
|
||||
|
||||
class LoginView(auth_views.LoginView):
|
||||
# Jen vezmeme vestavěný a dáme mu vhodný template a přesměrovací URL
|
||||
template_name = 'autentizace/login.html'
|
||||
|
||||
|
||||
class LogoutView(auth_views.LogoutView):
|
||||
# Jen vezmeme vestavěný a dáme mu vhodný template a přesměrovací URL
|
||||
template_name = 'autentizace/logout.html'
|
||||
# Pavel: Vůbec nevím, proč to s _lazy funguje, ale bez toho to bylo rozbité.
|
||||
next_page = reverse_lazy('titulni_strana')
|
||||
|
||||
|
||||
# Nejsem si jistý, který view co dostává, tak zahazuji všechny POSTy
|
||||
class PasswordResetView(auth_views.PasswordResetView):
|
||||
""" Chci resetovat heslo. """
|
||||
template_name = 'autentizace/reset_hesla.html'
|
||||
success_url = reverse_lazy('reset_password_done')
|
||||
from_email = 'login@mam.mff.cuni.cz'
|
||||
email_template_name = 'autentizace/password_reset_email.html'
|
||||
subject_template_name = 'autentizace/password_reset_subject.txt'
|
||||
|
||||
|
||||
class PasswordResetDoneView(auth_views.PasswordResetDoneView):
|
||||
""" Poslali jsme e-mail (pokud bylo kam)). """
|
||||
template_name = 'autentizace/reset_poslan.html'
|
||||
|
||||
|
||||
class PasswordResetConfirmView(auth_views.PasswordResetConfirmView):
|
||||
""" Vymysli si heslo. """
|
||||
template_name = 'autentizace/nove_heslo.html'
|
||||
success_url = reverse_lazy('reset_password_complete')
|
||||
|
||||
|
||||
class PasswordResetCompleteView(auth_views.PasswordResetCompleteView):
|
||||
""" Heslo se asi změnilo."""
|
||||
template_name = 'autentizace/nove_nastaveno.html'
|
||||
|
||||
|
||||
class PasswordChangeView(auth_views.PasswordChangeView):
|
||||
# template_name = 'seminar/password_change.html'
|
||||
success_url = reverse_lazy('titulni_strana')
|
Loading…
Reference in a new issue