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
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 """
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
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
63
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
108
109
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
119
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
137
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('.', ',')
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
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