diff --git a/src/calibre/customize/builtins.py b/src/calibre/customize/builtins.py index 68df832048..1ddb2843a1 100644 --- a/src/calibre/customize/builtins.py +++ b/src/calibre/customize/builtins.py @@ -226,8 +226,7 @@ class OPFMetadataReader(MetadataReaderPlugin): def get_metadata(self, stream, ftype): from calibre.ebooks.metadata.opf2 import OPF - from calibre.ebooks.metadata import MetaInformation - return MetaInformation(OPF(stream, os.getcwd())) + return OPF(stream, os.getcwd()).to_book_metadata() class PDBMetadataReader(MetadataReaderPlugin): diff --git a/src/calibre/ebooks/conversion/plumber.py b/src/calibre/ebooks/conversion/plumber.py index 16282dd28d..38e47f6bf7 100644 --- a/src/calibre/ebooks/conversion/plumber.py +++ b/src/calibre/ebooks/conversion/plumber.py @@ -692,7 +692,7 @@ OptionRecommendation(name='timestamp', self.opts.read_metadata_from_opf) opf = OPF(open(self.opts.read_metadata_from_opf, 'rb'), os.path.dirname(self.opts.read_metadata_from_opf)) - mi = MetaInformation(opf) + mi = opf.to_book_metadata() self.opts_to_mi(mi) if mi.cover: if mi.cover.startswith('http:') or mi.cover.startswith('https:'): diff --git a/src/calibre/ebooks/metadata/cli.py b/src/calibre/ebooks/metadata/cli.py index 780d3febcf..a0be187512 100644 --- a/src/calibre/ebooks/metadata/cli.py +++ b/src/calibre/ebooks/metadata/cli.py @@ -109,7 +109,7 @@ def do_set_metadata(opts, mi, stream, stream_type): from_opf = getattr(opts, 'from_opf', None) if from_opf is not None: from calibre.ebooks.metadata.opf2 import OPF - opf_mi = MetaInformation(OPF(open(from_opf, 'rb'))) + opf_mi = OPF(open(from_opf, 'rb')).to_book_metadata() mi.smart_update(opf_mi) for pref in config().option_set.preferences: diff --git a/src/calibre/ebooks/metadata/epub.py b/src/calibre/ebooks/metadata/epub.py index ac6b5feebe..8984a252a3 100644 --- a/src/calibre/ebooks/metadata/epub.py +++ b/src/calibre/ebooks/metadata/epub.py @@ -167,7 +167,7 @@ def get_metadata(stream, extract_cover=True): """ Return metadata as a :class:`Metadata` object """ stream.seek(0) reader = OCFZipReader(stream) - mi = MetaInformation(reader.opf) + mi = reader.opf.to_book_metadata() if extract_cover: try: cdata = get_cover(reader.opf, reader.opf_path, stream, reader=reader) diff --git a/src/calibre/ebooks/metadata/lit.py b/src/calibre/ebooks/metadata/lit.py index 1a267b6858..3be1f22632 100644 --- a/src/calibre/ebooks/metadata/lit.py +++ b/src/calibre/ebooks/metadata/lit.py @@ -6,7 +6,6 @@ Support for reading the metadata from a LIT file. import cStringIO, os -from calibre.ebooks.metadata import MetaInformation from calibre.ebooks.metadata.opf2 import OPF def get_metadata(stream): @@ -16,7 +15,7 @@ def get_metadata(stream): src = litfile.get_metadata().encode('utf-8') litfile = litfile._litfile opf = OPF(cStringIO.StringIO(src), os.getcwd()) - mi = MetaInformation(opf) + mi = opf.to_book_metadata() covers = [] for item in opf.iterguide(): if 'cover' not in item.get('type', '').lower(): diff --git a/src/calibre/ebooks/metadata/meta.py b/src/calibre/ebooks/metadata/meta.py index eae8171362..68deca5e10 100644 --- a/src/calibre/ebooks/metadata/meta.py +++ b/src/calibre/ebooks/metadata/meta.py @@ -194,7 +194,7 @@ def opf_metadata(opfpath): try: opf = OPF(f, os.path.dirname(opfpath)) if opf.application_id is not None: - mi = MetaInformation(opf) + mi = opf.to_book_metadata() if hasattr(opf, 'cover') and opf.cover: cpath = os.path.join(os.path.dirname(opfpath), opf.cover) if os.access(cpath, os.R_OK): diff --git a/src/calibre/ebooks/metadata/opf2.py b/src/calibre/ebooks/metadata/opf2.py index 236b2fa18f..96f1fa4832 100644 --- a/src/calibre/ebooks/metadata/opf2.py +++ b/src/calibre/ebooks/metadata/opf2.py @@ -530,7 +530,7 @@ class OPF(object): # {{{ self.read_user_metadata() def read_user_metadata(self): - self.user_metadata = {} + self._user_metadata_ = {} from calibre.utils.config import from_json elems = self.root.xpath('//*[name() = "meta" and starts-with(@name,' '"calibre:user_metadata:") and @content]') @@ -547,14 +547,21 @@ class OPF(object): # {{{ import traceback traceback.print_exc() continue - self.user_metadata[name] = fm + self._user_metadata_[name] = fm + def to_book_metadata(self): + ans = MetaInformation(self) + for n, v in self._user_metadata_.items(): + ans.set_user_metadata(n, v) + return ans def write_user_metadata(self): - for elem in self.user_metadata_path(self.root): + elems = self.root.xpath('//*[name() = "meta" and starts-with(@name,' + '"calibre:user_metadata:") and @content]') + for elem in elems: elem.getparent().remove(elem) serialize_user_metadata(self.metadata, - self.user_metadata) + self._user_metadata_) def find_toc(self): self.toc = None @@ -983,6 +990,9 @@ class OPF(object): # {{{ val = getattr(mi, attr, None) if val is not None and val != [] and val != (None, None): setattr(self, attr, val) + temp = self.to_book_metadata() + temp.smart_update(mi, replace_metadata=replace_metadata) + self._user_metadata_ = temp.get_all_user_metadata(True) # }}} @@ -1417,9 +1427,9 @@ def test_user_metadata(): opf = OPF(f) f2 = StringIO(raw2) opf2 = OPF(f2) - assert um == opf.user_metadata - assert um == opf2.user_metadata - print raw + assert um == opf._user_metadata_ + assert um == opf2._user_metadata_ + print opf.render() if __name__ == '__main__': test_user_metadata() diff --git a/src/calibre/ebooks/mobi/reader.py b/src/calibre/ebooks/mobi/reader.py index 2a35c7cb45..6a44c2aa77 100644 --- a/src/calibre/ebooks/mobi/reader.py +++ b/src/calibre/ebooks/mobi/reader.py @@ -441,7 +441,7 @@ class MobiReader(object): html.tostring(elem, encoding='utf-8') + '' stream = cStringIO.StringIO(raw) opf = OPF(stream) - self.embedded_mi = MetaInformation(opf) + self.embedded_mi = opf.to_book_metadata() if guide is not None: for ref in guide.xpath('descendant::reference'): if 'cover' in ref.get('type', '').lower(): diff --git a/src/calibre/ebooks/oeb/reader.py b/src/calibre/ebooks/oeb/reader.py index d7d7bbf725..559421326c 100644 --- a/src/calibre/ebooks/oeb/reader.py +++ b/src/calibre/ebooks/oeb/reader.py @@ -126,10 +126,9 @@ class OEBReader(object): def _metadata_from_opf(self, opf): from calibre.ebooks.metadata.opf2 import OPF - from calibre.ebooks.metadata import MetaInformation from calibre.ebooks.oeb.transforms.metadata import meta_info_to_oeb_metadata stream = cStringIO.StringIO(etree.tostring(opf)) - mi = MetaInformation(OPF(stream)) + mi = OPF(stream).to_book_metadata() if not mi.language: mi.language = get_lang().replace('_', '-') self.oeb.metadata.add('language', mi.language) diff --git a/src/calibre/gui2/add.py b/src/calibre/gui2/add.py index 5b9fb35be3..9f246aeb93 100644 --- a/src/calibre/gui2/add.py +++ b/src/calibre/gui2/add.py @@ -138,7 +138,7 @@ class DBAdder(Thread): # {{{ self.critical[name] = open(opf, 'rb').read().decode('utf-8', 'replace') else: try: - mi = MetaInformation(OPF(opf)) + mi = OPF(opf).to_book_metadata() except: import traceback mi = MetaInformation('', [_('Unknown')]) diff --git a/src/calibre/library/cli.py b/src/calibre/library/cli.py index 9a2d0b0a62..cd4e472807 100644 --- a/src/calibre/library/cli.py +++ b/src/calibre/library/cli.py @@ -448,7 +448,7 @@ def command_show_metadata(args, dbpath): return 0 def do_set_metadata(db, id, stream): - mi = OPF(stream) + mi = OPF(stream).to_book_metadata() db.set_metadata(id, mi) db.clean() do_show_metadata(db, id, False)