Merge branch 'data_migrations' of gimli.ms.mff.cuni.cz:/akce/mam/git/mamweb into data_migrations
This commit is contained in:
		
						commit
						740a7fe758
					
				
					 1 changed files with 68 additions and 50 deletions
				
			
		|  | @ -463,7 +463,8 @@ def body_resitelu(resitele, za, odjakziva=True): | ||||||
| 				   reseni__hodnoceni__cislo_body__poradi__lte=cislo.poradi) )) | 				   reseni__hodnoceni__cislo_body__poradi__lte=cislo.poradi) )) | ||||||
| 	elif cislo and not odjakziva: # Body se sčítají za dané číslo. | 	elif cislo and not odjakziva: # Body se sčítají za dané číslo. | ||||||
| 		body_k_zapocteni = Sum('reseni__hodnoceni__body', | 		body_k_zapocteni = Sum('reseni__hodnoceni__body', | ||||||
| 			filter=( Q(reseni__hodnoceni__cislo_body=cislo) )) | 			filter=( Q(reseni__hodnoceni__cislo_body__rocnik__prvni_rok=rok, | ||||||
|  | 					reseni__hodnoceni__cislo_body__poradi__lte=cislo.poradi) )) | ||||||
| 	elif rocnik and odjakziva: # Spočítáme body za starší ročníky až do zadaného včetně.	 | 	elif rocnik and odjakziva: # Spočítáme body za starší ročníky až do zadaného včetně.	 | ||||||
| 		body_k_zapocteni = Sum('reseni__hodnoceni__body',  | 		body_k_zapocteni = Sum('reseni__hodnoceni__body',  | ||||||
| 			filter= Q(reseni__hodnoceni__cislo_body__rocnik__prvni_rok__lte=rok)) | 			filter= Q(reseni__hodnoceni__cislo_body__rocnik__prvni_rok__lte=rok)) | ||||||
|  | @ -503,10 +504,7 @@ def vysledkovka_rocniku(rocnik, jen_verejne=True): | ||||||
| 	## 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(Resitel.objects.filter( | 	aktivni_resitele = list(resi_v_rocniku(rocnik)) | ||||||
| 			rok_maturity__gte=rocnik.druhy_rok())) |  | ||||||
| 			# TODO: zkusit hodnoceni__rocnik... |  | ||||||
| 			#.filter(hodnoceni_set__rocnik__eq=cislo_rocnik) |  | ||||||
| 	cisla = cisla_rocniku(rocnik, jen_verejne) | 	cisla = cisla_rocniku(rocnik, jen_verejne) | ||||||
| 	body_cisla_slov = {} | 	body_cisla_slov = {} | ||||||
| 	for cislo in cisla: | 	for cislo in cisla: | ||||||
|  | @ -636,10 +634,15 @@ def pricti_body(slovnik, resitel, body): | ||||||
| 	 | 	 | ||||||
| 	slovnik[resitel.id] += body | 	slovnik[resitel.id] += body | ||||||
| 
 | 
 | ||||||
| def secti_body_za_rocnik(rocnik, aktivni_resitele): | def secti_body_za_rocnik(za, aktivni_resitele): | ||||||
| 	""" Spočítá body za ročník, setřídí je sestupně a vrátí jako seznam.""" | 	""" Spočítá body za ročník (celý nebo do daného čísla),  | ||||||
|  | 		setřídí je sestupně a vrátí jako seznam. | ||||||
|  | 	Parametry: | ||||||
|  | 		za (typu Rocnik nebo Cislo)	spočítá za ročník, nebo za ročník až do  | ||||||
|  | 						daného čísla | ||||||
|  | 	""" | ||||||
| 	# spočítáme všem řešitelům jejich body za ročník (False => ne odjakživa) | 	# spočítáme všem řešitelům jejich body za ročník (False => ne odjakživa) | ||||||
| 	resitel_rocnikbody_slov = body_resitelu(aktivni_resitele, rocnik, False) | 	resitel_rocnikbody_slov = body_resitelu(aktivni_resitele, za, False) | ||||||
| 	# zeptáme se na dvojice (řešitel, body) za ročník a setřídíme sestupně | 	# zeptáme se na dvojice (řešitel, body) za ročník a setřídíme sestupně | ||||||
| 	resitel_rocnikbody_sezn = sorted(resitel_rocnikbody_slov.items(), | 	resitel_rocnikbody_sezn = sorted(resitel_rocnikbody_slov.items(), | ||||||
| 					key = lambda x: x[1], reverse = True) | 					key = lambda x: x[1], reverse = True) | ||||||
|  | @ -685,6 +688,9 @@ def secti_body_za_cislo(cislo, aktivni_resitele, hlavni_problemy=None): | ||||||
| 			 | 			 | ||||||
| 				# a mít více řešitelů | 				# a mít více řešitelů | ||||||
| 				for resitel in list(reseni.resitele.all()): | 				for resitel in list(reseni.resitele.all()): | ||||||
|  | 					if resitel not in aktivni_resitele: | ||||||
|  | 						print("Skipping {}".format(resitel.id)) | ||||||
|  | 						continue | ||||||
| 					pricti_body(cislobody, resitel, body) | 					pricti_body(cislobody, resitel, body) | ||||||
| 					pricti_body(nadproblem_slovnik, resitel, body) | 					pricti_body(nadproblem_slovnik, resitel, body) | ||||||
| 	return hlavni_problemy_slovnik, cislobody | 	return hlavni_problemy_slovnik, cislobody | ||||||
|  | @ -697,16 +703,13 @@ 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(Resitel.objects.filter( | 	aktivni_resitele = list(aktivniResitele(cislo.rocnik.rocnik, cislo.poradi)) | ||||||
| 			rok_maturity__gte=cislo.rocnik.druhy_rok())) |  | ||||||
| 			# TODO: zkusit hodnoceni__rocnik... |  | ||||||
| 			#.filter(hodnoceni_set__rocnik__eq=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) | ||||||
| 
 | 
 | ||||||
| 	# získáme body za ročník, seznam obsahuje dvojice (řešitel_id, body) setřízené sestupně | 	# získáme body za ročník, seznam obsahuje dvojice (řešitel_id, body) setřízené sestupně | ||||||
| 	resitel_rocnikbody_sezn = secti_body_za_rocnik(cislo.rocnik, aktivni_resitele) | 	resitel_rocnikbody_sezn = secti_body_za_rocnik(cislo, aktivni_resitele) | ||||||
| 
 | 
 | ||||||
| 	# získáme body odjakživa | 	# získáme body odjakživa | ||||||
| 	resitel_odjakzivabody_slov = body_resitelu(aktivni_resitele, cislo) | 	resitel_odjakzivabody_slov = body_resitelu(aktivni_resitele, cislo) | ||||||
|  | @ -808,58 +811,73 @@ class RocnikVysledkovkaView(RocnikView): | ||||||
| 	#vypise na stranku textovy obsah vyTeXane vysledkovky k okopirovani | 	#vypise na stranku textovy obsah vyTeXane vysledkovky k okopirovani | ||||||
| 
 | 
 | ||||||
| ### Generovani obalek | ### Generovani obalek | ||||||
|  | def resi_v_rocniku(rocnik, cislo=None): | ||||||
|  | 	""" Vrátí seznam řešitelů, co vyřešili nějaký problém v daném ročníku, do daného čísla. | ||||||
|  | 	Parametry: | ||||||
|  | 		rocnik (typu Rocnik)	ročník, ze kterého chci řešitele, co něco odevzdali | ||||||
|  | 		cislo (typu Cislo)	číslo, do kterého včetně se počítá, že v daném  | ||||||
|  | 					ročníku řešitel něco poslal. | ||||||
|  | 					Pokud není zadané, počítají se všechna řešení z daného ročníku. | ||||||
|  | 	Výstup: | ||||||
|  | 		QuerySet objektů typu Resitel """ | ||||||
| 
 | 
 | ||||||
| class CisloObalkyStruct: | 	if cislo is None: | ||||||
| 	rocnik = None | 		# filtrujeme pouze podle ročníku | ||||||
| 	cisla = None | 		letosni_reseni = Reseni.objects.filter(hodnoceni__cislo_body__rocnik = rocnik) | ||||||
|  | 	else: # filtrujeme podle ročníku i čísla | ||||||
|  | 		letosni_reseni = Reseni.objects.filter(hodnoceni__cislo_body__rocnik = rocnik, | ||||||
|  | 					hodnoceni__cislo_body__poradi__lte=cislo.poradi) | ||||||
| 
 | 
 | ||||||
|  | 	# vygenerujeme queryset řešitelů, co letos něco poslali | ||||||
|  | 	letosni_resitele = Resitel.objects.none() | ||||||
|  | 	for reseni in letosni_reseni: | ||||||
|  | 		letosni_resitele = letosni_resitele | reseni.resitele.filter(rok_maturity__gte=rocnik.druhy_rok()) | ||||||
|  | 	return letosni_resitele.distinct() | ||||||
|  | 	 | ||||||
|  | 		 | ||||||
|  | def aktivniResitele(rocnik, cislo): | ||||||
|  | 	""" Vrací QuerySet aktivních řešitelů, což jsou ti, co ještě neodmaturovali | ||||||
|  | 	a letos něco poslali (anebo loni něco poslali, pokud jde o první tři čísla). | ||||||
|  | 	Parametry: | ||||||
|  | 		rocnik (typu int)	číslo ročníku, o který se jedná | ||||||
|  | 		cislo (typu int)	pořadí čísla, o které se jedná | ||||||
| 
 | 
 | ||||||
| # Vraci QuerySet aktualnich resitelu = nekdy neco poslali, ale jeste neodmaturovali | 	""" | ||||||
| def aktualniResitele(rocnik): |  | ||||||
| 	letos = Rocnik.objects.get(rocnik = rocnik) | 	letos = Rocnik.objects.get(rocnik = rocnik) | ||||||
| 	return Resitel.objects.filter(rok_maturity__gt = letos.prvni_rok) | 	#TODO: co se stane, když zadané kombinace neexistují? ošetřit | ||||||
| #	# ALERT: pokud nekdo nema vypleny rok maturity, tak neni aktualni, protoze Karel Tesar a jini | 	aktualni_cislo = Cislo.objects.get(rocnik = rocnik, poradi = cislo) | ||||||
| #	return Resitel.objects.filter(Q(rok_maturity__gt = letos.prvni_rok)|Q(rok_maturity = None)) | 	loni = Rocnik.objects.get(rocnik = rocnik - 1) | ||||||
| 
 | 
 | ||||||
| # Vraci QuerySet aktivnich resitelu = |         # detekujeme, zda jde o první tři čísla či nikoli | ||||||
| # jeste neodmaturovali && | 	zacatek_rocniku = True | ||||||
| # (pokud je aktualni cislo mensi nez 3, pak (letos || loni) neco poslali | 	try: | ||||||
| # jinak letos neco poslali) | 		if int(aktualni_cislo.poradi) > 3: | ||||||
| def aktivniResitele(rocnik,cislo): | 			zacatek_rocniku = False | ||||||
| 	letos = CisloObalkyStruct() | 	except ValueError: | ||||||
| 	loni = CisloObalkyStruct() |        		# pravděpodobně se jedná o číslo 7-8 | ||||||
|  | 		zacatek_rocniku = False | ||||||
| 
 | 
 | ||||||
| 	aktualni_resitele = aktualniResitele(rocnik) | 	if not zacatek_rocniku: | ||||||
| 
 | 		return resi_v_rocniku(letos)	 | ||||||
| 	letos.rocnik = Rocnik.objects.get(rocnik = rocnik) |  | ||||||
| 	loni.rocnik = Rocnik.objects.get(rocnik = int(rocnik)-1) |  | ||||||
| 	letos.cisla = Cislo.objects.filter(rocnik=letos.rocnik, cislo__lte = cislo) |  | ||||||
| 	loni.cisla = Cislo.objects.filter(rocnik=loni.rocnik) |  | ||||||
| 	if int(cislo) > 3: |  | ||||||
| 		problemy = Problem.objects.filter(cislo_zadani__in = letos.cisla) |  | ||||||
| 	else: | 	else: | ||||||
| 		problemy = Problem.objects.filter( | 		# spojíme querysety s řešiteli loni a letos do daného čísla | ||||||
| 			Q(cislo_zadani__in = letos.cisla) | Q(cislo_zadani__in = loni.cisla) ) | 		return (resi_v_rocniku(loni) | resi_v_rocniku(letos, aktualni_cislo)).distinct() | ||||||
| 	resitele = aktualni_resitele.filter(reseni__in = Reseni.objects.filter( | 
 | ||||||
| 		problem__in=problemy)).distinct() | def cisloObalkyView(request, rocnik, cislo): | ||||||
| 	return resitele | 	return obalkyView(request, aktivniResitele(rocnik, cislo)) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def cisloObalkyView(request,rocnik,cislo): | def obalkyView(request, resitele): | ||||||
| 	return obalkyView(request,aktivniResitele(rocnik,cislo)) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def obalkyView(request,resitele): |  | ||||||
| 	tex = render(request,'seminar/archiv/obalky.tex', {'resitele': resitele}).content | 	tex = render(request,'seminar/archiv/obalky.tex', {'resitele': resitele}).content | ||||||
| 
 | 
 | ||||||
| 	tempdir = tempfile.mkdtemp() | 	tempdir = tempfile.mkdtemp() | ||||||
| 	with open(tempdir+"/obalky.tex","w") as texfile: | 	with open(tempdir+"/obalky.tex","w") as texfile: | ||||||
| 		texfile.write(tex) | 		texfile.write(tex.decode()) | ||||||
| 	shutil.copy(os.path.join(settings.STATIC_ROOT, 'seminar/lisak.pdf'),tempdir) | 	shutil.copy(os.path.join(settings.STATIC_ROOT, 'seminar/lisak.pdf'), tempdir) | ||||||
| 	subprocess.call(["pdflatex","obalky.tex"],cwd = tempdir) | 	subprocess.call(["pdflatex","obalky.tex"], cwd = tempdir) | ||||||
| 
 | 
 | ||||||
| 	with open(tempdir+"/obalky.pdf","rb") as pdffile: | 	with open(tempdir+"/obalky.pdf","rb") as pdffile: | ||||||
| 		response = HttpResponse(pdffile.read(),content_type='application/pdf') | 		response = HttpResponse(pdffile.read(), content_type='application/pdf') | ||||||
| 	shutil.rmtree(tempdir) | 	shutil.rmtree(tempdir) | ||||||
| 	return response | 	return response | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Kateřina Čížková
						Kateřina Čížková