From 1216a41f2089371f577c366a0dec4ed7cb312aab Mon Sep 17 00:00:00 2001 From: Charles Haley <> Date: Sun, 7 Oct 2012 08:51:12 +0200 Subject: [PATCH] Put back the optimization in book matching for UUID matches: only update metadata if the last mod date has changed. To avoid the problem that caused the change to be taken out, fix the smartapp driver to detect when a new cover must be sent and clear the date. --- .../devices/smart_device_app/driver.py | 23 +++++++++++++++---- src/calibre/gui2/device.py | 4 +++- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/calibre/devices/smart_device_app/driver.py b/src/calibre/devices/smart_device_app/driver.py index 0f325bfdd7..e8afc4daca 100644 --- a/src/calibre/devices/smart_device_app/driver.py +++ b/src/calibre/devices/smart_device_app/driver.py @@ -35,7 +35,7 @@ from calibre.library.server import server_config as content_server_config from calibre.ptempfile import PersistentTemporaryFile from calibre.utils.ipc import eintr_retry_call from calibre.utils.config import from_json, tweaks -from calibre.utils.date import isoformat, now +from calibre.utils.date import isoformat, now, UNDEFINED_DATE from calibre.utils.filenames import ascii_filename as sanitize, shorten_components_to from calibre.utils.mdns import (publish as publish_zeroconf, unpublish as unpublish_zeroconf, get_all_ips) @@ -657,9 +657,16 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin): def _metadata_already_on_device(self, book): v = self.known_metadata.get(book.lpath, None) if v is not None: - return (v.get('uuid', None) == book.get('uuid', None) and - v.get('last_modified', None) == book.get('last_modified', None) and - v.get('thumbnail', None) == book.get('thumbnail', None)) + # Metadata is the same if the uuids match, if the last_modified dates + # match, and if the height of the thumbnails is the same. The last + # is there to allow a device to demand a different thumbnail size + if (v.get('uuid', None) == book.get('uuid', None) and + v.get('last_modified', None) == book.get('last_modified', None)): + v_thumb = v.get('thumbnail', None) + b_thumb = book.get('thumbnail', None) + if bool(v_thumb) != bool(b_thumb): + return False + return not v_thumb or v_thumb[1] == b_thumb[1] return False def _set_known_metadata(self, book, remove=False): @@ -976,6 +983,14 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin): if '_series_sort_' in result: del result['_series_sort_'] book = self.json_codec.raw_to_book(result, SDBook, self.PREFIX) + + # If the thumbnail is the wrong size, zero the last mod date + # so the metadata will be resent + thumbnail = book.get('thumbnail', None) + if thumbnail and not (thumbnail[0] == self.THUMBNAIL_HEIGHT or + thumbnail[1] == self.THUMBNAIL_HEIGHT): + book.set('last_modified', UNDEFINED_DATE) + bl.add_book(book, replace_metadata=True) if '_new_book_' in result: book.set('_new_book_', True) diff --git a/src/calibre/gui2/device.py b/src/calibre/gui2/device.py index 01e5c17768..d6b76a15f6 100644 --- a/src/calibre/gui2/device.py +++ b/src/calibre/gui2/device.py @@ -1695,7 +1695,9 @@ class DeviceMixin(object): # {{{ book.in_library = None if getattr(book, 'uuid', None) in self.db_book_uuid_cache: id_ = db_book_uuid_cache[book.uuid] - if update_metadata: + if (update_metadata and + db.metadata_last_modified(id_, index_is_id=True) != + getattr(book, 'last_modified', None)): mi = db.get_metadata(id_, index_is_id=True, get_cover=get_covers) book.smart_update(mi, replace_metadata=True)