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

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. __license__ = 'GPL v3'
  5. __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
  6. __docformat__ = 'restructuredtext en'
  7. import os
  8. import mimetypes
  9. import sys
  10. import re
  11. from urllib import unquote, quote
  12. from urlparse import urlparse
  13. from calibre import relpath, prints
  14. from calibre.utils.config import tweaks
  15. from calibre.utils.date import isoformat
  16. _author_pat = re.compile(',?\\s+(and|with)\\s+', re.IGNORECASE)
  17.  
  18. def string_to_authors(raw):
  19.     raw = raw.replace('&&', u'∩┐┐')
  20.     raw = _author_pat.sub('&', raw)
  21.     authors = [ a.strip().replace(u'∩┐┐', '&') for a in raw.split('&') ]
  22.     return _[2]
  23.  
  24.  
  25. def authors_to_string(authors):
  26.     if authors is not None:
  27.         return [](_[1])
  28.     return ''
  29.  
  30. _bracket_pat = re.compile('[\\[({].*?[})\\]]')
  31.  
  32. def author_to_author_sort(author):
  33.     if not author:
  34.         return ''
  35.     method = tweaks['author_sort_copy_method']
  36.     if (method == 'copy' or method == 'comma') and ',' in author:
  37.         return author
  38.     author = _bracket_pat.sub('', author).strip()
  39.     tokens = author.split()
  40.     tokens = tokens[-1:] + tokens[:-1]
  41.     return ' '.join(tokens)
  42.  
  43.  
  44. def authors_to_sort_string(authors):
  45.     return ' & '.join(map(author_to_author_sort, authors))
  46.  
  47. _title_pat = re.compile('^(A|The|An)\\s+', re.IGNORECASE)
  48.  
  49. def title_sort(title):
  50.     match = _title_pat.search(title)
  51.     if match:
  52.         prep = match.group(1)
  53.         title = title[len(prep):] + ', ' + prep
  54.     
  55.     return title.strip()
  56.  
  57. coding = zip([
  58.     1000,
  59.     900,
  60.     500,
  61.     400,
  62.     100,
  63.     90,
  64.     50,
  65.     40,
  66.     10,
  67.     9,
  68.     5,
  69.     4,
  70.     1], [
  71.     'M',
  72.     'CM',
  73.     'D',
  74.     'CD',
  75.     'C',
  76.     'XC',
  77.     'L',
  78.     'XL',
  79.     'X',
  80.     'IX',
  81.     'V',
  82.     'IV',
  83.     'I'])
  84.  
  85. def roman(num):
  86.     if num <= 0 and num >= 4000 or int(num) != num:
  87.         return str(num)
  88.     result = []
  89.     for d, r in coding:
  90.         while num >= d:
  91.             result.append(r)
  92.             num -= d
  93.             continue
  94.             int(num) != num
  95.     
  96.     return ''.join(result)
  97.  
  98.  
  99. def fmt_sidx(i, fmt = '%.2f', use_roman = False):
  100.     if i is None or i == '':
  101.         i = 1
  102.     
  103.     
  104.     try:
  105.         i = float(i)
  106.     except TypeError:
  107.         return str(i)
  108.  
  109.     if int(i) == float(i):
  110.         if use_roman:
  111.             return roman(int(i))
  112.         return '%d' % int(i)
  113.     return fmt % i
  114.  
  115.  
  116. class Resource(object):
  117.     
  118.     def __init__(self, href_or_path, basedir = os.getcwd(), is_path = True):
  119.         self._href = None
  120.         self._basedir = basedir
  121.         self.path = None
  122.         self.fragment = ''
  123.         
  124.         try:
  125.             self.mime_type = mimetypes.guess_type(href_or_path)[0]
  126.         except:
  127.             self.mime_type = None
  128.  
  129.         if self.mime_type is None:
  130.             self.mime_type = 'application/octet-stream'
  131.         
  132.         if is_path:
  133.             path = href_or_path
  134.             if not os.path.isabs(path):
  135.                 path = os.path.abspath(os.path.join(basedir, path))
  136.             
  137.             if isinstance(path, str):
  138.                 path = path.decode(sys.getfilesystemencoding())
  139.             
  140.             self.path = path
  141.         else:
  142.             url = urlparse(href_or_path)
  143.             if url[0] not in ('', 'file'):
  144.                 self._href = href_or_path
  145.             else:
  146.                 pc = url[2]
  147.                 if isinstance(pc, unicode):
  148.                     pc = pc.encode('utf-8')
  149.                 
  150.                 pc = unquote(pc).decode('utf-8')
  151.                 self.path = os.path.abspath(os.path.join(basedir, pc.replace('/', os.sep)))
  152.                 self.fragment = unquote(url[-1])
  153.  
  154.     
  155.     def href(self, basedir = None):
  156.         if basedir is None:
  157.             if self._basedir:
  158.                 basedir = self._basedir
  159.             else:
  160.                 basedir = os.getcwd()
  161.         
  162.         if self.path is None:
  163.             return self._href
  164.         f = self.path is None if isinstance(self.fragment, unicode) else self.fragment
  165.         frag = None if self.fragment else ''
  166.         if self.path == basedir:
  167.             return '' + frag
  168.         
  169.         try:
  170.             rpath = relpath(self.path, basedir)
  171.         except OSError:
  172.             self.path == basedir
  173.             self.path == basedir
  174.             rpath = self.path
  175.         except:
  176.             self.path == basedir
  177.  
  178.         if isinstance(rpath, unicode):
  179.             rpath = rpath.encode('utf-8')
  180.         
  181.         return quote(rpath.replace(os.sep, '/')) + frag
  182.  
  183.     
  184.     def set_basedir(self, path):
  185.         self._basedir = path
  186.  
  187.     
  188.     def basedir(self):
  189.         return self._basedir
  190.  
  191.     
  192.     def __repr__(self):
  193.         return 'Resource(%s, %s)' % (repr(self.path), repr(self.href()))
  194.  
  195.  
  196.  
  197. class ResourceCollection(object):
  198.     
  199.     def __init__(self):
  200.         self._resources = []
  201.  
  202.     
  203.     def __iter__(self):
  204.         for r in self._resources:
  205.             yield r
  206.         
  207.  
  208.     
  209.     def __len__(self):
  210.         return len(self._resources)
  211.  
  212.     
  213.     def __getitem__(self, index):
  214.         return self._resources[index]
  215.  
  216.     
  217.     def __bool__(self):
  218.         return len(self._resources) > 0
  219.  
  220.     
  221.     def __str__(self):
  222.         resources = map(repr, self)
  223.         return '[%s]' % ', '.join(resources)
  224.  
  225.     
  226.     def __repr__(self):
  227.         return str(self)
  228.  
  229.     
  230.     def append(self, resource):
  231.         if not isinstance(resource, Resource):
  232.             raise ValueError('Can only append objects of type Resource')
  233.         isinstance(resource, Resource)
  234.         self._resources.append(resource)
  235.  
  236.     
  237.     def remove(self, resource):
  238.         self._resources.remove(resource)
  239.  
  240.     
  241.     def replace(self, start, end, items):
  242.         self._resources[start:end] = items
  243.  
  244.     
  245.     def from_directory_contents(top, topdown = True):
  246.         collection = ResourceCollection()
  247.         for spec in os.walk(top, topdown = topdown):
  248.             path = os.path.abspath(os.path.join(spec[0], spec[1]))
  249.             res = Resource.from_path(path)
  250.             res.set_basedir(top)
  251.             collection.append(res)
  252.         
  253.         return collection
  254.  
  255.     from_directory_contents = staticmethod(from_directory_contents)
  256.     
  257.     def set_basedir(self, path):
  258.         for res in self:
  259.             res.set_basedir(path)
  260.         
  261.  
  262.  
  263.  
  264. class MetaInformation(object):
  265.     
  266.     def copy(mi):
  267.         ans = MetaInformation(mi.title, mi.authors)
  268.         for attr in ('author_sort', 'title_sort', 'comments', 'category', 'publisher', 'series', 'series_index', 'rating', 'isbn', 'tags', 'cover_data', 'application_id', 'guide', 'manifest', 'spine', 'toc', 'cover', 'language', 'book_producer', 'timestamp', 'lccn', 'lcc', 'ddc', 'author_sort_map', 'pubdate', 'rights', 'publication_type', 'uuid'):
  269.             if hasattr(mi, attr):
  270.                 setattr(ans, attr, getattr(mi, attr))
  271.                 continue
  272.         
  273.  
  274.     copy = staticmethod(copy)
  275.     
  276.     def __init__(self, title, authors = (_('Unknown'),)):
  277.         mi = None
  278.         if hasattr(title, 'title') and hasattr(title, 'authors'):
  279.             mi = title
  280.             title = mi.title
  281.             authors = mi.authors
  282.         
  283.         self.title = title
  284.         self.author = None if authors else []
  285.         self.authors = None if authors else []
  286.         self.tags = getattr(mi, 'tags', [])
  287.         self.cover_data = getattr(mi, 'cover_data', (None, None))
  288.         self.author_sort_map = getattr(mi, 'author_sort_map', { })
  289.         for x in ('author_sort', 'title_sort', 'comments', 'category', 'publisher', 'series', 'series_index', 'rating', 'isbn', 'language', 'application_id', 'manifest', 'toc', 'spine', 'guide', 'cover', 'book_producer', 'timestamp', 'lccn', 'lcc', 'ddc', 'pubdate', 'rights', 'publication_type', 'uuid'):
  290.             setattr(self, x, getattr(mi, x, None))
  291.         
  292.  
  293.     
  294.     def print_all_attributes(self):
  295.         for x in ('title', 'author', 'author_sort', 'title_sort', 'comments', 'category', 'publisher', 'series', 'series_index', 'tags', 'rating', 'isbn', 'language', 'application_id', 'manifest', 'toc', 'spine', 'guide', 'cover', 'book_producer', 'timestamp', 'lccn', 'lcc', 'ddc', 'pubdate', 'rights', 'publication_type', 'uuid', 'author_sort_map'):
  296.             prints(x, getattr(self, x, 'None'))
  297.         
  298.  
  299.     
  300.     def smart_update(self, mi, replace_metadata = False):
  301.         if mi.title and mi.title != _('Unknown'):
  302.             self.title = mi.title
  303.         
  304.         if mi.authors and mi.authors[0] != _('Unknown'):
  305.             self.authors = mi.authors
  306.         
  307.         for attr in ('author_sort', 'title_sort', 'category', 'publisher', 'series', 'series_index', 'rating', 'isbn', 'application_id', 'manifest', 'spine', 'toc', 'cover', 'guide', 'book_producer', 'timestamp', 'lccn', 'lcc', 'ddc', 'pubdate', 'rights', 'publication_type', 'uuid'):
  308.             if replace_metadata:
  309.                 None(setattr, self, attr(getattr, mi, attr if attr == 'series_index' else None))
  310.                 continue
  311.             if hasattr(mi, attr):
  312.                 val = getattr(mi, attr)
  313.                 if val is not None:
  314.                     setattr(self, attr, val)
  315.                 
  316.             val is not None
  317.         
  318.         if replace_metadata:
  319.             self.tags = mi.tags
  320.         elif mi.tags:
  321.             self.tags += mi.tags
  322.         
  323.         self.tags = list(set(self.tags))
  324.         if mi.author_sort_map:
  325.             self.author_sort_map.update(mi.author_sort_map)
  326.         
  327.         if getattr(mi, 'cover_data', False):
  328.             other_cover = mi.cover_data[-1]
  329.             self_cover = None if self.cover_data else ''
  330.             if not self_cover:
  331.                 self_cover = ''
  332.             
  333.             if not other_cover:
  334.                 other_cover = ''
  335.             
  336.             if len(other_cover) > len(self_cover):
  337.                 self.cover_data = mi.cover_data
  338.             
  339.         
  340.         if replace_metadata:
  341.             self.comments = getattr(mi, 'comments', '')
  342.         else:
  343.             my_comments = getattr(self, 'comments', '')
  344.             other_comments = getattr(mi, 'comments', '')
  345.             if not my_comments:
  346.                 my_comments = ''
  347.             
  348.             if not other_comments:
  349.                 other_comments = ''
  350.             
  351.             if len(other_comments.strip()) > len(my_comments.strip()):
  352.                 self.comments = other_comments
  353.             
  354.         other_lang = getattr(mi, 'language', None)
  355.         if other_lang and other_lang.lower() != 'und':
  356.             self.language = other_lang
  357.         
  358.  
  359.     
  360.     def format_series_index(self):
  361.         
  362.         try:
  363.             x = float(self.series_index)
  364.         except ValueError:
  365.             x = 1
  366.  
  367.         return fmt_sidx(x)
  368.  
  369.     
  370.     def authors_from_string(self, raw):
  371.         self.authors = string_to_authors(raw)
  372.  
  373.     
  374.     def format_authors(self):
  375.         return authors_to_string(self.authors)
  376.  
  377.     
  378.     def format_tags(self):
  379.         return []([ unicode(t) for t in self.tags ])
  380.  
  381.     
  382.     def format_rating(self):
  383.         return unicode(self.rating)
  384.  
  385.     
  386.     def __unicode__(self):
  387.         ans = []
  388.         
  389.         def fmt(x, y):
  390.             ans.append(u'%-20s: %s' % (unicode(x), unicode(y)))
  391.  
  392.         fmt('Title', self.title)
  393.         if self.title_sort:
  394.             fmt('Title sort', self.title_sort)
  395.         
  396.         if self.authors:
  397.             None(fmt, 'Author(s)' + authors_to_string(self.authors) if self.author_sort else '')
  398.         
  399.         if self.publisher:
  400.             fmt('Publisher', self.publisher)
  401.         
  402.         if getattr(self, 'book_producer', False):
  403.             fmt('Book Producer', self.book_producer)
  404.         
  405.         if self.category:
  406.             fmt('Category', self.category)
  407.         
  408.         if self.comments:
  409.             fmt('Comments', self.comments)
  410.         
  411.         if self.isbn:
  412.             fmt('ISBN', self.isbn)
  413.         
  414.         if self.series:
  415.             fmt('Series', self.series + ' #%s' % self.format_series_index())
  416.         
  417.         if self.language:
  418.             fmt('Language', self.language)
  419.         
  420.         if self.rating is not None:
  421.             fmt('Rating', self.rating)
  422.         
  423.         if self.timestamp is not None:
  424.             fmt('Timestamp', isoformat(self.timestamp))
  425.         
  426.         if self.pubdate is not None:
  427.             fmt('Published', isoformat(self.pubdate))
  428.         
  429.         if self.rights is not None:
  430.             fmt('Rights', unicode(self.rights))
  431.         
  432.         if self.lccn:
  433.             fmt('LCCN', unicode(self.lccn))
  434.         
  435.         if self.lcc:
  436.             fmt('LCC', unicode(self.lcc))
  437.         
  438.         if self.ddc:
  439.             fmt('DDC', unicode(self.ddc))
  440.         
  441.         return u'\n'.join(ans)
  442.  
  443.     
  444.     def to_html(self):
  445.         ans = [
  446.             (_('Title'), unicode(self.title))]
  447.         None += [
  448.             (ans, _('Author(s)') if self.authors else _('Unknown'))]
  449.         ans += [
  450.             (_('Publisher'), unicode(self.publisher))]
  451.         ans += [
  452.             (_('Producer'), unicode(self.book_producer))]
  453.         ans += [
  454.             (_('Comments'), unicode(self.comments))]
  455.         ans += [
  456.             ('ISBN', unicode(self.isbn))]
  457.         if self.lccn:
  458.             ans += [
  459.                 ('LCCN', unicode(self.lccn))]
  460.         
  461.         if self.lcc:
  462.             ans += [
  463.                 ('LCC', unicode(self.lcc))]
  464.         
  465.         if self.ddc:
  466.             ans += [
  467.                 ('DDC', unicode(self.ddc))]
  468.         
  469.         u', '.join += [
  470.             ([], []([ unicode(t) for t in self.tags ]))]
  471.         ans += [
  472.             (_('Language'), unicode(self.language))]
  473.         if self.timestamp is not None:
  474.             ans += [
  475.                 (_('Timestamp'), unicode(self.timestamp.isoformat(' ')))]
  476.         
  477.         if self.pubdate is not None:
  478.             ans += [
  479.                 (_('Published'), unicode(self.pubdate.isoformat(' ')))]
  480.         
  481.         if self.rights is not None:
  482.             ans += [
  483.                 (_('Rights'), unicode(self.rights))]
  484.         
  485.         for i, x in enumerate(ans):
  486.             ans[i] = u'<tr><td><b>%s</b></td><td>%s</td></tr>' % x
  487.         
  488.         return u'<table>%s</table>' % u'\n'.join(ans)
  489.  
  490.     
  491.     def __str__(self):
  492.         return self.__unicode__().encode('utf-8')
  493.  
  494.     
  495.     def __nonzero__(self):
  496.         if not self.title and self.author and self.comments:
  497.             pass
  498.         return bool(self.tags)
  499.  
  500.  
  501.  
  502. def check_isbn10(isbn):
  503.     
  504.     try:
  505.         digits = map(int, isbn[:9])
  506.         products = [ (i + 1) * digits[i] for i in range(9) ]
  507.         check = sum(products) % 11
  508.         if check == 10 or isbn[9] == 'X' or check == int(isbn[9]):
  509.             return isbn
  510.     except:
  511.         pass
  512.  
  513.  
  514.  
  515. def check_isbn13(isbn):
  516.     
  517.     try:
  518.         digits = map(int, isbn[:12])
  519.         products = [ _[1] if i % 2 == 0 else 3 * digits[i] for i in range(12) ]
  520.         check = 10 - sum(products) % 10
  521.         if check == 10:
  522.             check = 0
  523.         
  524.         if str(check) == isbn[12]:
  525.             return isbn
  526.     except:
  527.         pass
  528.  
  529.  
  530.  
  531. def check_isbn(isbn):
  532.     isbn = re.sub('[^0-9X]', '', isbn.upper())
  533.     if len(isbn) == 10:
  534.         return check_isbn10(isbn)
  535.     if len(isbn) == 13:
  536.         return check_isbn13(isbn)
  537.  
  538.