diff --git a/src/calibre/db/backend.py b/src/calibre/db/backend.py index 76c5841180..c6aa2e646f 100644 --- a/src/calibre/db/backend.py +++ b/src/calibre/db/backend.py @@ -985,11 +985,19 @@ class DB(object): else: if callable(getattr(data, 'read', None)): data = data.read() - try: - save_cover_data_to(data, path) - except (IOError, OSError): - time.sleep(0.2) - save_cover_data_to(data, path) + if data is None: + if os.path.exists(path): + try: + os.remove(path) + except (IOError, OSError): + time.sleep(0.2) + os.remove(path) + else: + try: + save_cover_data_to(data, path) + except (IOError, OSError): + time.sleep(0.2) + save_cover_data_to(data, path) def copy_format_to(self, book_id, fmt, fname, path, dest, windows_atomic_move=None, use_hardlink=False): diff --git a/src/calibre/db/cache.py b/src/calibre/db/cache.py index ba68de23a7..b79ff2a31b 100644 --- a/src/calibre/db/cache.py +++ b/src/calibre/db/cache.py @@ -826,7 +826,8 @@ class Cache(object): @write_api def set_cover(self, book_id_data_map): ''' Set the cover for this book. data can be either a QImage, - QPixmap, file object or bytestring ''' + QPixmap, file object or bytestring. It can also be None, in which + case any existing cover is removed. ''' for book_id, data in book_id_data_map.iteritems(): try: @@ -836,7 +837,8 @@ class Cache(object): path = self._field_for('path', book_id).replace('/', os.sep) self.backend.set_cover(book_id, path, data) - self._set_field('cover', {book_id:1 for book_id in book_id_data_map}) + return self._set_field('cover', { + book_id:(0 if data is None else 1) for book_id, data in book_id_data_map.iteritems()}) @write_api def set_metadata(self, book_id, mi, ignore_errors=False, force_changes=False, diff --git a/src/calibre/db/tests/writing.py b/src/calibre/db/tests/writing.py index 9ec368dd83..5e25155713 100644 --- a/src/calibre/db/tests/writing.py +++ b/src/calibre/db/tests/writing.py @@ -355,7 +355,24 @@ class WritingTest(BaseTest): ae(opf.authors, ['author1', 'author2']) # }}} - def test_set_cover(self): + def test_set_cover(self): # {{{ ' Test setting of cover ' - self.assertTrue(False, 'TODO: test set_cover() and set_metadata()') + cache = self.init_cache() + ae = self.assertEqual + + # Test removing a cover + ae(cache.field_for('cover', 1), 1) + ae(cache.set_cover({1:None}), set([1])) + ae(cache.field_for('cover', 1), 0) + + img = b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x01\x00`\x00`\x00\x00\xff\xe1\x00\x16Exif\x00\x00II*\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xdb\x00C\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xff\xdb\x00C\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xff\xc0\x00\x11\x08\x00\x01\x00\x01\x03\x01"\x00\x02\x11\x01\x03\x11\x01\xff\xc4\x00\x15\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\xff\xc4\x00\x14\x10\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xc4\x00\x14\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xc4\x00\x14\x11\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xda\x00\x0c\x03\x01\x00\x02\x11\x03\x11\x00?\x00\xbf\x80\x01\xff\xd9' # noqa {{{ }}} + # Test setting a cover + ae(cache.set_cover({bid:img for bid in (1, 2, 3)}), {1, 2, 3}) + for book_id in (1, 2, 3): + ae(cache.cover(book_id), img, 'Cover was not set correctly for book %d' % book_id) + # }}} + + def test_set_metadata(self): + ' Test setting of metadata ' + self.assertTrue(False, 'TODO: test set_metadata()') diff --git a/src/calibre/db/write.py b/src/calibre/db/write.py index 1bdbabf082..7fdb2070c0 100644 --- a/src/calibre/db/write.py +++ b/src/calibre/db/write.py @@ -461,7 +461,7 @@ class Writer(object): dt = field.metadata['datatype'] self.accept_vals = lambda x: True if dt == 'composite' or field.name in { - 'id', 'cover', 'size', 'path', 'formats', 'news'}: + 'id', 'size', 'path', 'formats', 'news'}: self.set_books_func = dummy elif self.name[0] == '#' and self.name.endswith('_index'): self.set_books_func = custom_series_index