home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / lib / python2.4 / email / _parseaddr.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2006-08-31  |  12.7 KB  |  538 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.4)
  3.  
  4. '''Email address parsing code.
  5.  
  6. Lifted directly from rfc822.py.  This should eventually be rewritten.
  7. '''
  8. import time
  9. SPACE = ' '
  10. EMPTYSTRING = ''
  11. COMMASPACE = ', '
  12. _monthnames = [
  13.     'jan',
  14.     'feb',
  15.     'mar',
  16.     'apr',
  17.     'may',
  18.     'jun',
  19.     'jul',
  20.     'aug',
  21.     'sep',
  22.     'oct',
  23.     'nov',
  24.     'dec',
  25.     'january',
  26.     'february',
  27.     'march',
  28.     'april',
  29.     'may',
  30.     'june',
  31.     'july',
  32.     'august',
  33.     'september',
  34.     'october',
  35.     'november',
  36.     'december']
  37. _daynames = [
  38.     'mon',
  39.     'tue',
  40.     'wed',
  41.     'thu',
  42.     'fri',
  43.     'sat',
  44.     'sun']
  45. _timezones = {
  46.     'UT': 0,
  47.     'UTC': 0,
  48.     'GMT': 0,
  49.     'Z': 0,
  50.     'AST': -400,
  51.     'ADT': -300,
  52.     'EST': -500,
  53.     'EDT': -400,
  54.     'CST': -600,
  55.     'CDT': -500,
  56.     'MST': -700,
  57.     'MDT': -600,
  58.     'PST': -800,
  59.     'PDT': -700 }
  60.  
  61. def parsedate_tz(data):
  62.     '''Convert a date string to a time tuple.
  63.  
  64.     Accounts for military timezones.
  65.     '''
  66.     data = data.split()
  67.     if data[0].endswith(',') or data[0].lower() in _daynames:
  68.         del data[0]
  69.     else:
  70.         i = data[0].rfind(',')
  71.         if i >= 0:
  72.             data[0] = data[0][i + 1:]
  73.         
  74.     if len(data) == 3:
  75.         stuff = data[0].split('-')
  76.         if len(stuff) == 3:
  77.             data = stuff + data[1:]
  78.         
  79.     
  80.     if len(data) == 4:
  81.         s = data[3]
  82.         i = s.find('+')
  83.         if i > 0:
  84.             data[3:] = [
  85.                 s[:i],
  86.                 s[i + 1:]]
  87.         else:
  88.             data.append('')
  89.     
  90.     if len(data) < 5:
  91.         return None
  92.     
  93.     data = data[:5]
  94.     (dd, mm, yy, tm, tz) = data
  95.     mm = mm.lower()
  96.     if mm not in _monthnames:
  97.         dd = mm
  98.         mm = dd.lower()
  99.         if mm not in _monthnames:
  100.             return None
  101.         
  102.     
  103.     mm = _monthnames.index(mm) + 1
  104.     if mm > 12:
  105.         mm -= 12
  106.     
  107.     if dd[-1] == ',':
  108.         dd = dd[:-1]
  109.     
  110.     i = yy.find(':')
  111.     if i > 0:
  112.         yy = tm
  113.         tm = yy
  114.     
  115.     if yy[-1] == ',':
  116.         yy = yy[:-1]
  117.     
  118.     if not yy[0].isdigit():
  119.         yy = tz
  120.         tz = yy
  121.     
  122.     if tm[-1] == ',':
  123.         tm = tm[:-1]
  124.     
  125.     tm = tm.split(':')
  126.     if len(tm) == 2:
  127.         (thh, tmm) = tm
  128.         tss = '0'
  129.     elif len(tm) == 3:
  130.         (thh, tmm, tss) = tm
  131.     else:
  132.         return None
  133.     
  134.     try:
  135.         yy = int(yy)
  136.         dd = int(dd)
  137.         thh = int(thh)
  138.         tmm = int(tmm)
  139.         tss = int(tss)
  140.     except ValueError:
  141.         return None
  142.  
  143.     tzoffset = None
  144.     tz = tz.upper()
  145.     if _timezones.has_key(tz):
  146.         tzoffset = _timezones[tz]
  147.     else:
  148.         
  149.         try:
  150.             tzoffset = int(tz)
  151.         except ValueError:
  152.             pass
  153.  
  154.     if tzoffset:
  155.         if tzoffset < 0:
  156.             tzsign = -1
  157.             tzoffset = -tzoffset
  158.         else:
  159.             tzsign = 1
  160.         tzoffset = tzsign * ((tzoffset // 100) * 3600 + (tzoffset % 100) * 60)
  161.     
  162.     return (yy, mm, dd, thh, tmm, tss, 0, 1, 0, tzoffset)
  163.  
  164.  
  165. def parsedate(data):
  166.     '''Convert a time string to a time tuple.'''
  167.     t = parsedate_tz(data)
  168.     if isinstance(t, tuple):
  169.         return t[:9]
  170.     else:
  171.         return t
  172.  
  173.  
  174. def mktime_tz(data):
  175.     '''Turn a 10-tuple as returned by parsedate_tz() into a UTC timestamp.'''
  176.     if data[9] is None:
  177.         return time.mktime(data[:8] + (-1,))
  178.     else:
  179.         t = time.mktime(data[:8] + (0,))
  180.         return t - data[9] - time.timezone
  181.  
  182.  
  183. def quote(str):
  184.     '''Add quotes around a string.'''
  185.     return str.replace('\\', '\\\\').replace('"', '\\"')
  186.  
  187.  
  188. class AddrlistClass:
  189.     '''Address parser class by Ben Escoto.
  190.  
  191.     To understand what this class does, it helps to have a copy of RFC 2822 in
  192.     front of you.
  193.  
  194.     Note: this class interface is deprecated and may be removed in the future.
  195.     Use rfc822.AddressList instead.
  196.     '''
  197.     
  198.     def __init__(self, field):
  199.         """Initialize a new instance.
  200.  
  201.         `field' is an unparsed address header field, containing
  202.         one or more addresses.
  203.         """
  204.         self.specials = '()<>@,:;."[]'
  205.         self.pos = 0
  206.         self.LWS = ' \t'
  207.         self.CR = '\r\n'
  208.         self.atomends = self.specials + self.LWS + self.CR
  209.         self.phraseends = self.atomends.replace('.', '')
  210.         self.field = field
  211.         self.commentlist = []
  212.  
  213.     
  214.     def gotonext(self):
  215.         '''Parse up to the start of the next address.'''
  216.         while self.pos < len(self.field):
  217.             if self.field[self.pos] in self.LWS + '\n\r':
  218.                 self.pos += 1
  219.                 continue
  220.             self
  221.             if self.field[self.pos] == '(':
  222.                 self.commentlist.append(self.getcomment())
  223.                 continue
  224.             break
  225.  
  226.     
  227.     def getaddrlist(self):
  228.         '''Parse all addresses.
  229.  
  230.         Returns a list containing all of the addresses.
  231.         '''
  232.         result = []
  233.         while self.pos < len(self.field):
  234.             ad = self.getaddress()
  235.             if ad:
  236.                 result += ad
  237.                 continue
  238.             result.append(('', ''))
  239.         return result
  240.  
  241.     
  242.     def getaddress(self):
  243.         '''Parse the next address.'''
  244.         self.commentlist = []
  245.         self.gotonext()
  246.         oldpos = self.pos
  247.         oldcl = self.commentlist
  248.         plist = self.getphraselist()
  249.         self.gotonext()
  250.         returnlist = []
  251.         if self.pos >= len(self.field):
  252.             if plist:
  253.                 returnlist = [
  254.                     (SPACE.join(self.commentlist), plist[0])]
  255.             
  256.         elif self.field[self.pos] in '.@':
  257.             self.pos = oldpos
  258.             self.commentlist = oldcl
  259.             addrspec = self.getaddrspec()
  260.             returnlist = [
  261.                 (SPACE.join(self.commentlist), addrspec)]
  262.         elif self.field[self.pos] == ':':
  263.             returnlist = []
  264.             fieldlen = len(self.field)
  265.             self.pos += 1
  266.             while self.pos < len(self.field):
  267.                 self.gotonext()
  268.                 returnlist = returnlist + self.getaddress()
  269.                 continue
  270.                 None if self.pos < fieldlen and self.field[self.pos] == ';' else self
  271.         elif self.field[self.pos] == '<':
  272.             routeaddr = self.getrouteaddr()
  273.             if self.commentlist:
  274.                 returnlist = [
  275.                     (SPACE.join(plist) + ' (' + ' '.join(self.commentlist) + ')', routeaddr)]
  276.             else:
  277.                 returnlist = [
  278.                     (SPACE.join(plist), routeaddr)]
  279.         elif plist:
  280.             returnlist = [
  281.                 (SPACE.join(self.commentlist), plist[0])]
  282.         elif self.field[self.pos] in self.specials:
  283.             self.pos += 1
  284.         
  285.         self.gotonext()
  286.         if self.pos < len(self.field) and self.field[self.pos] == ',':
  287.             self.pos += 1
  288.         
  289.         return returnlist
  290.  
  291.     
  292.     def getrouteaddr(self):
  293.         '''Parse a route address (Return-path value).
  294.  
  295.         This method just skips all the route stuff and returns the addrspec.
  296.         '''
  297.         if self.field[self.pos] != '<':
  298.             return None
  299.         
  300.         expectroute = False
  301.         self.pos += 1
  302.         self.gotonext()
  303.         adlist = ''
  304.         while self.pos < len(self.field):
  305.             if expectroute:
  306.                 self.getdomain()
  307.                 expectroute = False
  308.             elif self.field[self.pos] == '>':
  309.                 self.pos += 1
  310.                 break
  311.             elif self.field[self.pos] == '@':
  312.                 self.pos += 1
  313.                 expectroute = True
  314.             elif self.field[self.pos] == ':':
  315.                 self.pos += 1
  316.             else:
  317.                 adlist = self.getaddrspec()
  318.                 self.pos += 1
  319.                 break
  320.             self.gotonext()
  321.             continue
  322.             self
  323.         return adlist
  324.  
  325.     
  326.     def getaddrspec(self):
  327.         '''Parse an RFC 2822 addr-spec.'''
  328.         aslist = []
  329.         self.gotonext()
  330.         while self.pos < len(self.field):
  331.             if self.field[self.pos] == '.':
  332.                 aslist.append('.')
  333.                 self.pos += 1
  334.             elif self.field[self.pos] == '"':
  335.                 aslist.append('"%s"' % self.getquote())
  336.             elif self.field[self.pos] in self.atomends:
  337.                 break
  338.             else:
  339.                 aslist.append(self.getatom())
  340.             self.gotonext()
  341.         if self.pos >= len(self.field) or self.field[self.pos] != '@':
  342.             return EMPTYSTRING.join(aslist)
  343.         
  344.         aslist.append('@')
  345.         self.pos += 1
  346.         self.gotonext()
  347.         return EMPTYSTRING.join(aslist) + self.getdomain()
  348.  
  349.     
  350.     def getdomain(self):
  351.         '''Get the complete domain name from an address.'''
  352.         sdlist = []
  353.         while self.pos < len(self.field):
  354.             if self.field[self.pos] in self.LWS:
  355.                 self.pos += 1
  356.                 continue
  357.             self
  358.             if self.field[self.pos] == '(':
  359.                 self.commentlist.append(self.getcomment())
  360.                 continue
  361.             if self.field[self.pos] == '[':
  362.                 sdlist.append(self.getdomainliteral())
  363.                 continue
  364.             if self.field[self.pos] == '.':
  365.                 self.pos += 1
  366.                 sdlist.append('.')
  367.                 continue
  368.             self
  369.             if self.field[self.pos] in self.atomends:
  370.                 break
  371.                 continue
  372.             sdlist.append(self.getatom())
  373.         return EMPTYSTRING.join(sdlist)
  374.  
  375.     
  376.     def getdelimited(self, beginchar, endchars, allowcomments = True):
  377.         """Parse a header fragment delimited by special characters.
  378.  
  379.         `beginchar' is the start character for the fragment.
  380.         If self is not looking at an instance of `beginchar' then
  381.         getdelimited returns the empty string.
  382.  
  383.         `endchars' is a sequence of allowable end-delimiting characters.
  384.         Parsing stops when one of these is encountered.
  385.  
  386.         If `allowcomments' is non-zero, embedded RFC 2822 comments are allowed
  387.         within the parsed fragment.
  388.         """
  389.         if self.field[self.pos] != beginchar:
  390.             return ''
  391.         
  392.         slist = [
  393.             '']
  394.         quote = False
  395.         self.pos += 1
  396.         while self.pos < len(self.field):
  397.             if quote:
  398.                 slist.append(self.field[self.pos])
  399.                 quote = False
  400.             elif self.field[self.pos] in endchars:
  401.                 self.pos += 1
  402.                 break
  403.             elif allowcomments and self.field[self.pos] == '(':
  404.                 slist.append(self.getcomment())
  405.             elif self.field[self.pos] == '\\':
  406.                 quote = True
  407.             else:
  408.                 slist.append(self.field[self.pos])
  409.             self.pos += 1
  410.             continue
  411.             self
  412.         return EMPTYSTRING.join(slist)
  413.  
  414.     
  415.     def getquote(self):
  416.         """Get a quote-delimited fragment from self's field."""
  417.         return self.getdelimited('"', '"\r', False)
  418.  
  419.     
  420.     def getcomment(self):
  421.         """Get a parenthesis-delimited fragment from self's field."""
  422.         return self.getdelimited('(', ')\r', True)
  423.  
  424.     
  425.     def getdomainliteral(self):
  426.         '''Parse an RFC 2822 domain-literal.'''
  427.         return '[%s]' % self.getdelimited('[', ']\r', False)
  428.  
  429.     
  430.     def getatom(self, atomends = None):
  431.         """Parse an RFC 2822 atom.
  432.  
  433.         Optional atomends specifies a different set of end token delimiters
  434.         (the default is to use self.atomends).  This is used e.g. in
  435.         getphraselist() since phrase endings must not include the `.' (which
  436.         is legal in phrases)."""
  437.         atomlist = [
  438.             '']
  439.         if atomends is None:
  440.             atomends = self.atomends
  441.         
  442.         while self.pos < len(self.field):
  443.             if self.field[self.pos] in atomends:
  444.                 break
  445.             else:
  446.                 atomlist.append(self.field[self.pos])
  447.             self.pos += 1
  448.             continue
  449.             self
  450.         return EMPTYSTRING.join(atomlist)
  451.  
  452.     
  453.     def getphraselist(self):
  454.         '''Parse a sequence of RFC 2822 phrases.
  455.  
  456.         A phrase is a sequence of words, which are in turn either RFC 2822
  457.         atoms or quoted-strings.  Phrases are canonicalized by squeezing all
  458.         runs of continuous whitespace into one space.
  459.         '''
  460.         plist = []
  461.         while self.pos < len(self.field):
  462.             if self.field[self.pos] in self.LWS:
  463.                 self.pos += 1
  464.                 continue
  465.             self
  466.             if self.field[self.pos] == '"':
  467.                 plist.append(self.getquote())
  468.                 continue
  469.             if self.field[self.pos] == '(':
  470.                 self.commentlist.append(self.getcomment())
  471.                 continue
  472.             if self.field[self.pos] in self.phraseends:
  473.                 break
  474.                 continue
  475.             plist.append(self.getatom(self.phraseends))
  476.         return plist
  477.  
  478.  
  479.  
  480. class AddressList(AddrlistClass):
  481.     '''An AddressList encapsulates a list of parsed RFC 2822 addresses.'''
  482.     
  483.     def __init__(self, field):
  484.         AddrlistClass.__init__(self, field)
  485.         if field:
  486.             self.addresslist = self.getaddrlist()
  487.         else:
  488.             self.addresslist = []
  489.  
  490.     
  491.     def __len__(self):
  492.         return len(self.addresslist)
  493.  
  494.     
  495.     def __add__(self, other):
  496.         newaddr = AddressList(None)
  497.         newaddr.addresslist = self.addresslist[:]
  498.         for x in other.addresslist:
  499.             if x not in self.addresslist:
  500.                 newaddr.addresslist.append(x)
  501.                 continue
  502.         
  503.         return newaddr
  504.  
  505.     
  506.     def __iadd__(self, other):
  507.         for x in other.addresslist:
  508.             if x not in self.addresslist:
  509.                 self.addresslist.append(x)
  510.                 continue
  511.         
  512.         return self
  513.  
  514.     
  515.     def __sub__(self, other):
  516.         newaddr = AddressList(None)
  517.         for x in self.addresslist:
  518.             if x not in other.addresslist:
  519.                 newaddr.addresslist.append(x)
  520.                 continue
  521.         
  522.         return newaddr
  523.  
  524.     
  525.     def __isub__(self, other):
  526.         for x in other.addresslist:
  527.             if x in self.addresslist:
  528.                 self.addresslist.remove(x)
  529.                 continue
  530.         
  531.         return self
  532.  
  533.     
  534.     def __getitem__(self, index):
  535.         return self.addresslist[index]
  536.  
  537.  
  538.