home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2011 January / maximum-cd-2011-01.iso / DiscContents / calibre-0.7.26.msi / file_810 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-10-31  |  13.7 KB  |  418 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. __license__ = 'GPL v3'
  5. __copyright__ = '2009, John Schember <john at nachtimwald.com>'
  6. __docformat__ = 'restructuredtext en'
  7. import os
  8. import re
  9. import time
  10. from itertools import cycle
  11. from calibre import prints, isbytestring
  12. from calibre.constants import filesystem_encoding, DEBUG
  13. from calibre.devices.usbms.cli import CLI
  14. from calibre.devices.usbms.device import Device
  15. from calibre.devices.usbms.books import BookList, Book
  16. from calibre.ebooks.metadata.book.json_codec import JsonCodec
  17. BASE_TIME = None
  18.  
  19. def debug_print(*args):
  20.     global BASE_TIME
  21.     if BASE_TIME is None:
  22.         BASE_TIME = time.time()
  23.     
  24.     if DEBUG:
  25.         prints('DEBUG: %6.1f' % (time.time() - BASE_TIME), *args)
  26.     
  27.  
  28.  
  29. class USBMS(CLI, Device):
  30.     description = _('Communicate with an eBook reader.')
  31.     author = _('John Schember')
  32.     supported_platforms = [
  33.         'windows',
  34.         'osx',
  35.         'linux']
  36.     booklist_class = BookList
  37.     book_class = Book
  38.     FORMATS = []
  39.     CAN_SET_METADATA = []
  40.     METADATA_CACHE = 'metadata.calibre'
  41.     
  42.     def get_device_information(self, end_session = True):
  43.         self.report_progress(1, _('Get device information...'))
  44.         return (self.get_gui_name(), '', '', '')
  45.  
  46.     
  47.     def books(self, oncard = None, end_session = True):
  48.         path_to_ext = path_to_ext
  49.         import calibre.ebooks.metadata.meta
  50.         debug_print('USBMS: Fetching list of books from device. oncard=', oncard)
  51.         dummy_bl = self.booklist_class(None, None, None)
  52.         if oncard == 'carda' and not (self._card_a_prefix):
  53.             self.report_progress(1, _('Getting list of books on device...'))
  54.             return dummy_bl
  55.         if oncard == 'cardb' and not (self._card_b_prefix):
  56.             self.report_progress(1, _('Getting list of books on device...'))
  57.             return dummy_bl
  58.         if oncard and oncard != 'carda' and oncard != 'cardb':
  59.             self.report_progress(1, _('Getting list of books on device...'))
  60.             return dummy_bl
  61.         if oncard == 'carda':
  62.             pass
  63.         elif oncard == 'cardb':
  64.             pass
  65.         
  66.         prefix = self._main_prefix
  67.         if oncard == 'carda':
  68.             pass
  69.         elif oncard == 'cardb':
  70.             pass
  71.         
  72.         ebook_dirs = self.get_main_ebook_dir()
  73.         debug_print('USBMS: dirs are:', prefix, ebook_dirs)
  74.         bl = self.booklist_class(oncard, prefix, self.settings)
  75.         need_sync = self.parse_metadata_cache(bl, prefix, self.METADATA_CACHE)
  76.         bl_cache = { }
  77.         for idx, b in enumerate(bl):
  78.             bl_cache[b.lpath] = idx
  79.         
  80.         
  81.         def update_booklist(filename, path, prefix):
  82.             changed = False
  83.             if path_to_ext(filename) in self.FORMATS:
  84.                 
  85.                 try:
  86.                     lpath = os.path.join(path, filename).partition(self.normalize_path(prefix))[2]
  87.                     if lpath.startswith(os.sep):
  88.                         lpath = lpath[len(os.sep):]
  89.                     
  90.                     lpath = lpath.replace('\\', '/')
  91.                     idx = bl_cache.get(lpath, None)
  92.                     if idx is not None:
  93.                         bl_cache[lpath] = None
  94.                         if self.update_metadata_item(bl[idx]):
  95.                             changed = True
  96.                         
  97.                     elif bl.add_book(self.book_from_path(prefix, lpath), replace_metadata = False):
  98.                         changed = True
  99.                 import traceback
  100.                 traceback.print_exc()
  101.  
  102.             
  103.             return changed
  104.  
  105.         if isinstance(ebook_dirs, basestring):
  106.             ebook_dirs = [
  107.                 ebook_dirs]
  108.         
  109.         for ebook_dir in ebook_dirs:
  110.             ebook_dir = self.path_to_unicode(ebook_dir)
  111.             ebook_dir = None(self.normalize_path if ebook_dir else prefix)
  112.             if not os.path.exists(ebook_dir):
  113.                 continue
  114.             
  115.             if self.SUPPORTS_SUB_DIRS:
  116.                 flist = []
  117.                 for path, dirs, files in os.walk(ebook_dir):
  118.                     for filename in files:
  119.                         if filename != self.METADATA_CACHE:
  120.                             flist.append({
  121.                                 'filename': self.path_to_unicode(filename),
  122.                                 'path': self.path_to_unicode(path) })
  123.                             continue
  124.                     
  125.                 
  126.                 for i, f in enumerate(flist):
  127.                     self.report_progress(i / float(len(flist)), _('Getting list of books on device...'))
  128.                     changed = update_booklist(f['filename'], f['path'], prefix)
  129.                     if changed:
  130.                         need_sync = True
  131.                         continue
  132.                 
  133.             paths = os.listdir(ebook_dir)
  134.             for i, filename in enumerate(paths):
  135.                 self.report_progress((i + 1) / float(len(paths)), _('Getting list of books on device...'))
  136.                 changed = update_booklist(self.path_to_unicode(filename), ebook_dir, prefix)
  137.                 if changed:
  138.                     need_sync = True
  139.                     continue
  140.             
  141.         
  142.         for idx in sorted(bl_cache.itervalues(), reverse = True):
  143.             if idx is not None:
  144.                 need_sync = True
  145.                 del bl[idx]
  146.                 continue
  147.         
  148.         debug_print('USBMS: count found in cache: %d, count of files in metadata: %d, need_sync: %s' % (len(bl_cache), len(bl), need_sync))
  149.         if need_sync:
  150.             if oncard == 'cardb':
  151.                 self.sync_booklists((None, None, bl))
  152.             elif oncard == 'carda':
  153.                 self.sync_booklists((None, bl, None))
  154.             else:
  155.                 self.sync_booklists((bl, None, None))
  156.         
  157.         self.report_progress(1, _('Getting list of books on device...'))
  158.         debug_print('USBMS: Finished fetching list of books from device. oncard=', oncard)
  159.         return bl
  160.  
  161.     
  162.     def upload_books(self, files, names, on_card = None, end_session = True, metadata = None):
  163.         debug_print('USBMS: uploading %d books' % len(files))
  164.         path = self._sanity_check(on_card, files)
  165.         paths = []
  166.         names = iter(names)
  167.         metadata = iter(metadata)
  168.         for i, infile in enumerate(files):
  169.             mdata = metadata.next()
  170.             fname = names.next()
  171.             filepath = self.normalize_path(self.create_upload_path(path, mdata, fname))
  172.             paths.append(filepath)
  173.             if not hasattr(infile, 'read'):
  174.                 infile = self.normalize_path(infile)
  175.             
  176.             self.put_file(infile, filepath, replace_file = True)
  177.             
  178.             try:
  179.                 self.upload_cover(os.path.dirname(filepath), os.path.splitext(os.path.basename(filepath))[0], mdata, filepath)
  180.             except:
  181.                 import traceback
  182.                 traceback.print_exc()
  183.  
  184.             self.report_progress((i + 1) / float(len(files)), _('Transferring books to device...'))
  185.         
  186.         self.report_progress(1, _('Transferring books to device...'))
  187.         debug_print('USBMS: finished uploading %d books' % len(files))
  188.         return zip(paths, cycle([
  189.             on_card]))
  190.  
  191.     
  192.     def upload_cover(self, path, filename, metadata, filepath):
  193.         pass
  194.  
  195.     
  196.     def add_books_to_metadata(self, locations, metadata, booklists):
  197.         debug_print('USBMS: adding metadata for %d books' % len(metadata))
  198.         metadata = iter(metadata)
  199.         for i, location in enumerate(locations):
  200.             self.report_progress((i + 1) / float(len(locations)), _('Adding books to device metadata listing...'))
  201.             info = metadata.next()
  202.             if location[1] == 'cardb':
  203.                 pass
  204.             elif location[1] == 'carda':
  205.                 pass
  206.             
  207.             blist = 0
  208.             path = self.normalize_path(location[0])
  209.             if self._main_prefix:
  210.                 prefix = None if path.startswith(self.normalize_path(self._main_prefix)) else None
  211.             
  212.             if not prefix and self._card_a_prefix:
  213.                 prefix = None if path.startswith(self.normalize_path(self._card_a_prefix)) else None
  214.             
  215.             if not prefix and self._card_b_prefix:
  216.                 prefix = None if path.startswith(self.normalize_path(self._card_b_prefix)) else None
  217.             
  218.             if prefix is None:
  219.                 prints('in add_books_to_metadata. Prefix is None!', path, self._main_prefix)
  220.                 continue
  221.             
  222.             lpath = path.partition(prefix)[2]
  223.             if lpath.startswith('/') or lpath.startswith('\\'):
  224.                 lpath = lpath[1:]
  225.             
  226.             book = self.book_class(prefix, lpath, other = info)
  227.             if book.size is None:
  228.                 book.size = os.stat(self.normalize_path(path)).st_size
  229.             
  230.             b = booklists[blist].add_book(book, replace_metadata = True)
  231.             if b:
  232.                 b._new_book = True
  233.                 continue
  234.         
  235.         self.report_progress(1, _('Adding books to device metadata listing...'))
  236.         debug_print('USBMS: finished adding metadata')
  237.  
  238.     
  239.     def delete_books(self, paths, end_session = True):
  240.         debug_print('USBMS: deleting %d books' % len(paths))
  241.         for i, path in enumerate(paths):
  242.             self.report_progress((i + 1) / float(len(paths)), _('Removing books from device...'))
  243.             path = self.normalize_path(path)
  244.             if os.path.exists(path):
  245.                 os.unlink(path)
  246.                 filepath = os.path.splitext(path)[0]
  247.                 for ext in self.DELETE_EXTS:
  248.                     if os.path.exists(filepath + ext):
  249.                         os.unlink(filepath + ext)
  250.                     
  251.                     if os.path.exists(path + ext):
  252.                         os.unlink(path + ext)
  253.                         continue
  254.                 
  255.                 if self.SUPPORTS_SUB_DIRS:
  256.                     
  257.                     try:
  258.                         os.removedirs(os.path.dirname(path))
  259.  
  260.                 
  261.             self.SUPPORTS_SUB_DIRS
  262.         
  263.         self.report_progress(1, _('Removing books from device...'))
  264.         debug_print('USBMS: finished deleting %d books' % len(paths))
  265.  
  266.     
  267.     def remove_books_from_metadata(self, paths, booklists):
  268.         debug_print('USBMS: removing metadata for %d books' % len(paths))
  269.         for i, path in enumerate(paths):
  270.             self.report_progress((i + 1) / float(len(paths)), _('Removing books from device metadata listing...'))
  271.             for bl in booklists:
  272.                 for book in bl:
  273.                     if path.endswith(book.path):
  274.                         bl.remove_book(book)
  275.                         continue
  276.                 
  277.             
  278.         
  279.         self.report_progress(1, _('Removing books from device metadata listing...'))
  280.         debug_print('USBMS: finished removing metadata for %d books' % len(paths))
  281.  
  282.     
  283.     def sync_booklists(self, booklists, end_session = True):
  284.         debug_print('USBMS: starting sync_booklists')
  285.         json_codec = JsonCodec()
  286.         if not os.path.exists(self.normalize_path(self._main_prefix)):
  287.             os.makedirs(self.normalize_path(self._main_prefix))
  288.         
  289.         
  290.         def write_prefix(prefix, listid):
  291.             pass
  292.  
  293.         write_prefix(self._main_prefix, 0)
  294.         write_prefix(self._card_a_prefix, 1)
  295.         write_prefix(self._card_b_prefix, 2)
  296.         for blist in booklists:
  297.             if blist is not None:
  298.                 for book in blist:
  299.                     book._new_book = False
  300.                 
  301.             (None, None, None)
  302.         
  303.         self.report_progress(1, _('Sending metadata to device...'))
  304.         debug_print('USBMS: finished sync_booklists')
  305.  
  306.     
  307.     def build_template_regexp(cls):
  308.         
  309.         def replfunc(match):
  310.             if match.group(1) in ('title', 'series', 'series_index', 'isbn'):
  311.                 return '(?P<' + match.group(1) + '>.+?)'
  312.             if match.group(1) in ('authors', 'author_sort'):
  313.                 return '(?P<author>.+?)'
  314.             return '(.+?)'
  315.  
  316.         template = cls.save_template().rpartition('/')[2]
  317.         return re.compile(re.sub('{([^}]*)}', replfunc, template) + '([_\\d]*$)')
  318.  
  319.     build_template_regexp = classmethod(build_template_regexp)
  320.     
  321.     def path_to_unicode(cls, path):
  322.         if isbytestring(path):
  323.             path = path.decode(filesystem_encoding)
  324.         
  325.         return path
  326.  
  327.     path_to_unicode = classmethod(path_to_unicode)
  328.     
  329.     def normalize_path(cls, path):
  330.         if path is None:
  331.             return None
  332.         if os.sep == '\\':
  333.             path = path.replace('/', '\\')
  334.         else:
  335.             path = path.replace('\\', '/')
  336.         return cls.path_to_unicode(path)
  337.  
  338.     normalize_path = classmethod(normalize_path)
  339.     
  340.     def parse_metadata_cache(cls, bl, prefix, name):
  341.         json_codec = JsonCodec()
  342.         need_sync = False
  343.         cache_file = cls.normalize_path(os.path.join(prefix, name))
  344.         if os.access(cache_file, os.R_OK):
  345.             
  346.             try:
  347.                 
  348.                 try:
  349.                     f = _[1]
  350.                     json_codec.decode_from_file(f, bl, cls.book_class, prefix)
  351.                 finally:
  352.                     pass
  353.  
  354.             import traceback
  355.             traceback.print_exc()
  356.             bl = []
  357.             need_sync = True
  358.  
  359.         else:
  360.             need_sync = True
  361.         return need_sync
  362.  
  363.     parse_metadata_cache = classmethod(parse_metadata_cache)
  364.     
  365.     def update_metadata_item(cls, book):
  366.         changed = False
  367.         size = os.stat(cls.normalize_path(book.path)).st_size
  368.         if size != book.size:
  369.             changed = True
  370.             mi = cls.metadata_from_path(book.path)
  371.             book.smart_update(mi)
  372.             book.size = size
  373.         
  374.         return changed
  375.  
  376.     update_metadata_item = classmethod(update_metadata_item)
  377.     
  378.     def metadata_from_path(cls, path):
  379.         return cls.metadata_from_formats([
  380.             path])
  381.  
  382.     metadata_from_path = classmethod(metadata_from_path)
  383.     
  384.     def metadata_from_formats(cls, fmts):
  385.         metadata_from_formats = metadata_from_formats
  386.         import calibre.ebooks.metadata.meta
  387.         quick_metadata = quick_metadata
  388.         import calibre.customize.ui
  389.         quick_metadata.__enter__()
  390.         
  391.         try:
  392.             return metadata_from_formats(fmts, force_read_metadata = True, pattern = cls.build_template_regexp())
  393.         finally:
  394.             pass
  395.  
  396.  
  397.     metadata_from_formats = classmethod(metadata_from_formats)
  398.     
  399.     def book_from_path(cls, prefix, lpath):
  400.         Metadata = Metadata
  401.         import calibre.ebooks.metadata.book.base
  402.         if cls.settings().read_metadata or cls.MUST_READ_METADATA:
  403.             mi = cls.metadata_from_path(cls.normalize_path(os.path.join(prefix, lpath)))
  404.         else:
  405.             metadata_from_filename = metadata_from_filename
  406.             import calibre.ebooks.metadata.meta
  407.             mi = metadata_from_filename(cls.normalize_path(os.path.basename(lpath)), cls.build_template_regexp())
  408.         if mi is None:
  409.             mi = Metadata(os.path.splitext(os.path.basename(lpath))[0], [
  410.                 _('Unknown')])
  411.         
  412.         size = os.stat(cls.normalize_path(os.path.join(prefix, lpath))).st_size
  413.         book = cls.book_class(prefix, lpath, other = mi, size = size)
  414.         return book
  415.  
  416.     book_from_path = classmethod(book_from_path)
  417.  
  418.