Deadliny už jsou řešené jinak
This commit is contained in:
		
							parent
							
								
									e30ae81854
								
							
						
					
					
						commit
						9e05e0dc0f
					
				
					 3 changed files with 1 additions and 215 deletions
				
			
		|  | @ -19,7 +19,7 @@ import logging | |||
| import seminar.models as m | ||||
| from . import forms as f | ||||
| from .forms import OdevzdavatkoTabulkaFiltrForm as FiltrForm | ||||
| from seminar.utils import resi_v_rocniku, deadline | ||||
| from seminar.utils import resi_v_rocniku | ||||
| from seminar.views import formularOKView | ||||
| 
 | ||||
| logger = logging.getLogger(__name__) | ||||
|  |  | |||
|  | @ -1,149 +0,0 @@ | |||
| from django.test import TestCase | ||||
| from datetime import date | ||||
| 
 | ||||
| import seminar.models as m | ||||
| from seminar.utils import deadline, TypDeadline | ||||
| 
 | ||||
| class DeadlineTestCase(TestCase): | ||||
| 	def setUp(self): | ||||
| 		# Chceme pár ročníků a v nich pár čísel | ||||
| 		r1 = m.Rocnik.objects.create(rocnik=1, prvni_rok=2000, exportovat=False) | ||||
| 		r2 = m.Rocnik.objects.create(rocnik=2, prvni_rok=2001, exportovat=False) | ||||
| 		r3 = m.Rocnik.objects.create(rocnik=3, prvni_rok=2002, exportovat=False) | ||||
| 
 | ||||
| 		# První číslo mívá soustřeďkový deadline… | ||||
| 		c1_1 = m.Cislo.objects.create(rocnik=r1, poradi='1', | ||||
| 				datum_vydani=date.fromisoformat('2000-05-22'), | ||||
| 				datum_preddeadline=date.fromisoformat('2000-09-11'), | ||||
| 				datum_deadline_soustredeni=date.fromisoformat('2000-09-11'), | ||||
| 				datum_deadline=date.fromisoformat('2000-10-01'), | ||||
| 			) | ||||
| 		c1_2 = m.Cislo.objects.create(rocnik=r1, poradi='2', | ||||
| 				datum_vydani=date.fromisoformat('2000-10-19'), | ||||
| 				datum_preddeadline=date.fromisoformat('2000-12-05'), | ||||
| 				datum_deadline=date.fromisoformat('2001-01-02'), | ||||
| 			) | ||||
| 		# Některá čísla nemají předdeadline… | ||||
| 		c1_3 = m.Cislo.objects.create(rocnik=r1, poradi='3', | ||||
| 				datum_vydani=date.fromisoformat('2001-01-28'), | ||||
| 				datum_deadline=date.fromisoformat('2001-03-12'), | ||||
| 			) | ||||
| 		# Poslední číslo nemá ani normální deadline… | ||||
| 		c1_4 = m.Cislo.objects.create(rocnik=r1, poradi='4-5', | ||||
| 				datum_vydani=date.fromisoformat('2001-04-24'), | ||||
| 			) | ||||
| 		# První číslo dalšího ročníku se někdy vydá dřív, než poslední minulého… | ||||
| 		c2_1 = m.Cislo.objects.create(rocnik=r2, poradi='1', | ||||
| 				datum_vydani=date.fromisoformat('2001-04-19'), | ||||
| 				datum_deadline_soustredeni=date.fromisoformat('2001-09-26'), | ||||
| 				datum_deadline=date.fromisoformat('2001-10-07'), | ||||
| 			) | ||||
| 		# Tohle číslo má finální deadline až po vydání prvního čísla dalšího ročníku | ||||
| 		# To samé se skoro stalo na přelomu (reálných) ročníků 27 a 28. | ||||
| 		c2_2 = m.Cislo.objects.create(rocnik=r2, poradi='2', | ||||
| 				datum_vydani=date.fromisoformat('2002-03-14'), | ||||
| 				datum_preddeadline=date.fromisoformat('2002-05-26'), | ||||
| 				datum_deadline=date.fromisoformat('2002-06-30'), | ||||
| 			) | ||||
| 		# Závěrečné číslo druhého ročníku až na podzim | ||||
| 		c2_3 = m.Cislo.objects.create(rocnik=r2, poradi='3', | ||||
| 				datum_vydani=date.fromisoformat('2002-09-05'), | ||||
| 			) | ||||
| 		# Divný případ: sous deadline stejný jako finální | ||||
| 		c3_1 = m.Cislo.objects.create(rocnik=r3, poradi='1', | ||||
| 				datum_vydani=date.fromisoformat('2002-06-02'), | ||||
| 				datum_preddeadline=date.fromisoformat('2002-08-31'), | ||||
| 				datum_deadline=date.fromisoformat('2002-09-30'), | ||||
| 				datum_deadline_soustredeni=date.fromisoformat('2002-09-30'), | ||||
| 			) | ||||
| 
 | ||||
| 	# Celkový harmonogram: | ||||
| 	# 2000-05-22	začátek 1. ročníku, číslo 1.1 | ||||
| 	 | ||||
| 	# 2000-09-11	sous a 1. deadline 1.1 | ||||
| 	# 2000-10-01	finální deadline 1.1 | ||||
| 	# 2000-10-19	Vydání 1.2 | ||||
| 	# 2000-12-05	předdeadline 1.2 | ||||
| 	# 2001-01-02	finální deadline 1.2 | ||||
| 	# 2001-01-28	vyd 1.3 | ||||
| 	# 2001-03-12	deadline 1.3 | ||||
| 	# 2001-04-19	Začátek 2. ročníku, číslo 2.1 | ||||
| 	# 2001-04-24	Vydání 1.4-5 -- závěrečné číslo 1. roč. | ||||
| 	 | ||||
| 	# 2001-09-26	Sous-deadline 2.1 | ||||
| 	# 2001-10-07	Deadline 2.1 | ||||
| 	# 2002-03-14	Pí den, vydání 2.2 | ||||
| 	# 2002-05-26	Předdeadline 2.2 | ||||
| 	# 2002-06-02	Třetí ročník, vydání 3.1 | ||||
| 	# 2002-06-30	Deadline 2.2 | ||||
| 
 | ||||
| 	# 2002-08-31	Předdeadline 3.1 | ||||
| 	# 2002-09-04	Vydání 2.3, konec 2. roč. | ||||
| 	# 2002-09-30	Sous a finální deadline 3.1 | ||||
| 	 | ||||
| 	def test_deadline_spravne_vysledky(self): | ||||
| 		"""V každém intervalu mezi deadliny dostáváme ten správný deadline""" | ||||
| 		# První ročník | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2000-05-30')), (TypDeadline.PredDeadline, m.Cislo.objects.get(rocnik__rocnik=1, poradi='1'), date.fromisoformat('2000-09-11'))) | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2000-09-15')), (TypDeadline.FinalDeadline, m.Cislo.objects.get(rocnik__rocnik=1, poradi='1'), date.fromisoformat('2000-10-01'))) | ||||
| 
 | ||||
| 		# Trochu divný případ, kdy někdo něco pošle před vydáním čísla. Ale článkům se to asi stát může… | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2000-10-10')), (TypDeadline.PredDeadline, m.Cislo.objects.get(rocnik__rocnik=1, poradi='2'), date.fromisoformat('2000-12-05'))) | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2000-10-22')), (TypDeadline.PredDeadline, m.Cislo.objects.get(rocnik__rocnik=1, poradi='2'), date.fromisoformat('2000-12-05'))) | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2000-12-15')), (TypDeadline.FinalDeadline, m.Cislo.objects.get(rocnik__rocnik=1, poradi='2'), date.fromisoformat('2001-01-02'))) | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2001-01-08')), (TypDeadline.FinalDeadline, m.Cislo.objects.get(rocnik__rocnik=1, poradi='3'), date.fromisoformat('2001-03-12'))) | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2001-01-30')), (TypDeadline.FinalDeadline, m.Cislo.objects.get(rocnik__rocnik=1, poradi='3'), date.fromisoformat('2001-03-12'))) | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2001-03-15')), (TypDeadline.SousDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='1'), date.fromisoformat('2001-09-26'))) | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2001-04-22')), (TypDeadline.SousDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='1'), date.fromisoformat('2001-09-26'))) | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2001-04-30')), (TypDeadline.SousDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='1'), date.fromisoformat('2001-09-26'))) | ||||
| 
 | ||||
| 		# Druhý ročník | ||||
| 		# Pro jistotu ještě prázdniny | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2001-07-30')), (TypDeadline.SousDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='1'), date.fromisoformat('2001-09-26'))) | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2001-09-27')), (TypDeadline.FinalDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='1'), date.fromisoformat('2001-10-07'))) | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2001-12-27')), (TypDeadline.PredDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='2'), date.fromisoformat('2002-05-26'))) | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2002-03-15')), (TypDeadline.PredDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='2'), date.fromisoformat('2002-05-26'))) | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2002-03-15')), (TypDeadline.PredDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='2'), date.fromisoformat('2002-05-26'))) | ||||
| 		 | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2002-05-27')), (TypDeadline.FinalDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='2'), date.fromisoformat('2002-06-30'))) | ||||
| 		# Tohle je trochu podezřelý případ, protože relevantní deadliny existují dvě… Ale ten pro minulý ročník je těsnější a realističtější | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2002-06-03')), (TypDeadline.FinalDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='2'), date.fromisoformat('2002-06-30'))) | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2002-07-01')), (TypDeadline.PredDeadline, m.Cislo.objects.get(rocnik__rocnik=3, poradi='1'), date.fromisoformat('2002-08-31'))) | ||||
| 
 | ||||
| 		# Třetí ročník | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2002-09-01')), (TypDeadline.SousDeadline, m.Cislo.objects.get(rocnik__rocnik=3, poradi='1'), date.fromisoformat('2002-09-30'))) | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2002-09-05')), (TypDeadline.SousDeadline, m.Cislo.objects.get(rocnik__rocnik=3, poradi='1'), date.fromisoformat('2002-09-30'))) | ||||
| 
 | ||||
| 	def test_deadline_ve_zlomove_dny(self): | ||||
| 		"""Pro dny, kdy je deadline nebo vydání čísla, pořád dostáváme správné deadliny. | ||||
| 
 | ||||
| 		Testuje hlavně přítomnost někde nějakých off-by-one""" | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2000-05-22')), (TypDeadline.PredDeadline, m.Cislo.objects.get(rocnik__rocnik=1, poradi='1'), date.fromisoformat('2000-09-11'))) | ||||
| 
 | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2000-09-11')), (TypDeadline.PredDeadline, m.Cislo.objects.get(rocnik__rocnik=1, poradi='1'), date.fromisoformat('2000-09-11'))) | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2000-10-01')), (TypDeadline.FinalDeadline, m.Cislo.objects.get(rocnik__rocnik=1, poradi='1'), date.fromisoformat('2000-10-01'))) | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2000-10-19')), (TypDeadline.PredDeadline, m.Cislo.objects.get(rocnik__rocnik=1, poradi='2'), date.fromisoformat('2000-12-05'))) | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2000-12-05')), (TypDeadline.PredDeadline, m.Cislo.objects.get(rocnik__rocnik=1, poradi='2'), date.fromisoformat('2000-12-05'))) | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2001-01-02')), (TypDeadline.FinalDeadline, m.Cislo.objects.get(rocnik__rocnik=1, poradi='2'), date.fromisoformat('2001-01-02'))) | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2001-01-28')), (TypDeadline.FinalDeadline, m.Cislo.objects.get(rocnik__rocnik=1, poradi='3'), date.fromisoformat('2001-03-12'))) | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2001-03-12')), (TypDeadline.FinalDeadline, m.Cislo.objects.get(rocnik__rocnik=1, poradi='3'), date.fromisoformat('2001-03-12'))) | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2001-04-19')), (TypDeadline.SousDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='1'), date.fromisoformat('2001-09-26'))) | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2001-04-24')), (TypDeadline.SousDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='1'), date.fromisoformat('2001-09-26'))) | ||||
| 
 | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2001-09-26')), (TypDeadline.SousDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='1'), date.fromisoformat('2001-09-26'))) | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2001-10-07')), (TypDeadline.FinalDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='1'), date.fromisoformat('2001-10-07'))) | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2002-03-14')), (TypDeadline.PredDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='2'), date.fromisoformat('2002-05-26'))) | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2002-05-26')), (TypDeadline.PredDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='2'), date.fromisoformat('2002-05-26'))) | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2002-06-02')), (TypDeadline.FinalDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='2'), date.fromisoformat('2002-06-30'))) | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2002-06-30')), (TypDeadline.FinalDeadline, m.Cislo.objects.get(rocnik__rocnik=2, poradi='2'), date.fromisoformat('2002-06-30'))) | ||||
| 
 | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2002-08-31')), (TypDeadline.PredDeadline, m.Cislo.objects.get(rocnik__rocnik=3, poradi='1'), date.fromisoformat('2002-08-31'))) | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2002-09-04')), (TypDeadline.SousDeadline, m.Cislo.objects.get(rocnik__rocnik=3, poradi='1'), date.fromisoformat('2002-09-30'))) | ||||
| 		self.assertEqual(deadline(date.fromisoformat('2002-09-30')), (TypDeadline.SousDeadline, m.Cislo.objects.get(rocnik__rocnik=3, poradi='1'), date.fromisoformat('2002-09-30'))) | ||||
| 
 | ||||
| 	def test_deadline_pro_datetime(self): | ||||
| 		"""Testuje, že i pro datetime dostáváme správné deadliny""" | ||||
| 		self.skipTest('Chybí implementace testu') | ||||
| 
 | ||||
| 	def test_moc_pozdni_deadline(self): | ||||
| 		self.assertIsNone(deadline(date.max)) | ||||
|  | @ -14,9 +14,6 @@ from django.contrib.auth.models import AnonymousUser | |||
| from django.contrib.contenttypes.models import ContentType | ||||
| from django.core.exceptions import ObjectDoesNotExist | ||||
| 
 | ||||
| from enum import Enum | ||||
| from enum import auto | ||||
| 
 | ||||
| import logging | ||||
| 
 | ||||
| import seminar.models as m | ||||
|  | @ -249,68 +246,6 @@ def viewMethodSwitch(get, post): | |||
| 	return NewView.as_view() | ||||
| 
 | ||||
| 
 | ||||
| class TypDeadline(Enum): | ||||
| 	PredDeadline = auto() | ||||
| 	SousDeadline = auto() | ||||
| 	FinalDeadline = auto() | ||||
| 
 | ||||
| def deadline_v_rocniku(datum, rocnik): | ||||
| 	"""Funkce pro dohledání, ke kterému deadlinu daného ročníku se datum váže. | ||||
| 	 | ||||
| 	Vrací trojici (TypDeadline, Cislo, datumDeadline: date). | ||||
| 
 | ||||
| 	V případě nevalidního volání není aktuálně chování definováno(!) | ||||
| 	""" | ||||
| 	cisla = m.Cislo.objects.filter(rocnik=rocnik) | ||||
| 	deadliny = [] | ||||
| 	for c in cisla: | ||||
| 		if c.datum_preddeadline is not None: | ||||
| 			deadliny.append((TypDeadline.PredDeadline, c, c.datum_preddeadline)) | ||||
| 		if c.datum_deadline_soustredeni is not None: | ||||
| 			deadliny.append((TypDeadline.SousDeadline, c, c.datum_deadline_soustredeni)) | ||||
| 		if c.datum_deadline is not None: | ||||
| 			deadliny.append((TypDeadline.FinalDeadline, c, c.datum_deadline)) | ||||
| 	deadliny = sorted(deadliny, key=lambda x: x[2])	# podle data | ||||
| 	for dl in deadliny: | ||||
| 		if datum <= dl[2]: | ||||
| 			# První takový deadline je ten nejtěsnější | ||||
| 			return dl | ||||
| 	logger.error(f'Pro datum {datum} v ročníku {rocnik} neexistuje deadline.') | ||||
| 
 | ||||
| def deadline(datum): | ||||
| 	"""Funkce pro dohledání, ke kterému deadlinu se datum váže. | ||||
| 	 | ||||
| 	Vrací trojici (TypDeadline, Cislo, datumDeadline: date). Pokud se deadline nenajde, vrátí None | ||||
| 	""" | ||||
| 
 | ||||
| 	if isinstance(datum, datetime.datetime): | ||||
| 		datum = datum.date() | ||||
| 	rok = datum.year | ||||
| 	# Dva ročníky podezřelé z obsahování dat | ||||
| 	try: | ||||
| 		pozdejsi_rocnik = m.Rocnik.objects.get(prvni_rok=rok) | ||||
| 	except m.Rocnik.DoesNotExist: | ||||
| 		pozdejsi_rocnik = None | ||||
| 
 | ||||
| 	try: | ||||
| 		drivejsi_rocnik = m.Rocnik.objects.get(prvni_rok=rok-1) | ||||
| 	except m.Rocnik.DoesNotExist: | ||||
| 		drivejsi_rocnik = None | ||||
| 
 | ||||
| 	if drivejsi_rocnik is not None: | ||||
| 		# Předpokládáme, že neexistuje číslo, které má deadline ale nemá finální deadline. | ||||
| 		# Seznam čísel je potřeba ručně setřídit chronologicky, protože Model říká, že se řadí od nejnovějšího | ||||
| 		posledni_deadline_drivejsiho_rocniku = m.Cislo.objects.filter(rocnik=drivejsi_rocnik, datum_deadline__isnull=False).order_by('poradi').last().datum_deadline | ||||
| 
 | ||||
| 	logger.debug(f'Nalezené ročníky: {drivejsi_rocnik}, {pozdejsi_rocnik}') | ||||
| 	if drivejsi_rocnik is not None and datum <= posledni_deadline_drivejsiho_rocniku: | ||||
| 		logger.debug(f'Hledám v dřívějším ročníku: {drivejsi_rocnik}') | ||||
| 		return deadline_v_rocniku(datum, drivejsi_rocnik) | ||||
| 	else: | ||||
| 		logger.debug(f'Hledám v pozdějším ročníku: {pozdejsi_rocnik}') | ||||
| 		return deadline_v_rocniku(datum, pozdejsi_rocnik) | ||||
| 
 | ||||
| 
 | ||||
| def sync_skoly(base_url): | ||||
| 	"""Stáhne všechny školy z mamwebu na adrese <base_url> a uloží je do databáze""" | ||||
| 	from django.urls import reverse | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue