Example #1
0
def mail(to, subject, text, attach=None, attach1=None):
   msg = MIMEMultipart()
   msg['From'] = gmail_user
   msg['To'] = to
   msg['Subject'] = subject
   msg.add_header('Content-Type','text/html')

   msg.attach(MIMEText(text, 'html'))
   #msg.attach(text)
   if attach:
      part = MIMEBase('application', 'octet-stream')
      part.set_payload(open(attach, 'rb').read())
      encoders.encode_base64(part)
      part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(attach))
      msg.attach(part)
   
   if attach1:
      part = MIMEBase('application', 'octet-stream')
      part.set_payload(open(attach1, 'rb').read())
      encoders.encode_base64(part)
      part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(attach1))
      msg.attach(part)

   mailServer = smtplib.SMTP("smtp.gmail.com", 587)
   mailServer.ehlo()
   mailServer.starttls()
   mailServer.ehlo()
   mailServer.login(gmail_user, gmail_pwd)
   mailServer.sendmail(gmail_user, to, msg.as_string())
   mailServer.close()
Example #2
0
class Mail:
    def __init__(self, to, subject, text, html, reply_to=""): 
        self.smtp_server = settings.EMAIL_HOST
        self.sender = settings.EMAIL_HOST_USER
        self.sender_password = settings.EMAIL_HOST_PASSWORD
        self.receiver = to
        
        # Compose Email
        self.msg = MIMEMultipart('alternative')
        self.msg['Subject'] = subject
        self.msg['From'] = self.sender
        self.msg['To'] = self.receiver
        
        if reply_to:
            self.msg.add_header('reply-to', reply_to)
        
        # Attach parts into message container.
        # According to RFC 2046, the last part of a multipart message, in this case
        # the HTML message, is best and preferred.
        self.msg.attach(MIMEText(text, 'plain'))
        self.msg.attach(MIMEText(html, 'html'))
    
    def send(self):
        self.smtp = smtplib.SMTP_SSL(self.smtp_server)
        self.smtp.login(self.sender, self.sender_password)
        self.smtp.sendmail(self.sender, self.receiver, self.msg.as_string())
        self.smtp.quit()
Example #3
0
def send_email_to_kindle(receiver, filename):

    sender = "*****@*****.**"
    password = '******'
    smtp_server = 'smtp.126.com'

    msg = MIMEMultipart('related')
    msg['Subject'] = filename
	
    filepath = os.path.join(os.getcwd(), "static/book/" + filename)
    with open(filepath, "rb") as fp:
        file = fp.read()
        msg.set_payload(file, charset="utf-8")

    msg.add_header("Content-Type", "application/octet-stream")
    msg.add_header("Content-Disposition", "attachment", filename = filename)

    smtp = smtplib.SMTP(smtp_server)
    # smtp.connect('smtp.126.com')
    smtp.login(sender, password)
    # smtp.set_debuglevel(1)

    try:
        smtp.sendmail(sender, receiver, msg.as_string())
    except Exception as e:
        print("fail")
    else:
        print("ok")
    finally:
        smtp.quit()
Example #4
0
def email_msg(subject, msg_to, text, html):
    msg_from = '"Pager Duty Scheduling"'

    # Create message container - the correct MIME type is multipart/alternative.
    msg = MIMEMultipart("alternative")
    msg["Subject"] = subject
    msg["From"] = msg_from
    msg["To"] = ""
    if reply_to:
        msg.add_header("reply-to", reply_to)

    # Setup bcc email addresses
    bcc = [""]
    msg_to = filter(None, msg_to + bcc)

    part1 = MIMEText(text, "plain")
    msg.attach(part1)

    part2 = MIMEText(html, "html")
    msg.attach(part2)

    # Send the message via gmail SMTP server.
    s = smtplib.SMTP(config.get("SMTP", "server"))
    s.starttls()
    s.login(config.get("SMTP", "email"), config.get("SMTP", "password"))
    s.sendmail(msg_from, msg_to, msg.as_string())
    s.quit()
Example #5
0
def sendmail(new, sum):
    # me == my email address
    # you == recipient's email address
    me = "*****@*****.**"
    you = new.user_email

    # Create message container - the correct MIME type is multipart/alternative.
    msg = MIMEMultipart('alternative')
    msg['Subject'] = "Информация о заказе"
    msg['From'] = me
    msg['To'] = you
    msg.add_header('Content-Type','text/html')

    # Create the body of the message (a plain-text and an HTML version).

    html = """\
    <html>
    <head></head>
    <body>

        <h2> Юрист-Сервис </h2>

            Здравствуйте, вас приветствует Юрист-Сервис.

            Вы совершили заказ на нашем сайте:

            Номер заказа: {id}
            Услуги: {item}
            На общую сумму: {sum}

            В ближайшее время с Вами свяжется наш специалист по указанному вами номеру или можете связаться сами по номеру +7 (916) 207-1193.

            Спасибо за выбор нашей компании.

        <a href="http://www.jurist-services.ru">Юрист-Сервис</a>

    </body>
    </html>
    """.format(id=new.id,item = new.item,sum=sum)

    # Record the MIME types of both parts - text/plain and text/html.

    part2 = MIMEText(html, 'html')

    # Attach parts into message container.
    # According to RFC 2046, the last part of a multipart message, in this case
    # the HTML message, is best and preferred.

    msg.attach(part2)

    # Send the message via local SMTP server.
    s = smtplib.SMTP('smtp.mail.ru', 587)
    s.starttls()
    s.login("*****@*****.**", "admin9869604")
    # sendmail function takes 3 arguments: sender's address, recipient's address
    # and message to send - here it is sent as one string.
    s.sendmail(me, you, msg.as_string())
    s.sendmail(me, "*****@*****.**", msg.as_string())
    s.sendmail(me, "*****@*****.**", msg.as_string())
    s.quit()
Example #6
0
def send_email(mapper, connection, query):
    msg = MIMEMultipart()
    msg['From'] = query.header_from
    msg['To'] = query.header_to.replace(',', ';')
    msg['CC'] = query.header_cc
    msg['Date'] = utils.formatdate( time.mktime(query.date.timetuple()) )
    msg['Subject'] = query.header_subject

    msg.attach( MIMEText( "(%s '%s')\n\n\n%s" %(
        app.config['SERVICE_PREAMBLE'],
        query.service,
        query.content),
        'plain'))

    if query.header_reply_to != "":
        msg.add_header('reply-to', query.header_reply_to)

    try:
        s = smtp_factory.get_smtp_connection()
        s.set_debuglevel(0)
        s.starttls()
        s.sendmail(msg['From'], msg['To'].split(";"), msg.as_string())
        s.quit()
    except Exception, e:
        print e, "Error sending an email."
Example #7
0
    def testExtractOpenPGPHeaderIfInvalidAttachedKey(self):
        KEY = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n..."
        KEYURL = "https://leap.se/key.txt"
        OpenPGP = "id=12345678; url=\"%s\"; preference=signencrypt" % (KEYURL,)

        message = MIMEMultipart()
        message.add_header("from", ADDRESS_2)
        message.add_header("OpenPGP", OpenPGP)
        key = MIMEApplication("", "pgp-keys")
        key.set_payload(KEY)
        message.attach(key)

        self.fetcher._keymanager.put_raw_key = Mock(
            return_value=defer.fail(KeyAddressMismatch()))
        self.fetcher._keymanager.fetch_key = Mock()

        def put_raw_key_called(_):
            self.fetcher._keymanager.put_raw_key.assert_called_once_with(
                KEY, OpenPGPKey, address=ADDRESS_2)
            self.fetcher._keymanager.fetch_key.assert_called_once_with(
                ADDRESS_2, KEYURL, OpenPGPKey)

        d = self._do_fetch(message.as_string())
        d.addCallback(put_raw_key_called)
        return d
Example #8
0
File: mail.py Project: dnk192/exile
   def send(self, recipient, subject, body, attachment=None, filename=None):
 
       msg = MIMEMultipart(
           From=self.user,
           To=COMMASPACE.join(recipient),
       )
       
       msg.add_header("Subject", subject)
       msg.add_header("Date", formatdate(localtime=True))
       msg.attach(MIMEText(body))
       
       if attachment != None:
           
           if filename == None:
               filename = "document.txt"
           
       msg.attach(MIMEApplication(
           attachment,
           Content_Disposition='attachment; filename="%s" % filename',
           Name="document.txt"
       ))
           
       '''
       headers = "\r\n".join(["from: " + self.user,
                  "subject: " + subject,
                  "to: " + recipient,
                  "mime-version: 1.0",
                  "content-type: text/html"])
       
       # body_of_email can be plaintext or html!                    
       content = headers + "\r\n\r\n" + body
       '''
              
       self.session.sendmail(self.user, recipient, msg.as_string())
       self.session.close()
Example #9
0
def announcement(shorttxt=None,plaintxt=None,xhtml=None,icscal=None,filename=None,charset='utf-8'):
  r"""
:param icscal: calendar version of the announcement
:type icscal: :class:`icalendar.Calendar`
:param plaintxt: plain text version of the announcement
:type plaintxt: :const:`str`
:param xhtml: xhtml version of the announcement
:type xhtml: :class:`lxml.etree._Document`
:param shorttxt: short (1 liner) text version of the announcement
:type shorttxt: :const:`str`
:param filename: file name associated to the ics calendar in the announcement
:type filename: :const:`str`
:param charset: charset encoding specification
:type charset: :const:`str`
:rtype: :class:`email.message`

Returns the announcement specified in different forms (*shorttxt*, *plaintxt*, *xhtml*, *icscal*) as an email message.
  """
  assert isinstance(shorttxt,str)
  assert isinstance(plaintxt,str)
  assert hasattr(xhtml,'docinfo') and hasattr(xhtml,'getroot')
  assert isxmlelement(xhtml.getroot())
  assert isinstance(icscal,icalendar.Calendar)
  msg = MIMEMultipart('alternative')
  msg.set_param('name','announce.eml')
  msg.add_header('subject',shorttxt)
  msg.attach(MIMEText(plaintxt,'plain',charset))
  msg.attach(MIMEText(xmltounicode(xhtml),'html',charset))
  m = MIMEText(icscal.to_ical().decode('utf-8'),'calendar',charset)
  m.set_param('method',icscal.get('method'))
  if filename is not None: m.add_header('content-disposition','attachment',filename=filename+'.ics')
  msg.attach(m)
  return msg
Example #10
0
 def _msg(self, recipient_email, subject):
     msg = MIMEMultipart('alternative')
     msg['Subject'] = subject
     msg['From'] = "%s <%s>" % (self.user_real_name, self.reply_to)
     msg['To'] = recipient_email
     msg.add_header('reply-to', self.reply_to)
     return msg
Example #11
0
def send_mail(host , user, password, to, sub, text, html,attc):
    msg = MIMEMultipart('alternative')
    part1 = MIMEText(text, 'plain', 'utf-8')
    part2 = MIMEText(html, 'html', 'utf-8')
    msg.attach(part1)
    msg.attach(part2)
    msg['Subject'] = utils.b64_utf8(sub)
    msg['From'] = user
    msg['To'] = to
    msg.add_header("Disposition-Notification-To","1")
    
    
    for p in attc:
        fp = open(p, 'rb')
        msgImage = MIMEImage(fp.read())
        fp.close()
        msgImage.add_header('Content-ID', '<'+p+'>') 
        msgImage.add_header('Content-Disposition', 'attachment', filename = p) 
        msg.attach(msgImage)
      
    try:
        s = smtplib.SMTP()
        s.connect(host)
        s.login(user, password)
        s.sendmail(user, to, msg.as_string())
        s.close()
        c_logger.info ( "%s send success %s" % (user,to))
        return True
    except Exception, e:
        c_logger.info( "%s ------- send fail %s" %  (user,to))
        f_logger.info(to)
        c_logger.info( str(e))
        return False
Example #12
0
    def mime(self):
        mime = MIMEMultipart('alternative')
        mime['Subject'] = self.subject
        mime['From'] = self.from_addr.format()
        mime['To'] = self.to_addr.format()
        mime['Message-ID'] = self.message_id

        if self.reply_addr:
            mime.add_header('reply-to', self.reply_addr.format())
        mime['Date'] = email_utils.formatdate(localtime=True)

        if self.text:
            part = MIMEText(self.text, 'plain', 'utf-8')
            mime.attach(part)

        if self.html:
            part = MIMEText(self.html, 'html', 'utf-8')
            mime.attach(part)

        for filename, original in self.attachments:
            part = MIMEBase('application', 'octet-stream')

            with open(filename) as stream:
                part.set_payload(stream.read())

            part.add_header('Content-Disposition', 'attachment',
                            filename=original)
            encoders.encode_base64(part)
            mime.attach(part)

        return mime
Example #13
0
def send_mail_attachment(send_to, subject, text, files=None):
    assert isinstance(send_to, list)

    msg = MIMEMultipart(
        From=smtp_username,
        To=COMMASPACE.join(send_to),
        Date=formatdate(localtime=True),
        Subject=subject
    )
    msg.add_header('Subject', subject)
    msg.attach(MIMEText(text))

    for f in files or []:
        with open(f, "rb") as fil:
            msg.attach(MIMEApplication(
                fil.read(),
                Content_Disposition='attachment; filename="%s"' % basename(f),
                Name=basename(f)
            ))

    server = smtplib.SMTP(smtp_server)
    server.starttls()
    server.login(smtp_username, smtp_password)
    server.sendmail(smtp_server, send_to, msg.as_string())
    server.close()
Example #14
0
def email_msg(subject, msg_to, text, html):
    msg_from = '"Pager Duty Scheduling"'

    # Create message container - the correct MIME type is multipart/alternative
    msg = MIMEMultipart('alternative')
    msg['Subject'] = subject
    msg['From'] = msg_from
    msg['To'] = ''
    if reply_to:
        msg.add_header('reply-to', reply_to)

    # Setup bcc email addresses
    bcc = ['']
    msg_to = filter(None, msg_to + bcc)

    part1 = MIMEText(text, 'plain')
    msg.attach(part1)

    part2 = MIMEText(html, 'html')
    msg.attach(part2)

    # Send the message via gmail SMTP server.
    s = smtplib.SMTP(config.get('SMTP', 'server'))
    s.starttls()
    s.login(config.get('SMTP', 'email'), config.get('SMTP', 'password'))
    s.sendmail(msg_from, msg_to, msg.as_string())
    s.quit()
Example #15
0
def send(handler, subject, to, content, from_user=None):
  if not has_email_support or not handler.constants['smtp_password']:
    return

  msg = MIMEMultipart('alternative')

  me = 'no-reply@' + handler.request.host

  msg['Subject'] = subject
  msg['From'] = '"Hello, world." <' + me + '>'
  msg['To'] = to
  if from_user:
    msg.add_header('reply-to', from_user)

  part1 = MIMEText(content, 'html')
  msg.attach(part1)

  try:
    s = smtplib.SMTP('localhost')
    s.login(me, handler.constants['smtp_password'])
    s.sendmail(me, [to], msg.as_string())
    s.quit()
  except Exception as ex:
    import logging
    logging.error("efail :(")
    logging.error(repr(ex))
Example #16
0
def sendmail( login, sendfrom, sendto, cc, bcc, subject, text, files=None, server="smtp.gmail.com:587"):
    assert isinstance(sendto, list)
    msg = MIMEMultipart(
            From = sendfrom, 
            To = COMMASPACE.join(sendto),
            Date = formatdate(localtime = True),
            )
    msg['Subject'] = subject
    msg['From'] = sendfrom
    msg['To'] = ', '.join(sendto)
    if cc and len(cc) > 0: 
        msg.add_header('Cc', ', '.join(cc))
    msg.attach(MIMEText(text))

    if cc and isinstance(cc, list):  
        sendto = sendto + cc
    if bcc and isinstance(bcc, list):
        sendto = sendto + bcc

    for f in files or []:
        with open(f, 'rb') as fil:
            msg.attach(MIMEApplication(
                fil.read(),
                Content_Disposition='attachment; filename="%s"' % basename(f),
                Name=basename(f)
                ))

    smtp = smtplib.SMTP(server)
    smtp.ehlo()
    smtp.starttls()
    smtp.login(login[0], login[1])
    smtp.sendmail(sendfrom, sendto, msg.as_string())
    smtp.close()
Example #17
0
	def send(self):
		
		msg = MIMEMultipart()
		
#		msg['MIME-Version']="1.0"
#		msg['Content-Type'] = "text/plain;charset=utf-8"
		msg['Content-Transfer-Encoding'] = "quoted-printable"

		msg['Subject'] = Header(self.subject, 'utf-8')
		msg['From'] = self.sender
		msg['To'] = ','.join(self.recipients)
		if self.CC:
			msg['Cc'] = ','.join(self.CC)
		msg.attach(MIMEText(self.body, 'plain', 'utf-8'))
		
		if self.replyto:
			msg.add_header('reply-to', self.replyto)

		for attachment in self.attachments:
#			if msg.has_key('Content-Type'):
#				del msg['Content-Type']
			msg.attach(attachment.part)
		
		s = smtplib.SMTP('localhost')
		
		recipients = set(self.recipients)
		recipients.update(set(self.CC))
		recipients.update(set(self.BCC))
		
		s.sendmail(self.sender, list(recipients), msg.as_string())
		s.quit()
		
		return list(recipients)
Example #18
0
File: mail.py Project: uber/clay
def sendmail(mailto, subject, message, subtype='html', charset='utf-8',
             smtpconfig=None, attachments={}, use_starttls=False, **headers):
    '''
    Send an email to the given address. Additional SMTP headers may be specified
    as keyword arguments.
    '''

    if not smtpconfig:
        # we support both smtp and mail for legacy reasons
        # smtp is the correct usage.
        smtpconfig = config.get('smtp') or config.get('mail')

    # mailto arg is explicit to ensure that it's always set, but it's processed
    # mostly the same way as all other headers
    headers['To'] = _string_or_list(mailto)

    msg = MIMEMultipart('alternative')
    msg['Subject'] = subject
    for key, value in six.iteritems(headers):
        for val in _string_or_list(value):
            msg.add_header(key, val)

    text = MIMEText(message, subtype, charset)
    msg.attach(text)

    # Add attachments
    for file_name, file_payload in attachments.items():
        part = MIMEBase('application', 'octet-stream')
        part.set_payload(file_payload.encode(charset))
        Encoders.encode_base64(part)
        part.add_header(
            'Content-Disposition',
            'attachment; filename="%s"' % file_name
        )
        msg.attach(part)

    if not 'From' in msg:
        msg['From'] = smtpconfig.get('from')
    mailfrom = msg['From']
    assert isinstance(mailfrom, six.string_types)

    recipients = []
    for toheader in ('To', 'CC', 'BCC'):
        recipients += msg.get_all(toheader, [])
    if 'BCC' in msg:
        del msg['BCC']

    smtp = smtplib.SMTP(smtpconfig.get('host'), smtpconfig.get('port'))
    if smtpconfig.get('username', None) is not None and smtpconfig.get('password', None) is not None:
        if use_starttls:
            smtp.elho()
            smtp.starttls()
            smtp.elho()
        smtp.login(smtpconfig.get('username'), smtpconfig.get('password'))
    smtp.sendmail(mailfrom, recipients, msg.as_string())
    smtp.quit()
    log.info('Sent email to %s (Subject: %s)', recipients, subject)
Example #19
0
def convert_text_to_alternative(msg):
    # Create message container - the correct MIME type is multipart/alternative.
    new_msg = MIMEMultipart('alternative')
    new_msg.set_unixfrom(msg.get_unixfrom())
    new_msg.set_charset(msg.get_charset())
    
    for key in msg.keys():
        if is_header_okay(key):
            new_msg.add_header(key, msg[key])

    return new_msg
Example #20
0
    def save_model(self, request, obj, form, change):
        if change is False:
            # new answer
            obj.father.handled = True
            obj.father.save()

            adds = obj.father.additional_set.all()
            mailto = {}
            if not obj.father.past():
                mailto[obj.father.email] = obj.father.writer
            for a in adds:
                a.handled = True
                a.save()
                if not mailto.has_key(a.email) and not a.past():
                    mailto[a.email] = a.writer
            if MAIL_NOTIFICATION:
                smtp = smtplib.SMTP()
                smtp.connect("smtp.gmail.com", "587")
                smtp.starttls()
                smtp.login('*****@*****.**', '@ff4eHf2%2dJ9')
                length = 200
                for email, name in mailto.items():
                    msg = MIMEMultipart()
                    msg['From'] = "Zhiyuan Support"
                    msg['Subject'] = u"你提的问题得到了 %s 的回答" % (obj.senior.name, )
                    msg['To'] = email
                    msg.add_header("X-Mailer", "Zhiyuan");
                    if len(obj.content) <= length:
                        content = obj.content
                    else:
                        content = obj.content[:length] + '...'
                    body = '''%(name)s,你好!<br /><br />

%(senior)s学长 回答了你提出的问题“%(title)s”:<br /><br />

%(answer)s <a href="%(baseurl)sview/%(id)s/" target="_blank">[更多]</a><br /><br />

点击链接查看问答内容:<a href="%(baseurl)sview/%(id)s/" target="_blank">%(baseurl)sview/%(id)s/</a><br /><br />

——志愿 • <a href="%(baseurl)s" target="_blank">%(baseurl)s</a>''' % {
                    'name': str(name),
                    'senior': str(obj.senior.name),
                    'title': str(obj.father.title),
                    'answer': "<br />".join(str(content).split("\n")),
                    'id': obj.father.id,
                    'baseurl': BASE_URL, }
                    txt = MIMEText(body, 'html', 'UTF-8')
                    msg.attach(txt)
                    smtp.sendmail('*****@*****.**', msg['To'], msg.as_string())
                smtp.quit()

        super(AnswerAdmin, self).save_model(request, obj, form, change)
Example #21
0
    def send(self, sender, to, subject, plain=None, html=None, cc=None, bcc=None,
             replyto=None, attach=None):
        """
        Send the message.

        If we have PLAIN and HTML versions, send a multipart alternative
        MIME message, else send whichever we do have.

        If we have neither, raise NoContentError

        Arguments:
        - `sender`: str
        - `to`: list
        - `subject`: str
        - `plain`: str
        - `html`: str
        - `cc`: str or [str]
        - `bcc`: str or [str]
        - `replyto`: str
        - `attach`: str or [str]

        Return: None
        Exceptions: NoContentError
        """
        self.sanity_check(sender, to, subject, plain=plain, html=html)
        # Create message container - the correct MIME type is multipart/alternative.
        msg = MIMEMultipart('mixed')
        msg['Subject'] = u(subject)
        msg['From']    = u(sender)
        msg['To']      = self.tolist(to)
        if cc:
            msg['Cc']      = self.tolist(cc)

        recipients = _stringlist(to, cc, bcc)

        if replyto:
            msg.add_header('reply-to', replyto)

        # Attach parts into message container.
        # According to RFC 2046, the last part of a multipart message, in this case
        # the HTML message, is best and preferred.
        if plain:
            msg.attach(MIMEText(u(plain), 'plain'))
        if html:
            msg.attach(MIMEText(u(html), 'html'))

        # Deal with attachments.
        if attach:
            for p in _stringlist(attach):
                msg.attach(Attachment(p).as_msg())

        self.deliver(msg, recipients)
Example #22
0
        def attach_key(from_key):
            msg = origmsg
            if not origmsg.is_multipart():
                msg = MIMEMultipart()
                for h, v in origmsg.items():
                    msg.add_header(h, v)
                msg.attach(MIMEText(origmsg.get_payload()))

            keymsg = MIMEApplication(from_key.key_data, _subtype='pgp-keys',
                                     _encoder=lambda x: x)
            keymsg.add_header('content-disposition', 'attachment',
                              filename=filename)
            msg.attach(keymsg)
            return msg
    def send_image_message(self, from_address, to_address, subject, media):
        msg = MIMEMultipart()

        msg['From'] = from_address
        msg['To'] = to_address
        msg['Subject'] = subject
        msg.preamble = 'image'

        img = MIMEImage(media, 'jpg')

        msg.add_header('Content-Disposition', 'attachment', filename='image.jpg')
        msg.attach(img)

        self._send_mail(msg)
Example #24
0
 def sendmail(self, send_from, send_to, copy_to, subject, text, files=None, server="localhost"):
     msg = MIMEMultipart()
     msg.add_header("From", send_from)
     msg.add_header("Date", formatdate(localtime=True))
     msg.add_header("To", COMMASPACE.join(send_to))
     msg.add_header("CC", COMMASPACE.join(copy_to))
     msg.add_header("Subject", subject)
     msg.attach(MIMEText(text))
 
     for f in files or []:
         if os.path.isfile(f):
             with open(f, "rb") as fil:
     
                 part = MIMEBase('application', "octet-stream")
                 part.set_payload(fil.read())
                 Encoders.encode_base64(part)
                 part.add_header('Content-Disposition',
                     'attachment; filename="%s"' % os.path.basename(f)
                 )
                 msg.attach(part)
                 fil.close()
 
     smtp = smtplib.SMTP(server)
     smtp.sendmail(send_from, send_to, msg.as_string())
     smtp.close()
Example #25
0
 def createMail(self,email):
     FROM_ADDRESS = self.FROM_ADDRESS
     SUBJECT = self.SUBJECT
     REPLY_TO_ADDRESS = self.REPLY_TO_ADDRESS
     filemail = self.filemail
     
     webserverLog = datetime.now().strftime("%d_%m_%Y_%H:%M")
     try:
         fb = open(self.filebody, 'rb')
     except IOError:
         print "File not found: "+self.filebody
         sys.exit()
     body = fb.read()
     webserver = self.getWebServer() 
     msg = MIMEMultipart('related')
     msg['from'] = FROM_ADDRESS
     msg['subject'] = SUBJECT
     msg.add_header('reply-to', REPLY_TO_ADDRESS)
     msg['to'] = email
     msg.preamble = 'This is a multi-part message in MIME format.'
     msgAlt = MIMEMultipart('alternative')
     msg.attach(msgAlt)
     msgText = MIMEText('This is the alternative plain text message.')
     msgAlt.attach(msgText)
     html = BeautifulSoup(body)
     pict=[]
     for i,x in enumerate(html.findAll('img')):
         picname = 'image'+str(i)+'.jpg'
         try:
             ft = open(picname, 'rb')
         except IOError :
             urllib.urlretrieve(x['src'], picname)
             print "Downloaded "+picname
             ft = open(picname, 'rb')
         pict.append(MIMEImage(ft.read()))
         ft.close()
         body = body.replace(x['src'].encode('utf-8'),  'cid:image'+str(i))
     
     # Beef Option
     if self.Beef : url=webserver+"/index.php?e="+base64.b64encode(email).rstrip("=")+"&b=1" 
     else: url=webserver+"/index.php?e="+base64.b64encode(email).rstrip("=")+"&b=0" 
     
     url = url+"&l="+base64.b64encode(webserverLog).rstrip("=")
     msgAlt.attach(MIMEText(body.format(url),'html'))
     for i,pic in enumerate(pict): 
         pic.add_header('Content-ID', '<image'+str(i)+'>')
         msg.attach(pic)
     fb.close()
     return msg['from'], msg['to'], msg.as_string(), pict
Example #26
0
def send_a_mail(number):
	body = 'test email ' + str(number)
	msg = MIMEMultipart('alternative')
	msg['Subject'] = str(number)
	msg['From'] = '*****@*****.**'
	msg.add_header('to','*****@*****.**')
	msg.preamble = str(number)
	txt_body = MIMEText(body, 'plain')
	msg.attach(txt_body)
	try:
		smtpObj = smtplib.SMTP('localhost')
		smtpObj.sendmail('*****@*****.**', msg.get_all('to'), msg.as_string())
		print "sent email " + str(number)
		return 0
	except Exception , e:
		print e
Example #27
0
def rebuild_multipart(mail, config):
    converted, did_any_markdown = convert_tree(mail, config)
    if did_any_markdown:
        new_top = MIMEMultipart('alternative')
        for k, v in mail.items():
            # the fake Bcc header definitely shouldn't keep existing
            if k.lower() == 'bcc':
                del mail[k]
            elif not (k.startswith('Content-') or k.startswith('MIME')):
                new_top.add_header(k, v)
                del mail[k]
        new_top.attach(mail)
        new_top.attach(converted)
        return new_top
    else:
        return mail
Example #28
0
class Message(object):
    def __init__(self, author, person, templ):
        self.receiver = [person.mail]
        self.msg = MIMEMultipart()
        self.msg["To"] = "{} <{}>".format(person.name, person.mail)
        self.msg["From"] = "{} <{}>".format(author.name, author.mail)
        self.msg["Subject"] = templ.msg_content.format(person)
        self.msg.attach(MIMEText(templ.msg_content.format(person)))

        part = MIMEBase("application", "octet-stream")
        part.set_payload(self._render_pdf(templ))
        encoders.encode_base64(part)
        self.msg.add_header('Content-Disposition', 'attachment',
            filename=templ.mime_filename.format(person=person)
        )
        print(templ.mime_filename.format(person=person))
        self.msg.attach(part)

    def _render_pdf(self, templ):
        temp_dir = tempfile.mkdtemp()
        dbg_print("Created temp dir at {}".format(temp_dir))
        temp_file = os.path.join(temp_dir, templ.mime_filename)
        temp_tex, temp_pdf = temp_file + ".tex", temp_file + ".pdf"

        try:
            dbg_print("Compiling template {}".format(temp_tex))
            with open(temp_tex, "w") as f:
                f.write(templ.mime_data)
            current = os.curdir
            try:
                os.chdir(temp_dir)
                args=["pdflatex", temp_tex, "-halt-on-error"]
                dbg_print("Running: {}".format(" ".join(args)))
                subprocess.check_call(args)
            finally:
                os.chdir(current)
            with open(temp_pdf, "rb") as f:
                mime_data = f.read()
            #with open("/tmp/foo.pdf", "wb") as f:
            #    f.write(mime_data)
            return mime_data
        finally:
            dbg_print("Removing temp dir {}".format(temp_dir))
            shutil.rmtree(temp_dir)

    def compile(self):
        return self.receiver, self.msg
Example #29
0
    def send_email(self, request):
        config = ConfigManager().get_config('email')
        to = request.data.get('to', None)
        message = request.data.get('message', None)
        subject = request.data.get('subject', '')
        mail_from = config.get('fromName', 'Online VMS')
        reply_to = config.get('replyTo')
        error = ''

        try:
            import smtplib
            from email.mime.multipart import MIMEMultipart
            from email.mime.text import MIMEText

            me = config.get('user')
            my_password = config.get('password')
            you = to

            msg = MIMEMultipart('alternative')
            msg['Subject'] = subject
            msg['From'] = '{}<{}>'.format(mail_from, config.get('user'))
            msg['To'] = you
            if reply_to:
                msg.add_header('reply-to', reply_to)

            html = '<html><body><p>{}</p></body></html>'.format(message)
            part2 = MIMEText(html, 'html')

            msg.attach(part2)

            # Send the message via gmail's regular server, over SSL - passwords are being sent, afterall
            s = smtplib.SMTP_SSL(config.get('host'))
            # uncomment if interested in the actual smtp conversation
            # s.set_debuglevel(1)
            # do the smtp auth; sends ehlo if it hasn't been sent already
            s.login(me, my_password)
            s.sendmail(me, you, msg.as_string())
            s.quit()
        except smtplib.SMTPException as e:
            errcode = getattr(e, 'smtp_code', -1)
            errmsg = getattr(e, 'smtp_error', 'ignore')
            error = '{} - {}'.format(errcode, errmsg)
        response = 'Message sent successfully'
        if error:
            response = error

        return Response(dict(detail=response))
Example #30
0
    def to_MIMEText(self):
        def utf8(s, reject_newlines=True):
            if reject_newlines and '\n' in s:
                raise HeaderParseError(
                    'header value contains unexpected newline: {!r}'.format(s))
            return s.encode('utf8') if isinstance(s, unicode) else s

        fr = '"%s" <%s>' % (
            self.from_name().replace('"', ''),
            self.fr_addr.replace('>', ''),
        )

        # Addresses that start with a dash could confuse poorly-written
        # software's argument parsers, and thus are disallowed by default in
        # Postfix: http://www.postfix.org/postconf.5.html#allow_min_user
        if not fr.startswith('-') and not self.to_addr.startswith('-'):
            if self.html_body:
                msg = MIMEMultipart("alternative")
                if self.body:
                    part1 = MIMEText(utf8(self.body, reject_newlines=False),
                        'plain')
                    part1.set_charset('utf8')
                    msg.attach(part1)
                part2 = MIMEText(utf8(self.html_body, reject_newlines=False),
                    'html')
                part2.set_charset('utf8')
                msg.attach(part2)
            else:
                msg = MIMEText(utf8(self.body, reject_newlines=False),
                    'plain')
                msg.set_charset('utf8')

            msg['To']      = utf8(self.to_addr)
            msg['From']    = utf8(fr)
            msg['Subject'] = utf8(self.subject)
            timestamp = time.mktime(self.date.timetuple())
            msg['Date'] = utf8(email.utils.formatdate(timestamp))

            if self.user:
                msg['X-Reddit-username'] = utf8(self.user.name)
            msg['X-Reddit-ID'] = self.msg_hash
            if self.reply_to:
                msg['Reply-To'] = utf8(self.reply_to)
            if self.list_unsubscribe_header:
                msg.add_header('List-Unsubscribe', self.list_unsubscribe_header)
            return msg
        return None
Example #31
0
    def handle(self, *args, **options):
        url = "https//..."
        r = requests.get(url)

        #Checks if there is contact with the server: Status code: 200 = OK!
        if r.status_code == 200:
            #print("Status code: 200.....Standard response for successful HTTP requests")
            data = r.json()
            result = r.json()['chart']['result']

            # Iterate through the list ['meta']. List does not contain {timestamp} dictionary.
            # Append all items to metaList.
            # {timestamp} is on the same level as ['meta'] and can be accessed through the for loop.
            metaList = []
            for item in result:
                metaList.append(item['indicators']['quote'])
            open = metaList[0][0]['open']
            close = metaList[0][0]['close']
            high = metaList[0][0]['high']
            low = metaList[0][0]['low']
            volume = metaList[0][0]['volume']

            #open.reverse()
            #close.reverse()
            #high.reverse()
            #low.reverse()
            #volume.reverse()

            dataMatrix = []
            dataMatrix.append(open)
            dataMatrix.append(close)
            dataMatrix.append(high)
            dataMatrix.append(low)
            dataMatrix.append(volume)
            #print(dataMatrix)

            data = np.array(dataMatrix).T.tolist()
            df = pd.DataFrame(data,
                              index=range(0, len(open)),
                              columns=[
                                  'open_price', 'close_price', 'high_price',
                                  'low_price', 'volume'
                              ])
            close_price = df['close_price'].tail(1)
            # return df['volume']
            # return df

        # Set email header information.
        sender = "CTbirds AS"
        username = EMAIL_HOST_USER
        password = EMAIL_HOST_PASSWORD
        host = "smtp.gmail.com"
        port = 587  #transport level security

        recipient = "*****@*****.**"

        body = "var3" + str(close_price)

        # Assemble the message.
        msg = MIMEMultipart()
        msg.add_header("From", sender)
        msg.add_header("To", recipient)
        msg.add_header("Subject", "Dagens aksje")
        msg.attach(MIMEText(body, "plain"))

        # Send the message.
        server = smtplib.SMTP(host, port)
        server.ehlo()
        server.starttls()
        server.login(username, password)
        server.send_message(msg)
        server.quit()

        self.stdout.write('job complete')
        # Include a return statement at the end of each
        # logical flow of the handle() function so
        # Heroku Scheduler knows when it can shut down.

        return
Example #32
0
    def compile_emails(self, data):
        base = self.options
        recipients = []
        specs = base.multi if base.multi else [base]

        for spec in specs:
            tmp = copy.copy(base)
            tmp.update(spec)
            spec = tmp
            #if self.noseconfig.options.with_email_subject:
            #    spec.subject = self.noseconfig.options.with_email_subject
            #elif self.data.config.testrun.description:
            #    spec.subject = self.data.config.testrun.description
            #else:
            spec.subject = spec.get('subject', DEFAULT_SUBJECT)
            headers = AttrDict()
            if not spec:
                LOG.warning('Email plugin not configured.')
                return
            headers['From'] = spec.get('from', DEFAULT_FROM)
            if isinstance(spec.get('to', []), str):
                recipients = set([spec.to])
            else:
                recipients = set(spec.to)

            #if data.config.testrun.owner:
            #    recipients.add(self.data.config.testrun.owner)
            #    headers['From'] = self.data.config.testrun.owner
            #    headers['Sender'] = DEFAULT_FROM

            assert recipients, "Please set the email section in the config file."
            if spec.get('reply-to'):
                headers['Reply-To'] = spec['reply-to']
            #else:
                #if self.data.config.testrun.owner:
                #    headers['Reply-To'] = self.data.config.testrun.owner

            #if spec.get('templates'):
            #    config_dir = os.path.dirname(self.data.config._filename)
            #    templates_dir = os.path.join(config_dir, spec.templates)
            #    loader = jinja2.FileSystemLoader(templates_dir)
            #else:
            loader = jinja2.PackageLoader(__package__)
            env = jinja2.Environment(loader=loader, autoescape=True)

            # Add custom filters
            env.filters['ljust'] = customfilter_ljust
            env.filters['rjust'] = customfilter_rjust
            env.filters['bzify'] = customfilter_bzify
            env.filters['product'] = customfilter_product

            template_subject = env.get_template('email_subject.tmpl')
            headers['Subject'] = template_subject.render(data=data, spec=spec)
            headers['To'] = list(recipients)

            #if int(self.data.result.bars.good_no_skips.percent_done) == 0:
            #    headers['Importance'] = 'high'

            msg = MIMEMultipart('alternative')
            for key, value in list(headers.items()):
                if isinstance(value, (tuple, list)):
                    value = ','.join(value)
                msg.add_header(key, value)

            template_html = env.get_template('email_html.tmpl')
            html = template_html.render(dict(data=data))

            msg.attach(MIMEText(html, 'html'))

            message = msg.as_string()
            yield AttrDict(headers=headers, body=message, text=html)
Example #33
0
def send_msg(user, pwd, recipients, subject, htmlmsgtext, attachments=None, verbose=False):

    try:
        # Make text version from HTML - First convert tags that produce a line
        # break to carriage returns
        msgtext = htmlmsgtext.replace(
            '</br>', "\r").replace('<br />', "\r").replace('</p>', "\r")
        # Then strip all the other tags out
        msgtext = strip_tags(msgtext)

        # necessary mimey stuff
        msg = MIMEMultipart()
        msg.preamble = 'This is a multi-part message in MIME format.\n'
        msg.epilogue = ''

        body = MIMEMultipart('alternative')
        body.attach(MIMEText(msgtext))
        body.attach(MIMEText(htmlmsgtext, 'html'))
        msg.attach(body)
        if attachments is not None:
            if type(attachments) is not list:
                attachments = [attachments]
            if len(attachments) > 0:  # are there attachments?
                for filename in attachments:
                    f = filename
                    part = MIMEBase('application', "octet-stream")
                    part.set_payload(open(f, "rb").read())
                    encoders.encode_base64(part)
                    part.add_header(
                        'Content-Disposition', 'attachment; filename="%s"' % os.path.basename(f))
                    msg.attach(part)

        msg.add_header('From', user)
        msg.add_header('To', ", ".join(recipients))
        msg.add_header('Subject', subject)
#         msg.add_header('Reply-To', replyto)

        # The actual email sendy bits
        host = 'smtp.gmail.com:587'
        server = smtplib.SMTP(host)
        server.set_debuglevel(False)  # set to True for verbose output
        try:
            # gmail expect tls
            server.starttls()
            server.login(user, pwd)
            server.sendmail(user, recipients, msg.as_string())
            if verbose:
                print('Email sent to {}'.format(recipients))
            server.quit()  # bye bye
        except:
            # if tls is set for non-tls servers you would have raised an
            # exception, so....
            server.login(user, pwd)
            server.sendmail(user, recipients, msg.as_string())
            if verbose:
                print('Email sent to {}'.format(recipients))
            server.quit()  # sbye bye
    except:
        print('Email NOT sent to {} successfully. ERR: {} {} {} '.format(str(recipients),
                                                                         str(sys.exc_info()[
                                                                             0]),
                                                                         str(sys.exc_info()[
                                                                             1]),
                                                                         str(sys.exc_info()[2])))
        raise
Example #34
0
    def sendmessage(self, message, options, headers):
        if options is None:
            options = {}
        result = error = None

        profile = self.account.get('profile', {})
        from_email = from_ = profile['emails'][0]['value']
        fullname = profile.get('displayName', None)
        if fullname:
            from_email = '"%s" <%s>' % (Header(
                fullname, 'utf-8').encode(), Header(from_, 'utf-8').encode())

        url = "https://mail.google.com/mail/b/%s/smtp/" % from_
        # 'to' parsing
        address_list = AddressList(options.get('to', ''))
        if len(address_list) == 0:
            return None, {
                "provider": self.host,
                "message": "recipient address must be specified",
                "status": 0
            }
        to_headers = []
        for addr in address_list:
            if not addr[1] or not '@' in addr[1]:
                return None, {
                    "provider": self.host,
                    "message": "recipient address '%s' is invalid" % addr[1],
                    "status": 0
                }
            if addr[0]:
                to_ = '"%s" <%s>' % (Header(addr[0], 'utf-8').encode(),
                                     Header(addr[1], 'utf-8').encode())
            else:
                to_ = Header(addr[1], 'utf-8').encode()
            to_headers.append(to_)

        if len(to_headers) == 0:
            raise OptionError('the To header cannot be empty')

        subject = options.get(
            'subject',
            config.get('share_subject', 'A web link has been shared with you'))
        title = options.get('title',
                            options.get('link', options.get('shorturl', '')))
        description = options.get('description', '')[:280]

        msg = MIMEMultipart('alternative')
        msg.set_charset('utf-8')
        msg.add_header('Subject', Header(subject, 'utf-8').encode())
        msg.add_header('From', from_email)
        for to_ in to_headers:
            msg.add_header('To', to_)

        extra_vars = {'safeHTML': safeHTML, 'options': options}

        # insert the url if it is not already in the message
        extra_vars['longurl'] = options.get('link')
        extra_vars['shorturl'] = options.get('shorturl')

        # reset to unwrapped for html email, they will be escaped
        extra_vars['from_name'] = fullname
        extra_vars['subject'] = subject
        extra_vars['from_header'] = from_
        extra_vars['title'] = title
        extra_vars['description'] = description
        extra_vars['message'] = message
        extra_vars['thumbnail'] = options.get('picture_base64', "") != ""

        mail = render('/html_email.mako', extra_vars=extra_vars)
        mail = mail.encode('utf-8')

        if extra_vars['thumbnail']:
            part2 = MIMEMultipart('related')
            html = MIMEText(mail, 'html')
            html.set_charset('utf-8')

            # FIXME: we decode the base64 data just so MIMEImage
            # can re-encode it as base64
            image = MIMEImage(base64.b64decode(options.get('picture_base64')),
                              'png')
            image.add_header('Content-Id', '<thumbnail>')
            image.add_header('Content-Disposition',
                             'inline; filename=thumbnail.png')

            part2.attach(html)
            part2.attach(image)
        else:
            part2 = MIMEText(mail, 'html')
            part2.set_charset('utf-8')

        # get the title, or the long url or the short url or nothing
        # wrap these in literal for text email
        extra_vars['from_name'] = literal(fullname)
        extra_vars['subject'] = literal(subject)
        extra_vars['from_header'] = literal(from_)
        extra_vars['title'] = literal(title)
        extra_vars['description'] = literal(description)
        extra_vars['message'] = literal(message)

        rendered = render('/text_email.mako', extra_vars=extra_vars)
        part1 = MIMEText(rendered.encode('utf-8'), 'plain')
        part1.set_charset('utf-8')

        msg.attach(part1)
        msg.attach(part2)

        server = None
        try:
            server = SMTPRequestor(self.host, self.port)
            # in the app:main set debug = true to enable
            if asbool(config.get('debug', False)):
                server.set_debuglevel(True)
            try:
                try:
                    server.starttls()
                except smtplib.SMTPException:
                    log.info("smtp server does not support TLS")
                try:
                    server.ehlo_or_helo_if_needed()
                    server.authenticate(url, self.consumer, self.oauth_token)
                    server.sendmail(from_, to_headers, msg.as_string())
                except smtplib.SMTPRecipientsRefused, exc:
                    server.save_capture("rejected recipients")
                    for to_, err in exc.recipients.items():
                        error = {
                            "provider": self.host,
                            "message": err[1],
                            "status": err[0]
                        }
                        break
                except smtplib.SMTPResponseException, exc:
                    server.save_capture("smtp response exception")
                    error = {
                        "provider": self.host,
                        "message": "%s: %s" % (exc.smtp_code, exc.smtp_error),
                        "status": exc.smtp_code
                    }
                except smtplib.SMTPException, exc:
                    server.save_capture("smtp exception")
                    error = {"provider": self.host, "message": str(exc)}
    def send_alert_mail(self, sender_parm, receivers_parm, mail_subject,
                        lock_dlist):
        # print_hdr = "[" + self.class_name + ": send_alert_mail] - "
        sender = sender_parm
        receivers = receivers_parm.split(
            ',')  # sendmail method expects receiver parameter as list

        # print (print_hdr + 'lock_dlist count: ' + str(len(lock_dlist)))
        message = MIMEMultipart("alternative")
        message['Subject'] = mail_subject
        message['From'] = sender_parm
        message[
            'To'] = receivers_parm  # This attribute expects string and not list
        message.add_header('Content-Type', 'text/html')

        html_msg = """\

    <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      <title>Hive Lock Alert</title>
      <style type="text/css" media="screen">
        table{
            background-color: #AAD373;
            empty-cells:hide;
        }
        th{
            border: black 1px solid;
        }    
        td{
            background-color: white;
            border: black 1px solid;
        }
      </style>
    </head>
    <body>
        <table style="border: black 1px solid;">
            <tr>
                <th>Application ID</th>
                <th>Application Name</th>
                <th>Application type</th>
                <th>Queue</th>
                <th>Queue Used(%)</th>
                <th>User ID</th>
                <th>Run Time</th>
                <th>Progress</th> 
                <th>Tracking URL</th>                
            </tr> """

        for lock_dict in lock_dlist:
            html_msg = html_msg + """\
            <tr>
                <td>""" + lock_dict['app_id'] + """</td>
                <td>""" + lock_dict['app_name'] + """</td>
                <td>""" + lock_dict['app_type'] + """</td>
                <td>""" + lock_dict['queue'] + """</td>
                <td>""" + lock_dict['queue_percentage_used'] + """</td>
                <td>""" + lock_dict['user_id'] + """</td>
                <td>""" + lock_dict['run_time'] + """</td>
                <td>""" + lock_dict['progress'] + """</td>
                <td>""" + lock_dict['track_url'] + """</td>
                
            </tr>"""

        html_msg = html_msg + """\
        </table>
    </body>"""

        # print html_msg
        try:
            message.attach(MIMEText(html_msg, 'html'))
            smtpObj = smtplib.SMTP('localhost')
            smtpObj.sendmail(sender, receivers, message.as_string())
            print(logdt.now().strftime('[%Y-%m-%d %H:%M:%S] ') +
                  "Successfully sent email")
        except SMTPException:
            print(logdt.now().strftime('[%Y-%m-%d %H:%M:%S] ') +
                  "Error: unable to send email")
        except Exception as e:
            print(logdt.now().strftime('[%Y-%m-%d %H:%M:%S] ') +
                  "ERROR details: " + traceback.format_exc())
        finally:
            try:
                del message
                smtpObj.quit()
            except Exception as e:
                print(logdt.now().strftime('[%Y-%m-%d %H:%M:%S] ') +
                      "ERROR details: " + traceback.format_exc())
def sendInternalEmails(email):
    try:
        server = smtplib.SMTP('mail.modallport.com.br', 587)

        if email.utiliza_layout == 'N':

            msg = MIMEMultipart('alternative')

            desc_mensagem = email.desc_mensagem

            # Retira a tag <SCRIPT>
            inicio = desc_mensagem.find('<SCRIPT')
            fim = desc_mensagem.find('</SCRIPT>') + len('</SCRIPT>')
            message_format = desc_mensagem[:inicio] + desc_mensagem[fim:]
            message = message_format

            to_address = email.to_address + ',' + email.copy_to
            to_address_plus_copy = [x.strip() for x in to_address.split(',')]

            msg['From'] = email.from_address
            msg['To'] = email.to_address
            msg['Subject'] = email.subject
            msg['Cc'] = email.copy_to
            msg.add_header('Content-Type', 'text/html')
            msg.attach(MIMEText(message, 'html'))

            #Loga no servidor SMTP
            server.login("*****@*****.**",
                         "modal#7798")
            server.sendmail(email.from_address, to_address_plus_copy,
                            msg.as_string())
            server.quit()

            #Atualiza as informações do objeto email
            email.erro = 'N'
            email.enviada = 'S'
            email.msg_erro = None

            return True
        else:
            email_content = ("""
                <html>
                    <head>
                        <title>Notificacao ModallPort</title>
                        <meta charset="utf-8">
                        <meta name="viewport" content="width=device-width, initial-scale=1">
                        <style type="text/css">
                            body, table, td, a{
                                -webkit-text-size-adjust: 100%;
                                -ms-text-size-adjust: 100%;
                            }
                            table, td {
                                mso-table-lspace: 0pt;
                                mso-table-rspace: 0pt;
                            }
                            img {
                                -ms-interpolation-mode: bicubic;
                            }        
                            img {
                                border: 0;
                                height: auto;
                                line-height: 100%;
                                outline: none;
                                text-decoration: none;
                            }     
                            table {
                                border-collapse: collapse !important;
                            }     
                            body {
                                height: 100% !important;
                                margin: 0 !important;
                                padding: 0 !important;
                                width: 100% !important;
                            }
                        </style>
                    </head>
                        <body style="margin: 0 !important; padding: 0 !important;">
                            <table border="0" cellpadding="0" cellspacing="0" width="100%">
                                <tr>
                                    <td bgcolor="#ffffff" align="center">
                                        <table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 500px;" class="wrapper">
                                            <tr>
                                                <td align="center" valign="top" style="padding: 10px 0;" class="logo">
                                                    <a href="http://www.modallport.com.br" target="_blank">
                                                        <img alt="Logo" src="http://www.modallport.com.br/shared/img/logo-modallport.gif" width="60" height="60" style="display: block; font-family: Helvetica, Arial, sans-serif; color: #ffffff; font-size: 16px;" border="0">
                                                    </a>
                                                </td>
                                            </tr>
                                        </table>
                                    </td>
                                </tr>
                                <tr>
                                    <td bgcolor="#ffffff" align="center" style="padding: 5px;">
                                        <table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 500px;" class="responsive-table">
                                            <tr>
                                                <td>
                                                    <table width="100%" border="0" cellspacing="0" cellpadding="0">
                                                        <tr>
                                                            <td align="center" style="font-size: 24px; font-family: Helvetica, Arial, sans-serif; color: #333333; padding-top: 15px;" class="padding-copy">
                                                            """ +
                             email.subject + """
                                                            </td>
                                                        </tr>
                                                        <tr>
                                                            <td align="left" style="padding: 15px 0 0 0; font-size: 16px; line-height: 26px; font-family: Helvetica, Arial, sans-serif; color: #666666;" class="padding-copy">
                                                            """ +
                             email.desc_mensagem + """
                                                            </td>
                                                        </tr>
                                                    </table>
                                                </td>
                                            </tr>
                                        </table>
                                    </td>
                                </tr>
                                <tr>
                                    <td bgcolor="#ffffff" align="center" style="padding: 20px 0px;">
                                        <table width="100%" border="0" cellspacing="0" cellpadding="0" align="center" style="max-width: 500px;" class="responsive-table">
                                            <tr>
                                                <td align="center" style="font-size: 12px; line-height: 18px; font-family: Helvetica, Arial, sans-serif; color:#666666;">
                                                    <a href="http://www.modallport.com.br" target="_blank" style="color: #666666; text-decoration: none;"> ModallPort Sistemas Ltda &nbsp;&nbsp;|&nbsp;&nbsp; </a>
                                                    <a style="color: #666666; text-decoration: none;">Tel/Fax: 55 (47) 3348-0434</a>
                                                    <br>
                                                    <span style="font-family: Arial, sans-serif; font-size: 12px; color: #444444;"></span>
                                                    <a style="color: #666666; text-decoration: none;">Mensagem automática, gerada eletronicamente pelo serviço de notificação.</a>
                                                </td>
                                            </tr>
                                        </table>
                                    </td>
                                </tr>
                            </table>
                        </body>
                </html>
            """)

            msg = MIMEMultipart('alternative')
            content = MIMEText(email_content, 'html')

            msg['Subject'] = email.subject
            msg['From'] = email.from_address
            msg['To'] = email.to_address
            msg['Cc'] = email.copy_to

            to_address = email.to_address + ',' + email.copy_to
            to_address_plus_copy = [x.strip() for x in to_address.split(',')]

            msg.add_header('Content-Type', 'text/html')
            msg.attach(content)

            #Loga no SMTP
            server.login("*****@*****.**",
                         "modal#7798")
            server.sendmail(email.from_address, to_address_plus_copy,
                            msg.as_string())
            server.quit()

            #Atualiza as informações do objeto email
            email.erro = 'N'
            email.enviada = 'S'
            email.msg_erro = None

            return True

    except Exception as e:
        msg = 'Não foi possível se conectar e enviar os e-mails no SMTP: {}'.format(
            e)

        #Atualiza as informações do objeto email
        email.erro = 'S'
        email.enviada = 'N'
        email.msg_erro = msg

        return False
Example #37
0
class Mdn(object):
    """Class for handling AS2 MDNs. Includes functions for both
    parsing and building them.
    """
    def __init__(self, mdn_mode=None, digest_alg=None, mdn_url=None):
        self.message_id = None
        self.orig_message_id = None
        self.payload = None
        self.mdn_mode = mdn_mode
        self.digest_alg = digest_alg
        self.mdn_url = mdn_url

    @property
    def content(self):
        """Function returns the body of the mdn message as a byte string"""

        if self.payload is not None:
            message_bytes = mime_to_bytes(self.payload)
            boundary = b'--' + self.payload.get_boundary().encode('utf-8')
            temp = message_bytes.split(boundary)
            temp.pop(0)
            return boundary + boundary.join(temp)
        else:
            return ''

    @property
    def headers(self):
        if self.payload:
            return dict(self.payload.items())
        else:
            return {}

    @property
    def headers_str(self):
        message_header = ''
        if self.payload:
            for k, v in self.headers.items():
                message_header += f'{k}: {v}\r\n'
        return message_header.encode('utf-8')

    def build(self,
              message,
              status,
              detailed_status=None,
              confirmation_text=MDN_CONFIRM_TEXT,
              failed_text=MDN_FAILED_TEXT):
        """Function builds and signs an AS2 MDN message.

        :param message: The received AS2 message for which this is an MDN.

        :param status: The status of processing of the received AS2 message.

        :param detailed_status: The optional detailed status of processing of the received AS2
        message. Used to give additional error info (default "None")

        :param confirmation_text: The confirmation message sent in the first part of the MDN.

        :param failed_text: The failure message sent in the first part of the failed MDN.
        """

        # Generate message id using UUID 1 as it uses both hostname and time
        self.message_id = email_utils.make_msgid().lstrip('<').rstrip('>')
        self.orig_message_id = message.message_id

        # Set up the message headers
        mdn_headers = {
            'AS2-Version': AS2_VERSION,
            'ediint-features': EDIINT_FEATURES,
            'Message-ID': f'<{self.message_id}>',
            'AS2-From': quote_as2name(message.headers.get('as2-to')),
            'AS2-To': quote_as2name(message.headers.get('as2-from')),
            'Date': email_utils.formatdate(localtime=True),
            'user-agent': 'pyAS2 Open Source AS2 Software'
        }

        # Set the confirmation text message here
        # overwrite with organization specific message
        if message.receiver and message.receiver.mdn_confirm_text:
            confirmation_text = message.receiver.mdn_confirm_text

        # overwrite with partner specific message
        if message.sender and message.sender.mdn_confirm_text:
            confirmation_text = message.sender.mdn_confirm_text

        if status != 'processed':
            confirmation_text = failed_text

        self.payload = MIMEMultipart('report',
                                     report_type='disposition-notification')

        # Create and attach the MDN Text Message
        mdn_text = email_message.Message()
        mdn_text.set_payload(f'{confirmation_text}\r\n')
        mdn_text.set_type('text/plain')
        del mdn_text['MIME-Version']
        encoders.encode_7or8bit(mdn_text)
        self.payload.attach(mdn_text)

        # Create and attache the MDN Report Message
        mdn_base = email_message.Message()
        mdn_base.set_type('message/disposition-notification')
        mdn_report = 'Reporting-UA: pyAS2 Open Source AS2 Software\r\n'
        mdn_report += f'Original-Recipient: rfc822; {message.headers.get("as2-to")}\r\n'
        mdn_report += f'Final-Recipient: rfc822; {message.headers.get("as2-to")}\r\n'
        mdn_report += f'Original-Message-ID: <{message.message_id}>\r\n'
        mdn_report += f'Disposition: automatic-action/MDN-sent-automatically; {status}'
        if detailed_status:
            mdn_report += f': {detailed_status}'
        mdn_report += '\r\n'
        if message.mic:
            mdn_report += f'Received-content-MIC: {message.mic.decode()}, {message.digest_alg}\r\n'
        mdn_base.set_payload(mdn_report)
        del mdn_base['MIME-Version']
        encoders.encode_7or8bit(mdn_base)
        self.payload.attach(mdn_base)

        logger.debug(
            f'MDN report for message {message.message_id} created:\n{mime_to_bytes(mdn_base)}'
        )

        # Sign the MDN if it is requested by the sender
        if message.headers.get('disposition-notification-options') and \
                message.receiver and message.receiver.sign_key:
            self.digest_alg = message.headers['disposition-notification-options'].\
                split(';')[-1].split(',')[-1].strip().replace('-', '')
            signed_mdn = MIMEMultipart('signed',
                                       protocol="application/pkcs7-signature")
            del signed_mdn['MIME-Version']
            signed_mdn.attach(self.payload)

            # Create the signature mime message
            signature = email_message.Message()
            signature.set_type('application/pkcs7-signature')
            signature.set_param('name', 'smime.p7s')
            signature.set_param('smime-type', 'signed-data')
            signature.add_header('Content-Disposition',
                                 'attachment',
                                 filename='smime.p7s')
            del signature['MIME-Version']

            signed_data = sign_message(canonicalize(self.payload),
                                       self.digest_alg,
                                       message.receiver.sign_key)
            signature.set_payload(signed_data)
            encoders.encode_base64(signature)

            signed_mdn.set_param('micalg', self.digest_alg)
            signed_mdn.attach(signature)

            self.payload = signed_mdn
            logger.debug(f'Signing the MDN for message {message.message_id}')

        # Update the headers of the final payload and set message boundary
        for k, v in mdn_headers.items():
            if self.payload.get(k):
                self.payload.replace_header(k, v)
            else:
                self.payload.add_header(k, v)
        self.payload.set_boundary(make_mime_boundary())
        logger.debug(f'MDN generated for message {message.message_id} with '
                     f'content:\n {mime_to_bytes(self.payload)}')

    def parse(self, raw_content, find_message_cb):
        """Function parses the RAW AS2 MDN, verifies it and extracts the
        processing status of the orginal AS2 message.

        :param raw_content:
            A byte string of the received HTTP headers followed by the body.

        :param find_message_cb:
            A callback the must returns the original Message Object. The
            original message-id and original recipient AS2 ID are passed
            as arguments to it.

        :returns:
            A two element tuple containing (status, detailed_status). The
            status is a string indicating the status of the transaction. The
            optional detailed_status gives additional information about the
            processing status.
        """

        status, detailed_status = None, None
        try:
            self.payload = parse_mime(raw_content)
            self.orig_message_id, orig_recipient = self.detect_mdn()

            # Call the find message callback which should return a Message instance
            orig_message = find_message_cb(self.orig_message_id,
                                           orig_recipient)

            # Extract the headers and save it
            mdn_headers = {}
            for k, v in self.payload.items():
                k = k.lower()
                if k == 'message-id':
                    self.message_id = v.lstrip('<').rstrip('>')
                mdn_headers[k] = v

            if orig_message.receiver.mdn_digest_alg \
                    and self.payload.get_content_type() != 'multipart/signed':
                status = 'failed/Failure'
                detailed_status = 'Expected signed MDN but unsigned MDN returned'
                return status, detailed_status

            if self.payload.get_content_type() == 'multipart/signed':
                logger.debug(
                    f'Verifying signed MDN: \n{mime_to_bytes(self.payload)}')
                message_boundary = (
                    '--' + self.payload.get_boundary()).encode('utf-8')

                # Extract the signature and the signed payload
                signature = None
                signature_types = [
                    'application/pkcs7-signature',
                    'application/x-pkcs7-signature'
                ]
                for part in self.payload.walk():
                    if part.get_content_type() in signature_types:
                        signature = part.get_payload(decode=True)
                    elif part.get_content_type() == 'multipart/report':
                        self.payload = part

                # Verify the message, first using raw message and if it fails
                # then convert to canonical form and try again
                mic_content = extract_first_part(raw_content, message_boundary)
                verify_cert = orig_message.receiver.load_verify_cert()
                try:
                    self.digest_alg = verify_message(mic_content, signature,
                                                     verify_cert)
                except IntegrityError:
                    mic_content = canonicalize(self.payload)
                    self.digest_alg = verify_message(mic_content, signature,
                                                     verify_cert)

            for part in self.payload.walk():
                if part.get_content_type(
                ) == 'message/disposition-notification':
                    logger.debug(
                        f'MDN report for message {orig_message.message_id}:\n{part.as_string()}'
                    )

                    mdn = part.get_payload()[-1]
                    mdn_status = mdn['Disposition'].split(
                        ';').pop().strip().split(':')
                    status = mdn_status[0]
                    if status == 'processed':
                        # Compare the original mic with the received mic
                        mdn_mic = mdn.get('Received-Content-MIC',
                                          '').split(',')[0]
                        if mdn_mic and orig_message.mic and mdn_mic != orig_message.mic.decode(
                        ):
                            status = 'processed/warning'
                            detailed_status = 'Message Integrity check failed.'
                    else:
                        detailed_status = ' '.join(mdn_status[1:]).strip()
        except MDNNotFound:
            status = 'failed/Failure'
            detailed_status = 'mdn-not-found'
        except Exception as e:
            status = 'failed/Failure'
            detailed_status = f'Failed to parse received MDN. {e}'
            logger.error(
                f'Failed to parse AS2 MDN\n: {traceback.format_exc()}')

        finally:
            return status, detailed_status

    def detect_mdn(self):
        """ Function checks if the received raw message is an AS2 MDN or not.

        :raises MDNNotFound: If the received payload is not an MDN then this
        exception is raised.

        :return:
            A two element tuple containing (message_id, message_recipient). The
            message_id is the original AS2 message id and the message_recipient
            is the original AS2 message recipient.
        """
        mdn_message = None
        if self.payload.get_content_type() == 'multipart/report':
            mdn_message = self.payload
        elif self.payload.get_content_type() == 'multipart/signed':
            for part in self.payload.walk():
                if part.get_content_type() == 'multipart/report':
                    mdn_message = self.payload

        if not mdn_message:
            raise MDNNotFound('No MDN found in the received message')

        message_id, message_recipient = None, None
        for part in mdn_message.walk():
            if part.get_content_type() == 'message/disposition-notification':
                mdn = part.get_payload()[0]
                message_id = mdn.get('Original-Message-ID').strip('<>')
                original_recipient = mdn.get('Original-Recipient')
                if original_recipient is not None:
                    message_recipient = mdn.get('Original-Recipient').\
                      split(';')[1].strip()
                else:
                    message_recipient = ""
        return message_id, message_recipient
Example #38
0
def create_multilingual_mail(template_name: str, subject: str, context: dict,
                             **kwargs) -> EmailMessage:
    """
    Creates an instance of EmailMessage. If multiple languages exist for
    the given template name, it will create an RFC8255_ compatible email, and if
    only one language exists, it will simply send an email in that language,
    without bothering with any multilingual crap.

    As of implementing this method, very few to no email clients support
    RFC8255_ and so it is recommended to either use create_mail with a
    preference language or use this method and only create one set of language
    templates.

    :param template_name: The template that should be used for this email
    :param subject: The subject of this email
    :param context: The context for the template
    :param kwargs: Any other data that should be passed to the EmailMessage
        constructor
    :return: an EmailMessage

    .. _RFC8255: https://tools.ietf.org/html/rfc8255
    """
    _ensure_setup()
    kwargs['headers'] = kwargs['headers'] if 'headers' in kwargs else {}

    kwargs['headers'] = {"X-Mailer": get_mailer_name(), **kwargs['headers']}

    langs = templates[template_name]

    if len(langs.items()) == 1:
        lang, tpls = list(langs.items())[0]

        with language(lang):
            kwargs['headers'] = {"Content-Language": lang, **kwargs['headers']}

            msg = MultiTemplatableEmailMessage(subject=subject,
                                               body=False,
                                               **kwargs)

            for template in tpls:
                msg.attach_alternative(
                    SafeMIMEText(_text=get_template(template['file']).render({
                        'locale':
                        template['locale'],
                        **context,
                    }),
                                 _subtype=template['subtype'],
                                 _charset=msg.encoding
                                 or settings.DEFAULT_CHARSET),
                    'unknown/unknown')

        return msg

    msg = MultilingualEmailMessage(subject=subject, **kwargs)

    for lang, tpls in langs.items():
        with language(lang):
            lang_alt = MIMEMultipart(_subtype='alternative')
            lang_alt.add_header("Subject", _(subject))

            for template in tpls:
                lang_alt.attach(
                    SafeMIMEText(get_template(template['file']).render({
                        'locale':
                        template['locale'],
                        **context,
                    }),
                                 _subtype=template['subtype']))

            msg.add_language(lang, lang_alt)

    info = MIMEMultipart(_subtype='alternative')
    info.attach(
        SafeMIMEText(get_template(
            "steambird/../templates/mail/multilingual_header.html").render({}),
                     _subtype="html",
                     _charset="utf-8"))
    info.attach(
        SafeMIMEText(get_template(
            "steambird/../templates/mail/multilingual_header.plain").render(
                {}),
                     _subtype="plain",
                     _charset="utf-8"))

    info.add_header("Content-Disposition", "inline")

    msg.attach(info)

    return msg
Example #39
0
def encode_base64(msg):
  """Extend encoders.encode_base64 to return CRLF at end of lines"""
  original_encode_base64(msg)
  msg.set_payload(msg.get_payload().replace("\n", "\r\n"))

outer = MIMEMultipart(subtype)
for key, value in param_list:
  outer.set_param(key, value)
if boundary is not None:
  outer.set_boundary(boundary)
if replace_header_list is not None:
  for key, value in replace_header_list:
    outer.replace_header(key, value)
if header_dict is not None:  # adds headers, does not replace or set
  for key, value in header_dict.items():
    outer.add_header(key, value)
if add_header_list is not None:
  for key, value in add_header_list:
    outer.add_header(key, value)
for attachment in attachment_list:
  mime_type = attachment.get("mime_type", "application/octet-stream")
  data = attachment.get("data", "")
  encoding = attachment.get("encode")
  if encoding not in ("base64", "quoted-printable", "7or8bit", "noop", None):
    raise ValueError("unknown attachment encoding %r" % encoding)
  main_type, sub_type = mime_type.split("/")
  if encoding is None:
    if main_type == "image":
      if sub_type == "svg+xml":
        part = MIMEImage(data, sub_type, encode_quopri)  # should we trust the mime_type ?
      else:
    def send_email(
        self,
        message_html="",
        subject="",
        sent_from="Data and Analytics Team <*****@*****.**>",
        to=[],
        cc=[],
        bcc=[],
        reciepts=[],
        attachments=[],
        extra_headers={
            "Return-Path": "<>",
            "Auto-Submitted": "auto-generated"
        },
    ):
        """Compile and send a html email message"""

        # We cannot send an email if there is nobody to send it to
        if to == [] and cc == [] and bcc == []:
            print("No recipients")
            return

        # Create a text-only version of the message
        message_text = "\n\n".join([
            x.strip()
            for x in MLStripper().strip_tags(message_html).split("\n")
            if x.strip()
        ])

        # Create message container - the correct MIME type is multipart/alternative.
        msg = MIMEMultipart("alternative")

        # Fill message header fields
        msg["Subject"] = subject
        msg.add_header("reply-to", sent_from)
        msg["From"] = sent_from
        msg["To"] = ", ".join(to)
        msg["Cc"] = ", ".join(cc)
        msg["Bcc"] = ", ".join(bcc)
        # Do we want read-reciepts?
        if reciepts:
            msg["Disposition-Notification-To"] = ", ".join(reciepts)

        # Read, encode and add any attachments
        for f in attachments:
            with open(f, "rb") as fil:
                part = MIMEApplication(fil.read(), Name=os.path.basename(f))
            # After the file is closed
            part[
                "Content-Disposition"] = f'attachment; filename="{os.path.basename(f)}"'
            msg.attach(part)

        # Record the MIME types of both parts - text/plain and text/html.
        part1 = MIMEText(message_text, "plain")
        part2 = MIMEText(message_html, "html")

        # Attach parts into message container.
        # According to RFC 2046, the last part of a multipart message, in this case
        # the HTML message, is best and preferred.
        msg.attach(part1)
        msg.attach(part2)

        # Add any extra headers that we want to the message
        for header, value in extra_headers.items():
            msg.add_header(header, value)

        # Actually send the message
        self._send(msg)
Example #41
0
def training_report(df):
    for event in df[(df['meetreq_status'] == 'done')
                    & (df['report_status'].isnull()) &
                    (df['fdh_status'] == 'done')]['event_code'].unique():
        list_to = []
        df_dept = wb_trainee[wb_trainee['event_code'] == event]
        for i in wb_cc[wb_cc['dept'].isin(
                df_dept['dept'].unique().tolist())].iloc[:,
                                                         2:].values.tolist():
            for l in i:
                if l not in list_to and str(l) != 'nan':
                    list_to.append(l)

        list_cc = wb_trainer[wb_trainer['event_code'] ==
                             event].loc[:, 'trainer_email'].values.tolist()

        # fro = "*****@*****.**"
        fro = formataddr(
            (str(Header('YDL',
                        'utf-8')), '*****@*****.**'))
        rt = replyto

        new_df1 = wb_main[wb_main['event_code'] == event]
        new_df2 = wb_trainer[wb_trainer['event_code'] == event]
        new_df3 = wb_trainee[wb_trainee['event_code'] == event]
        new_df = new_df1.merge(new_df2,
                               on=['event_code', 'event_name'],
                               how='left')
        new_df = new_df.merge(new_df3,
                              on=['event_code', 'event_name'],
                              how='left')
        new_df = new_df.merge(wb_cc, on='dept', how='left')

        table_1 = new_df[['event_name', 'trainer_name',
                          'event_date']].set_index('event_name')
        table_1 = table_1.drop_duplicates(keep='last')
        table_1 = table_1.transpose()

        table_2 = new_df[[
            'trainee_name', 'dept', 'atasan', 'nilai_post_test', 'presensi',
            'absent_remark'
        ]]

        total_id_1 = 'totalID1'
        header_id_1 = 'headerID1'
        total_id_2 = 'totalID2'
        header_id_2 = 'headerID2'
        style_1_in_html = """<style>table#{total_table} {{color='black';font-size:13px; text-align:left; border:0.2px solid black; border-collapse:collapse; table-layout:fixed; padding:10px; width=100%; height="250"; text-align:left}} thead#{header_table} {{background-color: #fff645; color:#000000}}</style>""".format(
            total_table=total_id_1, header_table=header_id_1)
        style_2_in_html = """<style>table#{total_table} {{color='black';font-size:13px; text-align:center; border:0.2px solid black; border-collapse:collapse; table-layout:fixed; padding:10px; width=100%; height="250"; text-align:center}} thead#{header_table} {{background-color: #fff645; color:#000000}}</style>""".format(
            total_table=total_id_2, header_table=header_id_2)
        table_1_in_html = table_1.to_html()
        table_1_in_html = re.sub(r'<table', r'<table id=%s ' % total_id_1,
                                 table_1_in_html)
        table_1_in_html = re.sub(r'<thead', r'<thead id=%s ' % header_id_1,
                                 table_1_in_html)
        table_2_in_html = table_2.to_html(index=False)
        table_2_in_html = re.sub(r'<table', r'<table id=%s ' % total_id_2,
                                 table_2_in_html)
        table_2_in_html = re.sub(r'<thead', r'<thead id=%s ' % header_id_2,
                                 table_2_in_html)
        body1 = "<p>Dear rekan-rekan leader,<br/>Berikut adalah report dari pelaksanaan training:<br/></p>"
        body2 = style_1_in_html + table_1_in_html
        body3 = style_2_in_html + table_2_in_html
        body4 = f"<p>Terimakasih,<br/><br/>{quote}<br/></p>"
        body5 = "<br/>"
        body = body1 + body2 + body5 + body3 + body4

        msg = MIMEMultipart()
        msg['From'] = fro
        msg['To'] = ",".join(list_to)
        msg['Cc'] = ",".join(list_cc)
        msg['Subject'] = "Report {}".format(new_df['event_name'].unique()[0])
        msg.add_header('reply-to', ",".join(rt))
        msg.attach(MIMEText(body, 'html'))

        idx = wb_main[wb_main['event_code'] == event].index[0]
        update_excel(idx, column="O")

        mailServer = smtplib.SMTP('smtp.gmail.com', 587)
        mailServer.ehlo()
        mailServer.starttls()
        mailServer.ehlo()
        mailServer.login(login, password)
        mailServer.sendmail(msg['From'], list_to + list_cc, msg.as_string())
        mailServer.close()

        print(
            "Report", event, "-",
            wb_main[wb_main['event_code'] == event]['event_name'].iloc[0],
            "." * (35 - len(wb_main[wb_main['event_code'] == event]
                            ['event_name'].iloc[0])), "done")
Example #42
0
def apply_mtom(headers, envelope, params, paramvals):
    """Apply MTOM to a SOAP envelope, separating attachments into a
    MIME multipart message.

    Returns a tuple of length 2 with dictionary of headers and string of body
    that can be sent with HTTPConnection

    References:
    XOP     http://www.w3.org/TR/xop10/
    MTOM    http://www.w3.org/TR/soap12-mtom/
            http://www.w3.org/Submission/soap11mtom10/

    :param headers   Headers dictionary of the SOAP message that would
                     originally be sent.
    :param envelope  Iterable containing SOAP envelope string that would have
                     originally been sent.
    :param params    params attribute from the Message object used for the SOAP
    :param paramvals values of the params, passed to Message.to_parent
    """

    # grab the XML element of the message in the SOAP body
    envelope = ''.join(envelope)

    soaptree = etree.fromstring(envelope)
    soapbody = soaptree.find("{%s}Body" % _ns_soap_env)

    message = None
    for child in list(soapbody):
        if child.tag == ("{%s}Fault" % _ns_soap_env):
            return headers, envelope
        else:
            message = child
            break

    # Get additional parameters from original Content-Type
    ctarray = []
    for n, v in headers.items():
        if n.lower() == 'content-type':
            ctarray = v.split(';')
            break

    roottype = ctarray[0].strip()
    rootparams = {}
    for ctparam in ctarray[1:]:
        n, v = ctparam.strip().split('=')
        rootparams[n] = v.strip("\"'")

    # Set up initial MIME parts.
    mtompkg = MIMEMultipart('related', boundary='?//<><>spyne_MIME_boundary<>')
    rootpkg = MIMEApplication(envelope, 'xop+xml', encode_7or8bit)

    # Set up multipart headers.
    del mtompkg['mime-version']
    mtompkg.set_param('start-info', roottype)
    mtompkg.set_param('start', '<spyneEnvelope>')
    if 'SOAPAction' in headers:
        mtompkg.add_header('SOAPAction', headers.get('SOAPAction'))

    # Set up root SOAP part headers.
    del rootpkg['mime-version']

    rootpkg.add_header('Content-ID', '<spyneEnvelope>')

    for n, v in rootparams.items():
        rootpkg.set_param(n, v)

    rootpkg.set_param('type', roottype)

    mtompkg.attach(rootpkg)

    # Extract attachments from SOAP envelope.
    for i in range(len(params)):
        name, typ = params[i]

        if issubclass(typ, (ByteArray, File)):
            id = "SpyneAttachment_%s" % (len(mtompkg.get_payload()), )

            param = message[i]
            param.text = ""

            incl = etree.SubElement(param, "{%s}Include" % _ns_xop)
            incl.attrib["href"] = "cid:%s" % id

            if paramvals[i].fileName and not paramvals[i].data:
                paramvals[i].load_from_file()

            if issubclass(type, File):
                data = paramvals[i].data
            else:
                data = ''.join(paramvals[i])

            attachment = MIMEApplication(data, _encoder=encode_7or8bit)

            del attachment['mime-version']

            attachment.add_header('Content-ID', '<%s>' % (id, ))
            mtompkg.attach(attachment)

    # Update SOAP envelope.
    rootpkg.set_payload(etree.tostring(soaptree))

    # extract body string from MIMEMultipart message
    bound = '--%s' % (mtompkg.get_boundary(), )
    marray = mtompkg.as_string().split(bound)
    mtombody = bound
    mtombody += bound.join(marray[1:])

    # set Content-Length
    mtompkg.add_header("Content-Length", str(len(mtombody)))

    # extract dictionary of headers from MIMEMultipart message
    mtomheaders = {}
    for name, value in mtompkg.items():
        mtomheaders[name] = value

    if len(mtompkg.get_payload()) <= 1:
        return headers, envelope

    return mtomheaders, [mtombody]
Example #43
0
def eti_report(df):
    for event in df[(df['meetreq_status'] == 'done')
                    & (df['eti_status'].isnull()) &
                    (df['fdh_status'] == 'done')]['event_code'].unique():
        list_to = wb_trainer[wb_trainer['event_code'] ==
                             event].loc[:, 'trainer_email'].values.tolist()

        fro = formataddr(
            (str(Header('YDL',
                        'utf-8')), '*****@*****.**'))

        topic = wb_main[wb_main['event_code'] ==
                        event].loc[:, 'event_name'].values.tolist()[0]
        hartang = str(wb_main[wb_main['event_code'] == event].
                      loc[:, 'event_day'].iloc[0]) + " / " + str(
                          wb_main[wb_main['event_code'] == event].
                          loc[:, 'event_date'].iloc[0].strftime("%H:%M:%S"))
        wakdar = str(
            wb_main[wb_main['event_code'] == event].loc[:, 'event_date'].
            iloc[0].strftime("%Y-%m-%d")) + " / " + str(
                wb_main[wb_main['event_code'] == event].
                loc[:, 'event_duration'].values.tolist()[0]) + " menit"
        loc = wb_trainroom[wb_trainroom['event_code'] ==
                           event].loc[:, 'meeting_room'].values[0]
        trainer = wb_trainer[wb_trainer['event_code'] ==
                             event].loc[:, 'trainer_name'].values[0]
        sumtrainee = len(wb_trainee[wb_trainee['event_code'] ==
                                    event].loc[:,
                                               'trainee_name'].values.tolist())

        code = wb_main[wb_main['event_code'] ==
                       event].loc[:, 'eval_training_code'].values[0]
        mean_eti_trainer_materi = wb_eti[wb_eti['eval_training_code'] ==
                                         code]['eti_trainer_materi'].mean()
        mean_eti_trainer_penampilan = wb_eti[
            wb_eti['eval_training_code'] ==
            code]['eti_trainer_penampilan'].mean()
        mean_eti_trainer_interaksi = wb_eti[
            wb_eti['eval_training_code'] ==
            code]['eti_trainer_interaksi'].mean()
        mean_eti_trainer_waktu = wb_eti[wb_eti['eval_training_code'] ==
                                        code]['eti_trainer_waktu'].mean()
        mean_eti_materi_bobot = wb_eti[wb_eti['eval_training_code'] ==
                                       code]['eti_materi_bobot'].mean()
        mean_eti_materi_jelas = wb_eti[wb_eti['eval_training_code'] ==
                                       code]['eti_materi_jelas'].mean()
        mean_eti_materi_objective = wb_eti[
            wb_eti['eval_training_code'] ==
            code]['eti_materi_objective'].mean()
        mean_eti_metode_objective = wb_eti[
            wb_eti['eval_training_code'] ==
            code]['eti_metode_objective'].mean()
        mean_eti_organizer = wb_eti[wb_eti['eval_training_code'] ==
                                    code]['eti_organizer'].mean()
        mean_eti_trainee_relevan = wb_eti[wb_eti['eval_training_code'] ==
                                          code]['eti_trainee_relevan'].mean()
        mean_eti_trainee_manfaat = wb_eti[wb_eti['eval_training_code'] ==
                                          code]['eti_trainee_manfaat'].mean()
        all_eti_essay_1 = "<br>".join(
            wb_eti[wb_eti['eval_training_code'] == code]['eti_essay_1'])
        all_eti_essay_2 = "<br>".join(
            wb_eti[wb_eti['eval_training_code'] == code]['eti_essay_2'])
        all_eti_essay_3 = "<br>".join(
            wb_eti[wb_eti['eval_training_code'] == code]['eti_essay_3'])

        df_trainee_postest = wb_trainee[wb_trainee['event_code'] == event]
        df_trainee_postest = df_trainee_postest.loc[:, [
            'trainee_name', 'NIK', 'dept', 'nilai_post_test'
        ]]

        body1 = f"""Dear {trainer},<br>
                Terimakasih sudah membawakan materi training. Berikut adalah Evaluasi Training Internal dari peserta training.<br><br>
                Topik\t\t: {topic} <br>
                Hari/tanggal\t\t: {hartang} <br>
                Waktu/durasi\t\t: {wakdar} <br>
                Tempat\t\t: {loc} <br>
                Jumlah peserta\t\t: {sumtrainee} <br><br>"""
        body2 = f"""<table border="1">
                    <tr>
                        <th>Aspek Trainer</th>
                        <th>Skala Nilai</th>
                    </tr>
                    <tr>
                        <td>Penguasaan materi</td>
                        <td>{mean_eti_trainer_materi:.2f}</td>
                    </tr>
                    <tr>
                        <td>Penampilan & body language</td>
                        <td>{mean_eti_trainer_penampilan:.2f}</td>
                    </tr>
                    <tr>
                        <td>Kemampuan interaksi</td>
                        <td>{mean_eti_trainer_interaksi:.2f}</td>
                    </tr>
                    <tr>
                        <td>Alokasi waktu training</td>
                        <td>{mean_eti_trainer_waktu:.2f}</td>
                    </tr>
                </table><br><br>"""
        body3 = f"""<table border="1">
                    <tr>
                        <th>Aspek Materi</th>
                        <th>Skala Nilai</th>
                    </tr>
                    <tr>
                        <td>Bobot</td>
                        <td>{mean_eti_materi_bobot:.2f}</td>
                    </tr>
                    <tr>
                        <td>Kejelasan</td>
                        <td>{mean_eti_materi_jelas:.2f}</td>
                    </tr>
                    <tr>
                        <td>Kesesuaian materi dgn objective training</td>
                        <td>{mean_eti_materi_objective:.2f}</td>
                    </tr>
                </table><br><br>"""
        body4 = f"""<table border="1">
                    <tr>
                        <th>Aspek Metode</th>
                        <th>Skala Nilai</th>
                    </tr>
                    <tr>
                        <td>Kesesuaian metode dgn objective training</td>
                        <td>{mean_eti_metode_objective:.2f}</td>
                    </tr>
                </table><br><br>"""
        body5 = f"""<table border="1">
                    <tr>
                        <th>Aspek Organizer</th>
                        <th>Skala Nilai</th>
                    </tr>
                    <tr>
                        <td>Layout, suhu & kebersihan ruangan</td>
                        <td>{mean_eti_organizer:.2f}</td>
                    </tr>
                </table><br><br>"""
        body6 = f"""<table border="1">
                    <tr>
                        <th>Aspek Trainee</th>
                        <th>Skala Nilai</th>
                    </tr>
                    <tr>
                        <td>Relevansi ke pekerjaan</td>
                        <td>{mean_eti_trainee_relevan:.2f}</td>
                    </tr>
                    <tr>
                        <td>Manfaat ke pekerjaan</td>
                        <td>{mean_eti_trainee_manfaat:.2f}</td>
                    </tr>
                    <tr>
                        <td>Poin-poin penting yg bermanfaat bagi pekerjaan</td>
                        <td>{all_eti_essay_1}</td>
                    </tr>
                    <tr>
                        <td>Poin-poin yg akan diimplementasikan dalam pekerjaan</td>
                        <td>{all_eti_essay_2}</td>
                    </tr>
                </table><br><br>"""
        body7 = f"""<table border="1">
                    <tr>
                        <th>Usulan Perbaikan</th>
                    </tr>
                    <tr>
                        <td>{all_eti_essay_3}</td>
                    </tr>
                </table><br><br>"""
        body8 = f"""<table border="1">
                    <tr>
                        <th>Nama Peserta</th>
                        <th>NIK</th>
                        <th>Dept</th>
                        <th>Nilai post-test</th>
                    </tr>"""
        for i in df_trainee_postest.index:
            body8 += f"""<tr>
                            <td>{df_trainee_postest.trainee_name[i]}</td>
                            <td>{df_trainee_postest.NIK[i]}</td>
                            <td>{df_trainee_postest.dept[i]}</td>
                            <td>{df_trainee_postest.nilai_post_test[i]}</td>
                        </tr>"""
        body8 += """</table><br><br>"""
        body9 = "Terimakasih,<br>Salam,<br>YDL<br>"
        body10 = f"{quote}"
        body = body1 + body2 + body3 + body4 + body5 + body6 + body7 + body8 + body9 + body10

        msg = MIMEMultipart()
        msg['From'] = fro
        msg['To'] = ",".join(list_to)
        # msg['Cc'] = ",".join(['*****@*****.**'])
        msg['Subject'] = f"Report ETI {topic}"
        msg.add_header('reply-to',
                       ",".join([fro, '*****@*****.**']))
        msg.attach(MIMEText(body, 'html'))

        idx = wb_main[wb_main['event_code'] == event].index[0]
        update_excel(idx, column="M")

        mailServer = smtplib.SMTP('smtp.gmail.com', 587)
        mailServer.ehlo()
        mailServer.starttls()
        mailServer.ehlo()
        mailServer.login(login, password)
        mailServer.sendmail(fro, list_to, msg.as_string())
        mailServer.close()

        print(
            "Report ETI", event, "-",
            wb_main[wb_main['event_code'] == event]['event_name'].iloc[0],
            "." * (35 - len(wb_main[wb_main['event_code'] == event]
                            ['event_name'].iloc[0])), 'done')
Example #44
0
def main():

    module = AnsibleModule(
        argument_spec=dict(
            username=dict(type='str'),
            password=dict(type='str', no_log=True),
            host=dict(type='str', default='localhost'),
            port=dict(type='int', default=25),
            sender=dict(type='str', default='root', aliases=['from']),
            to=dict(type='list', default=['root'], aliases=['recipients']),
            cc=dict(type='list', default=[]),
            bcc=dict(type='list', default=[]),
            subject=dict(type='str', required=True, aliases=['msg']),
            body=dict(type='str'),
            attach=dict(type='list', default=[]),
            headers=dict(type='list', default=[]),
            charset=dict(type='str', default='utf-8'),
            subtype=dict(type='str', default='plain', choices=['html', 'plain']),
            secure=dict(type='str', default='try', choices=['always', 'never', 'starttls', 'try']),
            timeout=dict(type='int', default=20),
        ),
        required_together=[['password', 'username']],
    )

    username = module.params.get('username')
    password = module.params.get('password')
    host = module.params.get('host')
    port = module.params.get('port')
    sender = module.params.get('sender')
    recipients = module.params.get('to')
    copies = module.params.get('cc')
    blindcopies = module.params.get('bcc')
    subject = module.params.get('subject')
    body = module.params.get('body')
    attach_files = module.params.get('attach')
    headers = module.params.get('headers')
    charset = module.params.get('charset')
    subtype = module.params.get('subtype')
    secure = module.params.get('secure')
    timeout = module.params.get('timeout')

    code = 0
    secure_state = False
    sender_phrase, sender_addr = parseaddr(sender)

    if not body:
        body = subject

    try:
        if secure != 'never':
            try:
                smtp = smtplib.SMTP_SSL(timeout=timeout)
                code, smtpmessage = smtp.connect(host, port=port)
                secure_state = True
            except ssl.SSLError as e:
                if secure == 'always':
                    module.fail_json(rc=1, msg='Unable to start an encrypted session to %s:%s: %s' %
                                               (host, port, to_native(e)), exception=traceback.format_exc())

        if not secure_state:
            smtp = smtplib.SMTP(timeout=timeout)
            code, smtpmessage = smtp.connect(host, port=port)

    except smtplib.SMTPException as e:
        module.fail_json(rc=1, msg='Unable to Connect %s:%s: %s' % (host, port, to_native(e)), exception=traceback.format_exc())

    try:
        smtp.ehlo()
    except smtplib.SMTPException as e:
            module.fail_json(rc=1, msg='Helo failed for host %s:%s: %s' % (host, port, to_native(e)), exception=traceback.format_exc())

    if int(code) > 0:
        if not secure_state and secure in ('starttls', 'try'):
            if smtp.has_extn('STARTTLS'):
                try:
                    smtp.starttls()
                    secure_state = True
                except smtplib.SMTPException as e:
                    module.fail_json(rc=1, msg='Unable to start an encrypted session to %s:%s: %s' %
                                     (host, port, to_native(e)), exception=traceback.format_exc())
                try:
                    smtp.ehlo()
                except smtplib.SMTPException as e:
                    module.fail_json(rc=1, msg='Helo failed for host %s:%s: %s' % (host, port, to_native(e)), exception=traceback.format_exc())
            else:
                if secure == 'starttls':
                    module.fail_json(rc=1, msg='StartTLS is not offered on server %s:%s' % (host, port))

    if username and password:
        if smtp.has_extn('AUTH'):
            try:
                smtp.login(username, password)
            except smtplib.SMTPAuthenticationError:
                module.fail_json(rc=1, msg='Authentication to %s:%s failed, please check your username and/or password' % (host, port))
            except smtplib.SMTPException:
                module.fail_json(rc=1, msg='No Suitable authentication method was found on %s:%s' % (host, port))
        else:
            module.fail_json(rc=1, msg="No Authentication on the server at %s:%s" % (host, port))

    if not secure_state and (username and password):
        module.warn('Username and Password was sent without encryption')

    msg = MIMEMultipart(_charset=charset)
    msg['From'] = formataddr((sender_phrase, sender_addr))
    msg['Subject'] = Header(subject, charset)
    msg.preamble = "Multipart message"

    for header in headers:
        # NOTE: Backward compatible with old syntax using '|' as delimiter
        for hdr in [x.strip() for x in header.split('|')]:
            try:
                h_key, h_val = hdr.split('=')
                h_val = to_native(Header(h_val, charset))
                msg.add_header(h_key, h_val)
            except Exception:
                module.warn("Skipping header '%s', unable to parse" % hdr)

    if 'X-Mailer' not in msg:
        msg.add_header('X-Mailer', 'Ansible mail module')

    addr_list = []
    for addr in [x.strip() for x in blindcopies]:
        addr_list.append(parseaddr(addr)[1])    # address only, w/o phrase

    to_list = []
    for addr in [x.strip() for x in recipients]:
        to_list.append(formataddr(parseaddr(addr)))
        addr_list.append(parseaddr(addr)[1])    # address only, w/o phrase
    msg['To'] = ", ".join(to_list)

    cc_list = []
    for addr in [x.strip() for x in copies]:
        cc_list.append(formataddr(parseaddr(addr)))
        addr_list.append(parseaddr(addr)[1])    # address only, w/o phrase
    msg['Cc'] = ", ".join(cc_list)

    part = MIMEText(body + "\n\n", _subtype=subtype, _charset=charset)
    msg.attach(part)

    # NOTE: Backware compatibility with old syntax using space as delimiter is not retained
    #       This breaks files with spaces in it :-(
    for filename in attach_files:
        try:
            part = MIMEBase('application', 'octet-stream')
            with open(filename, 'rb') as fp:
                part.set_payload(fp.read())
            encoders.encode_base64(part)
            part.add_header('Content-disposition', 'attachment', filename=os.path.basename(filename))
            msg.attach(part)
        except Exception as e:
            module.fail_json(rc=1, msg="Failed to send mail: can't attach file %s: %s" %
                             (filename, to_native(e)), exception=traceback.format_exc())

    composed = msg.as_string()

    try:
        result = smtp.sendmail(sender_addr, set(addr_list), composed)
    except Exception as e:
        module.fail_json(rc=1, msg="Failed to send mail to '%s': %s" %
                         (", ".join(set(addr_list)), to_native(e)), exception=traceback.format_exc())

    smtp.quit()

    if result:
        for key in result:
            module.warn("Failed to send mail to '%s': %s %s" % (key, result[key][0], result[key][1]))
        module.exit_json(msg='Failed to send mail to at least one recipient', result=result)

    module.exit_json(msg='Mail sent successfully', result=result)
# Create message container. The correct MIME type is multipart/alternative.
msg = MIMEMultipart('alternative')

# Add sender and recipient addresses to the message
msg['From'] = SENDER
msg['To'] = RECIPIENT
msg['Cc'] = CCRECIPIENT
msg['Bcc'] = BCCRECIPIENT

# Add the subject line, text body, and HTML body to the message.
msg['Subject'] = SUBJECT
msg.attach(textPart)
msg.attach(htmlPart)

# Add  headers for configuration set and message tags to the message.
msg.add_header('X-SES-CONFIGURATION-SET', CONFIGURATION_SET)
msg.add_header('X-SES-MESSAGE-TAGS', TAG0)
msg.add_header('X-SES-MESSAGE-TAGS', TAG1)

# Open a new connection to the SMTP server and begin the SMTP conversation.
try:
    with smtplib.SMTP(HOST, PORT) as server:
        server.ehlo()
        server.starttls()
        #stmplib docs recommend calling ehlo() before and after starttls()
        server.ehlo()
        server.login(USERNAME_SMTP, PASSWORD_SMTP)
        #Uncomment the next line to send SMTP server responses to stdout
        #server.set_debuglevel(1)
        server.sendmail(SENDER, RECIPIENT, msg.as_string())
except Exception as e:
Example #46
0
def send(body, subject, attachments=None):
    """Read a configuration file.

    Args:
        body: Text for email body
        subject: Subject for email
        attachments: List of filepaths to attach

    Returns:
        success: True if succesful

    """
    # Initialize key variables
    success = False
    config = Config()

    # Create SMTP TLS session
    client = smtplib.SMTP('smtp.gmail.com', 587)
    try:
        client.ehlo()
    except:
        _exception = sys.exc_info()
        log_message = 'Gmail Communication Failure'
        log.log2exception(1013, _exception, message=log_message)
    client.starttls()

    # Authentication
    try:
        client.login(config.smtp_user, config.smtp_pass)
    except:
        _exception = sys.exc_info()
        log_message = 'Gmail Authentication Failure'
        log.log2exception(1014, _exception, message=log_message)
        return success

    # Format message
    message = MIMEMultipart()
    message['Subject'] = subject
    message['From'] = config.email_from
    message['To'] = ', '.join(config.email_to)
    message.add_header('reply-to', config.email_from)
    html = '''
<html>
    <head></head>
    <body><font face="courier">
        {}
    </font></body>
</html>
'''.format('<br>'.join('&nbsp;'.join(body.split(' ')).split('\n')))

    message.attach(MIMEText(html, 'html', 'UTF-8'))

    # Add attachment if required
    if bool(attachments) is True:
        if isinstance(attachments, list) is True:
            for attachment in attachments:
                part = MIMEApplication(open(attachment, 'rb').read())
                part.add_header('Content-Disposition',
                                'attachment',
                                filename=('{}'.format(attachment)))
                message.attach(part)

    # Send
    try:
        client.sendmail(config.email_from, config.email_to,
                        message.as_string())
        success = True
    except:
        _exception = sys.exc_info()
        log_message = 'Gmail Send Failure'
        log.log2exception(1015, _exception, message=log_message)
        return success
    finally:
        client.quit()
    return success
Example #47
0
class Mdn(object):
    """Class for handling AS2 MDNs. Includes functions for both
    parsing and building them.
    """

    def __init__(self, mdn_mode=None, digest_alg=None, mdn_url=None):
        self.message_id = None
        self.orig_message_id = None
        self.payload = None
        self.mdn_mode = mdn_mode
        self.digest_alg = digest_alg
        self.mdn_url = mdn_url

    @property
    def content(self):
        """Function returns the body of the mdn message as a byte string"""

        if self.payload is not None:
            message_bytes = mime_to_bytes(self.payload)
            boundary = b"--" + self.payload.get_boundary().encode("utf-8")
            temp = message_bytes.split(boundary)
            temp.pop(0)
            return boundary + boundary.join(temp)
        else:
            return ""

    @property
    def headers(self):
        if self.payload:
            return dict(self.payload.items())
        else:
            return {}

    @property
    def headers_str(self):
        message_header = ""
        if self.payload:
            for k, v in self.headers.items():
                message_header += f"{k}: {v}\r\n"
        return message_header.encode("utf-8")

    def build(
        self,
        message,
        status,
        detailed_status=None,
        confirmation_text=MDN_CONFIRM_TEXT,
        failed_text=MDN_FAILED_TEXT,
    ):
        """Function builds and signs an AS2 MDN message.

        :param message: The received AS2 message for which this is an MDN.

        :param status: The status of processing of the received AS2 message.

        :param detailed_status: The optional detailed status of processing of the received AS2
        message. Used to give additional error info (default "None")

        :param confirmation_text: The confirmation message sent in the first part of the MDN.

        :param failed_text: The failure message sent in the first part of the failed MDN.
        """

        # Generate message id using UUID 1 as it uses both hostname and time
        self.message_id = email_utils.make_msgid().lstrip("<").rstrip(">")
        self.orig_message_id = message.message_id

        # Set up the message headers
        mdn_headers = {
            "AS2-Version": AS2_VERSION,
            "ediint-features": EDIINT_FEATURES,
            "Message-ID": f"<{self.message_id}>",
            "AS2-From": quote_as2name(message.headers.get("as2-to")),
            "AS2-To": quote_as2name(message.headers.get("as2-from")),
            "Date": email_utils.formatdate(localtime=True),
            "user-agent": "pyAS2 Open Source AS2 Software",
        }

        # Set the confirmation text message here
        # overwrite with organization specific message
        if message.receiver and message.receiver.mdn_confirm_text:
            confirmation_text = message.receiver.mdn_confirm_text

        # overwrite with partner specific message
        if message.sender and message.sender.mdn_confirm_text:
            confirmation_text = message.sender.mdn_confirm_text

        if status != "processed":
            confirmation_text = failed_text

        self.payload = MIMEMultipart("report", report_type="disposition-notification")

        # Create and attach the MDN Text Message
        mdn_text = email_message.Message()
        mdn_text.set_payload(f"{confirmation_text}\r\n")
        mdn_text.set_type("text/plain")
        del mdn_text["MIME-Version"]
        encoders.encode_7or8bit(mdn_text)
        self.payload.attach(mdn_text)

        # Create and attache the MDN Report Message
        mdn_base = email_message.Message()
        mdn_base.set_type("message/disposition-notification")
        mdn_report = "Reporting-UA: pyAS2 Open Source AS2 Software\r\n"
        mdn_report += f'Original-Recipient: rfc822; {message.headers.get("as2-to")}\r\n'
        mdn_report += f'Final-Recipient: rfc822; {message.headers.get("as2-to")}\r\n'
        mdn_report += f"Original-Message-ID: <{message.message_id}>\r\n"
        mdn_report += f"Disposition: automatic-action/MDN-sent-automatically; {status}"
        if detailed_status:
            mdn_report += f": {detailed_status}"
        mdn_report += "\r\n"
        if message.mic:
            mdn_report += f"Received-content-MIC: {message.mic.decode()}, {message.digest_alg}\r\n"
        mdn_base.set_payload(mdn_report)
        del mdn_base["MIME-Version"]
        encoders.encode_7or8bit(mdn_base)
        self.payload.attach(mdn_base)

        logger.debug(
            f"MDN report for message {message.message_id} created:\n{mime_to_bytes(mdn_base)}"
        )

        # Sign the MDN if it is requested by the sender
        if (
            message.headers.get("disposition-notification-options")
            and message.receiver
            and message.receiver.sign_key
        ):
            self.digest_alg = (
                message.headers["disposition-notification-options"]
                .split(";")[-1]
                .split(",")[-1]
                .strip()
                .replace("-", "")
            )
            signed_mdn = MIMEMultipart("signed", protocol="application/pkcs7-signature")
            del signed_mdn["MIME-Version"]
            signed_mdn.attach(self.payload)

            # Create the signature mime message
            signature = email_message.Message()
            signature.set_type("application/pkcs7-signature")
            signature.set_param("name", "smime.p7s")
            signature.set_param("smime-type", "signed-data")
            signature.add_header(
                "Content-Disposition", "attachment", filename="smime.p7s"
            )
            del signature["MIME-Version"]

            signed_data = sign_message(
                canonicalize(self.payload), self.digest_alg, message.receiver.sign_key
            )
            signature.set_payload(signed_data)
            encoders.encode_base64(signature)

            signed_mdn.set_param("micalg", self.digest_alg)
            signed_mdn.attach(signature)

            self.payload = signed_mdn
            logger.debug(f"Signing the MDN for message {message.message_id}")

        # Update the headers of the final payload and set message boundary
        for k, v in mdn_headers.items():
            if self.payload.get(k):
                self.payload.replace_header(k, v)
            else:
                self.payload.add_header(k, v)
        self.payload.set_boundary(make_mime_boundary())
        logger.debug(
            f"MDN generated for message {message.message_id} with "
            f"content:\n {mime_to_bytes(self.payload)}"
        )

    def parse(self, raw_content, find_message_cb):
        """Function parses the RAW AS2 MDN, verifies it and extracts the
        processing status of the orginal AS2 message.

        :param raw_content:
            A byte string of the received HTTP headers followed by the body.

        :param find_message_cb:
            A callback the must returns the original Message Object. The
            original message-id and original recipient AS2 ID are passed
            as arguments to it.

        :returns:
            A two element tuple containing (status, detailed_status). The
            status is a string indicating the status of the transaction. The
            optional detailed_status gives additional information about the
            processing status.
        """

        status, detailed_status = None, None
        try:
            self.payload = parse_mime(raw_content)
            self.orig_message_id, orig_recipient = self.detect_mdn()

            # Call the find message callback which should return a Message instance
            orig_message = find_message_cb(self.orig_message_id, orig_recipient)

            # Extract the headers and save it
            mdn_headers = {}
            for k, v in self.payload.items():
                k = k.lower()
                if k == "message-id":
                    self.message_id = v.lstrip("<").rstrip(">")
                mdn_headers[k] = v

            if (
                orig_message.receiver.mdn_digest_alg
                and self.payload.get_content_type() != "multipart/signed"
            ):
                status = "failed/Failure"
                detailed_status = "Expected signed MDN but unsigned MDN returned"
                return status, detailed_status

            if self.payload.get_content_type() == "multipart/signed":
                logger.debug(f"Verifying signed MDN: \n{mime_to_bytes(self.payload)}")
                message_boundary = ("--" + self.payload.get_boundary()).encode("utf-8")

                # Extract the signature and the signed payload
                signature = None
                signature_types = [
                    "application/pkcs7-signature",
                    "application/x-pkcs7-signature",
                ]
                for part in self.payload.walk():
                    if part.get_content_type() in signature_types:
                        signature = part.get_payload(decode=True)
                    elif part.get_content_type() == "multipart/report":
                        self.payload = part

                # Verify the message, first using raw message and if it fails
                # then convert to canonical form and try again
                mic_content = extract_first_part(raw_content, message_boundary)
                verify_cert = orig_message.receiver.load_verify_cert()
                try:
                    self.digest_alg = verify_message(
                        mic_content, signature, verify_cert
                    )
                except IntegrityError:
                    mic_content = canonicalize(self.payload)
                    self.digest_alg = verify_message(
                        mic_content, signature, verify_cert
                    )

            for part in self.payload.walk():
                if part.get_content_type() == "message/disposition-notification":
                    logger.debug(
                        f"MDN report for message {orig_message.message_id}:\n{part.as_string()}"
                    )

                    mdn = part.get_payload()[-1]
                    mdn_status = mdn["Disposition"].split(";").pop().strip().split(":")
                    status = mdn_status[0]
                    if status == "processed":
                        # Compare the original mic with the received mic
                        mdn_mic = mdn.get("Received-Content-MIC", "").split(",")[0]
                        if (
                            mdn_mic
                            and orig_message.mic
                            and mdn_mic != orig_message.mic.decode()
                        ):
                            status = "processed/warning"
                            detailed_status = "Message Integrity check failed."
                    else:
                        detailed_status = " ".join(mdn_status[1:]).strip()
        except MDNNotFound:
            status = "failed/Failure"
            detailed_status = "mdn-not-found"
        except Exception as e:
            status = "failed/Failure"
            detailed_status = f"Failed to parse received MDN. {e}"
            logger.error(f"Failed to parse AS2 MDN\n: {traceback.format_exc()}")

        finally:
            return status, detailed_status

    def detect_mdn(self):
        """ Function checks if the received raw message is an AS2 MDN or not.

        :raises MDNNotFound: If the received payload is not an MDN then this
        exception is raised.

        :return:
            A two element tuple containing (message_id, message_recipient). The
            message_id is the original AS2 message id and the message_recipient
            is the original AS2 message recipient.
        """
        mdn_message = None
        if self.payload.get_content_type() == "multipart/report":
            mdn_message = self.payload
        elif self.payload.get_content_type() == "multipart/signed":
            for part in self.payload.walk():
                if part.get_content_type() == "multipart/report":
                    mdn_message = self.payload

        if not mdn_message:
            raise MDNNotFound("No MDN found in the received message")

        message_id, message_recipient = None, None
        for part in mdn_message.walk():
            if part.get_content_type() == "message/disposition-notification":
                mdn = part.get_payload()[0]
                message_id = mdn.get("Original-Message-ID").strip("<>")
                message_recipient = mdn.get("Original-Recipient").split(";")[1].strip()
        return message_id, message_recipient
Example #48
0
# ======= START OF EMAIL SETUP CONTENT ====== #
if send_email in ['true', '1', 't', 'y', 'yes']:
    server = smtplib.SMTP('smtp.gmail.com:587')

msg = MIMEMultipart()
msg['Subject'] = 'MyProject Automation Status'

sender = '*****@*****.**'
recipients = ['*****@*****.**', '*****@*****.**']
ccrecipients = ['*****@*****.**', '*****@*****.**']

msg['From'] = sender
msg['To'] = ", ".join(recipients)
msg['Cc'] = ", ".join(ccrecipients)
password = "******"
msg.add_header('Content-Type', 'text/html')

# ======= END OF EMAIL SETUP CONTENT ====== #

head_content = """
<!doctype html>
<html lang="en">

<head>
    <link rel="shortcut icon" href="https://png.icons8.com/windows/50/000000/bot.png" type="image/x-icon" />
    <title>RF Metrics Report</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="viewport" content="width=device-width, initial-scale=1">

	<link href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css" rel="stylesheet"/>
Example #49
0
    def sendmessage(self, message, options={}):
        result = error = None

        profile = self.account.get('profile', {})
        from_email = from_ = profile['emails'][0]['value']
        fullname = profile.get('displayName', None)
        if fullname:
            from_email = '"%s" <%s>' % (Header(fullname, 'utf-8').encode(), Header(from_, 'utf-8').encode(),)

        url = "https://mail.google.com/mail/b/%s/smtp/" % from_
        to_ = options.get('to', None)
        if not to_ or not '@' in to_:
            return None, {
                "provider": self.host,
                "message": "recipient address is invalid",
                "status": 0
            }
        to_ = parseaddr(to_)
        if to_[0]:
            to_ = '"%s" <%s>' % (Header(to_[0], 'utf-8').encode(), Header(to_[1], 'utf-8').encode())
        else:
            to_ = Header(to_[1], 'utf-8').encode()

        server = SMTP(self.host, self.port)
        # in the app:main set debug = true to enable
        if asbool(config.get('debug', False)):
            server.set_debuglevel(True)

        subject = options.get('subject', config.get('share_subject', 'A web link has been shared with you'))
        title = options.get('title', options.get('link', options.get('shorturl', '')))
        description = options.get('description', '')[:280]

        msg = MIMEMultipart('alternative')
        msg.set_charset('utf-8')
        msg.add_header('Subject', Header(subject, 'utf-8').encode())
        msg.add_header('From', from_email)
        msg.add_header('To', to_)

        c.safeHTML = safeHTML
        c.options = options

        # insert the url if it is not already in the message
        c.longurl = options.get('link')
        c.shorturl = options.get('shorturl')


        # reset to unwrapped for html email, they will be escaped
        c.from_name = fullname
        c.subject = subject
        c.from_header = from_
        c.to_header = to_
        c.title = title
        c.description = description
        c.message = message

        c.thumbnail = (options.get('picture_base64', "") != "")

        if c.thumbnail:
            part2 = MIMEMultipart('related')

            html = MIMEText(render('/html_email.mako').encode('utf-8'), 'html')
            html.set_charset('utf-8')

            # FIXME: we decode the base64 data just so MIMEImage can re-encode it as base64
            image = MIMEImage(base64.b64decode(options.get('picture_base64')), 'png')
            image.add_header('Content-Id', '<thumbnail>')
            image.add_header('Content-Disposition', 'inline; filename=thumbnail.png')

            part2.attach(html)
            part2.attach(image)
        else:
            part2 = MIMEText(render('/html_email.mako').encode('utf-8'), 'html')
            part2.set_charset('utf-8')


        # get the title, or the long url or the short url or nothing
        # wrap these in literal for text email
        c.from_name = literal(fullname)
        c.subject = literal(subject)
        c.from_header = literal(from_)
        c.to_header = literal(to_)
        c.title = literal(title)
        c.description = literal(description)
        c.message = literal(message)

        part1 = MIMEText(render('/text_email.mako').encode('utf-8'), 'plain')
        part1.set_charset('utf-8')

        msg.attach(part1)
        msg.attach(part2)

        try:
            try:
                try:
                    server.starttls()
                except smtplib.SMTPException:
                    logger.info("smtp server does not support TLS")
                try:
                    server.ehlo_or_helo_if_needed()
                    server.authenticate(url, self.consumer, self.oauth_token)
                    server.sendmail(from_, to_, msg.as_string())
                except smtplib.SMTPRecipientsRefused, exc:
                    for to_, err in exc.recipients.items():
                        error = {"provider": self.host,
                                 "message": err[1],
                                 "status": err[0]
                                }
                        break
                except smtplib.SMTPException, exc:
                    error = {"provider": self.host,
                             "message": "%s: %s" % (exc.smtp_code, exc.smtp_error),
                             "status": exc.smtp_code
                            }
                except UnicodeEncodeError, exc:
                    raise
Example #50
0
class EmailFormatter(object):
    def __init__(self, msg_object):
        self.msg_obj = msg_object
        self.message = MIMEMultipart()
        self.message.set_charset("utf-8")

    def build_email(self):

        # Setting Message ID
        self.message.set_param("Message-ID", self.msg_obj.message_id)

        # Encoding for unicode subject
        self.message["Subject"] = Header(self.msg_obj.subject, charset="UTF-8")

        # Setting Date Time
        # Returns a date string as specified by RFC 2822, e.g.: Fri, 09 Nov 2001 01:08:47 -0000
        self.message["Date"] = str(self.msg_obj.sent_date)

        # At least one recipient is required
        # Required fromAddress
        from_address = flatten_list(self.msg_obj.sender)
        if from_address:
            self.message["From"] = from_address

        to_address = flatten_list(self.msg_obj.header_dict.get("To"))
        if to_address:
            self.message["To"] = to_address

        cc_address = flatten_list(self.msg_obj.header_dict.get("CC"))
        if cc_address:
            self.message["CC"] = cc_address

        bcc_address = flatten_list(self.msg_obj.header_dict.get("BCC"))
        if bcc_address:
            self.message["BCC"] = bcc_address

        # Add reply-to
        reply_to = flatten_list(self.msg_obj.reply_to)
        if reply_to:
            self.message.add_header("reply-to", reply_to)
        else:
            self.message.add_header("reply-to", from_address)

        # Required Email body content
        body_content = self.msg_obj.body
        if body_content:
            if "<html>" in body_content:
                body_type = "html"
            else:
                body_type = "plain"

            body = MIMEText(_text=body_content,
                            _subtype=body_type,
                            _charset="UTF-8")
            self.message.attach(body)
        else:
            raise KeyError("Missing email body")

        # Add message preamble
        self.message.preamble = "You will not see this in a MIME-aware mail reader.\n"

        # Optional attachments
        attachments = self.msg_obj.attachments
        if len(attachments) > 0:
            # Some issues here, where data is None or is bytes-like object.
            self._process_attachments(self.msg_obj.attachments)

        # composed email
        composed = self.message.as_string()

        return composed

    def save_file(self, file_path, file_name=None):

        eml_content = self.build_email()

        file_name = file_name if file_name is not None else str(
            self.message["Subject"]) + ".eml"

        eml_file_path = os.path.join(file_path, file_name)

        with codecs.open(eml_file_path, mode="wb+",
                         encoding="utf-8") as eml_file:
            eml_file.write(eml_content)

        return eml_file_path

    def _process_attachments(self, attachments):
        for attachment in attachments:
            ctype = attachment.AttachMimeTag
            data = attachment.data
            filename = attachment.Filename
            maintype, subtype = ctype.split("/", 1)

            if data is None:
                continue

            if maintype == "text" or "message" in maintype:
                if isinstance(data, bytes):
                    data = data.decode("utf-8", "ignore")
                attach = MIMEText(data, _subtype=subtype)
            elif maintype == "image":
                attach = MIMEImage(data, _subtype=subtype)
            elif maintype == "audio":
                attach = MIMEAudio(data, _subtype=subtype)
            else:
                attach = MIMEBase(maintype, subtype)
                attach.set_payload(data)

                # Encode the payload using Base64
                encoders.encode_base64(attach)
            # Set the filename parameter
            base_filename = os.path.basename(filename)
            attach.add_header("Content-ID", "<{}>".format(base_filename))
            attach.add_header("Content-Disposition",
                              "attachment",
                              filename=base_filename)
            self.message.attach(attach)
Example #51
0
from smtplib import SMTP_SSL, SMTP_SSL_PORT
from email.mime.multipart import MIMEMultipart, MIMEBase
from email.mime.text import MIMEText
from email.encoders import encode_base64

from_email = 'John Leon <*****@*****.**>'  # or simply the email address
to_emails = ['*****@*****.**', '*****@*****.**']

# Create multipart MIME email
email_message = MIMEMultipart()
email_message.add_header('To', ', '.join(to_emails))
email_message.add_header('From', from_email)
email_message.add_header('Subject', 'Hello!')
email_message.add_header('X-Priority', '2')  # Urgent/High priority

# Create text and HTML bodies for email
text_part = MIMEText('Hello world plain text!', 'plain')
html_part = MIMEText('<html><body><h1>HTML!</h1></body></html>', 'html')

# Create file attachment
attachment = MIMEBase("application", "octet-stream")
attachment.set_payload(b'\xDE\xAD\xBE\xEF')  # Raw attachment data
encode_base64(attachment)
attachment.add_header("Content-Disposition", "attachment; filename=myfile.dat")

# Attach all the parts to the Multipart MIME email
email_message.attach(text_part)
email_message.attach(html_part)
email_message.attach(attachment)

# Connect, authenticate, and send mail
Example #52
0
def handle(
    alert,
    type='smtp',
    sender_email=None,
    recipient_email=None,
    text=None,
    html=None,
    subject=None,
    reply_to=None,
    cc=None,
    bcc=None,
):

    if not os.environ.get('SMTP_SERVER'):
        log.info("No SMTP_SERVER in env, skipping handler.")
        return None

    smtp_server = os.environ['SMTP_SERVER']

    if 'SMTP_PORT' in os.environ:
        smtp_port = os.environ['SMTP_PORT']
    else:
        smtp_port = 587

    if 'SMTP_USE_SSL' in os.environ:
        smtp_use_ssl = os.environ['SMTP_USE_SSL']
    else:
        smtp_use_ssl = True

    if 'SMTP_USE_TLS' in os.environ:
        smtp_use_tls = os.environ['SMTP_USE_TLS']
    else:
        smtp_use_tls = True

    smtp_user = vault.decrypt_if_encrypted(os.environ['SMTP_USER'])
    smtp_password = vault.decrypt_if_encrypted(os.environ['SMTP_PASSWORD'])

    if recipient_email is None:
        log.error(f"Cannot identify recipient email")
        return None

    if text is None:
        log.error(f"SES Message is empty")
        return None

    # Create the base MIME message.
    if html is None:
        message = MIMEMultipart()
    else:
        message = MIMEMultipart('alternative')

    # Add HTML/plain-text parts to MIMEMultipart message
    # The email client will try to render the last part first

    # Turn these into plain/html MIMEText objects
    textPart = MIMEText(text, 'plain')
    message.attach(textPart)

    if html is not None:
        htmlPart = MIMEText(html, 'html')
        message.attach(htmlPart)

    message['Subject'] = subject
    message['From'] = sender_email
    message['To'] = recipient_email

    recipients = recipient_email.split(',')

    if cc is not None:
        message['Cc'] = cc
        recipients = recipients + cc.split(',')

    if bcc is not None:
        recipients = recipients + bcc.split(',')

    if reply_to is not None:
        message.add_header('reply-to', reply_to)

    if smtp_use_ssl is True:
        context = ssl.create_default_context()
        if smtp_use_tls is True:
            smtpserver = smtplib.SMTP(smtp_server, smtp_port)
            smtpserver.starttls(context=context)
        else:
            smtpserver = smtplib.SMTP_SSL(smtp_server,
                                          smtp_port,
                                          context=context)
    else:
        smtpserver = smtplib.SMTP(smtp_server, smtp_port)

    smtpserver.login(smtp_user, smtp_password)
    smtpserver.sendmail(sender_email, recipients, message.as_string())
    smtpserver.close()
Example #53
0
def send_simple_mail(sender, receiver, subject, msgtxt, attachments=None, usergenerated=False, cc=None, replyto=None, sendername=None, receivername=None, messageid=None, suppress_auto_replies=True, is_auto_reply=False, htmlbody=None, headers={}, staggertype=None, stagger=None):
    # attachment format, each is a tuple of (name, mimetype,contents)
    # content should be *binary* and not base64 encoded, since we need to
    # use the base64 routines from the email library to get a properly
    # formatted output message
    msg = MIMEMultipart()
    msg['Subject'] = subject
    msg['To'] = _encoded_email_header(receivername, receiver)
    msg['From'] = _encoded_email_header(sendername, sender)
    if cc:
        msg['Cc'] = cc
    if replyto:
        msg['Reply-To'] = replyto
    msg['Date'] = formatdate(localtime=True)
    if messageid:
        msg['Message-ID'] = messageid
    else:
        msg['Message-ID'] = make_msgid()
    if suppress_auto_replies:
        # Do our best to set some headers to indicate that auto-replies like out of office
        # messages should not be sent to this email.
        msg['X-Auto-Response-Suppress'] = 'All'

    # Is this email auto-generated or auto-replied?
    if is_auto_reply:
        msg['Auto-Submitted'] = 'auto-replied'
    elif not usergenerated:
        msg['Auto-Submitted'] = 'auto-generated'

    for h, v in headers.items():
        if h in msg:
            # Replace the existing header -- the one specified is supposedly overriding it
            msg.replace_header(h, v)
        else:
            msg.add_header(h, v)

    if htmlbody:
        mpart = MIMEMultipart("alternative")
        mpart.attach(MIMEText(msgtxt, _charset=_utf8_charset))
        mpart.attach(MIMEText(htmlbody, 'html', _charset=_utf8_charset))
        msg.attach(mpart)
    else:
        # Just a plaintext body, so append it directly
        msg.attach(MIMEText(msgtxt, _charset='utf-8'))

    if attachments:
        for a in attachments:
            main, sub = a['contenttype'].split('/')
            part = MIMENonMultipart(main, sub)
            part.set_payload(a['content'])
            part.add_header('Content-Disposition', a.get('disposition', 'attachment; filename="%s"' % a['filename']))
            if 'id' in a:
                part.add_header('Content-ID', a['id'])

            encoders.encode_base64(part)
            msg.attach(part)

    with transaction.atomic():
        if staggertype and stagger:
            # Don't send a second one too close after another one of this class.
            ls, created = LastSent.objects.get_or_create(type=staggertype, defaults={'lastsent': datetime.now()})

            sendat = ls.lastsent = ls.lastsent + stagger
            ls.save(update_fields=['lastsent'])
        else:
            sendat = datetime.now()

        # Just write it to the queue, so it will be transactionally rolled back
        QueuedMail(sender=sender, receiver=receiver, fullmsg=msg.as_string(), usergenerated=usergenerated, sendat=sendat).save()
        if cc:
            # Write a second copy for the cc, wihch will be delivered
            # directly to the recipient. (The sender doesn't parse the
            # message content to extract cc fields).
            QueuedMail(sender=sender, receiver=cc, fullmsg=msg.as_string(), usergenerated=usergenerated, sendat=sendat).save()
Example #54
0
    def get_mail_text(self, fields, request, context):
        """Get header and body of e-mail as text (string)
        """
        headerinfo = self.get_header_info(fields, request, context)
        body = self.get_mail_body(fields, request, context)
        if six.PY2 and isinstance(body, six.text_type):
            body = body.encode("utf-8")
        email_charset = "utf-8"
        # always use text/plain for encrypted bodies
        subtype = (
            getattr(self, "gpg_keyid", False) and "plain" or self.body_type or "html"
        )
        mime_text = MIMEText(
            safe_unicode(body).encode(email_charset, "replace"),
            _subtype=subtype,
            _charset=email_charset,
        )

        attachments = self.get_attachments(fields, request)

        if attachments:
            outer = MIMEMultipart()
            outer.attach(mime_text)
        else:
            outer = mime_text

        # write header
        for key, value in headerinfo.items():
            outer[key] = value

        # write additional header
        additional_headers = self.additional_headers or []
        for a in additional_headers:
            key, value = a.split(":", 1)
            outer.add_header(key, value.strip())

        for attachment in attachments:
            filename = attachment[0]
            ctype = attachment[1]
            # encoding = attachment[2]
            content = attachment[3]
            if ctype is None:
                ctype = "application/octet-stream"

            maintype, subtype = ctype.split("/", 1)

            if maintype == "text":
                if not six.PY2 and isinstance(content, six.binary_type):
                    content = content.decode("utf-8")
                msg = MIMEText(content, _subtype=subtype)
            elif maintype == "image":
                msg = MIMEImage(content, _subtype=subtype)
            elif maintype == "audio":
                msg = MIMEAudio(content, _subtype=subtype)
            else:
                msg = MIMEBase(maintype, subtype)
                msg.set_payload(content)
                # Encode the payload using Base64
                encoders.encode_base64(msg)

            # Set the filename parameter
            if six.PY2 and isinstance(filename, six.text_type):
                filename = filename.encode("utf-8")
            msg.add_header(
                "Content-Disposition", "attachment", filename=("utf-8", "", filename)
            )
            outer.attach(msg)

        return outer.as_string()
Example #55
0
class Email:

	"""
	Costumized email class based on python's 'email' libary.
	Initiated instances of this class will allow to send e-mails from John's 
	gmail account. The accound username and password are stored in a separate file
	that is not synchronised ...

	TO DO:
		- write method that can detach already attached mail attachments.
	"""

	def __init__(self, sender, recipients, cc=[], bcc=[], replyto=[], subject='', text='', attachments=[], connection='ssl'):

		"""
		Prepares mail container and puts in header, text and attachments, however,
		it does not send mail yet (see 'send()' method).
		"""

		self.sender          = sender
		self.recipients      = recipients
		self.cc              = cc
		self.bcc             = bcc
		self.replyto         = replyto
		self.subject         = subject
		self.text            = text
		self.attachments     = attachments
		self.connection      = connection
		self.is_sent         = False

		# mail container
		self.__msgBasis      = MIMEMultipart('mixed')
		
		# mail header
		self._prepare_headerMail()
		
		# mail attachments
		self._attachmentsMail( self.attachments )


	def send(self):

		username, password                 = secrets_personal.gmail_auth()
		server                             = self._connectSMPT(self.connection, username, password)
		#server.verify(sender)
		server.sendmail(self.sender, self.recipients + self.cc + self.bcc, self.__msgBasis.as_string())
		server.quit()
		self.is_sent                       = True


	def attach(self, file):
		
		self._attachmentsMail( file, single_add=True )


	def detach(self, file):
		# to bon programmed ..
		pass


	def show(self):

		pprint.pprint(self.__dict__)


	def _validMail(self, mail):

			"""
			Check if passed variable 'mail' is string. If not, make it string.
			Then, check if 'mail' matches e-mail pattern, if yes, return mail with
			preceding and succeeding white blancs stripped.
			If pattern isn't matched, return False (without doing lstrip() / rstrip())
			
			:return: mail / False 
			"""

			if not isinstance(mail, str) or not re.search(r"\w.@\w+\.\w+", mail):
				sys.exit(u'ERROR:    Given SENDER adress is no valid e-mail string. Exit.')
			return mail.lstrip().rstrip()


	def _valid_listMail(self, list_adresses):

			"""
			Check if passed list is a list, if yes, check if entries are valid mail
			adresses. Strips preceding and succeeding white blancs. Return a list only 
			with valid adresses, if there is no valid adress at all, return empty list.
			
			:return list_adress
			"""

			adresses = []
			if isinstance(list_adresses, list):
				pass
			elif isinstance(list_adresses, tuple):
				list_adresses = list(list_adresses)
			elif isinstance(list_adresses, str):
				list_adresses = [list_adresses]
			else:
				sys.exit(u'ERROR:    Given ADDRESSES are no valid list or tuple format. Exit.')

			for adress in list_adresses:
				if self._validMail(adress):
					adresses.append(adress)

			return adresses


	def _prepare_headerMail(self):

		"""
		Fill header informatione. 
		
		"""

		# preamble
		self.__msgBasis.preamble  = "PREAMBLE:   How to learn sending e-mails with Python's SMTP!"

		# date
		self.__msgBasis['Date']   = formatdate(localtime=True)		# dt.datetime.now().strftime('%Y-%m-%d, %H:%M Uhr')
		#print(msgBasis['Date'])
		
		# sender
		self.__msgBasis['From']   = self._validMail(self.sender)

		# recipients
		self.recipients           = self._valid_listMail(self.recipients)
		self.__msgBasis['To']     = ', '.join(self.recipients)
		
		# carbon copies
		self.cc                   = self._valid_listMail(self.cc)
		self.__msgBasis['Cc']     = ', '.join(self.cc)
		
		# blind carbon copies
		self.bcc                  = self._valid_listMail(self.bcc)
		self.__msgBasis['Bcc']    = ', '.join(self.bcc)
		
		# reply-to
		self.replyto              = self._valid_listMail(self.replyto)		
		self.__msgBasis.add_header('reply-to', ', '.join(self.replyto))

		# subject
		try:
			self.__msgBasis['Subject'] = str(self.subject)
		except:
			self.__msgBasis['Subject'] = ''


	def _attachmentsMail(self, attachments, single_add=False):

		"""
		Attach files past as list 'attachments' to e-mail message 'msgBasis' instance.
		If given attachment cannot be found, it is not attached.
		"""


		if isinstance(attachments, (numpy.ndarray, numpy.generic)):
			pass
		elif isinstance(attachments, list):
			attachments = numpy.array( attachments )
		elif isinstance(attachments, tuple):
			attachments = numpy.array( list(attachments) )
		elif isinstance(attachments, str):
			attachments = numpy.array( [attachments] )
		else:
			sys.exit(u'ERROR:    Given ATTACHMENTS are no valid list or tuple format of strings. Exit.')


		### attach files, if can not be found, state warning and delete from attachment list
		del_ind = []
		for i in range(len(attachments)):

			if attachments[i] in self.attachments:
				continue

			part = MIMEBase('application', "octet-stream")
			try: 
				part.set_payload(open(attachments[i], "rb").read())
				encoders.encode_base64(part)
				part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(attachments[i]))
				self.__msgBasis.attach(part)
			except Exception:
				del_ind.append(i)
				print(u"WARNING:    Attachment '%s' not found and thus not attached." % attachments[i])
				continue

		# delete faulty attachments from list
		clean_attachments     = list( numpy.delete(attachments,del_ind) )
		if single_add == True:
			self.attachments += clean_attachments
		elif single_add == False:
			self.attachments  = clean_attachments


	def _connectSMPT(self, client, username, password):

		"""
		Connect to SMTP mail server.
		
		:return: smtplib server
		"""

		try:
			if client.lower() == 'tls':
				try:
					server = smtplib.SMTP('smtp.gmail.com', 587)
					server.ehlo()
					#server.esmtp_features['starttls']
					server.starttls()
					server.ehlo()
					server.login(username,password)
					return server
				except Exception as err:
					print(u"WARNING:     Couldn't establish '%s' connection to server. Proceed with 'ssh', port '465'. Error message:\n%s" % (client, err))  
					server.quit()
					client = 'ssl'

			if client.lower() == 'ssl':
				server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
				server.ehlo()
				server.login(username,password)
				return server
			
			if client.lower() == 'localhost':
				command = 'python3 -m smtpd -n localhost:25'
				server  = smtplib.SMTP('localhost', 25)
				server.set_debuglevel(1)
				return server

			sys.exit(u"ERROR:    You want to connect to a SMTP server which is not known of the time being (choose 'localhost' or 'gmail'). Exit.")

		except smtplib.SMTPHeloError as err:
			sys.exit(u"ERROR:    Sever didn't reply properly to HELO GREETING! Exit.")

		except smtplib.SMTPAuthenticationError as err:
			sys.exit(u"ERROR:    Username and/or password not accepted to connect to SMTP server! Exit.")

		except smtplib.socket.error as err:
			if client.lower() == 'localhost':
				print(u'Did you started a local SMTP server? If not, try:%s' % command)
			sys.exit(u"ERROR:    Couldn't connect to '%s' server. Error message:\n%s." % (client, err))

		except smtplib.SMTPServerDisconnected as err: 
			sys.exit(u'ERROR:    Just try again! Error message:\n%s.' % err)

		except Exception as err:
			sys.exit(u'ERROR:    Error message:\n%s' % err)
Example #56
0
    body = MIMEMultipart('alternative')
    body.attach(MIMEText(msgtext))
    body.attach(MIMEText(htmlmsgtext, 'html'))
    msg.attach(body)

    if 'attachmentname' in globals():
        f = attachmentname
        part = MIMEBase('application', "octet-stream")
        part.set_payload(open(f, "rb").read())
        Encoders.encode_base64(part)
        part.add_header('Content-Disposition',
                        'attachment; filename="%s"' % os.path.basename(f))
        msg.attach(part)

    msg.add_header('From', fromaddr)
    msg.add_header('To', toaddr)
    msg.add_header('Subject', msgsubject)
    msg.add_header('Reply-To', replyto)

    # The actual email sendy bits
    server = smtplib.SMTP('smtp.gmail.com:587')
    server.set_debuglevel(
        True
    )  #commenting this out, changing to False will make the script give NO output at all upon successful completion
    server.starttls()
    server.login(username, password)
    server.sendmail(msg['From'], [msg['To']], msg.as_string())
    server.quit()

except:
    def send_alert_mail(self, sender_parm, receivers_parm, mail_subject, lock_dlist):
        print_hdr = "[" + self.class_name + ": send_alert_mail] - "
        sender          = sender_parm
        receivers       = receivers_parm.split(',')     # sendmail method expects receiver parameter as list

        print (print_hdr + 'lock_dlist count: ' + str(len(lock_dlist)))
        message = MIMEMultipart("alternative")
        message['Subject'] = mail_subject
        message['From'] = sender_parm
        message['To'] = receivers_parm   # This attribute expects string and not list
        message.add_header('Content-Type', 'text/html')

        html_msg = """\
    
    <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      <title>Hive Lock Alert</title>
      <style type="text/css" media="screen">
        table{
            background-color: #AAD373;
            empty-cells:hide;
        }
        th{
            border: black 1px solid;
        }    
        td{
            background-color: white;
            border: black 1px solid;
        }
      </style>
    </head>
    <body>
        <table style="border: black 1px solid;">
            <tr>
                <th>Table Name</th>
                <th>Lock Type</th>
                <th>Lock User</th>
                <th>Lock Datetime</th>
                <th>Current Lock Duration</th>
                <th>Lock Mode</th>
                <th>Lock Query Id</th>
                <th>Lock Query</th>
                <th>Waiting Job</th>
                <th>Waiting Job Start Datetime</th>
            </tr> """

        for lock_dict in lock_dlist:
            html_msg = html_msg + """\
            <tr>
                <td>""" + lock_dict['table_name'] + """</td>
                <td>""" + lock_dict['lock_type'] + """</td>
                <td>""" + lock_dict['lock_query_user'] + """</td>
                <td>""" + lock_dict['lock_datetime'] + """</td>
                <td>""" + lock_dict['current_lock_duration'] + """ mins</td>
                <td>""" + lock_dict['lock_mode'] + """</td>
                <td>""" + lock_dict['lock_query_id'] + """</td>
                <td>""" + lock_dict['lock_query_string'] + """</td>
                <td>""" + lock_dict['waiting_job'] + """</td>
                <td>""" + lock_dict['waiting_job_start_time'] + """</td>
            </tr>"""

        html_msg = html_msg + """\
        </table>
    </body>"""

        # print html_msg
        try:
            message.attach(MIMEText(html_msg, 'html'))
            smtpObj = smtplib.SMTP('localhost')
            smtpObj.sendmail(sender, receivers, message.as_string())
            print (logdt.now().strftime('[%Y-%m-%d %H:%M:%S] ') + print_hdr + "Successfully sent email")
        except SMTPException:
            print (logdt.now().strftime('[%Y-%m-%d %H:%M:%S] ') + print_hdr + "Error: unable to send email")
        except Exception as e:
            print (logdt.now().strftime('[%Y-%m-%d %H:%M:%S] ') + print_hdr + "ERROR details: " + traceback.format_exc())
        finally:
            try:
                del message
                smtpObj.quit()
            except Exception as e:
                print (logdt.now().strftime('[%Y-%m-%d %H:%M:%S] ') + print_hdr + "ERROR details: " + traceback.format_exc())
Example #58
0
  def SendEmail(self,
                to_addresses,
                from_address,
                subject,
                message,
                attachments=None,
                is_html=True,
                cc_addresses=None,
                message_id=None,
                headers=None):
    """This method sends an email notification.

    Args:
      to_addresses: [email protected] string, list of addresses as csv string,
                    or rdf_standard.DomainEmailAddress
      from_address: [email protected] string
      subject: email subject string
      message: message contents string, as HTML or plain text
      attachments: iterable of filename string and file data tuples,
                   e.g. {"/file/name/string": filedata}
      is_html: true if message is in HTML format
      cc_addresses: [email protected] string, or list of addresses as
                    csv string
      message_id: smtp message_id. Used to enable conversation threading
      headers: dict of str-> str, headers to set
    Raises:
      RuntimeError: for problems connecting to smtp server.
    """
    headers = headers or {}
    msg = MIMEMultipart("alternative")
    if is_html:
      text = self.RemoveHtmlTags(message)
      part1 = MIMEText(text, "plain")
      msg.attach(part1)
      part2 = MIMEText(message, "html")
      msg.attach(part2)
    else:
      part1 = MIMEText(message, "plain")
      msg.attach(part1)

    if attachments:
      for file_name, file_data in iteritems(attachments):
        part = MIMEBase("application", "octet-stream")
        part.set_payload(file_data)
        encoders.encode_base64(part)
        part.add_header("Content-Disposition",
                        "attachment; filename=\"%s\"" % file_name)
        msg.attach(part)

    msg["Subject"] = subject

    from_address = self.AddEmailDomain(from_address)
    to_addresses = self.SplitEmailsAndAppendEmailDomain(to_addresses)
    cc_addresses = self.SplitEmailsAndAppendEmailDomain(cc_addresses or "")

    msg["From"] = from_address
    msg["To"] = ",".join(to_addresses)
    if cc_addresses:
      msg["CC"] = ",".join(cc_addresses)

    if message_id:
      msg.add_header("Message-ID", message_id)

    for header, value in iteritems(headers):
      msg.add_header(header, value)

    try:
      s = smtplib.SMTP(config.CONFIG["Worker.smtp_server"],
                       int(config.CONFIG["Worker.smtp_port"]))
      s.ehlo()
      if config.CONFIG["Worker.smtp_starttls"]:
        s.starttls()
        s.ehlo()
      if (config.CONFIG["Worker.smtp_user"] and
          config.CONFIG["Worker.smtp_password"]):
        s.login(config.CONFIG["Worker.smtp_user"],
                config.CONFIG["Worker.smtp_password"])

      s.sendmail(from_address, to_addresses + cc_addresses, msg.as_string())
      s.quit()
    except (socket.error, smtplib.SMTPException) as e:
      raise RuntimeError("Could not connect to SMTP server to send email. "
                         "Please check config option Worker.smtp_server. "
                         "Currently set to %s. Error: %s" %
                         (config.CONFIG["Worker.smtp_server"], e))
Example #59
0
style0 = xlwt.easyxf('font: bold on')

ws.write(0, 0, "KMS LOGS(FQDN)", style0)
ws.write(0, 1, "AUTHORIZATION REQUESTS", style0)

for ind in range(0, len(res)):
    ws.write(ind + 1, 0, res[ind])
for ind in range(0, len(addresses)):
    ws.write(ind + 1, 1, addresses[ind])

wb.save('report.xls')

f = open('report.xls', 'rb')
att = MIMEBase("application", "vnd.ms-excel")
att.set_payload(f.read())
encoders.encode_base64(att)

me = "KMS Server"
you = ["example.com"]

msg = MIMEMultipart()
msg['Subject'] = "KMS Logs"
msg['To'] = "*****@*****.**"
msg.add_header('Content-Disposition', 'attachment; filename="report.xls"')
msg.attach(att)

s = smtplib.SMTP('localhost')
s.sendmail(me, you, msg.as_string())
s.quit()
Example #60
0
def send_notify_email(body, start_time, title, attendees, event_uid, patching_duartion_in_min):
    """Function for send Outlook-notifications and save notification to disk"""
    subject = 'Linux Monthly Patching {month} | RFC {rfc_number} | {project}'.format(
        month=datetime.datetime.now().strftime("%B %Y"), rfc_number=rfc_number, project=title)
    start_time_utc=return_utc(start_time)
    
    # create calendar
    cal = icalendar.Calendar()
    cal.add('prodid', '-//My calendar application//example.com//')
    cal.add('version', '2.0')
    cal.add('method', 'REQUEST')
    
    # create event
    event = icalendar.Event()
    event.add('summary', subject)
    event.add('dtstart', datetime.datetime.strptime(start_time_utc, "%d-%m-%Y %H:%M"))
    event.add('dtend', datetime.datetime.strptime(start_time_utc, "%d-%m-%Y %H:%M")+datetime.timedelta(minutes=patching_duartion_in_min))
    event.add('dtstamp', datetime.datetime.now().utcnow())
    event['uid'] = event_uid
    event.add('TZOFFSETFROM', datetime.timedelta(hours=3))
    event.add('TZOFFSETTO', datetime.timedelta(hours=3))
    event.add('TZID', 'Russian Standard Time')
    event.add('priority', 5)
    event.add('organizer', settings['organizer'])
    event.add('status', "confirmed")
    event.add('category', "Event")
    event.add('sequence', 1)
    event.add('X-MICROSOFT-DISALLOW-COUNTER', "TRUE")
    event.add('X-MICROSOFT-CDO-BUSYSTATUS', 'FREE')
    for current_attendee in attendees.split(","):
        event.add('attendee', current_attendee)
        
    # create alarm
    alarm = icalendar.Alarm()
    alarm.add("action", "DISPLAY")
    alarm.add('description', "Reminder")
    alarm.add("TRIGGER;RELATED=START", "-PT15M")
    alarm.add('X-MICROSOFT-CDO-BUSYSTATUS', 'FREE')
    event.add_component(alarm)
    cal.add_component(event)

    filename = "invite.ics"
    msg = MIMEMultipart("mixed")
    msg["Subject"] = subject
    msg["From"] = settings['e_mail_from']
    msg["To"] = attendees

    msg_for_cancel = copy.deepcopy(msg)
    cursor_hashes_db.execute('INSERT INTO "HASHES" (HASH,EMAILS) VALUES (?,?)', (str(event_uid), attendees))
    connect_hashes_db.commit()
    msg_a = MIMEMultipart('alternative')
    msg.attach(msg_a)
    part_calendar = MIMEMultipart('text', "calendar", method="REQUEST", name=filename)
    part_calendar.set_type('text/calendar; charset=UTF-8; method=REQUEST; component = VEVENT')
    part_calendar.add_header('Content-Type', 'text/calendar')
    part_calendar.add_header('charset', 'UTF-8')
    part_calendar.add_header('component', 'VEVENT')
    part_calendar.add_header('method', 'REQUEST')
    part_calendar.add_header('Content-Description', filename)
    part_calendar.add_header('Content-ID', 'calendar_message')
    part_calendar.add_header("Content-class", "urn:content-classes:appointment")
    part_calendar.add_header("Filename", filename)
    part_calendar.add_header("Path", filename)

    part_calendar_before_encode=copy.deepcopy(part_calendar)
    part_calendar.set_payload(cal.to_ical())

    encode_base64(part_calendar)
    msg_a.attach(MIMEText(body, 'html'))
    msg_a.attach(part_calendar)
    recept_list=attendees.split(",")

    try:
        s = smtplib.SMTP(settings['smtp_server'])
        s.sendmail(msg["From"], recept_list, msg.as_string())
        s.quit()
        print("e-mail with '{title}' title has been sent successfully!".format(title=title))
    except Exception as e:
        termcolor.cprint("Error during sending an-email, second try...", color="white", on_color="on_red")
        try:
            s = smtplib.SMTP(settings['smtp_server'])
            print(recept_list)
            s.sendmail(msg["From"], recept_list, msg.as_string())
            s.quit()
            print("e-mail with '{title}' title has been sent successfully!".format(title=title))
        except Exception as e:
            termcolor.cprint("Can not send outlook-notofocation for this {prj} project to {start_date}".format(start_date=start_time, prj=title), color="white", on_color="on_red")
            print("Exception: {e}".format(e=str(e)))

    cal.update({'method' : 'CANCEL'})
    event.update({'summary' : "[CANCELLED] " + subject})
    event.update({'status': "cancelled"})
    
    msg_for_cancel.replace_header('Subject', "[CANCELLED] "  + subject)
    msg_a_for_cancel = MIMEMultipart('alternative')
    msg_for_cancel.attach(msg_a_for_cancel)
    msg_a_for_cancel.attach(MIMEText(body.replace("please, perform this patching", "<font size=12 color='red'>DO NOT DO IT</font>"), 'html'))
    
    part_calendar_before_encode.replace_header('Content-Type', 'text/calendar; charset="UTF-8"; method="CANCEL"; component = "VEVENT"; name="invite.ics"; boundary="calendar"')
    part_calendar_before_encode.replace_header('method', 'CANCEL')
    part_calendar_before_encode.set_payload(cal.to_ical())
    encode_base64(part_calendar_before_encode)
    msg_a_for_cancel.attach(part_calendar_before_encode)
    save_notification_to_disk=open("./archive/" + event_uid + ".msg", 'wb')
    save_notification_to_disk.write(msg_for_cancel.as_bytes())
    save_notification_to_disk.close()
    input("Enter any symbol to proceed...")