root / logilab.pylintinstaller / logilab / common / umessage.py

Revision 202:d67e86292521, 3.7 kB (checked in by tziade@…, 9 months ago)

added logilab.pylintinstaller

Line 
1"""unicode email support"""
2
3import email
4from email.Utils import parseaddr, parsedate
5from email.Header import decode_header
6
7try:
8    from mx.DateTime import DateTime
9except ImportError:
10    def DateTime(*args): return None
11
12def decode_QP(string):
13    parts = []
14    for decoded, charset in decode_header(string):
15        if charset is None:
16            charset = 'iso-8859-15'
17        parts.append(unicode(decoded, charset, 'replace'))
18
19    return u' '.join(parts)
20
21def message_from_file(fd):
22    try:
23        return UMessage(email.message_from_file(fd))
24    except email.Errors.MessageParseError:
25        return ''
26   
27def message_from_string(string):
28    try:
29        return UMessage(email.message_from_string(string))
30    except email.Errors.MessageParseError:
31        return ''
32   
33class UMessage:
34    """Encapsulates an email.Message instance and returns only unicode objects"""
35
36    def __init__(self, message):
37        self.message = message
38
39    # email.Message interface #################################################
40   
41    def get(self, header, default=None):
42        value = self.message.get(header, default)
43        if value:
44            return decode_QP(value)
45        return value
46
47    def get_all(self, header, default=()):
48        return [decode_QP(val) for val in self.message.get_all(header, default)
49                if val is not None]
50   
51    def get_payload(self, index=None, decode=False):
52        message = self.message
53        if index is None:
54            payload = message.get_payload(index, decode)
55            if isinstance(payload, list):
56                return [UMessage(msg) for msg in payload]
57            if message.get_content_maintype() != 'text':
58                return payload
59
60            charset = message.get_content_charset() or 'iso-8859-1'
61            if charset == 'unknown-8bit':
62                charset = 'iso-8859-1'
63            return unicode(payload or '', charset)
64        else:
65            payload = UMessage(message.get_payload(index, decode))
66        return payload
67
68    def is_multipart(self):
69        return self.message.is_multipart()
70
71    def get_boundary(self):
72        return self.message.get_boundary()
73
74    def walk(self):
75        for part in self.message.walk():
76            yield UMessage(part)
77   
78    def get_content_maintype(self):
79        return unicode(self.message.get_content_maintype())
80
81    def get_content_type(self):
82        return unicode(self.message.get_content_type())
83
84    def get_filename(self, failobj=None):
85        value = self.message.get_filename(failobj)
86        if value is failobj:
87            return value
88        try:
89            return unicode(value)
90        except UnicodeDecodeError:
91            return u'error decoding filename'
92
93    # other convenience methods ###############################################
94
95    def headers(self):
96        """return an unicode string containing all the message's headers"""
97        values = []
98        for header in self.message.keys():
99            values.append(u'%s: %s' % (header, self.get(header)))
100        return '\n'.join(values)
101
102    def multi_addrs(self, header):
103        """return a list of 2-uple (name, address) for the given address (which
104        is exepected to be an header containing address such as from, to, cc...)
105        """
106        persons = []
107        for person in self.get_all(header, ()):
108            name, mail = parseaddr(person)
109            persons.append((name, mail))
110        return persons
111   
112    def date(self):
113        """return a mx.DateTime object for the email's date or None if no date is
114        set or if it can't be parsed
115        """
116        value = self.get('date')
117        if value:
118            datetuple = parsedate(value)
119            if datetuple:
120                return DateTime(*datetuple[:6])
121        return None
122
123   
124
125   
Note: See TracBrowser for help on using the browser.