def email_results(msg_body): from_address = "*****@*****.**" recipients = ['*****@*****.**', '*****@*****.**'] to_address = ", ".join(recipients) msg = MIMEMultipart() msg['From'] = from_address msg['To'] = to_address msg['Subject'] = "FundBot" msg.attach(MIMEText(msg_body, 'plain')) for filename in os.listdir(os.path.join("plots")): if filename.endswith(".png"): attachment = open(os.path.join("plots", filename), "rb") part = MIMEBase('application', 'octet-stream') part.set_payload(attachment.read()) encoders.encode_base64(part) part.add_header('Content-Disposition', "attachment; filename= %s" % filename) msg.attach(part) server = smtplib.SMTP('smtp.gmail.com', 587) server.starttls() server.login(from_address, "123456789") text = msg.as_string() server.sendmail(from_address, to_address, text) server.quit()
def send_message(self, dest_email, message_text, file=None): """Метод, который отправляет сообщение по заданному адресу, с заданным содержимым. Возможно добавить файл. :param dest_email: Адрес доставки сообщения :param message_text: Текст сообщения :param file: Путь к файлу :return: """ msg = MIMEMultipart() msg['Subject'] = self.subject msg['From'] = self.from_name msg['To'] = ', '.join(dest_email) msg.attach(MIMEText(message_text)) if file: part = MIMEBase.MIMEBase('application', 'octet-stream') part.set_payload(open(file, 'rb').read()) Encoders.encode_base64(part) part.add_header('Content-Disposition', 'attachment; filename="{}"'.format(file)) msg.attach(part) server = smtp.SMTP_SSL(self.server) server.ehlo() server.login(self.mail, self.password) server.sendmail(self.mail, dest_email, msg.as_string())
def send_manga_throw_email(self, title, number): """ This function sends an email using Gmail SMTP Server to the kindle cloud with the comic attached into it. Keyword arguments: title - The title of the manga number - The chapter number of the manga """ msg = MIMEMultipart.MIMEMultipart() msg['from'] = "*****@*****.**" msg['To'] = "*****@*****.**" msg['Date'] = Utils.formatdate(localtime=True) msg['Subject'] = '' msg.attach(MIMEText.MIMEText('')) part = MIMEBase.MIMEBase('application', "octet-stream") filename = title + "_" + str(number) + ".mobi" part.set_payload(open(filename, "rb").read()) Encoders.encode_base64(part) part.add_header('Content-Disposition', 'attachment', filename=filename) msg.attach(part) smtp = smtplib.SMTP("smtp.gmail.com", 587) smtp.ehlo() smtp.starttls() smtp.login("*****@*****.**", "xxxpasswordxxx") smtp.sendmail("*****@*****.**", "*****@*****.**", msg.as_string()) smtp.close()
def mail_message_to_mime_message(protocol_message): """Generate a MIMEMultitype message from protocol buffer. Generates a complete MIME multi-part email object from a MailMessage protocol buffer. The body fields are sent as individual alternatives if they are both present, otherwise, only one body part is sent. Multiple entry email fields such as 'To', 'Cc' and 'Bcc' are converted to a list of comma separated email addresses. Args: protocol_message: Message PB to convert to MIMEMultitype. Returns: MIMEMultitype representing the provided MailMessage. Raises: InvalidAttachmentTypeError when the file name of an attachment """ parts = [] if protocol_message.has_textbody(): parts.append(MIMEText.MIMEText(protocol_message.textbody())) if protocol_message.has_htmlbody(): parts.append(MIMEText.MIMEText(protocol_message.htmlbody(), _subtype='html')) if len(parts) == 1: payload = parts else: payload = [MIMEMultipart.MIMEMultipart('alternative', _subparts=parts)] result = MIMEMultipart.MIMEMultipart(_subparts=payload) for attachment in protocol_message.attachment_list(): file_name = attachment.filename() mime_type = _GetMimeType(file_name) maintype, subtype = mime_type.split('/') mime_attachment = MIMEBase.MIMEBase(maintype, subtype) mime_attachment.add_header('Content-Disposition', 'attachment', filename=attachment.filename()) mime_attachment.set_payload(attachment.data()) result.attach(mime_attachment) if protocol_message.to_size(): result['To'] = ', '.join(protocol_message.to_list()) if protocol_message.cc_size(): result['Cc'] = ', '.join(protocol_message.cc_list()) if protocol_message.bcc_size(): result['Bcc'] = ', '.join(protocol_message.bcc_list()) result['From'] = protocol_message.sender() result['Reply-To'] = protocol_message.replyto() result['Subject'] = protocol_message.subject() return result
def add_attachment(self, message, attachment): if not attachment: return False binary_blob = MIMEBase.MIMEBase('application', 'octet-stream') binary_blob.set_payload(FileOperations.open(attachment, 'rb').read()) Encoders.encode_base64(binary_blob) # base64 encode the Binary Blob. # Binary Blob headers. binary_blob.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(attachment)) message.attach(binary_blob) return True
def AddAttachment(self, Message, Attachment): if not Attachment: return False BinaryBlob = MIMEBase.MIMEBase('application', 'octet-stream') BinaryBlob.set_payload(open(Attachment, 'rb').read()) Encoders.encode_base64(BinaryBlob) # base64 encode the Binary Blob BinaryBlob.add_header( 'Content-Disposition', 'attachment; filename="%s"' % os.path.basename(Attachment)) # Binary Blob headers Message.attach(BinaryBlob) return True
def _generate_non_pgp_mime_email(self, signer, email, keyid, filename): '''Send the encrypted uid off to the user.''' msg = MIMEMultipart.MIMEMultipart() msg.epilogue = '' part = MIMEText.MIMEText(self._get_email_body(signer, keyid, email)) msg.attach(part) part = MIMEBase.MIMEBase('application', 'octet-stream') part.add_header('Content-Disposition', 'inline; filename="%s"' % os.path.basename(filename)) part.set_payload(open(filename, 'r').read()) msg.attach(part) return msg
def send_mail(fromaddr, toaddr, subject, mail_body, send_mail_server, ps, send_mail_port=587, send_file_name_as=None, send_file_path=None): """ simple send mail with body and attachment :param fromaddr: str|sender email address :param toaddr: dict of list of str| list of receiver email address :param subject: str| subject of email :param mail_body: str|email body :param send_mail_server: str| :param ps: str| password :param send_mail_port: int| :param send_file_name_as: str|filename of the attachment :param send_file_path: str|path to the attachment """ msg = MIMEMultipart.MIMEMultipart() msg['From'] = fromaddr msg['To'] = ", ".join(toaddr["To"]) msg['CC'] = ", ".join(toaddr["CC"]) msg['BCC'] = ", ".join(toaddr["BCC"]) msg['Subject'] = subject msg.attach(MIMEText.MIMEText(mail_body, 'plain')) if send_file_name_as and send_file_path: attachment = open(send_file_path, "rb") part = MIMEBase.MIMEBase('application', 'octet-stream') part.set_payload(attachment.read()) encoders.encode_base64(part) part.add_header('Content-Disposition', "attachment; filename= %s" % send_file_name_as) msg.attach(part) server = smtplib.SMTP(send_mail_server, send_mail_port) server.starttls() server.login(fromaddr, ps) text = msg.as_string() for k in toaddr: if toaddr[k]: server.sendmail(fromaddr, toaddr[k], text) server.quit()
def _sendPageToEmailAddress(self, pageData, query, destAddress): pageUrl, pageContents = pageData msg = MIMEMultipart.MIMEMultipart() msg['From'] = self.address msg['To'] = destAddress msg['Subject'] = "First Google result for '%s'" % query body = MIMEText.MIMEText("The first Google result for '%s' is:\n\n%s" % (query, pageUrl)) # create a text/html attachment with the page data attachment = MIMEBase.MIMEBase("text", "html") attachment['Content-Location'] = pageUrl attachment.set_payload(pageContents) msg.attach(body) msg.attach(attachment) return smtp.sendmail(self.upstreamServer, self.address, destAddress, msg)
def send_mail(self, file_list, title="Python邮件", txt="邮件内容(空)", to_mail='*****@*****.**'): print u'准备发送邮件给%s' % to_mail from_addr = '*****@*****.**' password = '******' to_addr = to_mail smtp_server = 'smtp.aliyun.com' msg = MIMEMultipart.MIMEMultipart() msg['From'] = self._format_addr(from_addr) msg['To'] = self._format_addr(to_addr) msg['Subject'] = Header(title, 'utf-8').encode() # 邮件正文是MIMEText: msg.attach(MIMEText(txt, 'plain', 'utf-8')) if file_list: for file_name in file_list: with open(file_name, 'rb') as f: # 设置附件的MIME和文件名,这里是png类型: mime = MIMEBase.MIMEBase('NEW', 'csv', filename=file_name) # 加上必要的头信息: mime.add_header('Content-Disposition', 'attachment', filename=file_name) mime.add_header('Content-ID', '<0>') mime.add_header('X-Attachment-Id', '0') # 把附件的内容读进来: mime.set_payload(f.read()) # 用Base64编码: encoders.encode_base64(mime) # 添加到MIMEMultipart: msg.attach(mime) #server = smtplib.SMTP(smtp_server, 25) server = smtplib.SMTP_SSL(smtp_server, 465) server.set_debuglevel(1) server.ehlo() server.login(from_addr, password) server.sendmail(from_addr, [to_addr], msg.as_string()) server.quit() print u'邮件发送成功'
def sendmail(smtpServer, username, passwd, toMail, subject, msg, file_name): server = smtplib.SMTP('smtp.126.com') server.login(username, passwd) main_msg = MIMEMultipart.MIMEMultipart() # 构造MIMEText对象做为邮件显示内容并附加到根容器 text_msg = MIMEText.MIMEText(msg, 'plain', "utf-8") main_msg.attach(text_msg) # 构造MIMEBase对象做为文件附件内容并附加到根容器 contype = 'application/octet-stream' maintype, subtype = contype.split('/', 1) ## 读入文件内容并格式化 if file_name != None: data = open(file_name, 'rb') file_msg = MIMEBase.MIMEBase(maintype, subtype) file_msg.set_payload(data.read()) data.close() Encoders.encode_base64(file_msg) ## 设置附件头 basename = os.path.basename(file_name) file_msg.add_header('Content-Disposition', 'attachment', filename=basename) main_msg.attach(file_msg) # 设置根容器属性 main_msg['From'] = username main_msg['To'] = "*****@*****.**" # main_msg['Subject'] = "[sxtwl]打包结果通知" main_msg['Date'] = formatdate() #带上python版本的信息 main_msg['Subject'] = subject # 得到格式化后的完整文本 fullText = main_msg.as_string() # 用smtp发送邮件 try: server.sendmail(main_msg['From'], main_msg['To'], fullText) finally: server.quit()
def send_failed_mail_necessary(plan, app, device, node): file_name = device.logPath + '/' + 'errorLog' + str( device.failedTime) + '.txt' me = "AUICrawler" + "<" + Setting.Mail_User + ">" main_msg = MIMEMultipart.MIMEMultipart() text = device.crawlStatue + " again in " + str(device.id) + ' when crawl ' + str( app.appName) + ' , please check the screenshot and the logcat file in attachment . \n' + \ ' Crawl this node is necessary to make app ' + device.crawlStatue + '. \n\n' msg = MIMEText(text + plan.resultHtml, _subtype='html', _charset='utf-8') main_msg.attach(msg) resource_id = node.resource_id resource_id = resource_id[resource_id.find('/') + 1:] screen = device.screenshotPath + '/' + str( device.saveScreenNum - 1) + '-' + str( node.currentActivity) + '-' + str(resource_id) + '-' + str( node.location[0]) + '-' + str(node.location[1]) + '.png' if os.path.exists(screen): fp = open(screen, 'rb') msgImage = MIMEImage(fp.read()) fp.close() msgImage.add_header('Content-Disposition', 'attachment', filename=os.path.basename("screenShot")) main_msg.attach(msgImage) data = open(file_name, 'rb') ctype, encoding = mimetypes.guess_type(file_name) if ctype is None or encoding is not None: ctype = 'application/octet-stream' maintype, subtype = ctype.split('/', 1) file_msg = MIMEBase.MIMEBase(maintype, subtype) file_msg.set_payload(data.read()) data.close() Encoders.encode_base64(file_msg) # 把附件编码 file_msg.add_header('Content-Disposition', 'attachment', filename=os.path.basename("log.txt")) # 修改邮件头 main_msg.attach(file_msg) # 设置根容器属性 main_msg['From'] = me main_msg['To'] = ";".join(Setting.Failed_Mail_To_List) main_msg['Subject'] = u"自动遍历测试 - 复现异常啦,此处应该有掌声!!!!" main_msg['Date'] = Utils.formatdate()
def send_failed_mail_first(plan, app, device): file_name = device.logPath + '/' + 'errorLog' + str( device.failedTime) + '.txt' me = "AUICrawler" + "<" + Setting.Mail_User + ">" main_msg = MIMEMultipart.MIMEMultipart() text = device.crawlStatue + " in " + str(device.id) + ' when crawl ' + str( app.appName) + ' , please check the logcat file in attachment . \n' + \ ' I will reCrawl this node again for check is necessary ' + device.crawlStatue + ' or not . \n\n' msg = MIMEText(text + plan.resultHtml, _subtype='html', _charset='utf-8') main_msg.attach(msg) data = open(file_name, 'rb') ctype, encoding = mimetypes.guess_type(file_name) if ctype is None or encoding is not None: ctype = 'application/octet-stream' maintype, subtype = ctype.split('/', 1) file_msg = MIMEBase.MIMEBase(maintype, subtype) file_msg.set_payload(data.read()) data.close() Encoders.encode_base64(file_msg) # 把附件编码 basename = os.path.basename("log.txt") file_msg.add_header('Content-Disposition', 'attachment', filename=basename) # 修改邮件头 main_msg.attach(file_msg) # 设置根容器属性 main_msg['From'] = me main_msg['To'] = ";".join(Setting.Failed_Mail_To_List) main_msg['Subject'] = u"自动遍历测试发现异常啦!!!快看我!!!" main_msg['Date'] = Utils.formatdate() try: s = smtplib.SMTP() s.connect(Setting.SMTP_HOST) s.login(Setting.Mail_User, Setting.Mail_Pass) s.sendmail(me, Setting.Failed_Mail_To_List, main_msg.as_string()) s.close() return True except Exception as e: print(str(e)) return False
def send_email_attachment(filename): msg = MIMEMultipart() file_content = open(filename, "rb").read() part = MIMEBase("application", "octet-stream") part.set_payload(file_content) Encoders.encode_base64(part) today = datetime.now().strftime('%Y-%m-%d') part.add_header("Content-Disposition", "attachment; filename=content-%s.csv" % today) msg.attach(part) msg['Subject'] = "PI | Automation Framework - [%s]" % today msg['From'] = sender msg['To'] = rcvr try: smtpObj = smtplib.SMTP('localhost') smtpObj.sendmail(sender, rcvr, msg.as_string()) smtpObj.close() except smtplib.SMTPException: print "Failed to send email"
def send_files_to_email(fromaddr=config.email_from_addr, toaddr=config.email_to_addr, frompassword=config.email_from_password, path_to_dir=config.gif_dir_random, count_of_files=10, delele_files=False): attachment_size = 0 # создаем почтовое сообщение msg = MIMEMultipart.MIMEMultipart() # заполняем поля отправителя, адресата и тему сообщения msg['From'] = fromaddr msg['To'] = toaddr msg['Subject'] = 'gifs ' + time.asctime() # текстовая часть сообщения (не забываем указать кодировку) msg.attach(MIMEText.MIMEText("свежая порция гифочек", "plain", "utf-8")) for i in range(count_of_files): file_to_send = choose_random_file_from_dir_on_hdd(path_to_dir) attachment_size += os.stat(file_to_send).st_size if attachment_size > 1.05 * config.email_limit: break # прикрепляем файл backup.tar.gz к почтовому сообщению att = MIMEBase.MIMEBase('application', 'octet-stream') att.set_payload(open(file_to_send, "rb").read()) Encoders.encode_base64(att) att.add_header('Content-Disposition', 'attachment; filename="' + file_to_send + '"') msg.attach(att) os.remove(file_to_send) # соединяемся с почтовым сервером и выполняем авторизацию server = SMTP('smtp.mail.ru', 25) server.ehlo() server.starttls() server.ehlo() server.login(fromaddr, frompassword) # отправляем сформированное сообщение, после чего выходим server.sendmail(fromaddr, toaddr, msg.as_string()) server.quit()
def _fileItemToEmailPart(fileItem): """ Convert a L{File} item into an appropriate MIME part object understandable by the stdlib's C{email} package """ (majorType, minorType) = fileItem.type.split('/') if majorType == 'multipart': part = P.Parser().parse(fileItem.body.open()) else: part = MB.MIMEBase(majorType, minorType) if majorType == 'message': part.set_payload([P.Parser().parse(fileItem.body.open())]) else: part.set_payload(fileItem.body.getContent()) if majorType == 'text': EE.encode_quopri(part) else: EE.encode_base64(part) part.add_header('content-disposition', 'attachment', filename=fileItem.name) return part
def mime_new(fname, data, mimetype, charset): import mimetypes from email import Charset, Encoders from email import MIMEBase, MIMEText, MIMEImage, MIMEAudio # Try to guess the mimetype. if not mimetype: (mimetype, _) = mimetypes.guess_type(fname) if not mimetype: mimetype = 'text/plain' (maintype, subtype) = mimetype.split('/') # Create a MIME object. if maintype == 'text': # Text # Try to determine the character encoding. charset = charset or config.TERMINAL_CHARSET # Re-encode the data in a specified encoding. csmap = Charset.Charset(charset) try: if csmap.input_codec: data = unicode(data, str(csmap.input_codec), 'replace') if csmap.output_codec: data = data.encode(str(csmap.output_codec), 'replace') charset = str(csmap.output_charset) except UnicodeError: raise EncodingError('Cannot encode with %s' % charset) obj = MIMEText.MIMEText(data, subtype, charset) elif maintype == 'image': # Image obj = MIMEImage.MIMEImage(data, subtype) elif maintype == 'audio': # Audio obj = MIMEAudio.MIMEAudio(data, subtype) else: # Other obj = MIMEBase.MIMEBase(maintype, subtype) obj.set_payload(data) Encoders.encode_base64(obj) # Attach the MIME object to the original Message. obj.add_header('Content-Disposition', 'attachment', filename=fname) return obj
def send_email(self, email_to, email_from, subject, body, attachment_path=None): msg = MIMEMultipart() msg['From'] = email_from msg['To'] = email_to msg['Subject'] = subject msg.attach(MIMEText(body, 'plain')) if attachment_path: part = MIMEBase('application', 'octet-stream') part.set_payload(attachment_path.read()) encoders.encode_base64(part) part.add_header('Content-Disposition', "attachment; filename= %s" % attachment_path) msg.attach(part) server = smtplib.SMTP(self.smtp_server, self.smtp_port) server.sendmail(email_from, email_to, msg.as_string()) server.quit()
def _get_email_attach_rar(self): """ 获取到zip的msg对象 :return: zip的msg对象 """ data = open(self.attach_file_name_zip, 'rb') ctype, encoding = mimetypes.guess_type(self.attach_file_name_zip) if ctype is None or encoding is not None: ctype = 'application/octet-stream' maintype, subtype = ctype.split('/', 1) file_msg = MIMEBase.MIMEBase(maintype, subtype) file_msg.set_payload(data.read()) data.close() # 把附件编码 Encoders.encode_base64(file_msg) ## 设置附件头 basename = os.path.basename(self.attach_file_name_zip) file_msg.add_header('Content-Disposition', 'attachment', filename=basename) # 修改邮件头 return file_msg
each['shuiwei_delta_flag'].decode('unicode-escape').encode( 'utf-8'), '流量(立方米/秒)': each['liuliang'], '警戒水位(米)': each['jingjieshuiwei'], }) main_msg = MIMEMultipart.MIMEMultipart() file_name = 'dajiangdahe.csv' data = open(file_name, 'rb') ctype, encoding = mimetypes.guess_type(file_name) if ctype is None or encoding is not None: ctype = 'application/octet-stream' maintype, subtype = ctype.split('/', 1) file_msg = MIMEBase.MIMEBase(maintype, subtype) file_msg.set_payload(data.read()) data.close() email.Encoders.encode_base64(file_msg) # 把附件编码 basename = os.path.basename(file_name) file_msg.add_header('Content-Disposition', 'attachment', filename=basename) # 修改邮件头 main_msg.attach(file_msg) print '------1111-1--1-1-1-----' main_msg['From'] = '*****@*****.**' main_msg['To'] = '*****@*****.**' main_msg['Subject'] = Header(u'大江大河报告({})'.format( time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(unix_time)))) fullText = main_msg.as_string() print '------2222--------' print fullText
message = MIMEMultipart() message["From"] = sender_email message["To"] = receiver_email message["Subject"] = Betreff message["Bcc"] = receiver_email # Recommended for mass emails # Add body to email message.attach(MIMEText(Inhalt, "plain")) filename = "/home/pi/NAS/error.log" # In same directory as script # Open PDF file in binary mode with open(filename, "rb") as attachment: #Add file as application/octet-stream # Email client can usually download this automatically as attachment part = MIMEBase("application", "octet-stream") part.set_payload(attachment.read()) # Encode file in ASCII characters to send by email encoders.encode_base64(part) # Add header as key/value pair to attachment part part.add_header("Content-Disposition", "attachment; filename=logfile.txt",) # Add attachment to message and convert message to string message.attach(part) text = message.as_string() # Log in to server using secure context and send email context = ssl.create_default_context()
def mail_message_to_mime_message(protocol_message): """Generates a `MIMEMultipart` message from a `MailMessage` protocol buffer. This function generates a complete `MIMEMultipart` email object from a `MailMessage` protocol buffer. The body fields are sent as individual alternatives if they are both present; otherwise, only one body part is sent. Multiple entry email fields, such as 'To', 'Cc', and 'Bcc' are converted to a list of comma-separated email addresses. Args: protocol_message: Message protocol buffer to convert to a `MIMEMultipart` message. Returns: A `MIMEMultipart` message that represents the provided `MailMessage`. Raises: InvalidAttachmentTypeError: If the file type of the attachment is invalid. """ parts = [] if protocol_message.has_textbody(): parts.append( MIMEText.MIMEText(protocol_message.textbody(), _charset=_GuessCharset( protocol_message.textbody()))) if protocol_message.has_htmlbody(): parts.append( MIMEText.MIMEText(protocol_message.htmlbody(), _subtype='html', _charset=_GuessCharset( protocol_message.htmlbody()))) if protocol_message.has_amphtmlbody(): parts.append( MIMEText.MIMEText(protocol_message.amphtmlbody(), _subtype='x-amp-html', _charset=_GuessCharset( protocol_message.amphtmlbody()))) if len(parts) == 1: payload = parts else: payload = [MIMEMultipart.MIMEMultipart('alternative', _subparts=parts)] result = MIMEMultipart.MIMEMultipart(_subparts=payload) for attachment in protocol_message.attachment_list(): file_name = attachment.filename() mime_type = _GetMimeType(file_name) maintype, subtype = mime_type.split('/') mime_attachment = MIMEBase.MIMEBase(maintype, subtype) mime_attachment.add_header('Content-Disposition', 'attachment', filename=attachment.filename()) mime_attachment.set_payload(attachment.data()) if attachment.has_contentid(): mime_attachment['content-id'] = attachment.contentid() result.attach(mime_attachment) if protocol_message.to_size(): result['To'] = _I18nHeader(', '.join(protocol_message.to_list())) if protocol_message.cc_size(): result['Cc'] = _I18nHeader(', '.join(protocol_message.cc_list())) if protocol_message.bcc_size(): result['Bcc'] = _I18nHeader(', '.join(protocol_message.bcc_list())) result['From'] = _I18nHeader(protocol_message.sender()) result['Reply-To'] = _I18nHeader(protocol_message.replyto()) result['Subject'] = _I18nHeader(protocol_message.subject()) for header in protocol_message.header_list(): result[header.name()] = _I18nHeader(header.value()) return result
def send_email(msg_text, attachment_flag): fromaddr = "*****@*****.**" toaddrs = "*****@*****.**" subject = "SmartHome App问题反馈" smtpserver = 'smtp.163.com' username = '******' password = '******' # 构造MIMEMultipart对象做为根容器 msg = MIMEMultipart.MIMEMultipart() # 构造MIMEText对象做为邮件显示内容并附加到根容器 text_msg = MIMEText.MIMEText(msg_text, 'plain', 'utf-8') msg.attach(text_msg) if attachment_flag: #带有附件 # 构造MIMEBase对象做为文件附件内容并附加到根容器 contype = 'application/octet-stream' maintype, subtype = contype.split('/', 1) app_path = "" if getattr(sys, 'frozen', False): app_path = os.path.dirname( sys.executable) #sys.executable:python.exe所在目录 else: app_path = os.path.abspath('.') file = "temp" log_filepath = os.path.join(app_path, file) log_files = os.listdir(log_filepath) for file in log_files: file_name = os.path.join(log_filepath, file) ## 读入文件内容并格式化 data = open(file_name, 'rb') file_msg = MIMEBase.MIMEBase(maintype, subtype) file_msg.set_payload(data.read()) data.close() email.Encoders.encode_base64(file_msg) ## 设置附件头 basename = os.path.basename(file_name) file_msg.add_header('Content-Disposition', 'attachment', filename=basename) msg.attach(file_msg) # else: #没有附件 # msg=email.mime.text.MIMEText(msg_text,'plain','utf-8')#中文需参数‘utf-8’,单字节字符不需要 # 设置根容器属性 msg['Subject'] = Header(subject, 'utf-8') msg['From'] = '用户<*****@*****.**>' msg['To'] = '*****@*****.**' msg['Date'] = email.Utils.formatdate() # 用smtp发送邮件 smtp = smtplib.SMTP() flag = True try: smtp.connect(smtpserver) smtp.login(username, password) smtp.sendmail(fromaddr, toaddrs, msg.as_string()) flag = True except Exception as e: # print(e.message) flag = False smtp.quit() finally: return flag
def send(self, to, subject='None', message='None', attachments=None, cc=None, bcc=None, reply_to=None, encoding='utf-8', raw=False, headers={}): """ Sends an email using data specified in constructor Arguments: to: list or tuple of receiver addresses; will also accept single object subject: subject of the email message: email body text; depends on type of passed object: if 2-list or 2-tuple is passed: first element will be source of plain text while second of html text; otherwise: object will be the only source of plain text and html source will be set to None; If text or html source is: None: content part will be ignored, string: content part will be set to it, file-like object: content part will be fetched from it using it's read() method attachments: list or tuple of Mail.Attachment objects; will also accept single object cc: list or tuple of carbon copy receiver addresses; will also accept single object bcc: list or tuple of blind carbon copy receiver addresses; will also accept single object reply_to: address to which reply should be composed encoding: encoding of all strings passed to this method (including message bodies) headers: dictionary of headers to refine the headers just before sending mail, e.g. {'Return-Path' : '*****@*****.**'} Examples: #Send plain text message to single address: mail.send('*****@*****.**', 'Message subject', 'Plain text body of the message') #Send html message to single address: mail.send('*****@*****.**', 'Message subject', '<html>Plain text body of the message</html>') #Send text and html message to three addresses (two in cc): mail.send('*****@*****.**', 'Message subject', ('Plain text body', '<html>html body</html>'), cc=['*****@*****.**', '*****@*****.**']) #Send html only message with image attachment available from the message by 'photo' content id: mail.send('*****@*****.**', 'Message subject', (None, '<html><img src="cid:photo" /></html>'), Mail.Attachment('/path/to/photo.jpg' content_id='photo')) #Send email with two attachments and no body text mail.send('[email protected], 'Message subject', None, [Mail.Attachment('/path/to/fist.file'), Mail.Attachment('/path/to/second.file')]) Returns True on success, False on failure. Before return, method updates two object's fields: self.result: return value of smtplib.SMTP.sendmail() or GAE's mail.send_mail() method self.error: Exception message or None if above was successful """ def encode_header(key): if [c for c in key if 32 > ord(c) or ord(c) > 127]: return Header.Header(key.encode('utf-8'), 'utf-8') else: return key # encoded or raw text def encoded_or_raw(text): if raw: text = encode_header(text) return text if not isinstance(self.server, str): raise Exception('Server address not specified') if not isinstance(self.sender, str): raise Exception('Sender address not specified') if not raw: payload_in = MIMEMultipart.MIMEMultipart('mixed') else: # no encoding configuration for raw messages if isinstance(message, basestring): text = message.decode(encoding).encode('utf-8') else: text = message.read().decode(encoding).encode('utf-8') # No charset passed to avoid transport encoding # NOTE: some unicode encoded strings will produce # unreadable mail contents. payload_in = MIMEText.MIMEText(text) if to: if not isinstance(to, (list, tuple)): to = [to] else: raise Exception('Target receiver address not specified') if cc: if not isinstance(cc, (list, tuple)): cc = [cc] if bcc: if not isinstance(bcc, (list, tuple)): bcc = [bcc] if message is None: text = html = None elif isinstance(message, (list, tuple)): text, html = message elif message.strip().startswith('<html') and message.strip().endswith( '</html>'): text = self.server == 'gae' and message or None html = message else: text = message html = None if (not text is None or not html is None) and (not raw): attachment = MIMEMultipart.MIMEMultipart('alternative') if not text is None: if isinstance(text, basestring): text = text.decode(encoding).encode('utf-8') else: text = text.read().decode(encoding).encode('utf-8') attachment.attach(MIMEText.MIMEText(text, _charset='utf-8')) if not html is None: if isinstance(html, basestring): html = html.decode(encoding).encode('utf-8') else: html = html.read().decode(encoding).encode('utf-8') attachment.attach( MIMEText.MIMEText(html, 'html', _charset='utf-8')) payload_in.attach(attachment) if (attachments is None) or raw: pass elif isinstance(attachments, (list, tuple)): for attachment in attachments: payload_in.attach(attachment) else: payload_in.attach(attachments) ####################################################### # CIPHER # ####################################################### cipher_type = self.cipher_type sign = self.sign sign_passphrase = self.sign_passphrase encrypt = self.encrypt ####################################################### # GPGME # ####################################################### if cipher_type == 'gpg': if self.gpg_home: # Set GNUPGHOME environment variable to set home of gnupg import os os.environ['GNUPGHOME'] = self.gpg_home if not sign and not encrypt: self.error = "No sign and no encrypt is set but cipher type to gpg" return False # need a python-pyme package and gpgme lib from pyme import core, errors from pyme.constants.sig import mode ############################################ # sign # ############################################ if sign: import string core.check_version(None) pin = string.replace(payload_in.as_string(), '\n', '\r\n') plain = core.Data(pin) sig = core.Data() c = core.Context() c.set_armor(1) c.signers_clear() # search for signing key for From: for sigkey in c.op_keylist_all(self.sender, 1): if sigkey.can_sign: c.signers_add(sigkey) if not c.signers_enum(0): self.error = 'No key for signing [%s]' % self.sender return False c.set_passphrase_cb(lambda x, y, z: sign_passphrase) try: # make a signature c.op_sign(plain, sig, mode.DETACH) sig.seek(0, 0) # make it part of the email payload = MIMEMultipart.MIMEMultipart( 'signed', boundary=None, _subparts=None, **dict(micalg="pgp-sha1", protocol="application/pgp-signature")) # insert the origin payload payload.attach(payload_in) # insert the detached signature p = MIMEBase.MIMEBase("application", 'pgp-signature') p.set_payload(sig.read()) payload.attach(p) # it's just a trick to handle the no encryption case payload_in = payload except errors.GPGMEError: self.error = "GPG error: %s" return False ############################################ # encrypt # ############################################ if encrypt: core.check_version(None) plain = core.Data(payload_in.as_string()) cipher = core.Data() c = core.Context() c.set_armor(1) # collect the public keys for encryption recipients = [] rec = to[:] if cc: rec.extend(cc) if bcc: rec.extend(bcc) for addr in rec: c.op_keylist_start(addr, 0) r = c.op_keylist_next() if r is None: self.error = 'No key for [%s]' % addr return False recipients.append(r) try: # make the encryption c.op_encrypt(recipients, 1, plain, cipher) cipher.seek(0, 0) # make it a part of the email payload = MIMEMultipart.MIMEMultipart( 'encrypted', boundary=None, _subparts=None, **dict(protocol="application/pgp-encrypted")) p = MIMEBase.MIMEBase("application", 'pgp-encrypted') p.set_payload("Version: 1\r\n") payload.attach(p) p = MIMEBase.MIMEBase("application", 'octet-stream') p.set_payload(cipher.read()) payload.attach(p) except errors.GPGMEError: self.error = "GPG error: %s" return False ####################################################### # X.509 # ####################################################### elif cipher_type == 'x509': if not sign and not encrypt: self.error = "No sign and no encrypt is set but cipher type to x509" return False x509_sign_keyfile = self.x509_sign_keyfile if self.x509_sign_certfile: x509_sign_certfile = self.x509_sign_certfile else: # if there is no sign certfile we'll assume the # cert is in keyfile x509_sign_certfile = self.x509_sign_keyfile # crypt certfiles could be a string or a list x509_crypt_certfiles = self.x509_crypt_certfiles x509_nocerts = self.x509_nocerts # need m2crypto try: from M2Crypto import BIO, SMIME, X509 except Exception: self.error = "Can't load M2Crypto module" return False msg_bio = BIO.MemoryBuffer(payload_in.as_string()) s = SMIME.SMIME() # SIGN if sign: #key for signing try: s.load_key(x509_sign_keyfile, x509_sign_certfile, callback=lambda x: sign_passphrase) except Exception: self.error = "Something went wrong on certificate / private key loading: <%s>" % str( e) return False try: if x509_nocerts: flags = SMIME.PKCS7_NOCERTS else: flags = 0 if not encrypt: flags += SMIME.PKCS7_DETACHED p7 = s.sign(msg_bio, flags=flags) msg_bio = BIO.MemoryBuffer(payload_in.as_string( )) # Recreate coz sign() has consumed it. except Exception: self.error = "Something went wrong on signing: <%s> %s" return False # ENCRYPT if encrypt: try: sk = X509.X509_Stack() if not isinstance(x509_crypt_certfiles, (list, tuple)): x509_crypt_certfiles = [x509_crypt_certfiles] # make an encryption cert's stack for x in x509_crypt_certfiles: sk.push(X509.load_cert(x)) s.set_x509_stack(sk) s.set_cipher(SMIME.Cipher('des_ede3_cbc')) tmp_bio = BIO.MemoryBuffer() if sign: s.write(tmp_bio, p7) else: tmp_bio.write(payload_in.as_string()) p7 = s.encrypt(tmp_bio) except Exception: self.error = "Something went wrong on encrypting: <%s>" return False # Final stage in sign and encryption out = BIO.MemoryBuffer() if encrypt: s.write(out, p7) else: if sign: s.write(out, p7, msg_bio, SMIME.PKCS7_DETACHED) else: out.write('\r\n') out.write(payload_in.as_string()) out.close() st = str(out.read()) payload = message_from_string(st) else: # no cryptography process as usual payload = payload_in payload['From'] = encoded_or_raw(self.sender.decode(encoding)) origTo = to[:] if to: payload['To'] = encoded_or_raw(', '.join(to).decode(encoding)) if reply_to: payload['Reply-To'] = encoded_or_raw(reply_to.decode(encoding)) if cc: payload['Cc'] = encoded_or_raw(', '.join(cc).decode(encoding)) to.extend(cc) if bcc: to.extend(bcc) payload['Subject'] = encoded_or_raw(subject.decode(encoding)) payload['Date'] = time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime()) for k, v in headers.iteritems(): payload[k] = encoded_or_raw(v.decode(encoding)) result = {} try: if self.server == 'logging': logger.warn('email not sent\n%s\nFrom: %s\nTo: %s\nSubject: %s\n\n%s\n%s\n' % \ ('-'*40,self.sender, ', '.join(to),subject, text or html,'-'*40)) elif self.server == 'gae': xcc = dict() if cc: xcc['cc'] = cc if bcc: xcc['bcc'] = bcc if reply_to: xcc['reply_to'] = reply_to from google.appengine.api import mail attachments = attachments and [(a.my_filename, a.my_payload) for a in attachments if not raw] if attachments: result = mail.send_mail(sender=self.sender, to=origTo, subject=subject, body=text, html=html, attachments=attachments, **xcc) elif html and (not raw): result = mail.send_mail(sender=self.sender, to=origTo, subject=subject, body=text, html=html, **xcc) else: result = mail.send_mail(sender=self.sender, to=origTo, subject=subject, body=text, **xcc) else: smtp_args = self.server.split(':') if self.ssl: server = smtplib.SMTP_SSL(*smtp_args) else: server = smtplib.SMTP(*smtp_args) if self.tls and not self.ssl: server.ehlo() server.starttls() server.ehlo() if self.login: server.login(*self.login.split(':', 1)) result = server.sendmail(self.sender, to, payload.as_string()) server.quit() except Exception: self.result = result self.error = None return False self.result = result self.error = None return True
def send(self, to, subject='[no subject]', message='[no message]', attachments=None, cc=None, bcc=None, reply_to=None, sender=None, encoding='utf-8', raw=False, headers={}, from_address=None, cipher_type=None, sign=None, sign_passphrase=None, encrypt=None, x509_sign_keyfile=None, x509_sign_chainfile=None, x509_sign_certfile=None, x509_crypt_certfiles=None, x509_nocerts=None ): """ Sends an email using data specified in constructor Args: to: list or tuple of receiver addresses; will also accept single object subject: subject of the email message: email body text; depends on type of passed object: - if 2-list or 2-tuple is passed: first element will be source of plain text while second of html text; - otherwise: object will be the only source of plain text and html source will be set to None If text or html source is: - None: content part will be ignored, - string: content part will be set to it, - file-like object: content part will be fetched from it using it's read() method attachments: list or tuple of Mail.Attachment objects; will also accept single object cc: list or tuple of carbon copy receiver addresses; will also accept single object bcc: list or tuple of blind carbon copy receiver addresses; will also accept single object reply_to: address to which reply should be composed encoding: encoding of all strings passed to this method (including message bodies) headers: dictionary of headers to refine the headers just before sending mail, e.g. `{'X-Mailer' : 'web2py mailer'}` from_address: address to appear in the 'From:' header, this is not the envelope sender. If not specified the sender will be used cipher_type : gpg - need a python-pyme package and gpgme lib x509 - smime gpg_home : you can set a GNUPGHOME environment variable to specify home of gnupg sign : sign the message (True or False) sign_passphrase : passphrase for key signing encrypt : encrypt the message (True or False). It defaults to True. ... x509 only ... x509_sign_keyfile : the signers private key filename or string containing the key. (PEM format) x509_sign_certfile: the signers certificate filename or string containing the cert. (PEM format) x509_sign_chainfile: sets the optional all-in-one file where you can assemble the certificates of Certification Authorities (CA) which form the certificate chain of email certificate. It can be a string containing the certs to. (PEM format) x509_nocerts : if True then no attached certificate in mail x509_crypt_certfiles: the certificates file or strings to encrypt the messages with can be a file name / string or a list of file names / strings (PEM format) Examples: Send plain text message to single address:: mail.send('*****@*****.**', 'Message subject', 'Plain text body of the message') Send html message to single address:: mail.send('*****@*****.**', 'Message subject', '<html>Plain text body of the message</html>') Send text and html message to three addresses (two in cc):: mail.send('*****@*****.**', 'Message subject', ('Plain text body', '<html>html body</html>'), cc=['*****@*****.**', '*****@*****.**']) Send html only message with image attachment available from the message by 'photo' content id:: mail.send('*****@*****.**', 'Message subject', (None, '<html><img src="cid:photo" /></html>'), Mail.Attachment('/path/to/photo.jpg' content_id='photo')) Send email with two attachments and no body text:: mail.send('[email protected], 'Message subject', None, [Mail.Attachment('/path/to/fist.file'), Mail.Attachment('/path/to/second.file')]) Returns: True on success, False on failure. Before return, method updates two object's fields: - self.result: return value of smtplib.SMTP.sendmail() or GAE's mail.send_mail() method - self.error: Exception message or None if above was successful """ # We don't want to use base64 encoding for unicode mail Charset.add_charset('utf-8', Charset.QP, Charset.QP, 'utf-8') def encode_header(key): if [c for c in key if 32 > ord(c) or ord(c) > 127]: return Header.Header(key.encode('utf-8'), 'utf-8') else: return key # encoded or raw text def encoded_or_raw(text): if raw: text = encode_header(text) return text sender = sender or self.settings.sender if not isinstance(self.settings.server, str): raise Exception('Server address not specified') if not isinstance(sender, str): raise Exception('Sender address not specified') if not raw and attachments: # Use multipart/mixed if there is attachments payload_in = MIMEMultipart.MIMEMultipart('mixed') elif raw: # no encoding configuration for raw messages if not isinstance(message, basestring): message = message.read() if isinstance(message, unicode): text = message.encode('utf-8') elif not encoding == 'utf-8': text = message.decode(encoding).encode('utf-8') else: text = message # No charset passed to avoid transport encoding # NOTE: some unicode encoded strings will produce # unreadable mail contents. payload_in = MIMEText.MIMEText(text) if to: if not isinstance(to, (list, tuple)): to = [to] else: raise Exception('Target receiver address not specified') if cc: if not isinstance(cc, (list, tuple)): cc = [cc] if bcc: if not isinstance(bcc, (list, tuple)): bcc = [bcc] if message is None: text = html = None elif isinstance(message, (list, tuple)): text, html = message elif message.strip().startswith('<html') and \ message.strip().endswith('</html>'): text = self.settings.server == 'gae' and message or None html = message else: text = message html = None if (text is not None or html is not None) and (not raw): if text is not None: if not isinstance(text, basestring): text = text.read() if isinstance(text, unicode): text = text.encode('utf-8') elif not encoding == 'utf-8': text = text.decode(encoding).encode('utf-8') if html is not None: if not isinstance(html, basestring): html = html.read() if isinstance(html, unicode): html = html.encode('utf-8') elif not encoding == 'utf-8': html = html.decode(encoding).encode('utf-8') # Construct mime part only if needed if text is not None and html: # We have text and html we need multipart/alternative attachment = MIMEMultipart.MIMEMultipart('alternative') attachment.attach(MIMEText.MIMEText(text, _charset='utf-8')) attachment.attach( MIMEText.MIMEText(html, 'html', _charset='utf-8')) elif text is not None: attachment = MIMEText.MIMEText(text, _charset='utf-8') elif html: attachment = \ MIMEText.MIMEText(html, 'html', _charset='utf-8') if attachments: # If there is attachments put text and html into # multipart/mixed payload_in.attach(attachment) else: # No attachments no multipart/mixed payload_in = attachment if (attachments is None) or raw: pass elif isinstance(attachments, (list, tuple)): for attachment in attachments: payload_in.attach(attachment) else: payload_in.attach(attachments) attachments = [attachments] ####################################################### # CIPHER # ####################################################### cipher_type = cipher_type or self.settings.cipher_type sign = sign if sign is not None else self.settings.sign sign_passphrase = sign_passphrase or self.settings.sign_passphrase encrypt = encrypt if encrypt is not None else self.settings.encrypt ####################################################### # GPGME # ####################################################### if cipher_type == 'gpg': if self.settings.gpg_home: # Set GNUPGHOME environment variable to set home of gnupg os.environ['GNUPGHOME'] = self.settings.gpg_home if not sign and not encrypt: self.error = "No sign and no encrypt is set but cipher type to gpg" return False # need a python-pyme package and gpgme lib from pyme import core, errors from pyme.constants.sig import mode ############################################ # sign # ############################################ if sign: core.check_version(None) pin = string.replace(payload_in.as_string(), '\n', '\r\n') plain = core.Data(pin) sig = core.Data() c = core.Context() c.set_armor(1) c.signers_clear() # search for signing key for From: for sigkey in c.op_keylist_all(sender, 1): if sigkey.can_sign: c.signers_add(sigkey) if not c.signers_enum(0): self.error = 'No key for signing [%s]' % sender return False c.set_passphrase_cb(lambda x, y, z: sign_passphrase) try: # make a signature c.op_sign(plain, sig, mode.DETACH) sig.seek(0, 0) # make it part of the email payload = \ MIMEMultipart.MIMEMultipart('signed', boundary=None, _subparts=None, **dict(micalg="pgp-sha1", protocol="application/pgp-signature")) # insert the origin payload payload.attach(payload_in) # insert the detached signature p = MIMEBase.MIMEBase("application", 'pgp-signature') p.set_payload(sig.read()) payload.attach(p) # it's just a trick to handle the no encryption case payload_in = payload except errors.GPGMEError, ex: self.error = "GPG error: %s" % ex.getstring() return False ############################################ # encrypt # ############################################ if encrypt: core.check_version(None) plain = core.Data(payload_in.as_string()) cipher = core.Data() c = core.Context() c.set_armor(1) # collect the public keys for encryption recipients = [] rec = to[:] if cc: rec.extend(cc) if bcc: rec.extend(bcc) for addr in rec: c.op_keylist_start(addr, 0) r = c.op_keylist_next() if r is None: self.error = 'No key for [%s]' % addr return False recipients.append(r) try: # make the encryption c.op_encrypt(recipients, 1, plain, cipher) cipher.seek(0, 0) # make it a part of the email payload = MIMEMultipart.MIMEMultipart('encrypted', boundary=None, _subparts=None, **dict(protocol="application/pgp-encrypted")) p = MIMEBase.MIMEBase("application", 'pgp-encrypted') p.set_payload("Version: 1\r\n") payload.attach(p) p = MIMEBase.MIMEBase("application", 'octet-stream') p.set_payload(cipher.read()) payload.attach(p) except errors.GPGMEError, ex: self.error = "GPG error: %s" % ex.getstring() return False
def send_book(buy): book = buy.book sell = book.sell_set.all()[0] admin_email = settings.ADMINS[0][1] pandoc_info = { "PANDOC_HOME": PANDOC_HOME, "MD_ROOT": PANDOC_HOME + "/md", "GEN_ROOT": PANDOC_HOME + "/gen", "filename": sell.filename, "email": buy.email, "buy_id": buy.id, } msg = MIMEMultipart.MIMEMultipart() msg['From'] = settings.DEFAULT_FROM_EMAIL msg['To'] = COMMASPACE.join([buy.email, admin_email]) msg['Date'] = formatdate(localtime=True) msg['Subject'] = Header(s=utf8(u"%s 전자책(E-Book)" % book.subject), charset='utf-8') text = u""""%(subject)s"을 구매 해 주셔서 감사합니다. 총 3개의 첨부 파일을 확인 해 주시기 바랍니다. - %(filename)s.pdf (PDF) - %(filename)s.epub (일반 전자문서) - %(filename)s.mobi (킨들용 전자문서) 첨부 파일에 문제가 있을 경우 답장주시면 교환 또는 환불 해 드립니다. 문의 : 박응용 ([email protected]) 감사합니다. p.s. 전자문서의 품질이 개선되었을 경우 이메일이 재 발송될 수 있습니다. """ % { "subject": book.subject, "filename": sell.filename } msg.attach(MIMEText(utf8(text), _charset='utf-8')) files = [] files.append("%(GEN_ROOT)s/%(buy_id)s/%(filename)s.pdf" % pandoc_info) files.append("%(GEN_ROOT)s/%(buy_id)s/%(filename)s.epub" % pandoc_info) files.append("%(GEN_ROOT)s/%(buy_id)s/%(filename)s.mobi" % pandoc_info) for f in files: part = MIMEBase.MIMEBase('application', "octet-stream") part.set_payload(open(f, "rb").read()) Encoders.encode_base64(part) part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(f)) msg.attach(part) mailServer = smtplib.SMTP(settings.EMAIL_HOST) mailServer.ehlo() mailServer.starttls() mailServer.ehlo() mailServer.login(settings.EMAIL_HOST_USER, settings.EMAIL_HOST_PASSWORD) # msg.set_charset('utf-8') mailServer.sendmail(msg["From"], [buy.email, admin_email], msg.as_string()) mailServer.quit() buy.send_yn = "Y" buy.save()
def genIcal(event): from icalendar import Calendar, Event, Alarm #get details from event instance title = event.title desc = event.title duration = 3 start = datetime.combine(event.when, event.time) end = datetime.combine(event.when, event.time) + timedelta(hours=duration) location = event.location # Timezone to use for our dates - change as needed reminderHours = 3 cal = Calendar() cal.add('prodid', '-//APERTA calendar application//aperta.lu//') cal.add('version', '2.0') cal.add('method', "REQUEST") vevent = Event() # event.add('attendee', self.getEmail()) vevent.add('organizer', settings.EMAILS['sender']['default']) vevent.add('status', "confirmed") vevent.add('category', "Event") vevent.add('summary', title) vevent.add('description', desc) vevent.add('location', location) vevent.add('dtstart', start) vevent.add('dtend', end) from attendance.functions import gen_hash vevent['uid'] = gen_hash( event, settings.EMAILS['sender']['default'])[:10] # Generate some unique ID vevent.add('priority', 5) vevent.add('sequence', 1) vevent.add('created', timezone.now()) alarm = Alarm() alarm.add("action", "DISPLAY") alarm.add('description', "Reminder") alarm.add("trigger", timedelta(hours=-reminderHours)) # The only way to convince Outlook to do it correctly alarm.add("TRIGGER;RELATED=START", "-PT{0}H".format(reminderHours)) vevent.add_component(alarm) cal.add_component(vevent) #gen file to be attached to an email from email import MIMEBase, Encoders filename = "invite.ics" invite = MIMEBase.MIMEBase('text', "calendar", method="REQUEST", name=filename) invite.set_payload(cal.to_ical()) Encoders.encode_base64(invite) invite.add_header('Content-Description', desc) invite.add_header("Content-class", "urn:content-classes:calendarmessage") invite.add_header("Filename", filename) invite.add_header("Path", filename) return invite
def _generate_pgp_mime_email(self, signer, email, keyid, filename, psigner): '''Generates the PGP/Mime body. The message headers MUST be added by the caller.''' msg = MIMEMultipart.MIMEMultipart('encrypted', micalg="pgp-sha1", protocol="application/pgp-encrypted") msg.preamble = 'This is an OpenPGP/MIME signed message (RFC 2440 and 3156)' # The signed part of the message. This is a MIME encapsulation # of the main body of the message *and* the key. encrypted_body = MIMEMultipart.MIMEMultipart('mixed') # First part of signed body textpart = MIMEBase.MIMEBase('text', 'plain', charset="ISO-8859-1") textpart.add_header('Content-Transfer-Encoding', 'quoted-printable') textpart.__delitem__('MIME-Version') textpart.set_payload( quopriMIME.encode(self._get_email_body(signer, keyid, email))) encrypted_body.attach(textpart) # The second part of the signed body file_base = os.path.basename(filename) attached_sig = MIMEBase.MIMEBase('application', 'pgp-keys', name='%s' % file_base) attached_sig.add_header('Content-Disposition', 'inline', filename='%s' % file_base) attached_sig.__delitem__('MIME-Version') # # We USED to make this quoted-printable, but people with non-PGP-aware MUAs # were decrypting the body manually, and then trying to import the resulting # MIME message which was QP-encoded... so if there was an equals-sign in the # message, it would actually be an '=3D' and thus fail the import. # # RFC2015 strongly suggests using QP for any signed data to prevent MTAs # from messing with it... however, since this gets encrypted, this data is # never available for an MTA to mess with, so this ... should be safe, and # allows both methods of decrypting and importing the key. # # Side-note, if we ever turn to QP, be sure to use quopriMIME.encode to # encode the payload. # attached_sig.set_payload(open(filename, 'r').read()) encrypted_body.attach(attached_sig) encrypted_body.__delitem__('MIME-Version') # Encryt/Sign the MIME body. # # We have to conver to DOS newlines since that's what happens # to mail anyway and we don't want verification to fail dos_body = encrypted_body.as_string().replace('\n', '\r\n') tmpfile = os.path.join(self.tmp_dir, 'pius_tmp') signed_tmpfile = '%s.asc' % tmpfile clean_files([tmpfile, signed_tmpfile]) tfile = open(tmpfile, 'w') tfile.write(dos_body) tfile.close() try: psigner.encrypt_and_sign_file(tmpfile, signed_tmpfile, keyid) except EncryptionKeyError: raise EncryptionKeyError # Create the version part of the PGP/Mime encryption pgp_ver = MIMEBase.MIMEBase('application', 'pgp-encrypted') pgp_ver.add_header('Content-Description', 'PGP/MIME version identification') pgp_ver.__delitem__('MIME-Version') pgp_ver.set_payload('Version: 1\n') # Create the big sign-encrypted body part pgp_data = MIMEBase.MIMEBase('application', 'octet-stream', name='encrypted.asc') pgp_data.add_header('Content-Description', 'OpenPGP encrypted message') pgp_data.add_header('Content-Disposition', 'inline', filename='encrypted.asc') pgp_data.__delitem__('MIME-Version') pgp_data.set_payload(open(signed_tmpfile, 'r').read()) # This is the actual encrypt-signed PGP/Mime message msg.attach(pgp_ver) msg.attach(pgp_data) clean_files([tmpfile, signed_tmpfile]) return msg
mail_body = 'hello, this is the mail content' mail_from = '' # 发件人的邮箱 mail_to = [''] # 收件人邮箱 # 构造MIMEMultipart对象做为根容器 msg = MIMEMultipart() # 构造MIMEText对象做为邮件显示内容并附加到根容器 body = MIMEText(mail_body) msg.attach(body) # 构造MIMEBase对象做为文件附件内容并附加到根容器 # 等同于如下3行 # contype = 'application/octet-stream' # maintype, subtype = contype.split('/', 1) # part = MIMEBase(maintype, subtype) part = MIMEBase('application', 'octet-stream') # 读入文件内容并格式化,此处文件为当前目录下,也可指定目录 例如:open(r'/tmp/123.txt','rb') part.set_payload(open('123.txt', 'rb').read()) Encoders.encode_base64(part) ## 设置附件头 part.add_header('Content-Disposition', 'attachment; filename="herb.zip"') msg.attach(part) # 设置根容器属性 msg['Subject'] = 'this is the title' msg['From'] = mail_from msg['To'] = ';'.join(mail_to) msg['date'] = time.strftime('%a, %d %b %Y %H:%M:%S %z') # 如上得到了格式化后的完整文本msg.as_string() # 用smtp发送邮件
# html-mail # 发送附件 # 如果Email中要加上附件怎么办?带附件的邮件可以看做包含若干部分的邮件:文本和各个附件本身,所以,可以构造一个MIMEMultipart对象代表邮件本身,然后往里面加上一个MIMEText作为邮件正文,再继续往里面加上表示附件的MIMEBase对象即可: # 邮件对象: msg = MIMEMultipart() msg['From'] = _format_addr(u'Python爱好者 <%s>' % from_addr) msg['To'] = _format_addr(u'管理员 <%s>' % to_addr) msg['Subject'] = Header(u'来自SMTP的问候……', 'utf-8').encode() # 邮件正文是MIMEText: msg.attach(MIMEText('send with file...', 'plain', 'utf-8')) # 添加附件就是加上一个MIMEBase,从本地读取一个图片: with open('/Users/michael/Downloads/test.png', 'rb') as f: # 设置附件的MIME和文件名,这里是png类型: mime = MIMEBase('image', 'png', filename='test.png') # 加上必要的头信息: mime.add_header('Content-Disposition', 'attachment', filename='test.png') mime.add_header('Content-ID', '<0>') mime.add_header('X-Attachment-Id', '0') # 把附件的内容读进来: mime.set_payload(f.read()) # 用Base64编码: encoders.encode_base64(mime) # 添加到MIMEMultipart: msg.attach(mime) # 然后,按正常发送流程把msg(注意类型已变为MIMEMultipart)发送出去,就可以收到如下带附件的邮件: # mimemultipart # 发送图片 # 如果要把一个图片嵌入到邮件正文中怎么做?直接在HTML邮件中链接图片地址行不行?答案是,大部分邮件服务商都会自动屏蔽带有外链的图片,因为不知道这些链接是否指向恶意网站。 # 要把图片嵌入到邮件正文中,我们只需按照发送附件的方式,先把邮件作为附件添加进去,然后,在HTML中通过引用src="cid:0"就可以把附件作为图片嵌入了。如果有多个图片,给它们依次编号,然后引用不同的cid:x即可。