diff --git a/src/calibre/ebooks/metadata/book/base.py b/src/calibre/ebooks/metadata/book/base.py index 366d12e5be..41b913455a 100644 --- a/src/calibre/ebooks/metadata/book/base.py +++ b/src/calibre/ebooks/metadata/book/base.py @@ -92,6 +92,8 @@ class Metadata(object): def is_null(self, field): null_val = NULL_VALUES.get(field, None) val = getattr(self, field, None) + if val is False or val in (0, 0.0): + return True return not val or val == null_val def __getattribute__(self, field): diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py index e8467aaa50..e46f9b818d 100644 --- a/src/calibre/library/database2.py +++ b/src/calibre/library/database2.py @@ -1691,7 +1691,8 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): return books_to_refresh def set_metadata(self, id, mi, ignore_errors=False, set_title=True, - set_authors=True, commit=True, force_changes=False): + set_authors=True, commit=True, force_cover=False, + force_tags=False): ''' Set metadata for the book `id` from the `Metadata` object `mi` ''' @@ -1709,12 +1710,10 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): raise # force_changes has no role to play in setting title or author path_changed = False - if set_title and mi.title: + if set_title and not mi.is_null('title'): self._set_title(id, mi.title) path_changed = True - if set_authors: - if not mi.authors: - mi.authors = [_('Unknown')] + if set_authors and not mi.is_null('authors'): authors = [] for a in mi.authors: authors += string_to_authors(a) @@ -1723,15 +1722,15 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): if path_changed: self.set_path(id, index_is_id=True) - if force_changes or mi.author_sort: + if not mi.is_null('author_sort'): doit(self.set_author_sort, id, mi.author_sort, notify=False, commit=False) - if force_changes or mi.publisher: + if not mi.is_null('publisher'): doit(self.set_publisher, id, mi.publisher, notify=False, commit=False) - if force_changes or mi.rating: + if not mi.is_null('rating'): doit(self.set_rating, id, mi.rating, notify=False, commit=False) - if force_changes or mi.series: + if not mi.is_null('series'): doit(self.set_series, id, mi.series, notify=False, commit=False) if mi.cover_data[1] is not None: @@ -1742,19 +1741,17 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): raw = f.read() if raw: doit(self.set_cover, id, raw, commit=False) - elif force_changes: + elif force_cover: doit(self.remove_cover, id, notify=False, commit=False) - if force_changes or mi.tags: + if force_tags or not mi.is_null('tags'): doit(self.set_tags, id, mi.tags, notify=False, commit=False) - if force_changes or mi.comments: + if not mi.is_null('comments'): doit(self.set_comment, id, mi.comments, notify=False, commit=False) - if force_changes or mi.series_index: + if not mi.is_null('series_index'): doit(self.set_series_index, id, mi.series_index, notify=False, commit=False) - - # force_changes would have no effect on the next two. - if mi.pubdate: + if not mi.is_null('pubdate'): doit(self.set_pubdate, id, mi.pubdate, notify=False, commit=False) if getattr(mi, 'timestamp', None) is not None: doit(self.set_timestamp, id, mi.timestamp, notify=False, @@ -1764,19 +1761,16 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): if mi_idents: identifiers = self.get_identifiers(id, index_is_id=True) for key, val in mi_idents.iteritems(): - if force_changes or (val and val.strip()): + if val and val.strip(): identifiers[icu_lower(key)] = val self.set_identifiers(id, identifiers, notify=False, commit=False) - user_mi = mi.get_all_user_metadata(make_copy=False) for key in user_mi.iterkeys(): if key in self.field_metadata and \ user_mi[key]['datatype'] == self.field_metadata[key]['datatype']: - val = mi.get(key, None) - if force_changes or val: - doit(self.set_custom, id, val=val, extra=mi.get_extra(key), - label=user_mi[key]['label'], commit=False) + doit(self.set_custom, id, val=mi.get(key), commit=False, + extra=mi.get_extra(key), label=user_mi[key]['label']) if commit: self.conn.commit() self.notify('metadata', [id]) @@ -2366,6 +2360,8 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): @param tags: list of strings @param append: If True existing tags are not removed ''' + if not tags: + tags = [] if not append: self.conn.execute('DELETE FROM books_tags_link WHERE book=?', (id,)) self.conn.execute('''DELETE FROM tags WHERE (SELECT COUNT(id) @@ -2516,6 +2512,8 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): self.notify('metadata', [id]) def set_rating(self, id, rating, notify=True, commit=True): + if not rating: + rating = 0 rating = int(rating) self.conn.execute('DELETE FROM books_ratings_link WHERE book=?',(id,)) rat = self.conn.get('SELECT id FROM ratings WHERE rating=?', (rating,), all=False) @@ -2530,7 +2528,10 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): def set_comment(self, id, text, notify=True, commit=True): self.conn.execute('DELETE FROM comments WHERE book=?', (id,)) - self.conn.execute('INSERT INTO comments(book,text) VALUES (?,?)', (id, text)) + if text: + self.conn.execute('INSERT INTO comments(book,text) VALUES (?,?)', (id, text)) + else: + text = '' if commit: self.conn.commit() self.data.set(id, self.FIELD_MAP['comments'], text, row_is_id=True) @@ -2539,6 +2540,8 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): self.notify('metadata', [id]) def set_author_sort(self, id, sort, notify=True, commit=True): + if not sort: + sort = '' self.conn.execute('UPDATE books SET author_sort=? WHERE id=?', (sort, id)) self.dirtied([id], commit=False) if commit: @@ -2610,6 +2613,8 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): def set_identifiers(self, id_, identifiers, notify=True, commit=True): cleaned = {} + if not identifiers: + identifiers = {} for typ, val in identifiers.iteritems(): typ, val = self._clean_identifier(typ, val) if val: