Merge branch 'data_migrations' into test
This commit is contained in:
		
						commit
						af803ddfb7
					
				
					 5 changed files with 216 additions and 59 deletions
				
			
		|  | @ -582,7 +582,7 @@ class Organizator(SeminarModelBase): | |||
| 		"školu, ale jen obor, možnost zobrazit zvlášť") | ||||
| 
 | ||||
| 	def clean(self): | ||||
| 		if self.organizuje_od > self.organizuje_do: | ||||
| 		if self.organizuje_od and self.organizuje_do and (self.organizuje_od > self.organizuje_do): | ||||
| 			raise ValidationError("Organizátor nemůže skončit s organizováním dříve než začal!") | ||||
| 		super().clean() | ||||
| 
 | ||||
|  |  | |||
|  | @ -17,7 +17,7 @@ | |||
| </h1> | ||||
| 
 | ||||
| {% for clanek in object_list %} | ||||
| {% with clanek.cislo_zadani.rocnik.rocnik as rocnik %} | ||||
| {% with clanek.cislo.rocnik.rocnik as rocnik %} | ||||
|   {% ifchanged rocnik %} | ||||
|     {% if not forloop.first %}</ul>{% endif %} | ||||
|     <h2>{{ rocnik }}. ročník</h2> | ||||
|  |  | |||
							
								
								
									
										86
									
								
								seminar/templates/seminar/orgorozcestnik.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								seminar/templates/seminar/orgorozcestnik.html
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,86 @@ | |||
| {% extends "base.html" %} | ||||
| 
 | ||||
| {% block content %} | ||||
| <h2><strong>Informace, komunikace</strong></h2> | ||||
| 
 | ||||
| <ul> | ||||
| 	<li><strong><a href="https://wiki.mam.bezva.org/">wiki</a> </strong>obsahuje různé návody a know-how</li> | ||||
| 	<li><strong><a href="https://riot.im/app/#/room/#orgovna:dolujeme.eu">Riot</a> </strong>chatování s dalšími orgy</li> | ||||
| 	<li><strong>Kanboard </strong>správa TODO | ||||
| 	<ul> | ||||
| 		<li><a href="https://kanboard.ledoian.cz/?controller=BoardViewController&action=show&project_id=10">webařský</a></li> | ||||
| 		<li>soustředění</li> | ||||
| 	</ul> | ||||
| 	</li> | ||||
| 	<li><a href="https://mam.mff.cuni.cz/admin/seminar/novinky/add/"><strong>přidat novinku</strong></a> na web</li> | ||||
| </ul> | ||||
| 
 | ||||
| <hr /> | ||||
| <h2><strong>Tvorba čísla</strong></h2> | ||||
| 
 | ||||
| <ul> | ||||
| 	<li><a href="https://mam.mff.cuni.cz/admin/seminar/problemnavrh/add/"><strong>přidat téma</strong></a></li> | ||||
| 	<li><strong>korektury</strong> | ||||
| 	<ul> | ||||
| 		<li><a href="https://mam.mff.cuni.cz/korektury/">korekturování</a></li> | ||||
| 		<li><a href="https://mam.mff.cuni.cz/admin/korektury/korekturovanepdf/add/">přidat pdf k opravám</a></li> | ||||
| 	</ul> | ||||
| 	</li> | ||||
| 	<li><a href='{{ posledni_cislo_url }}'><strong>poslední vydané číslo </strong></a></li> | ||||
| </ul> | ||||
| <hr /> | ||||
| 
 | ||||
| <h2><strong>Moje problémy</strong></h2> | ||||
| 
 | ||||
| <h3> Témata </h3> | ||||
| <ul> | ||||
| {% for t in temata %} | ||||
| <li> {{ t }} </li> | ||||
| {% endfor %} | ||||
| </ul> | ||||
| 
 | ||||
| <h3> Úlohy </h3> | ||||
| <ul> | ||||
| {% for u in ulohy %} | ||||
| <li> {{ u }} </li> | ||||
| {% endfor %} | ||||
| </ul> | ||||
| 
 | ||||
| <h3> Články </h3> | ||||
| <ul> | ||||
| {% for c in clanky %} | ||||
| <li> {{ c }} </li> | ||||
| {% endfor %} | ||||
| </ul> | ||||
| 
 | ||||
| <hr /> | ||||
| <h2><strong>Soustředění</strong></h2> | ||||
| 
 | ||||
| <ul> | ||||
| 	<li><strong>přednášky</strong> | ||||
| 
 | ||||
| 	<ul> | ||||
| 		<li><a href="https://mam.mff.cuni.cz/admin/prednasky/prednaska/">vypisování přednášek</a></li> | ||||
| 		<li>hlasování o přednáškách</li> | ||||
| 	</ul> | ||||
| 	</li> | ||||
| 	<li><a href="https://mam.mff.cuni.cz/soustredeni/probehlo/">proběhlá soustředění</a> | ||||
| 	<ul> | ||||
| 		<li>vytvoření galerie</li> | ||||
| 		<li>stažení seznamu účastníků</li> | ||||
| 		<li>obálky</li> | ||||
| 	</ul> | ||||
| 	</li> | ||||
| </ul> | ||||
| 
 | ||||
| <hr /> | ||||
| <h2><strong>Můj profil</strong></h2> | ||||
| 
 | ||||
| <ul> | ||||
| 	<li><a href="http://127.0.0.1:8000/admin/seminar/organizator/{{ organizator.id }}/change/"><strong>upravit </strong></a></li> | ||||
| </ul> | ||||
| 
 | ||||
| <hr /> | ||||
| <p>Nemůžeš najít, co hledáš? Může to být v <a href="https://mam.mff.cuni.cz/admin/">administračním rozhraní webu</a>.</p> | ||||
| {% endblock content %} | ||||
| 
 | ||||
|  | @ -90,6 +90,9 @@ urlpatterns = [ | |||
| 
 | ||||
| 	path('org/vloz_body/<int:tema>/', | ||||
| 		staff_member_required(views.VlozBodyView.as_view()),name='seminar_org_vlozbody'), | ||||
| 	# příprava na nestatický orgorozcestník | ||||
| 	path('org/rozcestnik/', | ||||
| 		staff_member_required(views.OrgoRozcestnikView.as_view()),name='seminar_org_rozcestnik'), | ||||
| 	path('prihlaska/',views.prihlaskaView, name='seminar_prihlaska'), | ||||
| 	path('login/', views.LoginView.as_view(), name='login'), | ||||
| 	path('logout/', views.LogoutView.as_view(), name='logout'), | ||||
|  |  | |||
|  | @ -10,6 +10,7 @@ from django.http import Http404,HttpResponseBadRequest,HttpResponseRedirect | |||
| from django.db.models import Q, Sum, Count | ||||
| from django.views.decorators.csrf import ensure_csrf_cookie | ||||
| from django.views.generic.edit import FormView, CreateView | ||||
| from django.views.generic.base import TemplateView | ||||
| 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 | ||||
|  | @ -200,7 +201,7 @@ class AktualniZadaniView(TreeNodeView): | |||
| #			"cisla" : cisla | ||||
| #		}) | ||||
| #	return render(request, 'seminar/tematka/rozcestnik.html', {"tematka": tematka, "rocnik" : nastaveni.aktualni_rocnik().rocnik}) | ||||
| #     | ||||
| #	 | ||||
| 
 | ||||
| #def ZadaniAktualniVysledkovkaView(request): | ||||
| #	nastaveni = get_object_or_404(Nastaveni) | ||||
|  | @ -873,6 +874,43 @@ def oldObalkovaniView(request, rocnik, cislo): | |||
| 		{'cislo': cislo, 'problemy': problemy, 'reseni': reseni} | ||||
| 	) | ||||
| 
 | ||||
| ### Orgostránky | ||||
| 
 | ||||
| class OrgoRozcestnikView(TemplateView): | ||||
| 	''' Zobrazí organizátorský rozcestník.''' | ||||
| 
 | ||||
| 	template_name = 'seminar/orgorozcestnik.html' | ||||
| 
 | ||||
| 	def get_context_data(self, **kwargs): | ||||
| 		context = super().get_context_data(**kwargs) | ||||
| 		context['posledni_soustredeni'] = Soustredeni.objects.order_by('-datum_konce').first() | ||||
| 		nastaveni = Nastaveni.objects.first() | ||||
| 		aktualni_rocnik = nastaveni.aktualni_rocnik | ||||
| 		context['posledni_cislo_url'] = nastaveni.aktualni_cislo.verejne_url() | ||||
| 		# TODO možná chceme odkazovat na právě rozpracované číslo, a ne to poslední vydané | ||||
| 		# pokud nechceme haluzit kód (= poradi) dalšího čísla, bude asi potřeba jít  | ||||
| 		# přes treenody (a dát si přitom pozor na MezicisloNode) | ||||
| 
 | ||||
| 		u = self.request.user | ||||
| 		os = s.Osoba.objects.get(user=u) | ||||
| 		organizator = s.Organizator.objects.get(osoba=os) | ||||
| 		temata_garant = s.Tema.objects.filter(garant=organizator,  | ||||
| 			rocnik=aktualni_rocnik) | ||||
| 		#FIXME: přidat opravovatel, stav='STAV_ZADANY' | ||||
| 		ulohy_garant = s.Uloha.objects.filter(garant=organizator, | ||||
| 			cislo_zadani__rocnik=aktualni_rocnik) | ||||
| 		clanky_garant = s.Clanek.objects.filter(garant=organizator, | ||||
| 			cislo__rocnik=aktualni_rocnik) | ||||
| 
 | ||||
| 		context['temata'] = temata_garant | ||||
| 		context['ulohy'] = ulohy_garant | ||||
| 		context['clanky'] = clanky_garant | ||||
| 		context['organizator'] = organizator | ||||
| 		return context | ||||
| 
 | ||||
| 		#content_type = 'text/plain; charset=UTF8' | ||||
| 	#XXX | ||||
| 
 | ||||
| ### Tituly | ||||
| 
 | ||||
| def TitulyView(request, rocnik, cislo): | ||||
|  | @ -951,12 +989,42 @@ def soustredeniUcastniciExportView(request,soustredeni): | |||
| 
 | ||||
| 
 | ||||
| ### Články | ||||
| def group_by_rocnik(clanky): | ||||
| 	''' Vezme zadaný seznam článků a seskupí je podle ročníku. | ||||
| 	Vrátí seznam seznamů článků ze stejného ročníku.''' | ||||
| 	if len(clanky) == 0: | ||||
| 		return clanky | ||||
| 	clanky.order_by('cislo__rocnik__rocnik') | ||||
| 	skupiny_clanku = [] | ||||
| 	skupina = [] | ||||
| 
 | ||||
| 	rocnik = clanky.first().cislo.rocnik.rocnik # první ročník | ||||
| 	for clanek in clanky: | ||||
| 		if clanek.cislo.rocnik.rocnik == rocnik: | ||||
| 			skupina.append(clanek) | ||||
| 		else: | ||||
| 			skupiny_clanku.append(skupina) | ||||
| 			skupina = [] | ||||
| 			skupina.append(clanek) | ||||
| 			rocnik = clanek.cislo.rocnik.rocnik | ||||
| 	skupiny_clanku.append(skupina) | ||||
| 	return skupiny_clanku | ||||
| 	 | ||||
| 
 | ||||
| # FIXME: clanky jsou vsechny, pokud budou i neresitelske, tak se take zobrazi | ||||
| class ClankyResitelView(generic.ListView): | ||||
| 	model = Problem | ||||
| 	template_name = 'seminar/clanky/resitelske_clanky.html' | ||||
| 	queryset = Clanek.objects.filter(stav=Problem.STAV_ZADANY).select_related('cislo_zadani__rocnik').order_by('-cislo_zadani__rocnik__rocnik', 'kod') | ||||
| 	#queryset | ||||
| 	clanky = Clanek.objects.filter(stav=Problem.STAV_ZADANY).select_related('cislo__rocnik').order_by('-cislo__rocnik__rocnik') | ||||
| 	queryset = [] | ||||
| 	skupiny_clanku = group_by_rocnik(clanky) | ||||
| 	for skupina in skupiny_clanku: | ||||
| 		skupina.sort(key=lambda clanek: clanek.kod_v_rocniku()) | ||||
| 		for clanek in skupina: | ||||
| 			queryset.append(clanek) | ||||
| 
 | ||||
| 	#zadani__rocnik').order_by('-cislo_zadani__rocnik__rocnik', 'kod') | ||||
| 
 | ||||
| # FIXME: pokud chceme orgoclanky, tak nejak zavest do modelu a podle toho odkomentovat a upravit | ||||
| #class ClankyOrganizatorView(generic.ListView)<F12>: | ||||
|  | @ -1065,63 +1133,63 @@ def logoutView(request): | |||
| 
 | ||||
| 
 | ||||
| def prihlaska_log_gdpr_safe(logger, gdpr_logger, msg, form_data): | ||||
| 	msg = "{}, form_hash:{}".format(msg,hash(form_data)) | ||||
| 	msg = "{}, form_hash:{}".format(msg,hash(frozenset(form_data.items))) | ||||
| 	logger.warn(msg) | ||||
| 	gdpr_logger.warn(msg+", form:{}".format(form_data))		 | ||||
| 
 | ||||
| from django.forms.models import model_to_dict | ||||
| def resitelEditView(request): | ||||
|     err_logger = logging.getLogger('seminar.prihlaska.problem') | ||||
|     ## Načtení objektu Osoba a Resitel, patrici k aktuálně přihlášenému uživately | ||||
|     u = request.user | ||||
|     osoba_edit = Osoba.objects.get(user=u) | ||||
|     resitel_edit = osoba_edit.resitel | ||||
|     user_edit = osoba_edit.user | ||||
|     ## Vytvoření slovníku, kterým předvyplním formulář  | ||||
|     prefill_1=model_to_dict(user_edit) | ||||
|     prefill_2=model_to_dict(resitel_edit) | ||||
|     prefill_3=model_to_dict(osoba_edit) | ||||
|     prefill_1.update(prefill_2) | ||||
|     prefill_1.update(prefill_3) | ||||
|     form = ProfileEditForm(initial=prefill_1) | ||||
|     ## Změna údajů a jejich uložení | ||||
|     if request.method == 'POST': | ||||
|         form = ProfileEditForm(request.POST) | ||||
|         if form.is_valid(): | ||||
|             ## Změny v osobě | ||||
|             fcd = form.cleaned_data | ||||
|             osoba_edit.jmeno = fcd['jmeno'] | ||||
|             osoba_edit.prijmeni = fcd['prijmeni'] | ||||
|             osoba_edit.pohlavi_muz = fcd['pohlavi_muz'] | ||||
|             osoba_edit.email = fcd['email'] | ||||
|             osoba_edit.telefon = fcd['telefon'] | ||||
|             osoba_edit.ulice = fcd['ulice'] | ||||
|             osoba_edit.mesto = fcd['mesto'] | ||||
|             osoba_edit.psc = fcd['psc'] | ||||
|             ## Změny v osobě s podmínkami | ||||
|             if fcd.get('spam',False): | ||||
|                 osoba_edit.datum_souhlasu_zasilani = date.today() | ||||
|             if fcd.get('stat','') in ('CZ','SK'): | ||||
|                 osoba_edit.stat = fcd['stat'] | ||||
|             else: | ||||
|                 ## Neznámá země | ||||
|                 msg = "Unknown country {}".format(fcd['stat_text']) | ||||
| 	err_logger = logging.getLogger('seminar.prihlaska.problem') | ||||
| 	## Načtení objektu Osoba a Resitel, patrici k aktuálně přihlášenému uživately | ||||
| 	u = request.user | ||||
| 	osoba_edit = Osoba.objects.get(user=u) | ||||
| 	resitel_edit = osoba_edit.resitel | ||||
| 	user_edit = osoba_edit.user | ||||
| 	## Vytvoření slovníku, kterým předvyplním formulář  | ||||
| 	prefill_1=model_to_dict(user_edit) | ||||
| 	prefill_2=model_to_dict(resitel_edit) | ||||
| 	prefill_3=model_to_dict(osoba_edit) | ||||
| 	prefill_1.update(prefill_2) | ||||
| 	prefill_1.update(prefill_3) | ||||
| 	form = ProfileEditForm(initial=prefill_1) | ||||
| 	## Změna údajů a jejich uložení | ||||
| 	if request.method == 'POST': | ||||
| 		form = ProfileEditForm(request.POST) | ||||
| 		if form.is_valid(): | ||||
| 			## Změny v osobě | ||||
| 			fcd = form.cleaned_data | ||||
| 			osoba_edit.jmeno = fcd['jmeno'] | ||||
| 			osoba_edit.prijmeni = fcd['prijmeni'] | ||||
| 			osoba_edit.pohlavi_muz = fcd['pohlavi_muz'] | ||||
| 			osoba_edit.email = fcd['email'] | ||||
| 			osoba_edit.telefon = fcd['telefon'] | ||||
| 			osoba_edit.ulice = fcd['ulice'] | ||||
| 			osoba_edit.mesto = fcd['mesto'] | ||||
| 			osoba_edit.psc = fcd['psc'] | ||||
| 			## Změny v osobě s podmínkami | ||||
| 			if fcd.get('spam',False): | ||||
| 				osoba_edit.datum_souhlasu_zasilani = date.today() | ||||
| 			if fcd.get('stat','') in ('CZ','SK'): | ||||
| 				osoba_edit.stat = fcd['stat'] | ||||
| 			else: | ||||
| 				## Neznámá země | ||||
| 				msg = "Unknown country {}".format(fcd['stat_text']) | ||||
| 
 | ||||
|             ## Změny v řešiteli | ||||
|             resitel_edit.skola = fcd['skola'] | ||||
|             resitel_edit.rok_maturity = fcd['rok_maturity'] | ||||
|             resitel_edit.zasilat = fcd['zasilat'] | ||||
|             if fcd.get('skola'): | ||||
|                 resitel_edit.skola = fcd['skola'] | ||||
|             else: | ||||
|                 # Unknown school - log it | ||||
|                 msg = "Unknown school {}, {}".format(fcd['skola_nazev'],fcd['skola_adresa']) | ||||
|             resitel_edit.save() | ||||
|             osoba_edit.save() | ||||
|             return HttpResponseRedirect('/thanks/') | ||||
|     else: | ||||
|         ## Stránka před odeslaním formuláře = předvyplněný formulář | ||||
|         return render(request, 'seminar/profil/edit.html', {'form': form}) | ||||
| 			## Změny v řešiteli | ||||
| 			resitel_edit.skola = fcd['skola'] | ||||
| 			resitel_edit.rok_maturity = fcd['rok_maturity'] | ||||
| 			resitel_edit.zasilat = fcd['zasilat'] | ||||
| 			if fcd.get('skola'): | ||||
| 				resitel_edit.skola = fcd['skola'] | ||||
| 			else: | ||||
| 				# Unknown school - log it | ||||
| 				msg = "Unknown school {}, {}".format(fcd['skola_nazev'],fcd['skola_adresa']) | ||||
| 			resitel_edit.save() | ||||
| 			osoba_edit.save() | ||||
| 			return HttpResponseRedirect('/thanks/') | ||||
| 	else: | ||||
| 		## Stránka před odeslaním formuláře = předvyplněný formulář | ||||
| 		return render(request, 'seminar/profil/edit.html', {'form': form}) | ||||
| 
 | ||||
| def prihlaskaView(request): | ||||
| 	generic_logger = logging.getLogger('seminar.prihlaska') | ||||
|  | @ -1133,8 +1201,8 @@ def prihlaskaView(request): | |||
| 		if form.is_valid(): | ||||
| 			generic_logger.info("Form valid") | ||||
| 			fcd = form.cleaned_data | ||||
| 			form_hash = hash(fcd) | ||||
| 			form_logger.info(fcd,form_hash=form_hash) | ||||
| 			form_hash = hash(frozenset(fcd.items())) | ||||
| 			form_logger.info(fcd,form_hash)  # TODO takhle log nefunguje, ale ta předchozí varianta dokonce padala | ||||
| 			 | ||||
| 			with transaction.atomic(): | ||||
| 				u = User.objects.create_user( | ||||
|  | @ -1164,7 +1232,7 @@ def prihlaskaView(request): | |||
| 				else: | ||||
| 					# Unknown country - log it | ||||
| 					msg = "Unknown country {}".format(fcd['stat_text']) | ||||
| 					err_logger.warn(msg,form_hash=form_hash) | ||||
| 					err_logger.warn(msg,form_hash)  # TODO viz výše | ||||
| 
 | ||||
| 				o.save() | ||||
| 				o.user = u | ||||
|  | @ -1182,7 +1250,7 @@ def prihlaskaView(request): | |||
| 				else: | ||||
| 					# Unknown school - log it | ||||
| 					msg = "Unknown school {}, {}".format(fcd['skola_nazev'],fcd['skola_adresa']) | ||||
| 					err_logger.warn(msg,form_hash=form_hash) | ||||
| 					err_logger.warn(msg,form_hash)  # TODO viz výše | ||||
| 				r.save() | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Pavel "LEdoian" Turinsky
						Pavel "LEdoian" Turinsky