Here's the main code:
Initialize, define mail server
Self. Imap_server= ' imap.gmail.com '
Self. imap_port=993
Self. M = None
Self.response
Self.mailboxes = []
Login, select mailbox:
Self. M = Imaplib. Imap4_ssl (self. Imap_server, self. Imap_por
RC, self.response = self. M.login (username, password)
Tye,data = M.m.select ()
Mail search:
RET, msgnums = M.m.search (None, ' body ', datapath)
Get message information:
Status, Response = self. M.fetch (ID, "(RFC822)")
Mailtext = response[0][1]
Mail_message = email.message_from_string (Mailtext)
Subject = Unicode (email. Header.make_header (email. Header.decode_header (mail_message[' subject '))
#print "subject_________:" +subject
Mail_from = Email.utils.parseaddr (mail_message["from"]) [1]
mail_to = Email.utils.parseaddr (mail_message["to"]) [1]
Time = mail_message[' Date ']
print ' [' +mail_message[' Date ']+ '] ' + ' \ n ' from: ' +mail_from+ ' to: ' +mail_to+ ' + ' Subject: ' +subject+ ' \ n '
Return Self.get_first_text_block (mail_message), subject, Mail_from, time
MainType = Email_message_instance.get_content_maintype () return the content of the message is what type, if the text is better to deal with, if it is multipart, also have to traverse Email_ Message_instance to be processed according to different types.
Email.message_from_string (Mailtext) Returns a structure that contains basic information about the message
The pain in the mail is the problem of string coding, after all, everyone's message format is not the same, some are Unicode, some are utf-8, some are gb2312, there are accessories, pictures and many other formats,
Of course, this time only to deal with the text, there is no need to deal with attachments and pictures of these. I am all unified to convert the character to Unicode to deal with.
String processing, you can use Chardet to determine the type of string, read and write files can be used to specify the type of read-write character codecs
Add three examples
Example 1
From Project Georegistry, under Directory Georegistry/lib, in source file smtp.py.
Score:13
Vote
Vote
Def SendMessage (Frombyvalue, tobyvalue, subject, Body, Headerbyname=none):
' Send a message using SMTP '
# Prepare
message = Email.message.Message ()
Message.add_header (' From ', Email.utils.formataddr (frombyvalue[' nickname ', frombyvalue[' email '))
Message.add_header (' to ', Email.utils.formataddr (tobyvalue[' nickname ', tobyvalue[' email '))
Message.add_header (' Subject ', subject)
Message.set_payload (body)
If Headerbyname:
For key, value in Headerbyname.iteritems ():
Message.add_header (key, value)
# Connect to Server
If frombyvalue[' smtp '] = = ' localhost ':
Server = Smtplib. SMTP (' localhost ')
Else
Server = Smtplib. Smtp_ssl (frombyvalue[' SMTP '), 465)
If Len (frombyvalue[' username ']):
Server.login (frombyvalue[' username '), frombyvalue[' password ']
# Send Mail
Try
Server.sendmail (frombyvalue[' email '), tobyvalue[' email '], message.as_string ()
Except Socket.error, error:
Raise Smtperror (Error)
Finally
Server.quit ()
Example 2
From Project Appengine-python3-master, under Directory google/appengine/tools/devappserver2/admin, in source file Mail_ request_handler_test.py.
Score:10
Vote
Vote
def test_send (self):
Self.mox.StubOutWithMock (Mail_request_handler. Mailrequesthandler,
' Dispatcher ')
Handler = Mail_request_handler. Mailrequesthandler (None, none)
Handler.dispatcher = Self.mox.CreateMock (dispatcher. Dispatcher)
Handler.dispatcher.add_request (
Method= ' POST ',
Relative_url= ' URL ',
headers=[(' Content-type ', ' message/rfc822 ')],
body= ' mail message ',
source_ip= ' 0.1.0.20 ')
Message = Self.mox.CreateMock (email.message.Message)
Message.as_string (). Andreturn (' mail message ')
Self.mox.ReplayAll ()
Handler._send (' URL ', message)
Self.mox.VerifyAll ()
Example 3
From Project Python-sipsimple-master, under Directory sipsimple/streams/applications, in source file chat.py.
Score:8
Vote
Vote
def __str__ (self):
headers = []
If Self.sender:
Headers.append (U ' from:%s '% self.sender)
For recipient in self.recipients:
Headers.append (U ' to:%s '% recipient)
For recipient in self.courtesy_recipients:
Headers.append (U ' cc:%s '% recipient)
If Self.subject:
Headers.append (U ' Subject:%s '% self.subject)
If Self.subject is not None:
For Lang, translation in Self.subject.translations.iteritems ():
Headers.append (U ' subject:;lang=%s%s '% (lang, translation))
If Self.timestamp:
Headers.append (U ' DateTime:%s '% self.timestamp)
If self.required:
Headers.append (U ' Required:%s '% ', '. Join (self.required))
namespaces = {u ': self.standard_namespace}
For header in Self.additional_headers:
If Namespaces.get (Header.namespace.prefix, None)!= header.namespace:
If Header.namespace.prefix:
Headers.append (U ' NS:%s <%s> '% (Header.namespace.prefix, header.namespace))
Else
Headers.append (U ' NS: <%s> '% header.namespace)
Namespaces[header.namespace.prefix] = Header.namespace
If Header.namespace.prefix:
Headers.append (U '%s.%s:%s '% (Header.namespace.prefix, Header.name, Header.value))
Else
Headers.append (U '%s:%s '% (Header.name, header.value))
Headers.append (U ')
headers = ' \ r \ n '. Join (S.encode (' Cpim-headers ') for s in headers)
message = Message ()
Message.set_type (Self.content_type)
If Isinstance (Self.body, Unicode):
Message.set_param (' CharSet ', ' utf-8 ')
Message.set_payload (Self.body.encode (' Utf-8 '))
Else
Message.set_payload (Self.body)
return headers + ' \ r \ n ' + message.as_string ()
Example 4
From Project Odoo, under Directory Addons/mail, in source file mail_thread.py.
Score:8
Vote
Vote
def _message_extract_payload (self, Message, Save_original=false):
"" "Extract body as HTML and attachments from" ""
attachments = []
BODY = U ' "
If save_original:
Attachments.append ((' Original_email.eml ', message.as_string ())
If not Message.is_multipart () or ' text/' in Message.get (' Content-type ', '):
encoding = Message.get_content_charset ()
BODY = Message.get_payload (decode=true)
BODY = TOOLS.USTR (body, encoding, errors= ' replace ')
If message.get_content_type () = = ' Text/plain ':
# Text/plain-> <pre/>
BODY = tools.append_content_to_html (U ", Body, Preserve=true)
Else
Alternative = False
For part in Message.walk ():
If part.get_content_type () = = ' Multipart/alternative ':
Alternative = True
If part.get_content_maintype () = = ' multipart ':
Continue # Skip Container
# Part.get_filename returns decoded value if able to decode, coded otherwise.
# Original Get_filename is isn't able to decode Iso-8859-1 (for instance).
# Therefore, ISO encoded attachements are not able to is decoded properly with Get_filename
# code here partially copy of the original Get_filename method, but handle more encoding
Filename=part.get_param (' filename ', None, ' content-disposition ')
If not filename:
Filename=part.get_param (' name ', None)
If filename:
If isinstance (filename, tuple):
# RFC2231
Filename=email.utils.collapse_rfc2231_value (filename). Strip ()
Else
Filename=decode (filename)
encoding = Part.get_content_charset () # None-If attachment
# 1) Explicit Attachments-> Attachments
If filename or part.get (' content-disposition ', '). Strip (). StartsWith (' attachment '):
Attachments.append ((filename or ' attachment ', Part.get_payload (decode=true))
Continue
# 2) Text/plain-> <pre/>
If part.get_content_type () = = ' Text/plain ' and (not alternative or not):
BODY = tools.append_content_to_html (the body, Tools.ustr (Part.get_payload (decode=true),
Encoding, errors= ' replace '), preserve=true)
# 3) text/html-> Raw
Elif Part.get_content_type () = = ' text/html ':
html = TOOLS.USTR (Part.get_payload (decode=true), encoding, errors= ' replace ')
If alternative:
BODY = html
Else
BODY = tools.append_content_to_html (body, HTML, Plaintext=false)
# 4) Anything else-> attachment
Else
Attachments.append ((filename or ' attachment ', Part.get_payload (decode=true))
return body, attachments
Example 5
From Project OPENERP-KTV, under Directory Openerp/addons/mail, in source file mail_message.py.
Score:5
Vote
Vote
def parse_message (self, Message, Save_original=false):
"" "parses a string or email.message.Message representing an
RFC-2822 email, and returns a generic dict holding the
Message details.
:p Aram Message:the Message to parse
: Type Message:email.message.Message | string | Unicode
:p Aram BOOL Save_original:whether the returned dict
Should include an ' original ' entry with the Base64
Encoded source of the message.
: rtype:dict
: Return:a dict with the following structure, where each
Field May is present if missing in original
Message::
{' Message-id ': msg_id,
' Subject ': Subject,
' From ':
"To": To,
' CC ': CC,
' Headers ': {' X-mailer ': Mailer,
#.. All x-headers ...
},
' Subtype ': Msg_mime_subtype,
' Body_text ': plaintext_body
' body_html ': html_body,
' Attachments ': [(' file1 ', ' bytes '),
(' file2 ', ' bytes ')}
# ...
' Original ': Source_of_email,
}
"""
Msg_txt = Message
If isinstance (message, str):
Msg_txt = email.message_from_string (message)
# warning:message_from_string doesn ' t always work correctly on Unicode,
# We must use UTF-8 strings here:-(
If Isinstance (message, Unicode):
message = Message.encode (' Utf-8 ')
Msg_txt = email.message_from_string (message)
message_id = Msg_txt.get (' Message-id ', False)
msg = {}
if save_original:
# Save original, we need to is able to read the original email sometimes
&NBSP;&NBSP;&NBSP;&N bsp; msg[' original '] = message.as_string () If isinstance (message, message) \
Else Message
msg[' original '] = Base64.b64encode (msg[' original ')) # Binary fields are b64
If not message_id:
# Very Unusual situation, be we should being fault-tolerant here
message_id = Time.time ()
msg_txt[' message-id '] = message_id
_logger.info (' parsing message without message-id, generating a random one:%s ', message_id)
Fields = Msg_txt.keys ()
msg[' id '] = message_id
msg[' message-id '] = message_id
If ' Subject ' in fields:
msg[' subject '] = Decode (msg_txt.get (' subject '))
If ' Content-type ' in fields:
msg[' content-type '] = msg_txt.get (' Content-type ')
If ' from ' in fields:
Msg[' from '] = decode (Msg_txt.get (' from ') or Msg_txt.get_unixfrom ())
If ' to ' in fields:
Msg[' to '] = decode (Msg_txt.get (' to '))
If ' delivered-to ' in fields:
Msg[' to '] = decode (msg_txt.get (' delivered-to '))
If ' CC ' in fields:
msg[' cc ' = Decode (Msg_txt.get (' cc '))
If ' Cc ' in fields:
msg[' cc ' = Decode (Msg_txt.get (' cc '))
If ' reply-to ' in fields:
msg[' reply '] = decode (msg_txt.get (' reply-to '))
If ' Date ' in fields:
Try
DATE_HDR = Decode (Msg_txt.get (' Date '))
Parsed_date = Dateutil.parser.parse (DATE_HDR, Fuzzy=true)
If Parsed_date.utcoffset () is None:
# naive DateTime, so we arbitrarily decide to make it
# UTC, there ' s no better choice. Should not happen,
# as RFC2822 requires timezone offset in Date headers.
Stored_date = Parsed_date.replace (TZINFO=PYTZ.UTC)
Else
Stored_date = Parsed_date.astimezone (PYTZ.UTC)
Except Exception:
_logger.warning (' Failed to parse Date header%r in incoming mail '
' With Message-id%r, assuming current date/time. ',
Msg_txt.get (' Date '), message_id)
Stored_date = Datetime.datetime.now ()
msg[' Date ' = Stored_date.strftime ("%y-%m-%d%h:%m:%s")
If ' content-transfer-encoding ' in fields:
msg[' encoding '] = msg_txt.get (' content-transfer-encoding ')
If ' References ' in fields:
msg[' references '] = Msg_txt.get (' References ')
If ' in-reply-to ' in fields:
msg[' in-reply-to '] = msg_txt.get (' in-reply-to ')
msg[' headers '] = {}
msg[' subtype '] = ' plain '
For item in Msg_txt.items ():
If Item[0].startswith (' x '):
msg[' headers '].update ({item[0]: item[1]})
If not Msg_txt.is_multipart () or ' Text/plain ' in Msg.get (' Content-type ', '):
encoding = Msg_txt.get_content_charset ()
BODY = Tools.ustr (Msg_txt.get_payload (decode=true), encoding, errors= ' replace ')
If ' text/html ' in Msg.get (' Content-type ', '):
msg[' body_html ' = body
msg[' subtype ' = ' html '
BODY = Tools.html2plaintext (body)
msg[' body_text '] = tools.ustr (body, encoding, errors= ' replace ')
attachments = []
If Msg_txt.is_multipart () or ' multipart/alternative ' in Msg.get (' Content-type ', '):
BODY = ""
If ' multipart/alternative ' in Msg.get (' Content-type ', '):
msg[' subtype '] = ' alternative '
Else
msg[' subtype '] = ' mixed '
For part in Msg_txt.walk ():
If part.get_content_maintype () = = ' multipart ':
Continue
encoding = Part.get_content_charset ()
filename = Part.get_filename ()
If part.get_content_maintype () = = ' Text ':
Content = Part.get_payload (decode=true)
If filename:
Attachments.append ((filename, content))
Content = tools.ustr (content, encoding, errors= ' replace ')
If part.get_content_subtype () = = ' html ':
msg[' body_html '] = content
msg[' subtype '] = ' HTML ' # HTML version prevails
BODY = tools.ustr (tools.html2plaintext (content))
BODY = Body.replace (' & #13; ', ')
Elif Part.get_content_subtype () = = ' Plain ':
BODY = Content
Elif Part.get_content_maintype () in (' Application ', ' image '):
If filename:
Attachments.append ((Filename,part.get_payload (decode=true))
Else
res = Part.get_payload (decode=true)
Body + = TOOLS.USTR (res, encoding, errors= ' replace ')
msg[' body_text ' = body
msg[' attachments '] = attachments
# for backwards compatibility:
msg[' body '] = msg[' Body_text ']
msg[' sub_type '] = msg[' subtype '] or ' plain '
Return msg