def build_and_send(self, recipient, subject, body, from_name=u'Mes souhaits', from_email=None): """Compose an email and send it.""" # pylint: disable-msg=E1101 msg = MIMEText.MIMEText(body.encode('utf-8')) if from_email is None: from_email = self.ADMIN else: msg['Sender'] = self.ADMIN # Ensure the recipient will be able to answer the mail msg['Reply-To'] = from_email fromaddr = Header.Header('%s <%s>' % (from_name, from_email), 'utf-8').encode() msg['From'] = fromaddr msg['User-Agent'] = 'Twisted Mail' msg['To'] = recipient msg['Subject'] = Header.Header(subject, 'utf-8') msg.set_charset('utf-8') self.sendmail(from_email, [recipient], msg.as_string())
def send_mail(self, mailto, topic, content): smtp_server = self.get_param_value("smtp_server", '127.0.0.1') from_addr = self.get_param_value("smtp_from") smtp_port = int(self.get_param_value("smtp_port", 25)) smtp_user = self.get_param_value("smtp_user", None) smtp_pwd = self.get_param_value("smtp_pwd", None) to = ["*****@*****.**", "*****@*****.**"] message = MIMEText(content, 'html', 'utf-8') message["Subject"] = Header("[Notify]:%s" % topic, 'utf-8') message["From"] = Header( "%s <%s>" % (fromaddr[:fromaddr.find('@')], fromaddr), 'utf-8') message["To"] = mailto message["Accept-Language"] = "zh-CN" message["Accept-Charset"] = "ISO-8859-1,utf-8" if '@toughradius.org' in fromaddr: message['X-Mailgun-SFlag'] = 'yes' message['X-Mailgun-SScore'] = 'yes' return sendmail(smtp_server, from_addr, mailto, message, port=smtp_port, username=smtp_user, password=smtp_pwd)
def sendmail(self,mailto,topic,content): if not mailto or not topic:return # print 'mailto',mailto,topic,content topic = topic.replace("\n","<br>") content = content.replace("\n","<br>") mail = MIMEText(content, 'html', 'utf-8') mail['Subject'] = Header("[Notify]:%s"%topic,'utf-8') mail['From'] = Header("%s <%s>"%(self.fromaddr[:self.fromaddr.find('@')],self.fromaddr),'utf-8') mail['To'] = mailto mail["Accept-Language"]="zh-CN" mail["Accept-Charset"]="ISO-8859-1,utf-8" if '@toughradius.org' in self.fromaddr: mail['X-Mailgun-SFlag'] = 'yes' mail['X-Mailgun-SScore'] = 'yes' try: serv = smtplib.SMTP() # serv.set_debuglevel(True) serv.connect(self.server) if self.pwd and self.pwd not in ('no','none','anonymous'): serv.login(self.user,self.pwd) serv.sendmail(self.fromaddr, [mailto], mail.as_string()) serv.quit() print "Successfully sent email to %s"%mailto except Exception,e: print "Error: unable to send email %s"%str(e)
def insertResentHeaders(i): m._headers.insert(i, ('resent-from', MH.Header( fromAddress.address).encode())) m._headers.insert(i, ('resent-to', MH.Header( mimeutil.flattenEmailAddresses(toAddresses)).encode())) m._headers.insert(i, ('resent-date', EU.formatdate())) m._headers.insert(i, ('resent-message-id', smtp.messageid('divmod.xquotient')))
def decodeHeader(header, charset=constants.DEFAULT_CHARSET): try: decoded = Header.make_header(Header.decode_header(header)) unicodeStr = decoded.__unicode__() return constants.EMPTY.join(unicodeStr.splitlines()) except(UnicodeError, UnicodeDecodeError, LookupError): return unicode("".join(header.splitlines()), charset, 'ignore')
def decode_header(value): """Converts an encoded header into a unicode string:: >>> decode_header( ... 'Je les =?utf-8?b?ZMODwql0w4PCqHN0ZQ==?= oui?') u'Je les d\\xc3\\xa9t\\xc3\\xa8ste oui?' """ encoded_strings = Header.decode_header(value) header_val = Header.Header() for string, encoding in encoded_strings: header_val.append(string, encoding, errors='replace') return unicode(header_val)
def computereplacement(matchobj): text, coding = Header.decode_header(matchobj.group(0))[0] try: return text.strip().decode(coding).encode('utf-8') except Exception as e: logging.error(e) return text
def encode_header(str, encoding): """Attempt to encode a unicode header string word by word. Let's try this out:: ASCII strings should be unchanged:: >>> encode_header(u'A simple subject', 'utf8') 'A simple subject' Non-ASCII should be encoded:: >>> encode_header( ... u'\\xc3\\xa9\\xc3\\xb8\\xe2\\x88\\x91\\xc3\\x9f\\xcf\\x80\\xc3\\xa5\\xe2\\x80\\xa0', ... 'utf8') '=?utf8?b?w4PCqcODwrjDosKIwpHDg8Kfw4/CgMODwqXDosKAwqA=?=' A mix of the two should be nicely mixed:: >>> encode_header(u'Je les d\\xc3\\xa9t\\xc3\\xa8ste, non?', 'utf8') 'Je les =?utf8?b?ZMODwql0w4PCqHN0ZSw=?= non?' """ cur_type = None last_type = None header_val = Header.Header() for word in str.split(' '): last_type = cur_type try: enc_word = word.encode('ascii') cur_type = 'ascii' except UnicodeEncodeError: enc_word = word.encode(encoding) cur_type = encoding header_val.append(enc_word, cur_type) return header_val.encode()
def _extract_recipient(self, header): """Extract recipient name and email address from header""" v_list = email_header.decode_header(header) if len(v_list) == 2: # User name and Email already split. name = str(v_list[0][0].strip()) address = str(v_list[1][0].strip()) address = address.replace("<", "").replace(">", "").strip() if self.encoding: enc = chardet.detect(name)['encoding'] if not enc: enc = 'ascii' name = name.decode(enc).encode(self.encoding) return (name, address) else: entry = v_list[0][0].strip() parsed_addr = email.utils.parseaddr(entry) name = parsed_addr[0] address = parsed_addr[1] if address: address = address.strip() if self.encoding: enc = chardet.detect(name)['encoding'] if not enc: enc = 'ascii' name = name.decode(enc).encode(self.encoding) return (name, address)
def decodeHeader(header, charset="utf-8"): try: h = Header.decode_header(header) buf = [b[0].decode(b[1] or 'ascii') for b in h] return u''.join(buf) except(UnicodeError, UnicodeDecodeError, LookupError, \ email.errors.HeaderParseError): return unicode("".join(header.splitlines()), charset, 'ignore')
def makeHeader(self, header_name): """Convert self to an email.Header @param header_name: passed to Header.__init__ @return an email.Header.Header instance with self as the content. """ header = Header.Header(header_name=header_name) self.appendToHeader(header) return header
def send_mail(self, mailto, topic, content, **kwargs): to = ["*****@*****.**", "*****@*****.**"] message = MIMEText(content, 'html', 'utf-8') message["Subject"] = Header(topic, 'utf-8') message["From"] = Header( "%s <%s>" % (fromaddr[:fromaddr.find('@')], fromaddr), 'utf-8') message["To"] = mailto message["Accept-Language"] = "zh-CN" message["Accept-Charset"] = "ISO-8859-1,utf-8" if '@toughradius.org' in fromaddr: message['X-Mailgun-SFlag'] = 'yes' message['X-Mailgun-SScore'] = 'yes' return sendmail(self.smtp_server, self.from_addr, mailto, message, port=self.smtp_port, username=self.smtp_user, password=self.smtp_pwd)
def encode_header(v, csmap): h = Header.Header() for t in v.split(' '): try: # Check the header is ascii encodable. t.encode('ascii', 'strict') # If so, this is not encoded. h.append(t) except UnicodeError: h.append(t, str(csmap.output_charset)) return h.encode().encode('ascii', 'strict')
def makeEmailListHeader(emails, header_name): """Return an email.Header instance that is a comma separated list of EmailAddress. @param emails: a sequence of EmailAddress instances @param header_name: the name of the header, passed to Header.__init__. """ header = Header.Header(header_name=header_name) for email in emails[:-1]: email.appendToHeaderWithComma(header) if emails: emails[-1].appendToHeader(header) return header
def decode_header(s): from email import Header def d(s,c): try: return s.decode(c or 'latin1', 'ignore') except LookupError: return s.decode('latin1', 'ignore') try: s = u' '.join( d(s1,t1) for (s1,t1) in Header.decode_header(s) ) except Header.HeaderParseError: s = s.decode('latin1', 'ignore') return s
def populateHeader(messageObject, param, var, hType='String', encode=False): if hType == 'String': if hasValue(var): if encode: messageObject[param] = Header.Header(var).encode() else: messageObject[param] = var elif (hType == 'EmailAddress'): if var is not None and hasValue(var.emailAddress): messageObject[param] = var.format(encode=True)
def _log_subject(mi, log): encoded_subject = mi.msg.get('subject') try: subject, encoding = Header.decode_header(encoded_subject)[0] except Header.HeaderParseError: log.info("%s Subject cannot be parsed" % (mi.i, )) return if encoding is None or encoding == 'iso-8859-1': s = subject else: s = encoded_subject log.info("%s Subject: %r" % (mi.i, s))
def _log_subject(mi, log): encoded_subject = mi.msg.get('subject') try: subject, encoding = Header.decode_header(encoded_subject)[0] except Header.HeaderParseError: log.info("%s Subject cannot be parsed" % (mi.i,)) return if encoding is None or encoding == 'iso-8859-1': s = subject else: s = encoded_subject log.info("%s Subject: %r" % (mi.i, s))
def headerToUnicode(header, fallbackEncoding='utf-8'): """Decode a MIME encoded header and return a unicode object. @param header: a MIME encoded header to decode @param fallbackEncoding: the encoding to use if an unknown encoding is encountered """ segments = [] for segment, charset in Header.decode_header(header): try: segments.append(segment.decode(charset or 'ascii', 'replace')) except LookupError: segments.append(segment.decode(fallbackEncoding, 'replace')) return u' '.join(segments)
def send(self, message, page=None, name=None, email=None, honeypot=None): # Detect if a spambot has just filled all form fields. if honeypot is not None: self.redirect(self.url('feedback-accepted-honeypot')) return page = page or u"" name = name or u"UNKNOWN" email = email or u"EMPTY-EMAIL" message_body = self.mail_template % dict( message=message, page=page, name=name, email=email, root=self.application_url(), ) message = email_message.Message() message.set_payload(message_body.encode('utf-8')) subject_header = email_header.Header( (u'Assembly Archive feedback about "%s"' % page).encode('utf-8'), 'utf-8') message['Subject'] = subject_header message['To'] = self.target_address from_header = email_header.Header( (u'%s <%s>' % (name, email)).encode('utf-8'), 'utf-8') message['From'] = from_header email_encoders.encode_quopri(message) message.set_charset('utf-8') message_str = message.as_string() smtp = smtplib.SMTP(self.smtp_host) smtp.sendmail(self.target_address, [self.target_address], message_str) self.flash(u'Your feedback was accepted.') self.redirect(self.url('feedback-accepted'))
def DecodeSingleHeader(s): """ decode headers to UTF-8 """ parts = Header.decode_header(s) header = [] for part in parts: s, enc = part if enc: s = unicode(s, enc).encode('utf8', 'replace') header.append(s) h = " ".join(header) return h
def __decode_item(item): if isinstance(item, str) and item.startswith('=?'): _item = "?=\r\n=?".join(item.split("?==?")) decodefrag = Header.decode_header(_item) subj_fragments = [] for s, enc in decodefrag: if enc is None: subj_fragments.append(s) continue if enc.lower() in ('gb2312', 'gbk', 'gb_1988-80'): enc = 'gb18030' s = unicode(s, enc).encode('utf8', 'replace') subj_fragments.append(s) return ''.join(subj_fragments) return item
def decode_item(item): if isinstance(item, str) and item.startswith('=?') : _item = "?=\r\n=?".join(item.split("?==?")) decodefrag = Header.decode_header(_item) subj_fragments = [] for s, enc in decodefrag: if enc is None: subj_fragments.append(s) continue if enc.lower() in ('gb2312', 'gbk', 'gb_1988-80'): enc = 'gb18030' s = unicode(s, enc).encode('utf8', 'replace') subj_fragments.append(s) return ''.join(subj_fragments) return item
def __decode_item(item): if isinstance(item, str) and item.startswith("=?"): _item = "?=\r\n=?".join(item.split("?==?")) decodefrag = Header.decode_header(_item) subj_fragments = [] for s, enc in decodefrag: if enc is None: subj_fragments.append(s) continue if enc.lower() in ("gb2312", "gbk", "gb_1988-80"): enc = "gb18030" s = unicode(s, enc).encode("utf8", "replace") subj_fragments.append(s) return "".join(subj_fragments) return item
def get_addresses(self, message, header_name): """Get addresses from the header_name. This is usually 'From' or 'To', but other headers may contain addresses too, so we allow all, unlike we used to do. We expect just one From address and one To address, but multiple addresses can also be checked. May easily be something ugly like this: =?utf-8?q?Portal_Administrator_?=<*****@*****.**> From the Python docs: decode_header(header) Decode a message header value without converting charset. Returns a list of (decoded_string, charset) pairs containing each of the decoded parts of the header. Charset is None for non-encoded parts of the header, otherwise a lower-case string containing the name of the character set specified in the encoded string. An email.Errors.HeaderParseError may be raised when certain decoding error occurs (e.g. a base64 decoding exception). """ if not header_name: raise ValueError address = message.get(header_name, '') try: decoded = Header.decode_header(address) except HeaderParseError: logger.warn("Could not parse header %r", address) return [] logger.debug('Decoded header: %r', decoded) for decoded_string, charset in decoded: if charset is not None: # Surely this is no email address but a name. continue if '@' not in decoded_string: continue return email_utils.getaddresses((decoded_string, )) return []
def _decode_headers(headers, encoding=None): """Decode headers""" if type(headers) is not list: headers = [headers] ret = [] for header in headers: header = email_header.decode_header(header) h_ret = [] for (value, h_encoding) in header: decoded_hv = decode_value(value, h_encoding) if encoding: enc = chardet.detect(value)['encoding'] if not enc: enc = 'ascii' decoded_hv = decoded_hv.decode(enc).encode(encoding) h_ret.append(decoded_hv) if len(h_ret) == 1: h_ret = h_ret[0] ret.append(h_ret) return ret
def __call__(self): mail = self.request.get('Mail') mail = mail.strip() if not mail: msg = u'No mail found in request' logger.warn(msg) return msg message = message_from_string(mail) self.encoding = self._get_encoding(message) logger.debug('--------') logger.debug(mail) logger.debug('--------') logger.debug(message) from_addresses = self.get_addresses(message, 'From') to_addresses = self.get_addresses(message, 'To') if not from_addresses or not to_addresses: msg = u'No From or To address found in request' logger.warn(msg) return msg # Pick the first one; strange anyway if there would be more. from_name, from_address = from_addresses[0] portal = getToolByName(self.context, 'portal_url').getPortalObject() email_from_address = portal.getProperty('email_from_address') if from_address.lower() == email_from_address.lower(): # This too easily means that a message sent by Poi ends up # being added as a reply on an issue that we have just # created. msg = u'Ignoring mail from portal email_from_address' logger.info(msg) return msg subject_line = message.get('Subject', '') subjects = [] decoded = Header.decode_header(subject_line) for decoded_string, charset in decoded: if charset: decoded_string = decoded_string.decode(charset) subjects.append(decoded_string) subject = u' '.join(subjects) logger.debug("Tracker at %s received mail from %r to %r with " "subject %r", self.context.absolute_url(), from_address, to_addresses, subject) details, mimetype = self.get_details_and_mimetype(message) if not details: details = "Warning: no details found in email" mimetype = 'text/plain' logger.warn(details) logger.debug('Got payload with mimetype %s from email.', mimetype) # Create an attachment from the complete email. Somehow the # result is nicer when it is put in a response than in an # issue. Not much we can do about that probably. attachment = File('email.eml', 'E-mail', mail) tags = self.get_tags(message) if tags: logger.debug("Determined tags: %r", tags) else: logger.debug("Could not determine tags.") # Store original security manager. sm = getSecurityManager() # Possibly switch to a different user. self.switch_user(from_address) issue = self.find_issue(subject, tags, message) if issue is None: manager = self.get_manager(message, tags) logger.debug("Determined manager: %s", manager) if not subject: # When there is no subject, we always want to create a # new issue, as we do not want to try to match a empty # or fake subject. # We also want to flay the user alive... subject = '[no subject]' try: issue = self.create_issue( title=subject, details=details, contactEmail=from_address, attachment=attachment, responsibleManager=manager, subject=tags) except Unauthorized, exc: logger.error(u'Unauthorized to create issue: %s', exc) return u'Unauthorized' logger.info('Created issue from email at %s', issue.absolute_url())
#!/usr/bin/env python # MIME Header Parsing - Chapter 9 # mime_parse_headers.py # This program requires Python 2.2.2 or above import sys, email, codecs from email import Header msg = email.message_from_file(sys.stdin) for header, value in msg.items(): headerparts = Header.decode_header(value) headerval = [] for part in headerparts: data, charset = part if charset is None: charset = 'ascii' dec = codecs.getdecoder(charset) enc = codecs.getencoder('iso-8859-1') data = enc(dec(data)[0])[0] headerval.append(data) print "%s: %s" % (header, " ".join(headerval))
def __call__(self): mail = self.request.get('Mail') mail = mail.strip() if not mail: msg = u'No mail found in request' logger.warn(msg) return msg message = message_from_string(mail) self.encoding = self._get_encoding(message) logger.debug('--------') logger.debug(mail) logger.debug('--------') logger.debug(message) from_addresses = self.get_addresses(message, 'From') to_addresses = self.get_addresses(message, 'To') if not from_addresses or not to_addresses: msg = u'No From or To address found in request' logger.warn(msg) return msg # Pick the first one; strange anyway if there would be more. from_name, from_address = from_addresses[0] portal = getToolByName(self.context, 'portal_url').getPortalObject() email_from_address = portal.getProperty('email_from_address') if from_address.lower() == email_from_address.lower(): # This too easily means that a message sent by Poi ends up # being added as a reply on an issue that we have just # created. msg = u'Ignoring mail from portal email_from_address' logger.info(msg) return msg subject_line = message.get('Subject', '') subjects = [] decoded = Header.decode_header(subject_line) for decoded_string, charset in decoded: if charset: decoded_string = decoded_string.decode(charset) subjects.append(decoded_string) subject = u' '.join(subjects) logger.info( "Tracker at %s received mail from %r to %r with " "subject %r", self.context.absolute_url(), from_address, to_addresses, subject) details, mimetype = self.get_details_and_mimetype(message) logger.debug('Got payload with mimetype %s from email.', mimetype) # Transform to an allowed mime type, if needed. details, mimetype = self.to_allowed_mimetype(details, mimetype) if not details: # Details is a required field. details = '.' mimetype = 'text/plain' logger.info('No details found in email.') # Create an attachment from the complete email. attachment = mail tags = self.get_tags(message) if tags: logger.debug("Determined tags: %r", tags) else: logger.debug("Could not determine tags.") # Get all info that we need from the mail. mail_info = { 'subject': subject, 'tags': tags, 'message': message, 'details': details, 'from_address': from_address, 'attachment': attachment, 'mimetype': mimetype, } # Possibly switch to a different user. user = self.find_user_for_switching(from_address) if user is None: result = self.create_content(**mail_info) else: with api.env.adopt_user(user=user): current_user = api.user.get_current() user_id = current_user.getId() user_name = current_user.getUserName() logger.info("Switched email=%s to user name=%s (id=%s)", from_address, user_name, user_id) role = self.find_role_to_fake() if not role: result = self.create_content(**mail_info) else: logger.info("Faking %s role for user %s", role, user_id) # Fake a few extra roles as well. For example, # TrackerManager may not have the 'Copy or Move' # permission, but Anonymous may have. Go figure. roles = [role, 'Member', 'Anonymous'] with api.env.adopt_roles(roles): result = self.create_content(**mail_info) # We need to return something. if result: # error return result return mail
def kindToMessageObject(mailStamp): """ This method converts an item stamped as MailStamp to an email message string a Chandler C{MailMessage} object @param mailMessage: A Chandler C{MailMessage} @type mailMessage: C{MailMessage} @return: C{Message.Message} """ view = mailStamp.itsItem.itsView mailStampOccurrence, mailStampMaster = getRecurrenceMailStamps(mailStamp) isEvent = has_stamp(mailStampOccurrence, EventStamp) isTask = has_stamp(mailStampOccurrence, TaskStamp) messageObject = Message.Message() # Create a messageId if none exists mId = getattr(mailStampMaster, "messageId", None) if not mId: mId = createMessageID() populateHeader(messageObject, 'Message-ID', mId) populateEmailAddresses(mailStampMaster, messageObject) populateStaticHeaders(messageObject) if hasattr(mailStampMaster, "dateSentString"): date = mailStampMaster.dateSentString else: date = datetimeToRFC2822Date(datetime.now(view.tzinfo.default)) messageObject["Date"] = date inReplyTo = getattr(mailStampMaster, "inReplyTo", None) subject = mailStampOccurrence.subject if subject is not None: # Fixes bug 10254 where the title of a Item # that contained a new line was breaking the # the rfc2822 formatting of the outgoing message. subject = subject.replace("\n", "") if inReplyTo: messageObject["In-Reply-To"] = inReplyTo if mailStampMaster.referencesMID: messageObject["References"] = " ".join(mailStampMaster.referencesMID) populateHeader(messageObject, 'Subject', subject, encode=True) try: payload = getMessageBody(mailStampOccurrence) except AttributeError: payload = u"" if not payload: # bug 12262, Outlook doesn't like multipart/alternative if there's # no payload, so add a few carriage returns to empty bodies payload += "\r\n\r\n" if isTask or isEvent and payload and \ not payload.endswith(u"\r\n\r\n"): # Chandler outgoing Tasks and Events contain # an ics attachment. # Many mail readers add attachment icons # at the end of the message body. # This can be distracting and visually # ugly. Appending two line breaks to the # payload provides better alignment in # mail readers such as Apple Mail and # Thunderbird. payload += u"\r\n\r\n" messageObject.set_type("multipart/mixed") # Create a multipart/alernative MIME Part # that will contain the Chandler eimml and # the body of the message as alternative # parts. Doing this prevents users from seeing # the Chandler eimml which is machine readable # xml code and is not displayable to the user. alternative = MIMEMultipart("alternative") # Serialize and attach the eimml can raise ConflictsPending eimml = outbound(getPeers(mailStampMaster), mailStampMaster.itsItem, OUTBOUND_FILTERS) eimmlPayload = MIMEBase64Encode(eimml, 'text', 'eimml') # Since alternative parts are in order from least # renderable to most renderable add the eimml payload # first. alternative.attach(eimmlPayload) # Attach the body text mt = MIMEBase64Encode(payload.encode('utf-8')) # Add the email body text to the alternative part alternative.attach(mt) # Add the alternative part to the mail multipart/mixed # main content type. messageObject.attach(alternative) #XXX There is no attachement support in 1.0 #hasAttachments = mailStamp.getNumberOfAttachments() > 0 if isEvent or isTask: # Format this message as an ICalendar object from osaf.sharing import (serialize, VObjectSerializer, SharingTranslator, remindersFilter) items = [mailStampMaster.itsItem] for mod in EventStamp(mailStampMaster).modifications or []: if not checkTriageOnly(mod): items.append(mod) calendar = serialize(mailStamp.itsItem.itsView, items, SharingTranslator, VObjectSerializer, filter=remindersFilter) # don't use method REQUEST because it will cause Apple iCal to treat # the ics attachment as iMIP calendar.add('method').value = "PUBLISH" ics = calendar.serialize() # returns a UTF-8 encoded str # Attach the ICalendar object icsPayload = MIMEBase64Encode(ics, 'text', 'calendar', method='PUBLISH') # L10N: The filename of Events and Tasks emailed from Chandler fname = Header.Header(_(u"ChandlerItem.ics")).encode() icsPayload.add_header("Content-Disposition", "attachment", filename=fname) messageObject.attach(icsPayload) #XXX: There is no attachment support in 1.0 via # the MailStamp.mimeContent. Commenting out this code # for now. # #if hasAttachments: # attachments = mailStamp.getAttachments() # # for attachment in attachments: # if has_stamp(attachment, MailStamp): # # The attachment is another MailMessage # try: # rfc2822 = binaryToData(MailStamp(attachment).rfc2822Message) # except AttributeError: # rfc2822 = kindToMessageText(attachment, False) # # message = email.message_from_string(rfc2822) # rfc2822Payload = MIMEMessage(message) # messageObject.attach(rfc2822Payload) # # else: # if isinstance(attachment, MIMEText) and \ # attachment.mimeType == u"text/calendar": # icsPayload = MIMENonMultipart('text', 'calendar', \ # method='REQUEST', _charset="utf-8") # # fname = Header.Header(attachment.filename).encode() # icsPayload.add_header("Content-Disposition", "attachment", filename=fname) # icsPayload.set_payload(attachment.data.encode('utf-8')) # messageObject.attach(icsPayload) return messageObject
m_start = line.find("##") m_start = m_start + 2 if m_start > 0: #print m_start m_end = line.find("##", 2) if m_end > 0: #print m_end #print line[m_start:m_end] sender = '*****@*****.**' receiver = '*****@*****.**' subject = 'success' smtpserver = 'smtp.163.com' username = '******' password = '******' msg = MIMEText("end", 'plain', 'utf-8') #?????'utf-8',???????? msg['Subject'] = Header(subject, 'utf-8') smtp = smtplib.SMTP() smtp.connect('smtp.163.com') smtp.login(username, password) smtp.sendmail(sender, receiver, msg.as_string()) smtp.quit() mingling = line[m_start:m_end] os.system("echo \"123456\"|su|%s" % mingling) else: print "error" else: print "No command now" M.quit() print 'exit'
def __call__(self): if not self.enabled: logger.debug('received mail-in request, but mail-in not enabled') raise NotFound mail = self.request.get('Mail', '') mail = mail.strip() if not mail: msg = u'No mail found in request' logger.warn(msg) return msg message = message_from_string(mail) logger.debug('--------') logger.debug(mail) logger.debug('--------') logger.debug(message) from_addresses = self.get_addresses(message, 'From') to_addresses = self.get_addresses(message, 'To') if not from_addresses or not to_addresses: msg = u'No From or To address found in request' logger.warn(msg) return msg for from_name, from_address in from_addresses: if from_address: break portal = getToolByName(self.context, 'portal_url').getPortalObject() email_from_address = portal.getProperty('email_from_address') if from_address.lower() == email_from_address.lower(): # This too easily means that a message sent by Poi ends up # being added as a reply on an issue that we have just # created. msg = u'Ignoring mail from portal email_from_address' logger.info(msg) return msg subject_line = message.get('Subject', '') subjects = [] decoded = Header.decode_header(subject_line) for decoded_string, charset in decoded: if charset: decoded_string = decoded_string.decode(charset) subjects.append(decoded_string) subject = u' '.join(subjects) logger.debug("Forum at %s received mail from %r to %r with " "subject %r", self.context.absolute_url(), from_address, to_addresses, subject) text, mimetype = self.get_text_and_mimetype(message) if not text: text = "Warning: no text found in email" mimetype = 'text/plain' logger.warn(text) logger.debug('Got payload with mimetype %s from email.', mimetype) # Create an attachment from the complete email. attachment = File('email.eml', 'E-mail', mail) tags = self.get_tags(message) if tags: logger.debug("Determined tags: %r", tags) else: logger.debug("Could not determine tags.") # Store original security manager. sm = getSecurityManager() # Possibly switch to a different user. self.switch_user(from_address) if self.add_attachments: attachments = self.get_attachments(message) attachments = [File(filename, filename, data) for filename, data in attachments] else: attachments = [attachment] target = self.find_conversation_or_thread(subject, text, tags, message) if target is None: # We don't allow creating conversations from mail, only replies logger.info('Could not find something to reply to') else: try: self.add_response(target, from_address, subject, text, mimetype, attachments) except Unauthorized, exc: logger.error(u'Unauthorized to add response: %s', exc) return u'Unauthorized' logger.info('Added mail as response to target %s', target.absolute_url())
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
def Show(): "Show an e-mail in HTML." global Allow, Remove, Attachment, Divider, PartTemplate, T # Deal with a particular message? if Form.has_key("msgid"): PVars["MsgID"] = Form["msgid"].value PVars.Save() # Check to make sure they're not trying to access anything other than email if not re.compile("^\d+\.\d+\.msg$").search(PVars["MsgID"]): CgiUtil.TermError("<tt>%s</tt> is not a valid message ID." % PVars["MsgID"], "Program error / corrupted link.", "retrieve pending e-mail", "", "Recheck link or contact TMDA programmers.") # Fetch the queue Queue = Pending.Queue(descending = 1, cache = 1) Queue.initQueue() Queue._loadCache() # Get e-mail template T = Template.Template("view.html") T["EmailClass"] = PVars[("ViewPending", "EmailClass")] # Locate messages in pending dir Msgs = Queue.listPendingIds() try: MsgIdx = Msgs.index(PVars["MsgID"]) except ValueError: # Oops. Perhaps they released the message? Get the list! raise Errors.MessageError # Any subcommands? if Form.has_key("subcmd"): # first/prev/next/last subcommands if Form["subcmd"].value == "first": MsgIdx = 0 PVars["Pager"] = 0 elif Form["subcmd"].value == "prev": if MsgIdx > 0: MsgIdx -= 1 PVars["Pager"] -= 1 elif Form["subcmd"].value == "next": if MsgIdx < (len(Msgs) - 1): MsgIdx += 1 PVars["Pager"] += 1 elif Form["subcmd"].value == "last": MsgIdx = len(Msgs) - 1 PVars["Pager"] = len(Msgs) # Toggle headers? elif Form["subcmd"].value == "headers": if PVars[("ViewPending", "Headers")] == "short": PVars[("ViewPending", "Headers")] = "all" else: PVars[("ViewPending", "Headers")] = "short" else: # Read in e-mail try: MsgObj = Pending.Message(PVars["MsgID"]) if Form["subcmd"].value == "pass": pass if Form["subcmd"].value == "delete": MsgObj.delete() elif Form["subcmd"].value == "release": MsgObj.release() PVars["InProcess"][PVars["MsgID"]] = 1 elif Form["subcmd"].value == "white": MsgObj.whitelist() MsgObj.release() PVars["InProcess"][PVars["MsgID"]] = 1 elif Form["subcmd"].value == "black": MsgObj.blacklist() MsgObj.delete() elif Form["subcmd"].value == "spamcop": CgiUtil.ReportToSpamCop(MsgObj) MsgObj.delete() # TODO: Check if subcmd is a custom filter and process accordingly del Msgs[MsgIdx] except IOError: pass # So which message are we on now? if len(Msgs) == 0: # Oops! None left! PVars.Save() raise Errors.MessageError if MsgIdx >= len(Msgs): MsgIdx = len(Msgs) - 1 PVars["MsgID"] = Msgs[MsgIdx] # Save session PVars.Save() # Get message ID T["MsgID"] = Msgs[MsgIdx] PVars["MsgID"] = Msgs[MsgIdx] # Grey out the first & prev buttons? if MsgIdx == 0: T["FirstButton1Active"] T["PrevButton1Active"] T["FirstButton2Active"] T["PrevButton2Active"] else: T["FirstButton1Inactive"] T["PrevButton1Inactive"] T["FirstButton2Inactive"] T["PrevButton2Inactive"] # Grey out the next & last buttons? if MsgIdx == (len(Msgs) - 1): T["NextButton1Active"] T["LastButton1Active"] T["NextButton2Active"] T["LastButton2Active"] else: T["NextButton1Inactive"] T["LastButton1Inactive"] T["NextButton2Inactive"] T["LastButton2Inactive"] # Use Javascript confirmation? if PVars[("General", "UseJSConfirm")] == "Yes": T["OnSubmit"] = "onSubmit=\"return TestConfirm()\"" T["DeleteURL"] = "javascript:ConfirmDelete()" T["BlacklistURL"] = "javascript:ConfirmBlacklist()" T["SpamCopURL"] = "javascript:ConfirmSpamCop()" else: T["OnSubmit"] = "" T["DeleteURL"] = "%s?cmd=view&subcmd=delete&SID=%s" % \ (os.environ["SCRIPT_NAME"], PVars.SID) T["BlacklistURL"] = "%s?cmd=view&subcmd=black&SID=%s" % \ (os.environ["SCRIPT_NAME"], PVars.SID) T["SpamCopURL"] = "%s?cmd=view&subcmd=spamcop&SID=%s" % \ (os.environ["SCRIPT_NAME"], PVars.SID) T["DispRange"] = "%d of %d" % (MsgIdx + 1, len(Msgs)) # Read in e-mail MsgObj = Pending.Message(PVars["MsgID"]) Queue._addCache(PVars["MsgID"]) Queue._saveCache() # Extract header row HeaderRow = T["HeaderRow"] if PVars[("ViewPending", "Headers")] == "all": # Remove header table T["ShortHeaders"] # Generate all headers Headers = "" for Line in CgiUtil.Escape(MsgObj.show()).split("\n"): if Line == "": break # Decode internationalized headers for decoded in email.Header.decode_header( Line ): Headers += decoded[0] + " " if decoded[1]: cset = email.Charset.Charset(decoded[1]).input_charset.split() T["CharSet"] = cset[0] Headers += "\n" T["Headers"] = '<pre class="Headers">%s</pre>' % Headers else: # Remove all header block T["AllHeaders"] # Generate short headers for Header in Defaults.SUMMARY_HEADERS: T["Name"] = Header.capitalize() value = "" # Decode internationalazed headers for decoded in email.Header.decode_header( MsgObj.msgobj[Header] ): value += decoded[0] + " " if decoded[1]: cset = email.Charset.Charset(decoded[1]).input_charset.split() T["CharSet"] = cset[0] T["Value"] = CgiUtil.Escape(value) HeaderRow.Add() # Go through each part and generate HTML Allow = re.split("[,\s]+", PVars[("ViewPending", "AllowTags")]) Remove = re.split("[,\s]+", PVars[("ViewPending", "BlockRemove")]) Attachment = T["Attachment"] Divider = T["Divider"] PartTemplate = T["Part"] ShowPart(MsgObj.msgobj) # Remove unneeded bits? NumCols = int(T["NumCols"]) # TODO: Programatically check a setting to see which are allowed, # and which should be shown. # For now, allow and show everything RlAllowed = 1 DlAllowed = 1 WhAllowed = 1 and Defaults.PENDING_WHITELIST_APPEND BlAllowed = 1 and Defaults.PENDING_BLACKLIST_APPEND ScAllowed = 1 and PVars[("General", "SpamCopAddr")] FltAllowed = 1 RlShow = RlAllowed and 1 DlShow = DlAllowed and 1 WhShow = WhAllowed and 1 BlShow = BlAllowed and 1 ScShow = ScAllowed and 1 if not RlAllowed: T["RlAction"] if not RlShow: NumCols -= 1 T["RlIcon1"] T["RlIcon2"] if not DlAllowed: T["DlAction"] if not DlShow: NumCols -= 1 T["DlIcon1"] T["DlIcon2"] if not BlAllowed: T["BlAction"] if not BlShow: NumCols -= 1 T["BlIcon1"] T["BlIcon2"] if not WhAllowed: T["WhAction"] if not WhShow: NumCols -= 1 T["WhIcon1"] T["WhIcon2"] if not ScAllowed: T["ScAction"] if not ScShow: NumCols -= 1 T["SCIcon1"] T["SCIcon2"] if FltAllowed: T["FilterOptions"] = CgiUtil.getFilterOptions() else: T["FilterOptions"] = "" T["NumCols"] = NumCols if len(Attachment.HTML) == 0: T["NoAttachments"] # Display HTML page with email included. print T
#!/usr/bin/python ''' File: mail_parser.py Author: Sigurd Fosseng Licence: MIT Licence Description: Converts the subject of the email given through stdin to Unicode, and sends it through xmlrpc ''' from email.Parser import Parser from email import Header import xmlrpclib import sys #mime handling data = sys.stdin.read() message = Parser().parsestr(data) subject = unicode(Header.make_header(Header.decode_header(message['subject']))) #send to bot s = xmlrpclib.Server("http://localhost:5656/") s.say(subject)
import smtplib def _format_addr(s): name,addr=parseaddr(s) return formataddr((Header(name,'utf-8').encode(),addr)) from_addr = input('From: ') password = input('Password: '******'To: ') smtp_server = input('SMTP server: ') msg=MIMEText('hello,world!','plain','utf-8') msg['From']=_format_addr('Python爱好者 <%S>' %from_addr) msg['to']=_format_addr('管理员 <%s>' %to_addr) msg['Subject']=Header('来自SMTP的问候。。。','utf-8').encode() server = smtplib.SMTP(smtp_server, 25) server.set_debuglevel(1) server.login(from_addr, password) server.sendmail(from_addr, [to_addr], msg.as_string()) server.quit() # 我们编写了一个函数_format_addr()来格式化一个邮件地址。注意不能简单地传入name <*****@*****.**>, # 因为如果包含中文,需要通过Header对象进行编码。msg['To']接收的是字符串而不是list,如果有多个邮件地址,用,分隔即可。 # 如果我们要发送HTML邮件,而不是普通的纯文本文件怎么办?方法很简单,在构造MIMEText对象时, # 把HTML字符串传进去,再把第二个参数由plain变为html就可以了 msg = MIMEText('<html><body><h1>Hello</h1>' +'<p>send by <a href="http://www.python.org">Python</a>...</p>' +'</body></html>', 'html', 'utf-8')
def createMessage(composer, cabinet, msgRepliedTo, fromAddress, toAddresses, subject, messageBody, cc, bcc, files, createMessageObject=None): """ Create an outgoing message, format the body into MIME parts, and populate its headers. @param createMessageObject: A one-argument callable which will be invoked with a file-like object containing MIME text and which should return a Message instance associated with objects representing that MIME data. """ MC.add_charset('utf-8', None, MC.QP, 'utf-8') encode = lambda s: MH.Header(s).encode() s = S.StringIO() wrappedMsgBody = FlowedParagraph.fromRFC2646(messageBody).asRFC2646() m = MT.MIMEText(wrappedMsgBody, 'plain', 'utf-8') m.set_param("format", "flowed") fileItems = [] if files: attachmentParts = [] for storeID in files: a = composer.store.getItemByID(long(storeID)) if isinstance(a, Part): a = cabinet.createFileItem( a.getParam('filename', default=u'', header=u'content-disposition'), unicode(a.getContentType()), a.getBody(decode=True)) fileItems.append(a) attachmentParts.append(_fileItemToEmailPart(a)) m = MMP.MIMEMultipart('mixed', None, [m] + attachmentParts) m['From'] = encode(fromAddress.address) m['To'] = encode(mimeutil.flattenEmailAddresses(toAddresses)) m['Subject'] = encode(subject) m['Date'] = EU.formatdate() m['Message-ID'] = smtp.messageid('divmod.xquotient') if cc: m['Cc'] = encode(mimeutil.flattenEmailAddresses(cc)) if msgRepliedTo is not None: #our parser does not remove continuation whitespace, so to #avoid duplicating it -- refs = [ hdr.value for hdr in msgRepliedTo.impl.getHeaders("References") ] if len(refs) == 0: irt = [ hdr.value for hdr in msgRepliedTo.impl.getHeaders("In-Reply-To") ] if len(irt) == 1: refs = irt else: refs = [] msgids = msgRepliedTo.impl.getHeaders("Message-ID") for hdr in msgids: msgid = hdr.value refs.append(msgid) #As far as I can tell, the email package doesn't handle #multiple values for headers automatically, so here's some #continuation whitespace. m['References'] = u'\n\t'.join(refs) m['In-Reply-To'] = msgid break G.Generator(s).flatten(m) s.seek(0) if createMessageObject is None: def createMessageObject(messageFile): return composer.createMessageAndQueueIt(fromAddress.address, messageFile, True) msg = createMessageObject(s) # there is probably a better way than this, but there # isn't a way to associate the same file item with multiple # messages anyway, so there isn't a need to reflect that here for fileItem in fileItems: fileItem.message = msg return msg
def cmd_bar(self, _chan, _args, sender_nick): "envoie un email aux grelakins" # vérification que l'invocateur soit un grelakins if hashlib.sha224(sender_nick).hexdigest() in self.liste_grelakins: # vérification que c'est la première invocation du messager if self.date_bar != str(time.strftime('%d/%m/%y', time.localtime())): heure = _args[0].decode('utf-8') lieu = ' '.join(_args[1:]).decode('utf-8') lieu = lieu.lower().strip().replace(" ", "") if re.match(r"(1[6-9]|2[0-4])+([hH]$|([hH]+" + "[0-5][0-9])|[:]+[0-5][0-9]+)", heure): # test de la compatibilité du format de l'heure # REGLE: on va au bar entre 16h et 24h59, # après c'est fermé, avant c'est être alcoolique for cle, valeur in self.liste_bar.items(): if lieu in valeur: # teste si le bar proposé est cool from_address = [u"Honorable tofbot", os.getenv( "TOFBOT_MAIL", "")] pwd = "" recipient = [u"Michels", os.getenv( "TOFBOT_MAILINGLIST", "")] subject = u"Bar ce soir" content = u"""Bonsoir les jeunes, Aujourd'hui, certains Michels vont au bar %s à %s. Rejoignez les! Tofbot, au service de %s """ % (cle, heure, sender_nick) content = content.encode('utf-8') Charset.add_charset('utf-8', Charset.QP, Charset.QP, 'utf-8') msg = MIMEMultipart('alternative') msg['Subject'] = "%s" % Header(subject, 'utf-8') msg['From'] = "\"%s\" <%s>" % (Header( from_address[0], 'utf-8'), from_address[1]) msg['To'] = "\"%s\" <%s>" % ( Header(recipient[0], 'utf-8'), recipient[1]) txtpart = MIMEText(content, 'plain', 'UTF-8') msg.attach(txtpart) str_out = StringIO() g = Generator(str_out, False) g.flatten(msg) mail_server = "localhost" server = smtplib.SMTP(mail_server, 25) server.ehlo() server.sendmail(from_address[1], recipient[1], str_out.getvalue()) server.quit() # message de confirmation de l'envoi de l'email self.say(u"Michels avertis!") self.date_bar = str(time.strftime( '%d/%m/%y', time.localtime())) return # avertissement bar non autorisé self.say(u"J'envoie pas ce mail, ce bar n'est pas cool!") else: # avertissement mauvaise heure if re.match(r"^(0[0-9]|1[0-5])", heure): # cas de l'heure trop matinale pour un Michel self.say(u"Beaucoup trop tôt, mec!") else: # cas d'un format horaire faux self.say(u"Euh... L'heure n'est pas claire.") else: self.say(u"Rameutage au bar déjà invoqué aujourd'hui") else: self.say(u"Seul un Grelakins autorisé peut envoyer un mail !bar")
#!/usr/bin/env python import sys, email, codecs from email import Header msg = email.message_from_file(sys.stdin) for header, value in msg.items(): headerparts = Header.decode_header(value) headerval = [] for part in headerparts: data, charset = part if charset is None: charset = 'ascii' dec = codecs.getdecoder(charset) enc = codecs.getencoder('iso-8859-1') data = enc(dec(data)[0])[0] headerval.append(data) print "%s: %s" % (header, " ".join(headerval))
def _format_addr(s): name,addr=parseaddr(s) return formataddr((Header(name,'utf-8').encode(),addr))