Merge branch 'develop' into test
This commit is contained in:
		
						commit
						348ee4da0d
					
				
					 16 changed files with 187 additions and 104 deletions
				
			
		|  | @ -1,13 +1,8 @@ | ||||||
| # -*- coding: utf-8 -*- | from django.http import HttpResponse | ||||||
| 
 | from django.utils.encoding import force_text | ||||||
| try: |  | ||||||
|     from django.http import HttpResponse |  | ||||||
|     from django.utils.encoding import force_text |  | ||||||
| except: |  | ||||||
|     force_text = str |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class OvvpFile(object): | class OvvpFile: | ||||||
| 	def __init__(self): | 	def __init__(self): | ||||||
| 		# { header: value, ... } | 		# { header: value, ... } | ||||||
| 		self.headers = {} | 		self.headers = {} | ||||||
|  | @ -19,10 +14,10 @@ class OvvpFile(object): | ||||||
| 	def to_lines(self): | 	def to_lines(self): | ||||||
| 		# header | 		# header | ||||||
| 		for hk in sorted(self.headers.keys()): | 		for hk in sorted(self.headers.keys()): | ||||||
|             yield '%s\t%s\n' % (hk, self.headers[hk]) | 			yield f'{hk}\t{self.headers[hk]}\n' | ||||||
| 		yield '\n' | 		yield '\n' | ||||||
| 		# columns | 		# columns | ||||||
|         yield '\t'.join([c for c in self.columns]) + '\n' | 		yield '\t'.join(self.columns) + '\n' | ||||||
| 		# rows | 		# rows | ||||||
| 		for r in self.rows: | 		for r in self.rows: | ||||||
| 			yield '\t'.join([force_text(r[c]) for c in self.columns]) + '\n' | 			yield '\t'.join([force_text(r[c]) for c in self.columns]) + '\n' | ||||||
|  | @ -30,52 +25,6 @@ class OvvpFile(object): | ||||||
| 	def to_string(self): | 	def to_string(self): | ||||||
| 		return ''.join(self.to_lines()) | 		return ''.join(self.to_lines()) | ||||||
| 
 | 
 | ||||||
|  | 	# Pozn: tohle je ta jediná funkce, která se reálně používá… | ||||||
| 	def to_HttpResponse(self): | 	def to_HttpResponse(self): | ||||||
| 		return HttpResponse(self.to_string(), content_type='text/plain; charset=utf-8') | 		return HttpResponse(self.to_string(), content_type='text/plain; charset=utf-8') | ||||||
| 
 |  | ||||||
|     def parse_from(self, source, with_headers=True): |  | ||||||
|         "Parse data from file, string or line iterator, overwriting self" |  | ||||||
|         if isinstance(source, str) or isinstance(source, unicode): |  | ||||||
|             return self.parse_from(source.split('\n')) |  | ||||||
|              |  | ||||||
|         it = iter(source) |  | ||||||
| 
 |  | ||||||
|         # header |  | ||||||
|         self.headers = {} |  | ||||||
|         if with_headers: |  | ||||||
|             for r in it: |  | ||||||
|                 if isinstance(r, str): |  | ||||||
|                     r = r.decode('utf8') |  | ||||||
|                 assert isinstance(r, unicode) |  | ||||||
|                 r = r.rstrip('\n') |  | ||||||
|                 if r == u"": |  | ||||||
|                     break |  | ||||||
|                 k, v = r.split(u'\t', 1) |  | ||||||
|                 self.headers[k] = v |  | ||||||
| 
 |  | ||||||
|         # columns |  | ||||||
|         r = it.next() |  | ||||||
|         if isinstance(r, str): |  | ||||||
|             r = r.decode('utf8') |  | ||||||
|         self.columns = [cn.strip() for cn in r.split(u'\t') if cn.strip() != ""] |  | ||||||
| 
 |  | ||||||
|         # rows |  | ||||||
|         self.rows = [] |  | ||||||
|         for r in it: |  | ||||||
|             if isinstance(r, str): |  | ||||||
|                 r = r.decode('utf8') |  | ||||||
|             r = r.rstrip('\n') |  | ||||||
|             if not r: |  | ||||||
|                 break |  | ||||||
|             rtup = r.split(u'\t') |  | ||||||
|             rdict = {} |  | ||||||
|             for ci in range(len(self.columns)): |  | ||||||
|                 rdict[self.columns[ci]] = rtup[ci] |  | ||||||
|             self.rows.append(rdict) |  | ||||||
|          |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def parse(source, with_headers=True): |  | ||||||
|     o = OvvpFile() |  | ||||||
|     o.parse_from(source, with_headers=with_headers) |  | ||||||
|     return o |  | ||||||
|  |  | ||||||
|  | @ -3,8 +3,16 @@ | ||||||
| # Props to https://www.commandlinefu.com/commands/view/8234/check-broken-links-using-wget-as-a-spider | # Props to https://www.commandlinefu.com/commands/view/8234/check-broken-links-using-wget-as-a-spider | ||||||
| set -eu | set -eu | ||||||
| 
 | 
 | ||||||
|  | if test "$#" -lt 1; then | ||||||
|  | 	echo >&2 "Usage: $0 <wget parameters, especially URL to test>" | ||||||
|  | 	exit 1 | ||||||
|  | fi | ||||||
|  | 
 | ||||||
| logfile="$(pwd)/wget.log.$(date +%FT%T)" | logfile="$(pwd)/wget.log.$(date +%FT%T)" | ||||||
| tmp=$(mktemp --directory) | tmp=$(mktemp --directory) | ||||||
| cd "$tmp" | cd "$tmp" | ||||||
| 
 | 
 | ||||||
| wget --spider -o "$logfile" -r -p -X '/soustredeni/*/fotogalerie/' "$@" | wget --spider -o "$logfile" -r -p -X '/soustredeni/*/fotogalerie/' "$@" || true # wget nejspíš skončí s chybou, že něco nestáhl… | ||||||
|  | 
 | ||||||
|  | echo "Result: (a last few lines of the file $logfile)" | ||||||
|  | sed -ne '/^Found [0-9]* broken links/,$ p' "$logfile" | ||||||
|  |  | ||||||
|  | @ -24,7 +24,7 @@ def zobrazit(galerie, request): | ||||||
| def cesta_od_korene(g): | def cesta_od_korene(g): | ||||||
| 	"""Vrátí seznam galerií od kořene ke g""" | 	"""Vrátí seznam galerií od kořene ke g""" | ||||||
| 	cesta = [] | 	cesta = [] | ||||||
| 	while g != None: | 	while g is not None: | ||||||
| 		cesta.append(g) | 		cesta.append(g) | ||||||
| 		g = g.galerie_up | 		g = g.galerie_up | ||||||
| 	return reversed(cesta) | 	return reversed(cesta) | ||||||
|  | @ -53,7 +53,7 @@ def nahled(request, pk, soustredeni): | ||||||
| 	for g in sourozenci: | 	for g in sourozenci: | ||||||
| 		if g.pk == galerie.pk: | 		if g.pk == galerie.pk: | ||||||
| 			predchozi = minuly | 			predchozi = minuly | ||||||
| 		if minuly != None and minuly.pk == galerie.pk: | 		if minuly is not None and minuly.pk == galerie.pk: | ||||||
| 			nasledujici = g | 			nasledujici = g | ||||||
| 			break | 			break | ||||||
| 		minuly = g | 		minuly = g | ||||||
|  |  | ||||||
|  | @ -4,7 +4,6 @@ from __future__ import unicode_literals | ||||||
| from django.db import migrations, models | from django.db import migrations, models | ||||||
| 
 | 
 | ||||||
| def transform_autor(apps, schema_editor): | def transform_autor(apps, schema_editor): | ||||||
|     print |  | ||||||
|     Organizator = apps.get_model('seminar', 'Organizator') |     Organizator = apps.get_model('seminar', 'Organizator') | ||||||
| 
 | 
 | ||||||
|     # preorgovani oprav |     # preorgovani oprav | ||||||
|  |  | ||||||
|  | @ -1,20 +0,0 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| 
 |  | ||||||
| from django.core.management.base import BaseCommand |  | ||||||
| from django.contrib.sessions.models import Session |  | ||||||
| from django.contrib.auth.models import User |  | ||||||
| 
 |  | ||||||
| class Command(BaseCommand): |  | ||||||
|     u"""Vypiš username přihlášeného orga s daným session_key. |  | ||||||
| 
 |  | ||||||
|     Příkaz pro manage.py, který ze vstupu přečte session_key (tak, jak je |  | ||||||
|     uložen v cookie sessionid) a pokud session existuje a příslušný přihlášený |  | ||||||
|     uživatel má právo přihlásit se do admina, vypíše jeho username. |  | ||||||
|     """ |  | ||||||
|     def handle(self, *args, **options): |  | ||||||
|         session_key = raw_input() |  | ||||||
|         s = Session.objects.get(pk=session_key).get_decoded() |  | ||||||
|         user_id = s['_auth_user_id'] |  | ||||||
|         user = User.objects.get(pk=user_id) |  | ||||||
|         if user.is_staff: |  | ||||||
|             print(user.username) |  | ||||||
|  | @ -1139,6 +1139,7 @@ class Reseni(SeminarModelBase): | ||||||
| 
 | 
 | ||||||
| 	# má ForeignKey s: | 	# má ForeignKey s: | ||||||
| 	# Hodnoceni | 	# Hodnoceni | ||||||
|  | 	# ReseniNode | ||||||
| 
 | 
 | ||||||
| 	def sum_body(self): | 	def sum_body(self): | ||||||
| 		return self.hodnoceni_set.all().aggregate(Sum('body'))["body__sum"] | 		return self.hodnoceni_set.all().aggregate(Sum('body'))["body__sum"] | ||||||
|  |  | ||||||
|  | @ -77,8 +77,8 @@ def gen_osoby(rnd, size): | ||||||
| 		prezdivka = rnd.choice(prezdivky) | 		prezdivka = rnd.choice(prezdivky) | ||||||
| 		email = "@".join([unidecode.unidecode(jmeno), rnd.choice(domain)]) | 		email = "@".join([unidecode.unidecode(jmeno), rnd.choice(domain)]) | ||||||
| 		telefon = "".join([str(rnd.choice([k for k in range(10)])) for i in range(9)]) | 		telefon = "".join([str(rnd.choice([k for k in range(10)])) for i in range(9)]) | ||||||
| 		narozeni = datetime.date(rnd.randint(1980, 2020), rnd.randint(1, 12), | 		narozeni = datetime.date(rnd.randint(1980, datetime.datetime.now().year),  | ||||||
| 						rnd.randint(1, 28)) | 				rnd.randint(1, 12), rnd.randint(1, 28)) | ||||||
| 		ulic = rnd.choice(seznam_ulic) | 		ulic = rnd.choice(seznam_ulic) | ||||||
| 		cp = rnd.randint(1, 99) | 		cp = rnd.randint(1, 99) | ||||||
| 		ulice = " ".join([ulic, str(cp)]) | 		ulice = " ".join([ulic, str(cp)]) | ||||||
|  | @ -142,7 +142,7 @@ def gen_resitele(rnd, osoby, skoly): | ||||||
| 				os.save() | 				os.save() | ||||||
| 				os.user.user_permissions.add(resitel_perm) | 				os.user.user_permissions.add(resitel_perm) | ||||||
| 			resitele.append(Resitel.objects.create(osoba=os, skola=rnd.choice(skoly), | 			resitele.append(Resitel.objects.create(osoba=os, skola=rnd.choice(skoly), | ||||||
| 				rok_maturity=rnd.randint(2019, 2029), | 				rok_maturity=os.datum_narozeni.year + rnd.randint(18, 21), | ||||||
| 				zasilat=rnd.choice(Resitel.ZASILAT_CHOICES)[0])) | 				zasilat=rnd.choice(Resitel.ZASILAT_CHOICES)[0])) | ||||||
| 	return resitele | 	return resitele | ||||||
| 
 | 
 | ||||||
|  | @ -890,6 +890,9 @@ def create_test_data(size = 6, rnd = None): | ||||||
| 	# Dohackované vytvoření jednoho článku | 	# Dohackované vytvoření jednoho článku | ||||||
| 	gen_clanek(rnd, organizatori, resitele) | 	gen_clanek(rnd, organizatori, resitele) | ||||||
| 
 | 
 | ||||||
|  | 			# TODO: přidat články včetně zařazení do struktury treenodů, | ||||||
|  | 			#	a následně otestovat konsistency check databáze z utils.py | ||||||
|  | 			# 	pomocí stránky /stav | ||||||
| 
 | 
 | ||||||
| 	# obecné nastavení semináře, musí být už přidané ročníky a čísla, jinak se nastaví divně | 	# obecné nastavení semináře, musí být už přidané ročníky a čísla, jinak se nastaví divně | ||||||
| 	nastaveni = Nastaveni.objects.create( | 	nastaveni = Nastaveni.objects.create( | ||||||
|  |  | ||||||
|  | @ -88,6 +88,11 @@ def from_roman(rom): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def seznam_problemu(): | def seznam_problemu(): | ||||||
|  | 	"""Funkce pro hledání nekonzistencí v databázi a dalších nežádoucích stavů webu/databáze. | ||||||
|  | 
 | ||||||
|  | 	Nijak nesouvisí s Problémy zadanými řešitelům.""" | ||||||
|  | 	# FIXME: přejmenovat funkci? | ||||||
|  | 	# FIXME: Tak, jak je napsaná, asi spíš patří někam k views a ne do utils (?) | ||||||
| 	problemy = [] | 	problemy = [] | ||||||
| 
 | 
 | ||||||
| 	# Pomocna fce k formatovani problemovych hlasek | 	# Pomocna fce k formatovani problemovych hlasek | ||||||
|  |  | ||||||
|  | @ -891,7 +891,7 @@ def TitulyView(request, rocnik, cislo): | ||||||
| 	asciijmena = [] | 	asciijmena = [] | ||||||
| 	jmenovci = False # detekuje, zda jsou dva řešitelé jmenovci (modulo nabodeníčka), | 	jmenovci = False # detekuje, zda jsou dva řešitelé jmenovci (modulo nabodeníčka), | ||||||
| 		# pokud ano, vrátí se jako true | 		# pokud ano, vrátí se jako true | ||||||
| 	slovnik_s_body = body_resitelu(resitele, rocnik_obj) | 	slovnik_s_body = body_resitelu(resitele, cislo_obj) | ||||||
| 
 | 
 | ||||||
| 	for resitel in resitele: | 	for resitel in resitele: | ||||||
| 		resitel.titul = resitel.get_titul(slovnik_s_body[resitel.id]) | 		resitel.titul = resitel.get_titul(slovnik_s_body[resitel.id]) | ||||||
|  |  | ||||||
							
								
								
									
										3
									
								
								setup/README
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								setup/README
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,3 @@ | ||||||
|  | Tato složka obsahuje různé konfiguráky potřebné k rozběhnutí webu na serveru. | ||||||
|  | 
 | ||||||
|  | TODO: Napsat sem i přehled toho, jak to funguje. | ||||||
							
								
								
									
										50
									
								
								setup/nginx/mam-test.ks.matfyz.cz
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								setup/nginx/mam-test.ks.matfyz.cz
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,50 @@ | ||||||
|  | server { | ||||||
|  |     listen 195.113.20.177:80; | ||||||
|  |     listen [2001:718:1e03:801::b1]:80; | ||||||
|  |     server_name mam-test.ks.matfyz.cz; | ||||||
|  |     return 301 https://$server_name$request_uri; | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | server { | ||||||
|  |     # SSL configuration | ||||||
|  |     listen 195.113.20.177:443 ssl; | ||||||
|  |     listen [2001:718:1e03:801::b1]:443 ssl; | ||||||
|  | 
 | ||||||
|  |     # SSL keys | ||||||
|  |     ssl on; | ||||||
|  |     ssl_certificate /etc/letsencrypt/live/mam-test.ks.matfyz.cz/fullchain.pem; # managed by Certbot | ||||||
|  |     ssl_certificate_key /etc/letsencrypt/live/mam-test.ks.matfyz.cz/privkey.pem; # managed by Certbot | ||||||
|  |     ssl_dhparam /etc/ssl/dhparams.pem; | ||||||
|  |     ssl_session_cache shared:SSL:10m; | ||||||
|  |     ssl_session_timeout 5m; | ||||||
|  | 
 | ||||||
|  |     server_name mam-test.ks.matfyz.cz; | ||||||
|  | 
 | ||||||
|  |     client_max_body_size 50M; | ||||||
|  | 
 | ||||||
|  |     auth_basic "MaMweb test - access restricted"; | ||||||
|  |     auth_basic_user_file /akce/mam/www/mamweb-test/.htpasswd; | ||||||
|  | 
 | ||||||
|  |     location /static/ { | ||||||
|  |         root /akce/mam/www/mamweb-test/; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     location /media/ { | ||||||
|  |         root /akce/mam/www/mamweb-test/; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     location /aesop-export/ { | ||||||
|  |         auth_basic "AESOP API"; | ||||||
|  |         auth_basic_user_file /akce/mam/www/mamweb-test/.htpasswd-aesop; | ||||||
|  |         try_files $uri @mamweb_test; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |      | ||||||
|  |     location / { try_files $uri @mamweb_test; } | ||||||
|  | 
 | ||||||
|  |     location @mamweb_test { | ||||||
|  |         include uwsgi_params; | ||||||
|  |         uwsgi_pass unix:/tmp/uwsgi-mamweb_test.sock; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										65
									
								
								setup/nginx/mam.mff.cuni.cz
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								setup/nginx/mam.mff.cuni.cz
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,65 @@ | ||||||
|  | 
 | ||||||
|  | server { | ||||||
|  |     listen 195.113.20.177:80; | ||||||
|  |     listen [2001:718:1e03:801::b1]:80; | ||||||
|  |     server_name mam.mff.cuni.cz; | ||||||
|  |     return 301 https://$server_name$request_uri; | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | server { | ||||||
|  |     # SSL configuration | ||||||
|  |     # | ||||||
|  |     listen 195.113.20.177:443 ssl; | ||||||
|  |     listen [2001:718:1e03:801::b1]:443 ssl; | ||||||
|  | 
 | ||||||
|  |     # SSL keys | ||||||
|  |     ssl on; | ||||||
|  |     ssl_certificate /etc/ssl/domains/mam.mff.cuni.cz/bundle.pem; | ||||||
|  |     ssl_certificate_key /etc/ssl/domains/mam.mff.cuni.cz/privkey.pem; | ||||||
|  |     ssl_dhparam /etc/ssl/dhparams.pem; | ||||||
|  |     ssl_session_cache shared:SSL:10m; | ||||||
|  |     ssl_session_timeout 5m; | ||||||
|  |      | ||||||
|  | 
 | ||||||
|  |     server_name mam.mff.cuni.cz; | ||||||
|  |     # server_name mamweb.bezva.org; | ||||||
|  | 
 | ||||||
|  |     client_max_body_size 50M; | ||||||
|  | 
 | ||||||
|  |     location /aesop-export/ { | ||||||
|  |         auth_basic "AESOP API"; | ||||||
|  |         auth_basic_user_file /akce/mam/www/mamweb-prod/.htpasswd-aesop; | ||||||
|  |         try_files $uri @mamweb_prod; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     location /static/ { | ||||||
|  |         root /akce/mam/www/mamweb-prod/; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     location /media/ { | ||||||
|  |         root /akce/mam/www/mamweb-prod/; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     location /wiki/ { | ||||||
|  |         proxy_pass http://127.0.0.1:5001/; | ||||||
|  |         proxy_set_header X-Real_IP $remote_addr; | ||||||
|  |         proxy_redirect / /wiki/; | ||||||
|  |         #rewrite '/' '/wiki';  | ||||||
|  |         sub_filter_once off; | ||||||
|  |         sub_filter 'href="/' 'href="/wiki/'; | ||||||
|  |         sub_filter 'src="/' 'src="/wiki/'; | ||||||
|  |         sub_filter 'action="/' 'action="/wiki/'; | ||||||
|  |         # Overkill: | ||||||
|  |         #sub_filter '="/' '="/wiki/'; | ||||||
|  |         #sub_filter ':5001/' '/wiki/';	 | ||||||
|  |         #sub_filter 'Location: /' 'Location: /wiki/';	 | ||||||
|  |         #sub_filter '_login' '_test'; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     location / { try_files $uri @mamweb_prod; } | ||||||
|  | 
 | ||||||
|  |     location @mamweb_prod { | ||||||
|  |         include uwsgi_params; | ||||||
|  |         uwsgi_pass unix:/tmp/uwsgi-mamweb_prod.sock; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										10
									
								
								setup/systemd/mamweb-prod.service
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								setup/systemd/mamweb-prod.service
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,10 @@ | ||||||
|  | [Unit] | ||||||
|  | Description=uWSGI instance to serve mam.mff.cuni.cz | ||||||
|  | After=network.target | ||||||
|  | 
 | ||||||
|  | [Service] | ||||||
|  | WorkingDirectory=/akce/mam/www/mamweb-prod | ||||||
|  | ExecStart=/usr/bin/uwsgi --ini mamweb_prod.ini | ||||||
|  | 
 | ||||||
|  | [Install] | ||||||
|  | WantedBy=default.target | ||||||
							
								
								
									
										10
									
								
								setup/systemd/mamweb-test.service
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								setup/systemd/mamweb-test.service
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,10 @@ | ||||||
|  | [Unit] | ||||||
|  | Description=uWSGI instance to serve mam-test.kam.mff.cuni.cz | ||||||
|  | After=network.target | ||||||
|  | 
 | ||||||
|  | [Service] | ||||||
|  | WorkingDirectory=/akce/mam/www/mamweb-test | ||||||
|  | ExecStart=/usr/bin/uwsgi --ini mamweb_test.ini | ||||||
|  | 
 | ||||||
|  | [Install] | ||||||
|  | WantedBy=default.target | ||||||
		Loading…
	
		Reference in a new issue