home *** CD-ROM | disk | FTP | other *** search
Wrap
# Source Generated with Decompyle++ # File: in.pyc (Python 2.6) __license__ = 'GPL v3' __copyright__ = '2010, Timothy Legge <timlegge at gmail.com> and Kovid Goyal <kovid@kovidgoyal.net>' __docformat__ = 'restructuredtext en' import os import sqlite3 as sqlite from calibre.devices.usbms.books import BookList from calibre.devices.kobo.books import Book from calibre.devices.kobo.books import ImageWrapper from calibre.devices.mime import mime_type_ext from calibre.devices.usbms.driver import USBMS from calibre import prints class KOBO(USBMS): name = 'Kobo Reader Device Interface' gui_name = 'Kobo Reader' description = _('Communicate with the Kobo Reader') author = 'Timothy Legge and Kovid Goyal' version = (1, 0, 4) supported_platforms = [ 'windows', 'osx', 'linux'] FORMATS = [ 'epub', 'pdf'] VENDOR_ID = [ 8759] PRODUCT_ID = [ 16737] BCD = [ 272] VENDOR_NAME = 'KOBO_INC' WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = '.KOBOEREADER' EBOOK_DIR_MAIN = '' SUPPORTS_SUB_DIRS = True VIRTUAL_BOOK_EXTENSIONS = frozenset([ 'kobo']) def initialize(self): USBMS.initialize(self) self.book_class = Book def books(self, oncard = None, end_session = True): path_to_ext = path_to_ext import calibre.ebooks.metadata.meta dummy_bl = BookList(None, None, None) if oncard == 'carda' and not (self._card_a_prefix): self.report_progress(1, _('Getting list of books on device...')) return dummy_bl if oncard == 'cardb' and not (self._card_b_prefix): self.report_progress(1, _('Getting list of books on device...')) return dummy_bl if oncard and oncard != 'carda' and oncard != 'cardb': self.report_progress(1, _('Getting list of books on device...')) return dummy_bl if oncard == 'carda': pass elif oncard == 'cardb': pass prefix = self._main_prefix bl = self.booklist_class(oncard, prefix, self.settings) need_sync = self.parse_metadata_cache(bl, prefix, self.METADATA_CACHE) bl_cache = { } for idx, b in enumerate(bl): bl_cache[b.lpath] = idx def update_booklist(prefix, path, title, authors, mime, date, ContentType, ImageID): changed = False try: lpath = path.partition(self.normalize_path(prefix))[2] if lpath.startswith(os.sep): lpath = lpath[len(os.sep):] lpath = lpath.replace('\\', '/') path = self.normalize_path(path) idx = bl_cache.get(lpath, None) if idx is not None: if ImageID is not None: imagename = self.normalize_path(self._main_prefix + '.kobo/images/' + ImageID + ' - NickelBookCover.parsed') if imagename is not None: bl[idx].thumbnail = ImageWrapper(imagename) bl_cache[lpath] = None if ContentType != '6': if self.update_metadata_item(bl[idx]): changed = True else: book = Book(prefix, lpath, title, authors, mime, date, ContentType, ImageID) if bl.add_book(book, replace_metadata = False): changed = True except: import traceback traceback.print_exc() return changed connection = sqlite.connect(self._main_prefix + '.kobo/KoboReader.sqlite') cursor = connection.cursor() query = 'select Title, Attribution, DateCreated, ContentID, MimeType, ContentType, ImageID from content where BookID is Null' cursor.execute(query) changed = False for i, row in enumerate(cursor): path = self.path_from_contentid(row[3], row[5], oncard) mime = mime_type_ext(path_to_ext(row[3])) if oncard != 'carda' and oncard != 'cardb' and not row[3].startswith('file:///mnt/sd/'): changed = update_booklist(self._main_prefix, path, row[0], row[1], mime, row[2], row[5], row[6]) elif oncard == 'carda' and row[3].startswith('file:///mnt/sd/'): changed = update_booklist(self._card_a_prefix, path, row[0], row[1], mime, row[2], row[5], row[6]) if changed: need_sync = True continue cursor.close() connection.close() for idx in sorted(bl_cache.itervalues(), reverse = True): if idx is not None: need_sync = True del bl[idx] continue if need_sync: if oncard == 'cardb': self.sync_booklists((None, None, bl)) elif oncard == 'carda': self.sync_booklists((None, bl, None)) else: self.sync_booklists((bl, None, None)) self.report_progress(1, _('Getting list of books on device...')) return bl def delete_via_sql(self, ContentID, ContentType): connection = sqlite.connect(self._main_prefix + '.kobo/KoboReader.sqlite') cursor = connection.cursor() t = (ContentID,) cursor.execute('select ImageID from content where ContentID = ?', t) ImageID = None for row in cursor: ImageID = row[0] cursor.close() cursor = connection.cursor() if ContentType == 6: cursor.execute('delete from shortcover_page where shortcoverid in (select ContentID from content where BookID = ?)', t) cursor.execute('delete from volume_shortcovers where volumeid = ?', t) t = (ContentID, ContentID) cursor.execute('delete from content where BookID = ? or ContentID = ?', t) connection.commit() cursor.close() if ImageID != None: print 'Error condition ImageID was not found' print 'You likely tried to delete a book that the kobo has not yet added to the database' connection.close() return ImageID def delete_images(self, ImageID): if ImageID != None: path_prefix = '.kobo/images/' path = self._main_prefix + path_prefix + ImageID file_endings = (' - iPhoneThumbnail.parsed', ' - bbMediumGridList.parsed', ' - NickelBookCover.parsed') for ending in file_endings: fpath = path + ending fpath = self.normalize_path(fpath) if os.path.exists(fpath): os.unlink(fpath) continue def delete_books(self, paths, end_session = True): for i, path in enumerate(paths): self.report_progress((i + 1) / float(len(paths)), _('Removing books from device...')) path = self.normalize_path(path) extension = os.path.splitext(path)[1] if extension == '.kobo': ContentType = 6 ContentID = self.contentid_from_path(path, ContentType) elif extension == '.pdf' or extension == '.epub': ContentType = 16 ContentID = self.contentid_from_path(path, ContentType) else: ContentType = 999 ContentID = self.contentid_from_path(path, ContentType) ImageID = self.delete_via_sql(ContentID, ContentType) self.delete_images(ImageID) if os.path.exists(path): os.unlink(path) filepath = os.path.splitext(path)[0] for ext in self.DELETE_EXTS: if os.path.exists(filepath + ext): os.unlink(filepath + ext) if os.path.exists(path + ext): os.unlink(path + ext) continue if self.SUPPORTS_SUB_DIRS: try: os.removedirs(os.path.dirname(path)) self.SUPPORTS_SUB_DIRS self.report_progress(1, _('Removing books from device...')) def remove_books_from_metadata(self, paths, booklists): for i, path in enumerate(paths): self.report_progress((i + 1) / float(len(paths)), _('Removing books from device metadata listing...')) for bl in booklists: for book in bl: if path.endswith(book.path): bl.remove_book(book) continue self.report_progress(1, _('Removing books from device metadata listing...')) def add_books_to_metadata(self, locations, metadata, booklists): metadata = iter(metadata) for i, location in enumerate(locations): self.report_progress((i + 1) / float(len(locations)), _('Adding books to device metadata listing...')) info = metadata.next() if location[1] == 'cardb': pass elif location[1] == 'carda': pass blist = 0 path = self.normalize_path(location[0]) if self._main_prefix: prefix = None if path.startswith(self.normalize_path(self._main_prefix)) else None if not prefix and self._card_a_prefix: prefix = None if path.startswith(self.normalize_path(self._card_a_prefix)) else None if not prefix and self._card_b_prefix: prefix = None if path.startswith(self.normalize_path(self._card_b_prefix)) else None if prefix is None: prints('in add_books_to_metadata. Prefix is None!', path, self._main_prefix) continue lpath = path.partition(prefix)[2] if lpath.startswith('/') or lpath.startswith('\\'): lpath = lpath[1:] lpath = self.normalize_path(prefix + lpath) book = Book(prefix, lpath, '', '', '', '', '', '', other = info) if book.size is None: book.size = os.stat(self.normalize_path(path)).st_size booklists[blist].add_book(book, replace_metadata = True) self.report_progress(1, _('Adding books to device metadata listing...')) def contentid_from_path(self, path, ContentType): if ContentType == 6: ContentID = os.path.splitext(path)[0] ContentID = ContentID.replace(self._main_prefix, '') if self._card_a_prefix is not None: ContentID = ContentID.replace(self._card_a_prefix, '') elif ContentType == 999: ContentID = path ContentID = ContentID.replace(self._main_prefix, '/mnt/onboard/') if self._card_a_prefix is not None: ContentID = ContentID.replace(self._card_a_prefix, '/mnt/sd/') else: ContentID = path ContentID = ContentID.replace(self._main_prefix, 'file:///mnt/onboard/') if self._card_a_prefix is not None: ContentID = ContentID.replace(self._card_a_prefix, 'file:///mnt/sd/') ContentID = ContentID.replace('\\', '/') return ContentID def path_from_contentid(self, ContentID, ContentType, oncard): path = ContentID if oncard == 'cardb': print 'path from_contentid cardb' elif oncard == 'carda': path = path.replace('file:///mnt/sd/', self._card_a_prefix) elif ContentType == '6': path = self._main_prefix + path + '.kobo' else: path = path.replace('file:///mnt/onboard/', self._main_prefix) path = path.replace('/mnt/onboard/', self._main_prefix) return path def get_file(self, path, *args, **kwargs): tpath = self.munge_path(path) extension = os.path.splitext(tpath)[1] if extension == '.kobo': UserFeedback = UserFeedback import calibre.devices.errors 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) extension == '.kobo' return USBMS.get_file(self, path, *args, **kwargs)