Merge remote-tracking branch 'gitea/master' into zadavatko_problemu
This commit is contained in:
commit
cd0a3b644a
22 changed files with 376 additions and 385 deletions
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
Normal file
0
odevzdavatko/templatetags/__init__.py
Normal file
9
odevzdavatko/templatetags/jmena.py
Normal file
9
odevzdavatko/templatetags/jmena.py
Normal file
|
@ -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(' ', '_')
|
|
@ -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')
|
||||||
|
|
|
@ -25,106 +25,85 @@ 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--text' : '---',
|
'data-placeholder--id': '-1',
|
||||||
'data-allow-clear': 'true'})
|
'data-placeholder--text': '---',
|
||||||
,required=False)
|
'data-allow-clear': 'true'
|
||||||
|
}
|
||||||
|
),
|
||||||
|
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)
|
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)
|
||||||
|
zasilat_cislo_papirove = forms.BooleanField(label='Chci dostávat čísla poštou (zasílání není zpoplatněno)', required=False, initial=False)
|
||||||
gdpr = forms.BooleanField(label='Souhlasím se zpracováním osobních údajů', required=True)
|
zasilat_cislo_emailem = forms.BooleanField(label='Chci dostávat e-mailem upozornění na vydání nového čísla', required=False, initial=True)
|
||||||
spam = forms.BooleanField(label='Souhlasím se zasíláním materiálů od MFF UK', required=False)
|
spam = forms.BooleanField(label='Souhlasím se zasíláním propagačních 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_email(self):
|
|
||||||
err_logger = logging.getLogger('seminar.prihlaska.problem')
|
|
||||||
email = self.cleaned_data.get('email')
|
|
||||||
try:
|
|
||||||
osoba = Osoba.objects.get(email=email)
|
|
||||||
msg = "Email {} exists".format(email)
|
|
||||||
if osoba.user is not None:
|
|
||||||
err_logger.info(msg)
|
|
||||||
raise forms.ValidationError('E-mail je již použit')
|
|
||||||
else:
|
|
||||||
msg += ', but currently has no User, so allowing registration.'
|
|
||||||
err_logger.info(msg)
|
|
||||||
|
|
||||||
except ObjectDoesNotExist:
|
|
||||||
pass
|
|
||||||
return email
|
|
||||||
|
|
||||||
def clean_prezdivka_resitele(self):
|
def clean_prezdivka_resitele(self):
|
||||||
prezdivka_resitele = self.cleaned_data.get('prezdivka_resitele')
|
prezdivka_resitele = self.cleaned_data.get('prezdivka_resitele')
|
||||||
if prezdivka_resitele == '':
|
if prezdivka_resitele == '':
|
||||||
return prezdivka_resitele
|
return prezdivka_resitele
|
||||||
if Resitel.objects.filter(prezdivka_resitele=prezdivka_resitele).count() > 0:
|
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')
|
raise forms.ValidationError('Přezdívka je již použita')
|
||||||
return prezdivka_resitele
|
return prezdivka_resitele
|
||||||
|
|
||||||
|
def clean_email(self):
|
||||||
|
email = self.cleaned_data.get('email')
|
||||||
|
try:
|
||||||
|
osoba = Osoba.objects.exclude(user__username=self.username).get(email=email)
|
||||||
|
msg = "Email {} exists".format(email)
|
||||||
|
if osoba.user is not None:
|
||||||
|
self.err_logger.info(msg)
|
||||||
|
raise forms.ValidationError('E-mail je již použit')
|
||||||
|
else:
|
||||||
|
msg += ', but currently has no User, so allowing registration.'
|
||||||
|
self.err_logger.info(msg)
|
||||||
|
|
||||||
|
except ObjectDoesNotExist:
|
||||||
|
pass
|
||||||
|
return email
|
||||||
|
|
||||||
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') != '':
|
||||||
|
@ -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",
|
class PrihlaskaForm(PasswordResetForm, UdajeForm):
|
||||||
queryset=Skola.objects.all(),
|
username = forms.CharField(
|
||||||
widget=autocomplete.ModelSelect2(
|
label='Přihlašovací jméno',
|
||||||
url='autocomplete_skola',
|
max_length=256,
|
||||||
attrs = {'data-placeholder--id': '-1',
|
required=True,
|
||||||
'data-placeholder--text' : '---',
|
help_text='Tímto jménem se následně budeš přihlašovat pro odevzdání řešení a další činnosti v semináři',
|
||||||
'data-allow-clear': 'true'})
|
)
|
||||||
,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)
|
||||||
|
|
||||||
skola_nazev = forms.CharField(label='Název školy', max_length=256, required=False)
|
def clean_username(self):
|
||||||
skola_adresa = forms.CharField(label='Adresa školy', max_length=256, required=False)
|
username = self.cleaned_data.get('username')
|
||||||
|
|
||||||
# trida = forms.CharField(label='Třída',max_length=10, required=True)
|
|
||||||
|
|
||||||
rok_maturity = forms.IntegerField(
|
|
||||||
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):
|
|
||||||
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):
|
|
||||||
err_logger = logging.getLogger('seminar.prihlaska.problem')
|
|
||||||
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()
|
|
||||||
#
|
|
||||||
# err_logger = logging.getLogger('seminar.prihlaska.problem')
|
|
||||||
|
|
||||||
# data = self.cleaned_data
|
|
||||||
# if data.get('password') != data.get('password_check'):
|
class ProfileEditForm(UdajeForm):
|
||||||
# self.add_error('password_check',forms.ValidationError('Hesla se neshodují'))
|
err_logger = logging.getLogger('seminar.edit.problem')
|
||||||
# if data.get('stat') != '' and data.get('stat_text') != '':
|
username = forms.CharField(
|
||||||
# self.add_error('stat',forms.ValidationError('Nelze mít vybraný stát z menu a zároven zapsaný textem'))
|
label='Přihlašovací jméno',
|
||||||
# if data.get('skola') and (data.get('skola_nazev') or data.get('skola_adresa')):
|
max_length=256,
|
||||||
# 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)'))
|
required=False,
|
||||||
# if not data.get('skola'):
|
disabled=True,
|
||||||
# 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):
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<p><a href="{% url 'reset_password' %}">Změnit heslo</a></p>
|
||||||
|
|
||||||
<form action="{% url 'seminar_resitel_edit' %}" method="post">
|
<form action="{% url 'seminar_resitel_edit' %}" method="post">
|
||||||
{% csrf_token %}
|
{% include "personalni/udaje/udaje.html"%}
|
||||||
{{form.non_field_errors}}
|
<input type="submit" value="Změnit">
|
||||||
|
|
||||||
<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>
|
|
||||||
|
|
||||||
<input type="submit" value="Změnit">
|
|
||||||
</form>
|
</form>
|
||||||
<script>
|
|
||||||
$("#id_stat").on("change",addrCountryChanged);
|
|
||||||
$("#id_skola_text_button").on("click",schoolNotInList);
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -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,109 +15,26 @@
|
||||||
<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}}
|
<h4>
|
||||||
|
GDPR
|
||||||
|
</h4>
|
||||||
|
{% include "personalni/udaje/gdpr.html" %}
|
||||||
|
<table class="form">
|
||||||
|
{% include "personalni/udaje/prihlaska_field.html" with field=form.gdpr %}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
<hr>
|
<h4>
|
||||||
<h4>
|
Ostatní
|
||||||
Přihlašovací údaje
|
</h4>
|
||||||
</h4>
|
<table class="form">
|
||||||
<table class="form">
|
{% include "personalni/udaje/prihlaska_field.html" with field=form.jak_se_dozvedeli %}
|
||||||
{% include "personalni/udaje/prihlaska_field.html" with field=form.username %}
|
</table>
|
||||||
{# {% include "personalni/udaje/prihlaska_field.html" with field=form.password %}#}
|
|
||||||
{# {% include "personalni/udaje/prihlaska_field.html" with field=form.password_check %}#}
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<h4>
|
<input type="submit" value="Odeslat">
|
||||||
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í – 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>
|
|
||||||
GDPR
|
|
||||||
</h4>
|
|
||||||
{% include "personalni/udaje/gdpr.html" %}
|
|
||||||
<table class="form">
|
|
||||||
{% include "personalni/udaje/prihlaska_field.html" with field=form.gdpr %}
|
|
||||||
</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>
|
|
||||||
|
|
||||||
<h4>
|
|
||||||
Ostatní
|
|
||||||
</h4>
|
|
||||||
<table class="form">
|
|
||||||
{% include "personalni/udaje/prihlaska_field.html" with field=form.jak_se_dozvedeli %}
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<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
Normal file
75
personalni/templates/personalni/udaje/udaje.html
Normal file
|
@ -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í – 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
Normal file
11
personalni/utils.py
Normal file
|
@ -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
|
||||||
|
|
|
@ -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
Normal file
18
seminar/migrations/0112_prijemce_zasilat_cislo_emailem.py
Normal file
|
@ -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
Normal file
42
seminar/migrations/0113_resitel_zasilat_cislo_papirove.py
Normal file
|
@ -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),
|
||||||
|
]
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 %}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
Normal file
33
various/utils.py
Normal file
|
@ -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…
Reference in a new issue