# Path: amivapi/utils.py
# def mail(to, subject, text):
#     """Send a mail to a list of recipients.
# 
#     The mail is sent from the address specified by `API_MAIL` in the config,
#     and the subject formatted according to `API_MAIL_SUBJECT`.
# 
# 
#     Args:
#         to(list of strings): List of recipient addresses
#         subject(string): Subject string
#         text(string): Mail content
#     """
#     sender = app.config['API_MAIL']
#     subject = app.config['API_MAIL_SUBJECT'].format(subject=subject)
# 
#     if app.config.get('TESTING', False):
#         app.test_mails.append({
#             'subject': subject,
#             'from': sender,
#             'receivers': to,
#             'text': text
#         })
#     elif config.SMTP_SERVER and config.SMTP_PORT:
#         msg = MIMEText(text)
#         msg['Subject'] = subject
#         msg['From'] = sender
#         msg['To'] = ';'.join([to] if isinstance(to, str) else to)
# 
#         try:
#             with smtplib.SMTP(config.SMTP_SERVER,
#                               port=config.SMTP_PORT,
#                               timeout=config.SMTP_TIMEOUT) as smtp:
#                 status_code, _ = smtp.starttls()
#                 if status_code != 220:
#                     app.logger.error("Failed to create secure "
#                                      "SMTP connection!")
#                     return
# 
#                 if config.SMTP_USERNAME and config.SMTP_PASSWORD:
#                     smtp.login(config.SMTP_USERNAME, config.SMTP_PASSWORD)
#                 else:
#                     smtp.ehlo()
# 
#                 try:
#                     smtp.sendmail(msg['From'], to, msg.as_string())
#                 except smtplib.SMTPRecipientsRefused:
#                     error = ("Failed to send mail:\n"
#                              "From: %s\nTo: %s\n"
#                              "Subject: %s\n\n%s")
#                     app.logger.error(error % (sender, str(to), subject, text))
#         except smtplib.SMTPException as e:
#             app.logger.error("SMTP error trying to send mails: %s" % e)
# 
# Path: amivapi/cron.py
# def schedulable(func):
#     """ Registers a function to be in the table of schedulable functions.
#     This is necessary, as we can not save references to python functions in the
#     database.
#     """
#     schedulable_functions[func_str(func)] = func
#     return func
# 
# def schedule_task(time, func, *args):
#     """ Schedule a task at some point in the future. """
#     func_s = func_str(func)
# 
#     if func_s not in schedulable_functions:
#         raise NotSchedulable("%s is not schedulable. Did you forget the "
#                              "@schedulable decorator?" % func.__name__)
# 
#     current_app.data.driver.db['scheduled_tasks'].insert_one({
#         'time': time,
#         'function': func_s,
#         'args': pickle.dumps(args)
#     })


from flask import current_app
from amivapi.utils import mail
from datetime import datetime
from amivapi.cron import schedulable, schedule_task
Send emails to users when they have a new entry on the blacklist or one of their
entries get resolved/deleted.
"""





def _get_email(item):
    """Retrieve the user email for a blacklist entry."""
    id_field = current_app.config['ID_FIELD']
    lookup = {id_field: item['user']}
    user = current_app.data.find_one('users', None, **lookup)
    return user['email']


@schedulable
def send_removed_mail(item):
    """Send scheduled email when a blacklist entry times out."""
    _item = current_app.data.find_one('blacklist', None, {"_id": item['_id']})
    # Check that the end date is still correct and has not changed again
    if _item is None:
        return  # Entry was deleted, no mail to send anymore
    if _item.get('end_time') is None:
        return  # Entry was patched to last indefinitely, so no mail to send.
    if _item['end_time'].replace(tzinfo=None) != item['end_time']:
        return  # Entry was edited, so this is outdated.

    email = _get_email(_item)
    fields = {'reason': _item['reason']}

# Path: amivapi/utils.py
# def mail(to, subject, text):
#     """Send a mail to a list of recipients.
# 
#     The mail is sent from the address specified by `API_MAIL` in the config,
#     and the subject formatted according to `API_MAIL_SUBJECT`.
# 
# 
#     Args:
#         to(list of strings): List of recipient addresses
#         subject(string): Subject string
#         text(string): Mail content
#     """
#     sender = app.config['API_MAIL']
#     subject = app.config['API_MAIL_SUBJECT'].format(subject=subject)
# 
#     if app.config.get('TESTING', False):
#         app.test_mails.append({
#             'subject': subject,
#             'from': sender,
#             'receivers': to,
#             'text': text
#         })
#     elif config.SMTP_SERVER and config.SMTP_PORT:
#         msg = MIMEText(text)
#         msg['Subject'] = subject
#         msg['From'] = sender
#         msg['To'] = ';'.join([to] if isinstance(to, str) else to)
# 
#         try:
#             with smtplib.SMTP(config.SMTP_SERVER,
#                               port=config.SMTP_PORT,
#                               timeout=config.SMTP_TIMEOUT) as smtp:
#                 status_code, _ = smtp.starttls()
#                 if status_code != 220:
#                     app.logger.error("Failed to create secure "
#                                      "SMTP connection!")
#                     return
# 
#                 if config.SMTP_USERNAME and config.SMTP_PASSWORD:
#                     smtp.login(config.SMTP_USERNAME, config.SMTP_PASSWORD)
#                 else:
#                     smtp.ehlo()
# 
#                 try:
#                     smtp.sendmail(msg['From'], to, msg.as_string())
#                 except smtplib.SMTPRecipientsRefused:
#                     error = ("Failed to send mail:\n"
#                              "From: %s\nTo: %s\n"
#                              "Subject: %s\n\n%s")
#                     app.logger.error(error % (sender, str(to), subject, text))
#         except smtplib.SMTPException as e:
#             app.logger.error("SMTP error trying to send mails: %s" % e)
# 
# Path: amivapi/cron.py
# def schedulable(func):
#     """ Registers a function to be in the table of schedulable functions.
#     This is necessary, as we can not save references to python functions in the
#     database.
#     """
#     schedulable_functions[func_str(func)] = func
#     return func
# 
# def schedule_task(time, func, *args):
#     """ Schedule a task at some point in the future. """
#     func_s = func_str(func)
# 
#     if func_s not in schedulable_functions:
#         raise NotSchedulable("%s is not schedulable. Did you forget the "
#                              "@schedulable decorator?" % func.__name__)
# 
#     current_app.data.driver.db['scheduled_tasks'].insert_one({
#         'time': time,
#         'function': func_s,
#         'args': pickle.dumps(args)
#     })


# Path: amivapi/blacklist/emails.py
from flask import current_app
from amivapi.utils import mail
from datetime import datetime
from amivapi.cron import schedulable, schedule_task

Send emails to users when they have a new entry on the blacklist or one of their
entries get resolved/deleted.
"""





def _get_email(item):
    """Retrieve the user email for a blacklist entry."""
    id_field = current_app.config['ID_FIELD']
    lookup = {id_field: item['user']}
    user = current_app.data.find_one('users', None, **lookup)
    return user['email']


@schedulable
def send_removed_mail(item):
    """Send scheduled email when a blacklist entry times out."""
    _item = current_app.data.find_one('blacklist', None, {"_id": item['_id']})
    # Check that the end date is still correct and has not changed again
    if _item is None:
        return  # Entry was deleted, no mail to send anymore
    if _item.get('end_time') is None:
        return  # Entry was patched to last indefinitely, so no mail to send.
    if _item['end_time'].replace(tzinfo=None) != item['end_time']:
        return  # Entry was edited, so this is outdated.

    email = _get_email(_item)
    fields = {'reason': _item['reason']}

    mail(email,