mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Add a count of how many books on the device matched a book in the library.
This commit is contained in:
commit
d02a9c49fc
@ -1306,16 +1306,26 @@ class DeviceMixin(object): # {{{
|
|||||||
self.library_view.model().refresh_ids(list(changed))
|
self.library_view.model().refresh_ids(list(changed))
|
||||||
|
|
||||||
def book_on_device(self, id, format=None, reset=False):
|
def book_on_device(self, id, format=None, reset=False):
|
||||||
loc = [None, None, None]
|
'''
|
||||||
|
Return an indication of whether the given book represented by its db id
|
||||||
|
is on the currently connected device. It returns a 4 element list. The
|
||||||
|
first three elements represent memory locations main, carda, and cardb,
|
||||||
|
and are true if the book is identifiably in that memory. The fourth
|
||||||
|
is the a count of how many instances of the book were found across all
|
||||||
|
the memory locations.
|
||||||
|
'''
|
||||||
|
loc = [None, None, None, 0]
|
||||||
|
|
||||||
if reset:
|
if reset:
|
||||||
self.book_db_title_cache = None
|
self.book_db_title_cache = None
|
||||||
self.book_db_uuid_cache = None
|
self.book_db_uuid_cache = None
|
||||||
|
self.book_db_id_counts = None
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.book_db_title_cache is None:
|
if self.book_db_title_cache is None:
|
||||||
self.book_db_title_cache = []
|
self.book_db_title_cache = []
|
||||||
self.book_db_uuid_cache = []
|
self.book_db_uuid_cache = []
|
||||||
|
self.book_db_id_counts = {}
|
||||||
for i, l in enumerate(self.booklists()):
|
for i, l in enumerate(self.booklists()):
|
||||||
self.book_db_title_cache.append({})
|
self.book_db_title_cache.append({})
|
||||||
self.book_db_uuid_cache.append(set())
|
self.book_db_uuid_cache.append(set())
|
||||||
@ -1333,6 +1343,10 @@ class DeviceMixin(object): # {{{
|
|||||||
db_id = book.db_id
|
db_id = book.db_id
|
||||||
if db_id is not None:
|
if db_id is not None:
|
||||||
self.book_db_title_cache[i][book_title]['db_ids'].add(db_id)
|
self.book_db_title_cache[i][book_title]['db_ids'].add(db_id)
|
||||||
|
# increment the count of books on the device with this
|
||||||
|
# db_id.
|
||||||
|
c = self.book_db_id_counts.get(db_id, 0)
|
||||||
|
self.book_db_id_counts[db_id] = c + 1
|
||||||
uuid = getattr(book, 'uuid', None)
|
uuid = getattr(book, 'uuid', None)
|
||||||
if uuid is not None:
|
if uuid is not None:
|
||||||
self.book_db_uuid_cache[i].add(uuid)
|
self.book_db_uuid_cache[i].add(uuid)
|
||||||
@ -1351,7 +1365,13 @@ class DeviceMixin(object): # {{{
|
|||||||
if mi.authors and \
|
if mi.authors and \
|
||||||
re.sub('(?u)\W|[_]', '', authors_to_string(mi.authors).lower()) \
|
re.sub('(?u)\W|[_]', '', authors_to_string(mi.authors).lower()) \
|
||||||
in cache['authors']:
|
in cache['authors']:
|
||||||
|
# We really shouldn't get here, because set_books_in_library
|
||||||
|
# should have set the db_ids for the books, and therefore
|
||||||
|
# the if just above should have found them. Mark the book
|
||||||
|
# anyway, and print a message about the situation
|
||||||
loc[i] = True
|
loc[i] = True
|
||||||
|
prints('book_on_device: matched title/author but not db_id!',
|
||||||
|
mi.title, authors_to_string(mi.authors))
|
||||||
continue
|
continue
|
||||||
# Also check author sort, because it can be used as author in
|
# Also check author sort, because it can be used as author in
|
||||||
# some formats
|
# some formats
|
||||||
@ -1360,9 +1380,16 @@ class DeviceMixin(object): # {{{
|
|||||||
in cache['authors']:
|
in cache['authors']:
|
||||||
loc[i] = True
|
loc[i] = True
|
||||||
continue
|
continue
|
||||||
|
loc[3] = self.book_db_id_counts.get(id, 0)
|
||||||
return loc
|
return loc
|
||||||
|
|
||||||
def set_books_in_library(self, booklists, reset=False):
|
def set_books_in_library(self, booklists, reset=False):
|
||||||
|
'''
|
||||||
|
Set the ondevice indications in the device database.
|
||||||
|
This method should be called before book_on_device is called, because
|
||||||
|
it sets the application_id for matched books. Book_on_device uses that
|
||||||
|
to both speed up matching and to count matches.
|
||||||
|
'''
|
||||||
# Force a reset if the caches are not initialized
|
# Force a reset if the caches are not initialized
|
||||||
if reset or not hasattr(self, 'db_book_title_cache'):
|
if reset or not hasattr(self, 'db_book_title_cache'):
|
||||||
# It might be possible to get here without having initialized the
|
# It might be possible to get here without having initialized the
|
||||||
@ -1393,10 +1420,12 @@ class DeviceMixin(object): # {{{
|
|||||||
self.db_book_uuid_cache[mi.uuid] = mi
|
self.db_book_uuid_cache[mi.uuid] = mi
|
||||||
|
|
||||||
# Now iterate through all the books on the device, setting the
|
# Now iterate through all the books on the device, setting the
|
||||||
# in_library field Fastest and most accurate key is the uuid. Second is
|
# in_library field. Fastest and most accurate key is the uuid. Second is
|
||||||
# the application_id, which is really the db key, but as this can
|
# the application_id, which is really the db key, but as this can
|
||||||
# accidentally match across libraries we also verify the title. The
|
# accidentally match across libraries we also verify the title. The
|
||||||
# db_id exists on Sony devices. Fallback is title and author match
|
# db_id exists on Sony devices. Fallback is title and author match.
|
||||||
|
# We set the application ID so that we can reproduce book matching,
|
||||||
|
# necessary for identifying copies of books.
|
||||||
|
|
||||||
update_metadata = prefs['manage_device_metadata'] == 'on_connect'
|
update_metadata = prefs['manage_device_metadata'] == 'on_connect'
|
||||||
for booklist in booklists:
|
for booklist in booklists:
|
||||||
@ -1418,12 +1447,15 @@ class DeviceMixin(object): # {{{
|
|||||||
if d is not None:
|
if d is not None:
|
||||||
if getattr(book, 'application_id', None) in d['db_ids']:
|
if getattr(book, 'application_id', None) in d['db_ids']:
|
||||||
book.in_library = True
|
book.in_library = True
|
||||||
|
# application already matches db_id, so no need to set it
|
||||||
if update_metadata:
|
if update_metadata:
|
||||||
book.smart_update(d['db_ids'][book.application_id],
|
book.smart_update(d['db_ids'][book.application_id],
|
||||||
replace_metadata=True)
|
replace_metadata=True)
|
||||||
continue
|
continue
|
||||||
if book.db_id in d['db_ids']:
|
if book.db_id in d['db_ids']:
|
||||||
book.in_library = True
|
book.in_library = True
|
||||||
|
book.application_id = \
|
||||||
|
d['db_ids'][book.db_id].application_id
|
||||||
if update_metadata:
|
if update_metadata:
|
||||||
book.smart_update(d['db_ids'][book.db_id],
|
book.smart_update(d['db_ids'][book.db_id],
|
||||||
replace_metadata=True)
|
replace_metadata=True)
|
||||||
@ -1435,11 +1467,15 @@ class DeviceMixin(object): # {{{
|
|||||||
book_authors = re.sub('(?u)\W|[_]', '', book_authors)
|
book_authors = re.sub('(?u)\W|[_]', '', book_authors)
|
||||||
if book_authors in d['authors']:
|
if book_authors in d['authors']:
|
||||||
book.in_library = True
|
book.in_library = True
|
||||||
|
book.application_id = \
|
||||||
|
d['authors'][book_authors].application_id
|
||||||
if update_metadata:
|
if update_metadata:
|
||||||
book.smart_update(d['authors'][book_authors],
|
book.smart_update(d['authors'][book_authors],
|
||||||
replace_metadata=True)
|
replace_metadata=True)
|
||||||
elif book_authors in d['author_sort']:
|
elif book_authors in d['author_sort']:
|
||||||
book.in_library = True
|
book.in_library = True
|
||||||
|
book.application_id = \
|
||||||
|
d['author_sort'][book_authors].application_id
|
||||||
if update_metadata:
|
if update_metadata:
|
||||||
book.smart_update(d['author_sort'][book_authors],
|
book.smart_update(d['author_sort'][book_authors],
|
||||||
replace_metadata=True)
|
replace_metadata=True)
|
||||||
|
@ -640,16 +640,17 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
|
|
||||||
def book_on_device_string(self, id):
|
def book_on_device_string(self, id):
|
||||||
loc = []
|
loc = []
|
||||||
|
count = 0
|
||||||
on = self.book_on_device(id)
|
on = self.book_on_device(id)
|
||||||
if on is not None:
|
if on is not None:
|
||||||
m, a, b = on
|
m, a, b, count = on
|
||||||
if m is not None:
|
if m is not None:
|
||||||
loc.append(_('Main'))
|
loc.append(_('Main'))
|
||||||
if a is not None:
|
if a is not None:
|
||||||
loc.append(_('Card A'))
|
loc.append(_('Card A'))
|
||||||
if b is not None:
|
if b is not None:
|
||||||
loc.append(_('Card B'))
|
loc.append(_('Card B'))
|
||||||
return ', '.join(loc)
|
return ', '.join(loc) + ((' (%s books)'%count) if count > 1 else '')
|
||||||
|
|
||||||
def set_book_on_device_func(self, func):
|
def set_book_on_device_func(self, func):
|
||||||
self.book_on_device_func = func
|
self.book_on_device_func = func
|
||||||
|
Loading…
x
Reference in New Issue
Block a user