Fix #5518 (EPUB: Unable to clear or delete series and update file series meta data when saving to disk)

This commit is contained in:
Kovid Goyal 2010-05-15 20:43:21 -06:00
parent d7a9c48849
commit 561f7a2c68
6 changed files with 39 additions and 3 deletions

View File

@ -236,6 +236,10 @@ class MetadataWriterPlugin(Plugin):
type = _('Metadata writer') type = _('Metadata writer')
def __init__(self, *args, **kwargs):
Plugin.__init__(self, *args, **kwargs)
self.apply_null = False
def set_metadata(self, stream, mi, type): def set_metadata(self, stream, mi, type):
''' '''
Set metadata for the file represented by stream (a file like object Set metadata for the file represented by stream (a file like object

View File

@ -329,7 +329,7 @@ class EPUBMetadataWriter(MetadataWriterPlugin):
def set_metadata(self, stream, mi, type): def set_metadata(self, stream, mi, type):
from calibre.ebooks.metadata.epub import set_metadata from calibre.ebooks.metadata.epub import set_metadata
set_metadata(stream, mi) set_metadata(stream, mi, apply_null=self.apply_null)
class LRFMetadataWriter(MetadataWriterPlugin): class LRFMetadataWriter(MetadataWriterPlugin):

View File

@ -187,6 +187,18 @@ class QuickMetadata(object):
quick_metadata = QuickMetadata() 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): def get_file_type_metadata(stream, ftype):
mi = MetaInformation(None, None) mi = MetaInformation(None, None)
@ -214,6 +226,7 @@ def set_file_type_metadata(stream, mi, ftype):
if not is_disabled(plugin): if not is_disabled(plugin):
with plugin: with plugin:
try: try:
plugin.apply_null = apply_null_metadata.apply_null
plugin.set_metadata(stream, mi, ftype.lower().strip()) plugin.set_metadata(stream, mi, ftype.lower().strip())
break break
except: except:

View File

@ -182,13 +182,21 @@ def get_metadata(stream, extract_cover=True):
def get_quick_metadata(stream): def get_quick_metadata(stream):
return get_metadata(stream, False) return get_metadata(stream, False)
def set_metadata(stream, mi): def set_metadata(stream, mi, apply_null=False):
stream.seek(0) stream.seek(0)
reader = OCFZipReader(stream, root=os.getcwdu()) reader = OCFZipReader(stream, root=os.getcwdu())
mi = MetaInformation(mi) mi = MetaInformation(mi)
for x in ('guide', 'toc', 'manifest', 'spine'): for x in ('guide', 'toc', 'manifest', 'spine'):
setattr(mi, x, None) setattr(mi, x, None)
reader.opf.smart_update(mi) 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()) newopf = StringIO(reader.opf.render())
safe_replace(stream, reader.container[OPF.MIMETYPE], newopf) safe_replace(stream, reader.container[OPF.MIMETYPE], newopf)

View File

@ -404,6 +404,10 @@ class MetadataField(object):
def __set__(self, obj, val): def __set__(self, obj, val):
elem = obj.get_metadata_element(self.name) 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: if elem is None:
elem = obj.create_metadata_element(self.name, is_dc=self.is_dc) elem = obj.create_metadata_element(self.name, is_dc=self.is_dc)
obj.set_text(elem, unicode(val)) obj.set_text(elem, unicode(val))
@ -722,6 +726,11 @@ class OPF(object):
def fset(self, val): def fset(self, val):
matches = self.isbn_path(self.metadata) matches = self.isbn_path(self.metadata)
if val is None:
if matches:
for x in matches:
x.getparent().remove(x)
return
if not matches: if not matches:
attrib = {'{%s}scheme'%self.NAMESPACES['opf']: 'ISBN'} attrib = {'{%s}scheme'%self.NAMESPACES['opf']: 'ISBN'}
matches = [self.create_metadata_element('identifier', matches = [self.create_metadata_element('identifier',

View File

@ -235,6 +235,7 @@ def save_book(task, library_path, path, recs, notification=lambda x,y:x):
from calibre.library.database2 import LibraryDatabase2 from calibre.library.database2 import LibraryDatabase2
db = LibraryDatabase2(library_path) db = LibraryDatabase2(library_path)
from calibre.library.save_to_disk import config, save_to_disk from calibre.library.save_to_disk import config, save_to_disk
from calibre.customize.ui import apply_null_metadata
opts = config().parse() opts = config().parse()
for name in recs: for name in recs:
setattr(opts, name, recs[name]) 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)) notification((id, title, not failed, tb))
return True return True
save_to_disk(db, task, path, opts, callback) with apply_null_metadata:
save_to_disk(db, task, path, opts, callback)