Kobo driver: Add support for new firmware with the series list on the device

Merge branch 'master' of https://github.com/davidfor/calibre
This commit is contained in:
Kovid Goyal 2020-03-03 17:45:50 +05:30
commit 477d9ef560
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 55 additions and 14 deletions

View File

@ -70,6 +70,7 @@ class Book(Book_):
self.can_put_on_shelves = True
self.kobo_series = None
self.kobo_series_number = None # Kobo stores the series number as string. And it can have a leading "#".
self.kobo_series_id = None
self.kobo_subtitle = None
if thumbnail_name is not None:
@ -84,6 +85,10 @@ class Book(Book_):
# If we don't have a content Id, we don't know what type it is.
return self.contentID and self.contentID.startswith("file")
@property
def has_kobo_series(self):
return self.kobo_series is not None
@property
def is_purchased_kepub(self):
return self.contentID and not self.contentID.startswith("file")
@ -102,6 +107,8 @@ class Book(Book_):
fmt('Content ID', self.contentID)
if self.kobo_series:
fmt('Kobo Series', self.kobo_series + ' #%s'%self.kobo_series_number)
if self.kobo_series_id:
fmt('Kobo Series ID', self.kobo_series_id)
if self.kobo_subtitle:
fmt('Subtitle', self.kobo_subtitle)
if self.mime:

View File

@ -83,7 +83,7 @@ class KOBO(USBMS):
dbversion = 0
fwversion = (0,0,0)
supported_dbversion = 156
supported_dbversion = 158
has_kepubs = False
supported_platforms = ['windows', 'osx', 'linux']
@ -1349,7 +1349,7 @@ class KOBOTOUCH(KOBO):
' Based on the existing Kobo driver by %s.') % KOBO.author
# icon = I('devices/kobotouch.jpg')
supported_dbversion = 157
supported_dbversion = 158
min_supported_dbversion = 53
min_dbversion_series = 65
min_dbversion_externalid = 65
@ -1357,11 +1357,12 @@ class KOBOTOUCH(KOBO):
min_dbversion_images_on_sdcard = 77
min_dbversion_activity = 77
min_dbversion_keywords = 82
min_dbversion_seriesid = 136
# Starting with firmware version 3.19.x, the last number appears to be is a
# build number. A number will be recorded here but it can be safely ignored
# when testing the firmware version.
max_supported_fwversion = (4, 19, 14114)
max_supported_fwversion = (4, 20, 14601)
# The following document firwmare versions where new function or devices were added.
# Not all are used, but this feels a good place to record it.
min_fwversion_shelves = (2, 0, 0)
@ -1377,11 +1378,13 @@ class KOBOTOUCH(KOBO):
min_librah20_fwversion = (4, 16, 13337) # "Reviewers" release.
min_fwversion_epub_location = (4, 17, 13651) # ePub reading location without full contentid.
min_fwversion_dropbox = (4, 18, 13737) # The Forma only at this point.
min_fwversion_serieslist = (4, 20, 14601) # Series list needs the SeriesID to be set.
has_kepubs = True
booklist_class = KTCollectionsBookList
book_class = Book
kobo_series_dict = {}
MAX_PATH_LEN = 185 # 250 - (len(" - N3_LIBRARY_SHELF.parsed") + len("F:\.kobo\images\"))
KOBO_EXTRA_CSSFILE = 'kobo_extra.css'
@ -1610,7 +1613,8 @@ class KOBOTOUCH(KOBO):
bl_cache[b.lpath] = idx
def update_booklist(prefix, path, ContentID, ContentType, MimeType, ImageID,
title, authors, DateCreated, Description, Publisher, series, seriesnumber,
title, authors, DateCreated, Description, Publisher,
series, seriesnumber, SeriesID, SeriesNumberFloat,
ISBN, Language, Subtitle,
readstatus, expired, favouritesindex, accessibility, isdownloaded,
userid, bookshelves
@ -1747,10 +1751,16 @@ class KOBOTOUCH(KOBO):
bl[idx].kobo_metadata = kobo_metadata
bl[idx].kobo_series = series
bl[idx].kobo_series_number = seriesnumber
bl[idx].kobo_series_id = SeriesID
bl[idx].kobo_subtitle = Subtitle
bl[idx].can_put_on_shelves = allow_shelves
bl[idx].mime = MimeType
if not bl[idx].is_sideloaded and bl[idx].has_kobo_series and SeriesID is not None:
if show_debug:
debug_print('KoboTouch:update_booklist - Have purchased kepub with series, saving SeriesID=', SeriesID)
self.kobo_series_dict[series] = SeriesID
if lpath in playlist_map:
bl[idx].device_collections = playlist_map.get(lpath,[])
bl[idx].current_shelves = bookshelves
@ -1800,10 +1810,16 @@ class KOBOTOUCH(KOBO):
book.kobo_metadata = kobo_metadata
book.kobo_series = series
book.kobo_series_number = seriesnumber
book.kobo_series_id = SeriesID
book.kobo_subtitle = Subtitle
book.can_put_on_shelves = allow_shelves
# debug_print('KoboTouch:update_booklist - title=', title, 'book.device_collections', book.device_collections)
if not book.is_sideloaded and book.has_kobo_series and SeriesID is not None:
if show_debug:
debug_print('KoboTouch:update_booklist - Have purchased kepub with series, saving SeriesID=', SeriesID)
self.kobo_series_dict[series] = SeriesID
if bl.add_book(book, replace_metadata=False):
changed = True
if show_debug:
@ -1863,6 +1879,10 @@ class KOBOTOUCH(KOBO):
columns += ", Series, SeriesNumber, ___UserID, ExternalId, Subtitle"
else:
columns += ', null as Series, null as SeriesNumber, ___UserID, null as ExternalId, null as Subtitle'
if self.supports_series_list:
columns += ", SeriesID, SeriesNumberFloat"
else:
columns += ', null as SeriesID, null as SeriesNumberFloat'
where_clause = ''
if self.supports_kobo_archive() or self.supports_overdrive():
@ -1957,7 +1977,8 @@ class KOBOTOUCH(KOBO):
prefix = self._card_a_prefix if oncard == 'carda' else self._main_prefix
changed = update_booklist(prefix, path, row['ContentID'], row['ContentType'], row['MimeType'], row['ImageId'],
row['Title'], row['Attribution'], row['DateCreated'], row['Description'], row['Publisher'],
row['Series'], row['SeriesNumber'], row['ISBN'], row['Language'], row['Subtitle'],
row['Series'], row['SeriesNumber'], row['SeriesID'], row['SeriesNumberFloat'],
row['ISBN'], row['Language'], row['Subtitle'],
row['ReadStatus'], row['___ExpirationStatus'],
int(row['FavouritesIndex']), row['Accessibility'], row['IsDownloaded'],
row['___UserID'], bookshelves
@ -1972,6 +1993,7 @@ class KOBOTOUCH(KOBO):
self.dump_bookshelves(connection)
else:
debug_print("KoboTouch:books - automatically managing metadata")
debug_print("KoboTouch:books - self.kobo_series_dict=", self.kobo_series_dict)
# 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
@ -3127,21 +3149,29 @@ class KOBOTOUCH(KOBO):
kobo_series_number = None
series_number_changed = not (kobo_series_number == newmi.series_index)
if series_changed or series_number_changed:
if newmi.series is not None:
new_series = newmi.series
try:
new_series_number = "%g" % newmi.series_index
except:
new_series_number = None
else:
new_series = None
if newmi.series is not None:
new_series = newmi.series
try:
new_series_number = "%g" % newmi.series_index
except:
new_series_number = None
else:
new_series = None
new_series_number = None
if series_changed or series_number_changed:
update_values.append(new_series)
set_clause += ', Series = ? '
update_values.append(new_series_number)
set_clause += ', SeriesNumber = ? '
if self.supports_series_list and book.is_sideloaded:
series_id = self.kobo_series_dict.get(new_series, new_series)
if not book.kobo_series_id == series_id or series_changed or series_number_changed:
update_values.append(series_id)
set_clause += ', SeriesID = ? '
update_values.append(new_series_number)
set_clause += ', SeriesNumberFloat = ? '
debug_print("KoboTouch:set_core_metadata Setting SeriesID - new_series='%s', series_id='%s'" % (new_series, series_id))
if not series_only:
if not (newmi.title == kobo_metadata.title):
@ -3537,6 +3567,10 @@ class KOBOTOUCH(KOBO):
def supports_series(self):
return self.dbversion >= self.min_dbversion_series
@property
def supports_series_list(self):
return self.dbversion >= self.min_dbversion_seriesid and self.fwversion >= self.min_fwversion_serieslist
def supports_kobo_archive(self):
return self.dbversion >= self.min_dbversion_archive