[Python-checkins] python/dist/src/Lib/email Utils.py,1.16,1.17

bwarsaw@users.sourceforge.net bwarsaw@users.sourceforge.net
Fri, 28 Jun 2002 22:58:06 -0700


Update of /cvsroot/python/python/dist/src/Lib/email
In directory usw-pr-cvs1:/tmp/cvs-serv4405/email

Modified Files:
	Utils.py 
Log Message:
Oleg Broytmann's support for RFC 2231 encoded parameters, SF patch #549133

Specifically,

decode_rfc2231(), encode_rfc2231(): Functions to encode and decode RFC
2231 style parameters.

decode_params(): Function to decode a list of parameters.


Index: Utils.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/email/Utils.py,v
retrieving revision 1.16
retrieving revision 1.17
diff -C2 -d -r1.16 -r1.17
*** Utils.py	2 Jun 2002 19:07:16 -0000	1.16
--- Utils.py	29 Jun 2002 05:58:04 -0000	1.17
***************
*** 46,49 ****
--- 46,50 ----
  
  COMMASPACE = ', '
+ EMPTYSTRING = ''
  UEMPTYSTRING = u''
  CRLF = '\r\n'
***************
*** 258,259 ****
--- 259,316 ----
          return '', ''
      return addrs[0]
+ 
+ 
+ 
+ # RFC2231-related functions - parameter encoding and decoding
+ def decode_rfc2231(s):
+     """Decode string according to RFC 2231"""
+     import urllib
+     charset, language, s = s.split("'", 2)
+     s = urllib.unquote(s)
+     return charset, language, s
+ 
+ 
+ def encode_rfc2231(s, charset=None, language=None):
+     """Encode string according to RFC 2231"""
+     import urllib
+     s = urllib.quote(s, safe='')
+     if charset is None and language is None:
+         return s
+     else:
+         return "%s'%s'%s" % (charset, language, s)
+ 
+ 
+ rfc2231_continuation = re.compile(r'^(?P<name>\w+)\*((?P<num>[0-9]+)\*?)?$')
+ 
+ def decode_params(params):
+     """Decode parameters list according to RFC 2231"""
+     new_params = []
+     # maps parameter's name to a list of continuations
+     rfc2231_params = {}
+     # params is a sequence of 2-tuples containing (content_type, string value)
+     name, value = params[0]
+     new_params.append((name, value))
+     # Cycle through each of the rest of the parameters.
+     for name, value in params[1:]:
+         value = unquote(value)
+         mo = rfc2231_continuation.match(name)
+         if mo:
+             name, num = mo.group('name', 'num')
+             if num is not None:
+                 num = int(num)
+             rfc2231_param1 = rfc2231_params.setdefault(name, [])
+             rfc2231_param1.append((num, value))
+         else:
+             new_params.append((name, '"%s"' % quote(value)))
+     if rfc2231_params:
+         for name, continuations in rfc2231_params.items():
+             value = []
+             # Sort by number
+             continuations.sort()
+             # And now append all values in num order
+             for num, continuation in continuations:
+                 value.append(continuation)
+             charset, language, value = decode_rfc2231(EMPTYSTRING.join(value))
+             new_params.append((name,
+                                (charset, language, '"%s"' % quote(value))))
+     return new_params