Browse Source

Merge remote-tracking branch 'gitea/master' into zadavatko_problemu

zadavatko_problemu
Pavel "LEdoian" Turinsky 2 years ago
parent
commit
cd0a3b644a
  1. 9
      korektury/admin.py
  2. 9
      korektury/views.py
  3. 1
      make/init_local
  4. 16
      mamweb/templates/base.html
  5. 23
      odevzdavatko/templates/odevzdavatko/detail.html
  6. 0
      odevzdavatko/templatetags/__init__.py
  7. 9
      odevzdavatko/templatetags/jmena.py
  8. 10
      odevzdavatko/views.py
  9. 200
      personalni/forms.py
  10. 98
      personalni/templates/personalni/udaje/edit.html
  11. 97
      personalni/templates/personalni/udaje/prihlaska.html
  12. 75
      personalni/templates/personalni/udaje/udaje.html
  13. 11
      personalni/utils.py
  14. 9
      personalni/views.py
  15. 18
      seminar/migrations/0112_prijemce_zasilat_cislo_emailem.py
  16. 42
      seminar/migrations/0113_resitel_zasilat_cislo_papirove.py
  17. 5
      seminar/models/personalni.py
  18. 12
      seminar/models/tvorba.py
  19. 2
      seminar/templates/seminar/archiv/obalky.tex
  20. 2
      seminar/utils.py
  21. 14
      various/mail_prefixer.py
  22. 33
      various/utils.py

9
korektury/admin.py

@ -12,7 +12,7 @@ from django.contrib import admin
from reversion.admin import VersionAdmin from reversion.admin import VersionAdmin
from korektury.models import KorekturovanePDF from korektury.models import KorekturovanePDF
from django.core.mail import send_mail from django.core.mail import EmailMessage
from django.urls import reverse from django.urls import reverse
# Register your models here. # Register your models here.
@ -64,6 +64,11 @@ Popis souboru:
S pozdravem a korekturám zdar! S pozdravem a korekturám zdar!
Korekturovátko Korekturovátko
''' '''
send_mail(predmet,text,odesilatel,[prijemce]) EmailMessage(
subject=predmet,
body=text,
from_email=odesilatel,
to=[prijemce],
).send()
admin.site.register(KorekturovanePDF, KorekturovanePDFAdmin) admin.site.register(KorekturovanePDF, KorekturovanePDFAdmin)

9
korektury/views.py

@ -8,7 +8,7 @@ from django.views import generic
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.conf import settings from django.conf import settings
from django.http import HttpResponseForbidden from django.http import HttpResponseForbidden
from django.core.mail import send_mail from django.core.mail import EmailMessage
from django.db.models import Count,Q from django.db.models import Count,Q
from .models import Oprava,Komentar,KorekturovanePDF, Organizator from .models import Oprava,Komentar,KorekturovanePDF, Organizator
@ -207,7 +207,12 @@ class KorekturyView(generic.TemplateView):
print("---- Konec upozornění") print("---- Konec upozornění")
return return
send_mail(subject, text, from_email, list(emails)) EmailMessage(
subject=subject,
body=text,
from_email=from_email,
to=list(emails),
).send()
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)

1
make/init_local

@ -8,3 +8,4 @@ ensure_venv
./manage.py testdata ./manage.py testdata
./manage.py loaddata data/* ./manage.py loaddata data/*
make/sync_prod_flatpages make/sync_prod_flatpages
./manage.py load_org_permissions deploy_v2/admin_org_prava.json

16
mamweb/templates/base.html

@ -170,6 +170,22 @@
rotace_a_posun($('.container'), randomUhel()); rotace_a_posun($('.container'), randomUhel());
</script> </script>
{% endif %} {% endif %}
{% if april == 2023 %}
<script>
{# By https://stackoverflow.com/a/34559316 #}
function walkText(node) {
if (node.nodeType == 3) {
node.data = node.data.replace(/M&M/g, "M💘M");
}
if (node.nodeType == 1 && node.nodeName != "SCRIPT") {
for (var i = 0; i < node.childNodes.length; i++) {
walkText(node.childNodes[i]);
}
}
}
walkText(document.body);
</script>
{% endif %}
{% render_block "js" %} {% render_block "js" %}
</body> </body>
</html> </html>

23
odevzdavatko/templates/odevzdavatko/detail.html

@ -2,12 +2,24 @@
{% load static %} {% load static %}
{% load deadliny %} {% load deadliny %}
{% load mail %} {% load mail %}
{% load jmena %}
{% block content %} {% block content %}
{% if edit %} {% if edit %}
<script src="{% static 'odevzdavatko/dynamic_formsets_for_detail.js' %}"></script> <script src="{% static 'odevzdavatko/dynamic_formsets_for_detail.js' %}"></script>
<script src="{% static 'odevzdavatko/check_for_detail.js' %}"></script> <script src="{% static 'odevzdavatko/check_for_detail.js' %}"></script>
<script type="text/javascript">
$(document).ready(function () {
const zaskrtavatko = document.getElementById('pridat-jmena-resitelu');
zaskrtavatko.addEventListener('change', () => {
for (var priloha of document.getElementsByClassName("reseni-ke-stazeni")) {
let new_download = zaskrtavatko.checked ? priloha.dataset.altFilename : '';
priloha.setAttribute('download', new_download);
}
});
});
</script>
{% endif %} {% endif %}
@ -40,11 +52,20 @@
<tr><th>Soubor</th><th>Řešitelova poznámka</th><th>Datum</th></tr> <tr><th>Soubor</th><th>Řešitelova poznámka</th><th>Datum</th></tr>
{% for priloha in object.prilohy.all %} {% for priloha in object.prilohy.all %}
<tr> <tr>
<td><a href="{{ priloha.soubor.url }}" download>{{ priloha.split | last }}</a></td> <td><a class='reseni-ke-stazeni'
href="{{ priloha.soubor.url }}"
download
data-alt-filename="{{object.resitele.first.osoba | jmeno_jako_prefix }}_{{ object.id }}_{{ priloha.split | last}}"
>{{ priloha.split | last }}</a></td>
<td>{{ priloha.res_poznamka }}</td> <td>{{ priloha.res_poznamka }}</td>
<td>{{ priloha.vytvoreno }}</td></tr> <td>{{ priloha.vytvoreno }}</td></tr>
{% endfor %} {% endfor %}
</table> </table>
{% if edit %} {# FIXME: tohle nesouvisí s editací, ale s tím, jestli je člověk org… #}
<br>
<input type=checkbox id="pridat-jmena-resitelu">
<label class="field-label" for="pridat-jmena-resitelu">Uvést jméno řešitele v názvu souboru při stažení.</label>
{% endif %}
{% else %} {% else %}
<p>Žádné přílohy</p> <p>Žádné přílohy</p>
{% endif %} {% endif %}

0
odevzdavatko/templatetags/__init__.py

9
odevzdavatko/templatetags/jmena.py

@ -0,0 +1,9 @@
from django import template
register = template.Library()
from personalni.utils import normalizuj_jmeno
import seminar.models as m # jen kvůli typové anotaci…
@register.filter
def jmeno_jako_prefix(o: m.Osoba):
return normalizuj_jmeno(o).replace(' ', '_')

10
odevzdavatko/views.py

@ -1,7 +1,7 @@
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.views.generic import ListView, DetailView, FormView from django.views.generic import ListView, DetailView, FormView
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.mail import send_mail from django.core.mail import EmailMessage
from django.utils import timezone from django.utils import timezone
from django.views.generic import ListView, DetailView, FormView, CreateView from django.views.generic import ListView, DetailView, FormView, CreateView
from django.views.generic.list import MultipleObjectTemplateResponseMixin,MultipleObjectMixin from django.views.generic.list import MultipleObjectTemplateResponseMixin,MultipleObjectMixin
@ -449,11 +449,11 @@ class NahrajReseniView(LoginRequiredMixin, CreateView):
seznam = "problému " + str(problemy[0]) if len(problemy) == 1 else 'následujícím problémům:\n' + ', \n'.join(map(str, problemy)) seznam = "problému " + str(problemy[0]) if len(problemy) == 1 else 'následujícím problémům:\n' + ', \n'.join(map(str, problemy))
seznam_do_subjectu = "problému " + str(problemy[0]) + ("" if len(problemy) == 1 else f" (a dalším { len(problemy) - 1 })") seznam_do_subjectu = "problému " + str(problemy[0]) + ("" if len(problemy) == 1 else f" (a dalším { len(problemy) - 1 })")
send_mail( EmailMessage(
subject="Nové řešení k " + seznam_do_subjectu, subject="Nové řešení k " + seznam_do_subjectu,
message=f"Řešitel{ '' if resitel.pohlavi_muz else 'ka' } { resitel } právě nahrál{'' if resitel.pohlavi_muz else 'a' } nové řešení k { seznam }.\n\nHurá do opravování: { self.object.absolute_url() }", body=f"Řešitel{ '' if resitel.pohlavi_muz else 'ka' } { resitel } právě nahrál{'' if resitel.pohlavi_muz else 'a' } nové řešení k { seznam }.\n\nHurá do opravování: { self.object.absolute_url() }",
from_email="submitovatko@mam.mff.cuni.cz", # FIXME: Chceme to mít radši tady, nebo v nastavení? from_email="submitovatko@mam.mff.cuni.cz", # FIXME: Chceme to mít radši tady, nebo v nastavení?
recipient_list=list(prijemci), to=list(prijemci),
) ).send()
return formularOKView(self.request, text='Řešení úspěšně odevzdáno') return formularOKView(self.request, text='Řešení úspěšně odevzdáno')

200
personalni/forms.py

@ -25,107 +25,86 @@ class TelInput(forms.TextInput):
input_pattern="^[+]?[()/0-9. -]{9,}$" input_pattern="^[+]?[()/0-9. -]{9,}$"
class PrihlaskaForm(PasswordResetForm): class UdajeForm(forms.Form):
username = forms.CharField(label='Přihlašovací jméno', username = None
max_length=256, err_logger = logging.getLogger('seminar.prihlaska.problem')
required=True,
help_text='Tímto jménem se následně budeš přihlašovat pro odevzdání řešení a další činnosti v semináři')
jmeno = forms.CharField(label='Jméno', max_length=256, required=True) jmeno = forms.CharField(label='Jméno', max_length=256, required=True)
prezdivka_resitele = forms.CharField(label='Přezdívka (veřejná)', max_length=256, required=False) prezdivka_resitele = forms.CharField(label='Přezdívka (veřejná)', max_length=256, required=False)
prijmeni = forms.CharField(label='Příjmení', max_length=256, required=True) prijmeni = forms.CharField(label='Příjmení', max_length=256, required=True)
pohlavi_muz = forms.ChoiceField(label='Pohlaví', pohlavi_muz = forms.ChoiceField(label='Pohlaví', choices=((True, 'muž'), (False, 'žena')), required=True)
choices = ((True,'muž'),(False,'žena')), required=True)
email = forms.EmailField(label='E-mail', max_length=256, required=True) email = forms.EmailField(label='E-mail', max_length=256, required=True)
telefon = forms.CharField(widget=TelInput(), label='Telefon', max_length=256, required=False) telefon = forms.CharField(widget=TelInput(), label='Telefon', max_length=256, required=False)
datum_narozeni = forms.DateField(widget=DateInput(), label='Datum narození', required=False) datum_narozeni = forms.DateField(widget=DateInput(), label='Datum narození', required=False)
ulice = forms.CharField(label='Ulice a číslo popisné', max_length=256, required=False) ulice = forms.CharField(label='Ulice a číslo popisné', max_length=256, required=False)
mesto = forms.CharField(label='Město', max_length=256, required=False) mesto = forms.CharField(label='Město', max_length=256, required=False)
psc = forms.CharField(label='PSČ', max_length=32, required=False) psc = forms.CharField(label='PSČ', max_length=32, required=False)
stat = forms.ChoiceField(label='Stát', stat = forms.ChoiceField(label='Stát', choices=(('CZ', 'Česká republika'), ('SK', 'Slovenská republika'), ('other', 'Jiné')), required=False)
choices = (('CZ', 'Česká Republika'),
('SK', 'Slovenská Republika'),
('other', 'Jiné')),
required=False)
stat_text = forms.CharField(label='Stát', max_length=256, required=False) stat_text = forms.CharField(label='Stát', max_length=256, required=False)
skola = forms.ModelChoiceField(label="Škola", skola = forms.ModelChoiceField(
label="Škola",
queryset=Skola.objects.all(), queryset=Skola.objects.all(),
widget=autocomplete.ModelSelect2( widget=autocomplete.ModelSelect2(
url='autocomplete_skola', url='autocomplete_skola',
attrs = {'data-placeholder--id': '-1', attrs={
'data-placeholder--id': '-1',
'data-placeholder--text': '---', 'data-placeholder--text': '---',
'data-allow-clear': 'true'}) 'data-allow-clear': 'true'
,required=False) }
),
required=False,
)
skola_nazev = forms.CharField(label='Název školy', max_length=256, required=False) skola_nazev = forms.CharField(label='Název školy', max_length=256, required=False)
skola_adresa = forms.CharField(label='Adresa školy', max_length=256, required=False) skola_adresa = forms.CharField(label='Adresa školy', max_length=256, required=False)
# trida = forms.CharField(label='Třída',max_length=10, required=True)
rok_maturity = forms.IntegerField( rok_maturity = forms.IntegerField(
label='Rok maturity', label='Rok maturity',
min_value=date.today().year, min_value=date.today().year,
max_value=date.today().year+8, max_value=date.today().year+8,
required=True) required=True,
zasilat = forms.ChoiceField(label='Kam zasílat čísla',choices = Resitel.ZASILAT_CHOICES, required=True) )
zasilat_cislo_emailem = forms.BooleanField(label='Chci dostávat e-mailem upozornění na vydání nového čísla', required=False)
jak_se_dozvedeli = forms.CharField(widget=forms.Textarea({"rows": 3, "cols": 20}), label='Jak ses o M&M dozvěděl(a)? (Nechceš-li odpovídat, napiš „nechci uvést“.)', required=True)
gdpr = forms.BooleanField(label='Souhlasím se zpracováním osobních údajů', required=True)
spam = forms.BooleanField(label='Souhlasím se zasíláním materiálů od MFF UK', required=False)
def clean_username(self): zasilat = forms.ChoiceField(label='Kam zasílat (odměny, pozvánky, případně čísla nebo propagační materiály)', choices=[it for it in Resitel.ZASILAT_CHOICES if it[0] != Resitel.ZASILAT_NIKAM], required=True, initial=Resitel.ZASILAT_DOMU)
err_logger = logging.getLogger('seminar.prihlaska.problem') zasilat_cislo_papirove = forms.BooleanField(label='Chci dostávat čísla poštou (zasílání není zpoplatněno)', required=False, initial=False)
username = self.cleaned_data.get('username') zasilat_cislo_emailem = forms.BooleanField(label='Chci dostávat e-mailem upozornění na vydání nového čísla', required=False, initial=True)
try: spam = forms.BooleanField(label='Souhlasím se zasíláním propagačních materiálů od MFF UK', required=False)
User.objects.get(username=username)
msg = "Username {} exists".format(username)
err_logger.info(msg)
raise forms.ValidationError('Přihlašovací jméno je již použito')
except ObjectDoesNotExist: def clean_prezdivka_resitele(self):
pass prezdivka_resitele = self.cleaned_data.get('prezdivka_resitele')
return username if prezdivka_resitele == '':
return prezdivka_resitele
if Resitel.objects.filter(prezdivka_resitele=prezdivka_resitele).exclude(osoba__user__username=self.username).count() > 0:
raise forms.ValidationError('Přezdívka je již použita')
return prezdivka_resitele
def clean_email(self): def clean_email(self):
err_logger = logging.getLogger('seminar.prihlaska.problem')
email = self.cleaned_data.get('email') email = self.cleaned_data.get('email')
try: try:
osoba = Osoba.objects.get(email=email) osoba = Osoba.objects.exclude(user__username=self.username).get(email=email)
msg = "Email {} exists".format(email) msg = "Email {} exists".format(email)
if osoba.user is not None: if osoba.user is not None:
err_logger.info(msg) self.err_logger.info(msg)
raise forms.ValidationError('E-mail je již použit') raise forms.ValidationError('E-mail je již použit')
else: else:
msg += ', but currently has no User, so allowing registration.' msg += ', but currently has no User, so allowing registration.'
err_logger.info(msg) self.err_logger.info(msg)
except ObjectDoesNotExist: except ObjectDoesNotExist:
pass pass
return email return email
def clean_prezdivka_resitele(self):
prezdivka_resitele = self.cleaned_data.get('prezdivka_resitele')
if prezdivka_resitele == '':
return prezdivka_resitele
if Resitel.objects.filter(prezdivka_resitele=prezdivka_resitele).count() > 0:
raise forms.ValidationError('Přezdívka je již použita')
return prezdivka_resitele
def clean_zasilat(self): def clean_zasilat(self):
zasilat = self.cleaned_data.get('zasilat') zasilat = self.cleaned_data.get('zasilat')
ulice = self.cleaned_data.get('ulice') ulice = self.cleaned_data.get('ulice')
if zasilat == Resitel.ZASILAT_DOMU and ulice == "": if zasilat == Resitel.ZASILAT_DOMU and ulice == "":
raise forms.ValidationError('Nevyplněná adresa bydliště, nelze zasílat čísla domů.') raise forms.ValidationError('Nevyplněná adresa bydliště, nelze zasílat domů.')
return zasilat return zasilat
def clean(self): def clean(self):
super().clean() super().clean()
err_logger = logging.getLogger('seminar.prihlaska.problem')
data = self.cleaned_data data = self.cleaned_data
if data.get('stat') != 'other' and data.get('stat_text') != '': if data.get('stat') != 'other' and data.get('stat_text') != '':
self.add_error('stat',forms.ValidationError('Nelze mít vybraný stát z menu a zároven zapsaný textem')) self.add_error('stat',forms.ValidationError('Nelze mít vybraný stát z menu a zároven zapsaný textem'))
@ -140,106 +119,41 @@ class PrihlaskaForm(PasswordResetForm):
self.add_error('skola_adresa',forms.ValidationError('Je nutné vyplnit adresu školy')) self.add_error('skola_adresa',forms.ValidationError('Je nutné vyplnit adresu školy'))
class ProfileEditForm(forms.Form):
username = forms.CharField(label='Přihlašovací jméno',
max_length=256,
required=False,
disabled=True)
jmeno = forms.CharField(label='Jméno', max_length=256, required=True)
prezdivka_resitele = forms.CharField(label='Přezdívka (veřejná)', max_length=256, required=False)
prijmeni = forms.CharField(label='Příjmení', max_length=256, required=True)
pohlavi_muz = forms.ChoiceField(label='Pohlaví',
choices = ((True,'muž'),(False,'žena')), required=True)
email = forms.EmailField(label='E-mail',max_length=256, required=True)
telefon = forms.CharField(widget=TelInput(),label='Telefon',max_length=256, required=False)
datum_narozeni = forms.DateField(widget=DateInput(),label='Datum narození', required=False)
ulice = forms.CharField(label='Ulice', max_length=256, required=False)
mesto = forms.CharField(label='Město', max_length=256, required=False)
psc = forms.CharField(label='PSČ', max_length=32, required=False)
stat = forms.ChoiceField(label='Stát',
choices = (('CZ', 'Česká republika'),
('SK', 'Slovenská republika'),
('other', 'Jiné')),
required=False)
stat_text = forms.CharField(label='Stát', max_length=256, required=False)
skola = forms.ModelChoiceField(label="Škola",
queryset=Skola.objects.all(),
widget=autocomplete.ModelSelect2(
url='autocomplete_skola',
attrs = {'data-placeholder--id': '-1',
'data-placeholder--text' : '---',
'data-allow-clear': 'true'})
,required=False)
skola_nazev = forms.CharField(label='Název školy', max_length=256, required=False)
skola_adresa = forms.CharField(label='Adresa školy', max_length=256, required=False)
# trida = forms.CharField(label='Třída',max_length=10, required=True) class PrihlaskaForm(PasswordResetForm, UdajeForm):
username = forms.CharField(
label='Přihlašovací jméno',
max_length=256,
required=True,
help_text='Tímto jménem se následně budeš přihlašovat pro odevzdání řešení a další činnosti v semináři',
)
rok_maturity = forms.IntegerField( jak_se_dozvedeli = forms.CharField(widget=forms.Textarea({"rows": 3, "cols": 20}), label='Jak ses o M&M dozvěděl(a)? (Nechceš-li odpovídat, napiš „nechci uvést“.)', required=True)
label='Rok maturity',
min_value=date.today().year,
max_value=date.today().year+8,
required=True)
zasilat = forms.ChoiceField(label='Kam zasílat čísla',choices = Resitel.ZASILAT_CHOICES, required=True)
zasilat_cislo_emailem = forms.BooleanField(label='Chci dostávat email s upozorněním na vydání nového čísla', required=False)
spam = forms.BooleanField(label='Souhlasím se zasíláním materiálů od MFF UK', required=False)
# def clean_username(self):
# err_logger = logging.getLogger('seminar.prihlaska.problem')
# username = self.cleaned_data.get('username')
# try:
# User.objects.get(username=username)
# msg = "Username {} exists".format(username)
# err_logger.info(msg)
# raise forms.ValidationError('Přihlašovací jméno je již použito')
#
# except ObjectDoesNotExist:
# pass
# return username
#
def clean_prezdivka_resitele(self): gdpr = forms.BooleanField(label='Souhlasím se zpracováním osobních údajů', required=True)
prezdivka_resitele = self.cleaned_data.get('prezdivka_resitele')
if prezdivka_resitele == '':
return prezdivka_resitele
if Resitel.objects.filter(prezdivka_resitele=prezdivka_resitele).exclude(osoba__user__username=self.username).count() > 0:
raise forms.ValidationError('Přezdívka je již použita')
return prezdivka_resitele
def clean_email(self): def clean_username(self):
err_logger = logging.getLogger('seminar.prihlaska.problem') username = self.cleaned_data.get('username')
email = self.cleaned_data.get('email')
try: try:
Osoba.objects.exclude(user__username=self.username).get(email=email) User.objects.get(username=username)
msg = "Email {} exists (in edit)".format(email) msg = "Username {} exists".format(username)
err_logger.info(msg) self.err_logger.info(msg)
raise forms.ValidationError('Email je již použit') raise forms.ValidationError('Přihlašovací jméno je již použito')
except ObjectDoesNotExist: except ObjectDoesNotExist:
pass pass
return email return username
#def clean(self):
# super().clean()
# class ProfileEditForm(UdajeForm):
# err_logger = logging.getLogger('seminar.prihlaska.problem') err_logger = logging.getLogger('seminar.edit.problem')
username = forms.CharField(
# data = self.cleaned_data label='Přihlašovací jméno',
# if data.get('password') != data.get('password_check'): max_length=256,
# self.add_error('password_check',forms.ValidationError('Hesla se neshodují')) required=False,
# if data.get('stat') != '' and data.get('stat_text') != '': disabled=True,
# self.add_error('stat',forms.ValidationError('Nelze mít vybraný stát z menu a zároven zapsaný textem')) )
# if data.get('skola') and (data.get('skola_nazev') or data.get('skola_adresa')):
# self.add_error('skola',forms.ValidationError('Pokud je škola v seznamu, nevypisujte ji ručně, pokud není, zrušte výběr ze seznamu (křížek vpravo)'))
# if not data.get('skola'):
# if data.get('skola_nazev')=='' and data.get('skola_adresa')=='':
# self.add_error('skola',forms.ValidationError('Je nutné vyplnit školu'))
# elif data.get('skola_nazev')=='':
# self.add_error('skola_nazev',forms.ValidationError('Je nutné vyplnit název školy'))
# elif data.get('skola_adresa')=='':
# self.add_error('skola_adresa',forms.ValidationError('Je nutné vyplnit adresu školy'))
class PoMaturiteProfileEditForm(ProfileEditForm): class PoMaturiteProfileEditForm(ProfileEditForm):

98
personalni/templates/personalni/udaje/edit.html

@ -1,109 +1,19 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load static %} {% load static %}
{% block script %}
<script src="{% static 'personalni/prihlaska.js' %}"></script>
{% endblock %}
<!--
# pro přidání políčka do formuláře je potřeba
# - mít v modelu tu položku, kterou chci upravovat
# - přidat do views (prihlaskaView, resitelEditView)
# - přidat do forms
# - includovat do html
-->
{% block content %} {% block content %}
<h1> <h1>
{% block nadpis1a %} {% block nadpis1a %}
Změna osobních údajů Změna osobních údajů
{% endblock %} {% endblock %}
</h1> </h1>
<form action="{% url 'seminar_resitel_edit' %}" method="post">
{% csrf_token %}
{{form.non_field_errors}}
<hr>
<h4>
Přihlašovací údaje
</h4>
<table class="form">
{% include "personalni/udaje/prihlaska_field.html" with field=form.username %}
</table>
<p><a href="{% url 'reset_password' %}">
Změnit heslo
</a></p>
<hr>
<h4>
Osobní údaje
</h4>
<table class="form">
{% include "personalni/udaje/prihlaska_field.html" with field=form.jmeno %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.prezdivka_resitele %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.prijmeni %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.pohlavi_muz%}
{% include "personalni/udaje/prihlaska_field.html" with field=form.email %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.telefon %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.datum_narozeni %}
</table>
<hr>
<h4>
Bydliště
</h4>
<table class="form">
{% include "personalni/udaje/prihlaska_field.html" with field=form.ulice %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.mesto %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.psc %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.stat %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.stat_text id="id_li_stat_text"%}
</table>
<hr>
<h4>
Škola
</h4>
<table class="form">
{% include "personalni/udaje/prihlaska_field.html" with field=form.skola %}
<tr><td colspan="2" ><button id="id_skola_text_button" type="button">Škola není v seznamu</button></td></tr>
<tr><td id="id_li_skola_vypln" colspan="2">Vyplň prosím celý název a adresu školy.</td></tr>
{% include "personalni/udaje/prihlaska_field.html" with field=form.skola_nazev id="id_li_skola_nazev" %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.skola_adresa id="id_li_skola_adresa" %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.rok_maturity %}
</table>
<hr>
<h4>
Pošta
</h4>
<table class="form">
{% include "personalni/udaje/prihlaska_field.html" with field=form.zasilat %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.zasilat_cislo_emailem %}
</table>
<hr>
<h4>
Zasílání propagačních materiálů
</h4>
<table class="form">
{% include "personalni/udaje/prihlaska_field.html" with field=form.spam %}
</table>
<hr> <hr>
<p><a href="{% url 'reset_password' %}">Změnit heslo</a></p>
<form action="{% url 'seminar_resitel_edit' %}" method="post">
{% include "personalni/udaje/udaje.html"%}
<input type="submit" value="Změnit"> <input type="submit" value="Změnit">
</form> </form>
<script>
$("#id_stat").on("change",addrCountryChanged);
$("#id_skola_text_button").on("click",schoolNotInList);
</script>
{% endblock %} {% endblock %}

97
personalni/templates/personalni/udaje/prihlaska.html

@ -5,16 +5,6 @@
<script src="{% static 'personalni/prihlaska.js' %}"></script> <script src="{% static 'personalni/prihlaska.js' %}"></script>
{% endblock %} {% endblock %}
<!--
# pro přidání políčka do formuláře je potřeba
# - mít v modelu tu položku, kterou chci upravovat
# - přidat do views (prihlaskaView, resitelEditView)
# - přidat do forms
# - includovat do html
-->
{% block content %} {% block content %}
<h1> <h1>
{% block nadpis1a %} {% block nadpis1a %}
@ -25,73 +15,7 @@
<p><b>Tučně</b> popsaná pole jsou povinná.</p> <p><b>Tučně</b> popsaná pole jsou povinná.</p>
<form action="{% url 'seminar_prihlaska' %}" method="post"> <form action="{% url 'seminar_prihlaska' %}" method="post">
{% csrf_token %} {% include "personalni/udaje/udaje.html" %}
{{form.non_field_errors}}
<hr>
<h4>
Přihlašovací údaje
</h4>
<table class="form">
{% include "personalni/udaje/prihlaska_field.html" with field=form.username %}
{# {% include "personalni/udaje/prihlaska_field.html" with field=form.password %}#}
{# {% include "personalni/udaje/prihlaska_field.html" with field=form.password_check %}#}
</table>
<hr>
<h4>
Osobní údaje
</h4>
<table class="form">
{% include "personalni/udaje/prihlaska_field.html" with field=form.jmeno %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.prezdivka_resitele %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.prijmeni %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.pohlavi_muz%}
{% include "personalni/udaje/prihlaska_field.html" with field=form.email %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.telefon %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.datum_narozeni %}
</table>
<hr>
<h4>
Bydliště
</h4>
<table class="form">
{% include "personalni/udaje/prihlaska_field.html" with field=form.ulice %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.mesto %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.psc %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.stat %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.stat_text id="id_li_stat_text"%}
</table>
<hr>
<h4>
Škola
</h4>
<table class="form">
{% include "personalni/udaje/prihlaska_field.html" with field=form.skola %}
<tr><td colspan="2" ><button id="id_skola_text_button" type="button">Škola není v seznamu</button></td><td>(Prosíme, zkuste ji najít, téměř jistě ji v seznamu máme. Školy se dobře hledají podle příjmení lidí v jejich názvu, podle ulice, případně název ulice <i>mezera</i> město, atd. Nezadávejte slova, která se často zkracují &ndash; gymnázium, střední odborná škola, křestní jména…)</td></tr>
<tr><td id="id_li_skola_vypln" colspan="2">Vyplň prosím celý název a adresu školy.</td></tr>
{% include "personalni/udaje/prihlaska_field.html" with field=form.skola_nazev id="id_li_skola_nazev" %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.skola_adresa id="id_li_skola_adresa" %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.rok_maturity %}
</table>
<hr>
<h4>
Pošta
</h4>
<table class="form">
{% include "personalni/udaje/prihlaska_field.html" with field=form.zasilat %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.zasilat_cislo_emailem %}
</table>
<hr>
<h4> <h4>
GDPR GDPR
</h4> </h4>
@ -100,17 +24,6 @@
{% include "personalni/udaje/prihlaska_field.html" with field=form.gdpr %} {% include "personalni/udaje/prihlaska_field.html" with field=form.gdpr %}
</table> </table>
<hr>
<h4>
Zasílání propagačních materiálů
</h4>
<table class="form">
{% include "personalni/udaje/prihlaska_field.html" with field=form.spam %}
</table>
<hr> <hr>
<h4> <h4>
@ -120,14 +33,8 @@
{% include "personalni/udaje/prihlaska_field.html" with field=form.jak_se_dozvedeli %} {% include "personalni/udaje/prihlaska_field.html" with field=form.jak_se_dozvedeli %}
</table> </table>
<hr>
<input type="submit" value="Odeslat"> <input type="submit" value="Odeslat">
</form> </form>
<script>
$("#id_stat").on("change",addrCountryChanged);
$("#id_skola_text_button").on("click",schoolNotInList);
</script>
{% endblock %} {% endblock %}

75
personalni/templates/personalni/udaje/udaje.html

@ -0,0 +1,75 @@
{% load static %}
{% block script %}
<script src="{% static 'personalni/prihlaska.js' %}"></script>
{% endblock %}
{% csrf_token %}
{{form.non_field_errors}}
<hr>
<h4>
Přihlašovací údaje
</h4>
<table class="form">
{% include "personalni/udaje/prihlaska_field.html" with field=form.username %}
</table>
<hr>
<h4>
Osobní údaje
</h4>
<table class="form">
{% include "personalni/udaje/prihlaska_field.html" with field=form.jmeno %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.prezdivka_resitele %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.prijmeni %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.pohlavi_muz%}
{% include "personalni/udaje/prihlaska_field.html" with field=form.email %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.telefon %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.datum_narozeni %}
</table>
<hr>
<h4>
Škola
</h4>
<table class="form">
{% include "personalni/udaje/prihlaska_field.html" with field=form.skola %}
<tr><td colspan="2" ><button id="id_skola_text_button" type="button">Škola není v seznamu</button></td><td>(Prosíme, zkuste ji najít, téměř jistě ji v seznamu máme. Školy se dobře hledají podle příjmení lidí v jejich názvu, podle ulice, případně název ulice <i>mezera</i> město, atd. Nezadávejte slova, která se často zkracují &ndash; gymnázium, střední odborná škola, křestní jména…)</td></tr>
<tr><td id="id_li_skola_vypln" colspan="2">Vyplň prosím celý název a adresu školy.</td></tr>
{% include "personalni/udaje/prihlaska_field.html" with field=form.skola_nazev id="id_li_skola_nazev" %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.skola_adresa id="id_li_skola_adresa" %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.rok_maturity %}
</table>
<hr>
<h4>
Pošta
</h4>
<table class="form">
{% include "personalni/udaje/prihlaska_field.html" with field=form.zasilat_cislo_emailem %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.zasilat_cislo_papirove %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.spam %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.zasilat %}
</table>
<hr>
<h4>
Bydliště (povinné při volbě „domů“)
</h4>
<table class="form">
{% include "personalni/udaje/prihlaska_field.html" with field=form.ulice %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.mesto %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.psc %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.stat %}
{% include "personalni/udaje/prihlaska_field.html" with field=form.stat_text id="id_li_stat_text"%}
</table>
<hr>
<script>
$("#id_stat").on("change",addrCountryChanged);
$("#id_skola_text_button").on("click",schoolNotInList);
</script>

11
personalni/utils.py

@ -0,0 +1,11 @@
import seminar.models as m
from various.utils import bez_diakritiky_translate
import re
def normalizuj_jmeno(o: m.Osoba) -> str:
# FIXME: Možná není potřeba vázat na model?
cele_jmeno = f'{o.jmeno} {o.prijmeni}'
cele_jmeno = cele_jmeno.translate(bez_diakritiky_translate)
cele_jmeno = re.sub(r'[^a-zA-Z- ]', '', cele_jmeno)
return cele_jmeno

9
personalni/views.py

@ -165,6 +165,7 @@ def resitelEditView(request):
resitel_edit.rok_maturity = fcd['rok_maturity'] resitel_edit.rok_maturity = fcd['rok_maturity']
resitel_edit.zasilat = fcd['zasilat'] resitel_edit.zasilat = fcd['zasilat']
resitel_edit.zasilat_cislo_emailem = fcd['zasilat_cislo_emailem'] resitel_edit.zasilat_cislo_emailem = fcd['zasilat_cislo_emailem']
resitel_edit.zasilat_cislo_papirove = fcd['zasilat_cislo_papirove']
if fcd.get('skola'): if fcd.get('skola'):
resitel_edit.skola = fcd['skola'] resitel_edit.skola = fcd['skola']
else: else:
@ -264,10 +265,11 @@ def prihlaskaView(request):
err_logger.warning(f'Zaregistrovala se osoba s kolizním jménem. ID osob: {[o.id for o in kolize]}') err_logger.warning(f'Zaregistrovala se osoba s kolizním jménem. ID osob: {[o.id for o in kolize]}')
r = s.Resitel( r = s.Resitel(
prezdivka_resitele=fcd['prezdivka_resitele'], prezdivka_resitele=fcd['prezdivka_resitele'] if fcd['prezdivka_resitele'] != "" else None,
rok_maturity = fcd['rok_maturity'], rok_maturity = fcd['rok_maturity'],
zasilat = fcd['zasilat'], zasilat = fcd['zasilat'],
zasilat_cislo_emailem = fcd['zasilat_cislo_emailem'] zasilat_cislo_emailem = fcd['zasilat_cislo_emailem'],
zasilat_cislo_papirove = fcd['zasilat_cislo_papirove'],
) )
if fcd.get('skola'): if fcd.get('skola'):
@ -284,7 +286,7 @@ def prihlaskaView(request):
except m.Resitel.DoesNotExist: except m.Resitel.DoesNotExist:
# Stejný trik: # Stejný trik:
orig_resitel = r orig_resitel = r
resitel_attrs = ['skola', 'rok_maturity', 'zasilat', 'zasilat_cislo_emailem'] resitel_attrs = ['skola', 'rok_maturity', 'zasilat', 'zasilat_cislo_emailem', 'zasilat_cislo_papirove']
for attr in resitel_attrs: for attr in resitel_attrs:
new = getattr(r, attr) new = getattr(r, attr)
old = getattr(orig_resitel, attr) old = getattr(orig_resitel, attr)
@ -345,6 +347,7 @@ def dataResiteluCsvResponse(queryset, columns=None, with_header=True):
'rok_maturity', 'rok_maturity',
'zasilat', 'zasilat',
'zasilat_cislo_emailem', 'zasilat_cislo_emailem',
'zasilat_cislo_papirove',
'osoba__datum_registrace', 'osoba__datum_registrace',
'osoba__datum_souhlasu_udaje', 'osoba__datum_souhlasu_udaje',
'osoba__datum_souhlasu_zasilani', 'osoba__datum_souhlasu_zasilani',

18
seminar/migrations/0112_prijemce_zasilat_cislo_emailem.py

@ -0,0 +1,18 @@
# Generated by Django 2.2.28 on 2023-04-17 18:38
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('seminar', '0111_nikam2nezasilat_papirove'),
]
operations = [
migrations.AddField(
model_name='prijemce',
name='zasilat_cislo_emailem',
field=models.BooleanField(default=False, help_text='True pokud chce příjemce dostávat číslo emailem', verbose_name='zasílat číslo emailem'),
),
]

42
seminar/migrations/0113_resitel_zasilat_cislo_papirove.py

@ -0,0 +1,42 @@
# Generated by Django 2.2.28 on 2023-03-13 22:02
from django.db import migrations, models
ZASILAT_DOMU = 'domu'
ZASILAT_DO_SKOLY = 'do_skoly'
ZASILAT_NIKAM = 'nikam'
def default_zasilat_papirove(apps, schema_editor):
Resitel = apps.get_model('seminar', 'Resitel')
for resitel in Resitel.objects.all():
resitel.zasilat_cislo_papirove = resitel.zasilat != ZASILAT_NIKAM
if resitel.zasilat == ZASILAT_NIKAM:
resitel.zasilat = ZASILAT_DOMU if resitel.osoba.ulice else ZASILAT_DO_SKOLY
resitel.save()
def vrat_nikam(apps, schema_editor):
Resitel = apps.get_model('seminar', 'Resitel')
for resitel in Resitel.objects.all():
if not resitel.zasilat_cislo_papirove:
resitel.zasilat = ZASILAT_NIKAM
resitel.save()
class Migration(migrations.Migration):
dependencies = [
('seminar', '0112_prijemce_zasilat_cislo_emailem'),
]
operations = [
migrations.AddField(
model_name='resitel',
name='zasilat_cislo_papirove',
field=models.BooleanField(default=True, help_text='True pokud chce řešitel dostávat číslo papírově', verbose_name='zasílat číslo papírově'),
),
migrations.RunPython(default_zasilat_papirove, vrat_nikam),
]

5
seminar/models/personalni.py

@ -192,6 +192,8 @@ class Prijemce(SeminarModelBase):
help_text='Které osobě či na jakou adresu se mají zasílat čísla', help_text='Které osobě či na jakou adresu se mají zasílat čísla',
on_delete=models.CASCADE) on_delete=models.CASCADE)
zasilat_cislo_emailem = models.BooleanField('zasílat číslo emailem', help_text='True pokud chce příjemce dostávat číslo emailem', default=False)
# FIXME: možná chceme něco jako vazbu na osobu XOR školu a počet kusů k zaslání # FIXME: možná chceme něco jako vazbu na osobu XOR školu a počet kusů k zaslání
# FIXME: a možná taky posílání na mail a možná taky přes něj chceme posílat i řešitelům # FIXME: a možná taky posílání na mail a možná taky přes něj chceme posílat i řešitelům
@ -236,6 +238,8 @@ class Resitel(SeminarModelBase):
zasilat_cislo_emailem = models.BooleanField('zasílat číslo emailem', help_text='True pokud chce řešitel dostávat číslo emailem', default=False) zasilat_cislo_emailem = models.BooleanField('zasílat číslo emailem', help_text='True pokud chce řešitel dostávat číslo emailem', default=False)
zasilat_cislo_papirove = models.BooleanField('zasílat číslo papírově', help_text='True pokud chce řešitel dostávat číslo papírově', default=True)
poznamka = models.TextField('neveřejná poznámka', blank=True, poznamka = models.TextField('neveřejná poznámka', blank=True,
help_text='Neveřejná poznámka k řešiteli (plain text)') help_text='Neveřejná poznámka k řešiteli (plain text)')
@ -402,6 +406,7 @@ class Organizator(SeminarModelBase):
editable=False editable=False
) )
# Ne, date to nebude. SQLite: invalid literal for int() with base 10: b'17 23:00:00'
organizuje_od = models.DateTimeField('Organizuje od', blank=True, null=True) organizuje_od = models.DateTimeField('Organizuje od', blank=True, null=True)
organizuje_do = models.DateTimeField('Organizuje do', blank=True, null=True) organizuje_do = models.DateTimeField('Organizuje do', blank=True, null=True)

12
seminar/models/tvorba.py

@ -265,6 +265,7 @@ class Cislo(SeminarModelBase):
poslat_z_mailu = 'zadani@mam.mff.cuni.cz' poslat_z_mailu = 'zadani@mam.mff.cuni.cz'
predmet = 'Vyšlo číslo {}'.format(self.kod()) predmet = 'Vyšlo číslo {}'.format(self.kod())
# TODO Možná nechceme všem psát „Ahoj“, např. příjemcům…
text_mailu = 'Ahoj,\n' \ text_mailu = 'Ahoj,\n' \
'na adrese {} najdete nejnovější číslo.\n' \ 'na adrese {} najdete nejnovější číslo.\n' \
'Vaše M&M\n'.format(odkaz) 'Vaše M&M\n'.format(odkaz)
@ -288,9 +289,14 @@ class Cislo(SeminarModelBase):
email.send() email.send()
posli(text_mailu, resitele_vsichni.filter(zasilat=pm.Resitel.ZASILAT_NIKAM)) paticka = "---\nK odběru těchto e-mailů jste se přihlásili na stránkách https://mam.matfyz.cz. Z odběru se lze odhlásit na https://mam.matfyz.cz/resitel/osobni-udaje/"
posli(text_mailu + 'P. S. Také by vám brzy měla přijít papírová verze. Připomínáme, že pokud papírovou verzi čísla nevyužijete, můžete v https://mam.mff.cuni.cz/resitel/osobni-udaje/ zaškrtnout, abychom vám ji neposílali. Děkujeme. (Čísla vždy můžete nalézt v našem archivu a dál vám budou chodit e-mailem.)\n',
resitele_vsichni.exclude(zasilat=pm.Resitel.ZASILAT_NIKAM)) posli(text_mailu + paticka, resitele_vsichni.filter(zasilat=pm.Resitel.zasilat_cislo_papirove))
posli(text_mailu + 'P. S. Brzy budeme též rozesílat papírovou verzi čísla. Připomínáme, že pokud papírovou verzi čísla nevyužijete, můžete v https://mam.mff.cuni.cz/resitel/osobni-udaje/ zaškrtnout, abychom vám ji neposílali. Čísla vždy můžete nalézt v našem archivu a dál vám budou chodit e-mailem. Děkujeme.\n' + paticka,
resitele_vsichni.exclude(zasilat=pm.Resitel.zasilat_cislo_papirove))
paticka_prijemce = "---\nPokud tyto e-maily nechcete nadále dostávat, prosíme, ozvěte se nám na mam@matfyz.cz."
posli(text_mailu + paticka_prijemce, pm.Prijemce.objects.filter(zasilat_cislo_emailem=True))
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
super().save(*args, **kwargs) super().save(*args, **kwargs)

2
seminar/templates/seminar/archiv/obalky.tex

@ -100,6 +100,7 @@
{% with o=r.osoba %} {% with o=r.osoba %}
{% with s=r.skola %} {% with s=r.skola %}
{% spaceless %} {% spaceless %}
{% if r.zasilat_cislo_papirove %}
{% if r.zasilat == "do_skoly" %} {% if r.zasilat == "do_skoly" %}
{% if o.stat == "CZ" %} {% if o.stat == "CZ" %}
\obalka{{o.jmeno|sloz}}{{o.prijmeni|sloz}}{{s.nazev|sloz}}{{s.ulice|sloz}}{{s.psc|sloz}}{{s.mesto|sloz}}{{''|sloz}} \obalka{{o.jmeno|sloz}}{{o.prijmeni|sloz}}{{s.nazev|sloz}}{{s.ulice|sloz}}{{s.psc|sloz}}{{s.mesto|sloz}}{{''|sloz}}
@ -115,6 +116,7 @@
{% endif %} {% endif %}
{% else %} {% else %}
{% endif %} {% endif %}
{% endif %}
{% endspaceless %} {% endspaceless %}
{% endwith %} {% endwith %}
{% endwith %} {% endwith %}

2
seminar/utils.py

@ -265,7 +265,7 @@ def merge_resitele(cilovy, zdrojovy):
# Postup: # Postup:
# Sjednotit / upravit informace cílového řešitele # Sjednotit / upravit informace cílového řešitele
print('Upravuji data modelu') print('Upravuji data modelu')
fieldy_shoda = ['skola', 'rok_maturity', 'zasilat', 'zasilat_cislo_emailem'] fieldy_shoda = ['skola', 'rok_maturity', 'zasilat', 'zasilat_cislo_emailem', 'zasilat_cislo_papirove']
for f in fieldy_shoda: for f in fieldy_shoda:
zf = getattr(zdrojovy, f) zf = getattr(zdrojovy, f)

14
various/mail_prefixer.py

@ -7,6 +7,11 @@ Used to distinguish testing emails from production ones."""
from django.core.mail.backends.smtp import EmailBackend as DjangoSMTPBackend from django.core.mail.backends.smtp import EmailBackend as DjangoSMTPBackend
from django.conf import settings from django.conf import settings
def omezovatko_poctu_mailu(maily:list, maximum:int) -> str:
if len(maily) <= maximum: return str(maily)
# Aspoň zhruba simulujeme tisk pole…
return '[' + ", ".join(f"'{mail}'" for mail in maily[:maximum - 1]) + f', … ({len(maily)} e-mailů) ]'
class PrefixingMailBackend(DjangoSMTPBackend): class PrefixingMailBackend(DjangoSMTPBackend):
# method _send is not probably meant to be monkey_patched, so we patch send_messages instead. # method _send is not probably meant to be monkey_patched, so we patch send_messages instead.
def send_messages(self, messages): def send_messages(self, messages):
@ -16,10 +21,13 @@ class PrefixingMailBackend(DjangoSMTPBackend):
if message.from_email != settings.SERVER_EMAIL: if message.from_email != settings.SERVER_EMAIL:
message.subject = prefix + ' ' + message.subject message.subject = prefix + ' ' + message.subject
to = omezovatko_poctu_mailu(message.to, 3)
cc = omezovatko_poctu_mailu(message.cc, 3)
bcc = omezovatko_poctu_mailu(message.bcc, 3)
message.body = f"""Bylo by posláno na e-maily: message.body = f"""Bylo by posláno na e-maily:
To: {message.to} To: {to}
Cc: {message.cc} Cc: {cc}
Bcc: {message.bcc} Bcc: {bcc}
"""+ "\n\n" + message.body """+ "\n\n" + message.body
message.to = settings.TESTOVACI_EMAILOVA_KONFERENCE message.to = settings.TESTOVACI_EMAILOVA_KONFERENCE
message.cc = [] message.cc = []

33
various/utils.py

@ -0,0 +1,33 @@
bez_diakritiky = ({}
# FIXME: funguje jen pro český a slovenský text, jinak jsou špatně
# transliterace. Potenciální řešení:
# https://stackoverflow.com/questions/517923/what-is-the-best-way-to-remove-accents-normalize-in-a-python-unicode-string
# (ale přidává to další závislosti…)
# Tisknutelné ASCII
| {chr(a): chr(a) for a in range(32, 126+1)}
# České, slovenské a blízké diakritiky a divnoznaky
| { x: 'a' for x in 'áÁäÄ'}
| { x: 'c' for x in 'čČ'}
| { x: 'd' for x in 'ďĎ'}
| { x: 'e' for x in 'éÉěĚëË'}
| { x: 'i' for x in 'íÍ'}
| { x: 'l' for x in 'ľĽĺĹ'}
| { x: 'n' for x in 'ňŇ'}
| { x: 'o' for x in 'óÓöÖôÔ'}
| { x: 'r' for x in 'řŘŕŔ'}
| { x: 's' for x in 'šŠßẞ'}
| { x: 't' for x in 'ťŤ'}
| { x: 'u' for x in 'úÚůŮ'}
| { x: 'y' for x in 'ýÝ'}
| { x: 'z' for x in 'žŽ'}
)
# Tabulka pro str.translate
class _bez_diakritiky_translate:
def __getitem__(self, it):
return ord(bez_diakritiky.get(chr(it), None))
bez_diakritiky_translate = _bez_diakritiky_translate()
# TODO: testy?
Loading…
Cancel
Save