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

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. __all__ = [
  5.     'Header',
  6.     'decode_header',
  7.     'make_header']
  8. import re
  9. import binascii
  10. import email.quoprimime as email
  11. import email.base64mime as email
  12. from email.errors import HeaderParseError
  13. from email.charset import Charset
  14. NL = '\n'
  15. SPACE = ' '
  16. USPACE = u' '
  17. SPACE8 = ' ' * 8
  18. UEMPTYSTRING = u''
  19. MAXLINELEN = 76
  20. USASCII = Charset('us-ascii')
  21. UTF8 = Charset('utf-8')
  22. ecre = re.compile('\n  =\\?                   # literal =?\n  (?P<charset>[^?]*?)   # non-greedy up to the next ? is the charset\n  \\?                    # literal ?\n  (?P<encoding>[qb])    # either a "q" or a "b", case insensitive\n  \\?                    # literal ?\n  (?P<encoded>.*?)      # non-greedy up to the next ?= is the encoded string\n  \\?=                   # literal ?=\n  (?=[ \\t]|$)           # whitespace or the end of the string\n  ', re.VERBOSE | re.IGNORECASE | re.MULTILINE)
  23. fcre = re.compile('[\\041-\\176]+:$')
  24. _max_append = email.quoprimime._max_append
  25.  
  26. def decode_header(header):
  27.     header = str(header)
  28.     if not ecre.search(header):
  29.         return [
  30.             (header, None)]
  31.     decoded = []
  32.     dec = ''
  33.     for line in header.splitlines():
  34.         if not ecre.search(line):
  35.             decoded.append((line, None))
  36.             continue
  37.         
  38.         parts = ecre.split(line)
  39.         while parts:
  40.             unenc = parts.pop(0).strip()
  41.             if unenc:
  42.                 if decoded and decoded[-1][1] is None:
  43.                     decoded[-1] = (decoded[-1][0] + SPACE + unenc, None)
  44.                 else:
  45.                     decoded.append((unenc, None))
  46.             
  47.             if parts:
  48.                 (charset, encoding) = [ s.lower() for s in parts[0:2] ]
  49.                 encoded = parts[2]
  50.                 dec = None
  51.                 if encoding == 'q':
  52.                     dec = email.quoprimime.header_decode(encoded)
  53.                 elif encoding == 'b':
  54.                     
  55.                     try:
  56.                         dec = email.base64mime.decode(encoded)
  57.                     except binascii.Error:
  58.                         []
  59.                         []
  60.                         raise HeaderParseError
  61.                     except:
  62.                         []<EXCEPTION MATCH>binascii.Error
  63.                     
  64.  
  65.                 []
  66.                 if dec is None:
  67.                     dec = encoded
  68.                 
  69.                 if decoded and decoded[-1][1] == charset:
  70.                     decoded[-1] = (decoded[-1][0] + dec, decoded[-1][1])
  71.                 else:
  72.                     decoded.append((dec, charset))
  73.             
  74.             del parts[0:3]
  75.     
  76.     return decoded
  77.  
  78.  
  79. def make_header(decoded_seq, maxlinelen = None, header_name = None, continuation_ws = ' '):
  80.     h = Header(maxlinelen = maxlinelen, header_name = header_name, continuation_ws = continuation_ws)
  81.     for s, charset in decoded_seq:
  82.         if charset is not None and not isinstance(charset, Charset):
  83.             charset = Charset(charset)
  84.         
  85.         h.append(s, charset)
  86.     
  87.     return h
  88.  
  89.  
  90. class Header:
  91.     
  92.     def __init__(self, s = None, charset = None, maxlinelen = None, header_name = None, continuation_ws = ' ', errors = 'strict'):
  93.         if charset is None:
  94.             charset = USASCII
  95.         
  96.         if not isinstance(charset, Charset):
  97.             charset = Charset(charset)
  98.         
  99.         self._charset = charset
  100.         self._continuation_ws = continuation_ws
  101.         cws_expanded_len = len(continuation_ws.replace('\t', SPACE8))
  102.         self._chunks = []
  103.         if s is not None:
  104.             self.append(s, charset, errors)
  105.         
  106.         if maxlinelen is None:
  107.             maxlinelen = MAXLINELEN
  108.         
  109.         if header_name is None:
  110.             self._firstlinelen = maxlinelen
  111.         else:
  112.             self._firstlinelen = maxlinelen - len(header_name) - 2
  113.         self._maxlinelen = maxlinelen - cws_expanded_len
  114.  
  115.     
  116.     def __str__(self):
  117.         return self.encode()
  118.  
  119.     
  120.     def __unicode__(self):
  121.         uchunks = []
  122.         lastcs = None
  123.         for s, charset in self._chunks:
  124.             nextcs = charset
  125.             if uchunks:
  126.                 if lastcs not in (None, 'us-ascii'):
  127.                     if nextcs in (None, 'us-ascii'):
  128.                         uchunks.append(USPACE)
  129.                         nextcs = None
  130.                     
  131.                 elif nextcs not in (None, 'us-ascii'):
  132.                     uchunks.append(USPACE)
  133.                 
  134.             
  135.             lastcs = nextcs
  136.             uchunks.append(unicode(s, str(charset)))
  137.         
  138.         return UEMPTYSTRING.join(uchunks)
  139.  
  140.     
  141.     def __eq__(self, other):
  142.         return other == self.encode()
  143.  
  144.     
  145.     def __ne__(self, other):
  146.         return not (self == other)
  147.  
  148.     
  149.     def append(self, s, charset = None, errors = 'strict'):
  150.         if charset is None:
  151.             charset = self._charset
  152.         elif not isinstance(charset, Charset):
  153.             charset = Charset(charset)
  154.         
  155.         if charset != '8bit':
  156.             if isinstance(s, str):
  157.                 if not charset.input_codec:
  158.                     pass
  159.                 incodec = 'us-ascii'
  160.                 ustr = unicode(s, incodec, errors)
  161.                 if not charset.output_codec:
  162.                     pass
  163.                 outcodec = 'us-ascii'
  164.                 ustr.encode(outcodec, errors)
  165.             elif isinstance(s, unicode):
  166.                 for charset in (USASCII, charset, UTF8):
  167.                     
  168.                     try:
  169.                         if not charset.output_codec:
  170.                             pass
  171.                         outcodec = 'us-ascii'
  172.                         s = s.encode(outcodec, errors)
  173.                     continue
  174.                     except UnicodeError:
  175.                         continue
  176.                     
  177.  
  178.                 
  179.             
  180.         
  181.         self._chunks.append((s, charset))
  182.  
  183.     
  184.     def _split(self, s, charset, maxlinelen, splitchars):
  185.         splittable = charset.to_splittable(s)
  186.         encoded = charset.from_splittable(splittable, True)
  187.         elen = charset.encoded_header_len(encoded)
  188.         if elen <= maxlinelen:
  189.             return [
  190.                 (encoded, charset)]
  191.         if charset == '8bit':
  192.             return [
  193.                 (s, charset)]
  194.         if charset == 'us-ascii':
  195.             return self._split_ascii(s, charset, maxlinelen, splitchars)
  196.         fsplittable = charset.to_splittable(first)
  197.         fencoded = charset.from_splittable(fsplittable, True)
  198.         chunk = [
  199.             (fencoded, charset)]
  200.         return chunk + self._split(last, charset, self._maxlinelen, splitchars)
  201.  
  202.     
  203.     def _split_ascii(self, s, charset, firstlen, splitchars):
  204.         chunks = _split_ascii(s, firstlen, self._maxlinelen, self._continuation_ws, splitchars)
  205.         return zip(chunks, [
  206.             charset] * len(chunks))
  207.  
  208.     
  209.     def _encode_chunks(self, newchunks, maxlinelen):
  210.         chunks = []
  211.         for header, charset in newchunks:
  212.             if not header:
  213.                 continue
  214.             
  215.             if charset is None or charset.header_encoding is None:
  216.                 s = header
  217.             else:
  218.                 s = charset.header_encode(header)
  219.             if chunks and chunks[-1].endswith(' '):
  220.                 extra = ''
  221.             else:
  222.                 extra = ' '
  223.             _max_append(chunks, s, maxlinelen, extra)
  224.         
  225.         joiner = NL + self._continuation_ws
  226.         return joiner.join(chunks)
  227.  
  228.     
  229.     def encode(self, splitchars = ';, '):
  230.         newchunks = []
  231.         maxlinelen = self._firstlinelen
  232.         lastlen = 0
  233.         for s, charset in self._chunks:
  234.             targetlen = maxlinelen - lastlen - 1
  235.             if targetlen < charset.encoded_header_len(''):
  236.                 targetlen = maxlinelen
  237.             
  238.             newchunks += self._split(s, charset, targetlen, splitchars)
  239.             (lastchunk, lastcharset) = newchunks[-1]
  240.             lastlen = lastcharset.encoded_header_len(lastchunk)
  241.         
  242.         return self._encode_chunks(newchunks, maxlinelen)
  243.  
  244.  
  245.  
  246. def _split_ascii(s, firstlen, restlen, continuation_ws, splitchars):
  247.     lines = []
  248.     maxlen = firstlen
  249.     for line in s.splitlines():
  250.         line = line.lstrip()
  251.         if len(line) < maxlen:
  252.             lines.append(line)
  253.             maxlen = restlen
  254.             continue
  255.         
  256.         for ch in splitchars:
  257.             if ch in line:
  258.                 break
  259.                 continue
  260.         else:
  261.             maxlen = restlen
  262.         cre = re.compile('%s\\s*' % ch)
  263.         if ch in ';,':
  264.             eol = ch
  265.         else:
  266.             eol = ''
  267.         joiner = eol + ' '
  268.         joinlen = len(joiner)
  269.         wslen = len(continuation_ws.replace('\t', SPACE8))
  270.         this = []
  271.         linelen = 0
  272.         for part in cre.split(line):
  273.             curlen = linelen + max(0, len(this) - 1) * joinlen
  274.             partlen = len(part)
  275.             onfirstline = not lines
  276.             if ch == ' ' and onfirstline and len(this) == 1 and fcre.match(this[0]):
  277.                 this.append(part)
  278.                 linelen += partlen
  279.                 continue
  280.             if curlen + partlen > maxlen:
  281.                 if this:
  282.                     lines.append(joiner.join(this) + eol)
  283.                 
  284.                 if partlen > maxlen and ch != ' ':
  285.                     subl = _split_ascii(part, maxlen, restlen, continuation_ws, ' ')
  286.                     lines.extend(subl[:-1])
  287.                     this = [
  288.                         subl[-1]]
  289.                 else:
  290.                     this = [
  291.                         part]
  292.                 linelen = wslen + len(this[-1])
  293.                 maxlen = restlen
  294.                 continue
  295.             this.append(part)
  296.             linelen += partlen
  297.         
  298.         if this:
  299.             lines.append(joiner.join(this))
  300.             continue
  301.     
  302.     return lines
  303.  
  304.  
  305. def _binsplit(splittable, charset, maxlinelen):
  306.     i = 0
  307.     j = len(splittable)
  308.     while i < j:
  309.         m = i + j + 1 >> 1
  310.         chunk = charset.from_splittable(splittable[:m], True)
  311.         chunklen = charset.encoded_header_len(chunk)
  312.         if chunklen <= maxlinelen:
  313.             i = m
  314.             continue
  315.         j = m - 1
  316.     first = charset.from_splittable(splittable[:i], False)
  317.     last = charset.from_splittable(splittable[i:], False)
  318.     return (first, last)
  319.  
  320.