From 682bf119d0ad77c5a85226cf4a683b9d96724466 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 21 Jan 2011 10:58:31 -0700 Subject: [PATCH] When converting books in the calibre GUI, override metadata from the input document. So if you have removed all the tags and comments in the calibre GUI for the book in the calibre GUI, but the actual file that is being converted still has tags and comments, they are ignored. This affects only conversions in the calibre GUI, not from the command line via ebook-convert. Fixes #8390 ("comments" still showing up on inserted metadata page, despite deleting the "comments") --- src/calibre/ebooks/conversion/plumber.py | 7 +++-- src/calibre/ebooks/oeb/transforms/metadata.py | 28 +++++++++++++++++-- src/calibre/gui2/convert/gui_conversion.py | 11 ++++++-- src/calibre/gui2/tools.py | 4 +-- src/calibre/utils/ipc/worker.py | 3 ++ 5 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/calibre/ebooks/conversion/plumber.py b/src/calibre/ebooks/conversion/plumber.py index 908ca6a493..dd527ea0b5 100644 --- a/src/calibre/ebooks/conversion/plumber.py +++ b/src/calibre/ebooks/conversion/plumber.py @@ -72,7 +72,8 @@ class Plumber(object): ] def __init__(self, input, output, log, report_progress=DummyReporter(), - dummy=False, merge_plugin_recs=True, abort_after_input_dump=False): + dummy=False, merge_plugin_recs=True, abort_after_input_dump=False, + override_input_metadata=False): ''' :param input: Path to input file. :param output: Path to output file/directory @@ -87,6 +88,7 @@ class Plumber(object): self.log = log self.ui_reporter = report_progress self.abort_after_input_dump = abort_after_input_dump + self.override_input_metadata = override_input_metadata # Pipeline options {{{ # Initialize the conversion options that are independent of input and @@ -924,7 +926,8 @@ OptionRecommendation(name='sr3_replace', self.opts.dest = self.opts.output_profile from calibre.ebooks.oeb.transforms.metadata import MergeMetadata - MergeMetadata()(self.oeb, self.user_metadata, self.opts) + MergeMetadata()(self.oeb, self.user_metadata, self.opts, + override_input_metadata=self.override_input_metadata) pr(0.2) self.flush() diff --git a/src/calibre/ebooks/oeb/transforms/metadata.py b/src/calibre/ebooks/oeb/transforms/metadata.py index 4bb25f650e..dc52f3298c 100644 --- a/src/calibre/ebooks/oeb/transforms/metadata.py +++ b/src/calibre/ebooks/oeb/transforms/metadata.py @@ -10,7 +10,7 @@ import os from calibre.utils.date import isoformat, now from calibre import guess_type -def meta_info_to_oeb_metadata(mi, m, log): +def meta_info_to_oeb_metadata(mi, m, log, override_input_metadata=False): from calibre.ebooks.oeb.base import OPF if not mi.is_null('title'): m.clear('title') @@ -29,15 +29,23 @@ def meta_info_to_oeb_metadata(mi, m, log): if not mi.is_null('book_producer'): m.filter('contributor', lambda x : x.role.lower() == 'bkp') m.add('contributor', mi.book_producer, role='bkp') + elif override_input_metadata: + m.filter('contributor', lambda x : x.role.lower() == 'bkp') if not mi.is_null('comments'): m.clear('description') m.add('description', mi.comments) + elif override_input_metadata: + m.clear('description') if not mi.is_null('publisher'): m.clear('publisher') m.add('publisher', mi.publisher) + elif override_input_metadata: + m.clear('publisher') if not mi.is_null('series'): m.clear('series') m.add('series', mi.series) + elif override_input_metadata: + m.clear('series') if not mi.is_null('isbn'): has = False for x in m.identifier: @@ -46,19 +54,27 @@ def meta_info_to_oeb_metadata(mi, m, log): has = True if not has: m.add('identifier', mi.isbn, scheme='ISBN') + elif override_input_metadata: + m.filter('identifier', lambda x: x.scheme.lower() == 'isbn') if not mi.is_null('language'): m.clear('language') m.add('language', mi.language) if not mi.is_null('series_index'): m.clear('series_index') m.add('series_index', mi.format_series_index()) + elif override_input_metadata: + m.clear('series_index') if not mi.is_null('rating'): m.clear('rating') m.add('rating', '%.2f'%mi.rating) + elif override_input_metadata: + m.clear('rating') if not mi.is_null('tags'): m.clear('subject') for t in mi.tags: m.add('subject', t) + elif override_input_metadata: + m.clear('subject') if not mi.is_null('pubdate'): m.clear('date') m.add('date', isoformat(mi.pubdate)) @@ -68,9 +84,14 @@ def meta_info_to_oeb_metadata(mi, m, log): if not mi.is_null('rights'): m.clear('rights') m.add('rights', mi.rights) + elif override_input_metadata: + m.clear('rights') if not mi.is_null('publication_type'): m.clear('publication_type') m.add('publication_type', mi.publication_type) + elif override_input_metadata: + m.clear('publication_type') + if not m.timestamp: m.add('timestamp', isoformat(now())) @@ -78,11 +99,12 @@ def meta_info_to_oeb_metadata(mi, m, log): class MergeMetadata(object): 'Merge in user metadata, including cover' - def __call__(self, oeb, mi, opts): + def __call__(self, oeb, mi, opts, override_input_metadata=False): self.oeb, self.log = oeb, oeb.log m = self.oeb.metadata self.log('Merging user specified metadata...') - meta_info_to_oeb_metadata(mi, m, oeb.log) + meta_info_to_oeb_metadata(mi, m, oeb.log, + override_input_metadata=override_input_metadata) cover_id = self.set_cover(mi, opts.prefer_metadata_cover) m.clear('cover') if cover_id is not None: diff --git a/src/calibre/gui2/convert/gui_conversion.py b/src/calibre/gui2/convert/gui_conversion.py index d1e1270924..ce51d4ca77 100644 --- a/src/calibre/gui2/convert/gui_conversion.py +++ b/src/calibre/gui2/convert/gui_conversion.py @@ -12,17 +12,24 @@ from calibre.customize.ui import plugin_for_catalog_format from calibre.utils.logging import Log def gui_convert(input, output, recommendations, notification=DummyReporter(), - abort_after_input_dump=False, log=None): + abort_after_input_dump=False, log=None, override_input_metadata=False): recommendations = list(recommendations) recommendations.append(('verbose', 2, OptionRecommendation.HIGH)) if log is None: log = Log() plumber = Plumber(input, output, log, report_progress=notification, - abort_after_input_dump=abort_after_input_dump) + abort_after_input_dump=abort_after_input_dump, + override_input_metadata=override_input_metadata) plumber.merge_ui_recommendations(recommendations) plumber.run() +def gui_convert_override(input, output, recommendations, notification=DummyReporter(), + abort_after_input_dump=False, log=None): + gui_convert(input, output, recommendations, notification=notification, + abort_after_input_dump=abort_after_input_dump, log=log, + override_input_metadata=True) + def gui_catalog(fmt, title, dbspec, ids, out_file_name, sync, fmt_options, connected_device, notification=DummyReporter(), log=None): if log is None: diff --git a/src/calibre/gui2/tools.py b/src/calibre/gui2/tools.py index a5f0f52425..50c384b24c 100644 --- a/src/calibre/gui2/tools.py +++ b/src/calibre/gui2/tools.py @@ -75,7 +75,7 @@ def convert_single_ebook(parent, db, book_ids, auto_conversion=False, out_format temp_files.append(d.cover_file) args = [in_file, out_file.name, recs] temp_files.append(out_file) - jobs.append(('gui_convert', args, desc, d.output_format.upper(), book_id, temp_files)) + jobs.append(('gui_convert_override', args, desc, d.output_format.upper(), book_id, temp_files)) changed = True d.break_cycles() @@ -185,7 +185,7 @@ class QueueBulk(QProgressDialog): args = [in_file, out_file.name, lrecs] temp_files.append(out_file) - self.jobs.append(('gui_convert', args, desc, self.output_format.upper(), book_id, temp_files)) + self.jobs.append(('gui_convert_override', args, desc, self.output_format.upper(), book_id, temp_files)) self.changed = True self.setValue(self.i) diff --git a/src/calibre/utils/ipc/worker.py b/src/calibre/utils/ipc/worker.py index d8ffad7c53..e187235a9e 100644 --- a/src/calibre/utils/ipc/worker.py +++ b/src/calibre/utils/ipc/worker.py @@ -28,6 +28,9 @@ PARALLEL_FUNCS = { 'gui_convert' : ('calibre.gui2.convert.gui_conversion', 'gui_convert', 'notification'), + 'gui_convert_override' : + ('calibre.gui2.convert.gui_conversion', 'gui_convert_override', 'notification'), + 'gui_catalog' : ('calibre.gui2.convert.gui_conversion', 'gui_catalog', 'notification'),