mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 10:14:46 -04:00
Add support for new cover handling in Kobo Aura
The new Kobo Aura has firmware version 2.9.0. The main change needed for the driver is that cover images are stored in a different place. Version number is set to 2.9.1 to handle the later release for other Kobo devices.
This commit is contained in:
parent
07547628cc
commit
c893f0de7e
@ -31,6 +31,25 @@ from calibre.utils.config_base import prefs
|
||||
EPUB_EXT = '.epub'
|
||||
|
||||
|
||||
# Implementation of QtQHash for strings. This doesn't seem to be in the Python implemention.
|
||||
def qhash (inputstr):
|
||||
instr = ""
|
||||
if isinstance (inputstr, str):
|
||||
instr = inputstr
|
||||
elif isinstance (inputstr, unicode):
|
||||
instr = inputstr.encode ("utf8")
|
||||
else:
|
||||
return -1
|
||||
|
||||
h = 0x00000000
|
||||
for i in range (0, len (instr)):
|
||||
h = (h << 4) + ord(instr[i])
|
||||
h ^= (h & 0xf0000000) >> 23
|
||||
h &= 0x0fffffff
|
||||
|
||||
return h
|
||||
|
||||
|
||||
class DummyCSSPreProcessor(object):
|
||||
|
||||
def __call__(self, data, add_namespace=False):
|
||||
@ -44,11 +63,11 @@ class KOBO(USBMS):
|
||||
gui_name = 'Kobo Reader'
|
||||
description = _('Communicate with the Kobo Reader')
|
||||
author = 'Timothy Legge and David Forrester'
|
||||
version = (2, 1, 2)
|
||||
version = (2, 1, 3)
|
||||
|
||||
dbversion = 0
|
||||
fwversion = 0
|
||||
supported_dbversion = 80
|
||||
supported_dbversion = 90
|
||||
has_kepubs = False
|
||||
|
||||
supported_platforms = ['windows', 'osx', 'linux']
|
||||
@ -1221,16 +1240,18 @@ class KOBOTOUCH(KOBO):
|
||||
description = 'Communicate with the Kobo Touch, Glo, Mini and Aura HD ereaders. Based on the existing Kobo driver by %s.' % (KOBO.author)
|
||||
# icon = I('devices/kobotouch.jpg')
|
||||
|
||||
supported_dbversion = 80
|
||||
supported_dbversion = 90
|
||||
min_supported_dbversion = 53
|
||||
min_dbversion_series = 65
|
||||
min_dbversion_externalid = 65
|
||||
min_dbversion_archive = 71
|
||||
min_dbversion_images_on_sdcard = 77
|
||||
min_dbversion_activiy = 77
|
||||
min_dbversion_keywords = 82
|
||||
|
||||
max_supported_fwversion = (2,8,1)
|
||||
max_supported_fwversion = (2,9,1)
|
||||
min_fwversion_images_on_sdcard = (2,4,1)
|
||||
min_fwversion_images_tree = (2,9,0) # Cover images stored in tree under .kobo-images
|
||||
|
||||
has_kepubs = True
|
||||
|
||||
@ -1331,15 +1352,16 @@ class KOBOTOUCH(KOBO):
|
||||
|
||||
BCD = [0x0110, 0x0326]
|
||||
|
||||
# Image file name endings. Made up of: image size, min_dbversion, max_dbversion,
|
||||
# Image file name endings. Made up of: image size, min_dbversion, max_dbversion, isFullSize,
|
||||
COVER_FILE_ENDINGS = {
|
||||
' - N3_FULL.parsed':[(600,800),0, 99,True,], # Used for screensaver, home screen
|
||||
' - N3_LIBRARY_FULL.parsed':[(355,473),0, 99,False,], # Used for Details screen
|
||||
' - N3_LIBRARY_FULL.parsed':[(355,473),0, 81,False,], # Used for Details screen
|
||||
' - N3_LIBRARY_GRID.parsed':[(149,198),0, 99,False,], # Used for library lists
|
||||
' - N3_LIBRARY_LIST.parsed':[(60,90),0, 53,False,],
|
||||
' - AndroidBookLoadTablet_Aspect.parsed':[(355,473), 82, 99,False,], # Used for Details screen
|
||||
# ' - N3_LIBRARY_SHELF.parsed': [(40,60),0, 52,],
|
||||
}
|
||||
GLO_COVER_FILE_ENDINGS = {
|
||||
GLO_COVER_FILE_ENDINGS = { # Glo and Aura share resolution, so the image sizes should be the same.
|
||||
' - N3_FULL.parsed':[(758,1024),0, 99,True,], # Used for screensaver, home screen
|
||||
' - N3_LIBRARY_FULL.parsed':[(355,479),0, 99,False,], # Used for Details screen
|
||||
' - N3_LIBRARY_GRID.parsed':[(149,201),0, 99,False,], # Used for library lists
|
||||
@ -1404,6 +1426,7 @@ class KOBOTOUCH(KOBO):
|
||||
debug_print('Kobo device: %s' % self.gui_name)
|
||||
debug_print('Version of driver:', self.version, 'Has kepubs:', self.has_kepubs)
|
||||
debug_print('Version of firmware:', self.fwversion, 'Has kepubs:', self.has_kepubs)
|
||||
debug_print('Firmware supports cover image tree:', self.fwversion >= self.min_fwversion_images_tree)
|
||||
|
||||
self.booklist_class.rebuild_collections = self.rebuild_collections
|
||||
|
||||
@ -1526,7 +1549,7 @@ class KOBOTOUCH(KOBO):
|
||||
if (ContentType == '6' and MimeType != 'application/x-kobo-epub+zip'):
|
||||
if os.path.exists(self.normalize_path(os.path.join(prefix, lpath))):
|
||||
if self.update_metadata_item(bl[idx]):
|
||||
print 'update_metadata_item returned true'
|
||||
# print 'update_metadata_item returned true'
|
||||
changed = True
|
||||
else:
|
||||
debug_print(" Strange: The file: ", prefix, lpath, " does not exist!")
|
||||
@ -1741,8 +1764,9 @@ class KOBOTOUCH(KOBO):
|
||||
bookshelves = get_bookshelvesforbook(connection, row[3])
|
||||
|
||||
prefix = self._card_a_prefix if oncard == 'carda' else self._main_prefix
|
||||
changed = update_booklist(prefix, path, row[0], row[1], mime, row[2], row[3], row[5], row[
|
||||
6], row[7], row[4], row[8], row[9], row[10], row[11], row[12], row[13], row[14], bookshelves)
|
||||
changed = update_booklist(prefix, path, row[0], row[1], mime, row[2], row[3], row[5],
|
||||
row[6], row[7], row[4], row[8], row[9], row[10], row[11],
|
||||
row[12], row[13], row[14], bookshelves)
|
||||
|
||||
if changed:
|
||||
need_sync = True
|
||||
@ -1812,11 +1836,11 @@ class KOBOTOUCH(KOBO):
|
||||
def imagefilename_from_imageID(self, prefix, ImageID):
|
||||
show_debug = self.is_debugging_title(ImageID)
|
||||
|
||||
path = self.images_path(prefix)
|
||||
path = self.normalize_path(path.replace('/', os.sep))
|
||||
path = self.images_path(prefix, ImageID)
|
||||
# path = self.normalize_path(path.replace('/', os.sep))
|
||||
|
||||
for ending, cover_options in self.cover_file_endings().items():
|
||||
fpath = path + ImageID + ending
|
||||
fpath = path + ending
|
||||
if os.path.exists(fpath):
|
||||
if show_debug:
|
||||
debug_print("KoboTouch:imagefilename_from_imageID - have cover image fpath=%s" % (fpath))
|
||||
@ -1917,8 +1941,6 @@ class KOBOTOUCH(KOBO):
|
||||
else:
|
||||
debug_print("KoboTouch:_modify_epub: received container")
|
||||
|
||||
# cssnames = [n for n in container.name_path_map if n.endswith('.css')]
|
||||
# for cssname in cssnames:
|
||||
from calibre.ebooks.oeb.base import OEB_STYLES
|
||||
for cssname, mt in container.mime_map.iteritems():
|
||||
if mt in OEB_STYLES:
|
||||
@ -2009,17 +2031,23 @@ class KOBOTOUCH(KOBO):
|
||||
def delete_images(self, ImageID, book_path):
|
||||
debug_print("KoboTouch:delete_images - ImageID=", ImageID)
|
||||
if ImageID != None:
|
||||
path = self.images_path(book_path)
|
||||
path = path + ImageID
|
||||
path = self.images_path(book_path, ImageID)
|
||||
debug_print("KoboTouch:delete_images - path=%s" % path)
|
||||
|
||||
for ending in self.cover_file_endings().keys():
|
||||
fpath = path + ending
|
||||
fpath = self.normalize_path(fpath)
|
||||
debug_print("KoboTouch:delete_images - fpath=%s" % fpath)
|
||||
|
||||
if os.path.exists(fpath):
|
||||
# print 'Image File Exists: ' + fpath
|
||||
debug_print("KoboTouch:delete_images - Image File Exists")
|
||||
os.unlink(fpath)
|
||||
|
||||
try:
|
||||
os.removedirs(os.path.dirname(path))
|
||||
except:
|
||||
pass
|
||||
|
||||
def contentid_from_path(self, path, ContentType):
|
||||
show_debug = self.is_debugging_title(path) and True
|
||||
if show_debug:
|
||||
@ -2297,14 +2325,22 @@ class KOBOTOUCH(KOBO):
|
||||
ImageID = ImageID.replace('.', '_')
|
||||
return ImageID
|
||||
|
||||
def images_path(self, path):
|
||||
def images_path(self, path, imageId=None):
|
||||
if self._card_a_prefix and os.path.abspath(path).startswith(os.path.abspath(self._card_a_prefix)) and self.supports_covers_on_sdcard():
|
||||
path_prefix = 'koboExtStorage/images/'
|
||||
path_prefix = 'koboExtStorage/images-cache/' if self.supports_images_tree() else 'koboExtStorage/images/'
|
||||
path = os.path.join(self._card_a_prefix, path_prefix)
|
||||
else:
|
||||
path_prefix = '.kobo/images/'
|
||||
path_prefix = '.kobo-images/' if self.supports_images_tree() else '.kobo/images/'
|
||||
path = os.path.join(self._main_prefix, path_prefix)
|
||||
|
||||
if self.supports_images_tree() and imageId:
|
||||
hash1 = qhash(imageId)
|
||||
dir1 = hash1 & (0xff * 1)
|
||||
dir2 = (hash1 & (0xff00 * 1)) >> 8
|
||||
path = os.path.join(path, "%s" % dir1, "%s" % dir2)
|
||||
|
||||
if imageId:
|
||||
path = os.path.join(path, imageId)
|
||||
return path
|
||||
|
||||
def _upload_cover(self, path, filename, metadata, filepath, uploadgrayscale, keep_cover_aspect=False):
|
||||
@ -2326,8 +2362,7 @@ class KOBOTOUCH(KOBO):
|
||||
|
||||
try:
|
||||
import sqlite3 as sqlite
|
||||
with closing(sqlite.connect(self.normalize_path(self._main_prefix +
|
||||
'.kobo/KoboReader.sqlite'))) as connection:
|
||||
with closing(sqlite.connect(self.device_database_path())) as connection:
|
||||
|
||||
# return bytestrings if the content cannot the decoded as unicode
|
||||
connection.text_factory = lambda x: unicode(x, "utf-8", "ignore")
|
||||
@ -2347,7 +2382,7 @@ class KOBOTOUCH(KOBO):
|
||||
cursor.close()
|
||||
|
||||
if ImageID != None:
|
||||
path = os.path.join(self.images_path(path), ImageID)
|
||||
path = self.images_path(path, ImageID)
|
||||
|
||||
if show_debug:
|
||||
debug_print("KoboTouch:_upload_cover - About to loop over cover endings")
|
||||
@ -2762,6 +2797,9 @@ class KOBOTOUCH(KOBO):
|
||||
def supports_covers_on_sdcard(self):
|
||||
return self.dbversion >= self.min_dbversion_images_on_sdcard and self.fwversion >= self.min_fwversion_images_on_sdcard
|
||||
|
||||
def supports_images_tree(self):
|
||||
return self.fwversion >= self.min_fwversion_images_tree
|
||||
|
||||
def has_externalid(self):
|
||||
return self.dbversion >= self.min_dbversion_externalid
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user