Merge branch 'master' into stable
This commit is contained in:
		
						commit
						1d78128ecb
					
				
					 35 changed files with 801 additions and 158 deletions
				
			
		
							
								
								
									
										15
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								Makefile
									
									
									
									
									
								
							|  | @ -44,7 +44,7 @@ clean_virtualenv: | |||
| 	rm -rf virtualenv-*.tar.gz | ||||
| 
 | ||||
| run: | ||||
| 	./manage.py runserver_plus | ||||
| 	./manage.py runserver | ||||
| 
 | ||||
| test: | ||||
| 	./manage.py test -v2 seminar mamweb | ||||
|  | @ -93,3 +93,16 @@ deploy_prod: | |||
| 	touch mamweb/wsgi.py | ||||
| 	@echo Done. | ||||
| 
 | ||||
| # Sync media directory with atrey. Useful for local development with production database
 | ||||
| # Does not sync Galerie and CACHE (too huge). 
 | ||||
| sync_media: | ||||
| 	rsync -ave ssh --exclude Galerie --exclude CACHE\
 | ||||
| 		atrey.karlin.mff.cuni.cz:/akce/MaM/WWW/mamweb-prod/media/ ./media/ | ||||
| # Downloads and restores production database to local database. PostgreSQL only. 
 | ||||
| sync_db: | ||||
| 	scp atrey.karlin.mff.cuni.cz:`ssh atrey.karlin.mff.cuni.cz 'ls -v /akce/MaM/WWW/backups/mam-prod-*\.pgdump | tail -n 1'` \
 | ||||
| 		./last.pgdump | ||||
| 	pg_restore -c -d mam -U mam last.pgdump | ||||
| 
 | ||||
| # Sync database and media. See above lines
 | ||||
| sync: sync_media sync_db | ||||
|  |  | |||
|  | @ -9,7 +9,7 @@ class KorekturovanePDFAdmin(VersionAdmin): | |||
|          (None,              {'fields': ['pdf', 'cas', 'stran', 'nazev', 'komentar']}), | ||||
| #         (u'PDF',       {'fields': ['pdf']}), | ||||
|          ] | ||||
|      list_display = ['pdf', 'cas', 'stran'] | ||||
|      list_display = ['nazev', 'cas', 'stran'] | ||||
|      list_filter = [] | ||||
|      search_fields = [] | ||||
|   | ||||
|  |  | |||
|  | @ -78,7 +78,9 @@ class KorekturovanePDF(models.Model): | |||
|             "-density","180x180", | ||||
|             "-geometry"," 1024x1448", | ||||
|             self.pdf.path+"[%d]"%self.stran, | ||||
|             os.path.join(settings.KOREKTURY_IMG_DIR, "%s-%d.png"%(filename,self.stran))]) | ||||
|             os.path.join(settings.BASE_DIR, "media", | ||||
|                 settings.KOREKTURY_IMG_DIR,  | ||||
|                 "%s-%d.png"%(filename,self.stran))]) | ||||
|             if res==1: | ||||
|                 break | ||||
|             self.stran +=1 | ||||
|  |  | |||
|  | @ -126,7 +126,7 @@ function img_click(element, ev) { | |||
| function toggle_visibility(button){ | ||||
| 	var divbox = button.parentNode.parentNode.parentNode; | ||||
| 	var id = divbox.id; | ||||
| 	var text = document.getElementById(id+'-text'); | ||||
| 	var text = document.getElementById(id+'-body'); | ||||
| 	if (text.style.display == 'none'){ | ||||
| 		text.style.display = 'block'; | ||||
| 	}else { | ||||
|  |  | |||
|  | @ -150,6 +150,7 @@ | |||
| 
 | ||||
| 			</div> | ||||
| 		</div> | ||||
| 		<div class='corr-body' id='op{{o.id}}-body'> | ||||
| 		<div id='op{{o.id}}-text'>{{o.text}}</div> | ||||
| 
 | ||||
| 		{% for k in o.komentare %} | ||||
|  | @ -178,6 +179,7 @@ | |||
| 			<div id='kt{{k.id}}'>{{k.text}}</div> | ||||
| 		</div> | ||||
| 		{% endfor %}  | ||||
| 		</div> | ||||
| 	</div>	 | ||||
| 	{% endfor %} | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from django.shortcuts import render | ||||
| from django.shortcuts import get_object_or_404, render | ||||
| from django.views import generic | ||||
| from django.utils.translation import ugettext as _ | ||||
| from django.conf import settings | ||||
|  | @ -114,7 +114,7 @@ class KorekturyView(generic.TemplateView): | |||
| 
 | ||||
|     def get_context_data(self, **kwargs): | ||||
|         context = super(KorekturyView,self).get_context_data(**kwargs) | ||||
|         pdf = KorekturovanePDF.objects.get(id=self.kwargs['pdf']) | ||||
|         pdf = get_object_or_404(KorekturovanePDF, id=self.kwargs['pdf']) | ||||
|         context['pdf'] = pdf | ||||
|         context['img_name'] = os.path.split(pdf.pdf.path)[1].split('.')[0] | ||||
|         context['img_path'] = settings.KOREKTURY_IMG_DIR | ||||
|  |  | |||
|  | @ -240,7 +240,8 @@ LOGGING = { | |||
| 
 | ||||
| # MaM specific | ||||
| 
 | ||||
| SEMINAR_RESENI_DIR = os.path.join(BASE_DIR, 'media', 'reseni') | ||||
| SEMINAR_KONFERY_DIR = os.path.join(BASE_DIR, 'media', 'konfery') | ||||
| KOREKTURY_PDF_DIR = os.path.join(BASE_DIR, 'media', 'korektury','pdf') | ||||
| KOREKTURY_IMG_DIR = os.path.join(BASE_DIR, 'media', 'korektury','img') | ||||
| SEMINAR_RESENI_DIR = os.path.join('reseni') | ||||
| SEMINAR_KONFERY_DIR = os.path.join('konfery') | ||||
| KOREKTURY_PDF_DIR = os.path.join('korektury','pdf') | ||||
| KOREKTURY_IMG_DIR = os.path.join('korektury','img') | ||||
| CISLO_IMG_DIR = os.path.join('cislo','img') | ||||
|  |  | |||
|  | @ -52,7 +52,7 @@ div.content { | |||
| 	padding: 15px 30px; | ||||
| } | ||||
| 
 | ||||
| h2 { | ||||
| h1 { | ||||
| 	margin-top: 0px; | ||||
| } | ||||
| 
 | ||||
|  | @ -92,6 +92,7 @@ h2 { | |||
| 	top: 40px; | ||||
| 	left: 55px; | ||||
| } | ||||
| /* | ||||
| #header h1 { | ||||
| 	font-size: 130%; | ||||
| 	position: absolute; | ||||
|  | @ -99,6 +100,7 @@ h2 { | |||
| 	left: 30px; | ||||
| 	height: 110px; | ||||
| } | ||||
| */ | ||||
| #header img.header { | ||||
| 	margin: -25px 20px 0px 0px; | ||||
| 	height: 145px; | ||||
|  | @ -160,7 +162,7 @@ div.menu li.selected a { | |||
| 	z-index: 15px; | ||||
| } | ||||
| 
 | ||||
| h2 a:hover { | ||||
| h1 a:hover { | ||||
|     text-decoration: none; | ||||
| } | ||||
| 
 | ||||
|  | @ -263,7 +265,7 @@ div.zadani_azad_termin { | |||
|     text-align: center; | ||||
| } | ||||
| 
 | ||||
| #seznam_orgu h2 { | ||||
| #seznam_orgu h1 { | ||||
|     text-align: center; | ||||
| } | ||||
| 
 | ||||
|  | @ -495,7 +497,7 @@ div.zadani_azad_termin { | |||
|   margin: 20px auto 0 auto; | ||||
| } | ||||
| 
 | ||||
| .galerie h2 { | ||||
| .galerie h1 { | ||||
|   text-align: center; | ||||
| } | ||||
| 
 | ||||
|  | @ -679,3 +681,7 @@ div.zadani_azad_termin { | |||
| div.novinka_obrazek { | ||||
|     width: 100%; | ||||
| } | ||||
| 
 | ||||
| div.org-text { | ||||
|     font-style: italic; | ||||
| } | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ from django.db import models | |||
| 
 | ||||
| from django.contrib.auth.models import User | ||||
| 
 | ||||
| from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni, Nastaveni, Soustredeni, Soustredeni_Ucastnici, Soustredeni_Organizatori, Novinky, Organizator | ||||
| from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni, Nastaveni, Soustredeni, Soustredeni_Ucastnici, Soustredeni_Organizatori, Novinky, Organizator, Prispevek, Pohadka | ||||
| from autocomplete_light import shortcuts as autocomplete_light | ||||
| 
 | ||||
| 
 | ||||
|  | @ -296,6 +296,39 @@ class ReseniAdmin(VersionAdmin): | |||
| admin.site.register(Reseni, ReseniAdmin) | ||||
| 
 | ||||
| 
 | ||||
| ### Pohádka | ||||
| 
 | ||||
| class PohadkaAdminForm(forms.ModelForm): | ||||
|     class Meta: | ||||
|         model = Pohadka | ||||
|         exclude = [] | ||||
|     autor = UserModelChoiceField(User.objects.filter(is_staff=True)) | ||||
|     uloha = forms.ModelChoiceField(Problem.objects.filter(typ=Problem.TYP_ULOHA)) | ||||
| 
 | ||||
| class PohadkaAdmin(VersionAdmin): | ||||
|     form = PohadkaAdminForm | ||||
| 
 | ||||
|     def get_kod_ulohy(self, obj): | ||||
|         return obj.uloha.kod_v_rocniku() | ||||
|     get_kod_ulohy.short_description = u'Kód úlohy' | ||||
| 
 | ||||
|     def get_rocnik(self, obj): | ||||
|         return obj.uloha.cislo_zadani.rocnik.rocnik | ||||
|     get_rocnik.short_description = u'Ročník' | ||||
| 
 | ||||
|     list_display = ['__str__', 'get_rocnik', 'get_kod_ulohy', 'uloha', 'autor', 'timestamp'] | ||||
| 
 | ||||
|     get_form = get_form_predvypln_autora | ||||
| 
 | ||||
| class PohadkaKProblemuInline(admin.TabularInline): | ||||
|     form = PohadkaAdminForm | ||||
|     model = Pohadka | ||||
|     exclude = [] | ||||
|     extra = 0 | ||||
| 
 | ||||
| admin.site.register(Pohadka, PohadkaAdmin) | ||||
| 
 | ||||
| 
 | ||||
| ### Problem | ||||
| 
 | ||||
| from autocomplete_light.contrib.taggit_field import TaggitField, TaggitWidget | ||||
|  | @ -348,7 +381,14 @@ create_modeladmin(ProblemNavrhAdmin, Problem, 'ProblemNavrh', verbose_name=u'Pro | |||
| class ProblemZadanyAdmin(ProblemAdmin): | ||||
|     list_display = ['nazev', 'typ', 'autor', 'opravovatel', 'kod', 'cislo_zadani', 'pocet_reseni', 'verejne'] | ||||
|     list_filter = ['typ', 'zamereni', 'cislo_zadani__cislo', 'cislo_zadani__rocnik'] | ||||
|     inlines = [ReseniKProblemuInline] | ||||
| 
 | ||||
|     def get_inline_instances(self, request, obj=None): | ||||
|         if obj and obj.typ == Problem.TYP_ULOHA: | ||||
|             inlines = [ReseniKProblemuInline, PohadkaKProblemuInline] | ||||
|         else: | ||||
|             inlines = [ReseniKProblemuInline] | ||||
| 
 | ||||
|         return [inline(self.model, self.admin_site) for inline in inlines] | ||||
| 
 | ||||
|     def get_queryset(self, request): | ||||
|         qs = super(ProblemZadanyAdmin, self).get_queryset(request) | ||||
|  | @ -360,6 +400,24 @@ create_modeladmin(ProblemZadanyAdmin, Problem, 'ProblemZadany', verbose_name=u'P | |||
| 
 | ||||
| #admin.site.register(Problem, ProblemAdmin) | ||||
| 
 | ||||
| ### Prispevek (k tematkum) | ||||
| 
 | ||||
| class PrispevekAdminForm(forms.ModelForm): | ||||
|     text_org = forms.CharField(widget=CKEditorWidget(), required=False, | ||||
|             **field_labels(Prispevek, 'text_org')) | ||||
|     text_resitel = forms.CharField(widget=CKEditorWidget(), required=False, | ||||
|             **field_labels(Prispevek, 'text_resitel')) | ||||
| 
 | ||||
|     class Meta: | ||||
|         model = Prispevek | ||||
|         exclude = [] | ||||
| 
 | ||||
| class PrispevekAdmin(VersionAdmin): | ||||
|     form = PrispevekAdminForm | ||||
|     list_display = ['nazev', 'problem', 'reseni', 'zverejnit'] | ||||
| 
 | ||||
| admin.site.register(Prispevek, PrispevekAdmin) | ||||
| 
 | ||||
| ### Soustredeni | ||||
| 
 | ||||
| class SoustredeniAdminForm(forms.ModelForm): | ||||
|  |  | |||
							
								
								
									
										29
									
								
								seminar/migrations/0037_prispevek.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								seminar/migrations/0037_prispevek.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,29 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('seminar', '0036_add_org_to_soustredeni'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.CreateModel( | ||||
|             name='Prispevek', | ||||
|             fields=[ | ||||
|                 ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), | ||||
|                 ('nazev', models.CharField(max_length=200, verbose_name=b'N\xc3\xa1zev')), | ||||
|                 ('text_org', models.TextField(null=True, verbose_name=b'Orgovsk\xc3\xbd text', blank=True)), | ||||
|                 ('text_resitel', models.TextField(null=True, verbose_name=b'\xc5\x98e\xc5\xa1itelsk\xc3\xbd text', blank=True)), | ||||
|                 ('zverejnit', models.BooleanField(verbose_name=b'Zve\xc5\x99ejnit?')), | ||||
|                 ('problem', models.ForeignKey(verbose_name=b'Probl\xc3\xa9m', to='seminar.Problem')), | ||||
|                 ('reseni', models.OneToOneField(null=True, blank=True, to='seminar.Reseni', verbose_name=b'\xc5\x98e\xc5\xa1en\xc3\xad')), | ||||
|             ], | ||||
|             options={ | ||||
|                 'abstract': False, | ||||
|             }, | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										18
									
								
								seminar/migrations/0038_change_meta_prispevek.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								seminar/migrations/0038_change_meta_prispevek.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,18 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('seminar', '0037_prispevek'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.AlterModelOptions( | ||||
|             name='prispevek', | ||||
|             options={'verbose_name': 'P\u0159\xedsp\u011bvek k probl\xe9mu', 'verbose_name_plural': 'P\u0159\xedsp\u011bvky k probl\xe9m\u016fm'}, | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										34
									
								
								seminar/migrations/0039_pohadka.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								seminar/migrations/0039_pohadka.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,34 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
| import django.utils.timezone | ||||
| from django.conf import settings | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         migrations.swappable_dependency(settings.AUTH_USER_MODEL), | ||||
|         ('seminar', '0038_change_meta_prispevek'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.CreateModel( | ||||
|             name='Pohadka', | ||||
|             fields=[ | ||||
|                 ('id', models.AutoField(serialize=False, primary_key=True)), | ||||
|                 ('text', models.TextField(verbose_name='Text poh\xe1dky')), | ||||
|                 ('pred', models.BooleanField(default=True, verbose_name='P\u0159ed \xfalohou')), | ||||
|                 ('timestamp', models.DateTimeField(default=django.utils.timezone.now, verbose_name='Vytvo\u0159eno', editable=False, blank=True)), | ||||
|                 ('autor', models.ForeignKey(verbose_name=b'Autor poh\xc3\xa1dky', to=settings.AUTH_USER_MODEL)), | ||||
|                 ('uloha', models.ForeignKey(related_name='pohadky', verbose_name='\xdaloha', to='seminar.Problem')), | ||||
|             ], | ||||
|             options={ | ||||
|                 'ordering': ['uloha__cislo_zadani', 'uloha__kod', '-pred'], | ||||
|                 'db_table': 'seminar_pohadky', | ||||
|                 'verbose_name': 'Poh\xe1dka', | ||||
|                 'verbose_name_plural': 'Poh\xe1dky', | ||||
|             }, | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										20
									
								
								seminar/migrations/0040_pohadka_nepovinny_autor.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								seminar/migrations/0040_pohadka_nepovinny_autor.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,20 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
| from django.conf import settings | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('seminar', '0039_pohadka'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.AlterField( | ||||
|             model_name='pohadka', | ||||
|             name='autor', | ||||
|             field=models.ForeignKey(verbose_name=b'Autor poh\xc3\xa1dky', to=settings.AUTH_USER_MODEL, null=True), | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										70
									
								
								seminar/migrations/0041_konfery.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								seminar/migrations/0041_konfery.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,70 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
| import django.db.models.deletion | ||||
| import seminar.models | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('seminar', '0040_pohadka_nepovinny_autor'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.CreateModel( | ||||
|             name='Konfera', | ||||
|             fields=[ | ||||
|                 ('id', models.AutoField(serialize=False, primary_key=True)), | ||||
|                 ('nazev', models.CharField(help_text='N\xe1zev konfery', max_length=40, verbose_name='n\xe1zev konfery')), | ||||
|                 ('popis', models.TextField(help_text='Popis konfery k zobrazen\xed na webu', verbose_name='popis konfery', blank=True)), | ||||
|                 ('abstrakt', models.TextField(help_text='Abstrakt konfery tak, jak byl uveden ve sborn\xedku', verbose_name='abstrakt', blank=True)), | ||||
|                 ('org_poznamka', models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka ke konfe\u0159e(plain text)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True)), | ||||
|                 ('typ_prezentace', models.CharField(default=b'veletrh', max_length=16, verbose_name='typ prezentace', choices=[(b'veletrh', 'Veletrh (postery)'), (b'prezentace', 'Prezentace (p\u0159edn\xe1\u0161ka)')])), | ||||
|                 ('prezentace', models.FileField(help_text='Prezentace nebo fotka posteru', upload_to=seminar.models.generate_filename_konfera, verbose_name='prezentace')), | ||||
|                 ('materialy', models.FileField(help_text='Dal\u0161\xed materi\xe1ly ke konfe\u0159e zabalen\xe9 do jednoho souboru', upload_to=seminar.models.generate_filename_konfera, verbose_name='materialy')), | ||||
|                 ('organizator', models.ForeignKey(related_name='konfery', on_delete=django.db.models.deletion.SET_NULL, verbose_name='organiz\xe1tor', to='seminar.Organizator', null=True)), | ||||
|             ], | ||||
|             options={ | ||||
|                 'db_table': 'seminar_konfera', | ||||
|                 'verbose_name': 'Konfera', | ||||
|                 'verbose_name_plural': 'Konfery', | ||||
|             }, | ||||
|         ), | ||||
|         migrations.CreateModel( | ||||
|             name='Konfery_Ucastnici', | ||||
|             fields=[ | ||||
|                 ('id', models.AutoField(serialize=False, primary_key=True)), | ||||
|                 ('poznamka', models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka k \xfa\u010dasti (plain text)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True)), | ||||
|                 ('konfera', models.ForeignKey(verbose_name='konfera', to='seminar.Konfera')), | ||||
|                 ('resitel', models.ForeignKey(verbose_name='\u0159e\u0161itel', to='seminar.Resitel')), | ||||
|             ], | ||||
|             options={ | ||||
|                 'ordering': ['konfera', 'resitel'], | ||||
|                 'db_table': 'seminar_konfery_ucastnici', | ||||
|                 'verbose_name': '\xda\u010dast na konfe\u0159e', | ||||
|                 'verbose_name_plural': '\xda\u010dasti na konfe\u0159e', | ||||
|             }, | ||||
|         ), | ||||
|         migrations.AlterField( | ||||
|             model_name='problem', | ||||
|             name='typ', | ||||
|             field=models.CharField(default=b'uloha', max_length=32, verbose_name='typ probl\xe9mu', choices=[(b'uloha', '\xdaloha'), (b'tema', 'T\xe9ma'), (b'serial', 'Seri\xe1l'), (b'konfera', 'Konfera'), (b'org-clanek', 'Organiz\xe1torsk\xfd \u010dl\xe1nek'), (b'res-clanek', '\u0158e\u0161itelsk\xfd \u010dl\xe1nek')]), | ||||
|         ), | ||||
|         migrations.AddField( | ||||
|             model_name='konfera', | ||||
|             name='prispevek', | ||||
|             field=models.ForeignKey(related_name='konfery', on_delete=django.db.models.deletion.SET_NULL, verbose_name='p\u0159\xedsp\u011bvek do \u010d\xedsla', to='seminar.Problem', help_text='\xda\u010dastnick\xfd p\u0159\xedp\u011bvek o konfe\u0159e', null=True), | ||||
|         ), | ||||
|         migrations.AddField( | ||||
|             model_name='konfera', | ||||
|             name='soustredeni', | ||||
|             field=models.ForeignKey(related_name='konfery', on_delete=django.db.models.deletion.SET_NULL, verbose_name='soust\u0159ed\u011bn\xed', to='seminar.Soustredeni', null=True), | ||||
|         ), | ||||
|         migrations.AddField( | ||||
|             model_name='konfera', | ||||
|             name='ucastnici', | ||||
|             field=models.ManyToManyField(help_text='Seznam \xfa\u010dastn\xedk\u016f konfery', to='seminar.Resitel', verbose_name='\xfa\u010dastn\xedci konfery', through='seminar.Konfery_Ucastnici'), | ||||
|         ), | ||||
|     ] | ||||
|  | @ -16,7 +16,7 @@ from imagekit.processors import ResizeToFit, Transpose | |||
| 
 | ||||
| from PIL import Image | ||||
| import os | ||||
| from functools import partial | ||||
| #from functools import partial | ||||
| from cStringIO import StringIO | ||||
| from django.core.files.base import ContentFile | ||||
| 
 | ||||
|  | @ -402,12 +402,14 @@ class Problem(SeminarModelBase): | |||
|     TYP_ULOHA = 'uloha' | ||||
|     TYP_TEMA = 'tema' | ||||
|     TYP_SERIAL = 'serial' | ||||
|     TYP_KONFERA = 'konfera' | ||||
|     TYP_ORG_CLANEK = 'org-clanek' | ||||
|     TYP_RES_CLANEK = 'res-clanek' | ||||
|     TYP_CHOICES = [ | ||||
|         (TYP_ULOHA, u'Úloha'), | ||||
|         (TYP_TEMA, u'Téma'), | ||||
|         (TYP_SERIAL, u'Seriál'), | ||||
|         (TYP_KONFERA, u'Konfera'), | ||||
|         (TYP_ORG_CLANEK, u'Organizátorský článek'), | ||||
|         (TYP_RES_CLANEK, u'Řešitelský článek'), | ||||
|         ] | ||||
|  | @ -545,6 +547,10 @@ class Reseni(SeminarModelBase): | |||
| 
 | ||||
| 
 | ||||
| # PrilohaReseni method | ||||
| # TODO vyresit partial, tak aby slo migrovat | ||||
| #def generate_filename(self, filename, directory): | ||||
| # Django 1.9 podporuje partial | ||||
| 
 | ||||
| def generate_filename(self, filename): | ||||
|     clean = filename.replace('/','-').replace('\0', '') | ||||
|     datedir = timezone.now().strftime('%Y-%m') | ||||
|  | @ -553,6 +559,16 @@ def generate_filename(self, filename): | |||
|         clean) | ||||
|     return os.path.join(settings.SEMINAR_RESENI_DIR, datedir, fname) | ||||
| 
 | ||||
| def generate_filename_konfera(self, filename): | ||||
|     clean = filename.replace('/','-').replace('\0', '') | ||||
|     datedir = timezone.now().strftime('%Y-%m') | ||||
|     fname = "%s_%s" % ( | ||||
|         timezone.now().strftime('%Y-%m-%d-%H:%M'), | ||||
|         clean) | ||||
|     return os.path.join(settings.SEMINAR_KONFERY_DIR, datedir, fname) | ||||
| # TODO vyresit partial tak, aby slo migrovat | ||||
| #    return os.path.join(directory, datedir, fname) | ||||
| 
 | ||||
| 
 | ||||
| @reversion.register(ignore_duplicate_revisions=True) | ||||
| @python_2_unicode_compatible | ||||
|  | @ -580,6 +596,75 @@ class PrilohaReseni(SeminarModelBase): | |||
|         return force_unicode(self.soubor) | ||||
| 
 | ||||
| 
 | ||||
| @python_2_unicode_compatible | ||||
| class Pohadka(SeminarModelBase): | ||||
|     u"""Kus pohádky před/za úlohou v čísle""" | ||||
| 
 | ||||
|     class Meta: | ||||
|         db_table = 'seminar_pohadky' | ||||
|         verbose_name = u'Pohádka' | ||||
|         verbose_name_plural = u'Pohádky' | ||||
|         ordering = ['uloha__cislo_zadani', 'uloha__kod', '-pred'] | ||||
| 
 | ||||
|     # Interní ID | ||||
|     id = models.AutoField(primary_key=True) | ||||
| 
 | ||||
|     text = models.TextField(u'Text pohádky') | ||||
|     uloha = models.ForeignKey( | ||||
|         Problem, | ||||
|         verbose_name=u'Úloha', | ||||
|         related_name='pohadky' | ||||
|     ) | ||||
| 
 | ||||
|     # Kusů pohádky je v čísle obvykle o 1 více, než úloh. Jeden bude za úlohou | ||||
|     # místo před ní. | ||||
|     pred = models.BooleanField(u'Před úlohou', default=True) | ||||
| 
 | ||||
|     autor = models.ForeignKey( | ||||
|         settings.AUTH_USER_MODEL, | ||||
|         verbose_name="Autor pohádky", | ||||
| 
 | ||||
|         # Při nahrávání z TeXu není vyplnění vyžadováno, v adminu je | ||||
|         null=True, | ||||
|         blank=False | ||||
|     ) | ||||
| 
 | ||||
|     timestamp = models.DateTimeField( | ||||
|         u'Vytvořeno', | ||||
|         default=timezone.now, | ||||
|         blank=True, | ||||
|         editable=False | ||||
|     ) | ||||
| 
 | ||||
|     def __str__(self): | ||||
|         uryvek = self.text if len(self.text) < (50-3) else self.text[:50]+"..." | ||||
|         return force_unicode(uryvek) | ||||
| 
 | ||||
| 
 | ||||
| @reversion.register(ignore_duplicate_revisions=True) | ||||
| class Prispevek(SeminarModelBase): | ||||
|     problem = models.ForeignKey(Problem, verbose_name='Problém') # TODO autokompleet | ||||
|     nazev = models.CharField('Název', max_length=200) | ||||
|     reseni = models.OneToOneField(Reseni, verbose_name='Řešení', | ||||
|             blank = True, null = True) | ||||
|     text_org = models.TextField('Orgovský text', blank = True, null = True) | ||||
|     text_resitel = models.TextField('Řešitelský text', blank = True, null = True) | ||||
|     zverejnit = models.BooleanField('Zveřejnit?') | ||||
| 
 | ||||
|     class Meta: | ||||
|       verbose_name = 'Příspěvek k problému' | ||||
|       verbose_name_plural = 'Příspěvky k problémům' | ||||
| 
 | ||||
|     def __unicode__(self): | ||||
|       if self.reseni: | ||||
|         return force_unicode(self.nazev) + ' (' + \ | ||||
|                force_unicode(self.reseni.resitel) + ') <Problem: ' + \ | ||||
|                force_unicode(self.problem) + '>' | ||||
|       else: | ||||
|         return force_unicode(self.nazev) + ' <Problem: ' + \ | ||||
|                force_unicode(self.problem) + '>' | ||||
| 
 | ||||
| 
 | ||||
| @reversion.register(ignore_duplicate_revisions=True) | ||||
| @python_2_unicode_compatible | ||||
| class Organizator(models.Model): | ||||
|  | @ -736,69 +821,70 @@ class Soustredeni_Organizatori(models.Model): | |||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| #@reversion.register(ignore_duplicate_revisions=True) | ||||
| #@python_2_unicode_compatible | ||||
| #class Konfera(models.Model): | ||||
| #    class Meta: | ||||
| #        db_table = 'seminar_konfera' | ||||
| #        verbose_name = u'Konfera' | ||||
| #        verbose_name_plural = u'Konfery' | ||||
| #    # Interní ID | ||||
| #    id = models.AutoField(primary_key = True) | ||||
| #    nazev = models.CharField(u'název konfery', max_length=40, help_text = u'Název konfery') | ||||
| #    popis = models.TextField(u'popis konfery', blank=True, | ||||
| #        help_text=u'Popis konfery k zobrazení na webu') | ||||
| #    abstrakt = models.TextField(u'abstrakt', blank=True, | ||||
| #        help_text=u'Abstrakt konfery tak, jak byl uveden ve sborníku') | ||||
| #    organizator = models.ForeignKey(Organizator, verbose_name=u'organizátor', related_name='konfery', | ||||
| #            on_delete = models.SET_NULL, null=True) | ||||
| #    ucastnici = models.ManyToManyField(Resitel, verbose_name=u'účastníci konfery', | ||||
| #        help_text=u'Seznam účastníků konfery', through='Konfery_Ucastnici') | ||||
| #    soustredeni = models.ForeignKey(Soustredeni, verbose_name=u'soustředění', related_name='konfery', | ||||
| #            on_delete = models.SET_NULL, null=True) | ||||
| #    org_poznamka = models.TextField(u'neveřejná poznámka', blank=True, | ||||
| #        help_text=u'Neveřejná poznámka ke konfeře(plain text)') | ||||
| #    #prispevek #TODO | ||||
| #    TYP_VELETRH = 'veletrh' | ||||
| #    TYP_PREZENTACE = 'prezentace' | ||||
| #    TYP_CHOICES = [ | ||||
| #        (TYP_VELETRH, u'Veletrh (postery)'), | ||||
| #        (TYP_PREZENTACE, u'Prezentace (přednáška)'), | ||||
| #        ] | ||||
| #    typ_prezentace = models.CharField(u'typ prezentace', max_length=16, choices=TYP_CHOICES, blank=False, default=TYP_VELETRH) | ||||
| #    prezentace = models.FileField(u'prezentace',help_text = u'Prezentace nebo fotka posteru',  | ||||
| #            upload_to = partial(generate_filename,directory=settings.SEMINAR_KONFERY_DIR)) | ||||
| #    materialy = models.FileField(u'materialy',help_text = u'Další materiály ke konfeře zabalené do jednoho souboru',  | ||||
| #            upload_to = partial(generate_filename,directory=settings.SEMINAR_KONFERY_DIR)) | ||||
| # | ||||
| #    def __str__(self): | ||||
| #        return force_unicode(u"%s: (%s)" % (self.nazev, self.soustredeni)) | ||||
| # | ||||
| # | ||||
| # | ||||
| #@reversion.register(ignore_duplicate_revisions=True) | ||||
| #@python_2_unicode_compatible | ||||
| #class Konfery_Ucastnici(models.Model): | ||||
| # | ||||
| #    class Meta: | ||||
| #        db_table = 'seminar_konfery_ucastnici' | ||||
| #        verbose_name = u'Účast na konfeře' | ||||
| #        verbose_name_plural = u'Účasti na konfeře' | ||||
| #        ordering = ['konfera', 'resitel'] | ||||
| # | ||||
| #    # Interní ID | ||||
| #    id = models.AutoField(primary_key = True) | ||||
| # | ||||
| #    resitel = models.ForeignKey(Resitel, verbose_name=u'řešitel') | ||||
| # | ||||
| #    konfera = models.ForeignKey(Konfera, verbose_name=u'konfera') | ||||
| # | ||||
| #    poznamka = models.TextField(u'neveřejná poznámka', blank=True, | ||||
| #        help_text=u'Neveřejná poznámka k účasti (plain text)') | ||||
| # | ||||
| #    def __str__(self): | ||||
| #        return force_unicode(u'%s na %s' % (self.resitel, self.konfera, )) | ||||
| #        # NOTE: Poteciální DB HOG bez select_related | ||||
| @reversion.register(ignore_duplicate_revisions=True) | ||||
| @python_2_unicode_compatible | ||||
| class Konfera(models.Model): | ||||
|     class Meta: | ||||
|         db_table = 'seminar_konfera' | ||||
|         verbose_name = u'Konfera' | ||||
|         verbose_name_plural = u'Konfery' | ||||
|     # Interní ID | ||||
|     id = models.AutoField(primary_key = True) | ||||
|     nazev = models.CharField(u'název konfery', max_length=40, help_text = u'Název konfery') | ||||
|     popis = models.TextField(u'popis konfery', blank=True, | ||||
|         help_text=u'Popis konfery k zobrazení na webu') | ||||
|     abstrakt = models.TextField(u'abstrakt', blank=True, | ||||
|         help_text=u'Abstrakt konfery tak, jak byl uveden ve sborníku') | ||||
|     organizator = models.ForeignKey(Organizator, verbose_name=u'organizátor', related_name='konfery', | ||||
|             on_delete = models.SET_NULL, null=True) | ||||
|     ucastnici = models.ManyToManyField(Resitel, verbose_name=u'účastníci konfery', | ||||
|         help_text=u'Seznam účastníků konfery', through='Konfery_Ucastnici') | ||||
|     soustredeni = models.ForeignKey(Soustredeni, verbose_name=u'soustředění', related_name='konfery', | ||||
|             on_delete = models.SET_NULL, null=True) | ||||
|     org_poznamka = models.TextField(u'neveřejná poznámka', blank=True, | ||||
|         help_text=u'Neveřejná poznámka ke konfeře(plain text)') | ||||
|     prispevek = models.ForeignKey(Problem, verbose_name=u'příspěvek do čísla', related_name='konfery', | ||||
|         help_text=u'Účastnický přípěvek o konfeře',on_delete = models.SET_NULL, null=True) | ||||
|     TYP_VELETRH = 'veletrh' | ||||
|     TYP_PREZENTACE = 'prezentace' | ||||
|     TYP_CHOICES = [ | ||||
|         (TYP_VELETRH, u'Veletrh (postery)'), | ||||
|         (TYP_PREZENTACE, u'Prezentace (přednáška)'), | ||||
|         ] | ||||
|     typ_prezentace = models.CharField(u'typ prezentace', max_length=16, choices=TYP_CHOICES, blank=False, default=TYP_VELETRH) | ||||
|     prezentace = models.FileField(u'prezentace',help_text = u'Prezentace nebo fotka posteru',  | ||||
|             upload_to = generate_filename_konfera) | ||||
|     materialy = models.FileField(u'materialy',help_text = u'Další materiály ke konfeře zabalené do jednoho souboru',  | ||||
|             upload_to = generate_filename_konfera) | ||||
| 
 | ||||
|     def __str__(self): | ||||
|         return force_unicode(u"%s: (%s)" % (self.nazev, self.soustredeni)) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| @reversion.register(ignore_duplicate_revisions=True) | ||||
| @python_2_unicode_compatible | ||||
| class Konfery_Ucastnici(models.Model): | ||||
| 
 | ||||
|     class Meta: | ||||
|         db_table = 'seminar_konfery_ucastnici' | ||||
|         verbose_name = u'Účast na konfeře' | ||||
|         verbose_name_plural = u'Účasti na konfeře' | ||||
|         ordering = ['konfera', 'resitel'] | ||||
| 
 | ||||
|     # Interní ID | ||||
|     id = models.AutoField(primary_key = True) | ||||
| 
 | ||||
|     resitel = models.ForeignKey(Resitel, verbose_name=u'řešitel') | ||||
| 
 | ||||
|     konfera = models.ForeignKey(Konfera, verbose_name=u'konfera') | ||||
| 
 | ||||
|     poznamka = models.TextField(u'neveřejná poznámka', blank=True, | ||||
|         help_text=u'Neveřejná poznámka k účasti (plain text)') | ||||
| 
 | ||||
|     def __str__(self): | ||||
|         return force_unicode(u'%s na %s' % (self.resitel, self.konfera, )) | ||||
|         # NOTE: Poteciální DB HOG bez select_related | ||||
| 
 | ||||
| 
 | ||||
| @python_2_unicode_compatible | ||||
|  |  | |||
|  | @ -2,34 +2,38 @@ | |||
| 
 | ||||
| {% block content %} | ||||
| <div> | ||||
|   <h2> | ||||
|   <h1> | ||||
|     {% block nadpis1a %}{% block nadpis1b %} | ||||
|       Číslo {{ cislo }} | ||||
|     {% endblock %}{% endblock %} | ||||
|   </h2> | ||||
|   </h1> | ||||
| 
 | ||||
|   {% if cislo.pdf %} | ||||
|     <p><a href='{{ cislo.pdf.url }}'>Číslo v pdf</a> | ||||
|   {% endif %} | ||||
|   <p><a href='{{ cislo.rocnik.verejne_url }}'>Ročník {{ cislo.rocnik }}</a> | ||||
| 
 | ||||
|   <h3>Zadané problémy</h3> | ||||
|   <h2>Zadané problémy</h2> | ||||
|   <ul> | ||||
|   {% for p in v_cisle_zadane %} | ||||
|     <li>{# TODO zprovoznit odkazy, až bude na co <a href='{{ p.verejne_url }}'> #}{{ p.kod_v_rocniku }} {{ p.nazev }} {{ p.body_v_zavorce }}{# </a> #} | ||||
|     <li>{# TODO zprovoznit odkazy i pro účastníky, až bude na co #} | ||||
|       {% if user.is_staff %} | ||||
|         <a href='{{ p.verejne_url }}'>{% endif %}{{ p.kod_v_rocniku }} {{ p.nazev }} {{ p.body_v_zavorce }}{% if user.is_staff %}</a>{% endif %} | ||||
|   {% endfor %} | ||||
|   </ul> | ||||
| 
 | ||||
|   <h3>Řešené problémy</h3> | ||||
|   <h2>Řešené problémy</h2> | ||||
|   <ul> | ||||
|   {% for p in resene_problemy %} | ||||
|     <li>{# TODO zprovoznit odkazy, až bude na co <a href='{{ p.verejne_url }}'> #}{{ p.kod_v_rocniku }} {{ p.nazev }} {{ p.body_v_zavorce }}{# </a> #} | ||||
|     <li>{# TODO zprovoznit odkazy i pro účastníky, až bude na co #} | ||||
|       {% if user.is_staff %} | ||||
|         <a href='{{ p.verejne_url }}'>{% endif %}{{ p.kod_v_rocniku }} {{ p.nazev }} {{ p.body_v_zavorce }}{% if user.is_staff %}</a>{% endif %} | ||||
|   {% endfor %} | ||||
|   </ul> | ||||
| 
 | ||||
|   {% if user.is_staff %} | ||||
|       <div class="mam-org-only"> | ||||
|         <h3> Orgovské odkazy </h3> | ||||
|         <h2> Orgovské odkazy </h2> | ||||
|         <ul> | ||||
|           <li><a href="obalky.pdf">Obálky (PDF)</a></li> | ||||
|           <li><a href="tituly.tex">Tituly (TeX)</a></li> | ||||
|  | @ -40,11 +44,11 @@ | |||
|   {% endif %} | ||||
| 
 | ||||
|   {% if cislo.verejna_vysledkovka %} | ||||
|   <h3>Výsledkovka</h3> | ||||
|   <h2>Výsledkovka</h2> | ||||
|   {% else %} | ||||
|     {% if user.is_staff %} | ||||
|       <div class='mam-org-only'> | ||||
|       <h3>Výsledkovka (neveřejná)</h3> | ||||
|       <h2>Výsledkovka (neveřejná)</h2> | ||||
|     {% endif %} | ||||
|   {% endif %} | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										24
									
								
								seminar/templates/seminar/archiv/prispevek.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								seminar/templates/seminar/archiv/prispevek.html
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,24 @@ | |||
| {% extends "seminar/archiv/base_temata.html" %} | ||||
| 
 | ||||
| {% block title %} | ||||
|   {{prispevek.nazev}} | ||||
| {% endblock title %} | ||||
| 
 | ||||
| {% block content %} | ||||
|   {% if not prispevek.zverejnit %}<div class="mam-org-only">{% endif %} | ||||
|     <h1>{{prispevek.nazev}}</h1> | ||||
|     <h2>{{titul}} {{prispevek.reseni.resitel}}</h2> | ||||
|     <h3>Příspěvek k tématu <a href="..">{{prispevek.problem.nazev}}</a></h3> | ||||
|     {% if prispevek.reseni.body %} | ||||
|       <div class="body">({{prispevek.reseni.body}} b)</div> | ||||
|     {% endif %} | ||||
| 
 | ||||
|     {% if prispevek.text_org %} | ||||
|     <div class="org-text">{% autoescape off %}{{prispevek.text_org}}{% endautoescape %}</div> | ||||
|       {% endif %} | ||||
|    | ||||
|     {% if prispevek.text_resitel %} | ||||
|       {% autoescape off %}{{prispevek.text_resitel}}{% endautoescape %} | ||||
|     {% endif %} | ||||
|   {% if not prispevek.zverejnit %}</div>{% endif %} | ||||
| {% endblock content %} | ||||
|  | @ -10,10 +10,10 @@ | |||
|   {% if user.is_staff %} | ||||
|   <div class='mam-org-only'> | ||||
| 
 | ||||
|     <h3>Text - org</h3> | ||||
|     <h2>Text - org</h2> | ||||
|     {{ problem.text_org |safe }} | ||||
| 
 | ||||
|     <h3>Diskuse - org</h3> | ||||
|     <h2>Diskuse - org</h2> | ||||
|     {% render_comment_list for object %} | ||||
|     {% render_comment_form for object %} | ||||
| 
 | ||||
|  |  | |||
|  | @ -3,12 +3,12 @@ | |||
| {% block problem %} | ||||
|   {% if problem.cislo_zadani %} | ||||
| 
 | ||||
|     <h2> | ||||
|     <h1> | ||||
|       {{ problem.nazev_typu }}: | ||||
|       {% block nadpis1a %}{% block nadpis1b %} | ||||
|         {{ problem.nazev }} | ||||
|       {% endblock %}{% endblock %} | ||||
|     </h2> | ||||
|     </h1> | ||||
| 
 | ||||
|     <div class='problem-autori'> | ||||
|     {% if problem.typ == 'res-clanek' %} | ||||
|  | @ -30,7 +30,7 @@ | |||
| 
 | ||||
|   {% else %} | ||||
|     {# TODO ? #} | ||||
|     <h2>Problém {{ problem.nazev }}</h2> | ||||
|     <h1>Problém {{ problem.nazev }}</h1> | ||||
|   {% endif %} | ||||
| 
 | ||||
|   {{ problem.text_zadani |safe }} | ||||
|  |  | |||
|  | @ -1,11 +1,11 @@ | |||
| {% extends "seminar/archiv/problem.html" %} | ||||
| 
 | ||||
| {% block problem %} | ||||
|     <h2> | ||||
|     <h1> | ||||
|       {% block nadpis1a %}{% block nadpis1b %} | ||||
|         {{ problem.nazev_typu }} {{ problem.kod_v_rocniku }}: {{ problem.nazev }} {{ problem.body_v_zavorce }} | ||||
|       {% endblock %}{% endblock %} | ||||
|     </h2> | ||||
|     </h1> | ||||
|   {% if problem.cislo_zadani %} | ||||
|     <p>Zadáno v čísle <a href='{{ problem.cislo_zadani.verejne_url }}'>{{ problem.cislo_zadani.kod }}</a>. | ||||
|   {% endif %} | ||||
|  | @ -13,10 +13,10 @@ | |||
|     <p>Řešeno v čísle <a href='{{ problem.cislo_reseni.verejne_url }}'>{{ problem.cislo_reseni.kod }}</a>. | ||||
|   {% endif %} | ||||
| 
 | ||||
|   <h3>Zadání</h3> | ||||
|   <h2>Zadání</h2> | ||||
|   {{ problem.text_zadani |safe }} | ||||
|   {% if problem.text_reseni %} | ||||
|     <h3>Řešení</h3> | ||||
|     <h2>Řešení</h2> | ||||
|     {{ problem.text_reseni |safe }} | ||||
|   {% endif %} | ||||
| 
 | ||||
|  |  | |||
|  | @ -2,11 +2,11 @@ | |||
| 
 | ||||
| {% block content %} | ||||
| <div> | ||||
|   <h2> | ||||
|   <h1> | ||||
|     {% block nadpis1a %}{% block nadpis1b %} | ||||
|       Ročník {{ rocnik.roman }} | ||||
|     {% endblock %}{% endblock %} | ||||
|   </h2> | ||||
|   </h1> | ||||
| 
 | ||||
|   <p>Ročník číslo {{ rocnik.rocnik }} ({{ rocnik.prvni_rok }}/{{ rocnik.druhy_rok }}) | ||||
| 
 | ||||
|  | @ -20,7 +20,7 @@ | |||
|   </ul> | ||||
| 
 | ||||
|   {% if temata_v_rocniku %} | ||||
|     <h3>Témata</h3> | ||||
|     <h2>Témata</h2> | ||||
|     <ul> | ||||
|     {% for tema in temata_v_rocniku %} | ||||
|       <li>{# TODO zprovoznit odkaz až bude na co <a href="{{ tema.verejne_url }}"> #}{{ tema.kod_v_rocniku }}: {{ tema.nazev }}{# TODO </a> #} | ||||
|  | @ -29,13 +29,13 @@ | |||
|   {% endif %} | ||||
| 
 | ||||
|   {% if vysledkovka %} | ||||
|     <h3>Výsledková listina</h3> | ||||
|     <h2>Výsledková listina</h2> | ||||
|     {% include "seminar/vysledkovka_rocnik.html" %} | ||||
|   {% endif %} | ||||
| 
 | ||||
|   {% if user.is_staff and vysledkovka_s_neverejnymi %} | ||||
|     <div class='mam-org-only'> | ||||
|     <h3>Výsledková listina včetně neveřejných bodů</h3> | ||||
|     <h2>Výsledková listina včetně neveřejných bodů</h2> | ||||
|       {% with vysledkovka_s_neverejnymi as vysledkovka %} | ||||
|         {% include "seminar/vysledkovka_rocnik.html" %} | ||||
|       {% endwith %} | ||||
|  |  | |||
|  | @ -1,17 +1,17 @@ | |||
| {% extends "seminar/archiv/base_temata.html" %} | ||||
| 
 | ||||
| {% block content %} | ||||
|   <h2> | ||||
|   <h1> | ||||
|     {% block nadpis1a %}{% block nadpis1b %} | ||||
|       Archiv témat  | ||||
|     {% endblock %}{% endblock%} | ||||
|   </h2> | ||||
|   </h1> | ||||
| 
 | ||||
|   {% for tema in object_list %} | ||||
|   {% with tema.cislo_zadani.rocnik.rocnik as rocnik %} | ||||
|     {% ifchanged rocnik %} | ||||
|       {% if not forloop.first %}</ul>{% endif %} | ||||
|       <h3>{{ rocnik }}. ročník</h3> | ||||
|       <h2>{{ rocnik }}. ročník</h2> | ||||
|       <ul> | ||||
|     {% endifchanged %} | ||||
|         <li> | ||||
|  |  | |||
|  | @ -10,17 +10,17 @@ | |||
| 
 | ||||
| {% block content %} | ||||
| 
 | ||||
| <h2> | ||||
| <h1> | ||||
| {% block nadpis1a %}{% block nadpis1b %} | ||||
| Řešitelské články | ||||
| {% endblock %}{% endblock %} | ||||
| </h2> | ||||
| </h1> | ||||
| 
 | ||||
| {% for clanek in object_list %} | ||||
| {% with clanek.cislo_zadani.rocnik.rocnik as rocnik %} | ||||
|   {% ifchanged rocnik %} | ||||
|     {% if not forloop.first %}</ul>{% endif %} | ||||
|     <h3>{{ rocnik }}. ročník</h3> | ||||
|     <h2>{{ rocnik }}. ročník</h2> | ||||
|     <ul> | ||||
|   {% endifchanged %} | ||||
|       <li> | ||||
|  |  | |||
|  | @ -24,13 +24,13 @@ | |||
|     <br> | ||||
|   {% endif %} | ||||
|   {% for org in object_list %} | ||||
|     <h2> | ||||
|     <h1> | ||||
|     {{org.user.first_name}} | ||||
|     {% if org.prezdivka %} | ||||
|       „{{org.prezdivka}}“ | ||||
|     {% endif %} | ||||
|     {{org.user.last_name}} | ||||
|     </h2> | ||||
|     </h1> | ||||
|     <table> | ||||
|     <tr> | ||||
|     <td> | ||||
|  |  | |||
|  | @ -3,6 +3,9 @@ | |||
| <div> | ||||
|   {% if not novinka.zverejneno and user.is_staff %} | ||||
|   <div class="mam-org-only"> | ||||
|     <ul> | ||||
|       <li><a href="/admin/seminar/novinky/{{novinka.pk}}">Upravit novinku</a> | ||||
|     </ul> | ||||
|   {% endif %} | ||||
|   {% if novinka.zverejneno or user.is_staff %} | ||||
|   {# datum #} | ||||
|  |  | |||
|  | @ -1,11 +1,11 @@ | |||
| {% load staticfiles %} | ||||
| 
 | ||||
| {% block content %} | ||||
|   <h2> | ||||
|   <h1> | ||||
|     {% block nadpis1a %}{% block nadpis1b %} | ||||
|       Tady se pracuje | ||||
|     {% endblock %}{% endblock %} | ||||
|   </h2> | ||||
|   </h1> | ||||
| 
 | ||||
|   <p> | ||||
|     Na této stránce velmi intenzivně pracujeme. | ||||
|  |  | |||
|  | @ -14,10 +14,6 @@ | |||
| {% endblock %}{% endblock %} | ||||
| 
 | ||||
| {% block content %} | ||||
| <em> | ||||
|   Na galeriích ze soustředění a dalších informacích ještě pracujeme. | ||||
| </em><br><br> | ||||
| 
 | ||||
|   {# Projdi vsechna soustredeni #} | ||||
|   {% for soustredeni in object_list %} | ||||
|     {# Kdyz je verejne -> zobraz #} | ||||
|  | @ -27,10 +23,10 @@ | |||
|         <!--Groups of user: {{user.groups.all}} <br>--> | ||||
|       {% endif %} | ||||
|       {# misto soustredeni TODO upravit#} | ||||
|       <h2> | ||||
|       <h1> | ||||
| 	    {{soustredeni.get_typ_display}} | ||||
| 	    {{soustredeni.misto}} | ||||
|       </h2> | ||||
|       </h1> | ||||
|       <ul> | ||||
|         <li> | ||||
|           {{soustredeni.datum_zacatku}} – {{soustredeni.datum_konce}} | ||||
|  | @ -62,7 +58,7 @@ | |||
|       {% if user.is_staff %} | ||||
|       <div class="mam-org-only"> | ||||
|         {# Účastníci #} | ||||
|         <h3>Soustředění se zúčastnili tito účastníci:</h3> | ||||
|         <h2>Soustředění se zúčastnili tito účastníci:</h2> | ||||
|         <p> | ||||
|         {% for i in soustredeni.soustredeni_ucastnici_set.all %} | ||||
|           {{i.resitel}}{% if forloop.last %}.{% else %},{% endif %} | ||||
|  | @ -70,7 +66,7 @@ | |||
|           Nic! | ||||
|         {% endfor %} | ||||
|         </p> | ||||
|         <h3>Soustředění se účastnili tito organizátoři:</h3> | ||||
|         <h2>Soustředění se účastnili tito organizátoři:</h2> | ||||
|         <p> | ||||
|         {% for i in soustredeni.soustredeni_organizatori_set.all %} | ||||
|           {{i.organizator}}{% if forloop.last %}.{% else %},{% endif %} | ||||
|  |  | |||
|  | @ -2,11 +2,11 @@ | |||
| 
 | ||||
| {% block content %} | ||||
| 
 | ||||
|   <h2> | ||||
|   <h1> | ||||
|     {% block nadpis1a %}{% block nadpis1b %} | ||||
|     Archiv novinek | ||||
|     {% endblock %}{% endblock %} | ||||
|   </h2> | ||||
|   </h1> | ||||
| 
 | ||||
|   {% include 'seminar/novinky.html' %} | ||||
| 
 | ||||
|  |  | |||
|  | @ -2,13 +2,13 @@ | |||
| 
 | ||||
| {% block content %} | ||||
| <div> | ||||
|   <h2> | ||||
|   <h1> | ||||
|     {% block nadpis1a %}{% block nadpis1b %} | ||||
|       Stav databáze | ||||
|     {% endblock %}{% endblock %} | ||||
|   </h2> | ||||
|   </h1> | ||||
| 
 | ||||
|   <h3>Řešitelé</h3> | ||||
|   <h2>Řešitelé</h2> | ||||
| 
 | ||||
|   <div>Řešitelů: {{ resitele |length}} ({{ muzi |length}} mužů, {{ zeny |length}} žen)</div> | ||||
|   <div>Křestní jména mužů:</div> | ||||
|  | @ -16,9 +16,9 @@ | |||
|   <div>Křestní jména žen:</div> | ||||
|   <p><code>{% for n, c in jmena_zen.items %}{{ n }} ({{ c }}), {% endfor %}</code> | ||||
| 
 | ||||
|   <h3>Nastavení</h3> | ||||
|   <h2>Nastavení</h2> | ||||
| 
 | ||||
|   <h3>Problémy</h3> | ||||
|   <h2>Problémy</h2> | ||||
|   {% for p in problemy %} | ||||
|   <div>{{ p |safe }}</div> | ||||
|   {% endfor %} | ||||
|  |  | |||
|  | @ -6,11 +6,11 @@ | |||
| 
 | ||||
| {% block content %} | ||||
|   {# Uvitaci text #} | ||||
|   <h2> | ||||
|   <h1> | ||||
|     {% block nadpis1a %}{% block nadpis1b %} | ||||
|       Vítej! | ||||
|     {% endblock %}{% endblock %} | ||||
|   </h2> | ||||
|   </h1> | ||||
| <p> | ||||
| M&M je korespondeční seminář. Několikrát do roka zdarma vydáváme časopis a v něm zajímavé podněty k přemýšlení. Ty na ně můžeš reagovat.<br> | ||||
|   | ||||
|  | @ -26,7 +26,7 @@ M&M je korespondeční seminář. Několikrát do roka zdarma vydáváme ča | |||
|   {% endif %} | ||||
| 
 | ||||
|   {# Novinky #} | ||||
|   <h2>Novinky</h2> | ||||
|   <h1>Novinky</h1> | ||||
|   {% include 'seminar/novinky.html' %} | ||||
| 
 | ||||
|   <a href='/stare-novinky/'>Archiv novinek</a> | ||||
|  | @ -59,7 +59,7 @@ M&M je korespondeční seminář. Několikrát do roka zdarma vydáváme ča | |||
| 
 | ||||
| </map> | ||||
|   <span class="zjistit_vic"> | ||||
|     <h3><a href="/co-je-MaM/uvod/">Zjistit víc!</a></h3> | ||||
|     <h2><a href="/co-je-MaM/uvod/">Zjistit víc!</a></h2> | ||||
|   </span> | ||||
| </div> | ||||
| 
 | ||||
|  |  | |||
|  | @ -10,11 +10,11 @@ | |||
| {% block content %} | ||||
| {% with nastaveni.aktualni_rocnik as rocnik %} | ||||
| 
 | ||||
|   <h2> | ||||
|   <h1> | ||||
|     {% block nadpis1a %}{% block nadpis1b %} | ||||
|       Výsledky | ||||
|     {% endblock %}{% endblock %} | ||||
|   </h2> | ||||
|   </h1> | ||||
| 
 | ||||
|   {% if vysledkovka %} | ||||
|     {% include "seminar/vysledkovka_rocnik.html" %} | ||||
|  | @ -24,7 +24,7 @@ | |||
| 
 | ||||
|   {% if user.is_staff and vysledkovka_s_neverejnymi %} | ||||
|     <div class='mam-org-only'> | ||||
|     <h2>Výsledky včetně neveřejných</h2> | ||||
|     <h1>Výsledky včetně neveřejných</h1> | ||||
|     {% with vysledkovka_s_neverejnymi as vysledkovka %} | ||||
|       {% include "seminar/vysledkovka_rocnik.html" %} | ||||
|     {% endwith %} | ||||
|  |  | |||
|  | @ -32,7 +32,7 @@ | |||
|     {% for sada in jednorazove_problemy %} | ||||
|       {# podnadpisy, kdyz neni zakomentuje se nadpis #} | ||||
|       {% if not sada %}<!--{% endif %} | ||||
|       <h3>{% cycle 'Úlohy' 'Seriál' %}</h3> | ||||
|       <h2>{% cycle 'Úlohy' 'Seriál' %}</h2> | ||||
|       {% if not sada %}-->{% endif %} | ||||
|       {# publikace jednotlivych zadani #} | ||||
|       {% for problem in sada %} | ||||
|  | @ -41,7 +41,7 @@ | |||
|         {% endfor %} | ||||
| 
 | ||||
|         {# TODO použít {{problem.kod_v_rocniku}} ? vrací 4.u1 místo 4.1 #} | ||||
|         <h4>{{problem.cislo_zadani.cislo}}.{{problem.kod}} {{problem.nazev}} {{ problem.body_v_zavorce }}</h4> | ||||
|         <h3>{{problem.cislo_zadani.cislo}}.{{problem.kod}} {{problem.nazev}} {{ problem.body_v_zavorce }}</h3> | ||||
|         {% autoescape off %}{{problem.text_zadani}}{% endautoescape %} | ||||
|         <hr> | ||||
|       {% endfor %} | ||||
|  | @ -51,11 +51,11 @@ | |||
| 
 | ||||
| {% if user.is_staff and not verejne%}</div>{% endif %} | ||||
| {% else %} | ||||
|   <h3>Aktuálně nejsou zveřejněny žádné úlohy</h3> | ||||
|   <h2>Aktuálně nejsou zveřejněny žádné úlohy</h2> | ||||
| {% endif %} | ||||
| 
 | ||||
| 
 | ||||
|     <h3>Témata</h3> | ||||
|     <h2>Témata</h2> | ||||
|       <ul> | ||||
|       {% for problem in temata %} | ||||
|         {# TODO použít {{problem.kod_v_rocniku}} ? vrací t4 místo 4 #} | ||||
|  |  | |||
|  | @ -10,11 +10,11 @@ | |||
| {% block content %} | ||||
| {% with nastaveni.aktualni_rocnik as ar %} | ||||
| <div> | ||||
|   <h2> | ||||
|   <h1> | ||||
|     {% block nadpis1a %}{% block nadpis1b %} | ||||
|       Témata | ||||
|     {% endblock %}{% endblock %} | ||||
|   </h2> | ||||
|   </h1> | ||||
| 
 | ||||
|   <p> | ||||
|     Témata jsou hlavním obsahem časopisu M&M. Obvykle představují | ||||
|  | @ -30,6 +30,7 @@ | |||
|     Letos jsme pro tebe připravili tato témata: | ||||
|   </p> | ||||
|   {% endif %} | ||||
|   {# seznam temat s odkazy doprostred teto stranky #} | ||||
|   <ul> | ||||
|   {% for problem in temata %} | ||||
|     {# TODO použít {{problem.kod_v_rocniku}} ? vrací t4 místo 4 #} | ||||
|  | @ -38,11 +39,35 @@ | |||
|     </li> | ||||
|   {% endfor %} | ||||
|   </ul> | ||||
|   {# nahled kazdeho tematu #} | ||||
|   {% for problem in temata %} | ||||
|     {# TODO použít {{problem.kod_v_rocniku}} ? vrací t4 místo 4 #} | ||||
|     <a name="t{{problem.kod}}"></a> | ||||
|     <a href="{{problem.verejne_url}}"><h3>Téma {{problem.kod}}: {{problem.nazev}}</h3></a> | ||||
|     <h2>Téma {{problem.kod}}: {{problem.nazev}}</h2> | ||||
|     {% autoescape off %}{{problem.text_zadani}}{% endautoescape %} | ||||
|     {# kdyz je reseni pridej odkaz na samostatnou stranku s tematem #} | ||||
|     {% if problem.text_reseni %} | ||||
|     <p><a href="{{problem.verejne_url}}">Více</a></p> | ||||
|     {% else %} | ||||
|     <p><a href="{{problem.verejne_url}}">Stejně</a></p> | ||||
|     {% endif%} | ||||
|     {# prime odkazy na prispevky #} | ||||
|     {% if problem.prispevky %} | ||||
|     <h3> K tématu přišly a zveřejnili jsme následující příspěvky</h3> | ||||
|       <div class="seznam_prispeveku"> | ||||
|         <ul> | ||||
|           {% for prispevek in problem.prispevky %} | ||||
|             {% if not prispevek.zverejnit %}<div class=mam-org-only>{% endif %} | ||||
|               <li><a href="{{problem.verejne_url}}{{prispevek.id}}"> | ||||
|                   {{prispevek.nazev}}, | ||||
|                   {{prispevek.reseni.resitel}} | ||||
|                   ({{prispevek.reseni.body}} b) | ||||
|                   </a> | ||||
|             {% if not prispevek.zverejnit %}</div>{% endif %} | ||||
|           {% endfor %} | ||||
|         </ul> | ||||
|       </div> | ||||
|     {% endif %} | ||||
|     <hr> | ||||
|   {% empty %} | ||||
|     Aktuálně nejsou zadána žádná témata k řešení. | ||||
|  |  | |||
|  | @ -4,38 +4,49 @@ from django.contrib.auth.decorators import user_passes_test | |||
| from . import views, export | ||||
| from utils import staff_member_required | ||||
| from prednasky.views import newPrednaska, Prednaska_hotovo | ||||
| from django.views.generic.base import RedirectView | ||||
| 
 | ||||
| staff_member_required = user_passes_test(lambda u: u.is_staff) | ||||
| 
 | ||||
| urlpatterns = [ | ||||
|     # prednasky | ||||
|     url(r'^prednasky/$', newPrednaska), | ||||
|     url(r'^prednasky/hotovo$', Prednaska_hotovo), | ||||
|     #url(r'^prednasky/$', newPrednaska), | ||||
|     #url(r'^prednasky/hotovo$', Prednaska_hotovo), | ||||
| 
 | ||||
|     # REDIRECTy | ||||
|     url(r'^jak-resit/$', RedirectView.as_view(url='/co-je-MaM/jak-resit/')), | ||||
| 
 | ||||
|     # Organizatori | ||||
|     url(r'^co-je-MaM/organizatori/$', views.CojemamOrganizatoriView.as_view(), name='organizatori'), | ||||
|     url(r'^co-je-MaM/organizatori/organizovali/$', views.CojemamOrganizatoriStariView.as_view(), name='stari_organizatori'), | ||||
| 
 | ||||
|     # Archiv | ||||
|     url(r'^archiv/cisla/$', views.CislaView.as_view()), | ||||
|     url(r'^archiv/temata/$', views.ArchivTemataView.as_view()), | ||||
| 
 | ||||
|     url(r'^rocnik/(?P<rocnik>\d+)/$', views.RocnikView.as_view(), name='seminar_rocnik'), | ||||
|     url(r'^cislo/(?P<rocnik>\d+)\.(?P<cislo>[0-9-]+)/$', views.CisloView.as_view(), name='seminar_cislo'), | ||||
|     url(r'^problem/(?P<pk>\d+)/$', views.ProblemView.as_view(), name='seminar_problem'), | ||||
|     url(r'^problem/(?P<pk>\d+)/(?P<prispevek>\d+)/$', views.PrispevekView.as_view(), name='seminar_problem_prispevek'), | ||||
| 
 | ||||
|     # Soustredeni | ||||
|     url(r'^soustredeni/probehlo/$', views.SoustredeniListView.as_view(), | ||||
|         name = 'seminar_seznam_soustredeni'), | ||||
|     url(r'^soustredeni/probehlo/(?P<soustredeni>\d+)/$', views.SoustredeniView.as_view(), name='seminar_soustredeni'), | ||||
|     url(r'^soustredeni/(?P<soustredeni>\d+)/fotogalerie/', include('galerie.urls')), | ||||
| 
 | ||||
|     # Zadani | ||||
|     url(r'^zadani/aktualni/$', views.AktualniZadaniView, name='seminar_aktualni_zadani'), | ||||
|     url(r'^zadani/temata/$', views.ZadaniTemataView, name='seminar_temata'), | ||||
|     url(r'^zadani/vysledkova-listina/$', views.ZadaniAktualniVysledkovkaView, name='seminar_vysledky'), | ||||
|     url(r'^$', views.TitulniStranaView.as_view(), name='titulni_strana'), | ||||
|     url(r'^stare-novinky/$', views.StareNovinkyView.as_view(), name='stare_novinky'), | ||||
| 
 | ||||
|     # Clanky | ||||
|     url(r'^clanky/resitel/$', views.ClankyResitelView.as_view(), name='clanky_resitel'), | ||||
|     url(r'^clanky/org/$', views.ClankyOrganizatorView.as_view(), name='clanky_organizator'), | ||||
| 
 | ||||
|     # Aesop | ||||
|     url(r'^aesop-export/mam-rocnik-(?P<prvni_rok>\d+)\.csv$', export.ExportRocnikView.as_view(), name='seminar_export_rocnik'), | ||||
|     url(r'^aesop-export/mam-sous-(?P<datum_zacatku>[\d-]+)\.csv$', export.ExportSousView.as_view(), name='seminar_export_sous'), | ||||
|     url(r'^aesop-export/index.csv$', export.ExportIndexView.as_view(), name='seminar_export_index'), | ||||
|  | @ -52,6 +63,11 @@ urlpatterns = [ | |||
|         staff_member_required(views.StavDatabazeView), name='stav_databaze'), | ||||
|     url(r'^cislo/(?P<rocnik>\d+).(?P<cislo>[0-9-]+)/obalkovani$', | ||||
|         staff_member_required(views.obalkovaniView), name='seminar_cislo_resitel_obalkovani'), | ||||
|     url(r'^cislo/(?P<rocnik>\d+).(?P<cislo>[0-9-]+)/tex-download.json$', | ||||
|         staff_member_required(views.texDownloadView), name='seminar_tex_download'), | ||||
|     url(r'^soustredeni/(?P<soustredeni>\d+)/obalky.pdf', | ||||
|         staff_member_required(views.soustredeniObalkyView), name='seminar_soustredeni_obalky'), | ||||
| 
 | ||||
|     url(r'^tex-upload/login/$', views.LoginView, name='seminar_login'), | ||||
|     url(r'^tex-upload/$', staff_member_required(views.texUploadView), name='seminar_tex_upload'), | ||||
| ] | ||||
|  |  | |||
							
								
								
									
										264
									
								
								seminar/views.py
									
									
									
									
									
								
							
							
						
						
									
										264
									
								
								seminar/views.py
									
									
									
									
									
								
							|  | @ -1,15 +1,17 @@ | |||
| # coding:utf-8 | ||||
| 
 | ||||
| from django.shortcuts import get_object_or_404, render | ||||
| from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden | ||||
| from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, JsonResponse | ||||
| from django.core.urlresolvers import reverse | ||||
| from django.core.exceptions import PermissionDenied, ObjectDoesNotExist | ||||
| from django.views import generic | ||||
| from django.utils.translation import ugettext as _ | ||||
| from django.http import Http404 | ||||
| from django.db.models import Q | ||||
| from django.views.decorators.csrf import ensure_csrf_cookie | ||||
| from django.contrib.auth import authenticate, login | ||||
| 
 | ||||
| from .models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni, Organizator, Resitel, Novinky, Soustredeni_Ucastnici | ||||
| from .models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni, Organizator, Resitel, Novinky, Soustredeni_Ucastnici, Pohadka, Prispevek | ||||
| from .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva | ||||
| from . import utils | ||||
| 
 | ||||
|  | @ -21,6 +23,10 @@ import shutil | |||
| import os | ||||
| from django.conf import settings | ||||
| import unicodedata | ||||
| import json | ||||
| import traceback | ||||
| import sys | ||||
| 
 | ||||
| 
 | ||||
| def verejna_temata(rocnik): | ||||
|     """Vrací queryset zveřejněných témat v daném ročníku. | ||||
|  | @ -45,9 +51,15 @@ def AktualniZadaniView(request): | |||
| 
 | ||||
| def ZadaniTemataView(request): | ||||
|     nastaveni = get_object_or_404(Nastaveni) | ||||
|     temata = verejna_temata(nastaveni.aktualni_rocnik) | ||||
|     for t in temata: | ||||
|         if request.user.is_staff: | ||||
|             t.prispevky = t.prispevek_set.filter(problem=t) | ||||
|         else: | ||||
|             t.prispevky = t.prispevek_set.filter(problem=t, zverejnit=True) | ||||
|     return render(request, 'seminar/zadani/Temata.html', | ||||
|         { | ||||
|             'temata': verejna_temata(nastaveni.aktualni_rocnik) | ||||
|             'temata': temata, | ||||
|         } | ||||
|     ) | ||||
| 
 | ||||
|  | @ -241,6 +253,45 @@ class ProblemView(generic.DetailView): | |||
|             context['reseni'] = Reseni.objects.filter(problem=context['problem']).select_related('resitel').order_by('resitel__prijmeni') | ||||
|         return context | ||||
| 
 | ||||
| class PrispevekView(generic.DetailView): | ||||
|     model = Prispevek | ||||
|     template_name = 'seminar/archiv/prispevek.html' | ||||
|      | ||||
|     # Vlastni ziskavani objektu z databaze podle prispevku | ||||
|     # pokud je prispevek neverejny zobrazi se jenom orgum | ||||
|     def get_object(self, queryset=None): | ||||
|         if queryset is None: | ||||
|             queryset = self.get_queryset() | ||||
|         problem_arg = self.kwargs.get('pk') | ||||
|         prispevek_arg = self.kwargs.get('prispevek') | ||||
|         queryset = queryset.filter(pk=prispevek_arg) | ||||
| 
 | ||||
|         try: | ||||
|             obj = queryset.get() | ||||
|         except queryset.model.DoesNotExist: | ||||
|             raise Http404(_("No %(verbose_name)s found matching the query") % | ||||
|                           {'verbose_name': queryset.model._meta.verbose_name}) | ||||
| 
 | ||||
|         if self.request.user.is_staff or obj.zverejnit: | ||||
|             return obj | ||||
|         else: | ||||
|             raise Http404() | ||||
|      | ||||
|     def get_context_data(self, **kwargs): | ||||
|         context = super(PrispevekView, self).get_context_data(**kwargs) | ||||
|         # snaho o ziskani titulu | ||||
|         titul = '' | ||||
|         try: | ||||
|             resitel = context['prispevek'].reseni.resitel | ||||
|             cislo = context['prispevek'].reseni.cislo_body | ||||
|             body = VysledkyKCisluOdjakziva.objects.get(resitel=resitel, | ||||
|                                                        cislo=cislo).body | ||||
|             titul = resitel.get_titul(body) | ||||
|         except: | ||||
|             pass | ||||
|         context['titul'] = titul | ||||
|         return context | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| class RadekVysledkovky(object): | ||||
|  | @ -318,7 +369,7 @@ class CisloView(generic.DetailView): | |||
|         # za každé řešení doplníme k příslušnému řešiteli a úloze body | ||||
|         for r in reseni: | ||||
|            vysledky_resitele[r.resitel.id].body_ulohy[problem_index[r.problem.id]] = r.body | ||||
|                  | ||||
| 
 | ||||
|         context['vysledkovka'] = vysledkovka | ||||
|         context['problemy'] = problemy | ||||
|         context['v_cisle_zadane'] = v_cisle_zadane | ||||
|  | @ -360,9 +411,9 @@ def aktualniResitele(rocnik): | |||
|     return Resitel.objects.filter(rok_maturity__gt = letos.prvni_rok) | ||||
| #   # ALERT: pokud nekdo nema vypleny rok maturity, tak neni aktualni, protoze Karel Tesar a jini | ||||
| #    return Resitel.objects.filter(Q(rok_maturity__gt = letos.prvni_rok)|Q(rok_maturity = None)) | ||||
|      | ||||
| # Vraci QuerySet aktivnich resitelu =  | ||||
| # jeste neodmaturovali &&  | ||||
| 
 | ||||
| # Vraci QuerySet aktivnich resitelu = | ||||
| # jeste neodmaturovali && | ||||
| # (pokud je aktualni cislo mensi nez 3, pak (letos || loni) neco poslali | ||||
| # jinak letos neco poslali) | ||||
| def aktivniResitele(rocnik,cislo): | ||||
|  | @ -370,11 +421,11 @@ def aktivniResitele(rocnik,cislo): | |||
|     loni = CisloObalkyStruct() | ||||
| 
 | ||||
|     aktualni_resitele = aktualniResitele(rocnik) | ||||
|      | ||||
| 
 | ||||
|     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)  | ||||
|     loni.cisla = Cislo.objects.filter(rocnik=loni.rocnik) | ||||
|     if int(cislo) > 3: | ||||
|         problemy = Problem.objects.filter(cislo_zadani = letos.cisla) | ||||
|     else: | ||||
|  | @ -382,7 +433,7 @@ def aktivniResitele(rocnik,cislo): | |||
|     resitele = aktualni_resitele.filter(reseni = Reseni.objects.filter(problem=problemy)).distinct() | ||||
| 
 | ||||
|     return resitele | ||||
|      | ||||
| 
 | ||||
| 
 | ||||
| def cisloObalkyView(request,rocnik,cislo): | ||||
|     return obalkyView(request,aktivniResitele(rocnik,cislo)) | ||||
|  | @ -408,11 +459,22 @@ def obalkovaniView(request, rocnik, cislo): | |||
|     rocnik = Rocnik.objects.get(rocnik=rocnik) | ||||
|     cislo = Cislo.objects.get(rocnik=rocnik, cislo=cislo) | ||||
| 
 | ||||
|     reseni = Reseni.objects.filter(cislo_body=cislo) | ||||
|     serazena_reseni = sorted(reseni, key=lambda r: (r.resitel.prijmeni, r.resitel.jmeno, r.problem.typ, r.problem.kod)) | ||||
|     reseni = ( | ||||
|         Reseni.objects.filter(cislo_body=cislo) | ||||
|         .order_by( | ||||
|             'resitel__prijmeni', | ||||
|             'resitel__jmeno', | ||||
|             'problem__typ', | ||||
|             'problem__kod' | ||||
|         ) | ||||
|     ) | ||||
| 
 | ||||
|     problemy = sorted(set(r.problem for r in reseni), key=lambda p: (p.typ, p.kod)) | ||||
|     return render(request, 'seminar/archiv/cislo_obalkovani.html', {'cislo': cislo, 'problemy': problemy, 'reseni': serazena_reseni}) | ||||
|     return render( | ||||
|         request, | ||||
|         'seminar/archiv/cislo_obalkovani.html', | ||||
|         {'cislo': cislo, 'problemy': problemy, 'reseni': reseni} | ||||
|     ) | ||||
| 
 | ||||
| ### Tituly | ||||
| 
 | ||||
|  | @ -438,7 +500,7 @@ def TitulyView(request, rocnik, cislo): | |||
|         else: | ||||
|             broken = True | ||||
| 
 | ||||
|     return render(request, 'seminar/archiv/tituly.tex',{'resitele': resitele,'broken':broken}) | ||||
|     return render(request, 'seminar/archiv/tituly.tex',{'resitele': resitele,'broken':broken},content_type="text/plain") | ||||
| 
 | ||||
| 
 | ||||
| ### Soustredeni | ||||
|  | @ -487,3 +549,177 @@ def StavDatabazeView(request): | |||
|                 'jmena_muzu': utils.histogram([r.jmeno for r in muzi]), | ||||
|                 'jmena_zen': utils.histogram([r.jmeno for r in zeny]), | ||||
|             }) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| @ensure_csrf_cookie | ||||
| def LoginView(request): | ||||
|     """Pro přihlášení při nahrávání z texu""" | ||||
|     q = request.POST | ||||
|     # nastavení cookie csrftoken | ||||
|     if not q: | ||||
|         return JsonResponse({"ok": 1}) | ||||
| 
 | ||||
|     if "username" in q: | ||||
|         username = q["username"] | ||||
|         password = q["password"] | ||||
|         user = authenticate(username=username, password=password) | ||||
|         if user is not None and user.is_staff: | ||||
|             login(request, user) | ||||
|             return JsonResponse({"ok": 1}) | ||||
|         else: | ||||
|             return JsonResponse({"error": "Neplatné uživatelské jméno nebo heslo"}) | ||||
| 
 | ||||
| 
 | ||||
| @ensure_csrf_cookie | ||||
| def texUploadView(request): | ||||
| 
 | ||||
|     def uloz_soubory(files, rocnik, cislo): | ||||
|         for filename, f in files: | ||||
|             path = os.path.join( | ||||
|                 settings.MEDIA_ROOT, | ||||
|                 settings.CISLO_IMG_DIR, | ||||
|                 rocnik, | ||||
|                 cislo, | ||||
|                 filename | ||||
|             ) | ||||
| 
 | ||||
|             adresar = os.path.dirname(path) | ||||
|             if not os.path.exists(adresar): | ||||
|                 os.makedirs(adresar) | ||||
| 
 | ||||
|             with open(path, "wb+") as fout: | ||||
|                 for chunk in f.chunks(): | ||||
|                     fout.write(chunk) | ||||
| 
 | ||||
|     q = request.POST | ||||
|     # nastavení cookie csrftoken | ||||
|     if not q: | ||||
|         return JsonResponse({"ok": 1}) | ||||
| 
 | ||||
|     # Odchytíme všechny výjimky a traceback pošleme v odpovědi | ||||
|     try: | ||||
|         meta = json.loads(q["meta"]) | ||||
|         html = q["html"] | ||||
| 
 | ||||
|         if meta["typ"] in ["uloha", "serial", "reseni"]: | ||||
| 
 | ||||
|             # Uložíme soubory | ||||
|             if meta["typ"] != "reseni": | ||||
|                 c = meta["cislo"] | ||||
|             else: | ||||
|                 # Řešení má nastavené číslo svojí úlohy, ale obrázky jsou | ||||
|                 # ukládány do čísla, kde řešení vyšlo | ||||
|                 c = meta["cislo_reseni"] | ||||
|             uloz_soubory(request.FILES.items(), meta["rocnik"], c) | ||||
| 
 | ||||
|             # Zjistíme typ ukládaného problému | ||||
|             typy = { | ||||
|                 "uloha": Problem.TYP_ULOHA, | ||||
|                 "serial": Problem.TYP_SERIAL, | ||||
|                 "reseni": Problem.TYP_ULOHA, | ||||
|             } | ||||
|             problem_typ = typy[meta["typ"]] | ||||
| 
 | ||||
| 
 | ||||
|             # Pokud už problém existuje, vytáhneme jej z db a upravíme | ||||
| 
 | ||||
|             # Pokud ročník/číslo ještě neexistuje, vyhodí to výjimku -> | ||||
|             # čí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"]) | ||||
| 
 | ||||
|             existujici = Problem.objects.filter( | ||||
|                 typ=problem_typ, | ||||
|                 stav=Problem.STAV_ZADANY, | ||||
|                 cislo_zadani=cislo, | ||||
|                 kod=meta["kod"] | ||||
|             ) | ||||
| 
 | ||||
|             problem = None | ||||
|             if existujici: | ||||
|                 problem = existujici[0] | ||||
|             # Jinak vytvoříme nový | ||||
|             else: | ||||
|                 problem = Problem( | ||||
|                     typ=problem_typ, | ||||
|                     stav=Problem.STAV_ZADANY, | ||||
|                     kod=meta["kod"], | ||||
|                     cislo_zadani=cislo | ||||
|                 ) | ||||
| 
 | ||||
|             if meta["typ"] == "reseni": | ||||
|                 problem.text_reseni = html | ||||
|                 #při nahrávání řešení už původní zadání atd. neměníme | ||||
|             else: | ||||
|                 problem.text_zadani = html | ||||
|                 problem.nazev = meta["nazev"] | ||||
|                 problem.body = meta["body"] | ||||
| 
 | ||||
|             problem.save() | ||||
| 
 | ||||
|             # Vrátíme id dané úlohy, aby se k ní dala případně připojit pohádka | ||||
|             return JsonResponse({"db_id": problem.id}) | ||||
| 
 | ||||
|         elif meta["typ"] == "pohadka": | ||||
|             uloha = Problem.objects.get(typ=Problem.TYP_ULOHA, pk=meta["uloha"]) | ||||
| 
 | ||||
|             # Pokud už příslušná pohádka existuje, jen ji upravíme | ||||
|             existujici = Pohadka.objects.filter(uloha=uloha, pred=meta["pred"]) | ||||
|             pohadka = None | ||||
|             if existujici: | ||||
|                 pohadka = existujici[0] | ||||
|             else: | ||||
|                 pohadka = Pohadka(uloha=uloha, pred=meta["pred"]) | ||||
|             pohadka.text = q["html"] | ||||
|             pohadka.save() | ||||
| 
 | ||||
|             return JsonResponse({"db_id": pohadka.id}) | ||||
| 
 | ||||
|     except Exception, e: | ||||
|         # Pošleme zpátky traceback, ať uživatel ví, v čem je problém | ||||
|         tb = "".join(traceback.format_exception(type(e), e, sys.exc_info()[2])) | ||||
|         return JsonResponse({"error": tb}) | ||||
| 
 | ||||
| 
 | ||||
| def texDownloadView(request, rocnik, cislo): | ||||
|     """View posílající JSON se zadanými a řešenými problémy pro založení čísla | ||||
|     """ | ||||
|     cislo = Cislo.objects.get(rocnik__rocnik=rocnik, cislo=cislo) | ||||
|     zadane = Problem.objects.filter( | ||||
|         cislo_zadani=cislo, | ||||
|         stav=Problem.STAV_ZADANY | ||||
|     ) | ||||
|     resene = Problem.objects.filter( | ||||
|         cislo_reseni=cislo, | ||||
|         stav=Problem.STAV_ZADANY, | ||||
|         typ=Problem.TYP_ULOHA | ||||
|     ) | ||||
|     pred_pohadky = Pohadka.objects.filter(uloha__cislo_zadani=cislo, pred=True) | ||||
|     po_pohadky = Pohadka.objects.filter(uloha__cislo_zadani=cislo, pred=False) | ||||
| 
 | ||||
|     response = { | ||||
|         "zadane": [ | ||||
|             { | ||||
|                 "nazev": p.nazev, | ||||
|                 "typ": p.typ, | ||||
|                 "kod": p.kod, | ||||
|                 "body": p.body, | ||||
|                 "zadani": p.text_zadani, | ||||
|                 "pred_pohadky": [x.text for x in pred_pohadky.filter(uloha=p)], | ||||
|                 "po_pohadky": [x.text for x in po_pohadky.filter(uloha=p)], | ||||
|             } for p in zadane | ||||
|         ], | ||||
|         "resene": [ | ||||
|             { | ||||
|                 "nazev": p.nazev, | ||||
|                 "typ": p.typ, | ||||
|                 "kod": p.kod, | ||||
|                 "body": p.body, | ||||
|                 "zadani": p.text_zadani, | ||||
|                 "reseni": p.text_reseni, | ||||
|                 "cislo_zadani": p.cislo_zadani.cislo, | ||||
|             } for p in resene | ||||
|         ], | ||||
|     } | ||||
|     return JsonResponse(response) | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Bc. Petr Pecha
						Bc. Petr Pecha