Merge branch 'data_migrations' into treelib_tests
|  | @ -39,8 +39,8 @@ def obrazek_filename(self, filename): | |||
| 	# soustředění je v cestě jen pokud galerie pod nějaké patří | ||||
| 	cesta = ( | ||||
| 		['Galerie'] + | ||||
| 		(["soustredeni_" + gal.soustredeni.pk] if gal.soustredeni else []) + | ||||
| 		["galerie_" + cislo_gal, self.nazev] | ||||
| 		(["soustredeni_{}".format(gal.soustredeni.pk)] if gal.soustredeni else []) + | ||||
| 		["galerie_{}".format(cislo_gal), self.nazev] | ||||
| 	) | ||||
| 
 | ||||
| 	return os.path.join(*cesta) | ||||
|  |  | |||
| Before Width: | Height: | Size: 15 KiB | 
							
								
								
									
										35
									
								
								galerie/static/galerie/prvky/dalsi.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,35 @@ | |||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    width="25.135418mm" | ||||
|    height="42.333332mm" | ||||
|    viewBox="0 0 25.135418 42.333331" | ||||
|    version="1.1" | ||||
|    id="svg851"> | ||||
|   <defs | ||||
|      id="defs845" /> | ||||
|   <metadata | ||||
|      id="metadata848"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title></dc:title> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      id="layer1" | ||||
|      transform="matrix(-1.0282842,0,0,1,111.4545,-88.415317)"> | ||||
|     <path | ||||
|        d="m 108.38881,88.415317 -6.43264,21.166663 6.43264,21.16667 -18.011397,-21.16667 z" | ||||
|        style="fill:#e84e10;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.23177969" | ||||
|        id="path44-3" /> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 1 KiB | 
| Before Width: | Height: | Size: 18 KiB | 
| Before Width: | Height: | Size: 15 KiB | 
							
								
								
									
										35
									
								
								galerie/static/galerie/prvky/predchozi.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,35 @@ | |||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    width="25.135418mm" | ||||
|    height="42.333332mm" | ||||
|    viewBox="0 0 25.135418 42.333331" | ||||
|    version="1.1" | ||||
|    id="svg851"> | ||||
|   <defs | ||||
|      id="defs845" /> | ||||
|   <metadata | ||||
|      id="metadata848"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title></dc:title> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      id="layer1" | ||||
|      transform="matrix(-1.0282842,0,0,1,111.4545,-88.415317)"> | ||||
|     <path | ||||
|        d="m 83.944774,88.415319 6.43264,21.166661 -6.43264,21.16667 18.011396,-21.16667 z" | ||||
|        style="fill:#e84e10;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.23177969" | ||||
|        id="path44-3" /> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 1 KiB | 
|  | @ -242,6 +242,10 @@ nav.nav-button { | |||
| 	display: none; | ||||
| } | ||||
| 
 | ||||
| div.dropdown-backdrop { /* tohle způsobuje, že funguje mobilní menu */ | ||||
|     z-index: -1; | ||||
| } | ||||
| 
 | ||||
| h1 a:hover { | ||||
| 	text-decoration: none; | ||||
| } | ||||
|  | @ -387,11 +391,16 @@ p.license-mobile { | |||
|   } | ||||
| 
 | ||||
|   div.graf{ | ||||
| 		width: 70%; | ||||
|     float: none; | ||||
|     margin-left: auto; | ||||
|     margin-right: auto; | ||||
|     width: 70%; | ||||
| 		margin-top: 10px; | ||||
|   } | ||||
| 	#svg-graf{ | ||||
| 		width: 100%; | ||||
| 		height: auto;; | ||||
| 	} | ||||
| 
 | ||||
| ul.menu { | ||||
| 	font-size: 90%; | ||||
|  | @ -575,12 +584,9 @@ ul.submenu { | |||
|     float: none; | ||||
|   } | ||||
| 
 | ||||
|   div.graf{ | ||||
|     float: none; | ||||
|     width: 70%; | ||||
|     margin-left: auto; | ||||
|     margin-right: auto; | ||||
|   } | ||||
| 	div.graf { | ||||
| 		width: 100%; | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
|  | @ -706,19 +712,6 @@ div.cislo_odkazy ul { | |||
| 		padding: 0px; | ||||
| } | ||||
| 
 | ||||
| /* archiv ročník | ||||
| div.cisla-v-rocniku { | ||||
| 		font-weight: bold; | ||||
| 		color:  #6f2509; | ||||
| } | ||||
| 
 | ||||
| div.cislo-v-rocniku-blok { | ||||
| 	display: inline-block; | ||||
| 	width: 150px; | ||||
| 	height: 220px; | ||||
| 		text-align: center; | ||||
| }*/ | ||||
| 
 | ||||
| 
 | ||||
| /* galerie */ | ||||
| 
 | ||||
|  | @ -739,7 +732,8 @@ div.cislo-v-rocniku-blok { | |||
|   top: 0; | ||||
| } | ||||
| .predchozi_obrazek:hover{ | ||||
|   background-image: url("/static/galerie/prvky/predchozi.png"); | ||||
|   background-image: url("/static/galerie/prvky/predchozi.svg"); | ||||
| 	filter: drop-shadow(0px 5px 5px rgba(0, 0, 0, 0.4)); | ||||
|   background-position: left center; | ||||
|   background-repeat: no-repeat; | ||||
| } | ||||
|  | @ -752,7 +746,8 @@ div.cislo-v-rocniku-blok { | |||
|   top: 0; | ||||
| } | ||||
| .dalsi_obrazek:hover{ | ||||
|   background-image: url("/static/galerie/prvky/dalsi.png"); | ||||
|   background-image: url("/static/galerie/prvky/dalsi.svg"); | ||||
| 	filter: drop-shadow(0px 5px 5px rgba(0, 0, 0, 0.4)); | ||||
|   background-position: right center; | ||||
|   background-repeat: no-repeat; | ||||
| } | ||||
|  | @ -782,31 +777,25 @@ div.cislo-v-rocniku-blok { | |||
| 
 | ||||
| /* titulní obrázek hlavní galerie soustředění */ | ||||
| .titulni_obrazek { | ||||
|     border: 1px solid black; | ||||
| } | ||||
| 
 | ||||
| .galerie_nahledy{ | ||||
|   /*margin: 1em 0;*/ | ||||
|   margin: 0 auto 30px auto; | ||||
|   margin: auto; | ||||
| 	padding: 10px; | ||||
|   text-align: center; | ||||
|   overflow: auto; | ||||
| } | ||||
| 
 | ||||
| .galerie_nahledy div.navigace { | ||||
|     display: inline-block; | ||||
|     width: 150px; | ||||
| .galerie_nahledy img { | ||||
|   margin: 10px; | ||||
| } | ||||
| 
 | ||||
| /*.galerie_nahledy img{*/ | ||||
| /*margin: 0 10px 0 10px;*/ | ||||
| /*}*/ | ||||
| .galerie_nahledy div.navigace { | ||||
|     display: inline-block; | ||||
| } | ||||
| 
 | ||||
| /*.galerie_nahledy a{*/ | ||||
| /*height: 100%;*/ | ||||
| /*width: 100%;*/ | ||||
| /*}*/ | ||||
| 
 | ||||
| .galerie_nahled { /* frame */ | ||||
| .galerie_nahled, .podgalerie_nahled { /* frame */ | ||||
|   display: block; | ||||
|   position: relative; | ||||
|   float: left; | ||||
|  | @ -814,19 +803,19 @@ div.cislo-v-rocniku-blok { | |||
|   height: 200px; | ||||
|   text-align: center; | ||||
|   border: solid; | ||||
|   border-width: 2px; | ||||
|   border-radius: 5px; | ||||
|   /*border-color: #ffa500;*/ | ||||
|   border-color: #ffd546; | ||||
|   /*background-color: #ffb52d;*/ | ||||
|   background-color: white; | ||||
|   border-width: 1px; | ||||
|   border-radius: 4px; | ||||
|   border-color: #f9d59e; | ||||
|   background-color: #fffbf6; | ||||
|   white-space: nowrap; | ||||
|   margin: 10px 20px 10px 0px; | ||||
|   margin: 10px; | ||||
| 	font-weight: bold; | ||||
| } | ||||
| 
 | ||||
| .galerie_nahled:hover { | ||||
|     background-color: #ffd546; | ||||
|     border-color: #ffa500; | ||||
| .galerie_nahled:hover, .podgalerie_nahled:hover { | ||||
|    background-color: #f9d59e; | ||||
| 	 filter: drop-shadow(0px 5px 5px rgba(0, 0, 0, 0.4)); | ||||
| 	 color: #6f2509; | ||||
| } | ||||
| 
 | ||||
| .vystredeno{ /* helper */ | ||||
|  | @ -839,12 +828,6 @@ div.cislo-v-rocniku-blok { | |||
|   vertical-align: middle; | ||||
|   max-height: 180px; | ||||
|   max-width: 180px; | ||||
|   /*border: 1px solid white;*/ | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| .galerie_nahled img, .podgalerie_nahled img { | ||||
|     border-radius: 2px; | ||||
| } | ||||
| 
 | ||||
| .galerie_nahled div { | ||||
|  | @ -854,30 +837,6 @@ div.cislo-v-rocniku-blok { | |||
|     text-align: center; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| .podgalerie_nahled { | ||||
|   display: block; | ||||
|   position: relative; | ||||
|   float: left; | ||||
|   width: 200px; | ||||
|   height: 200px; | ||||
|   text-align: center; | ||||
|   border: solid; | ||||
|   border-width: 2px; | ||||
|   border-radius: 5px; | ||||
|   border-color: #ffa500; | ||||
|   /*border-color: #ffd546;*/ | ||||
|   background-color: #ffd546; | ||||
|   /*background-color: white;*/ | ||||
|   white-space: nowrap; | ||||
|   margin: 10px 20px 10px 0px; | ||||
|   font-weight: bold; | ||||
| } | ||||
| 
 | ||||
| .podgalerie_nahled:hover { | ||||
|     background-color: #ffa500; | ||||
| } | ||||
| 
 | ||||
| .podgalerie_nahled img { | ||||
|     margin-top: 20px; | ||||
|     margin-bottom: 15px; | ||||
|  | @ -893,10 +852,10 @@ div.cislo-v-rocniku-blok { | |||
| 
 | ||||
| /* plus a minus tlacitka */ | ||||
| .mam-org-only-galerie { | ||||
|   background: #fff0d7; | ||||
|   background: #eee4ec; | ||||
|   padding: 10px; | ||||
|   margin: 10px 10px 10px -20px; | ||||
|   border: orange 2px dashed; | ||||
|   border: #333 2px dashed; | ||||
|   float: left; | ||||
| } | ||||
| 
 | ||||
|  | @ -904,8 +863,8 @@ div.cislo-v-rocniku-blok { | |||
|   padding: 3px 5px; | ||||
|   margin: 5px; | ||||
|   border-radius: 20px; | ||||
|   background-color: lightblue; | ||||
|   color: black; | ||||
|   background-color: #6f2509;; | ||||
|   color: #fffbf6; | ||||
|   float: left; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -10,7 +10,7 @@ | |||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    version="1.1" | ||||
|    id="svg2" | ||||
|    id="svg-graf" | ||||
|    width="482.57019" | ||||
|    height="599.45636" | ||||
|    viewBox="0 0 482.57019 599.45636" | ||||
|  |  | |||
| Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB | 
|  | @ -173,13 +173,12 @@ def gen_organizatori(rnd, osoby, last_rocnik, users): | |||
| 			if do.year > datetime.datetime.now().year: | ||||
| 				do = None | ||||
| 			organizatori.append(Organizator.objects.create(osoba=os, | ||||
| 					organizuje_od=od, organizuje_do=do, strucny_popis_organizatora = popis_orga)) | ||||
| 				organizuje_od=od, organizuje_do=do, strucny_popis_organizatora = popis_orga)) | ||||
| 	return organizatori | ||||
| 
 | ||||
| def gen_ulohy_do_cisla(rnd, organizatori, resitele, rocnik_cisla, rocniky, size): | ||||
| 	logger.info('Generuji úlohy do čísla (size={})...'.format(size)) | ||||
| 
 | ||||
| 	# ulohy resene v cisle | ||||
| def gen_zadani_ulohy(rnd, cisla, organizatori, pocet_oboru, poradi_cisla, poradi_problemu): | ||||
| 	 | ||||
| 	# Proměnné pro náhodné generování názvů a zadání. | ||||
| 	jaka = ["Šachová", "Černá", "Větrná", "Dlouhá", "Křehká", "Rychlá", | ||||
| 		"Zákeřná", "Fyzikální"] | ||||
| 	co = ["kostka", "smršť", "díra", "zrada", "toulka", "tyč", | ||||
|  | @ -189,7 +188,47 @@ def gen_ulohy_do_cisla(rnd, organizatori, resitele, rocnik_cisla, rocniky, size) | |||
| 	ceho = ["všech", "správných", "konstatních", "zelených"] | ||||
| 	jmeno = ["řešení", "tahů", "čísel", "kalhot", "koulí", "hadů"] | ||||
| 	kde = ["na zemi", "ve vesmíru", "ve vzduchu", "na šňůře", "v letadle"] | ||||
| 	obor = ["M", "F", "I", "O", "B"] | ||||
| 	obory = ["M", "F", "I", "O", "B"] | ||||
| 	 | ||||
| 	p = Uloha.objects.create( | ||||
| 		# atributy třídy Problem | ||||
| 		nazev=" ".join([rnd.choice(jaka), rnd.choice(co)]), | ||||
| 		stav=Problem.STAV_ZADANY, | ||||
| 		zamereni=rnd.sample(obory, pocet_oboru), | ||||
| 		autor=rnd.choice(organizatori), | ||||
| 		garant=rnd.choice(organizatori), | ||||
| 		kod=str(poradi_problemu), | ||||
| 		# atributy třídy Uloha | ||||
| 		cislo_zadani=cisla[poradi_cisla-2-1], | ||||
| 		cislo_reseni=cisla[poradi_cisla-1], | ||||
| 		cislo_deadline=cisla[poradi_cisla-1], | ||||
| 		max_body = rnd.randint(1, 8) | ||||
| 	) | ||||
| 
 | ||||
| 	text_zadani = Text.objects.create( | ||||
| 		na_web = " ".join( | ||||
| 		[rnd.choice(sloveso), | ||||
| 		rnd.choice(koho), | ||||
| 		rnd.choice(ceho), | ||||
| 		rnd.choice(jmeno), | ||||
| 		rnd.choice(kde)] | ||||
| 		), | ||||
| 		do_cisla = " ".join( | ||||
| 		[rnd.choice(sloveso), | ||||
| 		rnd.choice(koho), | ||||
| 		rnd.choice(ceho), | ||||
| 		rnd.choice(jmeno), | ||||
| 		rnd.choice(kde)] | ||||
| 		) | ||||
| 	) | ||||
| 	zad = TextNode.objects.create(text = text_zadani) | ||||
| 	uloha_zadani = UlohaZadaniNode.objects.create(uloha = p, first_child = zad) | ||||
| 	p.ulohazadaninode = uloha_zadani | ||||
| 	otec_syn(cisla[poradi_cisla-2-1].cislonode, uloha_zadani) | ||||
| 
 | ||||
| 	return p | ||||
| 
 | ||||
| def gen_vzoroveho_reseni_ulohy(rnd, cisla, organizatori, uloha, pocet_opravovatelu, poradi_cisla): | ||||
| 	reseni = ["to je přece jasné", "triviální", "omlouváme se," | ||||
| 		"otevřený problém", "neřešitelné", "triviálně triviální", | ||||
| 		"použitím věty z prvního semestru na matfyzu", | ||||
|  | @ -197,96 +236,81 @@ def gen_ulohy_do_cisla(rnd, organizatori, resitele, rocnik_cisla, rocniky, size) | |||
| 		"netriviální aplikace diferenciálních rovnic", "zadání je vnitřně" | ||||
| 		"sporné", "nepopsatelně jednoduché", "pokud jste na to nepřišli," | ||||
| 		"tak jste fakt hloupí"] | ||||
| 
 | ||||
| 	# Generování vzorového řešení. | ||||
| 	text_vzoraku = Text.objects.create( | ||||
| 		na_web = rnd.choice(reseni), | ||||
| 		do_cisla = rnd.choice(reseni) | ||||
| 	) | ||||
| 	vzorak = TextNode.objects.create(text = text_vzoraku) | ||||
| 	uloha_vzorak = UlohaVzorakNode.objects.create(uloha = uloha, first_child = vzorak) | ||||
| 	uloha.ulohavzoraknode = uloha_vzorak | ||||
| 	otec_syn(cisla[poradi_cisla-1].cislonode, uloha_vzorak) | ||||
| 
 | ||||
| 	uloha.opravovatele.set(rnd.sample(organizatori, pocet_opravovatelu)) | ||||
| 	uloha.save() | ||||
| 	return | ||||
| 
 | ||||
| def gen_reseni_ulohy(rnd, cisla, uloha, pocet_resitelu, poradi_cisla, resitele_cisla, resitele): | ||||
| 	 | ||||
| 	pocet_reseni = rnd.randint(pocet_resitelu//4, pocet_resitelu * 4) | ||||
| 	# generujeme náhodný počet řešení vzhledem k počtu řešitelů čísla | ||||
| 	for _ in range(pocet_reseni): | ||||
| 		#print("Generuji {}-té řešení".format(reseni)) | ||||
| 		if rnd.randint(1, 10) == 1: | ||||
| 		# cca desetina řešení od více řešitelů | ||||
| 			res_vyber = rnd.sample(resitele_cisla,  | ||||
| 				rnd.randint(2, 5)) | ||||
| 		else: | ||||
| 			res_vyber = rnd.sample(resitele_cisla, 1) | ||||
| 		if resitele[0] in res_vyber: # speciální řešitel, který nemá žádné body | ||||
| 			res_vyber.remove(resitele[0]) | ||||
| 
 | ||||
| 		# Vytvoření řešení. | ||||
| 		res = Reseni.objects.create(forma=rnd.choice(Reseni.FORMA_CHOICES)[0]) | ||||
| 		# Problím a řešitele přiřadíme později, ManyToManyField | ||||
| 		# se nedá vyplnit v create(). | ||||
| 		res.resitele.set(res_vyber) | ||||
| 		res.save() | ||||
| 		 | ||||
| 		# Vytvoření hodnocení. | ||||
| 		hod = Hodnoceni.objects.create( | ||||
| 			body=rnd.randint(0, uloha.max_body), | ||||
| 			cislo_body=cisla[poradi_cisla - 1], | ||||
| 			reseni=res, | ||||
| 			problem=uloha | ||||
| 		) | ||||
| 	return | ||||
| 
 | ||||
| def gen_ulohy_do_cisla(rnd, organizatori, resitele, rocnik_cisla, rocniky, size): | ||||
| 	logger.info('Generuji úlohy do čísla (size={})...'.format(size)) | ||||
| 
 | ||||
| 	k = 0 | ||||
| 	for rocnik in rocniky: | ||||
| 		k+=1 | ||||
| 		k += 1 | ||||
| 		print("Generuji {}. číslo.".format(k)) | ||||
| 		cisla = rocnik_cisla[k-1] | ||||
| 		for ci in range(3, len(cisla)+1): # pro všechna čísla | ||||
| 		cisla = rocnik_cisla[k - 1] | ||||
| 		for ci in range(3, len(cisla) + 1): # pro všechna čísla | ||||
| 			resitele_size = round(7/8 * 30 * size) # očekáváný celkový počet řešitelů | ||||
| 			poc_res = rnd.randint(round(resitele_size/8), round(resitele_size/4)) | ||||
| 			poc_res = rnd.randint(resitele_size//8, resitele_size//4) | ||||
|  			# dané číslo řeší něco mezi osminou a čtvrtinou všech řešitelů | ||||
| 			# (náhodná hausnumera, možno změnit) | ||||
| 			# účelem je, aby se řešení generovala z menší množiny řešitelů a tedy | ||||
| 			# bylo více řešení od jednoho řešitele daného čísla | ||||
| 			resitele_cisla = rnd.sample(resitele, poc_res) | ||||
| 			for pi in range(1, ((size + 1) // 2) + 1): | ||||
| 			for pi in range(1, ((size + 1) // 2) + 1): # počet problémů | ||||
| 
 | ||||
| 				poc_op = rnd.randint(1, 4) # počet opravovatelů | ||||
| 				poc_oboru = rnd.randint(1, 2) | ||||
| 				p = Uloha.objects.create( | ||||
| 					# atributy třídy Problem | ||||
| 					nazev=" ".join([rnd.choice(jaka), rnd.choice(co)]), | ||||
| 					stav=Problem.STAV_ZADANY, | ||||
| 					zamereni=rnd.sample(["M", "F", "I", "O", "B"], poc_oboru), | ||||
| 					autor=rnd.choice(organizatori), | ||||
| 					garant=rnd.choice(organizatori), | ||||
| 					kod=str(pi), | ||||
| 					# atributy třídy Uloha | ||||
| 					cislo_zadani=cisla[ci-2-1], | ||||
| 					cislo_reseni=cisla[ci-1], | ||||
| 					cislo_deadline=cisla[ci-1], | ||||
| 					max_body = rnd.randint(1, 8) | ||||
| 				) | ||||
| 
 | ||||
| 				text_zadani = Text.objects.create( | ||||
| 					na_web = " ".join( | ||||
| 					[rnd.choice(sloveso), | ||||
| 					rnd.choice(koho), | ||||
| 					rnd.choice(ceho), | ||||
| 					rnd.choice(jmeno), | ||||
| 					rnd.choice(kde)] | ||||
| 					), | ||||
| 					do_cisla = " ".join( | ||||
| 					[rnd.choice(sloveso), | ||||
| 					rnd.choice(koho), | ||||
| 					rnd.choice(ceho), | ||||
| 					rnd.choice(jmeno), | ||||
| 					rnd.choice(kde)] | ||||
| 					) | ||||
| 				) | ||||
| 				zad = TextNode.objects.create(text = text_zadani) | ||||
| 				uloha_zadani = UlohaZadaniNode.objects.create(uloha=p, first_child = zad) | ||||
| 				p.ulohazadaninode = uloha_zadani | ||||
| 				otec_syn(cisla[ci-2-1].cislonode, uloha_zadani) | ||||
| 
 | ||||
| 				# generování vzorového textu | ||||
| 				text_vzoraku = Text.objects.create( | ||||
| 					na_web = rnd.choice(reseni), | ||||
| 					do_cisla = rnd.choice(reseni) | ||||
| 				) | ||||
| 				vzorak = TextNode.objects.create(text = text_vzoraku) | ||||
| 				uloha_vzorak = UlohaVzorakNode.objects.create(uloha=p, first_child = vzorak) | ||||
| 				p.ulohavzoraknode = uloha_vzorak | ||||
| 				otec_syn(cisla[ci-1].cislonode, uloha_vzorak) | ||||
| 
 | ||||
| 				p.opravovatele.set(rnd.sample(organizatori,poc_op)) | ||||
| 				p.save() | ||||
| 
 | ||||
| 				# generování řešení | ||||
| 				poc_reseni = rnd.randint(poc_res, poc_res * 4) | ||||
| 				# generujeme náhodný počet řešení vzhledem k počtu řešitelů čísla | ||||
| 				for ri in range(poc_reseni): | ||||
| 					#print("Generuji {}-té řešení".format(ri)) | ||||
| 					if rnd.randint(1, 10) == 6: | ||||
| 					# cca desetina řešení od více řešitelů | ||||
| 						res_vyber = rnd.sample(resitele_cisla,  | ||||
| 							rnd.randint(2, 5)) | ||||
| 					else: | ||||
| 						res_vyber = rnd.sample(resitele_cisla, 1) | ||||
| 					if resitele[0] in res_vyber: | ||||
| 						res_vyber.remove(resitele[0]) | ||||
| 					res = Reseni.objects.create(forma=rnd.choice(Reseni.FORMA_CHOICES)[0]) | ||||
| 					# problem a resitele přiřadíme později, ManyToManyField | ||||
| 					# se nedá vyplnit v create() | ||||
| 					res.resitele.set(res_vyber) | ||||
| 					res.save() | ||||
| 					hod = Hodnoceni.objects.create( | ||||
| 						body=rnd.randint(0, p.max_body), | ||||
| 						cislo_body=cisla[ci-1], | ||||
| 						reseni=res, | ||||
| 						problem=p | ||||
| 					) | ||||
| 				 | ||||
| 				# Generování zadání úlohy a UlohaZadaniNode,  | ||||
| 				# přivěšení pod dané číslo | ||||
| 				p = gen_zadani_ulohy(rnd, cisla, organizatori, poc_oboru, ci, pi)	 | ||||
| 				# Generování vzorového řešení | ||||
| 				gen_vzoroveho_reseni_ulohy(rnd, cisla, organizatori, p, poc_op, ci)				 | ||||
| 				# Generování řešení a hodnocení k úloze | ||||
| 				gen_reseni_ulohy(rnd, cisla, p, poc_res, ci,  | ||||
| 					resitele_cisla, resitele)  | ||||
| 
 | ||||
| 	return | ||||
| 
 | ||||
|  | @ -482,8 +506,10 @@ def gen_ulohy_k_tematum(rnd, rocniky, rocnik_cisla, rocnik_temata, organizatori) | |||
| 					rocnik=rocnik, | ||||
| 					poradi=str(int(cislo.poradi) + 2), | ||||
| 					) | ||||
| 			# Pokud není číslo pro vzorák, tak se dá do posledního čísla (i kdyby tam mělo být zadání i řešení...) | ||||
| 			# Tohle sice umožňuje vygenerovat vzorák do čísla dávno po konci témátka, ale to nám pro jednoduchost nevadí. | ||||
| 			# Pokud není číslo pro vzorák, tak se dá do posledního čísla  | ||||
| 			# (i kdyby tam mělo být zadání i řešení...) | ||||
| 			# Tohle sice umožňuje vygenerovat vzorák do čísla dávno po konci témátka,  | ||||
| 			# ale to nám pro jednoduchost nevadí. | ||||
| 			if len(cislo_se_vzorakem) == 0: | ||||
| 				cislo_se_vzorakem = cisla[-1] | ||||
| 			else: | ||||
|  | @ -505,7 +531,8 @@ def gen_ulohy_k_tematum(rnd, rocniky, rocnik_cisla, rocnik_temata, organizatori) | |||
| 				tema = tema_node.tema | ||||
| 					 | ||||
| 				# Pokud už témátko skončilo, žádné úložky negenerujeme | ||||
| 				# FIXME: Bylo by hezčí, kdyby se čísla předávala jako Cislo a ne jako int v té trojici (start, konec, tema) | ||||
| 				# FIXME: Bylo by hezčí, kdyby se čísla předávala jako Cislo a ne  | ||||
| 				# jako int v té trojici (start, konec, tema) | ||||
| 				if not temata[int(tema.kod)-1][1] >= int(cislo_se_vzorakem.poradi): | ||||
| 					continue | ||||
| 					 | ||||
|  | @ -581,8 +608,10 @@ def gen_novinky(rnd, organizatori): | |||
| 	kdy = ["Zítra bude", "10. 10. 2020 bude", "V prosinci bude", "V létě bude"] | ||||
| 
 | ||||
| 	for i in range(5): | ||||
| 		text_novinky = " ".join([rnd.choice(kdy),rnd.choice(kde),rnd.choice(jake),rnd.choice(co)]) | ||||
| 		novinka = Novinky.objects.create(id=i,autor=rnd.choice(organizatori),text=(text_novinky+", těšíme se na vás!"),zverejneno=rnd.choice([True,False])) | ||||
| 		text_novinky = " ".join([rnd.choice(kdy), rnd.choice(kde), rnd.choice(jake), | ||||
| 			rnd.choice(co)]) | ||||
| 		novinka = Novinky.objects.create(id=i,autor=rnd.choice(organizatori), | ||||
| 			text=(text_novinky+", těšíme se na vás!"),zverejneno=rnd.choice([True,False])) | ||||
| 		novinka.save() | ||||
| 	return | ||||
| 
 | ||||
|  |  | |||
|  | @ -324,10 +324,16 @@ class ArchivView(generic.ListView): | |||
| 
 | ||||
| ### Výsledky | ||||
| 
 | ||||
| # ze seznamu obsahujícího sestupně setřízené body řešitelů za daný ročník  | ||||
| # vytvoří seznam s pořadími (včetně 3.-5. a pak 2 volná místa atp.), | ||||
| # podle toho, jak jdou za sebou ve výsledkovce | ||||
| def sloupec_s_poradim(setrizene_body): | ||||
| 	""" Ze seznamu obsahujícího sestupně setřízené body řešitelů za daný ročník  | ||||
| 	vytvoří seznam s pořadími (včetně 3.-5. a pak 2 volná místa atp.), | ||||
| 	podle toho, jak jdou za sebou ve výsledkovce. | ||||
| 	Parametr: | ||||
| 		setrizene_body (seznam integerů): sestupně setřízená čísla | ||||
| 
 | ||||
| 	Výstup: | ||||
| 		sloupec_s_poradim (seznam stringů) | ||||
| 	""" | ||||
| 
 | ||||
| 	# ze seznamu obsahujícího setřízené body spočítáme sloupec s pořadím	 | ||||
| 	aktualni_poradi = 1 | ||||
|  | @ -358,20 +364,28 @@ def sloupec_s_poradim(setrizene_body): | |||
| 		aktualni_poradi = aktualni_poradi + velikost_skupiny | ||||
| 	return sloupec_s_poradim | ||||
| 
 | ||||
| # vrátí všechna čísla daného ročníku   | ||||
| def cisla_rocniku(rocnik, jen_verejne=True): | ||||
| 	""" Vrátí všechna čísla daného ročníku. | ||||
| 	Parametry: | ||||
| 		rocnik (Rocnik): ročník semináře | ||||
| 		jen_verejne (bool): zda se mají vrátit jen veřejná, nebo všechna čísla | ||||
| 	Vrátí: | ||||
| 		seznam objektů typu Cislo | ||||
| 	"""	 | ||||
| 	if jen_verejne: | ||||
| 		return rocnik.verejna_cisla() | ||||
| 	else: | ||||
| 		return rocnik.cisla.all() | ||||
| 
 | ||||
| # pro daný problém vrátí jeho nejvyšší nadproblém | ||||
| def hlavni_problem(problem): | ||||
| 	""" Pro daný problém vrátí jeho nejvyšší nadproblém.""" | ||||
| 	while not(problem.nadproblem == None): | ||||
| 		problem = problem.nadproblem | ||||
| 	return problem | ||||
| 
 | ||||
| def hlavni_problemy_rocniku(rocnik, jen_verejne=True): | ||||
| 	""" Pro zadaný ročník vrátí hlavní problémy ročníku, | ||||
| 	tj. ty, které už nemají nadproblém.""" | ||||
| 	hlavni_problemy = [] | ||||
| 	for cislo in cisla_rocniku(rocnik, jen_verejne): | ||||
| 		for problem in hlavni_problemy_cisla(cislo): | ||||
|  | @ -382,8 +396,8 @@ def hlavni_problemy_rocniku(rocnik, jen_verejne=True): | |||
| 	 | ||||
| 	return hlavni_problemy | ||||
| 
 | ||||
| # vrátí list všech problémů s body v daném čísle, které již nemají nadproblém | ||||
| def hlavni_problemy_cisla(cislo): | ||||
| 	""" Vrátí seznam všech problémů s body v daném čísle, které již nemají nadproblém. """ | ||||
| 	hodnoceni = cislo.hodnoceni.select_related('problem', 'reseni').all()	 | ||||
| 	# hodnocení, která se vážou k danému číslu | ||||
| 	 | ||||
|  | @ -405,36 +419,71 @@ def hlavni_problemy_cisla(cislo): | |||
| 	 | ||||
| 	return hlavni_problemy | ||||
| 
 | ||||
| # vrátí slovník řešitel:body obsahující počty bodů zadaných řešitelů za daný ročník | ||||
| def body_resitelu_odjakziva(rocnik, resitele): | ||||
| 	# Následující řádek přidá ke každému řešiteli údaj ".body" se součtem jejich bodů | ||||
| 	resitele_s_body = Resitel.objects.annotate(body=Sum('reseni__hodnoceni__body')) | ||||
| 	# Teď jen z QuerySetu řešitelů anotovaných body vygenerujeme slovník indexovaný řešitelským id obsahující body | ||||
| 	# ... ale jen ro řešitele, které dostaneme jako parametr. | ||||
| 	# TODO: Zjistit, co ten parametr říká a proč je potřeba | ||||
| 	body_odjakziva = {int(res.id) : res.body for res in resitele_s_body if res in resitele} | ||||
| 	return body_odjakziva | ||||
| def body_resitelu(resitele, za, odjakziva=True): | ||||
| 	""" Funkce počítající počty bodů pro zadané řešitele,  | ||||
| 	buď odjakživa do daného ročníku/čísla anebo za daný ročník/číslo. | ||||
| 	Parametry: | ||||
| 		resitele (seznam obsahující položky typu Resitel): aktivní řešitelé | ||||
| 		za (Rocnik/Cislo): za co se mají počítat body  | ||||
| 			(generování starších výsledkovek) | ||||
| 		odjakziva (bool): zda se mají počítat body odjakživa, nebo jen za číslo/ročník | ||||
| 			zadané v "za" | ||||
| 	Výstup: | ||||
| 		slovník (Resitel.id):body | ||||
| 	"""		 | ||||
| 	resitele_id = [r.id for r in resitele] | ||||
| 	# Zjistíme, typ objektu v parametru "za" | ||||
| 	if isinstance(za, Rocnik): | ||||
| 		cislo = None | ||||
| 		rocnik = za | ||||
| 		rok = rocnik.prvni_rok | ||||
| 	elif isinstance(za, Cislo): | ||||
| 		cislo = za | ||||
| 		rocnik = None | ||||
| 		rok = cislo.rocnik.prvni_rok | ||||
| 	else: | ||||
| 		assert True, "body_resitelu: za není ani číslo ani ročník."	 | ||||
| 
 | ||||
| # vrátí slovník řešitel:body obsahující počty bodů zadaných řešitelů za daný ročník | ||||
| def body_resitelu_za_rocnik(rocnik, aktivni_resitele): | ||||
| 	body_za_rocnik = {} | ||||
| 	# inicializujeme na 0 pro všechny aktivní řešitele | ||||
| 	for ar in aktivni_resitele: | ||||
| 		body_za_rocnik[ar.id] = 0 | ||||
| 	 | ||||
| 	# spočítáme body řešitelům přes všechna řešení s hodnocením v daném ročníku | ||||
| 	print("Před dotazem:{}".format(time.time()))	 | ||||
| 	reseni = Reseni.objects.prefetch_related('resitele', 'hodnoceni_set').filter(hodnoceni__cislo_body__rocnik=rocnik) | ||||
| 	print("Po dotazu:{}".format(time.time()))	 | ||||
| 	for res in reseni: | ||||
| 		for resitel in res.resitele.all(): | ||||
| 			for hodn in res.hodnoceni_set.all(): | ||||
| 				pricti_body(body_za_rocnik, resitel, hodn.body) | ||||
| 	print("Po for-cyklu:{}".format(time.time()))	 | ||||
| 	return body_za_rocnik | ||||
| 
 | ||||
| 	# Kvůli rychlosti používáme sčítáme body už v databázi, viz  | ||||
| 	# https://docs.djangoproject.com/en/3.0/topics/db/aggregation/,  | ||||
| 	# sekce Filtering on annotations (protože potřebujeme filtrovat výsledky | ||||
| 	# jen do nějakého data, abychom uměli správně nagenerovat výsledkovky i  | ||||
| 	# za historická čísla. | ||||
| 
 | ||||
| 	# Níže se vytváří dotaz na součet bodů za správně vyfiltrovaná hodnocení,  | ||||
| 	# který se použije ve výsledném dotazu. | ||||
| 	if cislo and odjakziva: # Body se sčítají odjakživa do zadaného čísla. | ||||
| 		# Vyfiltrujeme všechna hodnocení, která jsou buď ze starších ročníků,  | ||||
| 		# anebo ze stejného ročníku, jak je zadané číslo, tam ale sčítáme jen | ||||
| 		# pro čísla s pořadím nejvýše stejným, jako má zadané číslo. | ||||
| 		body_k_zapocteni = Sum('reseni__hodnoceni__body',  | ||||
| 			filter=( Q(reseni__hodnoceni__cislo_body__rocnik__prvni_rok__lt=rok) | | ||||
| 				 Q(reseni__hodnoceni__cislo_body__rocnik__prvni_rok=rok, | ||||
| 				   reseni__hodnoceni__cislo_body__poradi__lte=cislo.poradi) )) | ||||
| 	elif cislo and not odjakziva: # Body se sčítají za dané číslo. | ||||
| 		body_k_zapocteni = Sum('reseni__hodnoceni__body', | ||||
| 			filter=( Q(reseni__hodnoceni__cislo_body=cislo) )) | ||||
| 	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',  | ||||
| 			filter= Q(reseni__hodnoceni__cislo_body__rocnik__prvni_rok__lte=rok)) | ||||
| 	elif rocnik and not odjakziva: # Spočítáme body za daný ročník. | ||||
| 		body_k_zapocteni = Sum('reseni__hodnoceni__body', | ||||
| 			filter= Q(reseni__hodnoceni__cislo_body__rocnik=rocnik)) | ||||
| 	else:  | ||||
| 		assert True, "body_resitelu: Neplatná kombinace za a odjakživa." | ||||
| 
 | ||||
| 	# Následující řádek přidá ke každému řešiteli údaj ".body" se součtem jejich bodů | ||||
| 	resitele_s_body = Resitel.objects.filter(id__in=resitele_id).annotate( | ||||
| 		body=body_k_zapocteni) | ||||
| 	# Teď jen z QuerySetu řešitelů anotovaných body vygenerujeme slovník  | ||||
| 	# indexovaný řešitelským id obsahující body.  | ||||
| 	# Pokud jsou body None, nahradíme za 0. | ||||
| 	slovnik = {int(res.id) : (res.body if res.body else 0) for res in resitele_s_body} | ||||
| 	return slovnik | ||||
| 
 | ||||
| class RadekVysledkovkyRocniku(object): | ||||
| 	"""Obsahuje věci, které se hodí vědět při konstruování výsledkovky. | ||||
| 	""" Obsahuje věci, které se hodí vědět při konstruování výsledkovky. | ||||
| 	Umožňuje snazší práci v templatu (lepší, než seznam).""" | ||||
| 
 | ||||
| 	def __init__(self, poradi, resitel, body_cisla_sezn, body_rocnik, body_odjakziva, rok): | ||||
|  | @ -447,7 +496,7 @@ class RadekVysledkovkyRocniku(object): | |||
| 		self.titul = resitel.get_titul(body_odjakziva) | ||||
| 
 | ||||
| def vysledkovka_rocniku(rocnik, jen_verejne=True): | ||||
| 	"""Přebírá ročník (např. context["rocnik"]) a vrací výsledkovou listinu ve | ||||
| 	""" Přebírá ročník (např. context["rocnik"]) a vrací výsledkovou listinu ve | ||||
| 	formě vhodné pro šablonu "seminar/vysledkovka_rocniku.html" | ||||
| 	""" | ||||
| 	 | ||||
|  | @ -460,7 +509,6 @@ def vysledkovka_rocniku(rocnik, jen_verejne=True): | |||
| 			#.filter(hodnoceni_set__rocnik__eq=cislo_rocnik) | ||||
| 	cisla = cisla_rocniku(rocnik, jen_verejne) | ||||
| 	body_cisla_slov = {} | ||||
| 	print("Jen veřejná: {}, čísla: {}".format(jen_verejne, cisla)) | ||||
| 	for cislo in cisla: | ||||
| 		# získáme body za číslo | ||||
| 		_, cislobody = secti_body_za_cislo(cislo, aktivni_resitele) | ||||
|  | @ -476,7 +524,7 @@ def vysledkovka_rocniku(rocnik, jen_verejne=True): | |||
| 	poradi = sloupec_s_poradim(setrizene_body) | ||||
| 
 | ||||
| 	# získáme body odjakživa | ||||
| 	resitel_odjakzivabody_slov = body_resitelu_odjakziva(rocnik, aktivni_resitele) | ||||
| 	resitel_odjakzivabody_slov = body_resitelu(aktivni_resitele, rocnik) | ||||
| 
 | ||||
| 	# vytvoříme jednotlivé sloupce výsledkovky | ||||
| 	radky_vysledkovky = [] | ||||
|  | @ -495,11 +543,7 @@ def vysledkovka_rocniku(rocnik, jen_verejne=True): | |||
| 			setrizene_body[i], # body za ročník (spočítané výše s pořadím) | ||||
| 			resitel_odjakzivabody_slov[ar_id], # body odjakživa | ||||
| 			rocnik) # ročník semináře pro získání ročníku řešitele | ||||
| 		print("{}: číslobody - {}, ročníkbody - {}," | ||||
| 			"odjakživabody - {}".format(radek.resitel, radek.body_cisla_sezn,  | ||||
| 			radek.body_rocnik, radek.body_celkem_odjakziva)) | ||||
| 		radky_vysledkovky.append(radek) | ||||
| 		print("Přikládám {}-tý řádek.".format(i)) | ||||
| 		i += 1 | ||||
| 
 | ||||
| 	return radky_vysledkovky | ||||
|  | @ -581,8 +625,8 @@ class RadekVysledkovkyCisla(object): | |||
| 		self.titul = resitel.get_titul(body_odjakziva) | ||||
| 	 | ||||
| 
 | ||||
| # přiřazuje danému řešiteli body do slovníku | ||||
| def pricti_body(slovnik, resitel, body): | ||||
| 	""" Přiřazuje danému řešiteli body do slovníku. """ | ||||
| 	# testujeme na None (""), pokud je to první řešení  | ||||
| 	# daného řešitele, předěláme na 0 | ||||
| 	# (v dalším kroku přičteme reálný počet bodů), | ||||
|  | @ -593,15 +637,16 @@ def pricti_body(slovnik, resitel, body): | |||
| 	slovnik[resitel.id] += body | ||||
| 
 | ||||
| def secti_body_za_rocnik(rocnik, aktivni_resitele): | ||||
| 	# spočítáme všem řešitelům jejich body za ročník | ||||
| 	resitel_rocnikbody_slov = body_resitelu_za_rocnik(rocnik, aktivni_resitele) | ||||
| 	""" Spočítá body za ročník, setřídí je sestupně a vrátí jako seznam.""" | ||||
| 	# 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) | ||||
| 	# 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(), | ||||
| 					key = lambda x: x[1], reverse = True) | ||||
| 	return resitel_rocnikbody_sezn | ||||
| 
 | ||||
| # spočítá u řešitelů body za číslo a za jednotlivé hlavní problémy (témata) | ||||
| def secti_body_za_cislo(cislo, aktivni_resitele, hlavni_problemy=None): | ||||
| 	""" Spočítá u řešitelů body za číslo a za jednotlivé hlavní problémy (témata).""" | ||||
| 	# TODO setřídit hlavní problémy čísla podle id, ať jsou ve stejném pořadí pokaždé | ||||
| 	# pro každý hlavní problém zavedeme slovník s body za daný hlavní problém  | ||||
| 	# pro jednotlivé řešitele (slovník slovníků hlavních problémů) | ||||
|  | @ -664,8 +709,7 @@ def vysledkovka_cisla(cislo, context=None): | |||
| 	resitel_rocnikbody_sezn = secti_body_za_rocnik(cislo.rocnik, aktivni_resitele) | ||||
| 
 | ||||
| 	# získáme body odjakživa | ||||
| 	resitel_odjakzivabody_slov = body_resitelu_odjakziva(cislo.rocnik,  | ||||
| 								aktivni_resitele) | ||||
| 	resitel_odjakzivabody_slov = body_resitelu(aktivni_resitele, cislo) | ||||
| 
 | ||||
| 	# řešitelé setřídění podle bodů za číslo sestupně | ||||
| 	setrizeni_resitele_id = [dvojice[0] for dvojice in resitel_rocnikbody_sezn] | ||||
|  | @ -692,10 +736,7 @@ def vysledkovka_cisla(cislo, context=None): | |||
| 			setrizeni_resitele_body[i], # body za ročník (spočítané výše s pořadím) | ||||
| 			resitel_odjakzivabody_slov[ar_id], # body odjakživa | ||||
| 			cislo.rocnik) # ročník semináře pro zjištění ročníku řešitele | ||||
| 		print("{}: body za problémy - {}, číslobody - {}, ročníkbody - {}, odjakživabody - {}".format(radek.resitel,  | ||||
| 			radek.body_problemy_sezn, radek.body_cislo, radek.body_rocnik, radek.body_celkem_odjakziva)) | ||||
| 		radky_vysledkovky.append(radek) | ||||
| 		print("Přikládám {}-tý řádek.".format(i)) | ||||
| 		i += 1 | ||||
| 
 | ||||
| 	# vytahané informace předáváme do kontextu | ||||
|  | @ -704,7 +745,6 @@ def vysledkovka_cisla(cislo, context=None): | |||
| 	context['problemy'] = hlavni_problemy | ||||
| 	#context['v_cisle_zadane'] = TODO | ||||
| 	#context['resene_problemy'] = resene_problemy | ||||
| 	print("Předávám kontext.") | ||||
| 	return context | ||||
| 
 | ||||
| class CisloView(generic.DetailView): | ||||
|  | @ -742,7 +782,7 @@ class ArchivTemataView(generic.ListView): | |||
| ### Generovani vysledkovky | ||||
| 
 | ||||
| class CisloVysledkovkaView(CisloView): | ||||
| 	"View vytvořené pro stránku zobrazující výsledkovku čísla v TeXu." | ||||
| 	"""View vytvořené pro stránku zobrazující výsledkovku čísla v TeXu.""" | ||||
| 
 | ||||
| 	model = Cislo | ||||
| 	template_name = 'seminar/archiv/cislo_vysledkovka.tex' | ||||
|  | @ -752,7 +792,7 @@ class CisloVysledkovkaView(CisloView): | |||
| 	#vypise na stranku textovy obsah vyTeXane vysledkovky k okopirovani | ||||
| 
 | ||||
| class RocnikVysledkovkaView(RocnikView): | ||||
| 	"View vytvořené pro stránku zobrazující výsledkovku ročníku v TeXu." | ||||
| 	""" View vytvořené pro stránku zobrazující výsledkovku ročníku v TeXu.""" | ||||
| 	model = Rocnik | ||||
| 	template_name = 'seminar/archiv/rocnik_vysledkovka.tex' | ||||
| 	#content_type = 'application/x-tex; charset=UTF8' | ||||
|  | @ -761,6 +801,7 @@ class RocnikVysledkovkaView(RocnikView): | |||
| 	#vypise na stranku textovy obsah vyTeXane vysledkovky k okopirovani | ||||
| 
 | ||||
| ### Generovani obalek | ||||
| 
 | ||||
| class CisloObalkyStruct: | ||||
| 	rocnik = None | ||||
| 	cisla = None | ||||
|  | @ -785,13 +826,15 @@ def aktivniResitele(rocnik,cislo): | |||
| 
 | ||||
| 	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) | ||||
| 	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: | ||||
| 		problemy = Problem.objects.filter(Q(cislo_zadani__in = letos.cisla)|Q(cislo_zadani__in = loni.cisla)) | ||||
| 	resitele = aktualni_resitele.filter(reseni__in = Reseni.objects.filter(problem__in=problemy)).distinct() | ||||
| 		problemy = Problem.objects.filter( | ||||
| 			Q(cislo_zadani__in = letos.cisla) | Q(cislo_zadani__in = loni.cisla) ) | ||||
| 	resitele = aktualni_resitele.filter(reseni__in = Reseni.objects.filter( | ||||
| 		problem__in=problemy)).distinct() | ||||
| 	return resitele | ||||
| 
 | ||||
| 
 | ||||
|  | @ -838,13 +881,15 @@ def oldObalkovaniView(request, rocnik, cislo): | |||
| ### Tituly | ||||
| 
 | ||||
| def TitulyView(request, rocnik, cislo): | ||||
| 	""" View pro stažení makra titulů v TeXu.""" | ||||
| 	rocnik_obj = Rocnik.objects.get(rocnik = rocnik) | ||||
| 	resitele = Resitel.objects.filter(rok_maturity__gte = rocnik_obj.prvni_rok) | ||||
| 	cislo_obj = Cislo.objects.get(rocnik = rocnik_obj, poradi = cislo) | ||||
| 
 | ||||
| 	asciijmena = [] | ||||
| 	jmenovci = False # detekuje, zda jsou dva řešitelé jmenovci (modulo nabodeníčka), pokud ano, vrátí se jako true | ||||
| 	slovnik_s_body = body_resitelu_odjakziva(rocnik_obj, resitele) | ||||
| 	jmenovci = False # detekuje, zda jsou dva řešitelé jmenovci (modulo nabodeníčka),  | ||||
| 		# pokud ano, vrátí se jako true | ||||
| 	slovnik_s_body = body_resitelu(resitele, rocnik_obj) | ||||
| 
 | ||||
| 	for resitel in resitele: | ||||
| 		resitel.titul = resitel.get_titul(slovnik_s_body[resitel.id]) | ||||
|  | @ -862,8 +907,6 @@ def TitulyView(request, rocnik, cislo): | |||
| 	return render(request, 'seminar/archiv/tituly.tex', | ||||
| 		{'resitele': resitele,'jmenovci':jmenovci},content_type="text/plain") | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| ### Soustredeni | ||||
| 
 | ||||
| class SoustredeniListView(generic.ListView): | ||||
|  | @ -892,13 +935,13 @@ class SoustredeniUcastniciBaseView(generic.ListView): | |||
| 
 | ||||
| 
 | ||||
| class SoustredeniMailyUcastnikuView(SoustredeniUcastniciBaseView): | ||||
| 	"""Seznam e-mailů řešitelů oddělených čárkami""" | ||||
| 	""" Seznam e-mailů řešitelů oddělených čárkami. """ | ||||
| 	model = Soustredeni_Ucastnici | ||||
| 	template_name = 'seminar/soustredeni/maily_ucastniku.txt' | ||||
| 
 | ||||
| 
 | ||||
| class SoustredeniUcastniciView(SoustredeniUcastniciBaseView): | ||||
| 	"""HTML tabulka účastníků pro tisk""" | ||||
| 	""" HTML tabulka účastníků pro tisk. """ | ||||
| 	model = Soustredeni_Ucastnici | ||||
| 	template_name = 'seminar/soustredeni/seznam_ucastniku.html' | ||||
| 
 | ||||
|  | @ -1020,11 +1063,11 @@ def texUploadView(request): | |||
| 			} | ||||
| 			problem_typ = typy[meta["typ"]] | ||||
| 
 | ||||
| 			# Pokud už problém existuje, vytáhneme jej z db a upravíme | ||||
| 			# Pokud neexistuje, vytvoříme jej jedině pokud je to vynucené | ||||
| 			# Pokud už problém existuje, vytáhneme jej z db a upravíme. | ||||
| 			# Pokud neexistuje, vytvoříme jej jedině pokud je to vynucené. | ||||
| 
 | ||||
| 			# Pokud ročník/číslo ještě neexistuje, vyhodí to výjimku -> | ||||
| 			# číslo/ročník se musí založit ručně v adminu | ||||
| 			# číslo/ročník se musí založit ručně v adminu. | ||||
| 			rocnik = Rocnik.objects.get(rocnik=meta["rocnik"]) | ||||
| 			cislo = Cislo.objects.get(rocnik=rocnik, cislo=meta["cislo"]) | ||||
| 
 | ||||
|  | @ -1158,7 +1201,8 @@ class ResitelView(LoginRequiredMixin,generic.DetailView): | |||
| 		print(self.request.user) | ||||
| 		return Resitel.objects.get(osoba__user=self.request.user) | ||||
| 
 | ||||
| ## Formulare | ||||
| ### Formulare | ||||
| 
 | ||||
| class AddSolutionView(LoginRequiredMixin, FormView): | ||||
| 	template_name = 'seminar/org/vloz_reseni.html' | ||||
| 	form_class = f.VlozReseniForm | ||||
|  | @ -1197,9 +1241,6 @@ class SubmitSolutionView(LoginRequiredMixin, CreateView): | |||
| 
 | ||||
| 		return HttpResponseRedirect(self.get_success_url()) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| def resetPasswordView(request): | ||||
| 	pass | ||||
| 
 | ||||
|  | @ -1361,10 +1402,6 @@ def prihlaskaView(request): | |||
| 
 | ||||
| 	return render(request, 'seminar/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 | ||||
|  | @ -1382,25 +1419,25 @@ class LogoutView(auth_views.LogoutView): | |||
| 	# Pavel: Vůbec nevím, proč to s _lazy funguje, ale bez toho to bylo rozbité. | ||||
| 	next_page = reverse_lazy('titulni_strana') | ||||
| 
 | ||||
| # "Chci resetovat heslo" | ||||
| class PasswordResetView(auth_views.PasswordResetView): | ||||
| 	""" Chci resetovat heslo. """ | ||||
| 	#template_name = 'seminar/password_reset.html' | ||||
| 	# TODO: vlastní email_template_name a subject_template_name a html_email_template_name | ||||
| 	success_url = reverse_lazy('reset_password_done') | ||||
| 	from_email = 'login@mam.mff.cuni.cz' | ||||
| 
 | ||||
| # "Poslali jsme e-mail (pokud bylo kam))" | ||||
| class PasswordResetDoneView(auth_views.PasswordResetDoneView): | ||||
| 	""" Poslali jsme e-mail (pokud bylo kam)). """ | ||||
| 	#template_name = 'seminar/password_reset_done.html' | ||||
| 	pass | ||||
| 
 | ||||
| # "Vymysli si heslo" | ||||
| class PasswordResetConfirmView(auth_views.PasswordResetConfirmView): | ||||
| 	""" Vymysli si heslo. """ | ||||
| 	#template_name = 'seminar/password_confirm_done.html' | ||||
| 	success_url = reverse_lazy('reset_password_complete') | ||||
| 
 | ||||
| # "Heslo se asi změnilo." | ||||
| class PasswordResetCompleteView(auth_views.PasswordResetCompleteView): | ||||
| 	""" Heslo se asi změnilo.""" | ||||
| 	#template_name = 'seminar/password_complete_done.html' | ||||
| 	pass | ||||
| 
 | ||||
|  |  | |||
 Pavel 'LEdoian' Turinsky
						Pavel 'LEdoian' Turinsky