mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
Complete a merge of the mimelib project and the Python cvs codebases
for the email package. The former is now just a shell project that has some extra files for packaging for independent use (e.g. setup.py and README). Added a compatibility layer so that the same API can be used in Python 2.1 and 2.2/2.3 with the major differences shuffled off into helper modules (_compat21.py and _compat22.py). Also bumped the package version number to 2.0.3 for some fixes to be checked in momentarily.
This commit is contained in:
parent
2ae87539aa
commit
8c1aac2476
7 changed files with 168 additions and 45 deletions
|
@ -5,15 +5,34 @@
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import base64
|
import base64
|
||||||
from quopri import encodestring as _encodestring
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Helpers
|
# Helpers
|
||||||
def _qencode(s):
|
try:
|
||||||
enc = _encodestring(s, quotetabs=1)
|
from quopri import encodestring as _encodestring
|
||||||
# Must encode spaces, which quopri.encodestring() doesn't do
|
|
||||||
return enc.replace(' ', '=20')
|
def _qencode(s):
|
||||||
|
enc = _encodestring(s, quotetabs=1)
|
||||||
|
# Must encode spaces, which quopri.encodestring() doesn't do
|
||||||
|
return enc.replace(' ', '=20')
|
||||||
|
except ImportError:
|
||||||
|
# Python 2.1 doesn't have quopri.encodestring()
|
||||||
|
from cStringIO import StringIO
|
||||||
|
import quopri as _quopri
|
||||||
|
|
||||||
|
def _qencode(s):
|
||||||
|
if not s:
|
||||||
|
return s
|
||||||
|
hasnewline = (s[-1] == '\n')
|
||||||
|
infp = StringIO(s)
|
||||||
|
outfp = StringIO()
|
||||||
|
_quopri.encode(infp, outfp, quotetabs=1)
|
||||||
|
# Python 2.x's encode() doesn't encode spaces even when quotetabs==1
|
||||||
|
value = outfp.getvalue().replace(' ', '=20')
|
||||||
|
if not hasnewline and value[-1] == '\n':
|
||||||
|
return value[:-1]
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
def _bencode(s):
|
def _bencode(s):
|
||||||
|
|
|
@ -4,30 +4,8 @@
|
||||||
"""Various types of useful iterators and generators.
|
"""Various types of useful iterators and generators.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import generators
|
try:
|
||||||
from cStringIO import StringIO
|
from email._compat22 import body_line_iterator, typed_subpart_iterator
|
||||||
from types import StringType
|
except SyntaxError:
|
||||||
|
# Python 2.1 doesn't have generators
|
||||||
|
from email._compat21 import body_line_iterator, typed_subpart_iterator
|
||||||
|
|
||||||
def body_line_iterator(msg):
|
|
||||||
"""Iterate over the parts, returning string payloads line-by-line."""
|
|
||||||
for subpart in msg.walk():
|
|
||||||
payload = subpart.get_payload()
|
|
||||||
if type(payload) is StringType:
|
|
||||||
for line in StringIO(payload):
|
|
||||||
yield line
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def typed_subpart_iterator(msg, maintype='text', subtype=None):
|
|
||||||
"""Iterate over the subparts with a given MIME type.
|
|
||||||
|
|
||||||
Use `maintype' as the main MIME type to match against; this defaults to
|
|
||||||
"text". Optional `subtype' is the MIME subtype to match against; if
|
|
||||||
omitted, only the main type is matched.
|
|
||||||
"""
|
|
||||||
for subpart in msg.walk():
|
|
||||||
if subpart.get_main_type('text') == maintype:
|
|
||||||
if subtype is None or subpart.get_subtype('plain') == subtype:
|
|
||||||
yield subpart
|
|
||||||
|
|
|
@ -607,17 +607,11 @@ class Message:
|
||||||
newheaders.append((h, v))
|
newheaders.append((h, v))
|
||||||
self._headers = newheaders
|
self._headers = newheaders
|
||||||
|
|
||||||
def walk(self):
|
try:
|
||||||
"""Walk over the message tree, yielding each subpart.
|
from email._compat22 import walk
|
||||||
|
except SyntaxError:
|
||||||
The walk is performed in depth-first order. This method is a
|
# Must be using Python 2.1
|
||||||
generator.
|
from email._compat21 import walk
|
||||||
"""
|
|
||||||
yield self
|
|
||||||
if self.is_multipart():
|
|
||||||
for subpart in self.get_payload():
|
|
||||||
for subsubpart in subpart.walk():
|
|
||||||
yield subsubpart
|
|
||||||
|
|
||||||
def get_charsets(self, failobj=None):
|
def get_charsets(self, failobj=None):
|
||||||
"""Return a list containing the charset(s) used in this message.
|
"""Return a list containing the charset(s) used in this message.
|
||||||
|
|
|
@ -21,7 +21,24 @@ from rfc822 import mktime_tz
|
||||||
from rfc822 import parsedate as _parsedate
|
from rfc822 import parsedate as _parsedate
|
||||||
from rfc822 import parsedate_tz as _parsedate_tz
|
from rfc822 import parsedate_tz as _parsedate_tz
|
||||||
|
|
||||||
from quopri import decodestring as _qdecode
|
try:
|
||||||
|
from quopri import decodestring as _qdecode
|
||||||
|
except ImportError:
|
||||||
|
# Python 2.1 doesn't have quopri.decodestring()
|
||||||
|
def _qdecode(s):
|
||||||
|
import quopri as _quopri
|
||||||
|
|
||||||
|
if not s:
|
||||||
|
return s
|
||||||
|
hasnewline = (s[-1] == '\n')
|
||||||
|
infp = StringIO(s)
|
||||||
|
outfp = StringIO()
|
||||||
|
_quopri.decode(infp, outfp)
|
||||||
|
value = outfp.getvalue()
|
||||||
|
if not hasnewline and value[-1] =='\n':
|
||||||
|
return value[:-1]
|
||||||
|
return value
|
||||||
|
|
||||||
import base64
|
import base64
|
||||||
|
|
||||||
# Intrapackage imports
|
# Intrapackage imports
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
"""A package for parsing, handling, and generating email messages.
|
"""A package for parsing, handling, and generating email messages.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__version__ = '2.0'
|
__version__ = '2.0.3'
|
||||||
|
|
||||||
__all__ = ['Charset',
|
__all__ = ['Charset',
|
||||||
'Encoders',
|
'Encoders',
|
||||||
|
|
59
Lib/email/_compat21.py
Normal file
59
Lib/email/_compat21.py
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
# Copyright (C) 2002 Python Software Foundation
|
||||||
|
# Author: barry@zope.com
|
||||||
|
|
||||||
|
"""Module containing compatibility functions for Python 2.1.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from cStringIO import StringIO
|
||||||
|
from types import StringType, UnicodeType
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# This function will become a method of the Message class
|
||||||
|
def walk(self):
|
||||||
|
"""Walk over the message tree, yielding each subpart.
|
||||||
|
|
||||||
|
The walk is performed in depth-first order. This method is a
|
||||||
|
generator.
|
||||||
|
"""
|
||||||
|
parts = []
|
||||||
|
parts.append(self)
|
||||||
|
if self.is_multipart():
|
||||||
|
for subpart in self.get_payload():
|
||||||
|
parts.extend(subpart.walk())
|
||||||
|
return parts
|
||||||
|
|
||||||
|
|
||||||
|
# Used internally by the Header class
|
||||||
|
def _intdiv2(i):
|
||||||
|
"""Do an integer divide by 2."""
|
||||||
|
return i / 2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# These two functions are imported into the Iterators.py interface module.
|
||||||
|
# The Python 2.2 version uses generators for efficiency.
|
||||||
|
def body_line_iterator(msg):
|
||||||
|
"""Iterate over the parts, returning string payloads line-by-line."""
|
||||||
|
lines = []
|
||||||
|
for subpart in msg.walk():
|
||||||
|
payload = subpart.get_payload()
|
||||||
|
if isinstance(payload, StringType) or isinstance(payload, UnicodeType):
|
||||||
|
for line in StringIO(payload).readlines():
|
||||||
|
lines.append(line)
|
||||||
|
return lines
|
||||||
|
|
||||||
|
|
||||||
|
def typed_subpart_iterator(msg, maintype='text', subtype=None):
|
||||||
|
"""Iterate over the subparts with a given MIME type.
|
||||||
|
|
||||||
|
Use `maintype' as the main MIME type to match against; this defaults to
|
||||||
|
"text". Optional `subtype' is the MIME subtype to match against; if
|
||||||
|
omitted, only the main type is matched.
|
||||||
|
"""
|
||||||
|
parts = []
|
||||||
|
for subpart in msg.walk():
|
||||||
|
if subpart.get_main_type('text') == maintype:
|
||||||
|
if subtype is None or subpart.get_subtype('plain') == subtype:
|
||||||
|
parts.append(subpart)
|
||||||
|
return parts
|
56
Lib/email/_compat22.py
Normal file
56
Lib/email/_compat22.py
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
# Copyright (C) 2002 Python Software Foundation
|
||||||
|
# Author: barry@zope.com
|
||||||
|
|
||||||
|
"""Module containing compatibility functions for Python 2.1.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import generators
|
||||||
|
from __future__ import division
|
||||||
|
from cStringIO import StringIO
|
||||||
|
from types import StringTypes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# This function will become a method of the Message class
|
||||||
|
def walk(self):
|
||||||
|
"""Walk over the message tree, yielding each subpart.
|
||||||
|
|
||||||
|
The walk is performed in depth-first order. This method is a
|
||||||
|
generator.
|
||||||
|
"""
|
||||||
|
yield self
|
||||||
|
if self.is_multipart():
|
||||||
|
for subpart in self.get_payload():
|
||||||
|
for subsubpart in subpart.walk():
|
||||||
|
yield subsubpart
|
||||||
|
|
||||||
|
|
||||||
|
# Used internally by the Header class
|
||||||
|
def _intdiv2(i):
|
||||||
|
"""Do an integer divide by 2."""
|
||||||
|
return i // 2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# These two functions are imported into the Iterators.py interface module.
|
||||||
|
# The Python 2.2 version uses generators for efficiency.
|
||||||
|
def body_line_iterator(msg):
|
||||||
|
"""Iterate over the parts, returning string payloads line-by-line."""
|
||||||
|
for subpart in msg.walk():
|
||||||
|
payload = subpart.get_payload()
|
||||||
|
if isinstance(payload, StringTypes):
|
||||||
|
for line in StringIO(payload):
|
||||||
|
yield line
|
||||||
|
|
||||||
|
|
||||||
|
def typed_subpart_iterator(msg, maintype='text', subtype=None):
|
||||||
|
"""Iterate over the subparts with a given MIME type.
|
||||||
|
|
||||||
|
Use `maintype' as the main MIME type to match against; this defaults to
|
||||||
|
"text". Optional `subtype' is the MIME subtype to match against; if
|
||||||
|
omitted, only the main type is matched.
|
||||||
|
"""
|
||||||
|
for subpart in msg.walk():
|
||||||
|
if subpart.get_main_type('text') == maintype:
|
||||||
|
if subtype is None or subpart.get_subtype('plain') == subtype:
|
||||||
|
yield subpart
|
Loading…
Add table
Add a link
Reference in a new issue