# mailer/MailBlaster.py

"""
Class that sends email to a list of recipiants.
Content can be customized using additional data in the list.
does not include any UI.
.query is for creating the specific data sets.
"""
from django.conf import settings

from django.template import Context, Template

from django.core.mail import SMTPConnection, EmailMessage
# from django.core.mail import SMTPConnection
# from pycon.core.mail import EmailMessage
from pycon.core import safe_ascii_encode

from models import MessageLog

class MailBlaster(object):

    """
    manages the parameters to call a query, send and log messages.
    """

    def query(self):
        """
        Returns a list of email addresses
        and additional data referenced by the message content.
        toQueryName is a key into self.queries dict.
        """

        rs= [ {'email':'Test User <test@example.com>'}, ]
        return rs

    def get_sender(self):
        """ who the emails are from """

        # sender will fallback in the following order:
        #    queryParams['sender']
        #    message.sender
        #    settings.MAILER_EMAIL
        #    settings.DEFAULT_FROM_EMAIL (used by django mailer when sender is '')
        if self.query_params and 'sender' in self.query_params:
            sender = self.query_params['sender']
        #elif self.message.sender:
        #    sender = self.message.sender
        else:
            sender = getattr(settings, 'MAILER_FROM_EMAIL', '')

        return sender

    def get_headers(self):
        # http://www.rfc.net/rfc2822.html#s3.6.5 - email headers
        headers = {
            'keywords': settings.CONFERENCE_NAME,
            'Reply-To': settings.MAILER_REPLYTO_EMAIL,
            }

        return headers

    def setup_blast(self):

        # connect to the smtp server
        self.connection = SMTPConnection()

        self.user = self.query_params['request'].user

        self.sender = self.get_sender()
        self.headers = self.get_headers()

        self.subject_template=Template(self.message.subject)
        self.body_template=Template(self.message.body)

        # send an email for each item returned from query()
        self.details = self.query()

        # rendered messages - so UI can display them.
        self.messages=[]

        return

    def blast(self):
        """
        render content.
        if not in preview mode send one message, log it.
        add the rendered content to the messages list
        """

        to=self.detail['email']

        context=Context(self.detail)

        subject = self.subject_template.render(context)
        subject = safe_ascii_encode(subject)

        body = self.body_template.render(context)

        email = EmailMessage(subject, body, self.sender, [to] )
        if not self.preview:
            #print "sending to %s..."%(to),
            self.connection.send_messages([email])
            MessageLog(messageID=self.message.messageID, sender=self.sender,
                       user_id=self.user.id, to=to,
                       subject=subject, body=body).save()

        self.messages.append( {'subject':subject, 'body':body} )

        return

    def blast_loop(self):
        """ blast each detial """
        for self.detail in self.details:
            self.blast()
        return

    def mailBlast(self):

        """
        Given a Message object,
        run the query specified by message.toQueryName
        to get a list of addresses and other details referenced in the body
        and then send the Message.subject/body.

        This method expects these attributes to be set:
        self.query_params
        self.message
        self.preview
        """

        self.setup_blast()
        self.blast_loop()

        # self.connection.close()

        return


def test():
    mb=MailBlaster()

    class Request(object):
        def __init__(self):
            self.user='testuser'

    mb.query_params={'request':Request()}

    class Message(object):
        def __init__(self):
            self.subject='test sub'
            self.body='Dear {{email}}\nThis is a test.'

    mb.message=Message()
    mb.preview=True
    print mb.setup_blast()
    print mb.blast_loop()

    print mb.details
    print mb.messages

# eof mailer/views.py
