# Path: pypi_portal/extensions.py
# LOG = getLogger(__name__)
# def _on_connect(dbapi_connection, **_):
# 
# Path: pypi_portal/models/redis.py
# EMAIL_THROTTLE = 'pypi_portal:email_throttle:{md5}'  # Lock.


from contextlib import contextmanager
from logging import getLogger
from flask import current_app
from flask.ext.mail import Message
from werkzeug.debug import tbtools
from pypi_portal.extensions import mail, redis
from pypi_portal.models.redis import EMAIL_THROTTLE
import hashlib
        LOG.debug('Suppressing email: {}'.format(subject))
        return

    # Send email.
    msg = Message(subject=subject, recipients=current_app.config['ADMINS'], html=html)
    mail.send(msg)


def send_email(subject, body=None, html=None, recipients=None, throttle=None):
    """Send an email. Optionally throttle the amount an identical email goes out.

    If the throttle argument is set, an md5 checksum derived from the subject, body, html, and recipients is stored in
    Redis with a lock timeout. On the first email sent, the email goes out like normal. But when other emails with the
    same subject, body, html, and recipients is supposed to go out, and the lock hasn't expired yet, the email will be
    dropped and never sent.

    Positional arguments:
    subject -- the subject line of the email.

    Keyword arguments.
    body -- the body of the email (no HTML).
    html -- the body of the email, can be HTML (overrides body).
    recipients -- list or set (not string) of email addresses to send the email to. Defaults to the ADMINS list in the
        Flask config.
    throttle -- time in seconds or datetime.timedelta object between sending identical emails.
    """
    recipients = recipients or current_app.config['ADMINS']
    if throttle is not None:
        md5 = hashlib.md5('{}{}{}{}'.format(subject, body, html, recipients)).hexdigest()
        seconds = throttle.total_seconds() if hasattr(throttle, 'total_seconds') else throttle

# Path: pypi_portal/extensions.py
# LOG = getLogger(__name__)
# def _on_connect(dbapi_connection, **_):
# 
# Path: pypi_portal/models/redis.py
# EMAIL_THROTTLE = 'pypi_portal:email_throttle:{md5}'  # Lock.


# Path: pypi_portal/core/email.py
from contextlib import contextmanager
from logging import getLogger
from flask import current_app
from flask.ext.mail import Message
from werkzeug.debug import tbtools
from pypi_portal.extensions import mail, redis
from pypi_portal.models.redis import EMAIL_THROTTLE
import hashlib

        LOG.debug('Suppressing email: {}'.format(subject))
        return

    # Send email.
    msg = Message(subject=subject, recipients=current_app.config['ADMINS'], html=html)
    mail.send(msg)


def send_email(subject, body=None, html=None, recipients=None, throttle=None):
    """Send an email. Optionally throttle the amount an identical email goes out.

    If the throttle argument is set, an md5 checksum derived from the subject, body, html, and recipients is stored in
    Redis with a lock timeout. On the first email sent, the email goes out like normal. But when other emails with the
    same subject, body, html, and recipients is supposed to go out, and the lock hasn't expired yet, the email will be
    dropped and never sent.

    Positional arguments:
    subject -- the subject line of the email.

    Keyword arguments.
    body -- the body of the email (no HTML).
    html -- the body of the email, can be HTML (overrides body).
    recipients -- list or set (not string) of email addresses to send the email to. Defaults to the ADMINS list in the
        Flask config.
    throttle -- time in seconds or datetime.timedelta object between sending identical emails.
    """
    recipients = recipients or current_app.config['ADMINS']
    if throttle is not None:
        md5 = hashlib.md5('{}{}{}{}'.format(subject, body, html, recipients)).hexdigest()
        seconds = throttle.total_seconds() if hasattr(throttle, 'total_seconds') else throttle

        lock = redis.lock(EMAIL_THROTTLE.format(md5=md5), timeout=int(seconds))