From 8c060c57c25be580067328e256a1111643e5afe0 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 26 Jun 2018 13:52:27 +0530 Subject: [PATCH] Refactor GUI conversion widget classes Make the conversion option groups re-sueable in the server --- src/calibre/ebooks/conversion/config.py | 140 ++++++++++++++++-- src/calibre/ebooks/conversion/plumber.py | 21 +++ src/calibre/gui2/convert/__init__.py | 2 +- src/calibre/gui2/convert/azw3_output.py | 8 +- src/calibre/gui2/convert/comic_input.py | 9 +- src/calibre/gui2/convert/debug.py | 9 +- src/calibre/gui2/convert/docx_input.py | 4 +- src/calibre/gui2/convert/docx_output.py | 7 +- src/calibre/gui2/convert/epub_output.py | 8 +- src/calibre/gui2/convert/fb2_input.py | 4 +- src/calibre/gui2/convert/fb2_output.py | 3 +- src/calibre/gui2/convert/heuristics.py | 10 +- src/calibre/gui2/convert/htmlz_output.py | 4 +- src/calibre/gui2/convert/look_and_feel.py | 21 +-- src/calibre/gui2/convert/lrf_output.py | 9 +- src/calibre/gui2/convert/metadata.py | 3 +- src/calibre/gui2/convert/mobi_output.py | 9 +- src/calibre/gui2/convert/page_setup.py | 6 +- src/calibre/gui2/convert/pdb_output.py | 3 +- src/calibre/gui2/convert/pdf_input.py | 4 +- src/calibre/gui2/convert/pdf_output.py | 11 +- src/calibre/gui2/convert/pml_output.py | 4 +- src/calibre/gui2/convert/rb_output.py | 3 +- src/calibre/gui2/convert/rtf_input.py | 4 +- .../gui2/convert/search_and_replace.py | 8 +- src/calibre/gui2/convert/single.py | 11 +- src/calibre/gui2/convert/snb_output.py | 5 +- .../gui2/convert/structure_detection.py | 7 +- src/calibre/gui2/convert/toc.py | 8 +- src/calibre/gui2/convert/txt_input.py | 5 +- src/calibre/gui2/convert/txt_output.py | 6 +- 31 files changed, 205 insertions(+), 151 deletions(-) diff --git a/src/calibre/ebooks/conversion/config.py b/src/calibre/ebooks/conversion/config.py index 4af7ccaeb1..99db033b03 100644 --- a/src/calibre/ebooks/conversion/config.py +++ b/src/calibre/ebooks/conversion/config.py @@ -45,20 +45,6 @@ def load_defaults(name): return r -def load_all_defaults(): - ans = {} - for x in os.listdir(config_dir): - if x.endswith('.py'): - path = os.path.join(config_dir, x) - with ExclusiveFile(path) as f: - raw = f.read() - r = GuiRecommendations() - if raw: - r.deserialize(raw) - ans[os.path.splitext(x)[0]] = r.copy() - return ans - - def save_specifics(db, book_id, recs): raw = recs.serialize() db.set_conversion_options(book_id, 'PIPE', raw) @@ -81,7 +67,7 @@ class GuiRecommendations(dict): def __new__(cls, *args): dict.__new__(cls) obj = super(GuiRecommendations, cls).__new__(cls, *args) - obj.disabled_options = set([]) + obj.disabled_options = set() return obj def to_recommendations(self, level=OptionRecommendation.LOW): @@ -130,6 +116,12 @@ class GuiRecommendations(dict): elif opt.level > level or name not in self: self[name] = opt.recommended_value + def as_dict(self): + return { + 'options': self.copy(), + 'disabled': tuple(self.disabled_options) + } + def get_available_formats_for_book(db, book_id): available_formats = db.new_api.formats(book_id) @@ -184,7 +176,8 @@ def get_input_format_for_book(db, book_id, pref=None): pref = pref.lower() input_formats = get_supported_input_formats_for_book(db, book_id) input_format = pref if pref in input_formats else \ - sort_formats_by_preference(input_formats, prefs['input_format_order'])[0] + sort_formats_by_preference( + input_formats, prefs['input_format_order'])[0] return input_format, input_formats @@ -212,3 +205,118 @@ def get_sorted_output_formats(): pass fmts.insert(0, preferred_output_format) return fmts + + +OPTIONS = { + 'input': { + 'comic': ( + 'colors', 'dont_normalize', 'keep_aspect_ratio', 'right2left', 'despeckle', 'no_sort', 'no_process', 'landscape', + 'dont_sharpen', 'disable_trim', 'wide', 'output_format', 'dont_grayscale', 'comic_image_size', 'dont_add_comic_pages_to_toc'), + + 'docx': ('docx_no_cover', 'docx_no_pagebreaks_between_notes', 'docx_inline_subsup'), + + 'fb2': ('no_inline_fb2_toc',), + + 'pdf': ('no_images', 'unwrap_factor'), + + 'rtf': ('ignore_wmf',), + + 'txt': ('paragraph_type', 'formatting_type', 'markdown_extensions', 'preserve_spaces', 'txt_in_remove_indents'), + }, + + 'pipe': { + 'debug': ('debug_pipeline',), + + 'heuristics': ( + 'enable_heuristics', 'markup_chapter_headings', + 'italicize_common_cases', 'fix_indents', 'html_unwrap_factor', + 'unwrap_lines', 'delete_blank_paragraphs', 'format_scene_breaks', + 'replace_scene_breaks', 'dehyphenate', 'renumber_headings'), + + 'look_and_feel': ( + 'change_justification', 'extra_css', 'base_font_size', + 'font_size_mapping', 'line_height', 'minimum_line_height', + 'embed_font_family', 'embed_all_fonts', 'subset_embedded_fonts', + 'smarten_punctuation', 'unsmarten_punctuation', + 'disable_font_rescaling', 'insert_blank_line', + 'remove_paragraph_spacing', 'remove_paragraph_spacing_indent_size', + 'insert_blank_line_size', 'input_encoding', 'filter_css', + 'expand_css', 'asciiize', 'keep_ligatures', 'linearize_tables', + 'transform_css_rules'), + + 'metadata': ('prefer_metadata_cover',), + + 'page_setup': ( + 'margin_top', 'margin_left', 'margin_right', 'margin_bottom', + 'input_profile', 'output_profile'), + + 'search_and_replace': ( + 'search_replace', 'sr1_search', 'sr1_replace', 'sr2_search', 'sr2_replace', 'sr3_search', 'sr3_replace'), + + 'structure_detection': ( + 'chapter', 'chapter_mark', 'start_reading_at', + 'remove_first_image', 'remove_fake_margins', 'insert_metadata', + 'page_breaks_before'), + + 'toc': ( + 'level1_toc', 'level2_toc', 'level3_toc', + 'toc_threshold', 'max_toc_links', 'no_chapters_in_toc', + 'use_auto_toc', 'toc_filter', 'duplicate_links_in_toc',), + }, + + 'output': { + 'azw3': ('prefer_author_sort', 'toc_title', 'mobi_toc_at_start', 'dont_compress', 'no_inline_toc', 'share_not_sync',), + + 'docx': ( + 'docx_page_size', 'docx_custom_page_size', 'docx_no_cover', 'docx_no_toc', + 'docx_page_margin_left', 'docx_page_margin_top', 'docx_page_margin_right', + 'docx_page_margin_bottom', 'preserve_cover_aspect_ratio',), + + 'epub': ( + 'dont_split_on_page_breaks', 'flow_size', 'no_default_epub_cover', + 'no_svg_cover', 'epub_inline_toc', 'epub_toc_at_end', 'toc_title', + 'preserve_cover_aspect_ratio', 'epub_flatten', 'epub_version'), + + 'fb2': ('sectionize', 'fb2_genre'), + + 'htmlz': ('htmlz_css_type', 'htmlz_class_style', 'htmlz_title_filename'), + + 'lrf': ( + 'wordspace', 'header', 'header_format', 'minimum_indent', + 'serif_family', 'render_tables_as_images', 'sans_family', + 'mono_family', 'text_size_multiplier_for_rendered_tables', + 'autorotation', 'header_separation', 'minimum_indent'), + + 'mobi': ( + 'prefer_author_sort', 'toc_title', 'mobi_keep_original_images', + 'mobi_ignore_margins', 'mobi_toc_at_start', 'dont_compress', + 'no_inline_toc', 'share_not_sync', 'personal_doc', + 'mobi_file_type'), + + 'pdb': ('format', 'inline_toc', 'pdb_output_encoding'), + + 'pdf': ( + 'use_profile_size', 'paper_size', 'custom_size', 'pdf_hyphenate', + 'preserve_cover_aspect_ratio', 'pdf_serif_family', 'unit', + 'pdf_sans_family', 'pdf_mono_family', 'pdf_standard_font', + 'pdf_default_font_size', 'pdf_mono_font_size', 'pdf_page_numbers', + 'pdf_footer_template', 'pdf_header_template', 'pdf_add_toc', + 'toc_title', 'pdf_page_margin_left', 'pdf_page_margin_top', + 'pdf_page_margin_right', 'pdf_page_margin_bottom', + 'pdf_use_document_margins',), + + 'pmlz': ('inline_toc', 'full_image_depth', 'pml_output_encoding'), + + 'rb': ('inline_toc',), + + 'snb': ( + 'snb_insert_empty_line', 'snb_dont_indent_first_line', + 'snb_hide_chapter_name','snb_full_screen'), + + 'txt': ( + 'newline', 'max_line_length', 'force_max_line_length', + 'inline_toc', 'txt_output_formatting', 'keep_links', 'keep_image_references', + 'keep_color', 'txt_output_encoding'), + }, +} +OPTIONS['output']['txtz'] = OPTIONS['output']['txt'] diff --git a/src/calibre/ebooks/conversion/plumber.py b/src/calibre/ebooks/conversion/plumber.py index a361b6be2f..7a50146096 100644 --- a/src/calibre/ebooks/conversion/plumber.py +++ b/src/calibre/ebooks/conversion/plumber.py @@ -828,6 +828,14 @@ OptionRecommendation(name='search_replace', return f, os.path.splitext(f)[1].lower()[1:] return html_files[-1], os.path.splitext(html_files[-1])[1].lower()[1:] + def get_all_options(self): + ans = {} + for group in (self.input_options, self.pipeline_options, + self.output_options, self.all_format_options): + for rec in group: + ans[rec.option] = rec.recommended_value + return ans + def get_option_by_name(self, name): for group in (self.input_options, self.pipeline_options, self.output_options, self.all_format_options): @@ -1292,3 +1300,16 @@ def create_oebbook(log, path_or_stream, opts, reader=None, reader()(oeb, path_or_stream) return oeb + + +def create_dummy_plumber(input_format, output_format): + from calibre.utils.logging import Log + input_format = input_format.lower() + output_format = output_format.lower() + output_path = 'dummy.'+output_format + log = Log() + log.outputs = [] + input_file = 'dummy.'+input_format + if input_format in ARCHIVE_FMTS: + input_file = 'dummy.html' + return Plumber(input_file, output_path, log) diff --git a/src/calibre/gui2/convert/__init__.py b/src/calibre/gui2/convert/__init__.py index ec534de059..e7f5aec12e 100644 --- a/src/calibre/gui2/convert/__init__.py +++ b/src/calibre/gui2/convert/__init__.py @@ -61,6 +61,7 @@ class Widget(QWidget): set_help_signal = pyqtSignal(object) def __init__(self, parent, options): + options = list(options) QWidget.__init__(self, parent) self.setupUi(self) self._options = options @@ -304,4 +305,3 @@ class Widget(QWidget): def config_icon(self): return self._icon - diff --git a/src/calibre/gui2/convert/azw3_output.py b/src/calibre/gui2/convert/azw3_output.py index 8d2c3561f0..48de1823ab 100644 --- a/src/calibre/gui2/convert/azw3_output.py +++ b/src/calibre/gui2/convert/azw3_output.py @@ -9,6 +9,7 @@ __docformat__ = 'restructuredtext en' from calibre.gui2.convert.azw3_output_ui import Ui_Form from calibre.gui2.convert import Widget +from calibre.ebooks.conversion.config import OPTIONS font_family_model = None @@ -21,12 +22,7 @@ class PluginWidget(Widget, Ui_Form): ICON = I('mimetypes/azw3.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): - Widget.__init__(self, parent, - ['prefer_author_sort', 'toc_title', - 'mobi_toc_at_start', - 'dont_compress', 'no_inline_toc', 'share_not_sync', - ] - ) + Widget.__init__(self, parent, OPTIONS['output']['azw3']) self.db, self.book_id = db, book_id self.initialize_options(get_option, get_help, db, book_id) diff --git a/src/calibre/gui2/convert/comic_input.py b/src/calibre/gui2/convert/comic_input.py index 0fe3a3722d..9309e67888 100644 --- a/src/calibre/gui2/convert/comic_input.py +++ b/src/calibre/gui2/convert/comic_input.py @@ -9,6 +9,7 @@ __docformat__ = 'restructuredtext en' from calibre.gui2.convert.comic_input_ui import Ui_Form from calibre.gui2.convert import Widget +from calibre.ebooks.conversion.config import OPTIONS class PluginWidget(Widget, Ui_Form): @@ -19,13 +20,7 @@ class PluginWidget(Widget, Ui_Form): ICON = I('mimetypes/png.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): - Widget.__init__(self, parent, - ['colors', 'dont_normalize', 'keep_aspect_ratio', 'right2left', - 'despeckle', 'no_sort', 'no_process', 'landscape', - 'dont_sharpen', 'disable_trim', 'wide', 'output_format', - 'dont_grayscale', 'comic_image_size', - 'dont_add_comic_pages_to_toc'] - ) + Widget.__init__(self, parent, OPTIONS['input']['comic']) self.db, self.book_id = db, book_id for x in get_option('output_format').option.choices: self.opt_output_format.addItem(x) diff --git a/src/calibre/gui2/convert/debug.py b/src/calibre/gui2/convert/debug.py index 556e2fb7d8..ab1eae308c 100644 --- a/src/calibre/gui2/convert/debug.py +++ b/src/calibre/gui2/convert/debug.py @@ -11,6 +11,7 @@ import os from calibre.gui2.convert.debug_ui import Ui_Form from calibre.gui2.convert import Widget from calibre.gui2 import error_dialog, choose_dir +from calibre.ebooks.conversion.config import OPTIONS class DebugWidget(Widget, Ui_Form): @@ -21,9 +22,7 @@ class DebugWidget(Widget, Ui_Form): COMMIT_NAME = 'debug' def __init__(self, parent, get_option, get_help, db=None, book_id=None): - Widget.__init__(self, parent, - ['debug_pipeline'] - ) + Widget.__init__(self, parent, OPTIONS['pipe']['debug']) self.db, self.book_id = db, book_id self.initialize_options(get_option, get_help, db, book_id) self.button_debug_dir.clicked.connect(self.set_debug_dir) @@ -53,9 +52,7 @@ class DebugWidget(Widget, Ui_Form): import traceback det_msg = traceback.format_exc() error_dialog(self, _('Invalid debug directory'), - _('Failed to create debug directory')+': '+ - unicode(self.opt_debug_pipeline.text()), + _('Failed to create debug directory')+': '+ unicode(self.opt_debug_pipeline.text()), det_msg=det_msg, show=True) return False return True - diff --git a/src/calibre/gui2/convert/docx_input.py b/src/calibre/gui2/convert/docx_input.py index d148687eff..e39a0d1c9f 100644 --- a/src/calibre/gui2/convert/docx_input.py +++ b/src/calibre/gui2/convert/docx_input.py @@ -8,6 +8,7 @@ __copyright__ = '2013, Kovid Goyal ' from calibre.gui2.convert.docx_input_ui import Ui_Form from calibre.gui2.convert import Widget +from calibre.ebooks.conversion.config import OPTIONS class PluginWidget(Widget, Ui_Form): @@ -18,6 +19,5 @@ class PluginWidget(Widget, Ui_Form): ICON = I('mimetypes/docx.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): - Widget.__init__(self, parent, - ['docx_no_cover', 'docx_no_pagebreaks_between_notes', 'docx_inline_subsup']) + Widget.__init__(self, parent, OPTIONS['input']['docx']) self.initialize_options(get_option, get_help, db, book_id) diff --git a/src/calibre/gui2/convert/docx_output.py b/src/calibre/gui2/convert/docx_output.py index 07d20615a5..1c8eef00ea 100644 --- a/src/calibre/gui2/convert/docx_output.py +++ b/src/calibre/gui2/convert/docx_output.py @@ -7,6 +7,7 @@ __docformat__ = 'restructuredtext en' from PyQt5.Qt import QFormLayout, QComboBox, QCheckBox, QLineEdit, QDoubleSpinBox, QSizePolicy from calibre.gui2.convert import Widget +from calibre.ebooks.conversion.config import OPTIONS paper_size_model = None orientation_model = None @@ -20,11 +21,7 @@ class PluginWidget(Widget): ICON = I('mimetypes/docx.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): - Widget.__init__(self, parent, [ - 'docx_page_size', 'docx_custom_page_size', 'docx_no_cover', 'docx_no_toc', - 'docx_page_margin_left', 'docx_page_margin_top', 'docx_page_margin_right', - 'docx_page_margin_bottom', 'preserve_cover_aspect_ratio', - ]) + Widget.__init__(self, parent, OPTIONS['output']['docx']) for x in get_option('docx_page_size').option.choices: self.opt_docx_page_size.addItem(x) diff --git a/src/calibre/gui2/convert/epub_output.py b/src/calibre/gui2/convert/epub_output.py index c7e78ac665..08d1eb38cf 100644 --- a/src/calibre/gui2/convert/epub_output.py +++ b/src/calibre/gui2/convert/epub_output.py @@ -9,6 +9,7 @@ __docformat__ = 'restructuredtext en' from calibre.gui2.convert.epub_output_ui import Ui_Form from calibre.gui2.convert import Widget +from calibre.ebooks.conversion.config import OPTIONS class PluginWidget(Widget, Ui_Form): @@ -19,12 +20,7 @@ class PluginWidget(Widget, Ui_Form): ICON = I('mimetypes/epub.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): - Widget.__init__(self, parent, - ['dont_split_on_page_breaks', 'flow_size', - 'no_default_epub_cover', 'no_svg_cover', - 'epub_inline_toc', 'epub_toc_at_end', 'toc_title', - 'preserve_cover_aspect_ratio', 'epub_flatten', 'epub_version'] - ) + Widget.__init__(self, parent, OPTIONS['output']['epub']) for i in range(2): self.opt_no_svg_cover.toggle() ev = get_option('epub_version') diff --git a/src/calibre/gui2/convert/fb2_input.py b/src/calibre/gui2/convert/fb2_input.py index 4ef8831a47..14aee997a5 100644 --- a/src/calibre/gui2/convert/fb2_input.py +++ b/src/calibre/gui2/convert/fb2_input.py @@ -6,6 +6,7 @@ __docformat__ = 'restructuredtext en' from calibre.gui2.convert.fb2_input_ui import Ui_Form from calibre.gui2.convert import Widget +from calibre.ebooks.conversion.config import OPTIONS class PluginWidget(Widget, Ui_Form): @@ -16,7 +17,6 @@ class PluginWidget(Widget, Ui_Form): ICON = I('mimetypes/fb2.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): - Widget.__init__(self, parent, - ['no_inline_fb2_toc']) + Widget.__init__(self, parent, OPTIONS['input']['fb2']) self.db, self.book_id = db, book_id self.initialize_options(get_option, get_help, db, book_id) diff --git a/src/calibre/gui2/convert/fb2_output.py b/src/calibre/gui2/convert/fb2_output.py index 6c381a7834..57f21e1539 100644 --- a/src/calibre/gui2/convert/fb2_output.py +++ b/src/calibre/gui2/convert/fb2_output.py @@ -6,6 +6,7 @@ __docformat__ = 'restructuredtext en' from calibre.gui2.convert.fb2_output_ui import Ui_Form from calibre.gui2.convert import Widget +from calibre.ebooks.conversion.config import OPTIONS format_model = None @@ -18,7 +19,7 @@ class PluginWidget(Widget, Ui_Form): ICON = I('mimetypes/fb2.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): - Widget.__init__(self, parent, ['sectionize', 'fb2_genre']) + Widget.__init__(self, parent, OPTIONS['output']['fb2']) self.db, self.book_id = db, book_id for x in ('toc', 'files', 'nothing'): self.opt_sectionize.addItem(x) diff --git a/src/calibre/gui2/convert/heuristics.py b/src/calibre/gui2/convert/heuristics.py index 8a0d0e7170..9cab0fb452 100644 --- a/src/calibre/gui2/convert/heuristics.py +++ b/src/calibre/gui2/convert/heuristics.py @@ -10,6 +10,7 @@ from calibre.gui2 import gprefs from calibre.gui2.convert.heuristics_ui import Ui_Form from calibre.gui2.convert import Widget from calibre.utils.localization import localize_user_manual_link +from calibre.ebooks.conversion.config import OPTIONS class HeuristicsWidget(Widget, Ui_Form): @@ -20,14 +21,7 @@ class HeuristicsWidget(Widget, Ui_Form): ICON = I('heuristics.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): - Widget.__init__(self, parent, - ['enable_heuristics', 'markup_chapter_headings', - 'italicize_common_cases', 'fix_indents', - 'html_unwrap_factor', 'unwrap_lines', - 'delete_blank_paragraphs', - 'format_scene_breaks', 'replace_scene_breaks', - 'dehyphenate', 'renumber_headings'] - ) + Widget.__init__(self, parent, OPTIONS['pipe']['heuristics']) self.db, self.book_id = db, book_id self.rssb_defaults = [u'', u'
', u'∗ ∗ ∗', u'• • •', u'♦ ♦ ♦', u'† †', u'‡ ‡ ‡', u'∞ ∞ ∞', u'¤ ¤ ¤', u'§'] diff --git a/src/calibre/gui2/convert/htmlz_output.py b/src/calibre/gui2/convert/htmlz_output.py index 53fdc3b029..0e49239bcc 100644 --- a/src/calibre/gui2/convert/htmlz_output.py +++ b/src/calibre/gui2/convert/htmlz_output.py @@ -6,6 +6,7 @@ __docformat__ = 'restructuredtext en' from calibre.gui2.convert.htmlz_output_ui import Ui_Form from calibre.gui2.convert import Widget +from calibre.ebooks.conversion.config import OPTIONS format_model = None @@ -18,8 +19,7 @@ class PluginWidget(Widget, Ui_Form): ICON = I('mimetypes/html.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): - Widget.__init__(self, parent, ['htmlz_css_type', 'htmlz_class_style', - 'htmlz_title_filename']) + Widget.__init__(self, parent, OPTIONS['output']['htmlz']) self.db, self.book_id = db, book_id for x in get_option('htmlz_css_type').option.choices: self.opt_htmlz_css_type.addItem(x) diff --git a/src/calibre/gui2/convert/look_and_feel.py b/src/calibre/gui2/convert/look_and_feel.py index f8fe98cf08..565d0f5df4 100644 --- a/src/calibre/gui2/convert/look_and_feel.py +++ b/src/calibre/gui2/convert/look_and_feel.py @@ -12,6 +12,7 @@ from PyQt5.Qt import Qt from calibre.gui2.convert.look_and_feel_ui import Ui_Form from calibre.gui2.convert import Widget +from calibre.ebooks.conversion.config import OPTIONS class LookAndFeelWidget(Widget, Ui_Form): @@ -32,19 +33,7 @@ class LookAndFeelWidget(Widget, Ui_Form): } def __init__(self, parent, get_option, get_help, db=None, book_id=None): - Widget.__init__(self, parent, - ['change_justification', 'extra_css', 'base_font_size', - 'font_size_mapping', 'line_height', 'minimum_line_height', - 'embed_font_family', 'embed_all_fonts', 'subset_embedded_fonts', - 'smarten_punctuation', 'unsmarten_punctuation', - 'disable_font_rescaling', 'insert_blank_line', - 'remove_paragraph_spacing', - 'remove_paragraph_spacing_indent_size', - 'insert_blank_line_size', - 'input_encoding', 'filter_css', 'expand_css', - 'asciiize', 'keep_ligatures', - 'linearize_tables', 'transform_css_rules'] - ) + Widget.__init__(self, parent, OPTIONS['pipe']['look_and_feel']) for val, text in [ ('original', _('Original')), ('left', _('Left align')), @@ -59,11 +48,9 @@ class LookAndFeelWidget(Widget, Ui_Form): self.opt_remove_paragraph_spacing.toggle() self.opt_remove_paragraph_spacing.toggle() self.opt_smarten_punctuation.stateChanged.connect( - lambda state: state != Qt.Unchecked and - self.opt_unsmarten_punctuation.setCheckState(Qt.Unchecked)) + lambda state: state != Qt.Unchecked and self.opt_unsmarten_punctuation.setCheckState(Qt.Unchecked)) self.opt_unsmarten_punctuation.stateChanged.connect( - lambda state: state != Qt.Unchecked and - self.opt_smarten_punctuation.setCheckState(Qt.Unchecked)) + lambda state: state != Qt.Unchecked and self.opt_smarten_punctuation.setCheckState(Qt.Unchecked)) def get_value_handler(self, g): if g is self.opt_change_justification: diff --git a/src/calibre/gui2/convert/lrf_output.py b/src/calibre/gui2/convert/lrf_output.py index ae77da53e9..b4e51ab0f1 100644 --- a/src/calibre/gui2/convert/lrf_output.py +++ b/src/calibre/gui2/convert/lrf_output.py @@ -8,6 +8,7 @@ __docformat__ = 'restructuredtext en' from calibre.gui2.convert.lrf_output_ui import Ui_Form from calibre.gui2.convert import Widget +from calibre.ebooks.conversion.config import OPTIONS font_family_model = None @@ -20,13 +21,7 @@ class PluginWidget(Widget, Ui_Form): ICON = I('mimetypes/lrf.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): - Widget.__init__(self, parent, - ['wordspace', 'header', 'header_format', - 'minimum_indent', 'serif_family', - 'render_tables_as_images', 'sans_family', 'mono_family', - 'text_size_multiplier_for_rendered_tables', 'autorotation', - 'header_separation', 'minimum_indent'] - ) + Widget.__init__(self, parent, OPTIONS['output']['lrf']) self.db, self.book_id = db, book_id self.initialize_options(get_option, get_help, db, book_id) diff --git a/src/calibre/gui2/convert/metadata.py b/src/calibre/gui2/convert/metadata.py index cbf5f7acc3..106ee86aff 100644 --- a/src/calibre/gui2/convert/metadata.py +++ b/src/calibre/gui2/convert/metadata.py @@ -20,6 +20,7 @@ from calibre.gui2.convert import Widget from calibre.utils.icu import sort_key from calibre.library.comments import comments_to_html from calibre.utils.config import tweaks +from calibre.ebooks.conversion.config import OPTIONS def create_opf_file(db, book_id, opf_file=None): @@ -55,7 +56,7 @@ class MetadataWidget(Widget, Ui_Form): COMMIT_NAME = 'metadata' def __init__(self, parent, get_option, get_help, db=None, book_id=None): - Widget.__init__(self, parent, ['prefer_metadata_cover']) + Widget.__init__(self, parent, OPTIONS['pipe']['metadata']) self.db, self.book_id = db, book_id self.cover_changed = False self.cover_data = None diff --git a/src/calibre/gui2/convert/mobi_output.py b/src/calibre/gui2/convert/mobi_output.py index 68555c1803..99c2ddb073 100644 --- a/src/calibre/gui2/convert/mobi_output.py +++ b/src/calibre/gui2/convert/mobi_output.py @@ -9,6 +9,7 @@ __docformat__ = 'restructuredtext en' from calibre.gui2.convert.mobi_output_ui import Ui_Form from calibre.gui2.convert import Widget +from calibre.ebooks.conversion.config import OPTIONS font_family_model = None @@ -21,13 +22,7 @@ class PluginWidget(Widget, Ui_Form): ICON = I('mimetypes/mobi.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): - Widget.__init__(self, parent, - ['prefer_author_sort', 'toc_title', - 'mobi_keep_original_images', - 'mobi_ignore_margins', 'mobi_toc_at_start', - 'dont_compress', 'no_inline_toc', 'share_not_sync', - 'personal_doc', 'mobi_file_type'] - ) + Widget.__init__(self, parent, OPTIONS['output']['mobi']) self.db, self.book_id = db, book_id self.opt_mobi_file_type.addItems(['old', 'both', 'new']) diff --git a/src/calibre/gui2/convert/page_setup.py b/src/calibre/gui2/convert/page_setup.py index 723642bd2b..4a1dd1df08 100644 --- a/src/calibre/gui2/convert/page_setup.py +++ b/src/calibre/gui2/convert/page_setup.py @@ -11,6 +11,7 @@ from PyQt5.Qt import Qt, QAbstractListModel, QModelIndex from calibre.gui2.convert.page_setup_ui import Ui_Form from calibre.gui2.convert import Widget from calibre.customize.ui import input_profiles, output_profiles +from calibre.ebooks.conversion.config import OPTIONS class ProfileModel(QAbstractListModel): @@ -44,10 +45,7 @@ class PageSetupWidget(Widget, Ui_Form): def __init__(self, parent, get_option, get_help, db=None, book_id=None): self.__connections = [] - Widget.__init__(self, parent, - ['margin_top', 'margin_left', 'margin_right', 'margin_bottom', - 'input_profile', 'output_profile'] - ) + Widget.__init__(self, parent, OPTIONS['pipe']['page_setup']) self.db, self.book_id = db, book_id self.input_model = ProfileModel(input_profiles()) diff --git a/src/calibre/gui2/convert/pdb_output.py b/src/calibre/gui2/convert/pdb_output.py index a36bb0ae04..a8fc1bf7d6 100644 --- a/src/calibre/gui2/convert/pdb_output.py +++ b/src/calibre/gui2/convert/pdb_output.py @@ -6,6 +6,7 @@ __docformat__ = 'restructuredtext en' from calibre.gui2.convert.pdb_output_ui import Ui_Form from calibre.gui2.convert import Widget +from calibre.ebooks.conversion.config import OPTIONS format_model = None @@ -18,7 +19,7 @@ class PluginWidget(Widget, Ui_Form): ICON = I('mimetypes/unknown.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): - Widget.__init__(self, parent, ['format', 'inline_toc', 'pdb_output_encoding']) + Widget.__init__(self, parent, OPTIONS['output']['pdb']) self.db, self.book_id = db, book_id for x in get_option('format').option.choices: diff --git a/src/calibre/gui2/convert/pdf_input.py b/src/calibre/gui2/convert/pdf_input.py index 672903e80d..c90186217a 100644 --- a/src/calibre/gui2/convert/pdf_input.py +++ b/src/calibre/gui2/convert/pdf_input.py @@ -6,6 +6,7 @@ __docformat__ = 'restructuredtext en' from calibre.gui2.convert.pdf_input_ui import Ui_Form from calibre.gui2.convert import Widget, QDoubleSpinBox +from calibre.ebooks.conversion.config import OPTIONS class PluginWidget(Widget, Ui_Form): @@ -16,8 +17,7 @@ class PluginWidget(Widget, Ui_Form): ICON = I('mimetypes/pdf.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): - Widget.__init__(self, parent, - ['no_images', 'unwrap_factor']) + Widget.__init__(self, parent, OPTIONS['input']['pdf']) self.db, self.book_id = db, book_id self.initialize_options(get_option, get_help, db, book_id) diff --git a/src/calibre/gui2/convert/pdf_output.py b/src/calibre/gui2/convert/pdf_output.py index c1a707b840..72c3d64b8b 100644 --- a/src/calibre/gui2/convert/pdf_output.py +++ b/src/calibre/gui2/convert/pdf_output.py @@ -10,6 +10,7 @@ from PyQt5.Qt import QHBoxLayout, QFormLayout, QDoubleSpinBox, QCheckBox, QVBoxL from calibre.gui2.convert.pdf_output_ui import Ui_Form from calibre.gui2.convert import Widget from calibre.utils.localization import localize_user_manual_link +from calibre.ebooks.conversion.config import OPTIONS paper_size_model = None orientation_model = None @@ -23,15 +24,7 @@ class PluginWidget(Widget, Ui_Form): ICON = I('mimetypes/pdf.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): - Widget.__init__(self, parent, [ - 'use_profile_size', 'paper_size', 'custom_size', 'pdf_hyphenate', - 'preserve_cover_aspect_ratio', 'pdf_serif_family', 'unit', - 'pdf_sans_family', 'pdf_mono_family', 'pdf_standard_font', - 'pdf_default_font_size', 'pdf_mono_font_size', 'pdf_page_numbers', - 'pdf_footer_template', 'pdf_header_template', 'pdf_add_toc', 'toc_title', - 'pdf_page_margin_left', 'pdf_page_margin_top', 'pdf_page_margin_right', 'pdf_page_margin_bottom', - 'pdf_use_document_margins', - ]) + Widget.__init__(self, parent, OPTIONS['output']['pdf']) self.db, self.book_id = db, book_id try: self.hf_label.setText(self.hf_label.text() % localize_user_manual_link( diff --git a/src/calibre/gui2/convert/pml_output.py b/src/calibre/gui2/convert/pml_output.py index 70bcce3048..269b1e57a7 100644 --- a/src/calibre/gui2/convert/pml_output.py +++ b/src/calibre/gui2/convert/pml_output.py @@ -6,6 +6,7 @@ __docformat__ = 'restructuredtext en' from calibre.gui2.convert.pmlz_output_ui import Ui_Form from calibre.gui2.convert import Widget +from calibre.ebooks.conversion.config import OPTIONS format_model = None @@ -18,7 +19,6 @@ class PluginWidget(Widget, Ui_Form): ICON = I('mimetypes/unknown.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): - Widget.__init__(self, parent, ['inline_toc', 'full_image_depth', - 'pml_output_encoding']) + Widget.__init__(self, parent, OPTIONS['output']['pmlz']) self.db, self.book_id = db, book_id self.initialize_options(get_option, get_help, db, book_id) diff --git a/src/calibre/gui2/convert/rb_output.py b/src/calibre/gui2/convert/rb_output.py index c7f3939b2f..90be61edf0 100644 --- a/src/calibre/gui2/convert/rb_output.py +++ b/src/calibre/gui2/convert/rb_output.py @@ -6,6 +6,7 @@ __docformat__ = 'restructuredtext en' from calibre.gui2.convert.rb_output_ui import Ui_Form from calibre.gui2.convert import Widget +from calibre.ebooks.conversion.config import OPTIONS format_model = None @@ -18,6 +19,6 @@ class PluginWidget(Widget, Ui_Form): ICON = I('mimetypes/unknown.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): - Widget.__init__(self, parent, ['inline_toc']) + Widget.__init__(self, parent, OPTIONS['output']['rb']) self.db, self.book_id = db, book_id self.initialize_options(get_option, get_help, db, book_id) diff --git a/src/calibre/gui2/convert/rtf_input.py b/src/calibre/gui2/convert/rtf_input.py index 65f0e7bfb3..27775b9869 100644 --- a/src/calibre/gui2/convert/rtf_input.py +++ b/src/calibre/gui2/convert/rtf_input.py @@ -8,6 +8,7 @@ __copyright__ = '2013, Kovid Goyal ' from calibre.gui2.convert.rtf_input_ui import Ui_Form from calibre.gui2.convert import Widget +from calibre.ebooks.conversion.config import OPTIONS class PluginWidget(Widget, Ui_Form): @@ -18,6 +19,5 @@ class PluginWidget(Widget, Ui_Form): ICON = I('mimetypes/rtf.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): - Widget.__init__(self, parent, - ['ignore_wmf', ]) + Widget.__init__(self, parent, OPTIONS['input']['rtf']) self.initialize_options(get_option, get_help, db, book_id) diff --git a/src/calibre/gui2/convert/search_and_replace.py b/src/calibre/gui2/convert/search_and_replace.py index fbb513ce09..5ef34d1224 100644 --- a/src/calibre/gui2/convert/search_and_replace.py +++ b/src/calibre/gui2/convert/search_and_replace.py @@ -15,6 +15,7 @@ from calibre.gui2 import (error_dialog, question_dialog, choose_files, from calibre import as_unicode from calibre.utils.localization import localize_user_manual_link from calibre.ebooks.conversion.search_replace import compile_regular_expression +from calibre.ebooks.conversion.config import OPTIONS class SearchAndReplaceWidget(Widget, Ui_Form): @@ -35,12 +36,7 @@ class SearchAndReplaceWidget(Widget, Ui_Form): setattr(self, 'opt_'+z, z) self.opt_search_replace = 'search_replace' - Widget.__init__(self, parent, - ['search_replace', - 'sr1_search', 'sr1_replace', - 'sr2_search', 'sr2_replace', - 'sr3_search', 'sr3_replace'] - ) + Widget.__init__(self, parent, OPTIONS['pipe']['search_and_replace']) self.db, self.book_id = db, book_id self.sr_search.set_msg(_('&Search regular expression:')) diff --git a/src/calibre/gui2/convert/single.py b/src/calibre/gui2/convert/single.py index a96ddd31ef..e00a18df34 100644 --- a/src/calibre/gui2/convert/single.py +++ b/src/calibre/gui2/convert/single.py @@ -24,11 +24,10 @@ from calibre.gui2.convert.toc import TOCWidget from calibre.gui2.convert.debug import DebugWidget -from calibre.ebooks.conversion.plumber import (Plumber, ARCHIVE_FMTS) +from calibre.ebooks.conversion.plumber import create_dummy_plumber from calibre.ebooks.conversion.config import delete_specifics from calibre.customize.conversion import OptionRecommendation from calibre.utils.config import prefs -from calibre.utils.logging import Log class GroupModel(QAbstractListModel): @@ -125,13 +124,7 @@ class Config(QDialog, Ui_Dialog): oidx = self.groups.currentIndex().row() input_format = self.input_format output_format = self.output_format - output_path = 'dummy.'+output_format - log = Log() - log.outputs = [] - input_file = 'dummy.'+input_format - if input_format in ARCHIVE_FMTS: - input_file = 'dummy.html' - self.plumber = Plumber(input_file, output_path, log) + self.plumber = create_dummy_plumber(input_format, output_format) def widget_factory(cls): return cls(self.stack, self.plumber.get_option_by_name, diff --git a/src/calibre/gui2/convert/snb_output.py b/src/calibre/gui2/convert/snb_output.py index d504792764..9296a92380 100644 --- a/src/calibre/gui2/convert/snb_output.py +++ b/src/calibre/gui2/convert/snb_output.py @@ -6,6 +6,7 @@ __docformat__ = 'restructuredtext en' from calibre.gui2.convert.snb_output_ui import Ui_Form from calibre.gui2.convert import Widget +from calibre.ebooks.conversion.config import OPTIONS newline_model = None @@ -18,8 +19,6 @@ class PluginWidget(Widget, Ui_Form): ICON = I('mimetypes/snb.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): - Widget.__init__(self, parent, - ['snb_insert_empty_line', 'snb_dont_indent_first_line', - 'snb_hide_chapter_name','snb_full_screen']) + Widget.__init__(self, parent, OPTIONS['output']['snb']) self.db, self.book_id = db, book_id self.initialize_options(get_option, get_help, db, book_id) diff --git a/src/calibre/gui2/convert/structure_detection.py b/src/calibre/gui2/convert/structure_detection.py index 213956b128..dc28fb0940 100644 --- a/src/calibre/gui2/convert/structure_detection.py +++ b/src/calibre/gui2/convert/structure_detection.py @@ -9,6 +9,7 @@ __docformat__ = 'restructuredtext en' from calibre.gui2.convert.structure_detection_ui import Ui_Form from calibre.gui2.convert import Widget from calibre.gui2 import error_dialog +from calibre.ebooks.conversion.config import OPTIONS class StructureDetectionWidget(Widget, Ui_Form): @@ -20,11 +21,7 @@ class StructureDetectionWidget(Widget, Ui_Form): COMMIT_NAME = 'structure_detection' def __init__(self, parent, get_option, get_help, db=None, book_id=None): - Widget.__init__(self, parent, - ['chapter', 'chapter_mark', 'start_reading_at', - 'remove_first_image', 'remove_fake_margins', - 'insert_metadata', 'page_breaks_before'] - ) + Widget.__init__(self, parent, OPTIONS['pipe']['structure_detection']) self.db, self.book_id = db, book_id for x in ('pagebreak', 'rule', 'both', 'none'): self.opt_chapter_mark.addItem(x) diff --git a/src/calibre/gui2/convert/toc.py b/src/calibre/gui2/convert/toc.py index f2ebdc0956..d02d691771 100644 --- a/src/calibre/gui2/convert/toc.py +++ b/src/calibre/gui2/convert/toc.py @@ -11,6 +11,7 @@ from calibre.gui2.convert.toc_ui import Ui_Form from calibre.gui2.convert import Widget from calibre.gui2 import error_dialog from calibre.utils.localization import localize_user_manual_link +from calibre.ebooks.conversion.config import OPTIONS class TOCWidget(Widget, Ui_Form): @@ -21,12 +22,7 @@ class TOCWidget(Widget, Ui_Form): COMMIT_NAME = 'toc' def __init__(self, parent, get_option, get_help, db=None, book_id=None): - Widget.__init__(self, parent, - ['level1_toc', 'level2_toc', 'level3_toc', - 'toc_threshold', 'max_toc_links', 'no_chapters_in_toc', - 'use_auto_toc', 'toc_filter', 'duplicate_links_in_toc', - ] - ) + Widget.__init__(self, parent, OPTIONS['pipe']['toc']) self.db, self.book_id = db, book_id self.initialize_options(get_option, get_help, db, book_id) self.opt_level1_toc.set_msg(_('Level &1 TOC (XPath expression):')) diff --git a/src/calibre/gui2/convert/txt_input.py b/src/calibre/gui2/convert/txt_input.py index b73af00dcc..ab80a126ee 100644 --- a/src/calibre/gui2/convert/txt_input.py +++ b/src/calibre/gui2/convert/txt_input.py @@ -9,6 +9,7 @@ from PyQt5.Qt import QListWidgetItem, Qt from calibre.gui2.convert.txt_input_ui import Ui_Form from calibre.gui2.convert import Widget from calibre.ebooks.conversion.plugins.txt_input import MD_EXTENSIONS +from calibre.ebooks.conversion.config import OPTIONS class PluginWidget(Widget, Ui_Form): @@ -19,9 +20,7 @@ class PluginWidget(Widget, Ui_Form): ICON = I('mimetypes/txt.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): - Widget.__init__(self, parent, - ['paragraph_type', 'formatting_type', 'markdown_extensions', - 'preserve_spaces', 'txt_in_remove_indents']) + Widget.__init__(self, parent, OPTIONS['input']['txt']) self.db, self.book_id = db, book_id for x in get_option('paragraph_type').option.choices: self.opt_paragraph_type.addItem(x) diff --git a/src/calibre/gui2/convert/txt_output.py b/src/calibre/gui2/convert/txt_output.py index c905ea6c62..d2182296be 100644 --- a/src/calibre/gui2/convert/txt_output.py +++ b/src/calibre/gui2/convert/txt_output.py @@ -7,6 +7,7 @@ __docformat__ = 'restructuredtext en' from calibre.gui2.convert.txt_output_ui import Ui_Form from calibre.gui2.convert import Widget +from calibre.ebooks.conversion.config import OPTIONS class PluginWidget(Widget, Ui_Form): @@ -17,10 +18,7 @@ class PluginWidget(Widget, Ui_Form): ICON = I('mimetypes/txt.png') def __init__(self, parent, get_option, get_help, db=None, book_id=None): - Widget.__init__(self, parent, - ['newline', 'max_line_length', 'force_max_line_length', - 'inline_toc', 'txt_output_formatting', 'keep_links', 'keep_image_references', - 'keep_color', 'txt_output_encoding']) + Widget.__init__(self, parent, OPTIONS['output']['txt']) self.db, self.book_id = db, book_id for x in get_option('newline').option.choices: self.opt_newline.addItem(x)