Merge remote-tracking branch 'origin/master' into deadline-cisla-a-sousu
# Conflicts: # tvorba/models.py
This commit is contained in:
		
						commit
						e0e1dfda41
					
				
					 9 changed files with 144 additions and 3 deletions
				
			
		|  | @ -342,6 +342,7 @@ SEMINAR_KONFERY_DIR = os.path.join('konfery') | ||||||
| KOREKTURY_PDF_DIR = os.path.join('korektury', 'pdf') | KOREKTURY_PDF_DIR = os.path.join('korektury', 'pdf') | ||||||
| KOREKTURY_IMG_DIR = os.path.join('korektury', 'img') | KOREKTURY_IMG_DIR = os.path.join('korektury', 'img') | ||||||
| CISLO_IMG_DIR = os.path.join('cislo', 'img') | CISLO_IMG_DIR = os.path.join('cislo', 'img') | ||||||
|  | SOUSTREDENI_KONTAKTNICKY_DIR = os.path.join('soustredeni', 'kontaktnicky') | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										18
									
								
								soustredeni/migrations/0011_soustredeni_kontaktnicek_pdf.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								soustredeni/migrations/0011_soustredeni_kontaktnicek_pdf.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,18 @@ | ||||||
|  | # Generated by Django 4.2.13 on 2024-11-05 21:02 | ||||||
|  | 
 | ||||||
|  | from django.db import migrations, models | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Migration(migrations.Migration): | ||||||
|  | 
 | ||||||
|  |     dependencies = [ | ||||||
|  |         ('soustredeni', '0010_tvorba_post'), | ||||||
|  |     ] | ||||||
|  | 
 | ||||||
|  |     operations = [ | ||||||
|  |         migrations.AddField( | ||||||
|  |             model_name='soustredeni', | ||||||
|  |             name='kontaktnicek_pdf', | ||||||
|  |             field=models.FileField(blank=True, upload_to='kontaktnicky', verbose_name='kontaktníček'), | ||||||
|  |         ), | ||||||
|  |     ] | ||||||
|  | @ -0,0 +1,23 @@ | ||||||
|  | # Generated by Django 4.2.13 on 2024-11-05 21:07 | ||||||
|  | 
 | ||||||
|  | from django.db import migrations, models | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Migration(migrations.Migration): | ||||||
|  | 
 | ||||||
|  |     dependencies = [ | ||||||
|  |         ('soustredeni', '0011_soustredeni_kontaktnicek_pdf'), | ||||||
|  |     ] | ||||||
|  | 
 | ||||||
|  |     operations = [ | ||||||
|  |         migrations.AddField( | ||||||
|  |             model_name='soustredeni', | ||||||
|  |             name='kontaktnicek_vcf', | ||||||
|  |             field=models.FileField(blank=True, upload_to='kontaktnicky', verbose_name='kontaktníček vcf'), | ||||||
|  |         ), | ||||||
|  |         migrations.AlterField( | ||||||
|  |             model_name='soustredeni', | ||||||
|  |             name='kontaktnicek_pdf', | ||||||
|  |             field=models.FileField(blank=True, upload_to='kontaktnicky', verbose_name='kontaktníček pdf'), | ||||||
|  |         ), | ||||||
|  |     ] | ||||||
|  | @ -0,0 +1,24 @@ | ||||||
|  | # Generated by Django 4.2.16 on 2024-11-12 20:47 | ||||||
|  | 
 | ||||||
|  | from django.db import migrations, models | ||||||
|  | import soustredeni.models | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Migration(migrations.Migration): | ||||||
|  | 
 | ||||||
|  |     dependencies = [ | ||||||
|  |         ('soustredeni', '0012_soustredeni_kontaktnicek_vcf_and_more'), | ||||||
|  |     ] | ||||||
|  | 
 | ||||||
|  |     operations = [ | ||||||
|  |         migrations.AlterField( | ||||||
|  |             model_name='soustredeni', | ||||||
|  |             name='kontaktnicek_pdf', | ||||||
|  |             field=models.FileField(blank=True, null=True, upload_to=soustredeni.models.generate_filemane_pdf, verbose_name='kontaktníček pdf'), | ||||||
|  |         ), | ||||||
|  |         migrations.AlterField( | ||||||
|  |             model_name='soustredeni', | ||||||
|  |             name='kontaktnicek_vcf', | ||||||
|  |             field=models.FileField(blank=True, null=True, upload_to=soustredeni.models.generate_filename_vcf, verbose_name='kontaktníček vcf'), | ||||||
|  |         ), | ||||||
|  |     ] | ||||||
|  | @ -11,6 +11,23 @@ from personalni.models import Resitel, Organizator | ||||||
| 
 | 
 | ||||||
| from various.models import SeminarModelBase | from various.models import SeminarModelBase | ||||||
| from tvorba.models import Rocnik, Problem, aux_generate_filename | from tvorba.models import Rocnik, Problem, aux_generate_filename | ||||||
|  | import secrets | ||||||
|  | import string | ||||||
|  | from django.utils import timezone | ||||||
|  | 
 | ||||||
|  | def generate_filename_vcf(self, filename): | ||||||
|  | 	return generate_filename_kontaktnicek(self, filename, 'vcf') | ||||||
|  | 
 | ||||||
|  | def generate_filemane_pdf(self, filename): | ||||||
|  | 	return generate_filename_kontaktnicek(self, filename, 'pdf') | ||||||
|  | 
 | ||||||
|  | def generate_filename_kontaktnicek(self, filename, file_type): | ||||||
|  | 	# generate random string | ||||||
|  | 	length = 32 | ||||||
|  | 	fname = timezone.now().strftime('%Y-%m-%d-%H_%M') + "-" | ||||||
|  | 	fname += ''.join(secrets.choice(string.ascii_uppercase + string.digits) for _ in range(length)) | ||||||
|  | 	fname += '.' + file_type | ||||||
|  | 	return os.path.join(settings.SOUSTREDENI_KONTAKTNICKY_DIR, fname) | ||||||
| 
 | 
 | ||||||
| logger = logging.getLogger(__name__) | logger = logging.getLogger(__name__) | ||||||
| 
 | 
 | ||||||
|  | @ -65,7 +82,9 @@ class Soustredeni(SeminarModelBase): | ||||||
| 
 | 
 | ||||||
| 	exportovat = models.BooleanField('export do AESOPa', db_column='exportovat', default=False, | 	exportovat = models.BooleanField('export do AESOPa', db_column='exportovat', default=False, | ||||||
| 			help_text='Exportuje se jen podle tohoto flagu (ne veřejnosti)') | 			help_text='Exportuje se jen podle tohoto flagu (ne veřejnosti)') | ||||||
| 
 | 	#using lambda to avoid circular import | ||||||
|  | 	kontaktnicek_vcf = models.FileField('kontaktníček vcf', upload_to=generate_filename_vcf, blank=True, null=True) | ||||||
|  | 	kontaktnicek_pdf = models.FileField('kontaktníček pdf', upload_to=generate_filemane_pdf, blank=True, null=True) | ||||||
| 	def __str__(self): | 	def __str__(self): | ||||||
| 		return '{} ({})'.format(self.misto, self.datum_zacatku) | 		return '{} ({})'.format(self.misto, self.datum_zacatku) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -35,6 +35,14 @@ | ||||||
|             {% endif %} |             {% endif %} | ||||||
|           {% endfor %} |           {% endfor %} | ||||||
|         {% endif %} |         {% endif %} | ||||||
|  | 
 | ||||||
|  |         {% for i in soustredeni.ucastnici.all %} | ||||||
|  |           {% if i.osoba.user == user %} | ||||||
|  |             {% if soustredeni.kontaktnicek_pdf %} <li><a href="../{{soustredeni.pk}}/kontaktnicek_pdf">kontaktnicek pdf</a></li>{% endif %} | ||||||
|  |             {% if soustredeni.kontaktnicek_vcf %} <li><a href="../{{soustredeni.pk}}/kontaktnicek_vcf">kontaktnicek vcf</a></li>{% endif %} | ||||||
|  |           {% endif %} | ||||||
|  |         {% endfor %} | ||||||
|  | 
 | ||||||
|       </ul> |       </ul> | ||||||
|       {% if user.je_org %} |       {% if user.je_org %} | ||||||
|         <div class="mam-org-only"> |         <div class="mam-org-only"> | ||||||
|  | @ -73,6 +81,10 @@ | ||||||
|           Nic! |           Nic! | ||||||
|         {% endfor %} |         {% endfor %} | ||||||
|         </p> |         </p> | ||||||
|  |         <ul> | ||||||
|  |           {% if soustredeni.kontaktnicek_pdf %} <li><a href="../{{soustredeni.pk}}/kontaktnicek_pdf">kontaktnicek pdf</a></li>{% else %} <li>pdf kontaktníček není</li> {% endif %} | ||||||
|  |           {% if soustredeni.kontaktnicek_vcf %} <li><a href="../{{soustredeni.pk}}/kontaktnicek_vcf">kontaktnicek vcf</a></li>{% else %} <li>vcf kontaktníček není</li> {% endif %} | ||||||
|  |         </ul> | ||||||
|       </div> |       </div> | ||||||
|       {% endif %} |       {% endif %} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -44,6 +44,16 @@ urlpatterns = [ | ||||||
| 					org_required(views.SoustredeniAbstraktyView.as_view()), | 					org_required(views.SoustredeniAbstraktyView.as_view()), | ||||||
| 					name='soustredeni_abstrakty' | 					name='soustredeni_abstrakty' | ||||||
| 				), | 				), | ||||||
|  | 				path( | ||||||
|  | 					'kontaktnicek_pdf', | ||||||
|  | 					views.soustredeniKontaktnicekPdfView, | ||||||
|  | 					name='soustredeni_kontaktnicek_pdf' | ||||||
|  | 				), | ||||||
|  | 				path( | ||||||
|  | 					'kontaktnicek_vcf', | ||||||
|  | 					views.soustredeniKontaktnicekVcfView, | ||||||
|  | 					name='soustredeni_kontaktnicek_vcf' | ||||||
|  | 				), | ||||||
| 				path( | 				path( | ||||||
| 					'fotogalerie/', | 					'fotogalerie/', | ||||||
| 					include('galerie.urls') | 					include('galerie.urls') | ||||||
|  |  | ||||||
|  | @ -2,6 +2,8 @@ from django.shortcuts import get_object_or_404 | ||||||
| from django.http import HttpResponse | from django.http import HttpResponse | ||||||
| from django.views import generic | from django.views import generic | ||||||
| from django.contrib.staticfiles.finders import find | from django.contrib.staticfiles.finders import find | ||||||
|  | from django.http import Http404 | ||||||
|  | from django.core.exceptions import PermissionDenied | ||||||
| 
 | 
 | ||||||
| import csv | import csv | ||||||
| 
 | 
 | ||||||
|  | @ -107,3 +109,35 @@ class SoustredeniAbstraktyView(generic.DetailView): | ||||||
| 	model = Soustredeni | 	model = Soustredeni | ||||||
| 	template_name = 'soustredeni/export_do_abstraktu.html' | 	template_name = 'soustredeni/export_do_abstraktu.html' | ||||||
| 	pk_url_kwarg = 'soustredeni' # v url bude <int:soustredeni> místo defaultně požadovaného <int:pk> | 	pk_url_kwarg = 'soustredeni' # v url bude <int:soustredeni> místo defaultně požadovaného <int:pk> | ||||||
|  | 
 | ||||||
|  | # Kontaktníčky | ||||||
|  | def soustredeniKontaktnicekPdfView(request, soustredeni): | ||||||
|  | 	return soustredeniKontaktnicekView(request, soustredeni, "pdf") | ||||||
|  | 
 | ||||||
|  | def soustredeniKontaktnicekVcfView(request, soustredeni): | ||||||
|  | 	return soustredeniKontaktnicekView(request, soustredeni, "vcf") | ||||||
|  | 
 | ||||||
|  | def soustredeniKontaktnicekView(request, soustredeni, typ): | ||||||
|  | 	soustredeni = get_object_or_404(Soustredeni, id=soustredeni) | ||||||
|  |  	# nebyl jsi tam, nebo nejsi org | ||||||
|  | 	if (not request.user in [u.osoba.user for u in soustredeni.ucastnici.all()]) and not request.user.je_org: | ||||||
|  | 		raise PermissionDenied() | ||||||
|  | 	 | ||||||
|  | 	kontaktnicky = { | ||||||
|  | 		'pdf': (soustredeni.kontaktnicek_pdf, 'applcation/pdf', 'rb'), | ||||||
|  | 		'vcf': (soustredeni.kontaktnicek_vcf, 'text/vcard', 'rb'), | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	try: | ||||||
|  | 		field, mime, otevreni = kontaktnicky[typ] | ||||||
|  | 	except KeyError as e: | ||||||
|  | 		raise ValueError("Neznámý typ kontaktníčku") from e | ||||||
|  | 
 | ||||||
|  | 	# není k dispozici | ||||||
|  | 	if not field: | ||||||
|  | 		raise Http404() | ||||||
|  | 	 | ||||||
|  | 	with open(field.path, otevreni) as kontaktnicek: | ||||||
|  | 		response = HttpResponse(kontaktnicek.read(), content_type=mime) | ||||||
|  | 		response['Content-Disposition'] = 'attachment; filename="kontaktnicek.{}"'.format(typ) | ||||||
|  | 	return response | ||||||
|  |  | ||||||
|  | @ -334,7 +334,7 @@ class Deadline(SeminarModelBase): | ||||||
| 		on_delete=models.CASCADE) | 		on_delete=models.CASCADE) | ||||||
| 
 | 
 | ||||||
| 	TYP_CISLA = 'cisla' | 	TYP_CISLA = 'cisla' | ||||||
| 	TYP_CISLA_A_SOUS = 'cislaasous' | 	TYP_CISLA_A_SOUS = 'cislaasous' # Přidáno https://gitea.ks.matfyz.cz/mam/mamweb/pulls/74 | ||||||
| 	TYP_PRVNI_A_SOUS = 'prvniasous' | 	TYP_PRVNI_A_SOUS = 'prvniasous' | ||||||
| 	TYP_PRVNI = 'prvni' | 	TYP_PRVNI = 'prvni' | ||||||
| 	TYP_SOUS = 'sous' | 	TYP_SOUS = 'sous' | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue