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 | import django | ||||||
| from django.shortcuts import get_object_or_404, render | from django.shortcuts import get_object_or_404 | ||||||
| from django.http import HttpResponse | from django.http import HttpResponse | ||||||
| from django.urls import reverse | from django.urls import reverse | ||||||
| from django.views import generic | from django.views import generic | ||||||
| from django.utils.encoding import force_text | from django.utils.encoding import force_text | ||||||
| 
 | 
 | ||||||
| from .models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni | from .utils import default_ovvpfile | ||||||
| #from .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva | from seminar.models import Rocnik, Soustredeni | ||||||
| from .ovvpfile import OvvpFile |  | ||||||
| from seminar import views |  | ||||||
| from seminar.views import vysledkovka | from seminar.views import vysledkovka | ||||||
| from seminar.utils import aktivniResitele | 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') | 		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): | class ExportSousView(generic.View): | ||||||
| 
 | 
 | ||||||
| 	def get(self, request, datum_zacatku=None): | 	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 | import seminar.models as m | ||||||
| from .helpers import LoginRequiredAjaxMixin | 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): | class SkolaAutocomplete(autocomplete.Select2QuerySetView): | ||||||
| 	def get_queryset(self): | 	def get_queryset(self): | ||||||
|         	# Don't forget to filter out results depending on the visitor ! |         	# Don't forget to filter out results depending on the visitor ! | ||||||
| 		qs = m.Skola.objects.all() | 		qs = m.Skola.objects.all() | ||||||
| 		if self.q: | 		if self.q: | ||||||
| 			qs = qs.filter( | 			words = self.q.split(' ') #TODO re split podle bileho znaku | ||||||
| 				Q(nazev__istartswith=self.q)| | 			partq = Q() | ||||||
| 				Q(kratky_nazev__istartswith=self.q)| | 			for w in words:	# Hledej po slovech, zahoď čárky a tečky z konců.  | ||||||
| 				Q(ulice__istartswith=self.q)| | 				if w[-1] in (".",","): | ||||||
| 				Q(mesto__istartswith=self.q)) | 					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 | 		return qs | ||||||
| 
 | 
 | ||||||
|  | @ -1,4 +1,5 @@ | ||||||
| from dal import autocomplete | from django.http import JsonResponse | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| class LoginRequiredAjaxMixin(object): | class LoginRequiredAjaxMixin(object): | ||||||
| 	def dispatch(self, request, *args, **kwargs): | 	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', |     'prednasky', | ||||||
|     'header_fotky', |     'header_fotky', | ||||||
|     'various', |     'various', | ||||||
|  |     'various.autentizace', | ||||||
|  |     'api', | ||||||
|  |     'aesop', | ||||||
| 
 | 
 | ||||||
|     # Admin upravy: |     # Admin upravy: | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -23,6 +23,15 @@ urlpatterns = [ | ||||||
| 	# Prednaskova aplikace (ma vlastni podadresare) | 	# Prednaskova aplikace (ma vlastni podadresare) | ||||||
| 	path('', include('prednasky.urls')), | 	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) | 	# Comments (interni i verejne) | ||||||
| 	path('comments_dj/', include('django_comments.urls')), | 	path('comments_dj/', include('django_comments.urls')), | ||||||
| 	path('comments_fl/', include('fluent_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 solo.admin import SingletonModelAdmin | ||||||
| from django.utils.safestring import mark_safe | from django.utils.safestring import mark_safe | ||||||
| 
 | 
 | ||||||
| from seminar.views.vysledkovka import hlavni_problem | from seminar.utils import hlavni_problem | ||||||
| # TODO Přesunout do utils |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| # Todo: reversion | # Todo: reversion | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -27,16 +27,6 @@ class TelInput(forms.TextInput): | ||||||
|     input_type = 'tel' |     input_type = 'tel' | ||||||
|     input_pattern="^[+]?[()/0-9. -]{9,}$" |     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): | class PrihlaskaForm(PasswordResetForm): | ||||||
| 	username = forms.CharField(label='Přihlašovací jméno',  | 	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): | 	def getOdkazStr(self): | ||||||
| 		return str(self.reseni) | 		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) | @reversion.register(ignore_duplicates=True) | ||||||
| class Nastaveni(SingletonModel): | class Nastaveni(SingletonModel): | ||||||
|  | @ -1855,35 +1778,3 @@ class Novinky(models.Model): | ||||||
| 			return '[' + str(self.datum) + '] ' + self.text[0:50] | 			return '[' + str(self.datum) + '] ' + self.text[0:50] | ||||||
| 		else: | 		else: | ||||||
| 			return '[' + str(self.datum) + '] ' | 			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> | <p>Žádné přílohy</p> | ||||||
| {% endif %} | {% endif %} | ||||||
| 
 | 
 | ||||||
| <form method=post> | <form method=post onsubmit="return zkontroluj_hodnoceni();"> | ||||||
| {# Poznámka #} | {# Poznámka #} | ||||||
| <h3>Poznámka:</h3> | <h3>Poznámka:</h3> | ||||||
| <p>{{ poznamka_form.poznamka }}</p> | <p>{{ poznamka_form.poznamka }}</p> | ||||||
|  | @ -99,12 +99,14 @@ $(document).ready(function(){ | ||||||
| <table id="form_set"> | <table id="form_set"> | ||||||
| <tr><th>Problém</th><th>Body</th><th>Číslo pro body</th></tr> | <tr><th>Problém</th><th>Body</th><th>Číslo pro body</th></tr> | ||||||
| {% for subform in form %} | {% for subform in form %} | ||||||
|  |     <tbody> | ||||||
| 	<tr class="hodnoceni"> | 	<tr class="hodnoceni"> | ||||||
| 		<td>{{ subform.problem }}</td> | 		<td>{{ subform.problem }}</td> | ||||||
| 		<td>{{ subform.body }}</td> | 		<td>{{ subform.body }}</td> | ||||||
| 		<td>{{ subform.cislo_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> | 		<td><a href="#" class="smazat_hodnoceni" id="id_{{subform.prefix}}-jsremove"><img src="{% static "seminar/cross.png" %}" alt="Smazat"></a></td> | ||||||
| 	</tr> | 	</tr> | ||||||
|  |     </tbody> | ||||||
| {% endfor %} | {% endfor %} | ||||||
| </table> | </table> | ||||||
| 
 | 
 | ||||||
|  | @ -121,4 +123,19 @@ $(document).ready(function(){ | ||||||
| 	</tr> | 	</tr> | ||||||
| </table> | </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 %} | {% endblock %} | ||||||
|  |  | ||||||
|  | @ -1,8 +1,7 @@ | ||||||
| from django.urls import path, include, re_path | from django.urls import path, include, re_path | ||||||
| from django.contrib.auth.decorators import login_required | 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 .utils import org_required, resitel_required, viewMethodSwitch, resitel_or_org_required | ||||||
| from django.views.generic.base import RedirectView |  | ||||||
| 
 | 
 | ||||||
| urlpatterns = [ | urlpatterns = [ | ||||||
| #	path('aktualni/temata/', views.TemataRozcestnikView), | #	path('aktualni/temata/', views.TemataRozcestnikView), | ||||||
|  | @ -68,23 +67,6 @@ urlpatterns = [ | ||||||
| 	path('archiv/clanky/', views.ClankyResitelView.as_view(), name='clanky_resitel'), | 	path('archiv/clanky/', views.ClankyResitelView.as_view(), name='clanky_resitel'), | ||||||
| 	#path('clanky/org/', views.ClankyOrganizatorView.as_view(), name='clanky_organizator'), | 	#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: | 	# Stranky viditelne pouze pro orgy: | ||||||
| 	path( | 	path( | ||||||
| 		'rocnik/<int:rocnik>/vysledkovka.tex', | 		'rocnik/<int:rocnik>/vysledkovka.tex', | ||||||
|  | @ -133,17 +115,9 @@ urlpatterns = [ | ||||||
| 	), | 	), | ||||||
| 
 | 
 | ||||||
| 	path('prihlaska/',views.prihlaskaView, name='seminar_prihlaska'), | 	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('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( | 	path( | ||||||
| 		'resitel/osobni-udaje/', | 		'resitel/osobni-udaje/', | ||||||
| 		login_required(views.resitelEditView), | 		login_required(views.resitelEditView), | ||||||
|  | @ -153,14 +127,6 @@ urlpatterns = [ | ||||||
| 	# Obecný view na profil -- orgům dá rozcestník, řešitelům jejich stránku | 	# Obecný view na profil -- orgům dá rozcestník, řešitelům jejich stránku | ||||||
| 	path('profil/', views.profilView, name='profil'), | 	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('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'), | 	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('', views.TitulniStranaView.as_view(), name='titulni_strana'), | ||||||
| 	path('jak-resit/', views.JakResitView.as_view(), name='jak_resit'), | 	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/', 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/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'), | 	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 .views_all import * | ||||||
| from .autocomplete import * |  | ||||||
| from .views_rest import * | from .views_rest import * | ||||||
| from .odevzdavatko import * | from .odevzdavatko import * | ||||||
| 
 | 
 | ||||||
| from .exports import * |  | ||||||
| 
 |  | ||||||
| # Dočsasné views | # Dočsasné views | ||||||
| from .docasne import * | 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.shortcuts import get_object_or_404, render, redirect | ||||||
| from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, JsonResponse | from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, JsonResponse | ||||||
| from django.urls import reverse,reverse_lazy | from django.urls import reverse,reverse_lazy | ||||||
| from django.core.exceptions import PermissionDenied, ObjectDoesNotExist | from django.core.exceptions import PermissionDenied, ObjectDoesNotExist | ||||||
| from django.core.mail import send_mail | 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.views import generic | ||||||
| from django.utils.translation import ugettext as _ | from django.utils.translation import ugettext as _ | ||||||
| from django.http import Http404,HttpResponseBadRequest,HttpResponseRedirect | 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.decorators.debug import sensitive_post_parameters | ||||||
| from django.views.generic.edit import FormView, CreateView | from django.views.generic.edit import FormView, CreateView | ||||||
| from django.views.generic.base import TemplateView, RedirectView | 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.models import User, Permission, Group | ||||||
| from django.contrib.auth.mixins import LoginRequiredMixin | from django.contrib.auth.mixins import LoginRequiredMixin | ||||||
| from django.db import transaction | 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 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 .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva | ||||||
| from seminar import utils, treelib | 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.forms as f | ||||||
| import seminar.templatetags.treenodes as tnltt | import seminar.templatetags.treenodes as tnltt | ||||||
| import seminar.views.views_rest as vr | import seminar.views.views_rest as vr | ||||||
|  | @ -54,6 +48,8 @@ import logging | ||||||
| import time | import time | ||||||
| 
 | 
 | ||||||
| from seminar.utils import aktivniResitele, resi_v_rocniku, problemy_rocniku, cisla_rocniku, hlavni_problemy_f | 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 | # ze starého modelu | ||||||
| #def verejna_temata(rocnik): | #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}') | 				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)) | 			posli_reset_hesla(u, request) | ||||||
| 			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í? |  | ||||||
| 			) |  | ||||||
| 
 |  | ||||||
| 			return formularOKView(request, text='Na tvůj e-mail jsme právě poslali odkaz pro nastavení hesla.') | 			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 | 	# 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}) | 	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): | class VueTestView(generic.TemplateView): | ||||||
| 	template_name = 'seminar/vuetest.html' | 	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 | 	## 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í  | 	# 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 | 	# 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 | 	# získáme body za číslo | ||||||
| 	hlavni_problemy_slovnik, cislobody = secti_body_za_cislo(cislo, aktivni_resitele, hlavni_problemy) | 	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