From fa24530bc5d47f5f1d680c9410fb24e311f2bb83 Mon Sep 17 00:00:00 2001 From: gryf Date: Wed, 13 May 2026 22:13:58 +0200 Subject: [PATCH] Imports rearrangements, readme reformat, basic stuff. Smoke tests are 100/100. --- README.rst | 10 +++++----- ebook_converter/__init__.py | 5 +++-- ebook_converter/ebooks/conversion/cli.py | 5 +++-- .../ebooks/conversion/plugins/fb2_input.py | 6 +++--- .../ebooks/conversion/plugins/html_output.py | 17 +++++++---------- .../ebooks/conversion/plugins/lrf_input.py | 6 +++--- .../ebooks/conversion/plugins/rtf_input.py | 6 +++--- ebook_converter/ebooks/oeb/polish/toc.py | 9 +++++---- ebook_converter/ebooks/oeb/stylizer.py | 13 ++++++++++--- ebook_converter/ebooks/txt/processor.py | 4 ++-- ebook_converter/spell/__init__.py | 6 +++--- ebook_converter/utils/config_base.py | 6 +++--- ebook_converter/utils/localization.py | 7 +++---- 13 files changed, 53 insertions(+), 47 deletions(-) diff --git a/README.rst b/README.rst index d30f58a..319d0b1 100644 --- a/README.rst +++ b/README.rst @@ -125,17 +125,17 @@ managers), i.e: (venv) $ cd ebook-converter (venv) $ pip install --no-binary lxml . -Note: the ``--no-binary lxml`` flag is required to ensure ``lxml`` is compiled -against the same system ``libxml2`` as ``html5-parser``. Without it, pip may -install a pre-built ``lxml`` wheel bundling a different ``libxml2`` version, -which causes a ``RuntimeError``. - Simple as that. And from now on, you can issue converter: .. code:: shell-session (venv) $ ebook-converter book.docx book.lrf +.. note:: The ``--no-binary lxml`` flag is required to ensure ``lxml`` is + compiled against the same system ``libxml2`` as ``html5-parser``. Without + it, pip may install a pre-built ``lxml`` wheel bundling a different + ``libxml2`` version, which causes a ``RuntimeError``. + License ------- diff --git a/ebook_converter/__init__.py b/ebook_converter/__init__.py index fd4a062..d0e1dc5 100644 --- a/ebook_converter/__init__.py +++ b/ebook_converter/__init__.py @@ -1,5 +1,6 @@ +import importlib.resources import mimetypes -from importlib.resources import files -mimetypes.init([str(files('ebook_converter').joinpath('data/mime.types'))]) +mimetypes.init([str(importlib.resources. + files('ebook_converter') / 'data/mime.types')]) diff --git a/ebook_converter/ebooks/conversion/cli.py b/ebook_converter/ebooks/conversion/cli.py index cbc9842..14aed1a 100644 --- a/ebook_converter/ebooks/conversion/cli.py +++ b/ebook_converter/ebooks/conversion/cli.py @@ -2,12 +2,12 @@ Command line interface to conversion sub-system """ import collections +import importlib.resources import json import mimetypes import numbers import optparse import os -from importlib.resources import files import re import sys @@ -351,7 +351,8 @@ def read_sr_patterns(path, log=None): def main(args=sys.argv): log = logging.default_log - mimetypes.init([str(files('ebook_converter').joinpath('data/mime.types'))]) + mimetypes.init([str(importlib.resources.files('ebook_converter') / + 'data/mime.types')]) parser, plumber = create_option_parser(args, log) opts, leftover_args = parser.parse_args(args) if len(leftover_args) > 3: diff --git a/ebook_converter/ebooks/conversion/plugins/fb2_input.py b/ebook_converter/ebooks/conversion/plugins/fb2_input.py index 0487ef8..da31f36 100644 --- a/ebook_converter/ebooks/conversion/plugins/fb2_input.py +++ b/ebook_converter/ebooks/conversion/plugins/fb2_input.py @@ -1,9 +1,9 @@ """ Convert .fb2 files to .lrf """ +import importlib.resources import mimetypes import os -from importlib.resources import files import re from lxml import etree @@ -85,8 +85,8 @@ class FB2Input(InputFormatPlugin): css = re.sub(r'name\s*=\s*', 'class=', css) self.extract_embedded_content(doc) log.debug('Converting XML to HTML...') - with open(str(files('ebook_converter') - .joinpath('data/fb2.xsl'))) as f: + with open(importlib.resources.files('ebook_converter') / + 'data/fb2.xsl') as f: ss = f.read() ss = ss.replace("__FB_NS__", fb_ns) if options.no_inline_fb2_toc: diff --git a/ebook_converter/ebooks/conversion/plugins/html_output.py b/ebook_converter/ebooks/conversion/plugins/html_output.py index 9569f59..c429789 100644 --- a/ebook_converter/ebooks/conversion/plugins/html_output.py +++ b/ebook_converter/ebooks/conversion/plugins/html_output.py @@ -1,5 +1,5 @@ +import importlib.resources import os -from importlib.resources import files import re import shutil @@ -92,27 +92,24 @@ class HTMLOutput(OutputFormatPlugin): with open(opts.template_html_index, 'rb') as f: template_html_index_data = f.read() else: - with open(str(files('ebook_converter') - .joinpath('data/html_export_default_index.tmpl')) - ) as fobj: + with open(importlib.resources.files('ebook_converter') / + 'data/html_export_default_index.tmpl') as fobj: template_html_index_data = fobj.read().decode() if opts.template_html is not None: with open(opts.template_html, 'rb') as f: template_html_data = f.read() else: - with open(str(files('ebook_converter') - .joinpath('data/html_export_default.tmpl')) - ) as fobj: + with open(importlib.resources.files('ebook_converter') / + 'data/html_export_default.tmpl') as fobj: template_html_data = fobj.read().decode() if opts.template_css is not None: with open(opts.template_css, 'rb') as f: template_css_data = f.read() else: - with open(str(files('ebook_converter') - .joinpath('data/html_export_default.css')) - ) as fobj: + with open(importlib.resources.files('ebook_converter') / + 'data/html_export_default.css') as fobj: template_css_data = fobj.read().decode() template_html_index_data = template_html_index_data.decode('utf-8') diff --git a/ebook_converter/ebooks/conversion/plugins/lrf_input.py b/ebook_converter/ebooks/conversion/plugins/lrf_input.py index 36e9582..d6dc6f1 100644 --- a/ebook_converter/ebooks/conversion/plugins/lrf_input.py +++ b/ebook_converter/ebooks/conversion/plugins/lrf_input.py @@ -1,6 +1,6 @@ +import importlib.resources import os import sys -from importlib.resources import files from lxml import etree @@ -52,8 +52,8 @@ class LRFInput(InputFormatPlugin): self.log.info('Converting XML to HTML...') - with open(str(files('ebook_converter') - .joinpath('data/lrf.xsl'))) as fobj: + with open(importlib.resources.files('ebook_converter') / + 'data/lrf.xsl') as fobj: # TODO(gryf): change this nonsense to etree.parse() instead. styledoc = etree.fromstring(fobj.read()) media_type = MediaType() diff --git a/ebook_converter/ebooks/conversion/plugins/rtf_input.py b/ebook_converter/ebooks/conversion/plugins/rtf_input.py index 2bf45a5..92b5b48 100644 --- a/ebook_converter/ebooks/conversion/plugins/rtf_input.py +++ b/ebook_converter/ebooks/conversion/plugins/rtf_input.py @@ -1,6 +1,6 @@ +import importlib.resources import glob import os -from importlib.resources import files import re import textwrap @@ -288,8 +288,8 @@ class RTFInput(InputFormatPlugin): self.log.info('Converting XML to HTML...') inline_class = InlineClass(self.log) - with open(str(files('ebook_converter') - .joinpath('data/rtf.xsl'))) as fobj: + with open(importlib.resources.files('ebook_converter') / + 'data/rtf.xsl') as fobj: styledoc = etree.fromstring(fobj.read()) extensions = {('calibre', 'inline-class'): inline_class} transform = etree.XSLT(styledoc, extensions=extensions) diff --git a/ebook_converter/ebooks/oeb/polish/toc.py b/ebook_converter/ebooks/oeb/polish/toc.py index f4c54ea..0c3e297 100644 --- a/ebook_converter/ebooks/oeb/polish/toc.py +++ b/ebook_converter/ebooks/oeb/polish/toc.py @@ -1,7 +1,7 @@ import collections import functools +import importlib.resources import operator -from importlib.resources import files import re import urllib.parse @@ -719,8 +719,8 @@ def commit_nav_toc(container, toc, lang=None, landmarks=None, if previous_nav is not None: root = previous_nav[1] else: - with open(str(files('ebook_converter') - .joinpath('data/new_nav.html'))) as fobj: + with open(importlib.resources.file('ebook_converter') / + 'data/new_nav.html') as fobj: root = container.parse_xhtml(fobj.read()) container.replace(tocname, root) else: @@ -873,7 +873,8 @@ def toc_to_html(toc, container, toc_name, title, lang=None): E = ElementMaker(namespace=const.XHTML_NS, nsmap={None: const.XHTML_NS}) # TODO(gryf): revisit lack of css. - css_f = str(files('ebook_converter').joinpath('data/inline_toc_styles.css')) + css_f = str(importlib.resources.files('ebook_converter') / + 'data/inline_toc_styles.css') html = E.html(E.head(E.title(title), E.style(css_f, type='text/css')), E.body(E.h2(title), E.ul(), diff --git a/ebook_converter/ebooks/oeb/stylizer.py b/ebook_converter/ebooks/oeb/stylizer.py index 63b8006..50d7753 100644 --- a/ebook_converter/ebooks/oeb/stylizer.py +++ b/ebook_converter/ebooks/oeb/stylizer.py @@ -1,8 +1,14 @@ """ CSS property propagation class. """ -import os, re, logging, copy, unicodedata, numbers -from importlib.resources import files +import copy +import importlib.resources +import logging +import numbers +import os +import re +import unicodedata + from operator import itemgetter from weakref import WeakKeyDictionary from xml.dom import SyntaxErr as CSSSyntaxError @@ -28,7 +34,8 @@ _html_css_stylesheet = None def html_css_stylesheet(): global _html_css_stylesheet if _html_css_stylesheet is None: - with open(str(files('ebook_converter').joinpath('data/html.css')), 'rb') as f: + with open(importlib.resources.files('ebook_converter') / + 'data/html.css', 'rb') as f: html_css = f.read().decode('utf-8') _html_css_stylesheet = parseString(html_css, validate=False) return _html_css_stylesheet diff --git a/ebook_converter/ebooks/txt/processor.py b/ebook_converter/ebooks/txt/processor.py index ecdfc93..43867ea 100644 --- a/ebook_converter/ebooks/txt/processor.py +++ b/ebook_converter/ebooks/txt/processor.py @@ -1,7 +1,8 @@ """ Read content from txt file. """ -import os, re +import re +import os from ebook_converter.ebooks.metadata.opf2 import OPFCreator @@ -101,7 +102,6 @@ DEFAULT_MD_EXTENSIONS = ('footnotes', 'tables', 'toc') def create_markdown_object(extensions): - # Need to load markdown extensions without relying on pkg_resources import importlib from ebook_converter.ebooks.markdown import Markdown from markdown import Extension diff --git a/ebook_converter/spell/__init__.py b/ebook_converter/spell/__init__.py index b123c36..2ddbc6f 100644 --- a/ebook_converter/spell/__init__.py +++ b/ebook_converter/spell/__init__.py @@ -1,6 +1,6 @@ from collections import namedtuple +import importlib.resources import json -from importlib.resources import files from ebook_converter.utils.localization import canonicalize_lang @@ -16,8 +16,8 @@ ccodes, ccodemap, country_names = None, None, None def get_codes(): global ccodes, ccodemap, country_names if ccodes is None: - src = str(files('ebook_converter').joinpath('data/iso_3166-1.json')) - with open(src, 'rb') as f: + with open(importlib.resources.files('ebook_converter') / + 'data/iso_3166-1.json', 'rb') as f: db = json.load(f) codes = set() three_map = {} diff --git a/ebook_converter/utils/config_base.py b/ebook_converter/utils/config_base.py index 15fb13e..990a708 100644 --- a/ebook_converter/utils/config_base.py +++ b/ebook_converter/utils/config_base.py @@ -3,6 +3,7 @@ import collections import copy import datetime import functools +import importlib.resources import json import numbers import os @@ -10,8 +11,6 @@ import pickle import re import traceback -from importlib.resources import files as _resource_files - from ebook_converter.constants_old import config_dir from ebook_converter.constants_old import filesystem_encoding from ebook_converter.constants_old import preferred_encoding @@ -591,7 +590,8 @@ def exec_tweaks(path): def default_tweaks_raw(): - return str(_resource_files('ebook_converter').joinpath('data/default_tweaks.py')) + return str(importlib.resources.files('ebook_converter') / + 'data/default_tweaks.py') def read_tweaks(): diff --git a/ebook_converter/utils/localization.py b/ebook_converter/utils/localization.py index 02c9dea..f3817c2 100644 --- a/ebook_converter/utils/localization.py +++ b/ebook_converter/utils/localization.py @@ -1,5 +1,5 @@ +import importlib.resources import json -from importlib.resources import files def get_lang(): @@ -39,9 +39,8 @@ def _load_iso639(): # excerpt form Calibre transform code which is executed during Calibre # build). if _iso639 is None: - src = str(files('ebook_converter').joinpath('data/iso_639-3.json')) - - with open(src, 'rb') as f: + with open(importlib.resources.files('ebook_converter') / + 'data/iso_639-3.json', 'rb') as f: root = json.load(f) entries = root['639-3']