From 561f7a2c68c179cbde915962953a33bd715caacc Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 15 May 2010 20:43:21 -0600 Subject: [PATCH] Fix #5518 (EPUB: Unable to clear or delete series and update file series meta data when saving to disk) --- src/calibre/customize/__init__.py | 4 ++++ src/calibre/customize/builtins.py | 2 +- src/calibre/customize/ui.py | 13 +++++++++++++ src/calibre/ebooks/metadata/epub.py | 10 +++++++++- src/calibre/ebooks/metadata/opf2.py | 9 +++++++++ src/calibre/ebooks/metadata/worker.py | 4 +++- 6 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/calibre/customize/__init__.py b/src/calibre/customize/__init__.py index 0d6f041736..4eaaf3b90a 100644 --- a/src/calibre/customize/__init__.py +++ b/src/calibre/customize/__init__.py @@ -236,6 +236,10 @@ class MetadataWriterPlugin(Plugin): type = _('Metadata writer') + def __init__(self, *args, **kwargs): + Plugin.__init__(self, *args, **kwargs) + self.apply_null = False + def set_metadata(self, stream, mi, type): ''' Set metadata for the file represented by stream (a file like object diff --git a/src/calibre/customize/builtins.py b/src/calibre/customize/builtins.py index e9dd3d0cb4..52ec8fa255 100644 --- a/src/calibre/customize/builtins.py +++ b/src/calibre/customize/builtins.py @@ -329,7 +329,7 @@ class EPUBMetadataWriter(MetadataWriterPlugin): def set_metadata(self, stream, mi, type): from calibre.ebooks.metadata.epub import set_metadata - set_metadata(stream, mi) + set_metadata(stream, mi, apply_null=self.apply_null) class LRFMetadataWriter(MetadataWriterPlugin): diff --git a/src/calibre/customize/ui.py b/src/calibre/customize/ui.py index 68c26386c9..a2521b0023 100644 --- a/src/calibre/customize/ui.py +++ b/src/calibre/customize/ui.py @@ -187,6 +187,18 @@ class QuickMetadata(object): quick_metadata = QuickMetadata() +class ApplyNullMetadata(object): + + def __init__(self): + self.apply_null = False + + def __enter__(self): + self.apply_null = True + + def __exit__(self, *args): + self.apply_null = False + +apply_null_metadata = ApplyNullMetadata() def get_file_type_metadata(stream, ftype): mi = MetaInformation(None, None) @@ -214,6 +226,7 @@ def set_file_type_metadata(stream, mi, ftype): if not is_disabled(plugin): with plugin: try: + plugin.apply_null = apply_null_metadata.apply_null plugin.set_metadata(stream, mi, ftype.lower().strip()) break except: diff --git a/src/calibre/ebooks/metadata/epub.py b/src/calibre/ebooks/metadata/epub.py index 1dab9cd91c..d74ed37f66 100644 --- a/src/calibre/ebooks/metadata/epub.py +++ b/src/calibre/ebooks/metadata/epub.py @@ -182,13 +182,21 @@ def get_metadata(stream, extract_cover=True): def get_quick_metadata(stream): return get_metadata(stream, False) -def set_metadata(stream, mi): +def set_metadata(stream, mi, apply_null=False): stream.seek(0) reader = OCFZipReader(stream, root=os.getcwdu()) mi = MetaInformation(mi) for x in ('guide', 'toc', 'manifest', 'spine'): setattr(mi, x, None) reader.opf.smart_update(mi) + if apply_null: + if not getattr(mi, 'series', None): + reader.opf.series = None + if not getattr(mi, 'tags', []): + reader.opf.tags = [] + if not getattr(mi, 'isbn', None): + reader.opf.isbn = None + newopf = StringIO(reader.opf.render()) safe_replace(stream, reader.container[OPF.MIMETYPE], newopf) diff --git a/src/calibre/ebooks/metadata/opf2.py b/src/calibre/ebooks/metadata/opf2.py index 7eeac5cc85..e429574e57 100644 --- a/src/calibre/ebooks/metadata/opf2.py +++ b/src/calibre/ebooks/metadata/opf2.py @@ -404,6 +404,10 @@ class MetadataField(object): def __set__(self, obj, val): elem = obj.get_metadata_element(self.name) + if val is None: + if elem is not None: + elem.getparent().remove(elem) + return if elem is None: elem = obj.create_metadata_element(self.name, is_dc=self.is_dc) obj.set_text(elem, unicode(val)) @@ -722,6 +726,11 @@ class OPF(object): def fset(self, val): matches = self.isbn_path(self.metadata) + if val is None: + if matches: + for x in matches: + x.getparent().remove(x) + return if not matches: attrib = {'{%s}scheme'%self.NAMESPACES['opf']: 'ISBN'} matches = [self.create_metadata_element('identifier', diff --git a/src/calibre/ebooks/metadata/worker.py b/src/calibre/ebooks/metadata/worker.py index 3fc33f42cd..178174a0d7 100644 --- a/src/calibre/ebooks/metadata/worker.py +++ b/src/calibre/ebooks/metadata/worker.py @@ -235,6 +235,7 @@ def save_book(task, library_path, path, recs, notification=lambda x,y:x): from calibre.library.database2 import LibraryDatabase2 db = LibraryDatabase2(library_path) from calibre.library.save_to_disk import config, save_to_disk + from calibre.customize.ui import apply_null_metadata opts = config().parse() for name in recs: setattr(opts, name, recs[name]) @@ -244,5 +245,6 @@ def save_book(task, library_path, path, recs, notification=lambda x,y:x): notification((id, title, not failed, tb)) return True - save_to_disk(db, task, path, opts, callback) + with apply_null_metadata: + save_to_disk(db, task, path, opts, callback)