mirror of https://github.com/python/cpython
Support new overridable method, isheader() (ESR).
Also implement __setitem__(), more-or-less correctly (GvR).
This commit is contained in:
parent
444d0f87c9
commit
e894fc0ea3
|
@ -13,13 +13,13 @@ sys.stdin or call os.popen().
|
||||||
Then pass the open file object to the Message() constructor:
|
Then pass the open file object to the Message() constructor:
|
||||||
m = Message(fp)
|
m = Message(fp)
|
||||||
|
|
||||||
This class can work with any input object that supports read and seek
|
This class can work with any input object that supports a readline
|
||||||
methods. The initialization method which parses the message will work
|
method. If the input object has seek and tell capability, the
|
||||||
even without seek capability, but in that case the final seek to the
|
rewindbody method will work; also illegal lines will be pushed back
|
||||||
start of the delimiter line won't take place. However, if the input
|
onto the input stream. If the input object lacks seek but has an
|
||||||
object has an `unread' method that can push back a line of input,
|
`unread' method that can push back a line of input, Message will use
|
||||||
Message will use that to push back the delimiter line. Thus this class
|
that to push back illegal lines. Thus this class can be used to parse
|
||||||
can be used to parse messages coming from a buffered stream.
|
messages coming from a buffered stream.
|
||||||
|
|
||||||
The optional `seekable' argument is provided as a workaround for
|
The optional `seekable' argument is provided as a workaround for
|
||||||
certain stdio libraries in which tell() discards buffered data before
|
certain stdio libraries in which tell() discards buffered data before
|
||||||
|
@ -134,29 +134,30 @@ class Message:
|
||||||
self.unixfrom = self.unixfrom + line
|
self.unixfrom = self.unixfrom + line
|
||||||
continue
|
continue
|
||||||
firstline = 0
|
firstline = 0
|
||||||
if self.islast(line):
|
if headerseen and line[0] in ' \t':
|
||||||
break
|
|
||||||
elif headerseen and line[0] in ' \t':
|
|
||||||
# It's a continuation line.
|
# It's a continuation line.
|
||||||
list.append(line)
|
list.append(line)
|
||||||
x = (self.dict[headerseen] + "\n " +
|
x = (self.dict[headerseen] + "\n " + string.strip(line))
|
||||||
string.strip(line))
|
|
||||||
self.dict[headerseen] = string.strip(x)
|
self.dict[headerseen] = string.strip(x)
|
||||||
elif ':' in line:
|
continue
|
||||||
# It's a header line.
|
|
||||||
list.append(line)
|
|
||||||
i = string.find(line, ':')
|
|
||||||
headerseen = string.lower(line[:i])
|
|
||||||
self.dict[headerseen] = string.strip(
|
|
||||||
line[i+1:])
|
|
||||||
elif self.iscomment(line):
|
elif self.iscomment(line):
|
||||||
pass
|
# It's a comment. Ignore it.
|
||||||
|
continue
|
||||||
|
elif self.islast(line):
|
||||||
|
# Note! No pushback here! The delimiter line gets eaten.
|
||||||
|
break
|
||||||
|
headerseen = self.isheader(line)
|
||||||
|
if headerseen:
|
||||||
|
# It's a legal header line, save it.
|
||||||
|
list.append(line)
|
||||||
|
self.dict[headerseen] = string.strip(line[len(headerseen)+2:])
|
||||||
|
continue
|
||||||
else:
|
else:
|
||||||
# It's not a header line; stop here.
|
# It's not a header line; throw it back and stop here.
|
||||||
if not headerseen:
|
if not self.dict:
|
||||||
self.status = 'No headers'
|
self.status = 'No headers'
|
||||||
else:
|
else:
|
||||||
self.status = 'Bad header'
|
self.status = 'Non-header line where header expected'
|
||||||
# Try to undo the read.
|
# Try to undo the read.
|
||||||
if getattr(self.fp, 'unread'):
|
if getattr(self.fp, 'unread'):
|
||||||
self.fp.unread(line)
|
self.fp.unread(line)
|
||||||
|
@ -166,6 +167,19 @@ class Message:
|
||||||
self.status = self.status + '; bad seek'
|
self.status = self.status + '; bad seek'
|
||||||
break
|
break
|
||||||
|
|
||||||
|
def isheader(self, line):
|
||||||
|
"""Determine whether a given line is a legal header.
|
||||||
|
|
||||||
|
This method should return the header name, suitably canonicalized.
|
||||||
|
You may override this method in order to use Message parsing
|
||||||
|
on tagged data in RFC822-like formats with special header formats.
|
||||||
|
"""
|
||||||
|
i = string.find(line, ':')
|
||||||
|
if i > 0:
|
||||||
|
return string.lower(line[:i])
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
def islast(self, line):
|
def islast(self, line):
|
||||||
"""Determine whether a line is a legal end of RFC-822 headers.
|
"""Determine whether a line is a legal end of RFC-822 headers.
|
||||||
|
|
||||||
|
@ -324,6 +338,15 @@ class Message:
|
||||||
"""Get a specific header, as from a dictionary."""
|
"""Get a specific header, as from a dictionary."""
|
||||||
return self.dict[string.lower(name)]
|
return self.dict[string.lower(name)]
|
||||||
|
|
||||||
|
def __setitem__(self, name, value):
|
||||||
|
"""Set the value of a header."""
|
||||||
|
del self[name] # Won't fail if it doesn't exist
|
||||||
|
self.dict[string.lower(name)] = value
|
||||||
|
text = name + ": " + value
|
||||||
|
lines = string.split(text, "\n")
|
||||||
|
for line in lines:
|
||||||
|
self.headers.append(line + "\n")
|
||||||
|
|
||||||
def __delitem__(self, name):
|
def __delitem__(self, name):
|
||||||
"""Delete all occurrences of a specific header, if it is present."""
|
"""Delete all occurrences of a specific header, if it is present."""
|
||||||
name = string.lower(name)
|
name = string.lower(name)
|
||||||
|
@ -646,7 +669,8 @@ class AddrlistClass:
|
||||||
"""Parse a sequence of RFC-822 phrases.
|
"""Parse a sequence of RFC-822 phrases.
|
||||||
|
|
||||||
A phrase is a sequence of words, which are in turn either
|
A phrase is a sequence of words, which are in turn either
|
||||||
RFC-822 atoms or quoted-strings.
|
RFC-822 atoms or quoted-strings. Phrases are canonicalized
|
||||||
|
by squeezing all runs of continuous whitespace into one space.
|
||||||
"""
|
"""
|
||||||
plist = []
|
plist = []
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue