示例#1
0
文件: send_mail.py 项目: singit/Files
def send_mail(nick_name, receivers, subject, content):
    server = smtplib.SMTP(smtp_server, smtp_port)
    server.login(user, passwd)
    rec_list = [rec for rec in receivers.split(";") if rec.find("@") != -1]
    msg = Message()
    msg.add_header("from", formataddr((nick_name, sender)))
    for rec in rec_list:
        msg.add_header("to", rec)
    msg.add_header("subject", subject)
    msg.set_payload(content)
    logger.debug("mail:%s"%msg.as_string())
    server.sendmail(sender, rec_list, msg.as_string())
    server.close()
 def test_senders_becomes_reviewer(self):
     msg = Message()
     msg["From"] = "*****@*****.**"
     msg["Subject"] = "subject (issue%s)" % self.issue.key().id()
     msg.set_payload("body")
     views._process_incoming_mail(msg.as_string(), "*****@*****.**")
     issue = models.Issue.get_by_id(self.issue.key().id())  # re-fetch issue
     self.assertEqual(issue.reviewers, ["*****@*****.**"])
     issue.reviewers = []
     issue.put()
     # try again with sender that has an account
     # we do this to handle CamelCase emails correctly
     models.Account.get_account_for_user(User("*****@*****.**"))
     views._process_incoming_mail(msg.as_string(), "*****@*****.**")
     issue = models.Issue.get_by_id(self.issue.key().id())
     self.assertEqual(issue.reviewers, ["*****@*****.**"])
示例#3
0
 def test_empty_message(self):
   msg = Message()
   msg['From'] = '*****@*****.**'
   msg['Subject'] = 'subject (issue%s)\r\n\r\n' % self.issue.key.id()
   self.assertRaises(views.InvalidIncomingEmailError,
                     views._process_incoming_mail, msg.as_string(),
                     '*****@*****.**')
示例#4
0
 def sendEmail(self, subject=None, text=None):
     """Sends Email
     
     Keyword arguments:
     subject -- Email subject
     text -- Email body
     """
     
     SUBJECT = subject or 'Python Priority Test'
     TEXT = text or 'Sending this message with high priority because reasons.'
     
     msg = Message()
     msg['From'] = self.FROM
     # msg['To'] = self.emailRecipients
     msg['To'] = ", ".join(self.emailRecipients)
     msg['X-Priority'] = '1'
     msg['Subject'] = SUBJECT
     msg.set_payload(TEXT)
     
     #Prepare actual message
     message = '\r\n'.join(['To: %s' % self.emailRecipients, 'From: %s' % self.FROM, 'Subject: %s' % SUBJECT, '', TEXT])
     
     try:
         failures = self.server.sendmail(self.FROM, self.emailRecipients, msg.as_string())
         if failures:
             for x in failures:
                 self.writeToLog('Mail send error: ' + str(x))
         self.writeToLog('Sucessfully sent the mail')
     #except smtplib.SMTPDataError:
     #    print("Failed to send mail.  Possible permissions error.")
     except:
         print('Failed to send mail.\nUnexpected Error:', sys.exc_info()[0], '\n', sys.exc_info()[1])
         self.writeToLog('Failed to send mail.\nUnexpected Error:', sys.exc_info()[0], '\n', sys.exc_info()[1])
示例#5
0
文件: sendMail.py 项目: yfsuse/Traxex
def send_mail(subject, content):

    smtpserver = 'smtp.gmail.com'
    username = '******'
    password = '******'

    from_addr = '*****@*****.**'
    to_addr = '*****@*****.**'

    mailtime = email.utils.formatdate(time.time(), True)

    message = Message()
    message['Subject'] = subject
    message['From'] = from_addr
    message['To'] = to_addr

    mailcontent = "\nQuery Time: {0}\n\n{1}\n\n".format(mailtime, content)

    message.set_payload(mailcontent)
    msg = message.as_string()

    sm = smtplib.SMTP(smtpserver, port=587, timeout=20)
    sm.set_debuglevel(1)
    sm.ehlo()
    sm.starttls()
    sm.ehlo()
    sm.login(username, password)

    sm.sendmail(from_addr, to_addr, msg)
    sleep(5)
    sm.quit()
 def test_empty_message(self):
     msg = Message()
     msg["From"] = "*****@*****.**"
     msg["Subject"] = "subject (issue%s)\r\n\r\n" % self.issue.key().id()
     self.assertRaises(
         views.InvalidIncomingEmailError, views._process_incoming_mail, msg.as_string(), "*****@*****.**"
     )
示例#7
0
    def request(self, query, headers):
        # httplib would really help but there isn't any trivial way
        # that I know of to use your own socket with it.
        request = Message()
        for k,v in headers.iteritems():
            request[k] = v
        self.sock.send(query + "\r\n" + request.as_string())

        buffer = self.sock.recv(4096)
        try:
            [result, data] = buffer.split('\r\n', 1)
        except ValueError:
            traceback.print_exc()
            print >> sys.stderr, 'Buffer:', buffer
            print >> sys.stderr, 'Query:', query
            print >> sys.stderr, 'Headers:', headers
            return False
        result = result.split(' ')

        if int(result[1]) != 200:
            self.log.info('Request failed: %s', ' '.join(result))
            raise httplib.BadStatusLine(' '.join(result))

        response = FeedParser()
        response.feed(data)
        return response.close()
示例#8
0
    def mail(self, to, subject, tmplname, from_addr=None, from_name = None, **kw):
        """send a plain text email

        :param to: a simple string in RFC 822 format
        :param subject: The subject of the email
        :param tmplname: template name to be used
        :param **kw: parameters to be used in the template
        """

        # render template
        tmpl = self.templates.get_template(tmplname)
        payload = tmpl.render(kw)

        # now create the message
        msg = Message()
        msg.set_payload(payload.encode("utf8"))
        msg.set_charset(self.charset)
        msg['Subject'] = Header(subject, "utf8")
        if from_name is None:
            from_name = self.from_name
        if from_addr is None:
            fa = msg['From'] = "%s <%s>" %(from_name, self.from_addr)
        else:
            fa = msg['From'] = "%s <%s>" %(from_name, from_addr)
        msg['To'] = to

        server = self.server_factory()
        server.sendmail(fa, [to], msg.as_string())
        server.quit()
示例#9
0
文件: spamtest.py 项目: oelu/spamtest
def send_mail(sender,
              recipient,
              dstmta,
              subject,
              body,
              verbose):
    """
    Sends e-mail to specific server.
    """
    msg = Message()
    msg['From'] = sender
    msg['To'] = recipient
    msg['Subject'] = subject
    msg.set_payload(body)

    try:
        server = smtplib.SMTP(dstmta)
        if verbose:
            log.info("smtp debug level was set to 1")
            server.set_debuglevel(1)
        server.sendmail(sender, recipient, msg.as_string())
        print "Successfully sent email"
    # if no success code an
    except SMTPConnectError as smtpconnerr:
        log.error("unable to send mail")
        log.error(smtpconnerr)
示例#10
0
    def _attach_signed_parts(self, message, signed_part, signature):
        """
        Attach the signed_part and signature to the message (MIMEMultipart)
        and returns the new message as str
        """
        # According with RFC 3156 the signed_part in the message
        # must be equal to the signed one.
        # The best way to do this is "hard" attach the parts
        # using strings.

        if not isinstance(signature, (str, unicode)):
            signature = str(signature)

        # get the body of the MIMEMultipart message,
        # remove last lines which close the boundary
        msg_lines = message.as_string().split('\n')[:-3]

        # get the last opening boundary
        boundary = msg_lines.pop()

        # create the signature as attachment
        sigmsg = Message()
        sigmsg['Content-Type'] = 'application/pgp-signature; ' + \
                                 'name="signature.asc"'
        sigmsg['Content-Description'] = 'GooPG digital signature'
        sigmsg.set_payload(signature)

        # attach the signed_part
        msg_lines += [boundary, signed_part]
        # attach the signature
        msg_lines += [boundary,
                      sigmsg.as_string(),
                      '{}--'.format(boundary)]
        # return message a string
        return '\n'.join(msg_lines)
示例#11
0
 def do_email(self):
     """将最终结果以邮件形式发送"""
     print "准备发送邮件..."
     from_addr = self.conf.get("addr", "from")
     to_addr = self.conf.get("addr", "to")
     cc_addr = self.conf.get("addr", "cc")
     smtpserver = self.conf.get("mail", "smtpserver")
     username = self.conf.get("mail", "username")
     password = self.conf.get("mail", "password")
     to_and_cc_addr = self._str2list(to_addr) + self._str2list(cc_addr)
     if self.do_check_email_conf(smtpserver, username, password, from_addr, to_and_cc_addr) is not True:
         return
     subject = self.program_range + self.program_type + time.strftime("(发送时间:%Y年%m月%d日)", time.localtime())
     message = Message()
     message["Subject"] = subject
     message["From"] = from_addr
     message["To"] = to_addr
     message["Cc"] = cc_addr
     message.set_payload(self.file_content)
     smtp = smtplib.SMTP()
     smtp.connect(smtpserver)
     smtp.login(username, password)  
     smtp.sendmail(from_addr, to_and_cc_addr, message.as_string())
     smtp.quit()
     print "发送完毕,请到邮箱中查看抓取信息..."
示例#12
0
    def process(self, message: Message):
        """Displays desktop notification about specified message.

        :param message: E-Mail message object.
        """

        print("  - {}: {}.process()".format(self.name, self.__class__.__name__))

        notify2.init("Sendmail")

        title = self.title_template.format(
            subject=message.get("Subject"),
            from_email=message.get("From"),
            appname="Sendmail",
            name=self.name
        )
        text = self.text_template.format(
            subject=message.get("Subject"),
            from_email=message.get("From"),
            text=message.as_string(),
            appname="Sendmail",
            name=self.name
        )

        n = notify2.Notification(title,
            text,
            self.icon_name
        )

        n.show()
示例#13
0
 def test_senders_becomes_reviewer(self):
   msg = Message()
   msg['From'] ='*****@*****.**'
   msg['Subject'] = 'subject (issue%s)' % self.issue.key.id()
   msg.set_payload('body')
   views._process_incoming_mail(msg.as_string(), '*****@*****.**')
   issue = models.Issue.get_by_id(self.issue.key.id())  # re-fetch issue
   self.assertEqual(issue.reviewers, ['*****@*****.**'])
   issue.reviewers = []
   issue.put()
   # try again with sender that has an account
   # we do this to handle CamelCase emails correctly
   models.Account.get_account_for_user(User('*****@*****.**'))
   views._process_incoming_mail(msg.as_string(), '*****@*****.**')
   issue = models.Issue.get_by_id(self.issue.key.id())
   self.assertEqual(issue.reviewers, ['*****@*****.**'])
示例#14
0
文件: imapdb.py 项目: chr15m/dorcx
	def post(self, folder, subject="", body="", date=None, headers={}, metadata={}):
		folder_name = self.select_or_create_folder(folder)
		# create the post as a new email
		m = Message()
		m["From"] = self.email
		# m["To"] = "*****@*****.**"
		m["Content-Type"] = "text/plain"
		if subject:
			m["Subject"] = subject
		# Javascript should use d.toString() = "Sun Jun 09 2013 16:21:47 GMT+0800 (WST)"
		msg_time = (date and dateutil.parser.parse(date) or None)
		if msg_time:
			# Date - 
			# djb nails it:
			# http://cr.yp.to/immhf/date.html
			# Date: 23 Dec 1995 19:25:43 -0000
			m["Date"] = msg_time.strftime("%a, %d %b %Y %X %z")
		# set any other headers
		for h in headers:
			m[h] = headers[h]
		for md in metadata:
			m[json_marker + md] = json.dumps(metadata[md])
		# set the content of the message
		if body:
			m.set_payload(body)
		response = self.append(folder_name, m.as_string(), msg_time=msg_time)
		#print response
		# u'[APPENDUID 594556012 1] (Success)'
		# u'[APPENDUID 1370766584 11] Append completed.'
		result = {"message": None, "codes": []}
		if append_response_re.match(response):
			result = append_response_re.match(response).groupdict()
			result["codes"] = result["codes"].split(" ")
			result["UID"] = int(result["codes"][:].pop())
		return result, m
示例#15
0
def main(config):
    """main routine"""
    # Define the emails and couples
    # Only one sub-tuple level is supported
    emails = config['EMAILS']
    couples = config['COUPLES']
    sender = config['SENDER']
    content = config['CONTENT']

    # Find a random possible case
    persons = get_persons(couples)
    random_case = lets_do_santa_claus_job(couples)

    # Send mails
    message = Message()
    message.add_header('from', sender)
    message.add_header('subject','[Confidentiel] Message du Père-Noël')
    message.add_header('to', sender)

    server = smtplib.SMTP(config['MAIL_HOST'], config['MAIL_PORT'])
    server.starttls()
    server.login(config['MAIL_USERNAME'], config['MAIL_PASSWORD'])

    for i in range(len(persons)):
        recipients = emails[persons[i]]
        message.replace_header('to', recipients)
        message.set_payload(content.format(mail_receiver=persons[i], gift_receiver=random_case[i]))

        server.sendmail(sender, [recipients], message.as_string())
        print persons[i], ' => ', random_case[i]

    server.quit()
示例#16
0
def send_mail(event, dtstart):
	summary = event.get('summary').to_ical()
	description = event.get('description').to_ical().decode('string_escape').replace('\,', ',').replace('\;',';')
	starttime = dtstart.strftime("%a, %B %d %Y, %H:%M")

	body = "Time & Date: " + starttime + "\n"

	if event.get('location'):
		body += "Location: " + event.get('location').to_ical().decode('string_escape').replace('\,', ',').replace('\;',';') + "\n"

	body += "\n" + description
	subject = "[Event] " + summary + " (" + starttime + ")"

	if event.get('url'):
		url = event.get('url').to_ical()
		body = body + "\nURL: " + url

	msg = Message()
	msg.set_payload(body, "utf-8")
	msg["Subject"] = subject
	msg["From"] = config.MAIL_FROM
	msg["To"] = config.MAIL_TO

	server = smtplib.SMTP(config.SMTP_HOST, config.SMTP_PORT)
	server.ehlo()
	server.starttls()
	server.ehlo()
	server.login(config.SMTP_USER, config.SMTP_PASS)
	text = msg.as_string()
	server.sendmail(config.MAIL_FROM, config.MAIL_TO, text)
	server.quit()
示例#17
0
 def message_to_string(self, recever_addr, title, text):
     message = Message()
     message['From'] = self.from_addr
     message['Subject'] = title
     message['To'] = recever_addr
     message.set_payload(text, charset='utf-8')
     return message.as_string()
示例#18
0
文件: default.py 项目: kodinerds/repo
    def deliverMail(self, message):
        if self.__notification:
            try:
                __port = {'None': 25, 'SSL/TLS': 465, 'STARTTLS': 587}
                __s_msg = Message()
                __s_msg.set_charset(self.__charset)
                __s_msg.set_payload(message, charset=self.__charset)
                __s_msg["Subject"] = __LS__(30046) % (HOST)
                __s_msg["From"] = self.__smtpfrom
                __s_msg["To"] = self.__smtpto

                if self.__smtpenc == 'STARTTLS':
                    __s_conn = smtplib.SMTP(self.__smtpserver, __port[self.__smtpenc])
                    __s_conn.ehlo()
                    __s_conn.starttls()
                elif self.__smtpenc == 'SSL/TLS':
                    __s_conn = smtplib.SMTP_SSL(self.__smtpserver, __port[self.__smtpenc])
                    __s_conn.ehlo()
                else:
                    __s_conn = smtplib.SMTP(self.__smtpserver, __port[self.__smtpenc])
                __s_conn.login(self.__smtpuser, self.__smtppass)
                __s_conn.sendmail(self.__smtpfrom, self.__smtpto, __s_msg.as_string())
                __s_conn.close()
                writeLog('Mail delivered to %s.' % (self.__smtpto), level=xbmc.LOGNOTICE)
                return True
            except Exception, e:
                writeLog('Mail could not be delivered. Check your settings.', xbmc.LOGERROR)
                return False
示例#19
0
    def send(self, to_address, subject, message):
        """
        Generates and sends the email with the parameters specified

        Parameters:
            to_address (str) - The email address to send the (e.g. "*****@*****.**")
            subject (str) - The subject of the email message
            message (str) - The email message data
        """

        # Make sure the variables are the correct type
        if not isinstance(to_address, str):
            raise TypeError("The destination address must be a string")

        subject = str(subject)
        message = str(message)

        # Create a new email message object
        m = Message()

        # Set the message object's attributes
        m['From'] = str(self.from_name)
        m['X-Priority'] = str(self.priority)
        m['Subject'] = str(subject)

        # Set the payload (message) for the message object
        m.set_payload(message)

        # Try to connect to the server
        try:
            server = smtplib.SMTP(self.hostname, timeout=5)
        except Exception as e:
            raise Exception("Failed to connect to the email server!") from e

        # Greet the server
        server.ehlo()

        # Check for and enable TLS if requested
        if self.tls_enabled:
            try:
                server.starttls()
            except:
                if self.force_tls:
                    raise Exception("TLS failed to start and but is set to be required!")
                else:
                    self.warning("TLS failed to start. Proceeding without encryption!")

        try:  # Try to login, if it fails, write an error message and raise an exception
            server.login(self.username, self.password)
        except Exception as e:
            raise Exception("Server login failed, please check username and password!") from e

        # Try to send the email, if it fails, write an error message and raise an exception
        try:
            server.sendmail(str(self.from_address), str(to_address), m.as_string())
        except Exception as e:
            raise Exception("Sending mail failed!") from e

        server.close()
示例#20
0
    def on_feed_exit(self, feed):
        """Send email at exit."""
        config = self.get_config(feed)

        if not config['active']:
            return

        # don't send mail when learning
        if feed.manager.options.learn:
            return

        # don't send empty emails
        if not feed.accepted:
            return

        # generate email content
        entries_count = len(feed.accepted)
        subject = '[FlexGet] %s : %d new entries downloaded' % (feed.name, entries_count)
        content = (u'Hi,\n'
                    'FlexGet has just downloaded %d new entries for feed %s :' % (entries_count, feed.name))

        for entry in feed.accepted:
            content += "\n - %s (%s)" % (entry['title'], entry['url'])
            entry_path = entry.get('path', feed.config.get('download'))
            entry_filename = entry.get('filename', entry['title'])
            if entry_path:
                content += " => %s (%s)" % (entry_path, entry_filename)

        content += "\n\n"

        # prepare email message
        message = Message()
        message['To'] = ','.join(config['to'])
        message['From'] = config['from']
        message['Subject'] = subject
        message.set_payload(content.encode('utf-8'))
        message.set_charset('utf-8')

        # send email message
        if feed.manager.options.test:
            log.info('Would send email : %s' % message.as_string())
        else:
            try:
                if config['smtp_ssl']:
                    import sys
                    if sys.version_info < (2, 6, 3):
                        raise PluginError('SSL email support requires python >= 2.6.3 due to python bug #4066, upgrade python or use TLS', log)
                    # Create a SSL connection to smtp server
                    mailServer = smtplib.SMTP_SSL(config['smtp_host'], config['smtp_port'])
                else:
                    mailServer = smtplib.SMTP(config['smtp_host'], config['smtp_port'])
                    if config['smtp_tls']:
                        mailServer.ehlo()
                        mailServer.starttls()
            except socket.error, e:
                raise PluginWarning('Socket error: %s' % e, log)
            except SMTPException, e:
                # Ticket #1133
                raise PluginWarning('Unable to send email: %s' % e, log)
 def test_mails_from_appengine(self):  # bounces
     msg = Message()
     msg["Subject"] = "subject (issue%s)" % self.issue.key().id()
     msg["From"] = "*****@*****.**"
     msg["X-Google-Appengine-App-Id"] = "foo"
     self.assertRaises(
         views.InvalidIncomingEmailError, views._process_incoming_mail, msg.as_string(), "*****@*****.**"
     )
 def test_unknown_issue(self):
     msg = Message()
     msg["From"] = "*****@*****.**"
     msg["Subject"] = "subject (issue99999)"
     msg.set_payload("body")
     self.assertRaises(
         views.InvalidIncomingEmailError, views._process_incoming_mail, msg.as_string(), "*****@*****.**"
     )
示例#23
0
    def _compile_mail(self, _from, to, subject, _msg, attachments):
        msg = Message()
        msg.set_payload(_msg)
        msg["Subject"] = subject
        msg["From"] = _from
        msg["To"] = to

        return msg.as_string()
示例#24
0
 def test_mails_from_appengine(self):  # bounces
   msg = Message()
   msg['Subject'] = 'subject (issue%s)' % self.issue.key.id()
   msg['From'] = '*****@*****.**'
   msg['X-Google-Appengine-App-Id'] = 'foo'
   self.assertRaises(views.InvalidIncomingEmailError,
                     views._process_incoming_mail, msg.as_string(),
                     '*****@*****.**')
示例#25
0
 def test_unknown_issue(self):
   msg = Message()
   msg['From'] = '*****@*****.**'
   msg['Subject'] = 'subject (issue99999)'
   msg.set_payload('body')
   self.assertRaises(views.InvalidIncomingEmailError,
                     views._process_incoming_mail, msg.as_string(),
                     '*****@*****.**')
示例#26
0
 def test_huge_body_is_truncated(self):  # see issue325
   msg = Message()
   msg['subject'] = 'subject (issue%s)' % self.issue.key.id()
   msg['From'] = '*****@*****.**'
   msg.set_payload('1' * 600 * 1024)
   views._process_incoming_mail(msg.as_string(), '*****@*****.**')
   imsg = models.Message.query(ancestor=self.issue.key).get()
   self.assertEqual(len(imsg.text), 500 * 1024)
   self.assert_(imsg.text.endswith('... (message truncated)'))
 def build_input_message(self, text, target):
     msg = Message()
     msg['From'] = '*****@*****.**'
     msg['To'] = '{}@{}'.format(target, settings.DISTRO_TRACKER_FQDN)
     msg['Delivered-To'] = msg['To']
     msg['Subject'] = 'Test message'
     msg.set_payload(text)
     self.input_message = msg
     return force_bytes(msg.as_string(), 'utf-8')
示例#28
0
def sendEmail(subject, content):
    """
    Send Email.
    """
    writeLog("EMAIL SENDING", "", "")
    try:
        eps = getServerEmail()
        email = eps[0]
        passwd = eps[1]
        server = eps[2]
        smtpServer = server
        userName = email
        password = passwd
        rcb = getRCB()
        recipient = rcb[0]
        carbonCopy = rcb[1]
        blindCC = rcb[2]
        rList = splitStr(recipient, ",")
        cList = splitStr(carbonCopy, ",")
        bList = splitStr(blindCC, ",")
        rList = filterList(rList)
        cList = filterList(cList)
        bList = filterList(bList)

        fromAddr = email
        toAddrs = rList
        #lxw 2015.12.23
        if "无信息更新" in content or "网站访问故障" in content: #NOT: if "无信息更新" or "网站访问故障" in content:
            ccAddrs = []
            return  # No useful message. Don't send the email.
        else:
            ccAddrs = ["*****@*****.**", "*****@*****.**", "*****@*****.**", "*****@*****.**"]
            #ccAddrs = []
        bccAddrs = bList

        message = Message()
        message["Subject"] = subject
        message["From"] = fromAddr
        message["To"] = ";".join(toAddrs)
        #Copy to
        #message["CC"] is only for display, to send the email we must specify it in the method "SMTP.sendmail".
        message["CC"] = ";".join(ccAddrs)
        message.set_payload(content)
        message.set_charset("utf-8")
        msg = message.as_string()

        sm = smtplib.SMTP(smtpServer)
        sm.set_debuglevel(0)    #sm.set_debuglevel(1)
        sm.ehlo()
        sm.starttls()
        sm.ehlo()
        sm.login(userName, password)

        sm.sendmail(fromAddr, toAddrs+ccAddrs+bccAddrs, msg)
        sm.quit()
    except Exception, e:
        writeLog("EMAIL SENDING ERROR", "", traceback.format_exc())
示例#29
0
    def write_line(self, data):
        """
            Write a line *data* to socket. It appends a **newline** at
            the end of the *data* before sending it.
            
            The string MUST NOT contain **newline** otherwise an AssertionError will
            raise.
            
            Parameters:
            
            **data**
                String containing the data to be sent.
        """
        assert('\n' not in data)
        self.write_lock.acquire()
        try:
            try:
                data = data.encode('utf-8')
            except AttributeError:
                pass
            if self._debug_socket: 
                _log.debug("<:%d: %s", len(data), data.decode('utf-8')[:130])

            if self._http:
                msg = Message()
                msg.add_header('Content-Transfer-Encoding', '8bit')
                msg.add_header('Content-Type', 'application/json-rpc')
                msg.add_header('Content-Length', str(len(data)))
                msg.set_payload(data, charset='utf-8')
                self._wbuffer += 'HTTP/1.0 200 OK\n'+msg.as_string()
                #print(self._wbuffer)
            else:
                self._wbuffer += data + b'\n'
            sbytes = 0
            while self._wbuffer:
                try:
                    sbytes = self._sck.send(self._wbuffer)
                except IOError:
                    _log.debug("Write socket error: IOError (timeout: %r)",
                        self._sck.gettimeout())
                    _log.debug(traceback.format_exc(0))
                    return 0
                except socket.error:
                    _log.debug("Write socket error: socket.error (timeout: %r)",
                        self._sck.gettimeout())
                    _log.debug(traceback.format_exc(0))
                    return 0
                except:
                    raise
                if sbytes == 0: 
                    break
                self._wbuffer = self._wbuffer[sbytes:]
            if self._wbuffer:
                _log.warning("%d bytes left in write buffer", len(self._wbuffer))
            return len(self._wbuffer)
        finally:
            self.write_lock.release()
示例#30
0
 def test_long_subjects(self):
   # multi-line subjects should be collapsed into a single line
   msg = Message()
   msg['Subject'] = ('foo '*30)+' (issue%s)' % self.issue.key.id()
   msg['From'] = '*****@*****.**'
   msg.set_payload('body')
   views._process_incoming_mail(msg.as_string(), '*****@*****.**')
   imsg = models.Message.query(ancestor=self.issue.key).get()
   self.assertEqual(len(imsg.subject.splitlines()), 1)
#!/usr/bin/env python
# Foundations of Python Network Programming - Chapter 12 - trad_gen_newhdrs.py
# Traditional Message Generation with Date and Message-ID
# This program requires Python 2.5 or above

import email.utils
from email.message import Message

message = """Hello,

This is a test message from Chapter 12.  I hope you enjoy it!

-- Anonymous"""

msg = Message()
msg['To'] = '*****@*****.**'
msg['From'] = 'Test Sender <*****@*****.**>'
msg['Subject'] = 'Test Message, Chapter 12'
msg['Date'] = email.utils.formatdate(localtime = 1)
msg['Message-ID'] = email.utils.make_msgid()
msg.set_payload(message)

print msg.as_string()
示例#32
0
    def emailException(self, htmlErrMsg):
        """Email the exception.

        Send the exception via mail, either as an attachment,
        or as the body of the mail.
        """
        message = Message()

        # Construct the message headers
        headers = self.setting('ErrorEmailHeaders').copy()
        headers['Date'] = formatdate()
        headers['Mime-Version'] = '1.0'
        headers['Subject'] = '{} {}: {}'.format(
            headers.get('Subject', '[Webware Error]'), *sys.exc_info()[:2])
        for header, value in headers.items():
            if isinstance(value, (list, tuple)):
                value = ','.join(value)
            message.add_header(header, value)

        # Construct the message body
        if self.setting('EmailErrorReportAsAttachment'):
            # start off with a text/plain part
            text = self._emailBody.format(
                path=self.servletPathname(),
                ascTime=asclocaltime(self._time), time=self._time)
            message.set_type('multipart/mixed')
            part = Message()
            part.set_type('text/plain')
            body = StringIO()
            body.write(text)
            traceback.print_exc(file=body)
            part.set_payload(body.getvalue())
            body.close()
            message.attach(part)
            part = Message()
            # now add htmlErrMsg
            part.add_header('Content-Transfer-Encoding', '7bit')
            part.add_header(
                'Content-Description',
                'HTML version of Webware error message')
            part.add_header(
                'Content-Disposition',
                'attachment', filename='WebwareErrorMsg.html')
            part.set_type('text/html')
            part.set_payload(htmlErrMsg)
            message.attach(part)
        else:
            message.set_type('text/html')
            message.set_payload(htmlErrMsg, 'us-ascii')

        # Send the message
        server = self.setting('ErrorEmailServer')
        # This setting can be: server, server:port, server:port:user:password
        # or server:port:user:password:popserver:popport for "smtp after pop".
        parts = server.split(':', 5)
        server = port = user = passwd = None
        popserver = popssl = popport = None
        try:
            # fetch individual parts until we get an IndexError
            server = parts[0]
            try:
                port = int(parts[1])
            except ValueError:
                pass
            user = parts[2]
            passwd = parts[3]
            popserver = parts[4]
            try:
                popport = int(parts[5])
            except ValueError:
                popport = None
            if parts[6].lower() == 'ssl':
                popssl = True
        except IndexError:
            pass
        if user and passwd and popserver:
            # SMTP after POP
            if popssl is None and popport == 995:
                popssl = True
            popssl = poplib.POP3_SSL if popssl else poplib.POP3
            if popport:
                popserver = popssl(popserver, popport)
            else:
                popserver = popssl(popserver)
            popserver.set_debuglevel(0)
            popserver.user(user)
            popserver.pass_(passwd)
            try:
                popserver.quit()
            except Exception:
                pass
        if port:
            server = smtplib.SMTP(server, port)
        else:
            server = smtplib.SMTP(server)
        try:
            server.set_debuglevel(0)
            if user and passwd and not popserver:
                # SMTP-AUTH
                server.ehlo()
                if server.has_extn('starttls'):
                    server.starttls()
                    server.ehlo()
                server.login(user, passwd)
            body = message.as_string()
            server.sendmail(headers['From'], headers['To'], body)
        finally:
            try:
                server.quit()
            except Exception:
                pass
示例#33
0
    try:
        private_key = open(keyfile).read()
    except IOError, ex:
        log.error("file %s is not readable", keyfile)
        log.error(ex.message)
        sys.exit(2)

    # compose message
    msg = Message()
    msg['From'] = sender
    msg['To'] = recipient
    msg['Subject'] = subject
    msg.set_payload(body)

    # sign message
    email = msg.as_string()
    sig = sign(email, selector, domain, private_key)
    dkimmail = sig + email
    log.info("e-mail message is:")
    log.info(dkimmail)

    if printonly:
        print dkimmail
    else:
        try:
            server = smtplib.SMTP('localhost')
            # TODO: check loglevel
            if verbose:
                log.info("smtp debug level was set to 1")
                server.set_debuglevel(1)
            server.sendmail(sender, recipient, dkimmail)
示例#34
0
# E-Mail versenden

from email.message import Message

msg = Message()
log = open(LogOutputFile, "r")

# Error Log Datei auslesen
Text = ""
for line in log:
    Text += line

log.close()

# EMail erzeuegen
msg.attach(LogErrorFile)  # toDo
msg.set_payload(Text)
msg["Subject"] = MailSubject
msg["From"] = MailFrom
msg["To"] = MailTo

# EMail verschicken
server = smtplib.SMTP('localhost')
server.sendmail(MailFrom, MailTo, msg.as_string())
server.quit()

# Alle Dateien loeschen
os.remove(OUITmpDatei)
os.remove(LogOutputFile)
os.remove(LogErrorFile)
示例#35
0
def run_and_output_changes(env, pool, send_via_email):
	import json
	from difflib import SequenceMatcher

	if not send_via_email:
		out = ConsoleOutput()
	else:
		import io
		out = FileOutput(io.StringIO(""), 70)

	# Run status checks.
	cur = BufferedOutput()
	run_checks(True, env, cur, pool)

	# Load previously saved status checks.
	cache_fn = "/var/cache/mailinabox/status_checks.json"
	if os.path.exists(cache_fn):
		prev = json.load(open(cache_fn))

		# Group the serial output into categories by the headings.
		def group_by_heading(lines):
			from collections import OrderedDict
			ret = OrderedDict()
			k = []
			ret["No Category"] = k
			for line_type, line_args, line_kwargs in lines:
				if line_type == "add_heading":
					k = []
					ret[line_args[0]] = k
				else:
					k.append((line_type, line_args, line_kwargs))
			return ret
		prev_status = group_by_heading(prev)
		cur_status = group_by_heading(cur.buf)

		# Compare the previous to the current status checks
		# category by category.
		for category, cur_lines in cur_status.items():
			if category not in prev_status:
				out.add_heading(category + " -- Added")
				BufferedOutput(with_lines=cur_lines).playback(out)
			else:
				# Actual comparison starts here...
				prev_lines = prev_status[category]
				def stringify(lines):
					return [json.dumps(line) for line in lines]
				diff = SequenceMatcher(None, stringify(prev_lines), stringify(cur_lines)).get_opcodes()
				for op, i1, i2, j1, j2 in diff:
					if op == "replace":
						out.add_heading(category + " -- Previously:")
					elif op == "delete":
						out.add_heading(category + " -- Removed")
					if op in ("replace", "delete"):
						BufferedOutput(with_lines=prev_lines[i1:i2]).playback(out)

					if op == "replace":
						out.add_heading(category + " -- Currently:")
					elif op == "insert":
						out.add_heading(category + " -- Added")
					if op in ("replace", "insert"):
						BufferedOutput(with_lines=cur_lines[j1:j2]).playback(out)

		for category, prev_lines in prev_status.items():
			if category not in cur_status:
				out.add_heading(category)
				out.print_warning("This section was removed.")

	if send_via_email:
		# If there were changes, send off an email.
		buf = out.buf.getvalue()
		if len(buf) > 0:
			# create MIME message
			from email.message import Message
			msg = Message()
			msg['From'] = "\"%s\" <administrator@%s>" % (env['PRIMARY_HOSTNAME'], env['PRIMARY_HOSTNAME'])
			msg['To'] = "administrator@%s" % env['PRIMARY_HOSTNAME']
			msg['Subject'] = "[%s] Status Checks Change Notice" % env['PRIMARY_HOSTNAME']
			msg.set_payload(buf, "UTF-8")

			# send to administrator@
			import smtplib
			mailserver = smtplib.SMTP('localhost', 25)
			mailserver.ehlo()
			mailserver.sendmail(
				"administrator@%s" % env['PRIMARY_HOSTNAME'], # MAIL FROM
				"administrator@%s" % env['PRIMARY_HOSTNAME'], # RCPT TO
				msg.as_string())
			mailserver.quit()

	# Store the current status checks output for next time.
	os.makedirs(os.path.dirname(cache_fn), exist_ok=True)
	with open(cache_fn, "w") as f:
		json.dump(cur.buf, f, indent=True)
示例#36
0
    def sendMessage(self,
                    From,
                    To,
                    Subj,
                    extrahdrs,
                    bodytext,
                    attaches,
                    saveMailSeparator=(('=' * 80 + 'PY\n')),
                    bodytextEncoding='us-ascii',
                    attachesEncodings=None):
        if fix_text_required(bodytextEncoding):
            if not isinstance(bodytext, str):
                bodytext = bodytext.decode(bodytextEncoding)

        else:
            if not isinstance(bodytext, bytes):
                bodytext = bodytext.encode(bodytextEncoding)

        #make message root
        if not attaches:
            msg = Message()
            msg.set_payload(bodytext, charset=bodytextEncoding)
        else:
            msg = MIMEMultipart()
            self.addAttachments(msg, bodytext, attaches, bodytextEncoding,
                                attachesEncodings)

        hdrenc = mailconfig.headersEncodeTo or 'utf-8'
        Subj = self.encodeHeader(Subj, hdrenc)
        From = self.encodeAddrHeader(From, hdrenc)
        To = [self.encodeAddrHeader(T, hdrenc) for T in To]
        Tos = ', '.join(To)

        # add header to root
        msg['From'] = From
        msg['To'] = Tos
        msg['Subject'] = Subj
        msg['Date'] = email.utils.formatdate()
        recip = To
        for name, value in extrahdrs:
            if name.lower() not in ['cc', 'bcc']:
                value = self.encodeHeader(value, hdrenc)
                msg[name] = value

            else:
                value = [self.encodeAddrHeader(V, hdrenc) for V in value]
                recip += value

                if name.lower() != 'bcc':
                    msg[name] = ', '.join(value)
        recip = list(set(recip))
        fullText = msg.as_string()

        self.trace('Sending to...' + str(recip))
        self.trace(fullText[:self.tracesize])
        server = smtplib.SMTP_SSL(self.smtpServerName)
        self.getPassword()
        self.authenticateServer(server)
        try:
            failed = server.sendmail(From, recip, fullText)
        except:
            server.close()
            raise
        else:
            server.quit()
        self.saveSentMessage(fullText, saveMailSeparator)
        if failed:

            class SomeAddrsFailed(Exception):
                pass

            raise SomeAddrsFailed('Failed addrs:%s\n' % failed)
        self.trace('Send exit')
示例#37
0
#!/usr/bin/env python3
# Foundations of Python Network Programming, Third Edition
# https://github.com/brandon-rhodes/fopnp/blob/m/py3/chapter12/pre-python-3.4/trad_gen_newhdrs.py
# Traditional Message Generation with Date and Message-ID

import email.utils
from email.message import Message

message = """Hello,

This is a test message from Chapter 12.  I hope you enjoy it!

-- Anonymous"""

msg = Message()
msg['To'] = '*****@*****.**'
msg['From'] = 'Test Sender <*****@*****.**>'
msg['Subject'] = 'Test Message, Chapter 12'
msg['Date'] = email.utils.formatdate(localtime=1)
msg['Message-ID'] = email.utils.make_msgid()
msg.set_payload(message)

print(msg.as_string())
示例#38
0
    def sendMessage(self,
                    From,
                    To,
                    Subj,
                    extrahdrs,
                    bodytext,
                    attaches,
                    saveMailSeparator=(('=' * 80) + 'PY\n'),
                    bodytextEncoding='us-ascii',
                    attachesEncodings=None):
        """
        formats and sends an e-mail.
        saves the sent e-mail if sent sucessfully.
        arguments:
        bodytext - text part of the e-mail (assumes it is already in desired
                                                encoding.)
        attaches - list of files to be attached
        extrahdrs - list of tuples to be added (Name, Value)
        """
        # body text encoding
        if fix_text_required(bodytextEncoding):
            if not isinstance(bodytext, str):
                bodytext = bodytext.decode(bodytextEncoding)
        else:
            if not isinstance(bodytext, bytes):
                bodytext = bodytext.encode(bodytextEncoding)

        # attachments
        if not attaches:
            msg = Message()
            msg.set_payload(bodytext, charset=bodytextEncoding)
        else:
            msg = MIMEMultipart()
            self.addAttachments(msg, bodytext, attaches, bodytextEncoding,
                                attachesEncodings)

        # e-mail header encoding
        hdrenc = mailconfig.headersEncodeTo or 'utf-8'
        Subj = self.encodeHeader(Subj, hdrenc)
        From = self.encodeAddrHeader(From, hdrenc)
        To = [self.encodeAddrHeader(T, hdrenc) for T in To]
        Tos = ', '.join(To)

        # attach header to message
        msg['From'] = From
        msg['To'] = Tos
        msg['Subj'] = Subj
        msg['Date'] = email.utils.formatdate()
        recip = To

        for (name, value) in extrahdrs:
            if value:
                if name.lower() not in ['cc', 'bcc']:
                    value = self.encodeHeader(value, hdrenc)
                    msg[name] = value
                else:
                    value = [self.encodeAddrHeader(V, hdrenc) for V in value]
                    recip += value
                    if name.lower() != 'bcc':
                        msg[name] = ', '.join(value)

        # remove duplicates
        recip = list(set(recip))

        fullText = msg.as_string()

        self.trace('Sending to...' + str(recip))
        self.trace(fullText[:self.tracesize])

        # smtp connection.
        server = smtplib.SMTP_SSL(self.smtpservername)
        self.getPassword()
        self.authenticateServer(server)

        try:
            failed = server.sendmail(From, recip, fullText)
        except Exception:
            server.close()
            raise
        else:
            server.quit()

        self.saveSentMessage(fullText, saveMailSeparator)

        if failed:

            class SomeAddrsFailed(Exception):
                pass

            raise SomeAddrsFailed('Failed addrs:%s\n' % failed)
        self.trace('Send exit')
示例#39
0
    def _encrypt(self,
                 mail,
                 encrypt=True,
                 sign=True,
                 inline=False,
                 recipients=None,
                 toself=True,
                 passphrase=None,
                 verify=False,
                 **kwargs):
        import email.utils, six
        from email.header import decode_header
        from email.message import Message
        from email.utils import parseaddr
        from .mail import _mail_addreplace_header, protect_mail, _protected

        def find_sender(mail):
            sender = mail.get('from', '')
            sender = parseaddr(decode_header(sender)[0][0])[1]
            sender = self.find_key(sender, secret=True)
            if not sender: raise KeyMissingError("sender")
            return sender

        if not isinstance(mail, (Message, ) + six.string_types):
            raise TypeError("mail must be Message or str")
        if encrypt:
            mail = protect_mail(mail, linesep=None, sevenbit=False)
            if not recipients:
                tos = mail.get_all('to', []) + mail.get_all('cc', [])
                recipients = [
                    parseaddr(decode_header(to)[0][0])[1] for to in tos
                ]
            elif isinstance(recipients, six.string_types):
                recipients = [recipients]
            recipients = list(self.find_key(recipients).values())
            if None in recipients:
                raise KeyMissingError("public keys for recipients")
            if sign == True or toself:
                sender = find_sender(mail)  # use default_key?
            if toself and not sender in recipients: recipients.append(sender)
        else:
            mail = protect_mail(
                mail, linesep='\r\n',
                sevenbit=True)  # fix line separators + 7bit RFC2822
            if sign == True: sender = find_sender(mail)  # use default_key?
        if sign:
            if sign == True:
                sign = sender
                if not passphrase and self.default_key and self.default_key[
                        0] == sign:
                    passphrase = self.default_key[1]
            assert not type(sign) in (
                tuple, list), "multiple signers not yet supported"
            kwargs['default_key'] = sign
            kwargs['passphrase'] = passphrase
        plaintext, submsg = self._plaintext(mail, inline)
        if encrypt:
            # Do encryption, report errors
            try:
                result = self._encrypt_str(plaintext,
                                           recipients,
                                           armor=True,
                                           **kwargs)
            except:
                return None, None
            if not result: return None, result
            payload = str(result)
            if verify and toself:
                if sign: del kwargs['default_key']
                if self.default_key and kwargs.get('passphrase') is None:
                    kwargs['passphrase'] = self.default_key[1]
                vresult = self.decrypt_str(payload, **kwargs)
                if not vresult.ok or (sign and not vresult.valid):
                    return None, result
        else:
            # Generate signature, report errors
            try:
                if not mail.is_multipart() and inline:
                    result = self._sign_str(plaintext,
                                            clearsign=True,
                                            detach=False,
                                            **kwargs)
                else:
                    result = self._sign_str(plaintext,
                                            clearsign=False,
                                            detach=True,
                                            **kwargs)
            except:
                return None, None
            if not result: return None, result
            payload = str(result)  #signature
            if verify:
                if not mail.is_multipart() and inline:
                    vresult = self.verify_str(payload)
                else:
                    vresult = self.verify_str(submsg.as_string(), payload)
                if not vresult.valid: return None, result
        # Compile encrypted message
        if not mail.is_multipart() and inline:
            mail.set_payload(payload)
            if encrypt:
                _mail_addreplace_header(mail, 'Content-Transfer-Encoding',
                                        '7bit')
                mail.set_param('x-action', 'pgp-encrypted')
            else:
                mail.set_param('x-action', 'pgp-signed')
        else:
            # workaround to preserve header order
            tmp = Message()
            tmp['Content-Type'] = mail['Content-Type']
            if encrypt:
                tmp.set_type('multipart/encrypted')
                tmp.set_param('protocol', 'application/pgp-encrypted')
            else:
                tmp.set_type('multipart/signed')
                tmp.del_param(
                    'boundary')  # delete boundary as we need a new one
                tmp.set_param('protocol', 'application/pgp-signature')
                tmp.set_param('micalg', 'pgp-sha1;')
            mail.replace_header('Content-Type', tmp['Content-Type'])
            if six.PY3: mail = _protected(mail, headersonly=True)
            mail.set_payload(None)
            if encrypt:
                mail.preamble = 'This is an OpenPGP/MIME encrypted message (RFC 4880 and 3156)'
                submsg = Message()
                submsg.add_header('Content-Type', 'application/pgp-encrypted')
                submsg.set_payload('Version: 1\n')
                mail.attach(submsg)
                submsg = Message()
                submsg.add_header(
                    'Content-Type',
                    'application/octet-stream; name="encrypted.asc"')
                submsg.add_header('Content-Description',
                                  'OpenPGP encrypted message')
                submsg.add_header('Content-Disposition',
                                  'inline; filename="encrypted.asc"')
                submsg.set_payload(payload)
                mail.attach(submsg)
            else:
                mail.preamble = 'This is an OpenPGP/MIME signed message (RFC 4880 and 3156)'
                assert submsg.as_string() == plaintext, "plaintext was broken"
                mail.attach(submsg)
                submsg = Message()
                submsg.add_header(
                    'Content-Type',
                    'application/pgp-signature; name="signature.asc"')
                submsg.add_header('Content-Description',
                                  'OpenPGP digital signature')
                submsg.add_header('Content-Disposition',
                                  'attachment; filename="signature.asc"')
                submsg.set_payload(payload)
                mail.attach(submsg)
        return mail, result
class SmartMessage:
    """A simplified interface to Python's library for creating email
    messages, with and without MIME attachments."""
    def __init__(self, fromAddr, toAddrs, subject, body):
        """Start off on the assumption that the message will be a simple RFC
        2822 message with no MIME."""
        self.msg = Message()
        self.msg.set_payload(body)
        self['Subject'] = subject
        self.setFrom(fromAddr)
        self.setTo(toAddrs)
        self.hasAttachments = False

    def setFrom(self, fromAddr):
        "Sets the address of the sender of the message."
        if not fromAddr or not type(fromAddr) == type(''):
            raise Exception('A message must have one and only one sender.')
        self['From'] = fromAddr

    def setTo(self, to):
        "Sets the address or addresses that will receive this message."
        if not to:
            raise Exception('A message must have at least one recipient.')
        self._addresses(to, 'To')
        #Also store the addresses as a list, for the benefit of future
        #code that will actually send this message.
        self.to = to

    def setCc(self, cc):
        """Sets the address or addresses that should receive this message,
        even though it's not addressed directly to them ("carbon-copy")."""
        self._addresses(cc, 'Cc')

    def addAttachment(self, attachment, filename, mimetype=None):
        "Attaches the given file to this message."
        #Figure out the major and minor MIME type of this attachment,
        #given its filename.
        if not mimetype:
            mimetype = mimetypes.guess_type(filename)[0]
        if not mimetype:
            raise Exception("Couldn't determine MIME type for ", filename)
        if '/' in mimetype:
            major, minor = mimetype.split('/')
        else:
            major = mimetype
            minor = None
        #The message was constructed under the assumption that it was
        #a single-part message. Now that we know there's to be at
        #least one attachment, we need to change it into a multi-part
        #message, with the first part being the body of the message.
        if not self.hasAttachments:
            body = self.msg.get_payload()
            newMsg = MIMEMultipart()
            newMsg.attach(MIMEText(body))
            #Copy over the old headers to the new object.
            for header, value in self.msg.items():
                newMsg[header] = value
            self.msg = newMsg
            self.hasAttachments = True
        subMessage = MIMENonMultipart(major, minor, name=filename)
        subMessage.set_payload(attachment)
        #Encode text attachments as quoted-printable, and all other
        #types as base64.
        if major == 'text':
            encoder = Encoders.encode_quopri
        else:
            encoder = Encoders.encode_base64
        encoder(subMessage)
        #Link the MIME message part with its parent message.
        self.msg.attach(subMessage)

    def _addresses(self, addresses, key):
        """Sets the given header to a string representation of the given
        list of addresses."""
        if hasattr(addresses, '__iter__'):
            addresses = ', '.join(addresses)
        self[key] = addresses

    #A few methods to let scripts treat this object more or less like
    #a Message or MultipartMessage, by delegating to the real Message
    #or MultipartMessage this object holds.
    def __getitem__(self, key):
        "Return a header of the underlying message."
        return self.msg[key]

    def __setitem__(self, key, value):
        "Set a header of the underlying message."
        self.msg[key] = value

    def __getattr__(self, key):
        return getattr(self.msg, key)

    def __str__(self):
        "Returns a string representation of this message."
        return self.msg.as_string()
示例#41
0
            from email.message import Message
        except ImportError:
            from email.Message import Message

        msg = Message()
        msg["From"] = FROM_ADDRESS
        msg["To"] = to_email_id
        msg["Subject"] = SUBJECT_TEMPLATE % (branch_name, wc_version)
        msg["X-Mailer"] = "l10n-report.py r%s" % _rev()
        msg["Reply-To"] = LIST_ADDRESS
        msg["Mail-Followup-To"] = LIST_ADDRESS
        msg["In-Reply-To"] = MAIL_THREAD_ID % (branch_name.replace('/', '_'))
        msg["References"] = msg["In-Reply-To"]

        # http://www.iana.org/assignments/auto-submitted-keywords/auto-submitted-keywords.xhtml
        msg["Auto-Submitted"] = 'auto-generated'

        msg.set_type("text/plain")
        msg.set_payload("\n".join((title, format_head, format_line, body)))

        server = smtplib.SMTP('localhost')
        server.sendmail("From: " + FROM_ADDRESS,
                        "To: " + to_email_id,
                        msg.as_string())
        print("The report is sent to '%s' email id." % to_email_id)
    else:
        print("\nYou have not passed '-m' option, so email is not sent.")

if __name__ == "__main__":
    main()
示例#42
0
def main():
    # Parse the command-line options and arguments.
    try:
        opts, args = getopt.gnu_getopt(sys.argv[1:], "hm:", [
            "help",
            "to-email-id=",
        ])
    except getopt.GetoptError as msg:
        usage_and_exit(msg)

    to_email_id = None
    for opt, arg in opts:
        if opt in ("-h", "--help"):
            usage_and_exit()
        elif opt in ("-m", "--to-email-id"):
            to_email_id = arg

    l10n = l10nReport()
    os.chdir("%s/../.." % os.path.dirname(os.path.abspath(sys.argv[0])))
    l10n.pre_l10n_report()
    [info_out, info_err] = l10n.safe_command(['svn', 'info'])
    if info_err:
        sys.stderr.write("\nError: %s\n" % info_err)
        sys.stderr.flush()
        sys.exit(0)

    po_dir = 'subversion/po'
    branch_name = l10n.match('URL:.*/asf/subversion/(\S+)', info_out)
    [info_out, info_err] = l10n.safe_command(['svnversion', po_dir])
    if info_err:
        sys.stderr.write("\nError: %s\n" % info_err)
        sys.stderr.flush()
        sys.exit(0)

    wc_version = re.sub('[MS]', '', info_out.strip())
    title = "Translation status report for %s@r%s" % \
               (branch_name, wc_version)

    os.chdir(po_dir)
    files = sorted(os.listdir('.'))
    format_head = "\n%6s %7s %7s %7s %7s" % ("lang", "trans", "untrans",
                                             "fuzzy", "obs")
    format_line = "--------------------------------------"
    print("\n%s\n%s\n%s" % (title, format_head, format_line))

    body = ""
    po_pattern = re.compile('(.*).po$')
    for file in files:
        lang = l10n.match(po_pattern, file)
        if not lang:
            continue
        [trans, untrans, fuzzy, obsolete] = l10n.get_msgattribs(file)
        po_format = "%6s %7d %7d %7d %7d" %\
                    (lang, trans, untrans, fuzzy, obsolete)
        po_format += "  " + bar_graph(30, trans, untrans, fuzzy, obsolete)
        body += "%s\n" % po_format
        print(po_format)

    if to_email_id:
        import smtplib
        # Ensure compatibility of the email module all the way to Python 2.3
        try:
            from email.message import Message
        except ImportError:
            from email.Message import Message

        msg = Message()
        msg["From"] = FROM_ADDRESS
        msg["To"] = to_email_id
        msg["Subject"] = SUBJECT_TEMPLATE % (branch_name, wc_version)
        msg["X-Mailer"] = "l10n-report.py r%s" % _rev()
        msg["Reply-To"] = LIST_ADDRESS
        msg["Mail-Followup-To"] = LIST_ADDRESS
        msg["In-Reply-To"] = MAIL_THREAD_ID % (branch_name.replace('/', '_'))
        msg["References"] = msg["In-Reply-To"]

        # http://www.iana.org/assignments/auto-submitted-keywords/auto-submitted-keywords.xhtml
        msg["Auto-Submitted"] = 'auto-generated'

        msg.set_type("text/plain")
        msg.set_payload("\n".join((title, format_head, format_line, body)))

        server = smtplib.SMTP('localhost')
        server.sendmail("From: " + FROM_ADDRESS, "To: " + to_email_id,
                        msg.as_string())
        print("The report is sent to '%s' email id." % to_email_id)
    else:
        print("\nYou have not passed '-m' option, so email is not sent.")
示例#43
0
def get_mime_header(header, value, **kwargs):
    msg = Message()
    msg.add_header(header, value, **kwargs)
    return msg.as_string().replace('\n\n', '\r\n').encode()
示例#44
0
def sendmail(subject, text, to=None, cc=None, bcc=None, mail_from=None, html=None):
    """ Create and send a text/plain message

    Return a tuple of success or error indicator and message.

    :param subject: subject of email
    :type subject: unicode
    :param text: email body text
    :type text: unicode
    :param to: recipients
    :type to: list
    :param cc: recipients (CC)
    :type cc: list
    :param bcc: recipients (BCC)
    :type bcc: list
    :param mail_from: override default mail_from
    :type mail_from: unicode
    :param html: html email body text
    :type html: unicode

    :rtype: tuple
    :returns: (is_ok, Description of error or OK message)
    """
    import smtplib
    import socket
    from email.message import Message
    from email.mime.multipart import MIMEMultipart
    from email.mime.text import MIMEText
    from email.charset import Charset, QP
    from email.utils import formatdate, make_msgid

    cfg = app.cfg
    if not cfg.mail_enabled:
        return (0, _("Contact administrator: cannot send password recovery e-mail "
                     "because mail configuration is incomplete."))
    mail_from = mail_from or cfg.mail_from

    logging.debug("send mail, from: {0!r}, subj: {1!r}".format(mail_from, subject))
    logging.debug("send mail, to: {0!r}".format(to))

    if not to and not cc and not bcc:
        return 1, _("No recipients, nothing to do")

    subject = subject.encode(CHARSET)

    # Create a text/plain body using CRLF (see RFC2822)
    text = text.replace(u'\n', u'\r\n')
    text = text.encode(CHARSET)

    # Create a message using CHARSET and quoted printable
    # encoding, which should be supported better by mail clients.
    # TODO: check if its really works better for major mail clients
    text_msg = Message()
    charset = Charset(CHARSET)
    charset.header_encoding = QP
    charset.body_encoding = QP
    text_msg.set_charset(charset)

    # work around a bug in python 2.4.3 and above:
    text_msg.set_payload('=')
    if text_msg.as_string().endswith('='):
        text = charset.body_encode(text)

    text_msg.set_payload(text)

    if html:
        msg = MIMEMultipart('alternative')
        msg.attach(text_msg)
        html = html.encode(CHARSET)
        html_msg = MIMEText(html, 'html')
        html_msg.set_charset(charset)
        msg.attach(html_msg)
    else:
        msg = text_msg

    address = encodeAddress(mail_from, charset)
    msg['From'] = address
    if to:
        msg['To'] = ','.join(to)
    if cc:
        msg['CC'] = ','.join(cc)
    msg['Date'] = formatdate()
    msg['Message-ID'] = make_msgid()
    msg['Subject'] = Header(subject, charset)
    # See RFC 3834 section 5:
    msg['Auto-Submitted'] = 'auto-generated'

    if cfg.mail_sendmail:
        if bcc:
            # Set the BCC.  This will be stripped later by sendmail.
            msg['BCC'] = ','.join(bcc)
        # Set Return-Path so that it isn't set (generally incorrectly) for us.
        msg['Return-Path'] = address

    # Send the message
    if not cfg.mail_sendmail:
        try:
            logging.debug("trying to send mail (smtp) via smtp server '{0}'".format(cfg.mail_smarthost))
            host, port = (cfg.mail_smarthost + ':25').split(':')[:2]
            server = smtplib.SMTP(host, int(port))
            try:
                # server.set_debuglevel(1)
                if cfg.mail_username is not None and cfg.mail_password is not None:
                    try:  # try to do TLS
                        server.ehlo()
                        if server.has_extn('starttls'):
                            server.starttls()
                            server.ehlo()
                            logging.debug("tls connection to smtp server established")
                    except:
                        logging.debug("could not establish a tls connection to smtp server, continuing without tls")
                    logging.debug("trying to log in to smtp server using account '{0}'".format(cfg.mail_username))
                    server.login(cfg.mail_username, cfg.mail_password)
                server.sendmail(mail_from, (to or []) + (cc or []) + (bcc or []), msg.as_string())
            finally:
                try:
                    server.quit()
                except AttributeError:
                    # in case the connection failed, SMTP has no "sock" attribute
                    pass
        except smtplib.SMTPException as e:
            logging.exception("smtp mail failed with an exception.")
            return 0, str(e)
        except (os.error, socket.error) as e:
            logging.exception("smtp mail failed with an exception.")
            return (0, _("Connection to mailserver '%(server)s' failed: %(reason)s",
                    server=cfg.mail_smarthost,
                    reason=str(e)
            ))
    else:
        try:
            logging.debug("trying to send mail (sendmail)")
            sendmailp = os.popen(cfg.mail_sendmail, "w")
            # msg contains everything we need, so this is a simple write
            sendmailp.write(msg.as_string())
            sendmail_status = sendmailp.close()
            if sendmail_status:
                logging.error("sendmail failed with status: {0!s}".format(sendmail_status))
                return 0, str(sendmail_status)
        except:
            logging.exception("sendmail failed with an exception.")
            return 0, _("Mail not sent")

    logging.debug("Mail sent successfully")
    return 1, _("Mail sent successfully")
示例#45
0
def sendConfirmMail():
    # Initializing SMTP
    s = smtplib.SMTP('smtp.gmail.com', 587)

    # Start TLS for security
    s.starttls()

    # Mail ID and credential from where all the mails will be sent are to be given here
    # USE CHRIST ID!!! Personal mails have restrictions on the number of mails that can be sent
    s.login("Your Mail ID Ex- [email protected]",
            "Your Password")

    # The content variable will hold the JSON request body
    content = request.get_json()

    # Access the email field that is within the JSON request
    email = content['email']
    # Access the first_pref field that is within the JSON request (Subject code)
    first_pref = content['first']
    # Access the second_pref field that is within the JSON request (Subject code)
    second_pref = content['second']
    # Access the third_pref field that is within the JSON request (Subject code)
    third_pref = content['third']

    # Dictionary to lookup the name of the subject of the given subject code
    # Change according to the respective year's available subjects
    dictionary = {
        "CE636OE1": "Solid Waste Management",
        "CE636OE2": "Environmental Impact Assessment",
        "CE636OE4": "Disaster Management",
        "CH63OE02": "CATALYST TECHNOLOGY",
        "EC636OE1": "Embedded Boards for IOT Applications",
        "EC636OE3": "Virtual Instrumentation",
        "EC636OE7": "E-WASTE MANAGEMENT AND RADIATION",
        "CS636OE01": "WEB PROGRAMMING CONCEPTS",
        "CS636OE06": "USER INTERFACE DESIGN CONCEPTS",
        "CS636OE08": "PYTHON PROGRAMMING FOR ENGINEERS",
        "ME63OE01": "Green Belt Practice",
        "ME63OE03": "Basic Automobile Engineering",
        "ME63OE04": "Project Management",
        "ME63OE05": "Basic Aerospace Engineering",
        "PH63OE01": "TECHNICAL CERAMICS",
        "CH63OE02": "CATALYST TECHNOLOGY",
        "MA63OE03": "NUMERICAL SOLUTION OF DIFFERENTIAL EQUATIONS",
        "EE636OE03": "Introduction to Hybrid Electric Vehicles",
        "EE636OE06": "Robotics and Automation",
        "EE636OE08": "Matrix Computations",
        "PHE03": "Advances In Materials Science and Engineering"
    }

    # Getting the names of the subjects from the dictionary
    ffirst = dictionary[first_pref]
    ssecond = dictionary[second_pref]
    tthird = dictionary[third_pref]

    # Mail content
    email_cont = """
            <html>
  <head>  
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>Open Elective OTP</title>
  </head>
  <body>
  <h1>We have received your request as follows:</strong></h1>
  <ol>
    <li>First Preference: """ + ffirst + """</li>
    <li>Second Preference: """ + ssecond + """</li>
    <li>Third Preference: """ + tthird + """</li>
  </ol>
  </body>
</html>
        """

    # Construction of the message
    msg = Message()
    msg['Subject'] = "Open Elective Confirmation"
    msg['From'] = 'CHRIST (Deemed to be University)'
    msg['To'] = 'You'
    msg.add_header('Content-Type', 'text/html')
    msg.set_payload(email_cont)

    # Sending the mail
    # The mail ID specified above to be given here again
    s.sendmail("Your Mail ID Ex- [email protected]",
               email, msg.as_string())

    # Close SMTP session
    s.quit()

    #Sending Success Response
    resp = jsonify(success=True)
    return resp
示例#46
0
    def handle_reply(self, envelope, smtp: SMTP, msg: Message) -> str:
        reply_email = envelope.rcpt_tos[0].lower()

        # reply_email must end with EMAIL_DOMAIN
        if not reply_email.endswith(EMAIL_DOMAIN):
            LOG.error(f"Reply email {reply_email} has wrong domain")
            return "550 wrong reply email"

        forward_email = ForwardEmail.get_by(reply_email=reply_email)
        alias: str = forward_email.gen_email.email
        alias_domain = alias[alias.find("@") + 1:]

        # alias must end with one of the ALIAS_DOMAINS or custom-domain
        if not email_belongs_to_alias_domains(alias):
            if not CustomDomain.get_by(domain=alias_domain):
                return "550 alias unknown by SimpleLogin"

        user_email = forward_email.gen_email.user.email
        if envelope.mail_from.lower() != user_email.lower():
            LOG.error(
                f"Reply email can only be used by user email. Actual mail_from: %s. msg from header: %s, User email %s. reply_email %s",
                envelope.mail_from,
                msg["From"],
                user_email,
                reply_email,
            )

            send_reply_alias_must_use_personal_email(
                forward_email.gen_email.user,
                forward_email.gen_email.email,
                envelope.mail_from,
            )

            send_email(
                envelope.mail_from,
                f"Your email ({envelope.mail_from}) is not allowed to send email to {reply_email}",
                "",
                "",
            )

            return "550 ignored"

        delete_header(msg, "DKIM-Signature")

        # the email comes from alias
        msg.replace_header("From", alias)

        # some email providers like ProtonMail adds automatically the Reply-To field
        # make sure to delete it
        delete_header(msg, "Reply-To")

        msg.replace_header("To", forward_email.website_email)

        # add List-Unsubscribe header
        unsubscribe_link = f"{URL}/dashboard/unsubscribe/{forward_email.gen_email_id}"
        add_or_replace_header(msg, "List-Unsubscribe", f"<{unsubscribe_link}>")
        add_or_replace_header(msg, "List-Unsubscribe-Post",
                              "List-Unsubscribe=One-Click")

        # Received-SPF is injected by postfix-policyd-spf-python can reveal user original email
        delete_header(msg, "Received-SPF")

        LOG.d(
            "send email from %s to %s, mail_options:%s,rcpt_options:%s",
            alias,
            forward_email.website_email,
            envelope.mail_options,
            envelope.rcpt_options,
        )

        if alias_domain in ALIAS_DOMAINS:
            add_dkim_signature(msg, alias_domain)
        # add DKIM-Signature for custom-domain alias
        else:
            custom_domain: CustomDomain = CustomDomain.get_by(
                domain=alias_domain)
            if custom_domain.dkim_verified:
                add_dkim_signature(msg, alias_domain)

        msg_raw = msg.as_string().encode()
        smtp.sendmail(
            alias,
            forward_email.website_email,
            msg_raw,
            envelope.mail_options,
            envelope.rcpt_options,
        )

        ForwardEmailLog.create(forward_id=forward_email.id, is_reply=True)
        db.session.commit()

        return "250 Message accepted for delivery"
示例#47
0
    def sendMessage(self,
                    From,
                    To,
                    Subj,
                    extrahdrs,
                    bodytext,
                    attaches,
                    saveMailSeparator=(('=' * 80) + 'PY\n'),
                    bodytextEncoding='us-ascii',
                    attachesEncodings=None):
        """
        format and send mail: blocks caller, thread me in a GUI;
        bodytext is main text part, attaches is list of filenames,
        extrahdrs is list of (name, value) tuples to be added;
        raises uncaught exception if send fails for any reason;
        saves sent message text in a local file if successful;

        assumes that To, Cc, Bcc hdr values are lists of 1 or more already
        decoded addresses (possibly in full name+<addr> format); client
        must parse to split these on delimiters, or use multiline input;
        note that SMTP allows full name+<addr> format in recipients;
        4E: Bcc addrs now used for send/envelope, but header is dropped;
        4E: duplicate recipients removed, else will get >1 copies of mail;
        caveat: no support for multipart/alternative mails, just /mixed;
        """

        # 4E: assume main body text is already in desired encoding;
        # clients can decode to user pick, default, or utf8 fallback;
        # either way, email needs either str xor bytes specifically;

        if fix_text_required(bodytextEncoding):
            if not isinstance(bodytext, str):
                bodytext = bodytext.decode(bodytextEncoding)
        else:
            if not isinstance(bodytext, bytes):
                bodytext = bodytext.encode(bodytextEncoding)

        # make message root
        if not attaches:
            msg = Message()
            msg.set_payload(bodytext, charset=bodytextEncoding)
        else:
            msg = MIMEMultipart()
            self.addAttachments(msg, bodytext, attaches, bodytextEncoding,
                                attachesEncodings)

        # 4E: non-ASCII hdrs encoded on sends; encode just name in address,
        # else smtp may drop the message completely; encodes all envelope
        # To names (but not addr) also, and assumes servers will allow;
        # msg.as_string retains any line breaks added by encoding headers;

        hdrenc = mailconfig.headersEncodeTo or 'utf-8'  # default=utf8
        Subj = self.encodeHeader(Subj, hdrenc)  # full header
        From = self.encodeAddrHeader(From, hdrenc)  # email names
        To = [self.encodeAddrHeader(T, hdrenc) for T in To]  # each recip
        Tos = ', '.join(To)  # hdr+envelope

        # add headers to root
        msg['From'] = From
        msg['To'] = Tos  # poss many: addr list
        msg['Subject'] = Subj  # servers reject ';' sept
        msg['Date'] = email.utils.formatdate()  # curr datetime, rfc2822 utc
        recip = To
        for name, value in extrahdrs:  # Cc, Bcc, X-Mailer, etc.
            if value:
                if name.lower() not in ['cc', 'bcc']:
                    value = self.encodeHeader(value, hdrenc)
                    msg[name] = value
                else:
                    value = [self.encodeAddrHeader(V, hdrenc) for V in value]
                    recip += value  # some servers reject ['']
                    if name.lower() != 'bcc':  # 4E: bcc gets mail, no hdr
                        msg[name] = ', '.join(value)  # add commas between cc

        recip = list(set(recip))  # 4E: remove duplicates
        fullText = msg.as_string()  # generate formatted msg

        # sendmail call raises except if all Tos failed,
        # or returns failed Tos dict for any that failed

        self.trace('Sending to...' + str(recip))
        self.trace(fullText[:self.tracesize])  # SMTP calls connect
        server = smtplib.SMTP(self.smtpServerName,
                              timeout=20)  # this may fail too
        self.getPassword()  # if srvr requires
        self.authenticateServer(server)  # login in subclass
        try:
            failed = server.sendmail(From, recip, fullText)  # except or dict
        except:
            server.close()  # 4E: quit may hang!
            raise  # reraise except
        else:
            server.quit()  # connect + send OK
        self.saveSentMessage(fullText, saveMailSeparator)  # 4E: do this first
        if failed:

            class SomeAddrsFailed(Exception):
                pass

            raise SomeAddrsFailed('Failed addrs:%s\n' % failed)
        self.trace('Send exit')
示例#48
0
    def insert(self, table, fields):
        def add_payload(message, obj):
            payload = Message()
            encoding = obj.get("encoding", "utf-8")
            if encoding and (encoding.upper() in
                             ("BASE64", "7BIT", "8BIT", "BINARY")):
                payload.add_header("Content-Transfer-Encoding", encoding)
            else:
                payload.set_charset(encoding)
            mime = obj.get("mime", None)
            if mime:
                payload.set_type(mime)
            if "text" in obj:
                payload.set_payload(obj["text"])
            elif "payload" in obj:
                payload.set_payload(obj["payload"])
            if "filename" in obj and obj["filename"]:
                payload.add_header("Content-Disposition",
                    "attachment", filename=obj["filename"])
            message.attach(payload)

        mailbox = table.mailbox
        d = dict(((k.name, v) for k, v in fields))
        date_time = d.get("created") or datetime.datetime.now()
        struct_time = date_time.timetuple()
        if len(d) > 0:
            message = d.get("email", None)
            attachments = d.get("attachments", [])
            content = d.get("content", [])
            flags = " ".join(["\\%s" % flag.capitalize() for flag in
                     ("answered", "deleted", "draft", "flagged",
                      "recent", "seen") if d.get(flag, False)])
            if not message:
                from email.message import Message
                mime = d.get("mime", None)
                charset = d.get("encoding", None)
                message = Message()
                message["from"] = d.get("sender", "")
                message["subject"] = d.get("subject", "")
                message["date"] = self.convert_date(date_time, imf=True)

                if mime:
                    message.set_type(mime)
                if charset:
                    message.set_charset(charset)
                for item in ("to", "cc", "bcc"):
                    value = d.get(item, "")
                    if isinstance(value, basestring):
                        message[item] = value
                    else:
                        message[item] = ";".join([i for i in
                            value])
                if (not message.is_multipart() and
                   (not message.get_content_type().startswith(
                        "multipart"))):
                    if isinstance(content, basestring):
                        message.set_payload(content)
                    elif len(content) > 0:
                        message.set_payload(content[0]["text"])
                else:
                    [add_payload(message, c) for c in content]
                    [add_payload(message, a) for a in attachments]
                message = message.as_string()

            result, data = self.connection.append(mailbox, flags, struct_time, message)
            if result == "OK":
                uid = int(re.findall("\d+", str(data))[-1])
                return self.db(table.uid==uid).select(table.id).first().id
            else:
                raise Exception("IMAP message append failed: %s" % data)
        else:
            raise NotImplementedError("IMAP empty insert is not implemented")
示例#49
0
#!/usr/bin/env python

import smtplib
from email.message import Message
from getpass import getpass

FROMADDR = input("LMU-Physik E-Mail-Adresse: ")
PASSWORD = getpass("MAILSERVER-Passwort: ")

LOGIN = FROMADDR.split('@')[0]
TOADDRS = FROMADDR
SUBJECT = 'Test mail with smtplib.SMTP'

msg = Message()
msg['From'] = FROMADDR
msg['To'] = TOADDRS
msg['Subject'] = SUBJECT
msg.set_payload('This is the body of the mail')
print(msg.as_string())

server = smtplib.SMTP('mail.physik.uni-muenchen.de', 587)
server.set_debuglevel(1)
server.ehlo()
server.starttls()
server.login(LOGIN, PASSWORD)
server.sendmail(FROMADDR, TOADDRS, msg.as_string())
server.quit()
示例#50
0
def sendmail(request, to, subject, text, mail_from=None):
    """ Create and send a text/plain message

    Return a tuple of success or error indicator and message.

    @param request: the request object
    @param to: recipients (list)
    @param subject: subject of email (unicode)
    @param text: email body text (unicode)
    @param mail_from: override default mail_from
    @type mail_from: unicode
    @rtype: tuple
    @return: (is_ok, Description of error or OK message)
    """
    import smtplib, socket
    from email.message import Message
    from email.charset import Charset, QP
    from email.utils import formatdate, make_msgid

    _ = request.getText
    cfg = request.cfg
    mail_from = mail_from or cfg.mail_from

    logging.debug("send mail, from: %r, subj: %r" % (mail_from, subject))
    logging.debug("send mail, to: %r" % (to, ))

    if not to:
        return (1, _("No recipients, nothing to do"))

    subject = subject.encode(config.charset)

    # Create a text/plain body using CRLF (see RFC2822)
    text = text.replace(u'\n', u'\r\n')
    text = text.encode(config.charset)

    # Create a message using config.charset and quoted printable
    # encoding, which should be supported better by mail clients.
    # TODO: check if its really works better for major mail clients
    msg = Message()
    charset = Charset(config.charset)
    charset.header_encoding = QP
    charset.body_encoding = QP
    msg.set_charset(charset)

    # work around a bug in python 2.4.3 and above:
    msg.set_payload('=')
    if msg.as_string().endswith('='):
        text = charset.body_encode(text)

    msg.set_payload(text)

    # Create message headers
    # Don't expose emails addreses of the other subscribers, instead we
    # use the same mail_from, e.g. u"Jürgen Wiki <*****@*****.**>"
    address = encodeAddress(mail_from, charset)
    msg['From'] = address
    msg['To'] = address
    msg['Date'] = formatdate()
    msg['Message-ID'] = make_msgid()
    msg['Subject'] = Header(subject, charset)
    # See RFC 3834 section 5:
    msg['Auto-Submitted'] = 'auto-generated'

    if cfg.mail_sendmail:
        # Set the BCC.  This will be stripped later by sendmail.
        msg['BCC'] = ','.join(to)
        # Set Return-Path so that it isn't set (generally incorrectly) for us.
        msg['Return-Path'] = address

    # Send the message
    if not cfg.mail_sendmail:
        try:
            logging.debug("trying to send mail (smtp) via smtp server '%s'" %
                          cfg.mail_smarthost)
            host, port = (cfg.mail_smarthost + ':25').split(':')[:2]
            server = smtplib.SMTP(host, int(port))
            try:
                #server.set_debuglevel(1)
                if cfg.mail_login:
                    user, pwd = cfg.mail_login.split()
                    try:  # try to do tls
                        server.ehlo()
                        if server.has_extn('starttls'):
                            server.starttls()
                            server.ehlo()
                            logging.debug(
                                "tls connection to smtp server established")
                    except:
                        logging.debug(
                            "could not establish a tls connection to smtp server, continuing without tls"
                        )
                    logging.debug(
                        "trying to log in to smtp server using account '%s'" %
                        user)
                    server.login(user, pwd)
                server.sendmail(mail_from, to, msg.as_string())
            finally:
                try:
                    server.quit()
                except AttributeError:
                    # in case the connection failed, SMTP has no "sock" attribute
                    pass
        except UnicodeError, e:
            logging.exception("unicode error [%r -> %r]" % (
                mail_from,
                to,
            ))
            return (0, str(e))
        except smtplib.SMTPException, e:
            logging.exception("smtp mail failed with an exception.")
            return (0, str(e))
示例#51
0
    def handle_forward(self, envelope, smtp: SMTP, msg: Message) -> str:
        """return *status_code message*"""
        alias = envelope.rcpt_tos[0].lower()  # alias@SL

        gen_email = GenEmail.get_by(email=alias)
        if not gen_email:
            LOG.d(
                "alias %s not exist. Try to see if it can be created on the fly",
                alias)

            # try to see if alias could be created on-the-fly
            on_the_fly = False

            # check if alias belongs to a directory, ie having directory/anything@EMAIL_DOMAIN format
            if email_belongs_to_alias_domains(alias):
                if "/" in alias or "+" in alias or "#" in alias:
                    if "/" in alias:
                        sep = "/"
                    elif "+" in alias:
                        sep = "+"
                    else:
                        sep = "#"

                    directory_name = alias[:alias.find(sep)]
                    LOG.d("directory_name %s", directory_name)

                    directory = Directory.get_by(name=directory_name)

                    # Only premium user can use the directory feature
                    if directory:
                        dir_user = directory.user
                        if dir_user.is_premium():
                            LOG.d("create alias %s for directory %s", alias,
                                  directory)
                            on_the_fly = True

                            gen_email = GenEmail.create(
                                email=alias,
                                user_id=directory.user_id,
                                directory_id=directory.id,
                            )
                            db.session.commit()
                        else:
                            LOG.error(
                                "User %s is not premium anymore and cannot create alias with directory",
                                dir_user,
                            )
                            send_cannot_create_directory_alias(
                                dir_user, alias, directory_name)

            # try to create alias on-the-fly with custom-domain catch-all feature
            # check if alias is custom-domain alias and if the custom-domain has catch-all enabled
            if not on_the_fly:
                alias_domain = get_email_domain_part(alias)
                custom_domain = CustomDomain.get_by(domain=alias_domain)

                # Only premium user can continue using the catch-all feature
                if custom_domain and custom_domain.catch_all:
                    domain_user = custom_domain.user
                    if domain_user.is_premium():
                        LOG.d("create alias %s for domain %s", alias,
                              custom_domain)
                        on_the_fly = True

                        gen_email = GenEmail.create(
                            email=alias,
                            user_id=custom_domain.user_id,
                            custom_domain_id=custom_domain.id,
                            automatic_creation=True,
                        )
                        db.session.commit()
                    else:
                        LOG.error(
                            "User %s is not premium anymore and cannot create alias with domain %s",
                            domain_user,
                            alias_domain,
                        )
                        send_cannot_create_domain_alias(
                            domain_user, alias, alias_domain)

            if not on_the_fly:
                LOG.d("alias %s cannot be created on-the-fly, return 510",
                      alias)
                return "510 Email not exist"

        user_email = gen_email.user.email

        website_email = get_email_part(msg["From"])

        forward_email = ForwardEmail.get_by(gen_email_id=gen_email.id,
                                            website_email=website_email)
        if forward_email:
            # update the From header if needed
            if forward_email.website_from != msg["From"]:
                LOG.d("Update From header for %s", forward_email)
                forward_email.website_from = msg["From"]
                db.session.commit()
        else:
            LOG.debug(
                "create forward email for alias %s and website email %s",
                alias,
                website_email,
            )

            # generate a reply_email, make sure it is unique
            # not use while to avoid infinite loop
            for _ in range(1000):
                reply_email = f"reply+{random_string(30)}@{EMAIL_DOMAIN}"
                if not ForwardEmail.get_by(reply_email=reply_email):
                    break

            forward_email = ForwardEmail.create(
                gen_email_id=gen_email.id,
                website_email=website_email,
                website_from=msg["From"],
                reply_email=reply_email,
            )
            db.session.commit()

        forward_log = ForwardEmailLog.create(forward_id=forward_email.id)

        if gen_email.enabled:
            # add custom header
            add_or_replace_header(msg, "X-SimpleLogin-Type", "Forward")

            # remove reply-to header if present
            delete_header(msg, "Reply-To")

            # change the from header so the sender comes from @SL
            # so it can pass DMARC check
            # replace the email part in from: header
            from_header = (
                get_email_name(msg["From"]) +
                ("" if get_email_name(msg["From"]) == "" else " - ") +
                website_email.replace("@", " at ") +
                f" <{forward_email.reply_email}>")
            msg.replace_header("From", from_header)
            LOG.d("new from header:%s", from_header)

            # add List-Unsubscribe header
            unsubscribe_link = f"{URL}/dashboard/unsubscribe/{gen_email.id}"
            add_or_replace_header(msg, "List-Unsubscribe",
                                  f"<{unsubscribe_link}>")
            add_or_replace_header(msg, "List-Unsubscribe-Post",
                                  "List-Unsubscribe=One-Click")

            add_dkim_signature(msg, EMAIL_DOMAIN)

            LOG.d(
                "Forward mail from %s to %s, mail_options %s, rcpt_options %s ",
                website_email,
                user_email,
                envelope.mail_options,
                envelope.rcpt_options,
            )

            # smtp.send_message has UnicodeEncodeErroremail issue
            # encode message raw directly instead
            msg_raw = msg.as_string().encode()
            smtp.sendmail(
                forward_email.reply_email,
                user_email,
                msg_raw,
                envelope.mail_options,
                envelope.rcpt_options,
            )
        else:
            LOG.d("%s is disabled, do not forward", gen_email)
            forward_log.blocked = True

        db.session.commit()
        return "250 Message accepted for delivery"