annotate Lib/email/utils.py @ 58925:eecf1bef052d 2.6

Merged revisions 78207 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r78207 | ezio.melotti | 2010-02-17 01:26:09 +0200 (Wed, 17 Feb 2010) | 1 line #7930: fix stripid ........
author Ezio Melotti <ezio.melotti@gmail.com>
date Tue, 16 Feb 2010 23:29:44 +0000
parents fea53258ab7e
children 9eabba6ded09
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
57456
fea53258ab7e Add mktime_tz to __all__. It's documented as being available in email.utils.
Barry Warsaw <barry@python.org>
parents: 45468
diff changeset
1 # Copyright (C) 2001-2009 Python Software Foundation
37078
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
2 # Author: Barry Warsaw
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
3 # Contact: email-sig@python.org
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
4
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
5 """Miscellaneous utilities."""
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
6
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
7 __all__ = [
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
8 'collapse_rfc2231_value',
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
9 'decode_params',
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
10 'decode_rfc2231',
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
11 'encode_rfc2231',
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
12 'formataddr',
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
13 'formatdate',
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
14 'getaddresses',
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
15 'make_msgid',
57456
fea53258ab7e Add mktime_tz to __all__. It's documented as being available in email.utils.
Barry Warsaw <barry@python.org>
parents: 45468
diff changeset
16 'mktime_tz',
37078
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
17 'parseaddr',
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
18 'parsedate',
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
19 'parsedate_tz',
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
20 'unquote',
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
21 ]
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
22
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
23 import os
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
24 import re
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
25 import time
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
26 import base64
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
27 import random
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
28 import socket
39132
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
29 import urllib
37078
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
30 import warnings
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
31
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
32 from email._parseaddr import quote
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
33 from email._parseaddr import AddressList as _AddressList
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
34 from email._parseaddr import mktime_tz
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
35
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
36 # We need wormarounds for bugs in these methods in older Pythons (see below)
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
37 from email._parseaddr import parsedate as _parsedate
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
38 from email._parseaddr import parsedate_tz as _parsedate_tz
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
39
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
40 from quopri import decodestring as _qdecode
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
41
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
42 # Intrapackage imports
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
43 from email.encoders import _bencode, _qencode
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
44
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
45 COMMASPACE = ', '
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
46 EMPTYSTRING = ''
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
47 UEMPTYSTRING = u''
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
48 CRLF = '\r\n'
39112
ff539707a1ed decode_rfc2231(): Be more robust against buggy RFC 2231 encodings.
Barry Warsaw <barry@python.org>
parents: 37078
diff changeset
49 TICK = "'"
37078
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
50
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
51 specialsre = re.compile(r'[][\\()<>@,:;".]')
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
52 escapesre = re.compile(r'[][\\()"]')
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
53
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
54
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
55
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
56 # Helpers
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
57
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
58 def _identity(s):
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
59 return s
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
60
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
61
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
62 def _bdecode(s):
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
63 # We can't quite use base64.encodestring() since it tacks on a "courtesy
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
64 # newline". Blech!
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
65 if not s:
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
66 return s
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
67 value = base64.decodestring(s)
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
68 if not s.endswith('\n') and value.endswith('\n'):
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
69 return value[:-1]
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
70 return value
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
71
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
72
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
73
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
74 def fix_eols(s):
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
75 """Replace all line-ending characters with \r\n."""
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
76 # Fix newlines with no preceding carriage return
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
77 s = re.sub(r'(?<!\r)\n', CRLF, s)
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
78 # Fix carriage returns with no following newline
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
79 s = re.sub(r'\r(?!\n)', CRLF, s)
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
80 return s
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
81
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
82
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
83
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
84 def formataddr(pair):
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
85 """The inverse of parseaddr(), this takes a 2-tuple of the form
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
86 (realname, email_address) and returns the string value suitable
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
87 for an RFC 2822 From, To or Cc header.
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
88
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
89 If the first element of pair is false, then the second element is
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
90 returned unmodified.
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
91 """
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
92 name, address = pair
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
93 if name:
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
94 quotes = ''
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
95 if specialsre.search(name):
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
96 quotes = '"'
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
97 name = escapesre.sub(r'\\\g<0>', name)
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
98 return '%s%s%s <%s>' % (quotes, name, quotes, address)
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
99 return address
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
100
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
101
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
102
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
103 def getaddresses(fieldvalues):
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
104 """Return a list of (REALNAME, EMAIL) for each fieldvalue."""
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
105 all = COMMASPACE.join(fieldvalues)
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
106 a = _AddressList(all)
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
107 return a.addresslist
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
108
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
109
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
110
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
111 ecre = re.compile(r'''
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
112 =\? # literal =?
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
113 (?P<charset>[^?]*?) # non-greedy up to the next ? is the charset
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
114 \? # literal ?
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
115 (?P<encoding>[qb]) # either a "q" or a "b", case insensitive
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
116 \? # literal ?
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
117 (?P<atom>.*?) # non-greedy up to the next ?= is the atom
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
118 \?= # literal ?=
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
119 ''', re.VERBOSE | re.IGNORECASE)
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
120
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
121
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
122
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
123 def formatdate(timeval=None, localtime=False, usegmt=False):
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
124 """Returns a date string as specified by RFC 2822, e.g.:
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
125
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
126 Fri, 09 Nov 2001 01:08:47 -0000
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
127
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
128 Optional timeval if given is a floating point time value as accepted by
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
129 gmtime() and localtime(), otherwise the current time is used.
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
130
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
131 Optional localtime is a flag that when True, interprets timeval, and
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
132 returns a date relative to the local timezone instead of UTC, properly
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
133 taking daylight savings time into account.
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
134
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
135 Optional argument usegmt means that the timezone is written out as
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
136 an ascii string, not numeric one (so "GMT" instead of "+0000"). This
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
137 is needed for HTTP, and is only used when localtime==False.
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
138 """
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
139 # Note: we cannot use strftime() because that honors the locale and RFC
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
140 # 2822 requires that day and month names be the English abbreviations.
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
141 if timeval is None:
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
142 timeval = time.time()
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
143 if localtime:
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
144 now = time.localtime(timeval)
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
145 # Calculate timezone offset, based on whether the local zone has
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
146 # daylight savings time, and whether DST is in effect.
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
147 if time.daylight and now[-1]:
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
148 offset = time.altzone
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
149 else:
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
150 offset = time.timezone
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
151 hours, minutes = divmod(abs(offset), 3600)
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
152 # Remember offset is in seconds west of UTC, but the timezone is in
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
153 # minutes east of UTC, so the signs differ.
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
154 if offset > 0:
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
155 sign = '-'
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
156 else:
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
157 sign = '+'
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
158 zone = '%s%02d%02d' % (sign, hours, minutes // 60)
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
159 else:
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
160 now = time.gmtime(timeval)
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
161 # Timezone offset is always -0000
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
162 if usegmt:
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
163 zone = 'GMT'
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
164 else:
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
165 zone = '-0000'
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
166 return '%s, %02d %s %04d %02d:%02d:%02d %s' % (
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
167 ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'][now[6]],
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
168 now[2],
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
169 ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
170 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'][now[1] - 1],
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
171 now[0], now[3], now[4], now[5],
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
172 zone)
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
173
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
174
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
175
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
176 def make_msgid(idstring=None):
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
177 """Returns a string suitable for RFC 2822 compliant Message-ID, e.g:
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
178
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
179 <20020201195627.33539.96671@nightshade.la.mastaler.com>
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
180
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
181 Optional idstring if given is a string used to strengthen the
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
182 uniqueness of the message id.
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
183 """
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
184 timeval = time.time()
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
185 utcdate = time.strftime('%Y%m%d%H%M%S', time.gmtime(timeval))
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
186 pid = os.getpid()
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
187 randint = random.randrange(100000)
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
188 if idstring is None:
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
189 idstring = ''
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
190 else:
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
191 idstring = '.' + idstring
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
192 idhost = socket.getfqdn()
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
193 msgid = '<%s.%s.%s%s@%s>' % (utcdate, pid, randint, idstring, idhost)
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
194 return msgid
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
195
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
196
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
197
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
198 # These functions are in the standalone mimelib version only because they've
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
199 # subsequently been fixed in the latest Python versions. We use this to worm
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
200 # around broken older Pythons.
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
201 def parsedate(data):
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
202 if not data:
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
203 return None
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
204 return _parsedate(data)
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
205
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
206
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
207 def parsedate_tz(data):
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
208 if not data:
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
209 return None
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
210 return _parsedate_tz(data)
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
211
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
212
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
213 def parseaddr(addr):
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
214 addrs = _AddressList(addr).addresslist
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
215 if not addrs:
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
216 return '', ''
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
217 return addrs[0]
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
218
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
219
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
220 # rfc822.unquote() doesn't properly de-backslash-ify in Python pre-2.3.
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
221 def unquote(str):
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
222 """Remove quotes from a string."""
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
223 if len(str) > 1:
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
224 if str.startswith('"') and str.endswith('"'):
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
225 return str[1:-1].replace('\\\\', '\\').replace('\\"', '"')
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
226 if str.startswith('<') and str.endswith('>'):
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
227 return str[1:-1]
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
228 return str
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
229
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
230
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
231
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
232 # RFC2231-related functions - parameter encoding and decoding
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
233 def decode_rfc2231(s):
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
234 """Decode string according to RFC 2231"""
39112
ff539707a1ed decode_rfc2231(): Be more robust against buggy RFC 2231 encodings.
Barry Warsaw <barry@python.org>
parents: 37078
diff changeset
235 parts = s.split(TICK, 2)
ff539707a1ed decode_rfc2231(): Be more robust against buggy RFC 2231 encodings.
Barry Warsaw <barry@python.org>
parents: 37078
diff changeset
236 if len(parts) <= 2:
39132
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
237 return None, None, s
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
238 return parts
37078
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
239
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
240
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
241 def encode_rfc2231(s, charset=None, language=None):
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
242 """Encode string according to RFC 2231.
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
243
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
244 If neither charset nor language is given, then s is returned as-is. If
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
245 charset is given but not language, the string is encoded using the empty
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
246 string for language.
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
247 """
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
248 import urllib
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
249 s = urllib.quote(s, safe='')
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
250 if charset is None and language is None:
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
251 return s
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
252 if language is None:
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
253 language = ''
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
254 return "%s'%s'%s" % (charset, language, s)
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
255
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
256
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
257 rfc2231_continuation = re.compile(r'^(?P<name>\w+)\*((?P<num>[0-9]+)\*?)?$')
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
258
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
259 def decode_params(params):
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
260 """Decode parameters list according to RFC 2231.
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
261
39132
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
262 params is a sequence of 2-tuples containing (param name, string value).
37078
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
263 """
39132
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
264 # Copy params so we don't mess with the original
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
265 params = params[:]
37078
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
266 new_params = []
39132
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
267 # Map parameter's name to a list of continuations. The values are a
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
268 # 3-tuple of the continuation number, the string value, and a flag
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
269 # specifying whether a particular segment is %-encoded.
37078
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
270 rfc2231_params = {}
39132
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
271 name, value = params.pop(0)
37078
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
272 new_params.append((name, value))
39132
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
273 while params:
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
274 name, value = params.pop(0)
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
275 if name.endswith('*'):
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
276 encoded = True
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
277 else:
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
278 encoded = False
37078
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
279 value = unquote(value)
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
280 mo = rfc2231_continuation.match(name)
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
281 if mo:
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
282 name, num = mo.group('name', 'num')
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
283 if num is not None:
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
284 num = int(num)
39132
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
285 rfc2231_params.setdefault(name, []).append((num, value, encoded))
37078
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
286 else:
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
287 new_params.append((name, '"%s"' % quote(value)))
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
288 if rfc2231_params:
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
289 for name, continuations in rfc2231_params.items():
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
290 value = []
39132
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
291 extended = False
37078
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
292 # Sort by number
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
293 continuations.sort()
39132
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
294 # And now append all values in numerical order, converting
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
295 # %-encodings for the encoded segments. If any of the
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
296 # continuation names ends in a *, then the entire string, after
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
297 # decoding segments and concatenating, must have the charset and
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
298 # language specifiers at the beginning of the string.
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
299 for num, s, encoded in continuations:
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
300 if encoded:
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
301 s = urllib.unquote(s)
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
302 extended = True
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
303 value.append(s)
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
304 value = quote(EMPTYSTRING.join(value))
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
305 if extended:
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
306 charset, language, value = decode_rfc2231(value)
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
307 new_params.append((name, (charset, language, '"%s"' % value)))
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
308 else:
417cdede0688 More RFC 2231 improvements for the email 4.0 package. As Mark Sapiro rightly
Barry Warsaw <barry@python.org>
parents: 39112
diff changeset
309 new_params.append((name, '"%s"' % value))
37078
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
310 return new_params
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
311
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
312 def collapse_rfc2231_value(value, errors='replace',
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
313 fallback_charset='us-ascii'):
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
314 if isinstance(value, tuple):
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
315 rawval = unquote(value[2])
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
316 charset = value[0] or 'us-ascii'
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
317 try:
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
318 return unicode(rawval, charset, errors)
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
319 except LookupError:
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
320 # XXX charset is unknown to Python.
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
321 return unicode(rawval, fallback_charset, errors)
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
322 else:
3f90a93ff5d0 Merge email package 4.0 from the sandbox, including documentation, test cases,
Barry Warsaw <barry@python.org>
parents:
diff changeset
323 return unquote(value)