From 150acaffef9aa90aa55d9e42bee2e3a2e4f35c7b Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Wed, 2 Jun 2010 21:43:09 -0300 Subject: [PATCH 01/15] New KOBO driver. Displays and allows kobo books to be deleted from the sqlite database --- src/calibre/__init__.py | 1 + src/calibre/devices/kobo/books.py | 112 +++++++++++ src/calibre/devices/kobo/driver.py | 302 ++++++++++++++++++++++++++++- 3 files changed, 413 insertions(+), 2 deletions(-) create mode 100644 src/calibre/devices/kobo/books.py diff --git a/src/calibre/__init__.py b/src/calibre/__init__.py index ff4bab6a9a..65618aaff4 100644 --- a/src/calibre/__init__.py +++ b/src/calibre/__init__.py @@ -41,6 +41,7 @@ mimetypes.add_type('application/vnd.palm', '.pdb') mimetypes.add_type('application/x-mobipocket-ebook', '.mobi') mimetypes.add_type('application/x-mobipocket-ebook', '.prc') mimetypes.add_type('application/x-mobipocket-ebook', '.azw') +mimetypes.add_type('application/x-koboreader-ebook', '.kobo') mimetypes.add_type('image/wmf', '.wmf') guess_type = mimetypes.guess_type import cssutils diff --git a/src/calibre/devices/kobo/books.py b/src/calibre/devices/kobo/books.py new file mode 100644 index 0000000000..95daec58a9 --- /dev/null +++ b/src/calibre/devices/kobo/books.py @@ -0,0 +1,112 @@ +__license__ = 'GPL v3' +__copyright__ = '2010, Timothy Legge ' +''' +''' + +import os +import re +import time + +from calibre.ebooks.metadata import MetaInformation +from calibre.devices.interface import BookList as _BookList +from calibre.constants import filesystem_encoding, preferred_encoding +from calibre import isbytestring + +class Book(MetaInformation): + + BOOK_ATTRS = ['lpath', 'size', 'mime', 'device_collections'] + + JSON_ATTRS = [ + 'lpath', 'title', 'authors', 'mime', 'size', 'tags', 'author_sort', + 'title_sort', 'comments', 'category', 'publisher', 'series', + 'series_index', 'rating', 'isbn', 'language', 'application_id', + 'book_producer', 'lccn', 'lcc', 'ddc', 'rights', 'publication_type', + 'uuid', + ] + + def __init__(self, mountpath, path, title, authors, mime, date, ContentType, ImageID, other=None): + + MetaInformation.__init__(self, '') + self.device_collections = [] + + self.title = title + if not authors: + self.authors = [''] + else: + self.authors = [authors] + self.mime = mime + self.path = path + try: + self.size = os.path.getsize(path) + except OSError: + self.size = 0 + try: + if ContentType == '6': + self.datetime = time.strptime(date, "%Y-%m-%dT%H:%M:%S.%f") + else: + self.datetime = time.gmtime(os.path.getctime(path)) + except ValueError: + self.datetime = time.gmtime() + except OSError: + self.datetime = time.gmtime() + self.lpath = path + + self.thumbnail = ImageWrapper(mountpath + '.kobo/images/' + ImageID + ' - iPhoneThumbnail.parsed') + self.tags = [] + if other: + self.smart_update(other) + + def __eq__(self, other): + return self.path == getattr(other, 'path', None) + + @dynamic_property + def db_id(self): + doc = '''The database id in the application database that this file corresponds to''' + def fget(self): + match = re.search(r'_(\d+)$', self.lpath.rpartition('.')[0]) + if match: + return int(match.group(1)) + return None + return property(fget=fget, doc=doc) + + @dynamic_property + def title_sorter(self): + doc = '''String to sort the title. If absent, title is returned''' + def fget(self): + return re.sub('^\s*A\s+|^\s*The\s+|^\s*An\s+', '', self.title).rstrip() + return property(doc=doc, fget=fget) + + @dynamic_property + def thumbnail(self): + return None + + def smart_update(self, other): + ''' + Merge the information in C{other} into self. In case of conflicts, the information + in C{other} takes precedence, unless the information in C{other} is NULL. + ''' + + MetaInformation.smart_update(self, other) + + for attr in self.BOOK_ATTRS: + if hasattr(other, attr): + val = getattr(other, attr, None) + setattr(self, attr, val) + + def to_json(self): + json = {} + for attr in self.JSON_ATTRS: + val = getattr(self, attr) + if isbytestring(val): + enc = filesystem_encoding if attr == 'lpath' else preferred_encoding + val = val.decode(enc, 'replace') + elif isinstance(val, (list, tuple)): + val = [x.decode(preferred_encoding, 'replace') if + isbytestring(x) else x for x in val] + json[attr] = val + return json + +class ImageWrapper(object): + def __init__(self, image_path): + self.image_path = image_path + diff --git a/src/calibre/devices/kobo/driver.py b/src/calibre/devices/kobo/driver.py index 4b14b2bf8e..a480b8de2a 100644 --- a/src/calibre/devices/kobo/driver.py +++ b/src/calibre/devices/kobo/driver.py @@ -2,17 +2,26 @@ # vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai __license__ = 'GPL v3' -__copyright__ = '2010, Kovid Goyal ' +__copyright__ = '2010, Timothy Legge and Kovid Goyal ' __docformat__ = 'restructuredtext en' +import os + +import cStringIO +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 + class KOBO(USBMS): name = 'Kobo Reader Device Interface' gui_name = 'Kobo Reader' description = _('Communicate with the Kobo Reader') - author = 'Kovid Goyal' + author = 'Timothy Legge and Kovid Goyal' supported_platforms = ['windows', 'osx', 'linux'] @@ -29,3 +38,292 @@ class KOBO(USBMS): EBOOK_DIR_MAIN = '' SUPPORTS_SUB_DIRS = True + def initialize(self): + USBMS.initialize(self) + self.book_class = Book + + def books(self, oncard=None, end_session=True): + from calibre.ebooks.metadata.meta import path_to_ext + + dummy_bl = BookList(None, None, None) + + if oncard == 'carda' and not self._card_a_prefix: + self.report_progress(1.0, _('Getting list of books on device...')) + return dummy_bl + elif oncard == 'cardb' and not self._card_b_prefix: + self.report_progress(1.0, _('Getting list of books on device...')) + return dummy_bl + elif oncard and oncard != 'carda' and oncard != 'cardb': + self.report_progress(1.0, _('Getting list of books on device...')) + return dummy_bl + + prefix = self._card_a_prefix if oncard == 'carda' else \ + self._card_b_prefix if oncard == 'cardb' \ + else self._main_prefix + + ebook_dirs = self.EBOOK_DIR_CARD_A if oncard == 'carda' else \ + self.EBOOK_DIR_CARD_B if oncard == 'cardb' else \ + self.get_main_ebook_dir() + + # get the metadata cache + bl = self.booklist_class(oncard, prefix, self.settings) + need_sync = self.parse_metadata_cache(bl, prefix, self.METADATA_CACHE) + + # make a dict cache of paths so the lookup in the loop below is faster. + bl_cache = {} + for idx,b in enumerate(bl): + bl_cache[b.lpath] = idx + + def update_booklist(mountpath, ContentID, filename, title, authors, mime, date, ContentType, ImageID): + changed = False + # if path_to_ext(filename) in self.FORMATS: + try: + # lpath = os.path.join(path, filename).partition(self.normalize_path(prefix))[2] + # if lpath.startswith(os.sep): + # lpath = lpath[len(os.sep):] + # lpath = lpath.replace('\\', '/') + idx = bl_cache.get(filename, None) + if idx is not None: + bl[idx].thumbnail = ImageWrapper(mountpath + '.kobo/images/' + ImageID + ' - iPhoneThumbnail.parsed') + bl_cache[filename] = None + if ContentType != '6': + if self.update_metadata_item(bl[idx]): + # print 'update_metadata_item returned true' + changed = True + else: + book = Book(mountpath, filename, title, authors, mime, date, ContentType, ImageID) + # print 'Update booklist' + if bl.add_book(book, replace_metadata=False): + changed = True + except: # Probably a filename encoding error + import traceback + traceback.print_exc() + return changed + + connection = sqlite.connect(self._main_prefix + '.kobo/KoboReader.sqlite') + cursor = connection.cursor() + + query = 'select count(distinct volumeId) from volume_shortcovers' + cursor.execute(query) + for row in (cursor): + numrows = row[0] + cursor.close() + + query= 'select Title, Attribution, DateCreated, ContentID, MimeType, ContentType, ' \ + 'ImageID from content where ContentID in (select distinct volumeId from volume_shortcovers)' + + cursor.execute (query) + + changed = False + + for i, row in enumerate(cursor): + self.report_progress((i+1) / float(numrows), _('Getting list of books on device...')) + + filename = row[3] + if row[5] == "6": + filename = filename + '.kobo' + mime = mime_type_ext(path_to_ext(row[3])) + + if oncard != 'carda' and oncard != 'cardb': + if row[5] == '6': + # print "shortbook: " + filename + changed = update_booklist(self._main_prefix, row[3], filename, row[0], row[1], mime, row[2], row[5], row[6]) + if changed: + need_sync = True + else: + if filename.startswith("file:///mnt/onboard/"): + filename = filename.replace("file:///mnt/onboard/", self._main_prefix) + # print "Internal: " + filename + changed = update_booklist(self._main_prefix, row[3], filename, row[0], row[1], mime, row[2], row[5], row[6]) + if changed: + need_sync = True + elif oncard == 'carda': + if filename.startswith("file:///mnt/sd/"): + filename = filename.replace("file:///mnt/sd/", self._card_a_prefix) + # print "SD Card: " + filename + changed = update_booklist(self._card_a_prefix, row[3], filename, row[0], row[1], mime, row[2], row[5], row[6]) + if changed: + need_sync = True + else: + print "Add card b support" + + #FIXME - NOT NEEDED flist.append({'filename': filename, 'path':row[3]}) + #bl.append(book) + + cursor.close() + connection.close() + + # Remove books that are no longer in the filesystem. Cache contains + # indices into the booklist if book not in filesystem, None otherwise + # Do the operation in reverse order so indices remain valid + for idx in sorted(bl_cache.itervalues(), reverse=True): + if idx is not None: + need_sync = True + del bl[idx] + + print "count found in cache: %d, count of files in metadata: %d, need_sync: %s" % \ + (len(bl_cache), len(bl), need_sync) + if need_sync: #self.count_found_in_bl != len(bl) or 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.0, _('Getting list of books on device...')) + return bl + + def delete_via_sql(self, ContentID, ContentType): + # Delete Order: + # 1) shortcover_page + # 2) volume_shorcover + # 2) content + + connection = sqlite.connect(self._main_prefix + '.kobo/KoboReader.sqlite') + cursor = connection.cursor() + t = (ContentID,) + cursor.execute('select ImageID from content where ContentID = ?', t) + + for row in cursor: + # First get the ImageID to delete the images + ImageID = row[0] + cursor.close() + + cursor = connection.cursor() + if ContentType == 6: + # Delete the shortcover_pages first + cursor.execute('delete from shortcover_page where shortcoverid in (select ContentID from content where BookID = ?)', t) + + #Delete the volume_shortcovers second + cursor.execute('delete from volume_shortcovers where volumeid = ?', t) + + # Delete the chapters associated with the book next + t = (ContentID,ContentID,) + cursor.execute('delete from content where BookID = ? or ContentID = ?', t) + + connection.commit() + + cursor.close() + connection.close() + # If all this succeeds we need to delete the images files via the ImageID + return ImageID + + def delete_images(self, ImageID): + 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): + # print 'Image File Exists: ' + fpath + os.unlink(fpath) + + 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': + # Kobo books do not have book files. They do have some images though + #print "kobo book" + ContentType = 6 + ContentID = os.path.splitext(path)[0] + # Remove the prefix on the file. it could be either + ContentID = ContentID.replace(self._main_prefix, '') + if self._card_a_prefix is not None: + ContentID = ContentID.replace(self._card_a_prefix, '') + + ImageID = self.delete_via_sql(ContentID, ContentType) + #print " We would now delete the Images for" + ImageID + self.delete_images(ImageID) + if extension == '.pdf' or extension == '.epub': + # print "ePub or pdf" + ContentType = 16 + #print "Path: " + path + 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/") + # print "ContentID: " + ContentID + ImageID = self.delete_via_sql(ContentID, ContentType) + #print " We would now delete the Images for" + ImageID + self.delete_images(ImageID) + + if os.path.exists(path): + # Delete the ebook + # print "Delete the ebook: " + path + os.unlink(path) + + filepath = os.path.splitext(path)[0] + for ext in self.DELETE_EXTS: + if os.path.exists(filepath + ext): + # print "Filename: " + filename + os.unlink(filepath + ext) + if os.path.exists(path + ext): + # print "Filename: " + filename + os.unlink(path + ext) + + if self.SUPPORTS_SUB_DIRS: + try: + # print "removed" + os.removedirs(os.path.dirname(path)) + except: + pass + self.report_progress(1.0, _('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: + #print "Book Path: " + book.path + if path.endswith(book.path): + #print " Remove: " + book.path + bl.remove_book(book) + self.report_progress(1.0, _('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() + blist = 2 if location[1] == 'cardb' else 1 if location[1] == 'carda' else 0 + + # Extract the correct prefix from the pathname. To do this correctly, + # we must ensure that both the prefix and the path are normalized + # so that the comparison will work. Book's __init__ will fix up + # lpath, so we don't need to worry about that here. + path = self.normalize_path(location[0]) + if self._main_prefix: + prefix = self._main_prefix if \ + path.startswith(self.normalize_path(self._main_prefix)) else None + if not prefix and self._card_a_prefix: + prefix = self._card_a_prefix if \ + path.startswith(self.normalize_path(self._card_a_prefix)) else None + if not prefix and self._card_b_prefix: + prefix = self._card_b_prefix 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:] + #book = self.book_class(prefix, lpath, other=info) + 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.0, _('Adding books to device metadata listing...')) + +#class ImageWrapper(object): +# def __init__(self, image_path): +# self.image_path = image_path + From bb0c44693a8e43a6dfcc72eabfe04660dc41c6a7 Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Tue, 8 Jun 2010 19:38:27 -0300 Subject: [PATCH 02/15] Few changes for silly path differences in Windows and darn tabs versus spaces --- src/calibre/devices/kobo/books.py | 34 ++++----- src/calibre/devices/kobo/driver.py | 117 ++++++++++++++++------------- 2 files changed, 83 insertions(+), 68 deletions(-) diff --git a/src/calibre/devices/kobo/books.py b/src/calibre/devices/kobo/books.py index 95daec58a9..2ed95a4116 100644 --- a/src/calibre/devices/kobo/books.py +++ b/src/calibre/devices/kobo/books.py @@ -24,34 +24,34 @@ class Book(MetaInformation): 'uuid', ] - def __init__(self, mountpath, path, title, authors, mime, date, ContentType, ImageID, other=None): + def __init__(self, mountpath, path, title, authors, mime, date, ContentType, thumbnail_name, other=None): MetaInformation.__init__(self, '') self.device_collections = [] - self.title = title - if not authors: - self.authors = [''] - else: - self.authors = [authors] + self.title = title + if not authors: + self.authors = [''] + else: + self.authors = [authors] self.mime = mime - self.path = path - try: - self.size = os.path.getsize(path) - except OSError: - self.size = 0 + self.path = path try: - if ContentType == '6': - self.datetime = time.strptime(date, "%Y-%m-%dT%H:%M:%S.%f") - else: + self.size = os.path.getsize(path) + except OSError: + self.size = 0 + try: + if ContentType == '6': + self.datetime = time.strptime(date, "%Y-%m-%dT%H:%M:%S.%f") + else: self.datetime = time.gmtime(os.path.getctime(path)) except ValueError: self.datetime = time.gmtime() - except OSError: + except OSError: self.datetime = time.gmtime() self.lpath = path - self.thumbnail = ImageWrapper(mountpath + '.kobo/images/' + ImageID + ' - iPhoneThumbnail.parsed') + self.thumbnail = ImageWrapper(thumbnail_name) self.tags = [] if other: self.smart_update(other) @@ -108,5 +108,5 @@ class Book(MetaInformation): class ImageWrapper(object): def __init__(self, image_path): - self.image_path = image_path + self.image_path = image_path diff --git a/src/calibre/devices/kobo/driver.py b/src/calibre/devices/kobo/driver.py index a480b8de2a..35847cdbf8 100644 --- a/src/calibre/devices/kobo/driver.py +++ b/src/calibre/devices/kobo/driver.py @@ -82,14 +82,20 @@ class KOBO(USBMS): # if lpath.startswith(os.sep): # lpath = lpath[len(os.sep):] # lpath = lpath.replace('\\', '/') + print "Filename: " + filename + filename = self.normalize_path(filename) + print "Normalized FileName: " + filename + idx = bl_cache.get(filename, None) if idx is not None: - bl[idx].thumbnail = ImageWrapper(mountpath + '.kobo/images/' + ImageID + ' - iPhoneThumbnail.parsed') + imagename = self.normalize_path(mountpath + '.kobo/images/' + ImageID + ' - iPhoneThumbnail.parsed') + print "Image name Normalized: " + imagename + bl[idx].thumbnail = ImageWrapper(imagename) bl_cache[filename] = None if ContentType != '6': - if self.update_metadata_item(bl[idx]): - # print 'update_metadata_item returned true' - changed = True + if self.update_metadata_item(bl[idx]): + # print 'update_metadata_item returned true' + changed = True else: book = Book(mountpath, filename, title, authors, mime, date, ContentType, ImageID) # print 'Update booklist' @@ -103,21 +109,21 @@ class KOBO(USBMS): connection = sqlite.connect(self._main_prefix + '.kobo/KoboReader.sqlite') cursor = connection.cursor() - query = 'select count(distinct volumeId) from volume_shortcovers' - cursor.execute(query) - for row in (cursor): - numrows = row[0] - cursor.close() + #query = 'select count(distinct volumeId) from volume_shortcovers' + #cursor.execute(query) + #for row in (cursor): + # numrows = row[0] + #cursor.close() query= 'select Title, Attribution, DateCreated, ContentID, MimeType, ContentType, ' \ - 'ImageID from content where ContentID in (select distinct volumeId from volume_shortcovers)' + 'ImageID from content where ContentID in (select distinct volumeId from volume_shortcovers)' cursor.execute (query) changed = False for i, row in enumerate(cursor): - self.report_progress((i+1) / float(numrows), _('Getting list of books on device...')) + # self.report_progress((i+1) / float(numrows), _('Getting list of books on device...')) filename = row[3] if row[5] == "6": @@ -125,18 +131,18 @@ class KOBO(USBMS): mime = mime_type_ext(path_to_ext(row[3])) if oncard != 'carda' and oncard != 'cardb': - if row[5] == '6': - # print "shortbook: " + filename - changed = update_booklist(self._main_prefix, row[3], filename, row[0], row[1], mime, row[2], row[5], row[6]) + if row[5] == '6': + # print "shortbook: " + filename + changed = update_booklist(self._main_prefix, row[3], filename, row[0], row[1], mime, row[2], row[5], row[6]) + if changed: + need_sync = True + else: + if filename.startswith("file:///mnt/onboard/"): + filename = filename.replace("file:///mnt/onboard/", self._main_prefix) + # print "Internal: " + filename + changed = update_booklist(self._main_prefix, row[3], filename, row[0], row[1], mime, row[2], row[5], row[6]) if changed: need_sync = True - else: - if filename.startswith("file:///mnt/onboard/"): - filename = filename.replace("file:///mnt/onboard/", self._main_prefix) - # print "Internal: " + filename - changed = update_booklist(self._main_prefix, row[3], filename, row[0], row[1], mime, row[2], row[5], row[6]) - if changed: - need_sync = True elif oncard == 'carda': if filename.startswith("file:///mnt/sd/"): filename = filename.replace("file:///mnt/sd/", self._card_a_prefix) @@ -145,14 +151,14 @@ class KOBO(USBMS): if changed: need_sync = True else: - print "Add card b support" + print "Add card b support" #FIXME - NOT NEEDED flist.append({'filename': filename, 'path':row[3]}) #bl.append(book) - + cursor.close() connection.close() - + # Remove books that are no longer in the filesystem. Cache contains # indices into the booklist if book not in filesystem, None otherwise # Do the operation in reverse order so indices remain valid @@ -185,48 +191,56 @@ class KOBO(USBMS): t = (ContentID,) cursor.execute('select ImageID from content where ContentID = ?', t) + ImageID = None for row in cursor: # First get the ImageID to delete the images ImageID = row[0] cursor.close() - - cursor = connection.cursor() - if ContentType == 6: - # Delete the shortcover_pages first - cursor.execute('delete from shortcover_page where shortcoverid in (select ContentID from content where BookID = ?)', t) + + if ImageID != None: + cursor = connection.cursor() + if ContentType == 6: + # Delete the shortcover_pages first + cursor.execute('delete from shortcover_page where shortcoverid in (select ContentID from content where BookID = ?)', t) - #Delete the volume_shortcovers second - cursor.execute('delete from volume_shortcovers where volumeid = ?', t) + #Delete the volume_shortcovers second + cursor.execute('delete from volume_shortcovers where volumeid = ?', t) - # Delete the chapters associated with the book next - t = (ContentID,ContentID,) - cursor.execute('delete from content where BookID = ? or ContentID = ?', t) + # Delete the chapters associated with the book next + t = (ContentID,ContentID,) + cursor.execute('delete from content where BookID = ? or ContentID = ?', t) - connection.commit() + connection.commit() + + cursor.close() + else: + 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" - cursor.close() connection.close() # If all this succeeds we need to delete the images files via the ImageID return ImageID def delete_images(self, ImageID): - path_prefix = '.kobo/images/' - path = self._main_prefix + path_prefix + ImageID + if ImageID == None: + path_prefix = '.kobo/images/' + path = self._main_prefix + path_prefix + ImageID - file_endings = (' - iPhoneThumbnail.parsed', ' - bbMediumGridList.parsed', ' - NickelBookCover.parsed',) + file_endings = (' - iPhoneThumbnail.parsed', ' - bbMediumGridList.parsed', ' - NickelBookCover.parsed',) - for ending in file_endings: - fpath = path + ending - fpath = self.normalize_path(fpath) + for ending in file_endings: + fpath = path + ending + fpath = self.normalize_path(fpath) - if os.path.exists(fpath): - # print 'Image File Exists: ' + fpath - os.unlink(fpath) + if os.path.exists(fpath): + # print 'Image File Exists: ' + fpath + os.unlink(fpath) 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) + print "Delete file normalized path: " + path extension = os.path.splitext(path)[1] if extension == '.kobo': @@ -238,7 +252,7 @@ class KOBO(USBMS): ContentID = ContentID.replace(self._main_prefix, '') if self._card_a_prefix is not None: ContentID = ContentID.replace(self._card_a_prefix, '') - + ContentID = ContentID.replace("\\", '/') ImageID = self.delete_via_sql(ContentID, ContentType) #print " We would now delete the Images for" + ImageID self.delete_images(ImageID) @@ -250,6 +264,7 @@ class KOBO(USBMS): 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("\\", '/') # print "ContentID: " + ContentID ImageID = self.delete_via_sql(ContentID, ContentType) #print " We would now delete the Images for" + ImageID @@ -313,17 +328,17 @@ class KOBO(USBMS): prints('in add_books_to_metadata. Prefix is None!', path, self._main_prefix) continue + print "Add book to metatdata: " + print "prefix: " + prefix lpath = path.partition(prefix)[2] if lpath.startswith('/') or lpath.startswith('\\'): lpath = lpath[1:] + print "path: " + lpath #book = self.book_class(prefix, lpath, other=info) - book = Book(prefix, lpath, '', '', '', '', '', '', other=info) + 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.0, _('Adding books to device metadata listing...')) -#class ImageWrapper(object): -# def __init__(self, image_path): -# self.image_path = image_path - From 7b9823e80d8e4c7f96b2ced9752c3a4e1c991546 Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Tue, 8 Jun 2010 21:07:13 -0300 Subject: [PATCH 03/15] Fix silly bug --- src/calibre/devices/kobo/driver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/devices/kobo/driver.py b/src/calibre/devices/kobo/driver.py index 35847cdbf8..42d6cdc295 100644 --- a/src/calibre/devices/kobo/driver.py +++ b/src/calibre/devices/kobo/driver.py @@ -222,7 +222,7 @@ class KOBO(USBMS): return ImageID def delete_images(self, ImageID): - if ImageID == None: + if ImageID != None: path_prefix = '.kobo/images/' path = self._main_prefix + path_prefix + ImageID From 330c9ef1ba0196d3a1ff41bfd3cce30aff48b922 Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Tue, 8 Jun 2010 21:12:35 -0300 Subject: [PATCH 04/15] remove debugging statements --- src/calibre/devices/kobo/driver.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/calibre/devices/kobo/driver.py b/src/calibre/devices/kobo/driver.py index 42d6cdc295..10261351a8 100644 --- a/src/calibre/devices/kobo/driver.py +++ b/src/calibre/devices/kobo/driver.py @@ -82,14 +82,14 @@ class KOBO(USBMS): # if lpath.startswith(os.sep): # lpath = lpath[len(os.sep):] # lpath = lpath.replace('\\', '/') - print "Filename: " + filename + # print "Filename: " + filename filename = self.normalize_path(filename) - print "Normalized FileName: " + filename + # print "Normalized FileName: " + filename idx = bl_cache.get(filename, None) if idx is not None: imagename = self.normalize_path(mountpath + '.kobo/images/' + ImageID + ' - iPhoneThumbnail.parsed') - print "Image name Normalized: " + imagename + # print "Image name Normalized: " + imagename bl[idx].thumbnail = ImageWrapper(imagename) bl_cache[filename] = None if ContentType != '6': @@ -240,7 +240,7 @@ class KOBO(USBMS): for i, path in enumerate(paths): self.report_progress((i+1) / float(len(paths)), _('Removing books from device...')) path = self.normalize_path(path) - print "Delete file normalized path: " + path + # print "Delete file normalized path: " + path extension = os.path.splitext(path)[1] if extension == '.kobo': From 54d360e95acf37d22c9f51b0ec2082d6875e7bd7 Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Mon, 14 Jun 2010 23:01:16 -0300 Subject: [PATCH 05/15] Simplify path to ContentID --- src/calibre/devices/kobo/driver.py | 46 ++++++++++++++++-------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/src/calibre/devices/kobo/driver.py b/src/calibre/devices/kobo/driver.py index 10261351a8..dce72d0fba 100644 --- a/src/calibre/devices/kobo/driver.py +++ b/src/calibre/devices/kobo/driver.py @@ -74,7 +74,7 @@ class KOBO(USBMS): for idx,b in enumerate(bl): bl_cache[b.lpath] = idx - def update_booklist(mountpath, ContentID, filename, title, authors, mime, date, ContentType, ImageID): + def update_booklist(mountpath, filename, title, authors, mime, date, ContentType, ImageID): changed = False # if path_to_ext(filename) in self.FORMATS: try: @@ -89,7 +89,7 @@ class KOBO(USBMS): idx = bl_cache.get(filename, None) if idx is not None: imagename = self.normalize_path(mountpath + '.kobo/images/' + ImageID + ' - iPhoneThumbnail.parsed') - # print "Image name Normalized: " + imagename + print "Image name Normalized: " + imagename bl[idx].thumbnail = ImageWrapper(imagename) bl_cache[filename] = None if ContentType != '6': @@ -133,21 +133,21 @@ class KOBO(USBMS): if oncard != 'carda' and oncard != 'cardb': if row[5] == '6': # print "shortbook: " + filename - changed = update_booklist(self._main_prefix, row[3], filename, row[0], row[1], mime, row[2], row[5], row[6]) + changed = update_booklist(self._main_prefix, filename, row[0], row[1], mime, row[2], row[5], row[6]) if changed: need_sync = True else: if filename.startswith("file:///mnt/onboard/"): filename = filename.replace("file:///mnt/onboard/", self._main_prefix) # print "Internal: " + filename - changed = update_booklist(self._main_prefix, row[3], filename, row[0], row[1], mime, row[2], row[5], row[6]) + changed = update_booklist(self._main_prefix, filename, row[0], row[1], mime, row[2], row[5], row[6]) if changed: need_sync = True elif oncard == 'carda': if filename.startswith("file:///mnt/sd/"): filename = filename.replace("file:///mnt/sd/", self._card_a_prefix) # print "SD Card: " + filename - changed = update_booklist(self._card_a_prefix, row[3], filename, row[0], row[1], mime, row[2], row[5], row[6]) + changed = update_booklist(self._card_a_prefix, filename, row[0], row[1], mime, row[2], row[5], row[6]) if changed: need_sync = True else: @@ -247,28 +247,16 @@ class KOBO(USBMS): # Kobo books do not have book files. They do have some images though #print "kobo book" ContentType = 6 - ContentID = os.path.splitext(path)[0] - # Remove the prefix on the file. it could be either - ContentID = ContentID.replace(self._main_prefix, '') - if self._card_a_prefix is not None: - ContentID = ContentID.replace(self._card_a_prefix, '') - ContentID = ContentID.replace("\\", '/') - ImageID = self.delete_via_sql(ContentID, ContentType) - #print " We would now delete the Images for" + ImageID - self.delete_images(ImageID) + ContentID = self.contentid_from_path(path, ContentType) if extension == '.pdf' or extension == '.epub': # print "ePub or pdf" ContentType = 16 #print "Path: " + path - 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("\\", '/') + ContentID = self.contentid_from_path(path, ContentType) # print "ContentID: " + ContentID - ImageID = self.delete_via_sql(ContentID, ContentType) - #print " We would now delete the Images for" + ImageID - self.delete_images(ImageID) + ImageID = self.delete_via_sql(ContentID, ContentType) + #print " We would now delete the Images for" + ImageID + self.delete_images(ImageID) if os.path.exists(path): # Delete the ebook @@ -342,3 +330,17 @@ class KOBO(USBMS): booklists[blist].add_book(book, replace_metadata=True) self.report_progress(1.0, _('Adding books to device metadata listing...')) + def contentid_from_path(self, path, ContentType): + if ContentType == 6: + ContentID = os.path.splitext(path)[0] + # Remove the prefix on the file. it could be either + ContentID = ContentID.replace(self._main_prefix, '') + if self._card_a_prefix is not None: + ContentID = ContentID.replace(self._card_a_prefix, '') + else: # ContentType = 16 + 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 ContentType From 5c093f846eab08fb84c5a15e29e2db2ce5c12aa4 Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Thu, 17 Jun 2010 22:01:08 -0300 Subject: [PATCH 06/15] Remove debugging --- src/calibre/devices/kobo/driver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/devices/kobo/driver.py b/src/calibre/devices/kobo/driver.py index dce72d0fba..bb1e01283c 100644 --- a/src/calibre/devices/kobo/driver.py +++ b/src/calibre/devices/kobo/driver.py @@ -89,7 +89,7 @@ class KOBO(USBMS): idx = bl_cache.get(filename, None) if idx is not None: imagename = self.normalize_path(mountpath + '.kobo/images/' + ImageID + ' - iPhoneThumbnail.parsed') - print "Image name Normalized: " + imagename + #print "Image name Normalized: " + imagename bl[idx].thumbnail = ImageWrapper(imagename) bl_cache[filename] = None if ContentType != '6': From ff3433cde9767f9d2dd3aee4a8fab43533105e9f Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Thu, 17 Jun 2010 22:58:58 -0300 Subject: [PATCH 07/15] Simplify ContentID to path conversion --- src/calibre/devices/kobo/driver.py | 49 +++++++++++++++--------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/src/calibre/devices/kobo/driver.py b/src/calibre/devices/kobo/driver.py index bb1e01283c..1b2630c06f 100644 --- a/src/calibre/devices/kobo/driver.py +++ b/src/calibre/devices/kobo/driver.py @@ -22,6 +22,7 @@ class KOBO(USBMS): gui_name = 'Kobo Reader' description = _('Communicate with the Kobo Reader') author = 'Timothy Legge and Kovid Goyal' + version = (1, 0, 1) supported_platforms = ['windows', 'osx', 'linux'] @@ -121,40 +122,22 @@ class KOBO(USBMS): cursor.execute (query) changed = False - for i, row in enumerate(cursor): # self.report_progress((i+1) / float(numrows), _('Getting list of books on device...')) - filename = row[3] - if row[5] == "6": - filename = filename + '.kobo' + 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': - if row[5] == '6': - # print "shortbook: " + filename - changed = update_booklist(self._main_prefix, filename, row[0], row[1], mime, row[2], row[5], row[6]) - if changed: - need_sync = True - else: - if filename.startswith("file:///mnt/onboard/"): - filename = filename.replace("file:///mnt/onboard/", self._main_prefix) - # print "Internal: " + filename - changed = update_booklist(self._main_prefix, filename, row[0], row[1], mime, row[2], row[5], row[6]) - if changed: - need_sync = True + # print "shortbook: " + filename + changed = update_booklist(self._main_prefix, path, row[0], row[1], mime, row[2], row[5], row[6]) elif oncard == 'carda': - if filename.startswith("file:///mnt/sd/"): - filename = filename.replace("file:///mnt/sd/", self._card_a_prefix) - # print "SD Card: " + filename - changed = update_booklist(self._card_a_prefix, filename, row[0], row[1], mime, row[2], row[5], row[6]) - if changed: - need_sync = True + changed = update_booklist(self._card_a_prefix, path, row[0], row[1], mime, row[2], row[5], row[6]) else: print "Add card b support" - #FIXME - NOT NEEDED flist.append({'filename': filename, 'path':row[3]}) - #bl.append(book) + if changed: + need_sync = True cursor.close() connection.close() @@ -344,3 +327,21 @@ class KOBO(USBMS): ContentID = ContentID.replace(self._card_a_prefix, "file:///mnt/sd/") ContentID = ContentID.replace("\\", '/') return ContentType + + + def path_from_contentid(self, ContentID, ContentType, oncard): + path = ContentID + + if oncard != 'carda' and oncard != 'cardb': + if ContentType == "6": + path = path + '.kobo' + else: + if path.startswith("file:///mnt/onboard/"): + path = path.replace("file:///mnt/onboard/", self._main_prefix) + # print "Internal: " + filename + elif oncard == 'carda': + if path.startswith("file:///mnt/sd/"): + path = path.replace("file:///mnt/sd/", self._card_a_prefix) + # print "SD Card: " + filename + + return path From da83447900d61d10f14d2f13f6286fc220309745 Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Fri, 18 Jun 2010 22:37:16 -0300 Subject: [PATCH 08/15] Additional clean up and conver to using path and lpath correctly - more review of lpath and path needed --- src/calibre/devices/kobo/books.py | 15 ++++++++---- src/calibre/devices/kobo/driver.py | 38 +++++++++++++++++------------- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/src/calibre/devices/kobo/books.py b/src/calibre/devices/kobo/books.py index 2ed95a4116..f2ec8e2bf4 100644 --- a/src/calibre/devices/kobo/books.py +++ b/src/calibre/devices/kobo/books.py @@ -24,32 +24,37 @@ class Book(MetaInformation): 'uuid', ] - def __init__(self, mountpath, path, title, authors, mime, date, ContentType, thumbnail_name, other=None): + def __init__(self, prefix, lpath, title, authors, mime, date, ContentType, thumbnail_name, other=None): MetaInformation.__init__(self, '') self.device_collections = [] + self.path = os.path.join(prefix, lpath) + if os.sep == '\\': + self.path = self.path.replace('/', '\\') + self.lpath = lpath.replace('\\', '/') + else: + self.lpath = lpath + self.title = title if not authors: self.authors = [''] else: self.authors = [authors] self.mime = mime - self.path = path try: - self.size = os.path.getsize(path) + self.size = os.path.getsize(self.path) except OSError: self.size = 0 try: if ContentType == '6': self.datetime = time.strptime(date, "%Y-%m-%dT%H:%M:%S.%f") else: - self.datetime = time.gmtime(os.path.getctime(path)) + self.datetime = time.gmtime(os.path.getctime(self.path)) except ValueError: self.datetime = time.gmtime() except OSError: self.datetime = time.gmtime() - self.lpath = path self.thumbnail = ImageWrapper(thumbnail_name) self.tags = [] diff --git a/src/calibre/devices/kobo/driver.py b/src/calibre/devices/kobo/driver.py index 1b2630c06f..2a3ebfaea5 100644 --- a/src/calibre/devices/kobo/driver.py +++ b/src/calibre/devices/kobo/driver.py @@ -22,7 +22,7 @@ class KOBO(USBMS): gui_name = 'Kobo Reader' description = _('Communicate with the Kobo Reader') author = 'Timothy Legge and Kovid Goyal' - version = (1, 0, 1) + version = (1, 0, 2) supported_platforms = ['windows', 'osx', 'linux'] @@ -75,34 +75,35 @@ class KOBO(USBMS): for idx,b in enumerate(bl): bl_cache[b.lpath] = idx - def update_booklist(mountpath, filename, title, authors, mime, date, ContentType, ImageID): + def update_booklist(prefix, path, title, authors, mime, date, ContentType, ImageID): changed = False - # if path_to_ext(filename) in self.FORMATS: + # if path_to_ext(path) in self.FORMATS: try: - # lpath = os.path.join(path, filename).partition(self.normalize_path(prefix))[2] - # if lpath.startswith(os.sep): - # lpath = lpath[len(os.sep):] - # lpath = lpath.replace('\\', '/') - # print "Filename: " + filename - filename = self.normalize_path(filename) - # print "Normalized FileName: " + filename + lpath = path.partition(self.normalize_path(prefix))[2] + if lpath.startswith(os.sep): + lpath = lpath[len(os.sep):] + lpath = lpath.replace('\\', '/') +# print "LPATH: " + lpath - idx = bl_cache.get(filename, None) + path = self.normalize_path(path) + # print "Normalized FileName: " + path + + idx = bl_cache.get(lpath, None) if idx is not None: - imagename = self.normalize_path(mountpath + '.kobo/images/' + ImageID + ' - iPhoneThumbnail.parsed') + imagename = self.normalize_path(prefix + '.kobo/images/' + ImageID + ' - iPhoneThumbnail.parsed') #print "Image name Normalized: " + imagename bl[idx].thumbnail = ImageWrapper(imagename) - bl_cache[filename] = None + bl_cache[lpath] = None if ContentType != '6': if self.update_metadata_item(bl[idx]): # print 'update_metadata_item returned true' changed = True else: - book = Book(mountpath, filename, title, authors, mime, date, ContentType, ImageID) + book = Book(prefix, lpath, title, authors, mime, date, ContentType, ImageID) # print 'Update booklist' if bl.add_book(book, replace_metadata=False): changed = True - except: # Probably a filename encoding error + except: # Probably a path encoding error import traceback traceback.print_exc() return changed @@ -129,7 +130,7 @@ class KOBO(USBMS): mime = mime_type_ext(path_to_ext(row[3])) if oncard != 'carda' and oncard != 'cardb': - # print "shortbook: " + filename + # print "shortbook: " + path changed = update_booklist(self._main_prefix, path, row[0], row[1], mime, row[2], row[5], row[6]) elif oncard == 'carda': changed = update_booklist(self._card_a_prefix, path, row[0], row[1], mime, row[2], row[5], row[6]) @@ -334,7 +335,10 @@ class KOBO(USBMS): if oncard != 'carda' and oncard != 'cardb': if ContentType == "6": - path = path + '.kobo' + # This is a hack as the kobo files do not exist + # but the path is required to make a unique id + # for calibre's reference + path = self._main_prefix + os.sep + path + '.kobo' else: if path.startswith("file:///mnt/onboard/"): path = path.replace("file:///mnt/onboard/", self._main_prefix) From b722530e455454653190983bc75cee5893cac91c Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Sun, 20 Jun 2010 15:59:37 -0300 Subject: [PATCH 09/15] Use color pic where available - kobo --- src/calibre/devices/kobo/driver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/devices/kobo/driver.py b/src/calibre/devices/kobo/driver.py index 2a3ebfaea5..cd95247d13 100644 --- a/src/calibre/devices/kobo/driver.py +++ b/src/calibre/devices/kobo/driver.py @@ -90,7 +90,7 @@ class KOBO(USBMS): idx = bl_cache.get(lpath, None) if idx is not None: - imagename = self.normalize_path(prefix + '.kobo/images/' + ImageID + ' - iPhoneThumbnail.parsed') + imagename = self.normalize_path(prefix + '.kobo/images/' + ImageID + ' - NickelBookCover.parsed') #print "Image name Normalized: " + imagename bl[idx].thumbnail = ImageWrapper(imagename) bl_cache[lpath] = None From a36216fdd1be65fd621d6344c8cace1084f0f929 Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Sun, 20 Jun 2010 20:24:39 -0300 Subject: [PATCH 10/15] Fix contentid_from_path --- src/calibre/devices/kobo/driver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/devices/kobo/driver.py b/src/calibre/devices/kobo/driver.py index cd95247d13..4fcdb95c37 100644 --- a/src/calibre/devices/kobo/driver.py +++ b/src/calibre/devices/kobo/driver.py @@ -327,7 +327,7 @@ class KOBO(USBMS): if self._card_a_prefix is not None: ContentID = ContentID.replace(self._card_a_prefix, "file:///mnt/sd/") ContentID = ContentID.replace("\\", '/') - return ContentType + return ContentID def path_from_contentid(self, ContentID, ContentType, oncard): From 7044e5811681064b7453106ce09747af1c5aa0e8 Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Sun, 20 Jun 2010 23:25:44 -0300 Subject: [PATCH 11/15] Remove some extra prints used for debugging --- src/calibre/devices/kobo/driver.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/calibre/devices/kobo/driver.py b/src/calibre/devices/kobo/driver.py index 4fcdb95c37..159e8f484c 100644 --- a/src/calibre/devices/kobo/driver.py +++ b/src/calibre/devices/kobo/driver.py @@ -151,8 +151,8 @@ class KOBO(USBMS): need_sync = True del bl[idx] - print "count found in cache: %d, count of files in metadata: %d, need_sync: %s" % \ - (len(bl_cache), len(bl), need_sync) + #print "count found in cache: %d, count of files in metadata: %d, need_sync: %s" % \ + # (len(bl_cache), len(bl), need_sync) if need_sync: #self.count_found_in_bl != len(bl) or need_sync: if oncard == 'cardb': self.sync_booklists((None, None, bl)) @@ -300,12 +300,12 @@ class KOBO(USBMS): prints('in add_books_to_metadata. Prefix is None!', path, self._main_prefix) continue - print "Add book to metatdata: " - print "prefix: " + prefix + #print "Add book to metatdata: " + #print "prefix: " + prefix lpath = path.partition(prefix)[2] if lpath.startswith('/') or lpath.startswith('\\'): lpath = lpath[1:] - print "path: " + lpath + #print "path: " + lpath #book = self.book_class(prefix, lpath, other=info) lpath = self.normalize_path(prefix + lpath) book = Book(prefix, lpath, '', '', '', '', '', '', other=info) From 4e2bae4e01f3fe3a5027c5d1f6aaf67a27624ab4 Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Sun, 20 Jun 2010 23:27:31 -0300 Subject: [PATCH 12/15] Increment the version - Sucessful testing on Linux Development Machine --- src/calibre/devices/kobo/driver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/devices/kobo/driver.py b/src/calibre/devices/kobo/driver.py index 159e8f484c..d73ed97bf9 100644 --- a/src/calibre/devices/kobo/driver.py +++ b/src/calibre/devices/kobo/driver.py @@ -22,7 +22,7 @@ class KOBO(USBMS): gui_name = 'Kobo Reader' description = _('Communicate with the Kobo Reader') author = 'Timothy Legge and Kovid Goyal' - version = (1, 0, 2) + version = (1, 0, 3) supported_platforms = ['windows', 'osx', 'linux'] From 8bd036d9f44d4818afca95bba2646a43d58af73a Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Thu, 24 Jun 2010 22:48:29 -0300 Subject: [PATCH 13/15] Fix annoying little bug related to using an SD card. Caused by path from content id fix --- src/calibre/devices/kobo/driver.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/calibre/devices/kobo/driver.py b/src/calibre/devices/kobo/driver.py index d73ed97bf9..007072f1e8 100644 --- a/src/calibre/devices/kobo/driver.py +++ b/src/calibre/devices/kobo/driver.py @@ -129,14 +129,12 @@ class KOBO(USBMS): 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': - # print "shortbook: " + path + 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': + # print "shortbook: " + path + 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]) - else: - print "Add card b support" - + if changed: need_sync = True @@ -333,19 +331,21 @@ class KOBO(USBMS): def path_from_contentid(self, ContentID, ContentType, oncard): path = ContentID - if oncard != 'carda' and oncard != 'cardb': + if oncard == 'cardb': + print 'path from_contentid cardb' + elif oncard == 'carda': + path = path.replace("file:///mnt/sd/", self._card_a_prefix) + # print "SD Card: " + filename + else: if ContentType == "6": # This is a hack as the kobo files do not exist # but the path is required to make a unique id # for calibre's reference - path = self._main_prefix + os.sep + path + '.kobo' + path = self._main_prefix + path + '.kobo' + # print "Path: " + path else: - if path.startswith("file:///mnt/onboard/"): - path = path.replace("file:///mnt/onboard/", self._main_prefix) + # if path.startswith("file:///mnt/onboard/"): + path = path.replace("file:///mnt/onboard/", self._main_prefix) # print "Internal: " + filename - elif oncard == 'carda': - if path.startswith("file:///mnt/sd/"): - path = path.replace("file:///mnt/sd/", self._card_a_prefix) - # print "SD Card: " + filename return path From b8ff047ef4fa9ede0c849d04a982c03f1612d826 Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Thu, 24 Jun 2010 22:49:37 -0300 Subject: [PATCH 14/15] Increment driver version --- src/calibre/devices/kobo/driver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/devices/kobo/driver.py b/src/calibre/devices/kobo/driver.py index 007072f1e8..4071b10f6e 100644 --- a/src/calibre/devices/kobo/driver.py +++ b/src/calibre/devices/kobo/driver.py @@ -22,7 +22,7 @@ class KOBO(USBMS): gui_name = 'Kobo Reader' description = _('Communicate with the Kobo Reader') author = 'Timothy Legge and Kovid Goyal' - version = (1, 0, 3) + version = (1, 0, 4) supported_platforms = ['windows', 'osx', 'linux'] From 72b3053c56f510329f43fb46056f6210b40ebe6a Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Thu, 24 Jun 2010 23:31:45 -0300 Subject: [PATCH 15/15] More efficient select query --- src/calibre/devices/kobo/driver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/devices/kobo/driver.py b/src/calibre/devices/kobo/driver.py index 4071b10f6e..2a1e7bda89 100644 --- a/src/calibre/devices/kobo/driver.py +++ b/src/calibre/devices/kobo/driver.py @@ -118,7 +118,7 @@ class KOBO(USBMS): #cursor.close() query= 'select Title, Attribution, DateCreated, ContentID, MimeType, ContentType, ' \ - 'ImageID from content where ContentID in (select distinct volumeId from volume_shortcovers)' + 'ImageID from content where BookID is Null' cursor.execute (query)