|
- """
- This module contains classes for managing incoming emails
- """
-
- class IncomingMail:
- """
- Single incoming email object. Extracts, text / html and attachments from the email
- """
- def __init__(self, content):
- """
- Parse the incoming mail content
- """
- import email
-
- self.mail = email.message_from_string(content)
- self.text_content = ''
- self.html_content = ''
- self.attachments = []
- self.parse()
-
- def get_text_content(self):
- """
- Returns the text parts of the email. If None, then HTML parts
- """
- return self.text_content or self.html_content
-
- def get_charset(self, part):
- """
- Guesses character set
- """
- charset = part.get_content_charset()
- if not charset:
- import chardet
- charset = chardet.detect(str(part))['encoding']
-
- return charset
-
- def get_payload(self, part, charset):
- """
- get utf-8 encoded part content
- """
- try:
- return unicode(part.get_payload(decode=True),str(charset),"ignore").encode('utf8','replace')
- except LookupError, e:
- return part.get_payload()
-
- def get_attachment(self, part, charset):
- """
- Extracts an attachment
- """
- self.attachments.append({
- 'content-type': part.get_content_type(),
- 'filename': part.get_filename(),
- 'content': self.get_payload(part, charset)
- })
-
- def parse(self):
- """
- Extracts text, html and attachments from the mail
- """
- for part in self.mail.walk():
- self.process_part(part)
-
- def get_thread_id(self):
- """
- Extracts thread id of the message between first []
- from the subject
- """
- subject = self.mail.get('Subject', '')
- if '[' in subject and ']' in subject:
- return subject.split('[')[1].split(']')[0]
-
- def process_part(self, part):
- """
- Process a single part of an email
- """
- charset = self.get_charset(part)
- content_type = part.get_content_type()
-
- if content_type == 'text/plain':
- self.text_content += self.get_payload(part, charset)
-
- if content_type == 'text/html':
- self.html_content += self.get_payload(part, charset)
-
- if part.get_filename():
- self.get_attachment(part, charset)
-
- class POP3Mailbox:
- """
- A simple pop3 mailbox, abstracts connection and mail extraction
- To use, subclass it and override method process_message(from, subject, text, thread_id)
- """
-
- def __init__(self, settings_doc):
- """
- settings_doc must contain
- is_ssl, host, username, password
- (by name or object)
- """
- if type(settings_doc)==str:
- from webnotes.model.doc import Document
- self.settings = Document(settings_doc, settings_doc)
- else:
- self.settings = settings_doc
-
- def connect(self):
- """
- Connects to the mailbox
- """
- import poplib
-
- if self.settings.use_ssl:
- self.pop = poplib.POP3_SSL(self.settings.host)
- else:
- self.pop = poplib.POP3(self.settings.host)
- self.pop.user(self.settings.username)
- self.pop.pass_(self.settings.password)
-
-
- def get_messages(self):
- """
- Loads messages from the mailbox and calls
- process_message for each message
- """
-
- if not self.check_mails():
- return # nothing to do
-
- self.connect()
- num = len(self.pop.list()[1])
- for m in range(num):
- msg = self.pop.retr(m+1)
- try:
- self.process_message(IncomingMail('\n'.join(msg[1])))
- except:
- pass
- self.pop.dele(m+1)
- self.pop.quit()
-
- def check_mails(self):
- """
- To be overridden
- If mailbox is to be scanned, returns true
- """
- return True
-
- def process_message(self, mail):
- """
- To be overriden
- """
- pass
|