diff --git a/mamweb/settings_common.py b/mamweb/settings_common.py index 19616ac1..55817b6d 100644 --- a/mamweb/settings_common.py +++ b/mamweb/settings_common.py @@ -342,6 +342,7 @@ 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') +SOUSTREDENI_KONTAKTNICKY_DIR = os.path.join('soustredeni', 'kontaktnicky') diff --git a/soustredeni/migrations/0011_soustredeni_kontaktnicek_pdf.py b/soustredeni/migrations/0011_soustredeni_kontaktnicek_pdf.py new file mode 100644 index 00000000..7432f296 --- /dev/null +++ b/soustredeni/migrations/0011_soustredeni_kontaktnicek_pdf.py @@ -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'), + ), + ] diff --git a/soustredeni/migrations/0012_soustredeni_kontaktnicek_vcf_and_more.py b/soustredeni/migrations/0012_soustredeni_kontaktnicek_vcf_and_more.py new file mode 100644 index 00000000..18767632 --- /dev/null +++ b/soustredeni/migrations/0012_soustredeni_kontaktnicek_vcf_and_more.py @@ -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'), + ), + ] diff --git a/soustredeni/migrations/0013_alter_soustredeni_kontaktnicek_pdf_and_more.py b/soustredeni/migrations/0013_alter_soustredeni_kontaktnicek_pdf_and_more.py new file mode 100644 index 00000000..20ea60f1 --- /dev/null +++ b/soustredeni/migrations/0013_alter_soustredeni_kontaktnicek_pdf_and_more.py @@ -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'), + ), + ] diff --git a/soustredeni/models.py b/soustredeni/models.py index 57e3741f..c8b36741 100644 --- a/soustredeni/models.py +++ b/soustredeni/models.py @@ -11,6 +11,23 @@ from personalni.models import Resitel, Organizator from various.models import SeminarModelBase 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__) @@ -65,7 +82,9 @@ class Soustredeni(SeminarModelBase): exportovat = models.BooleanField('export do AESOPa', db_column='exportovat', default=False, 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): return '{} ({})'.format(self.misto, self.datum_zacatku) diff --git a/soustredeni/templates/soustredeni/seznam_soustredeni.html b/soustredeni/templates/soustredeni/seznam_soustredeni.html index fb79a7a0..7ba6cd29 100644 --- a/soustredeni/templates/soustredeni/seznam_soustredeni.html +++ b/soustredeni/templates/soustredeni/seznam_soustredeni.html @@ -35,6 +35,14 @@ {% endif %} {% endfor %} {% endif %} + + {% for i in soustredeni.ucastnici.all %} + {% if i.osoba.user == user %} + {% if soustredeni.kontaktnicek_pdf %}
  • kontaktnicek pdf
  • {% endif %} + {% if soustredeni.kontaktnicek_vcf %}
  • kontaktnicek vcf
  • {% endif %} + {% endif %} + {% endfor %} + {% if user.je_org %}
    @@ -73,6 +81,10 @@ Nic! {% endfor %}

    +
    {% endif %} diff --git a/soustredeni/urls.py b/soustredeni/urls.py index ed90e893..78fc2f12 100644 --- a/soustredeni/urls.py +++ b/soustredeni/urls.py @@ -44,11 +44,21 @@ urlpatterns = [ org_required(views.SoustredeniAbstraktyView.as_view()), name='soustredeni_abstrakty' ), + path( + 'kontaktnicek_pdf', + views.soustredeniKontaktnicekPdfView, + name='soustredeni_kontaktnicek_pdf' + ), + path( + 'kontaktnicek_vcf', + views.soustredeniKontaktnicekVcfView, + name='soustredeni_kontaktnicek_vcf' + ), path( 'fotogalerie/', include('galerie.urls') ), ] ) - ) + ) ] diff --git a/soustredeni/views.py b/soustredeni/views.py index c91da036..3cb129f7 100644 --- a/soustredeni/views.py +++ b/soustredeni/views.py @@ -2,6 +2,8 @@ from django.shortcuts import get_object_or_404 from django.http import HttpResponse from django.views import generic from django.contrib.staticfiles.finders import find +from django.http import Http404 +from django.core.exceptions import PermissionDenied import csv @@ -107,3 +109,35 @@ class SoustredeniAbstraktyView(generic.DetailView): model = Soustredeni template_name = 'soustredeni/export_do_abstraktu.html' pk_url_kwarg = 'soustredeni' # v url bude místo defaultně požadovaného + +# 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 diff --git a/tvorba/models.py b/tvorba/models.py index 9ec1afe7..36f34312 100644 --- a/tvorba/models.py +++ b/tvorba/models.py @@ -334,7 +334,7 @@ class Deadline(SeminarModelBase): on_delete=models.CASCADE) 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 = 'prvni' TYP_SOUS = 'sous'