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

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. __license__ = 'GPL v3'
  5. __copyright__ = '2010, Timothy Legge <timlegge at gmail.com> and Kovid Goyal <kovid@kovidgoyal.net>'
  6. __docformat__ = 'restructuredtext en'
  7. import os
  8. import sqlite3 as sqlite
  9. from calibre.devices.usbms.books import BookList
  10. from calibre.devices.kobo.books import Book
  11. from calibre.devices.kobo.books import ImageWrapper
  12. from calibre.devices.mime import mime_type_ext
  13. from calibre.devices.usbms.driver import USBMS
  14. from calibre import prints
  15.  
  16. class KOBO(USBMS):
  17.     name = 'Kobo Reader Device Interface'
  18.     gui_name = 'Kobo Reader'
  19.     description = _('Communicate with the Kobo Reader')
  20.     author = 'Timothy Legge and Kovid Goyal'
  21.     version = (1, 0, 4)
  22.     supported_platforms = [
  23.         'windows',
  24.         'osx',
  25.         'linux']
  26.     FORMATS = [
  27.         'epub',
  28.         'pdf']
  29.     VENDOR_ID = [
  30.         8759]
  31.     PRODUCT_ID = [
  32.         16737]
  33.     BCD = [
  34.         272]
  35.     VENDOR_NAME = 'KOBO_INC'
  36.     WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = '.KOBOEREADER'
  37.     EBOOK_DIR_MAIN = ''
  38.     SUPPORTS_SUB_DIRS = True
  39.     VIRTUAL_BOOK_EXTENSIONS = frozenset([
  40.         'kobo'])
  41.     
  42.     def initialize(self):
  43.         USBMS.initialize(self)
  44.         self.book_class = Book
  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.         dummy_bl = BookList(None, None, None)
  51.         if oncard == 'carda' and not (self._card_a_prefix):
  52.             self.report_progress(1, _('Getting list of books on device...'))
  53.             return dummy_bl
  54.         if oncard == 'cardb' and not (self._card_b_prefix):
  55.             self.report_progress(1, _('Getting list of books on device...'))
  56.             return dummy_bl
  57.         if oncard and oncard != 'carda' and oncard != 'cardb':
  58.             self.report_progress(1, _('Getting list of books on device...'))
  59.             return dummy_bl
  60.         if oncard == 'carda':
  61.             pass
  62.         elif oncard == 'cardb':
  63.             pass
  64.         
  65.         prefix = self._main_prefix
  66.         bl = self.booklist_class(oncard, prefix, self.settings)
  67.         need_sync = self.parse_metadata_cache(bl, prefix, self.METADATA_CACHE)
  68.         bl_cache = { }
  69.         for idx, b in enumerate(bl):
  70.             bl_cache[b.lpath] = idx
  71.         
  72.         
  73.         def update_booklist(prefix, path, title, authors, mime, date, ContentType, ImageID):
  74.             changed = False
  75.             
  76.             try:
  77.                 lpath = path.partition(self.normalize_path(prefix))[2]
  78.                 if lpath.startswith(os.sep):
  79.                     lpath = lpath[len(os.sep):]
  80.                     lpath = lpath.replace('\\', '/')
  81.                 
  82.                 path = self.normalize_path(path)
  83.                 idx = bl_cache.get(lpath, None)
  84.                 if idx is not None:
  85.                     if ImageID is not None:
  86.                         imagename = self.normalize_path(self._main_prefix + '.kobo/images/' + ImageID + ' - NickelBookCover.parsed')
  87.                         if imagename is not None:
  88.                             bl[idx].thumbnail = ImageWrapper(imagename)
  89.                         
  90.                     
  91.                     bl_cache[lpath] = None
  92.                     if ContentType != '6':
  93.                         if self.update_metadata_item(bl[idx]):
  94.                             changed = True
  95.                         
  96.                     
  97.                 else:
  98.                     book = Book(prefix, lpath, title, authors, mime, date, ContentType, ImageID)
  99.                     if bl.add_book(book, replace_metadata = False):
  100.                         changed = True
  101.             except:
  102.                 import traceback
  103.                 traceback.print_exc()
  104.             
  105.  
  106.             return changed
  107.  
  108.         connection = sqlite.connect(self._main_prefix + '.kobo/KoboReader.sqlite')
  109.         cursor = connection.cursor()
  110.         query = 'select Title, Attribution, DateCreated, ContentID, MimeType, ContentType, ImageID from content where BookID is Null'
  111.         cursor.execute(query)
  112.         changed = False
  113.         for i, row in enumerate(cursor):
  114.             path = self.path_from_contentid(row[3], row[5], oncard)
  115.             mime = mime_type_ext(path_to_ext(row[3]))
  116.             if oncard != 'carda' and oncard != 'cardb' and not row[3].startswith('file:///mnt/sd/'):
  117.                 changed = update_booklist(self._main_prefix, path, row[0], row[1], mime, row[2], row[5], row[6])
  118.             elif oncard == 'carda' and row[3].startswith('file:///mnt/sd/'):
  119.                 changed = update_booklist(self._card_a_prefix, path, row[0], row[1], mime, row[2], row[5], row[6])
  120.             
  121.             if changed:
  122.                 need_sync = True
  123.                 continue
  124.         
  125.         cursor.close()
  126.         connection.close()
  127.         for idx in sorted(bl_cache.itervalues(), reverse = True):
  128.             if idx is not None:
  129.                 need_sync = True
  130.                 del bl[idx]
  131.                 continue
  132.         
  133.         if need_sync:
  134.             if oncard == 'cardb':
  135.                 self.sync_booklists((None, None, bl))
  136.             elif oncard == 'carda':
  137.                 self.sync_booklists((None, bl, None))
  138.             else:
  139.                 self.sync_booklists((bl, None, None))
  140.         
  141.         self.report_progress(1, _('Getting list of books on device...'))
  142.         return bl
  143.  
  144.     
  145.     def delete_via_sql(self, ContentID, ContentType):
  146.         connection = sqlite.connect(self._main_prefix + '.kobo/KoboReader.sqlite')
  147.         cursor = connection.cursor()
  148.         t = (ContentID,)
  149.         cursor.execute('select ImageID from content where ContentID = ?', t)
  150.         ImageID = None
  151.         for row in cursor:
  152.             ImageID = row[0]
  153.         
  154.         cursor.close()
  155.         cursor = connection.cursor()
  156.         if ContentType == 6:
  157.             cursor.execute('delete from shortcover_page where shortcoverid in (select ContentID from content where BookID = ?)', t)
  158.         
  159.         cursor.execute('delete from volume_shortcovers where volumeid = ?', t)
  160.         t = (ContentID, ContentID)
  161.         cursor.execute('delete from content where BookID  = ? or ContentID = ?', t)
  162.         connection.commit()
  163.         cursor.close()
  164.         if ImageID != None:
  165.             print 'Error condition ImageID was not found'
  166.             print 'You likely tried to delete a book that the kobo has not yet added to the database'
  167.         
  168.         connection.close()
  169.         return ImageID
  170.  
  171.     
  172.     def delete_images(self, ImageID):
  173.         if ImageID != None:
  174.             path_prefix = '.kobo/images/'
  175.             path = self._main_prefix + path_prefix + ImageID
  176.             file_endings = (' - iPhoneThumbnail.parsed', ' - bbMediumGridList.parsed', ' - NickelBookCover.parsed')
  177.             for ending in file_endings:
  178.                 fpath = path + ending
  179.                 fpath = self.normalize_path(fpath)
  180.                 if os.path.exists(fpath):
  181.                     os.unlink(fpath)
  182.                     continue
  183.             
  184.         
  185.  
  186.     
  187.     def delete_books(self, paths, end_session = True):
  188.         for i, path in enumerate(paths):
  189.             self.report_progress((i + 1) / float(len(paths)), _('Removing books from device...'))
  190.             path = self.normalize_path(path)
  191.             extension = os.path.splitext(path)[1]
  192.             if extension == '.kobo':
  193.                 ContentType = 6
  194.                 ContentID = self.contentid_from_path(path, ContentType)
  195.             elif extension == '.pdf' or extension == '.epub':
  196.                 ContentType = 16
  197.                 ContentID = self.contentid_from_path(path, ContentType)
  198.             else:
  199.                 ContentType = 999
  200.                 ContentID = self.contentid_from_path(path, ContentType)
  201.             ImageID = self.delete_via_sql(ContentID, ContentType)
  202.             self.delete_images(ImageID)
  203.             if os.path.exists(path):
  204.                 os.unlink(path)
  205.                 filepath = os.path.splitext(path)[0]
  206.                 for ext in self.DELETE_EXTS:
  207.                     if os.path.exists(filepath + ext):
  208.                         os.unlink(filepath + ext)
  209.                     
  210.                     if os.path.exists(path + ext):
  211.                         os.unlink(path + ext)
  212.                         continue
  213.                 
  214.                 if self.SUPPORTS_SUB_DIRS:
  215.                     
  216.                     try:
  217.                         os.removedirs(os.path.dirname(path))
  218.  
  219.                 
  220.             self.SUPPORTS_SUB_DIRS
  221.         
  222.         self.report_progress(1, _('Removing books from device...'))
  223.  
  224.     
  225.     def remove_books_from_metadata(self, paths, booklists):
  226.         for i, path in enumerate(paths):
  227.             self.report_progress((i + 1) / float(len(paths)), _('Removing books from device metadata listing...'))
  228.             for bl in booklists:
  229.                 for book in bl:
  230.                     if path.endswith(book.path):
  231.                         bl.remove_book(book)
  232.                         continue
  233.                 
  234.             
  235.         
  236.         self.report_progress(1, _('Removing books from device metadata listing...'))
  237.  
  238.     
  239.     def add_books_to_metadata(self, locations, metadata, booklists):
  240.         metadata = iter(metadata)
  241.         for i, location in enumerate(locations):
  242.             self.report_progress((i + 1) / float(len(locations)), _('Adding books to device metadata listing...'))
  243.             info = metadata.next()
  244.             if location[1] == 'cardb':
  245.                 pass
  246.             elif location[1] == 'carda':
  247.                 pass
  248.             
  249.             blist = 0
  250.             path = self.normalize_path(location[0])
  251.             if self._main_prefix:
  252.                 prefix = None if path.startswith(self.normalize_path(self._main_prefix)) else None
  253.             
  254.             if not prefix and self._card_a_prefix:
  255.                 prefix = None if path.startswith(self.normalize_path(self._card_a_prefix)) else None
  256.             
  257.             if not prefix and self._card_b_prefix:
  258.                 prefix = None if path.startswith(self.normalize_path(self._card_b_prefix)) else None
  259.             
  260.             if prefix is None:
  261.                 prints('in add_books_to_metadata. Prefix is None!', path, self._main_prefix)
  262.                 continue
  263.             
  264.             lpath = path.partition(prefix)[2]
  265.             if lpath.startswith('/') or lpath.startswith('\\'):
  266.                 lpath = lpath[1:]
  267.             
  268.             lpath = self.normalize_path(prefix + lpath)
  269.             book = Book(prefix, lpath, '', '', '', '', '', '', other = info)
  270.             if book.size is None:
  271.                 book.size = os.stat(self.normalize_path(path)).st_size
  272.             
  273.             booklists[blist].add_book(book, replace_metadata = True)
  274.         
  275.         self.report_progress(1, _('Adding books to device metadata listing...'))
  276.  
  277.     
  278.     def contentid_from_path(self, path, ContentType):
  279.         if ContentType == 6:
  280.             ContentID = os.path.splitext(path)[0]
  281.             ContentID = ContentID.replace(self._main_prefix, '')
  282.             if self._card_a_prefix is not None:
  283.                 ContentID = ContentID.replace(self._card_a_prefix, '')
  284.             
  285.         elif ContentType == 999:
  286.             ContentID = path
  287.             ContentID = ContentID.replace(self._main_prefix, '/mnt/onboard/')
  288.             if self._card_a_prefix is not None:
  289.                 ContentID = ContentID.replace(self._card_a_prefix, '/mnt/sd/')
  290.             
  291.         else:
  292.             ContentID = path
  293.             ContentID = ContentID.replace(self._main_prefix, 'file:///mnt/onboard/')
  294.             if self._card_a_prefix is not None:
  295.                 ContentID = ContentID.replace(self._card_a_prefix, 'file:///mnt/sd/')
  296.             
  297.         ContentID = ContentID.replace('\\', '/')
  298.         return ContentID
  299.  
  300.     
  301.     def path_from_contentid(self, ContentID, ContentType, oncard):
  302.         path = ContentID
  303.         if oncard == 'cardb':
  304.             print 'path from_contentid cardb'
  305.         elif oncard == 'carda':
  306.             path = path.replace('file:///mnt/sd/', self._card_a_prefix)
  307.         elif ContentType == '6':
  308.             path = self._main_prefix + path + '.kobo'
  309.         else:
  310.             path = path.replace('file:///mnt/onboard/', self._main_prefix)
  311.             path = path.replace('/mnt/onboard/', self._main_prefix)
  312.         return path
  313.  
  314.     
  315.     def get_file(self, path, *args, **kwargs):
  316.         tpath = self.munge_path(path)
  317.         extension = os.path.splitext(tpath)[1]
  318.         if extension == '.kobo':
  319.             UserFeedback = UserFeedback
  320.             import calibre.devices.errors
  321.             raise UserFeedback(_('Not Implemented'), _('".kobo" files do not exist on the device as books instead, they are rows in the sqlite database. Currently they cannot be exported or viewed.'), UserFeedback.WARN)
  322.         extension == '.kobo'
  323.         return USBMS.get_file(self, path, *args, **kwargs)
  324.  
  325.  
  326.