home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2010 November / maximum-cd-2010-11.iso / DiscContents / calibre-0.7.13.msi / file_425 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-08-06  |  9.0 KB  |  391 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. __all__ = [
  5.     'FeedParser']
  6. import re
  7. from email import errors
  8. from email import message
  9. NLCRE = re.compile('\r\n|\r|\n')
  10. NLCRE_bol = re.compile('(\r\n|\r|\n)')
  11. NLCRE_eol = re.compile('(\r\n|\r|\n)$')
  12. NLCRE_crack = re.compile('(\r\n|\r|\n)')
  13. headerRE = re.compile('^(From |[\\041-\\071\\073-\\176]{1,}:|[\\t ])')
  14. EMPTYSTRING = ''
  15. NL = '\n'
  16. NeedMoreData = object()
  17.  
  18. class BufferedSubFile(object):
  19.     
  20.     def __init__(self):
  21.         self._partial = ''
  22.         self._lines = []
  23.         self._eofstack = []
  24.         self._closed = False
  25.  
  26.     
  27.     def push_eof_matcher(self, pred):
  28.         self._eofstack.append(pred)
  29.  
  30.     
  31.     def pop_eof_matcher(self):
  32.         return self._eofstack.pop()
  33.  
  34.     
  35.     def close(self):
  36.         self._lines.append(self._partial)
  37.         self._partial = ''
  38.         self._closed = True
  39.  
  40.     
  41.     def readline(self):
  42.         if not self._lines:
  43.             if self._closed:
  44.                 return ''
  45.             return NeedMoreData
  46.         line = self._lines.pop()
  47.         for ateof in self._eofstack[::-1]:
  48.             if ateof(line):
  49.                 self._lines.append(line)
  50.                 return ''
  51.         
  52.         return line
  53.  
  54.     
  55.     def unreadline(self, line):
  56.         self._lines.append(line)
  57.  
  58.     
  59.     def push(self, data):
  60.         data = self._partial + data
  61.         self._partial = ''
  62.         parts = NLCRE_crack.split(data)
  63.         self._partial = parts.pop()
  64.         lines = []
  65.         for i in range(len(parts) // 2):
  66.             lines.append(parts[i * 2] + parts[i * 2 + 1])
  67.         
  68.         self.pushlines(lines)
  69.  
  70.     
  71.     def pushlines(self, lines):
  72.         self._lines[:0] = lines[::-1]
  73.  
  74.     
  75.     def is_closed(self):
  76.         return self._closed
  77.  
  78.     
  79.     def __iter__(self):
  80.         return self
  81.  
  82.     
  83.     def next(self):
  84.         line = self.readline()
  85.         if line == '':
  86.             raise StopIteration
  87.         line == ''
  88.         return line
  89.  
  90.  
  91.  
  92. class FeedParser:
  93.     
  94.     def __init__(self, _factory = message.Message):
  95.         self._factory = _factory
  96.         self._input = BufferedSubFile()
  97.         self._msgstack = []
  98.         self._parse = self._parsegen().next
  99.         self._cur = None
  100.         self._last = None
  101.         self._headersonly = False
  102.  
  103.     
  104.     def _set_headersonly(self):
  105.         self._headersonly = True
  106.  
  107.     
  108.     def feed(self, data):
  109.         self._input.push(data)
  110.         self._call_parse()
  111.  
  112.     
  113.     def _call_parse(self):
  114.         
  115.         try:
  116.             self._parse()
  117.         except StopIteration:
  118.             pass
  119.  
  120.  
  121.     
  122.     def close(self):
  123.         self._input.close()
  124.         self._call_parse()
  125.         root = self._pop_message()
  126.         if root.get_content_maintype() == 'multipart' and not root.is_multipart():
  127.             root.defects.append(errors.MultipartInvariantViolationDefect())
  128.         
  129.         return root
  130.  
  131.     
  132.     def _new_message(self):
  133.         msg = self._factory()
  134.         if self._cur and self._cur.get_content_type() == 'multipart/digest':
  135.             msg.set_default_type('message/rfc822')
  136.         
  137.         if self._msgstack:
  138.             self._msgstack[-1].attach(msg)
  139.         
  140.         self._msgstack.append(msg)
  141.         self._cur = msg
  142.         self._last = msg
  143.  
  144.     
  145.     def _pop_message(self):
  146.         retval = self._msgstack.pop()
  147.         if self._msgstack:
  148.             self._cur = self._msgstack[-1]
  149.         else:
  150.             self._cur = None
  151.         return retval
  152.  
  153.     
  154.     def _parsegen(self):
  155.         self._new_message()
  156.         headers = []
  157.         for line in self._input:
  158.             if line is NeedMoreData:
  159.                 yield NeedMoreData
  160.                 continue
  161.             
  162.             if not headerRE.match(line):
  163.                 if not NLCRE.match(line):
  164.                     self._input.unreadline(line)
  165.                 
  166.                 break
  167.             
  168.             headers.append(line)
  169.         
  170.         self._parse_headers(headers)
  171.         if self._headersonly:
  172.             lines = []
  173.             while True:
  174.                 line = self._input.readline()
  175.                 if line is NeedMoreData:
  176.                     yield NeedMoreData
  177.                     continue
  178.                 
  179.                 if line == '':
  180.                     break
  181.                 
  182.                 lines.append(line)
  183.             self._cur.set_payload(EMPTYSTRING.join(lines))
  184.             return None
  185.         if self._cur.get_content_type() == 'message/delivery-status':
  186.             while True:
  187.                 self._input.push_eof_matcher(NLCRE.match)
  188.                 for retval in self._parsegen():
  189.                     pass
  190.                 
  191.                 msg = self._pop_message()
  192.                 self._input.pop_eof_matcher()
  193.                 while True:
  194.                     line = self._input.readline()
  195.                     break
  196.                     continue
  197.                     None if line is NeedMoreData else None if retval is NeedMoreData else self._headersonly
  198.                 while True:
  199.                     line = self._input.readline()
  200.                     if line is NeedMoreData:
  201.                         yield NeedMoreData
  202.                         continue
  203.                     
  204.                     break
  205.                 if line == '':
  206.                     break
  207.                 
  208.                 self._input.unreadline(line)
  209.             return None
  210.         if self._cur.get_content_maintype() == 'message':
  211.             for retval in self._parsegen():
  212.                 if retval is NeedMoreData:
  213.                     yield NeedMoreData
  214.                     self._cur.get_content_type() == 'message/delivery-status'
  215.                     continue
  216.                 
  217.             
  218.             self._pop_message()
  219.             return None
  220.         if self._cur.get_content_maintype() == 'multipart':
  221.             boundary = self._cur.get_boundary()
  222.             if boundary is None:
  223.                 self._cur.defects.append(errors.NoBoundaryInMultipartDefect())
  224.                 lines = []
  225.                 for line in self._input:
  226.                     lines.append(line)
  227.                 
  228.                 self._cur.set_payload(EMPTYSTRING.join(lines))
  229.                 return None
  230.             separator = '--' + boundary
  231.             boundaryre = re.compile('(?P<sep>' + re.escape(separator) + ')(?P<end>--)?(?P<ws>[ \\t]*)(?P<linesep>\\r\\n|\\r|\\n)?$')
  232.             capturing_preamble = True
  233.             preamble = []
  234.             linesep = False
  235.             while True:
  236.                 line = self._input.readline()
  237.                 if line == '':
  238.                     break
  239.                 
  240.                 mo = boundaryre.match(line)
  241.                 if mo:
  242.                     if mo.group('end'):
  243.                         linesep = mo.group('linesep')
  244.                         break
  245.                     
  246.                     if capturing_preamble:
  247.                         if preamble:
  248.                             lastline = preamble[-1]
  249.                             eolmo = NLCRE_eol.search(lastline)
  250.                             if eolmo:
  251.                                 preamble[-1] = lastline[:-len(eolmo.group(0))]
  252.                             
  253.                             self._cur.preamble = EMPTYSTRING.join(preamble)
  254.                         
  255.                         capturing_preamble = False
  256.                         self._input.unreadline(line)
  257.                         continue
  258.                     
  259.                     while True:
  260.                         line = self._input.readline()
  261.                         if line is NeedMoreData:
  262.                             yield NeedMoreData
  263.                             continue
  264.                         
  265.                         mo = boundaryre.match(line)
  266.                         if not mo:
  267.                             self._input.unreadline(line)
  268.                             break
  269.                             continue
  270.                     self._input.push_eof_matcher(boundaryre.match)
  271.                     for retval in self._parsegen():
  272.                         if retval is NeedMoreData:
  273.                             yield NeedMoreData
  274.                             continue
  275.                         
  276.                     
  277.                     if self._last.get_content_maintype() == 'multipart':
  278.                         epilogue = self._last.epilogue
  279.                         if epilogue == '':
  280.                             self._last.epilogue = None
  281.                         elif epilogue is not None:
  282.                             mo = NLCRE_eol.search(epilogue)
  283.                             if mo:
  284.                                 end = len(mo.group(0))
  285.                                 self._last.epilogue = epilogue[:-end]
  286.                             
  287.                         
  288.                     else:
  289.                         payload = self._last.get_payload()
  290.                         if isinstance(payload, basestring):
  291.                             mo = NLCRE_eol.search(payload)
  292.                             if mo:
  293.                                 payload = payload[:-len(mo.group(0))]
  294.                                 self._last.set_payload(payload)
  295.                             
  296.                         
  297.                     self._input.pop_eof_matcher()
  298.                     self._pop_message()
  299.                     self._last = self._cur
  300.                     continue
  301.                 preamble.append(line)
  302.             if capturing_preamble:
  303.                 self._cur.defects.append(errors.StartBoundaryNotFoundDefect())
  304.                 self._cur.set_payload(EMPTYSTRING.join(preamble))
  305.                 epilogue = []
  306.                 for line in self._input:
  307.                     if line is NeedMoreData:
  308.                         yield NeedMoreData
  309.                         continue
  310.                         continue
  311.                 
  312.                 self._cur.epilogue = EMPTYSTRING.join(epilogue)
  313.                 return None
  314.             if linesep:
  315.                 epilogue = [
  316.                     '']
  317.             else:
  318.                 epilogue = []
  319.             for line in self._input:
  320.                 if line is NeedMoreData:
  321.                     yield NeedMoreData
  322.                     continue
  323.                 
  324.                 epilogue.append(line)
  325.             
  326.             if epilogue:
  327.                 firstline = epilogue[0]
  328.                 bolmo = NLCRE_bol.match(firstline)
  329.                 if bolmo:
  330.                     epilogue[0] = firstline[len(bolmo.group(0)):]
  331.                 
  332.             
  333.             self._cur.epilogue = EMPTYSTRING.join(epilogue)
  334.             return None
  335.         lines = []
  336.         for line in self._input:
  337.             lines.append(line)
  338.         
  339.         self._cur.set_payload(EMPTYSTRING.join(lines))
  340.  
  341.     
  342.     def _parse_headers(self, lines):
  343.         lastheader = ''
  344.         lastvalue = []
  345.         for lineno, line in enumerate(lines):
  346.             if line[0] in ' \t':
  347.                 if not lastheader:
  348.                     defect = errors.FirstHeaderLineIsContinuationDefect(line)
  349.                     self._cur.defects.append(defect)
  350.                     continue
  351.                 
  352.                 lastvalue.append(line)
  353.                 continue
  354.             
  355.             if lastheader:
  356.                 lhdr = EMPTYSTRING.join(lastvalue)[:-1].rstrip('\r\n')
  357.                 self._cur[lastheader] = lhdr
  358.                 lastheader = ''
  359.                 lastvalue = []
  360.             
  361.             if line.startswith('From '):
  362.                 if lineno == 0:
  363.                     mo = NLCRE_eol.search(line)
  364.                     if mo:
  365.                         line = line[:-len(mo.group(0))]
  366.                     
  367.                     self._cur.set_unixfrom(line)
  368.                     continue
  369.                 elif lineno == len(lines) - 1:
  370.                     self._input.unreadline(line)
  371.                     return None
  372.                 defect = errors.MisplacedEnvelopeHeaderDefect(line)
  373.                 self._cur.defects.append(defect)
  374.                 continue
  375.             
  376.             i = line.find(':')
  377.             if i < 0:
  378.                 defect = errors.MalformedHeaderDefect(line)
  379.                 self._cur.defects.append(defect)
  380.                 continue
  381.             
  382.             lastheader = line[:i]
  383.             lastvalue = [
  384.                 line[i + 1:].lstrip()]
  385.         
  386.         if lastheader:
  387.             self._cur[lastheader] = EMPTYSTRING.join(lastvalue).rstrip('\r\n')
  388.         
  389.  
  390.  
  391.