Subversion Repositories SmartDukaan

Rev

Rev 22469 | Blame | Compare with Previous | Last modification | View Log | RSS feed

from email.mime.text import MIMEText
from shop2020.clients.HelperClient import HelperClient
from shop2020.clients.TransactionClient import TransactionClient
from shop2020.thriftpy.utils.ttypes import Mail
from shop2020.utils.daemon import Daemon
import optparse
import sched
import smtplib
import sys
import time
import os
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email import Encoders


class EmailSender(Daemon):
    def __init__(self, logfile='/var/log/utils/emailsender/emailsender.log', pidfile='/var/run/email-sender.pid', count = 0):
        Daemon.__init__(self, pidfile, stdout=logfile, stderr=logfile)
        print 'EmailSender initiated at', time.time()
        self.email_schedular = sched.scheduler(time.time, time.sleep)
        self.time_to_sleep = 10
        self.count = count
        self.exceptionCount = {}
        self.authenticate()

    def authenticate(self, sender="apikey", password="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"):
        try:
            print "Attempting authentication at ", time.time()
            print sender, password
            self.sendGridMailServer = smtplib.SMTP("smtp.sendgrid.net", 587)
            self.sendGridSender = sender
            self.sendGridPassword = password
            self.sendGridMailServer.ehlo()
            self.sendGridMailServer.starttls()
            self.sendGridMailServer.ehlo()
            self.sendGridMailServer.login(sender, password)

#            self.gmailServer = smtplib.SMTP("smtp.gmail.com", 587)
#            self.gmailSender = "help@shop2020.in"
#            self.gmailPassword = "5h0p2o2o"
#            self.gmailServer.ehlo()
#            self.gmailServer.starttls()
#            self.gmailServer.ehlo()
#            self.gmailServer.login(self.gmailSender, self.gmailPassword)            
            print "Authentication successful", time.time()
            
        except smtplib.SMTPConnectError as e:
            print 'Specified host did not respond correctly', e        
        except smtplib.SMTPHeloError as e:
            print 'The server did not reply properly to the HELO greeting.', e
        except smtplib.SMTPAuthenticationError as e:
            print 'The server did not accept the username/password combination.', e
        except smtplib.SMTPException as e:
            print e
        except Exception as e:
            print sys.exc_info()[0]
            print e
            
    def get_attachment_part(self, document, filename):
        part = MIMEBase('application', 'octet-stream')
        part.set_payload(document)
        Encoders.encode_base64(part)
        part.add_header('Content-Disposition', 'attachment; filename=%s' % filename + "-insurance-policy.pdf")
        return part

    def sendMail(self, mail):
        msg = MIMEMultipart()
        if mail.emailFrom is not None and mail.emailFrom.strip() != "" :
            if 'profitmandi.com' in mail.emailFrom:
                msg['From'] = "ProfitMandi <help@smartdukaan.com>"
            else:
                msg['From'] = mail.emailFrom
        else:
            msg['From'] = "Saholic <help@saholic.com>"
        msg['To'] = ', '.join(mail.emailTo)
        msg['Cc'] = ', '.join(mail.cc)
        #msg['Bcc'] = ', '.join(mail.bcc)
        msg['Subject'] = mail.subject
        
        html_msg = MIMEText(mail.body, 'html')
        msg.attach(html_msg)

        if mail.emailType == "DeliverySuccess":
            tclient = TransactionClient().get_client()
            if '-' in mail.source:
                subOrders = tclient.getGroupOrdersByLogisticsTxnId(mail.source)
                singleOrderId = 0
                for order in subOrders:
                    if order.insurer:
                        singleOrderId = order.id
                        break
                if singleOrderId > 0:
                    document = tclient.getDocument(1, int(singleOrderId))
                    if document != bin(0):
                        msg.attach(self.get_attachment_part(document, mail.source))
            else:
                document = tclient.getDocument(1, int(mail.source))
                if document != bin(0):
                    msg.attach(self.get_attachment_part(document, mail.source))
            
        try:
            #Temporary allowing email sender to send only through profitmandi domain
            #if 'profitmandi.com' in mail.emailFrom:
            if False:
                self.authenticate("profitmandi_key_new","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")
                self.setMailServerAndPassword(mail, "pma20aug")
                rs = self.mailServer.sendmail(self.password, mail.emailTo + mail.cc + mail.bcc, msg.as_string())
            else:
                self.authenticate()
                self.setMailServerAndPassword(mail)
                rs = self.mailServer.sendmail(self.password, mail.emailTo + mail.cc + mail.bcc + ['backup@saholic.com'], msg.as_string())
        except smtplib.SMTPServerDisconnected as e:
            print 'Server Disconnected at', time.time()
            self.authenticate()
            rs = self.mailServer.sendmail(self.password, mail.emailTo + mail.cc + mail.bcc + ['backup@saholic.com'], msg.as_string())
        
        print msg['To']
        # Should be mailServer.quit(), but that crashes...
        return rs

    def setMailServerAndPassword(self, mail, password="shop2020"):
        self.mailServer = self.sendGridMailServer
        self.password = password
        
#        self.mailServer = self.gmailServer
#        self.password = self.gmailPassword
#
#        for receiver in mail.to:
#            if not receiver.endswith('@saholic.com') and not receiver.endswith('@shop2020.in'):
#                self.mailServer = self.sendGridMailServer
#                self.password = self.sendGridPassword
#                break

    def send(self):
        '''
        If sending fails for a mail for more than 10 times then we will exit the sender.
        This is done to avoid sending a mail many times if one of the address in the 'emailTo' list is wrong.
        '''
        if self.count > 10:
            print str(self.count)
            print "Number of failed attempts is more than 10. Exiting"
            sys.exit()
            
        for emailId in self.exceptionCount.keys() :
            if self.exceptionCount[emailId] > 10:
                print "Number of exceptions for email id : " + str(emailId) + " is : " + str(self.exceptionCount[emailId]) + ". Exiting"
                sys.exit()
                
        print "Despatch stared at ", time.time()
        helper_client = HelperClient().get_client()
        
        emails_to_be_dispatched = helper_client.getEmailsToBeSent()
        print len(emails_to_be_dispatched)
        
        for email in emails_to_be_dispatched:
            try:
                send_result = "error"
                send_result = self.sendMail(email)
            except Exception as e:
                print sys.exc_info()[0]
                print e
                print 'Error occurred sending email with id - ' + str(email.id)
                if self.exceptionCount.has_key(email.id) :
                    self.exceptionCount[email.id] = self.exceptionCount[email.id] + 1
                else :
                    self.exceptionCount[email.id] = 1
                continue

            if len(send_result) == 0:
                print "Sent at", time.time()
                helper_client.markEmailAsSent(email.id)
                if self.exceptionCount.has_key(email.id) :
                    del self.exceptionCount[email.id]
            else:
                print "Failed sending email. Id:{0}", " Time:{1}".format(email, time.time())
                self.count = self.count + 1
            
        self.email_schedular.enter(self.time_to_sleep, 1, self.send, ())

    def run(self):
        self.email_schedular.enter(self.time_to_sleep, 1, self.send, ())
        self.email_schedular.run()

if __name__ == "__main__":
    parser = optparse.OptionParser()
    parser.add_option("-l", "--logfile", dest="logfile",
                      type="string",
                      help="Log all output to LOG_FILE",
                      )
    parser.add_option("-i", "--pidfile", dest="pidfile",
                      type="string",
                      help="Write the PID to pidfile")
    (options, args) = parser.parse_args()
    daemon = EmailSender(options.logfile, options.pidfile, 0)
    if len(args) == 0:
        daemon.run()
    elif len(args) == 1:
        if 'start' == args[0]:
            daemon.start()
        elif 'stop' == args[0]:
            daemon.stop()
        elif 'restart' == args[0]:
            daemon.restart()
        else:
            print "Unknown command"
            sys.exit(2)
        sys.exit(0)
    else:
        print "usage: %s start|stop|restart" % sys.argv[0]
        sys.exit(2)