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, ["*****@*****.**"])
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(), '*****@*****.**')
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])
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(), "*****@*****.**" )
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()
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()
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)
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)
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 "发送完毕,请到邮箱中查看抓取信息..."
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()
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, ['*****@*****.**'])
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
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()
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()
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()
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
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()
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(), "*****@*****.**" )
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()
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(), '*****@*****.**')
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')
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())
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()
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()
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
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)
# 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)
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)
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')
#!/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())
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')
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()
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()
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.")
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()
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")
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
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"
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')
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")
#!/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()
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))
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"