<filename>send_mail/tasks.py
"""
Defines email sending tasks that will run in the background with Huey

Author: <NAME> & <NAME> & <NAME> (lxy5611)

All db_tasks will retry at most 3 times.
"""
from petitions.models import *
from profile.models import Profile
from django.conf import settings
from django.db.models import Q
from django.core.mail import EmailMessage
from django.template.loader import get_template
from django.template import Context
from huey.contrib.djhuey import db_task
import time
import logging

logger = logging.getLogger("pawprints." + __name__)

email_titles = settings.CONFIG['email']
EMAIL_ADDR = settings.EMAIL_EMAIL_ADDR
ORGANIZATION = settings.CONFIG['organization']
COLORS = settings.CONFIG['email']['colors']
ORG_LOGO = settings.CONFIG['org_logo']
NAME = settings.CONFIG['name']
HEADER_IMAGE = settings.CONFIG['email']['header_image']


class EmailTitles():
    Petition_Approved = email_titles['approved']
    Petition_Charged = email_titles['charged']
    Petition_Needs_Approval = email_titles['needs_approval']
    Petition_Reached = email_titles['reached']
    Petition_Received = email_titles['received']
    Petition_Rejected = email_titles['rejected']
    Petition_Reported = email_titles['reported']
    Petition_Responded = email_titles['responded']
    Petition_Update = email_titles['updated']


def generate_email(petition_id, event, site_path, to=None, bcc=None, email_data=None):
    petition = Petition.objects.get(pk=petition_id)

    if event in email_titles:
        to = petition.author.email if to is None else to

        if email_data is None:
            email_data = {
                'petition_id': petition.id,
                'title': petition.title,
                'first_name': petition.author.first_name,
                'author': petition.author.profile.full_name,
                'site_path': site_path,
                'protocol': 'https',
                'timestamp': time.strftime('[%H:%M:%S %d/%m/%Y]') + ' End of message.',
                'organization': ORGANIZATION,
                'email_header': COLORS['email_header'],
                'org_logo': ORG_LOGO,
                'name': NAME,
                'header_image': HEADER_IMAGE
            }
        email = EmailMessage(
            email_titles[event],
            get_template('email_inlined/petition_' + event + '.html').render(email_data),
            EMAIL_ADDR,
            [to],
            bcc=bcc,
        )
        email.content_subtype = "html"
        return email
    return None


def send_email(email, petition_id, event):
    try:
        email.send()
        logger.info(
            "Petition " + event + " email SEND \nPetition ID: " + str(petition_id))
    except Exception as e:
        logger.critical(
            "Petition " + event + " email FAILED \nPetition ID: " + str(petition_id), exc_info=True)
        raise e


@db_task(retries=3, retry_delay=3)
def petition_approved(petition_id, site_path):
    email = generate_email(petition_id, 'approved', site_path)
    send_email(email, petition_id, 'Approved')


@db_task(retries=3, retry_delay=3)
def petition_rejected(petition_id, site_path):
    email = generate_email(petition_id, 'rejected', site_path)
    send_email(email, petition_id, 'Rejected')


@db_task(retries=3, retry_delay=3)
def petition_update(petition_id, site_path):
    petition = Petition.objects.get(pk=petition_id)

    # Gets all users that are subscribed or have signed the petition and if they want to receive email updates.
    users = Profile.objects.filter(Q(subscriptions=petition) | Q(petitions_signed=petition)).filter(
        notifications__update=True).distinct("id")

    # Construct array of email addresses
    recipients = [prof.user.email for prof in users]

    email = generate_email(petition_id, 'updated', site_path, EMAIL_ADDR, recipients)
    send_email(email, petition_id, 'Status Update')


@db_task(retries=3, retry_delay=3)
def petition_responded(petition_id, site_path):
    petition = Petition.objects.get(pk=petition_id)

    # Gets all users that are subscribed or have signed the petition and if they want to receive email updates.
    users = Profile.objects.filter(Q(subscriptions=petition) | Q(petitions_signed=petition)).filter(
        notifications__response=True).distinct("id")

    # Construct array of email addresses
    recipients = [prof.user.email for prof in users]

    email = generate_email(petition_id, 'responded', site_path, EMAIL_ADDR, recipients)
    send_email(email, petition_id, 'Response Received')


@db_task(retries=3, retry_delay=3)
def petition_reached(petition_id, site_path):
    petition = Petition.objects.get(pk=petition_id)

    # Gets all users that are subscribed or have signed the petition and if they want to receive emails about petition response.
    users = Profile.objects.filter(
        Q(subscriptions=petition) |
        Q(petitions_signed=petition) |
        Q(notifications__threshold=True)
    ).filter(notifications__response=True).distinct("id")

    # Construct array of email addresses
    recipients = [prof.user.email for prof in users]

    email = generate_email(petition_id, 'reached', site_path, EMAIL_ADDR, recipients)
    send_email(email, petition_id, 'Threshold Reached')


@db_task(retries=3, retry_delay=3)
def petition_received(petition_id, site_path):
    email = generate_email(petition_id, 'received', site_path)
    send_email(email, petition_id, 'Received')

@db_task(retries=3, retry_delay=3)
def petition_charged(petition_id, site_path):
    email = generate_email(petition_id, 'charged', site_path)
    send_email(email, petition_id, 'Charged')


@db_task(retries=3, retry_delay=3)
def petition_needs_approval(petition_id, site_path):
    email = generate_email(petition_id, 'needs_approval', site_path)
    send_email(email, petition_id, 'Needs Approval')


@db_task(retries=3, retry_delay=3)
def petition_reported(petition_id, report_id, site_path):
    petition = Petition.objects.get(pk=petition_id)
    report = Report.objects.get(pk=report_id)
    reporter = User.objects.get(pk=report.reporter_id)

    # Gets all users that are on the email list for reported petitions.
    users = Profile.objects.filter(notifications__reported=True).distinct("id")

    # Construct array of email addresses
    recipients = [prof.user.email for prof in users]

    email_data = {
                    'petition_id': petition.id,
                    'title': petition.title,
                    'first_name': petition.author.first_name,
                    'author': petition.author.profile.full_name,
                    'reason': report.reported_for,
                    'reporter': reporter.profile.display_name,
                    'site_path': site_path,
                    'protocol': 'https',
                    'timestamp': time.strftime('[%H:%M:%S %d/%m/%Y]') + ' End of message',
                    'organization': ORGANIZATION,
                    'email_header': COLORS['email_header'],
                    'org_logo': ORG_LOGO,
                    'name': NAME,
                    'header_image': HEADER_IMAGE
                 }
    email = generate_email(petition_id, 'reported', site_path, EMAIL_ADDR, recipients, email_data)
    send_email(email, petition_id, 'Reported')

<filename>send_mail/tasks.py
"""
Defines email sending tasks that will run in the background with Huey

Author: <NAME> & <NAME> & <NAME> (lxy5611)

All db_tasks will retry at most 3 times.
"""
from petitions.models import *
from profile.models import Profile
from django.conf import settings
from django.db.models import Q
from django.core.mail import EmailMessage
from django.template.loader import get_template
from django.template import Context
from huey.contrib.djhuey import db_task
import time
import logging

logger = logging.getLogger("pawprints." + __name__)

email_titles = settings.CONFIG['email']
EMAIL_ADDR = settings.EMAIL_EMAIL_ADDR
ORGANIZATION = settings.CONFIG['organization']
COLORS = settings.CONFIG['email']['colors']
ORG_LOGO = settings.CONFIG['org_logo']
NAME = settings.CONFIG['name']
HEADER_IMAGE = settings.CONFIG['email']['header_image']


class EmailTitles():
    Petition_Approved = email_titles['approved']
    Petition_Charged = email_titles['charged']
    Petition_Needs_Approval = email_titles['needs_approval']
    Petition_Reached = email_titles['reached']
    Petition_Received = email_titles['received']
    Petition_Rejected = email_titles['rejected']
    Petition_Reported = email_titles['reported']
    Petition_Responded = email_titles['responded']
    Petition_Update = email_titles['updated']


def generate_email(petition_id, event, site_path, to=None, bcc=None, email_data=None):
    petition = Petition.objects.get(pk=petition_id)

    if event in email_titles:
        to = petition.author.email if to is None else to

        if email_data is None:
            email_data = {
                'petition_id': petition.id,
                'title': petition.title,
                'first_name': petition.author.first_name,
                'author': petition.author.profile.full_name,
                'site_path': site_path,
                'protocol': 'https',
                'timestamp': time.strftime('[%H:%M:%S %d/%m/%Y]') + ' End of message.',
                'organization': ORGANIZATION,
                'email_header': COLORS['email_header'],
                'org_logo': ORG_LOGO,
                'name': NAME,
                'header_image': HEADER_IMAGE
            }
        email = EmailMessage(
            email_titles[event],
            get_template('email_inlined/petition_' + event + '.html').render(email_data),
            EMAIL_ADDR,
            [to],
            bcc=bcc,
        )
        email.content_subtype = "html"
        return email
    return None


def send_email(email, petition_id, event):
    try:
        email.send()
        logger.info(
            "Petition " + event + " email SEND \nPetition ID: " + str(petition_id))
    except Exception as e:
        logger.critical(
            "Petition " + event + " email FAILED \nPetition ID: " + str(petition_id), exc_info=True)
        raise e


@db_task(retries=3, retry_delay=3)
def petition_approved(petition_id, site_path):
    email = generate_email(petition_id, 'approved', site_path)
    send_email(email, petition_id, 'Approved')


@db_task(retries=3, retry_delay=3)
def petition_rejected(petition_id, site_path):
    email = generate_email(petition_id, 'rejected', site_path)
    send_email(email, petition_id, 'Rejected')


@db_task(retries=3, retry_delay=3)
def petition_update(petition_id, site_path):
    petition = Petition.objects.get(pk=petition_id)

    # Gets all users that are subscribed or have signed the petition and if they want to receive email updates.
    users = Profile.objects.filter(Q(subscriptions=petition) | Q(petitions_signed=petition)).filter(
        notifications__update=True).distinct("id")

    # Construct array of email addresses
    recipients = [prof.user.email for prof in users]

    email = generate_email(petition_id, 'updated', site_path, EMAIL_ADDR, recipients)
    send_email(email, petition_id, 'Status Update')


@db_task(retries=3, retry_delay=3)
def petition_responded(petition_id, site_path):
    petition = Petition.objects.get(pk=petition_id)

    # Gets all users that are subscribed or have signed the petition and if they want to receive email updates.
    users = Profile.objects.filter(Q(subscriptions=petition) | Q(petitions_signed=petition)).filter(
        notifications__response=True).distinct("id")

    # Construct array of email addresses
    recipients = [prof.user.email for prof in users]

    email = generate_email(petition_id, 'responded', site_path, EMAIL_ADDR, recipients)
    send_email(email, petition_id, 'Response Received')


@db_task(retries=3, retry_delay=3)
def petition_reached(petition_id, site_path):
    petition = Petition.objects.get(pk=petition_id)

    # Gets all users that are subscribed or have signed the petition and if they want to receive emails about petition response.
    users = Profile.objects.filter(
        Q(subscriptions=petition) |
        Q(petitions_signed=petition) |
        Q(notifications__threshold=True)
    ).filter(notifications__response=True).distinct("id")

    # Construct array of email addresses
    recipients = [prof.user.email for prof in users]

    email = generate_email(petition_id, 'reached', site_path, EMAIL_ADDR, recipients)
    send_email(email, petition_id, 'Threshold Reached')


@db_task(retries=3, retry_delay=3)
def petition_received(petition_id, site_path):
    email = generate_email(petition_id, 'received', site_path)
    send_email(email, petition_id, 'Received')

@db_task(retries=3, retry_delay=3)
def petition_charged(petition_id, site_path):
    email = generate_email(petition_id, 'charged', site_path)
    send_email(email, petition_id, 'Charged')


@db_task(retries=3, retry_delay=3)
def petition_needs_approval(petition_id, site_path):
    email = generate_email(petition_id, 'needs_approval', site_path)
    send_email(email, petition_id, 'Needs Approval')


@db_task(retries=3, retry_delay=3)
def petition_reported(petition_id, report_id, site_path):
    petition = Petition.objects.get(pk=petition_id)
    report = Report.objects.get(pk=report_id)
    reporter = User.objects.get(pk=report.reporter_id)

    # Gets all users that are on the email list for reported petitions.
    users = Profile.objects.filter(notifications__reported=True).distinct("id")

    # Construct array of email addresses
    recipients = [prof.user.email for prof in users]

    email_data = {
                    'petition_id': petition.id,
                    'title': petition.title,
                    'first_name': petition.author.first_name,
                    'author': petition.author.profile.full_name,
                    'reason': report.reported_for,
                    'reporter': reporter.profile.display_name,
                    'site_path': site_path,
                    'protocol': 'https',
                    'timestamp': time.strftime('[%H:%M:%S %d/%m/%Y]') + ' End of message',
                    'organization': ORGANIZATION,
                    'email_header': COLORS['email_header'],
                    'org_logo': ORG_LOGO,
                    'name': NAME,
                    'header_image': HEADER_IMAGE
                 }
    email = generate_email(petition_id, 'reported', site_path, EMAIL_ADDR, recipients, email_data)
    send_email(email, petition_id, 'Reported')

Defines email sending tasks that will run in the background with Huey  Author: <NAME> & <NAME> & <NAME> (lxy5611)  All db_tasks will retry at most 3 times. # Gets all users that are subscribed or have signed the petition and if they want to receive email updates. # Construct array of email addresses # Gets all users that are subscribed or have signed the petition and if they want to receive email updates. # Construct array of email addresses # Gets all users that are subscribed or have signed the petition and if they want to receive emails about petition response. # Construct array of email addresses # Gets all users that are on the email list for reported petitions. # Construct array of email addresses