Package emma :: Package interface :: Package email :: Module message
[hide private]
[frames] | no frames]

Source Code for Module emma.interface.email.message

  1  """ 
  2  email message support 
  3   
  4  @copyright: (c) 2011 hackmeeting U{http://sindominio.net/hackmeeting} 
  5  @author: Ruben Pollan 
  6  @organization: hackmeeting U{http://sindominio.net/hackmeeting} 
  7  @contact: meskio@sindominio.net 
  8  @license: 
  9    This program is free software; you can redistribute it and/or 
 10    modify it under the terms of the Do What The Fuck You Want To 
 11    Public License, Version 2, as published by Sam Hocevar. See 
 12    U{http://sam.zoy.org/projects/COPYING.WTFPL} for more details. 
 13  """ 
 14   
 15  import pyzmail 
 16  import re 
 17  from email.utils import parsedate 
 18  from time import mktime 
 19  from datetime import datetime 
 20   
 21  from emma.interface import message 
 22   
 23   
24 -class Message(message.Message):
25 """ 26 email message 27 28 All the headers apears on the dictionary as msg[hdr_name]. The attachments 29 are a list on the msg['attachments']. 30 """
31 - def __init__(self, list_lines):
32 message.Message.__init__(self, tpe='email') 33 34 msgStr = '\n'.join(list_lines) 35 msg = pyzmail.PyzMessage.factory(msgStr) 36 37 d = msg_to_dict(msg) 38 self.update(d) 39 timestamp = mktime(parsedate(self['Date'])) 40 self['Date'] = datetime.fromtimestamp(timestamp) 41 self['Commands'] = self.commands() 42 self['Tags'] = self.tags()
43
44 - def commands(self):
45 """ 46 get a list of the commands inside the email 47 48 Everithing with the form __cmd params__ will be reconice as command 49 50 @returns: [(cmd, params)] 51 """ 52 if 'Commands' in self: 53 return self['Commands'] 54 55 text = self['Body'] 56 commands = [] 57 cmd = ["", ""] 58 isCmd = False 59 isArg = False 60 isComment = False 61 for i in range(len(text)): 62 # don't parse the commented lines 63 # ignore everyline starting with '>' 64 if text[i] == '>': 65 j = i-1 66 while text[j] in (' ', '\t'): 67 j -= 1 68 if text[j] == '\n': 69 isComment = True 70 elif text[i] == '\n': 71 isComment = False 72 if isComment: 73 if isArg: 74 cmd[1] += text[i] 75 continue 76 77 if text[i-1] != '\\' and text[i:i+2] == '._' and (isCmd or isArg): 78 isArg = False 79 commands.append(cmd) 80 cmd = ["", ""] 81 elif isCmd: 82 if text[i] == ' ': 83 isArg = True 84 isCmd = False 85 else: 86 cmd[0] += text[i] 87 elif isArg: 88 if text[i:i+3] in ('\\._', '\\_.'): 89 pass 90 else: 91 cmd[1] += text[i] 92 elif text[i-1] != '\\' and text[i-1:i+1] == '_.': 93 isCmd = True 94 95 return commands
96
97 - def tags(self):
98 """ 99 get a list of the tags from the subject 100 101 The text between [ and ] is consider as a tag 102 103 @returns: [tag] 104 """ 105 tagexp = re.compile(r"\[([^\]]*)\]") 106 subject = self['Subject'] 107 return tagexp.findall(subject)
108 109
110 -def msg_to_dict(msg):
111 """ 112 Convert a PyZmail message to a dictionary 113 114 @type msg: PyzMessage 115 @param msg: email to convert 116 @returns: {'Header': 'content'} 117 """ 118 # FIXME: any repeated header will be ignored 119 # Usually it is only 'Received' header 120 d = {} 121 122 if msg.text_part: 123 body = msg.text_part.get_payload() 124 charset = msg.text_part.charset 125 else: 126 body = msg.get_payload() 127 charset = msg.get_charset() 128 if charset: 129 charset = charset.lower() 130 i = charset.find('iso') 131 u = charset.find('utf') 132 if i > 0: 133 charset = charset[i:] 134 elif u > 0: 135 charset = charset[u:] 136 # Some old emails say it's ascii or unkown but in reality is not 137 # not use any charset not iso or utf 138 elif i != 0 and u != 0: 139 charset = None 140 141 for header in msg.keys(): 142 value = msg.get_decoded_header(header) 143 value, _ = pyzmail.decode_text(value, charset, None) 144 value = value.encode('UTF-8') 145 header = header.replace('.', ',') # mongoDB don't likes '.' on keys 146 d[header] = value 147 148 attach = [] 149 if type(body) == str: 150 body, _ = pyzmail.decode_text(body, charset, None) 151 body = body.encode('UTF-8') 152 # On attachments of emails sometimes it end up with a list of email.message 153 elif type(body) == list: 154 for part in body: 155 zmail = pyzmail.PyzMessage(part) 156 a = msg_to_dict(zmail) 157 attach.append(a) 158 body = attach[0]['Body'] 159 d['Body'] = body 160 161 if len(msg.mailparts) > 1: 162 for mailpart in msg.mailparts: 163 zmail = pyzmail.PyzMessage(mailpart.part) 164 a = msg_to_dict(zmail) 165 attach.append(a) 166 167 if attach: 168 d['Attachments'] = attach 169 170 return d
171