Select Git revision
fib-test.py
-
Martin Mareš authoredMartin Mareš authored
email.py 4.79 KiB
# Rozesílání e-mailových notifikací všeho druhu
import datetime
import email.message
import email.headerregistry
import subprocess
import textwrap
import urllib.parse
import mo.db as db
import mo.config as config
from mo.util import logger
def send_user_email(user: db.User, subject: str, body: str) -> bool:
logger.info(f'Mail: "{subject}" -> {user.email}')
mail_from = getattr(config, 'MAIL_FROM', None)
if mail_from is None:
logger.error('Mail: V configu chybí nastavení MAIL_FROM')
return False
msg = email.message.EmailMessage()
msg['From'] = email.headerregistry.Address(
display_name='Odevzdávací Systém MO',
addr_spec=mail_from,
)
msg['To'] = [
email.headerregistry.Address(
display_name=user.full_name(),
addr_spec=user.email,
)
]
msg['Reply-To'] = email.headerregistry.Address(
display_name='Správce OSMO',
addr_spec=config.MAIL_CONTACT,
)
msg['Subject'] = 'OSMO – ' + subject
msg['Date'] = datetime.datetime.now()
msg.set_content(body, cte='quoted-printable')
mail_instead = getattr(config, 'MAIL_INSTEAD', None)
if mail_instead is None:
send_to = user.email
else:
send_to = mail_instead
sm = subprocess.Popen(
[
'/usr/sbin/sendmail',
'-oi',
'-f',
mail_from,
send_to,
],
stdin=subprocess.PIPE,
)
sm.communicate(msg.as_bytes())
if sm.returncode != 0:
logger.error('Mail: Sendmail failed with return code {}'.format(sm.returncode))
return False
return True
def activate_url(token: str) -> str:
return config.WEB_ROOT + 'acct/activate?' + urllib.parse.urlencode({'token': token}, safe=':')
def confirm_url(type: str, token: str) -> str:
return config.WEB_ROOT + f'acct/confirm/{type}?' + urllib.parse.urlencode({'token': token}, safe=':')
def contestant_list_url(contest: db.Contest, registered_only: bool) -> str:
url = config.WEB_ROOT + f'org/contest/c/{contest.contest_id}/participants'
if registered_only:
url += '?participation_state=registered'
return url
def send_new_account_email(user: db.User, token: str) -> bool:
return send_user_email(user, 'Založen nový účet', textwrap.dedent('''\
Vítejte!
Právě Vám byl založen účet v Odevzdávacím systému Matematické olympiády.
Nastavte si prosím heslo na následující stránce:
{}
Váš OSMO
'''.format(activate_url(token))))
def send_password_reset_email(user: db.User, token: str) -> bool:
return send_user_email(user, 'Obnova hesla', textwrap.dedent('''\
Někdo (pravděpodobně Vy) požádal o obnovení hesla k Vašemu účtu v Odevzdávacím
systému Matematické olympiády. Heslo si můžete nastavit, případně požadavek
zrušit, na následující stránce:
{}
Váš OSMO
'''.format(confirm_url('p', token))))
def send_confirm_create_email(user: db.User, token: str) -> bool:
return send_user_email(user, 'Založení účtu', textwrap.dedent('''\
Někdo (pravděpodobně Vy) požádal o založení účtu s touto e-mailovou adresou
v Odevzdávacím systému Matematické olympiády. Pokud účet chcete založit,
následujte tento odkaz:
{}
Váš OSMO
'''.format(confirm_url('r', token))))
def send_confirm_change_email(user: db.User, token: str) -> bool:
return send_user_email(user, 'Změna e-mailové adresy', textwrap.dedent('''\
Někdo (pravděpodobně Vy) požádal o nastavení e-mailové adresy k účtu
v Odevzdávacím systému Matematické olympiády na tuto adresu.
Pokud změnu chcete provést, následujte tento odkaz:
{}
Váš OSMO
'''.format(confirm_url('e', token))))
def send_join_notify_email(dest: db.User, who: db.User, contest: db.Contest) -> bool:
round = contest.round
place = contest.place
if contest.round.enroll_mode == db.RoundEnrollMode.confirm:
confirm = 'Přihlášku je potřeba potvrdit v seznamu účastníků soutěže.'
url = 'Přihlášky k potvrzení: ' + contestant_list_url(contest, True)
else:
confirm = 'Přihláška byla schválena automaticky.'
url = 'Seznam účastníků: ' + contestant_list_url(contest, False)
return send_user_email(dest, f'Nový účastník kategorie {round.category}', textwrap.dedent(f'''\
Nový účastník se přihlásil do MO v oblasti, kterou garantujete.
Jméno: {who.full_name()}
E-mail: {who.email}
Kategorie: {round.category}
Kolo: {round.name}
Místo: {place.name}
{confirm}
{url}
Váš OSMO
'''))