From 4216fef20eb535ccefc4948672c0743cf618a274 Mon Sep 17 00:00:00 2001 From: gryf Date: Mon, 13 Jul 2020 21:38:06 +0200 Subject: [PATCH] Removed prints and extract function from init module --- ebook_converter/__init__.py | 62 ------ ebook_converter/customize/ui.py | 6 +- ebook_converter/devices/interface.py | 3 +- ebook_converter/ebooks/__init__.py | 11 +- ebook_converter/ebooks/conversion/plumber.py | 25 --- ebook_converter/ebooks/html/input.py | 2 +- ebook_converter/ebooks/html/to_zip.py | 4 +- ebook_converter/ebooks/metadata/__init__.py | 6 +- ebook_converter/ebooks/metadata/book/base.py | 7 +- ebook_converter/ebooks/metadata/fb2.py | 6 +- ebook_converter/ebooks/metadata/opf2.py | 5 +- ebook_converter/ebooks/metadata/opf3.py | 3 +- ebook_converter/ebooks/metadata/pdf.py | 10 +- ebook_converter/ebooks/metadata/xmp.py | 7 +- ebook_converter/ebooks/pdf/pdftohtml.py | 6 +- ebook_converter/utils/filenames.py | 8 +- ebook_converter/utils/fonts/scanner.py | 30 +-- ebook_converter/utils/fonts/sfnt/subset.py | 34 ++-- ebook_converter/utils/formatter.py | 3 +- ebook_converter/utils/logging.py | 195 +++---------------- 20 files changed, 97 insertions(+), 336 deletions(-) diff --git a/ebook_converter/__init__.py b/ebook_converter/__init__.py index 8d38955..1f08880 100644 --- a/ebook_converter/__init__.py +++ b/ebook_converter/__init__.py @@ -14,9 +14,7 @@ from ebook_converter.constants_old import islinux, isfrozen, \ isbsd, __appname__, __version__, __author__, \ config_dir from ebook_converter.ebooks.html_entities import html5_entities -from ebook_converter.libunzip import extract as zipextract from ebook_converter.startup import winutil, winutilerror -from ebook_converter.utils.unrar import extract as rarextract if False: @@ -72,45 +70,6 @@ def sanitize_file_name(name, substitute='_'): return one -def prints(*args, **kwargs): - """ - Print unicode arguments safely by encoding them to preferred_encoding - Has the same signature as the print function from Python 3, except for the - additional keyword argument safe_encode, which if set to True will cause - the function to use repr when encoding fails. - - Returns the number of bytes written. - """ - fobj = kwargs.get('file', sys.stdout) - enc = ('utf-8' if os.getenv('CALIBRE_WORKER') - else constants_old.preferred_encoding) - sep = kwargs.get('sep', ' ') - if isinstance(sep, bytes): - sep = sep.decode(enc) - end = kwargs.get('end', '\n') - if isinstance(end, bytes): - end = end.decode(enc) - count = 0 - - for i, arg in enumerate(args): - if isinstance(arg, bytes): - arg = arg.decode(enc) - arg = repr(arg) - try: - fobj.write(arg) - count += len(arg) - except Exception: - arg = repr(arg) - fobj.write(arg) - count += len(arg) - if i != len(args)-1: - fobj.write(sep) - count += len(sep) - fobj.write(end) - count += len(end) - return count - - def setup_cli_handlers(logger, level): if os.getenv('CALIBRE_WORKER') and logger.handlers: return @@ -132,27 +91,6 @@ def setup_cli_handlers(logger, level): logger.addHandler(handler) -def extract(path, dir): - extractor = None - # First use the file header to identify its type - with open(path, 'rb') as f: - id_ = f.read(3) - if id_ == b'Rar': - extractor = rarextract - elif id_.startswith(b'PK'): - extractor = zipextract - if extractor is None: - # Fallback to file extension - ext = os.path.splitext(path)[1][1:].lower() - if ext in ['zip', 'cbz', 'epub', 'oebzip']: - extractor = zipextract - elif ext in ['cbr', 'rar']: - extractor = rarextract - if extractor is None: - raise Exception('Unknown archive type') - extractor(path, dir) - - def fit_image(width, height, pwidth, pheight): """ Fit image in box of width pwidth and height pheight. diff --git a/ebook_converter/customize/ui.py b/ebook_converter/customize/ui.py index 3f37fed..1ea48be 100644 --- a/ebook_converter/customize/ui.py +++ b/ebook_converter/customize/ui.py @@ -12,7 +12,6 @@ from ebook_converter.customize import profiles from ebook_converter.customize import builtins from ebook_converter.ebooks import metadata from ebook_converter.utils import config as cfg -from ebook_converter import prints builtin_names = frozenset(p.name for p in builtins.plugins) @@ -349,9 +348,8 @@ def set_file_type_metadata(stream, mi, ftype, report_error=None): break except Exception: if report_error is None: - prints('Failed to set metadata for the', ftype.upper(), - 'format of:', getattr(mi, 'title', ''), - file=sys.stderr) + print('Failed to set metadata for the', ftype.upper(), + 'format of:', getattr(mi, 'title', '')) traceback.print_exc() else: report_error(mi, ftype, traceback.format_exc()) diff --git a/ebook_converter/devices/interface.py b/ebook_converter/devices/interface.py index de10efb..7e3df92 100644 --- a/ebook_converter/devices/interface.py +++ b/ebook_converter/devices/interface.py @@ -1,7 +1,6 @@ import os from collections import namedtuple -from ebook_converter import prints from ebook_converter.customize import Plugin @@ -170,7 +169,7 @@ class DevicePlugin(Plugin): cbcd = self.BCD if self.test_bcd(bcd, cbcd): if debug: - prints(dev) + print(dev) if ch(dev, debug=debug): return True, dev return False, None diff --git a/ebook_converter/ebooks/__init__.py b/ebook_converter/ebooks/__init__.py index c09732c..e2a4eef 100644 --- a/ebook_converter/ebooks/__init__.py +++ b/ebook_converter/ebooks/__init__.py @@ -5,11 +5,9 @@ from various formats. import numbers import os import re -import sys from lxml import etree -from ebook_converter import prints from ebook_converter.ebooks.chardet import xml_to_unicode @@ -123,13 +121,14 @@ def render_html_data(path_to_html, width, height): result = {} def report_error(text=''): - prints('Failed to render', path_to_html, 'with errors:', - file=sys.stderr) + __import__('pdb').set_trace() + print(f'Failed to render {path_to_html}') + # file=sys.stderr) if text: - prints(text, file=sys.stderr) + print(text) # , file=sys.stderr) if result and result['stdout_stderr']: with open(result['stdout_stderr'], 'rb') as f: - prints(f.read(), file=sys.stderr) + print(f.read()) # , file=sys.stderr) with TemporaryDirectory('-render-html') as tdir: try: diff --git a/ebook_converter/ebooks/conversion/plumber.py b/ebook_converter/ebooks/conversion/plumber.py index de00ef7..f75d2f1 100644 --- a/ebook_converter/ebooks/conversion/plumber.py +++ b/ebook_converter/ebooks/conversion/plumber.py @@ -14,7 +14,6 @@ from ebook_converter.ebooks.conversion.preprocess import HTMLPreProcessor from ebook_converter.ptempfile import PersistentTemporaryDirectory from ebook_converter.utils.date import parse_date from ebook_converter.utils.zipfile import ZipFile -from ebook_converter import extract, walk from ebook_converter import constants from ebook_converter.constants_old import filesystem_encoding @@ -694,11 +693,6 @@ OptionRecommendation(name='search_replace', input_fmt = 'epub' self.archive_input_tdir = None self.changed_options = set() - if input_fmt in ARCHIVE_FMTS: - self.log('Processing archive...') - tdir = PersistentTemporaryDirectory('_pl_arc') - self.input, input_fmt = self.unarchive(self.input, tdir) - self.archive_input_tdir = tdir if os.access(self.input, os.R_OK): nfp = run_plugins_on_preprocess(self.input, input_fmt) if nfp != self.input: @@ -761,25 +755,6 @@ OptionRecommendation(name='search_replace', if merge_plugin_recs: self.merge_plugin_recommendations() - @classmethod - def unarchive(self, path, tdir): - extract(path, tdir) - files = list(walk(tdir)) - files = [f if isinstance(f, str) else f.decode(filesystem_encoding) - for f in files] - from ebook_converter.customize.ui import available_input_formats - fmts = set(available_input_formats()) - fmts -= {'htm', 'html', 'xhtm', 'xhtml'} - fmts -= set(ARCHIVE_FMTS) - - for ext in fmts: - for f in files: - if f.lower().endswith('.'+ext): - if ext in ['txt', 'rtf'] and os.stat(f).st_size < 2048: - continue - return f, ext - return self.find_html_index(files) - @classmethod def find_html_index(self, files): ''' diff --git a/ebook_converter/ebooks/html/input.py b/ebook_converter/ebooks/html/input.py index cb75c67..d327669 100644 --- a/ebook_converter/ebooks/html/input.py +++ b/ebook_converter/ebooks/html/input.py @@ -8,7 +8,7 @@ import sys import urllib.parse from ebook_converter.ebooks.chardet import detect_xml_encoding -from ebook_converter import unicode_path, replace_entities +from ebook_converter import replace_entities class Link(object): diff --git a/ebook_converter/ebooks/html/to_zip.py b/ebook_converter/ebooks/html/to_zip.py index 4f4f2d5..ca0e6ef 100644 --- a/ebook_converter/ebooks/html/to_zip.py +++ b/ebook_converter/ebooks/html/to_zip.py @@ -24,7 +24,6 @@ class HTML2ZIP(FileTypePlugin): def run(self, htmlfile): import codecs - from ebook_converter import prints from ebook_converter.ptempfile import TemporaryDirectory from ebook_converter.gui2.convert.gui_conversion import gui_convert from ebook_converter.customize.conversion import OptionRecommendation @@ -40,7 +39,8 @@ class HTML2ZIP(FileTypePlugin): try: codecs.lookup(enc) except Exception: - prints('Ignoring invalid input encoding for HTML:', enc) + print('Ignoring invalid input encoding for HTML: %s', + enc) else: recs.append(['input_encoding', enc, OptionRecommendation.HIGH]) if bf == 'bf': diff --git a/ebook_converter/ebooks/metadata/__init__.py b/ebook_converter/ebooks/metadata/__init__.py index a20e24c..c03c0bb 100644 --- a/ebook_converter/ebooks/metadata/__init__.py +++ b/ebook_converter/ebooks/metadata/__init__.py @@ -8,7 +8,7 @@ import re import sys import urllib.parse -from ebook_converter import prints, force_unicode +from ebook_converter import force_unicode from ebook_converter.utils.config_base import tweaks from ebook_converter.polyglot.urllib import unquote @@ -16,8 +16,8 @@ from ebook_converter.polyglot.urllib import unquote try: _author_pat = re.compile(tweaks['authors_split_regex']) except Exception: - prints('Author split regexp:', tweaks['authors_split_regex'], - 'is invalid, using default') + print(f"Author split regexp: {tweaks['authors_split_regex']}, is invalid, " + f"using default") _author_pat = re.compile(r'(?i),?\s+(and|with)\s+') diff --git a/ebook_converter/ebooks/metadata/book/base.py b/ebook_converter/ebooks/metadata/book/base.py index ecce2b9..dea2570 100644 --- a/ebook_converter/ebooks/metadata/book/base.py +++ b/ebook_converter/ebooks/metadata/book/base.py @@ -1,6 +1,5 @@ import copy, traceback -from ebook_converter import prints from ebook_converter.constants_old import DEBUG from ebook_converter.ebooks.metadata.book import (SC_COPYABLE_FIELDS, SC_FIELDS_COPY_NOT_NULL, STANDARD_METADATA_FIELDS, @@ -453,12 +452,12 @@ class Metadata(object): # Old Metadata API {{{ def print_all_attributes(self): for x in STANDARD_METADATA_FIELDS: - prints('%s:'%x, getattr(self, x, 'None')) + print('%s:' % x, getattr(self, x, 'None')) for x in self.custom_field_keys(): meta = self.get_user_metadata(x, make_copy=False) if meta is not None: - prints(x, meta) - prints('--------------') + print(x, meta) + print('--------------') def smart_update(self, other, replace_metadata=False): ''' diff --git a/ebook_converter/ebooks/metadata/fb2.py b/ebook_converter/ebooks/metadata/fb2.py index c005457..8cadba9 100644 --- a/ebook_converter/ebooks/metadata/fb2.py +++ b/ebook_converter/ebooks/metadata/fb2.py @@ -12,7 +12,7 @@ from lxml import etree from ebook_converter.utils.date import parse_only_date from ebook_converter.utils.img import save_cover_data_to from ebook_converter.utils.imghdr import identify -from ebook_converter import prints, force_unicode +from ebook_converter import force_unicode from ebook_converter.ebooks.metadata import MetaInformation, check_isbn from ebook_converter.ebooks.chardet import xml_to_unicode from ebook_converter.polyglot.binary import as_base64_unicode @@ -237,8 +237,8 @@ def _parse_cover_data(root, imgid, mi, ctx): fmt = identify(cdata)[0] mi.cover_data = (fmt, cdata) else: - prints("WARNING: Unsupported coverpage mime-type '%s' (id=#%s)" % - (mimetype, imgid)) + print(f"WARNING: Unsupported coverpage mime-type '{mimetype}' " + f"(id=#{imgid})") def _parse_tags(root, mi, ctx): diff --git a/ebook_converter/ebooks/metadata/opf2.py b/ebook_converter/ebooks/metadata/opf2.py index a907ad8..1ed10fc 100644 --- a/ebook_converter/ebooks/metadata/opf2.py +++ b/ebook_converter/ebooks/metadata/opf2.py @@ -32,7 +32,6 @@ from ebook_converter.ebooks.metadata import string_to_authors, \ from ebook_converter.ebooks.metadata.book.base import Metadata from ebook_converter.utils.date import parse_date, isoformat from ebook_converter.utils.localization import get_lang, canonicalize_lang -from ebook_converter import prints from ebook_converter.utils.cleantext import clean_ascii_chars, clean_xml_chars from ebook_converter.utils.config import tweaks from ebook_converter.polyglot.urllib import unquote @@ -516,7 +515,7 @@ def serialize_user_metadata(metadata_elem, all_user_metadata, fm = object_to_unicode(fm) fm = json.dumps(fm, default=to_json, ensure_ascii=False) except Exception: - prints('Failed to write user metadata:', name) + print('Failed to write user metadata: {name}') traceback.print_exc() continue meta = metadata_elem.makeelement('meta') @@ -671,7 +670,7 @@ class OPF(object): # {{{ decode_is_multiple(fm) temp.set_user_metadata(name, fm) except Exception: - prints('Failed to read user metadata:', name) + print('Failed to read user metadata: {name}') traceback.print_exc() continue self._user_metadata_ = temp.get_all_user_metadata(True) diff --git a/ebook_converter/ebooks/metadata/opf3.py b/ebook_converter/ebooks/metadata/opf3.py index 5c0831d..7c577c7 100644 --- a/ebook_converter/ebooks/metadata/opf3.py +++ b/ebook_converter/ebooks/metadata/opf3.py @@ -6,7 +6,6 @@ import re from lxml import etree from ebook_converter import constants as const -from ebook_converter import prints from ebook_converter.ebooks.metadata import authors_to_string from ebook_converter.ebooks.metadata import check_isbn from ebook_converter.ebooks.metadata import string_to_authors @@ -923,7 +922,7 @@ def read_user_metadata2(root, remove_tags=False): decode_is_multiple(fm) ans[name] = fm except Exception: - prints('Failed to read user metadata:', name) + print('Failed to read user metadata: {name}') import traceback traceback.print_exc() continue diff --git a/ebook_converter/ebooks/metadata/pdf.py b/ebook_converter/ebooks/metadata/pdf.py index 5456ef9..984cf6f 100644 --- a/ebook_converter/ebooks/metadata/pdf.py +++ b/ebook_converter/ebooks/metadata/pdf.py @@ -4,7 +4,6 @@ Read meta information from PDF files import os, subprocess, shutil, re from functools import partial -from ebook_converter import prints from ebook_converter.ptempfile import TemporaryDirectory from ebook_converter.ebooks.metadata import ( MetaInformation, string_to_authors, check_isbn, check_doi) @@ -39,12 +38,12 @@ def read_info(outputdir, get_cover): raw = subprocess.check_output([pdfinfo, '-enc', 'UTF-8', '-isodates', source_file]) except subprocess.CalledProcessError as e: - prints('pdfinfo errored out with return code: %d'%e.returncode) + print(f'pdfinfo errored out with return code: {e.returncode}') return None try: info_raw = raw.decode('utf-8') except UnicodeDecodeError: - prints('pdfinfo returned no UTF-8 data') + print('pdfinfo returned no UTF-8 data') return None for line in info_raw.splitlines(): @@ -63,7 +62,8 @@ def read_info(outputdir, get_cover): try: raw = subprocess.check_output([pdfinfo, '-meta', source_file]).strip() except subprocess.CalledProcessError as e: - prints('pdfinfo failed to read XML metadata with return code: %d'%e.returncode) + print('pdfinfo failed to read XML metadata with return code: ' + f'{e.returncode}') else: parts = re.split(br'^Metadata:', raw, 1, flags=re.MULTILINE) if len(parts) > 1: @@ -77,7 +77,7 @@ def read_info(outputdir, get_cover): subprocess.check_call([pdftoppm, '-singlefile', '-jpeg', '-cropbox', source_file, cover_file]) except subprocess.CalledProcessError as e: - prints('pdftoppm errored out with return code: %d'%e.returncode) + print('pdftoppm errored out with return code: {e.returncode}') return ans diff --git a/ebook_converter/ebooks/metadata/xmp.py b/ebook_converter/ebooks/metadata/xmp.py index e9a7faf..d68166b 100644 --- a/ebook_converter/ebooks/metadata/xmp.py +++ b/ebook_converter/ebooks/metadata/xmp.py @@ -4,11 +4,11 @@ import itertools import json import re import sys +import traceback from lxml import etree from lxml.builder import ElementMaker -from ebook_converter import prints from ebook_converter.ebooks.metadata import check_isbn, check_doi from ebook_converter.ebooks.metadata.book.base import Metadata from ebook_converter.ebooks.metadata.opf2 import dump_dict @@ -192,7 +192,7 @@ def read_user_metadata(mi, root): mi.set_user_metadata(name, fm) fields.add(name) except Exception: - prints('Failed to read user metadata:', name) + print(f'Failed to read user metadata: {name}') import traceback traceback.print_exc() @@ -467,8 +467,7 @@ def create_user_metadata(calibre, all_user_metadata): fm = object_to_unicode(fm) fm = json.dumps(fm, default=to_json, ensure_ascii=False) except Exception: - prints('Failed to write user metadata:', name) - import traceback + print('Failed to write user metadata: {name}') traceback.print_exc() continue li = bag.makeelement(expand('rdf:li')) diff --git a/ebook_converter/ebooks/pdf/pdftohtml.py b/ebook_converter/ebooks/pdf/pdftohtml.py index 42f1014..1f62166 100644 --- a/ebook_converter/ebooks/pdf/pdftohtml.py +++ b/ebook_converter/ebooks/pdf/pdftohtml.py @@ -7,7 +7,7 @@ import sys from lxml import etree -from ebook_converter import CurrentDir, xml_replace_entities, prints +from ebook_converter import CurrentDir, xml_replace_entities from ebook_converter.constants_old import isbsd, islinux, isosx from ebook_converter.ebooks import ConversionError, DRMError from ebook_converter.ebooks.chardet import xml_to_unicode @@ -78,8 +78,8 @@ def pdftohtml(output_dir, pdf_path, no_images, as_xml=False): raise ConversionError('pdftohtml failed with return code: ' '%d\n%s' % (ret, out)) if out: - prints("pdftohtml log:") - prints(out) + print("pdftohtml log:") + print(out) if not os.path.exists(index) or os.stat(index).st_size < 100: raise DRMError() diff --git a/ebook_converter/utils/filenames.py b/ebook_converter/utils/filenames.py index 88ba177..cc7f73d 100644 --- a/ebook_converter/utils/filenames.py +++ b/ebook_converter/utils/filenames.py @@ -5,13 +5,11 @@ meaning as possible. import errno import os import shutil -import time from math import ceil -from ebook_converter import force_unicode, prints, sanitize_file_name -from ebook_converter.constants_old import ( - filesystem_encoding, plugins, preferred_encoding, isosx -) +from ebook_converter import force_unicode, sanitize_file_name +from ebook_converter.constants_old import (filesystem_encoding, + preferred_encoding) from ebook_converter.utils.localization import get_udc diff --git a/ebook_converter/utils/fonts/scanner.py b/ebook_converter/utils/fonts/scanner.py index 0178461..da2e285 100644 --- a/ebook_converter/utils/fonts/scanner.py +++ b/ebook_converter/utils/fonts/scanner.py @@ -2,7 +2,7 @@ import os from collections import defaultdict from threading import Thread -from ebook_converter import walk, prints +from ebook_converter import walk from ebook_converter.constants_old import isosx from ebook_converter.constants_old import plugins, DEBUG from ebook_converter.constants_old import filesystem_encoding @@ -67,7 +67,7 @@ def fc_list(): try: ans.append(d.decode(filesystem_encoding)) except ValueError: - prints('Ignoring undecodeable font path: %r' % d) + print(f'Ignoring undecodeable font path: {d}') continue end(str_list) if len(ans) < 3: @@ -309,7 +309,7 @@ class FontScanner(Thread): files = tuple(walk(folder)) except EnvironmentError as e: if DEBUG: - prints('Failed to walk font folder:', folder, str(e)) + print(f'Failed to walk font folder: {folder}, {e}') continue for candidate in files: if (candidate.rpartition('.')[-1].lower() not in @@ -332,8 +332,8 @@ class FontScanner(Thread): self.read_font_metadata(candidate, fileid) except Exception as e: if DEBUG: - prints('Failed to read metadata from font file:', - candidate, str(e)) + print(f'Failed to read metadata from font file ' + f'{candidate}: {e}') continue if frozenset(cached_fonts) != frozenset(self.cached_fonts): @@ -369,18 +369,18 @@ class FontScanner(Thread): def dump_fonts(self): self.join() for family in self.font_families: - prints(family) + print(family) for font in self.fonts_for_family(family): - prints('\t%s: %s' % (font['full_name'], font['path'])) - prints(end='\t') + print('\t%s: %s' % (font['full_name'], font['path'])) + print(end='\t') for key in ('font-stretch', 'font-weight', 'font-style'): - prints('%s: %s' % (key, font[key]), end=' ') - prints() - prints('\tSub-family:', font['wws_subfamily_name'] or - font['preferred_subfamily_name'] or - font['subfamily_name']) - prints() - prints() + print('%s: %s' % (key, font[key])) + print() + print('\tSub-family: %s' % (font['wws_subfamily_name'] or + font['preferred_subfamily_name'] + or font['subfamily_name'])) + print() + print() font_scanner = FontScanner() diff --git a/ebook_converter/utils/fonts/sfnt/subset.py b/ebook_converter/utils/fonts/sfnt/subset.py index cf94147..1111367 100644 --- a/ebook_converter/utils/fonts/sfnt/subset.py +++ b/ebook_converter/utils/fonts/sfnt/subset.py @@ -204,15 +204,13 @@ def option_parser(): def print_stats(old_stats, new_stats): - from ebook_converter import prints - prints('========= Table comparison (original vs. subset) =========') - prints('Table', ' ', '%10s'%'Size', ' ', 'Percent', ' ', '%10s'%'New Size', - ' New Percent') - prints('='*80) + print('========= Table comparison (original vs. subset) =========') + print('Table Size Percent New Size New Percent') + print('='*80) old_total = sum(old_stats.values()) new_total = sum(new_stats.values()) - tables = sorted(old_stats, key=lambda x:old_stats[x], - reverse=True) + tables = sorted(old_stats, key=lambda x: old_stats[x], + reverse=True) for table in tables: osz = old_stats[table] op = osz/old_total * 100 @@ -220,15 +218,14 @@ def print_stats(old_stats, new_stats): np = nsz/new_total * 100 suffix = ' | same size' if nsz != osz: - suffix = ' | reduced to %.1f %%'%(nsz/osz * 100) - prints('%4s'%table, ' ', '%10s'%osz, ' ', '%5.1f %%'%op, ' ', - '%10s'%nsz, ' ', '%5.1f %%'%np, suffix) - prints('='*80) + suffix = ' | reduced to %.1f %%' % (nsz/osz * 100) + print('%4s %10s %5.1f %% %10s %5.1f %% %s' % + (table, osz, op, nsz, np, suffix)) + print('='*80) def main(args): import sys, time - from ebook_converter import prints parser = option_parser() opts, args = parser.parse_args(args) if len(args) < 4 or len(args) > 4: @@ -243,7 +240,7 @@ def main(args): def not_single(c): if len(c) > 1: - prints(c, 'is not a single character', file=sys.stderr) + print(f'{c}is not a single character') raise SystemExit(1) def conv_code(c): @@ -255,7 +252,7 @@ def main(args): if '-' in c: parts = [x.strip() for x in c.split('-')] if len(parts) != 2: - prints('Invalid range:', c, file=sys.stderr) + print(f'Invalid range: {c}') raise SystemExit(1) if opts.codes: parts = tuple(map(conv_code, parts)) @@ -272,13 +269,14 @@ def main(args): reduced = (len(sf)/len(orig)) * 100 def sz(x): - return '%gKB'%(len(x)/1024.) + return '%gKB' % (len(x)/1024.) print_stats(old_stats, new_stats) - prints('Original size:', sz(orig), 'Subset size:', sz(sf), 'Reduced to: %g%%'%(reduced)) - prints('Subsetting took %g seconds'%taken) + print('Original size:', sz(orig), 'Subset size:', sz(sf), + 'Reduced to: %g%%' % (reduced)) + print('Subsetting took %g seconds' % taken) with open(off, 'wb') as f: f.write(sf) - prints('Subset font written to:', off) + print('Subset font written to:', off) if __name__ == '__main__': diff --git a/ebook_converter/utils/formatter.py b/ebook_converter/utils/formatter.py index 5dbbfcc..19e836b 100644 --- a/ebook_converter/utils/formatter.py +++ b/ebook_converter/utils/formatter.py @@ -5,7 +5,6 @@ Created on 23 Sep 2010 """ import re, string, traceback, numbers -from ebook_converter import prints from ebook_converter.constants_old import DEBUG from ebook_converter.utils.formatter_functions import formatter_functions @@ -373,7 +372,7 @@ class TemplateFormatter(string.Formatter): if DEBUG: # and getattr(e, 'is_locking_error', False): traceback.print_exc() if column_name: - prints('Error evaluating column named:', column_name) + print('Error evaluating column named: {column_name}') ans = error_value + ' ' + str(e) return ans diff --git a/ebook_converter/utils/logging.py b/ebook_converter/utils/logging.py index c25ab46..3c06337 100644 --- a/ebook_converter/utils/logging.py +++ b/ebook_converter/utils/logging.py @@ -4,10 +4,10 @@ A simplified logging system import sys import traceback import io +import os from functools import partial -from threading import Lock -from ebook_converter import force_unicode, prints +from ebook_converter import constants_old DEBUG = 0 @@ -22,13 +22,13 @@ class Stream(object): if stream is None: stream = io.BytesIO() self.stream = getattr(stream, 'buffer', stream) - self._prints = partial(prints, safe_encode=True, file=stream) + # self._prints = partial(prints, safe_encode=True, file=stream) def flush(self): self.stream.flush() def prints(self, level, *args, **kwargs): - self._prints(*args, **kwargs) + raise NotImplementedError() class ANSIStream(Stream): @@ -43,97 +43,34 @@ class ANSIStream(Stream): } def prints(self, level, *args, **kwargs): - from ebook_converter.utils.terminal import ColoredStream - with ColoredStream(self.stream, self.color[level]): - self._prints(*args, **kwargs) - - def flush(self): - self.stream.flush() - - -class FileStream(Stream): - - def __init__(self, stream=None): - Stream.__init__(self, stream) - - def prints(self, level, *args, **kwargs): - self._prints(*args, **kwargs) - - -class HTMLStream(Stream): - - color = {DEBUG: b'', - INFO: b'', - WARN: b'', - ERROR: b''} - normal = b'' - - def __init__(self, stream=sys.stdout): - Stream.__init__(self, stream) - - def prints(self, level, *args, **kwargs): - self.stream.write(self.color[level]) - kwargs['file'] = self.stream - self._prints(*args, **kwargs) - self.stream.write(self.normal) - - def flush(self): - self.stream.flush() - - -class UnicodeHTMLStream(HTMLStream): - - color = {k: v.decode('ascii') for k, v in HTMLStream.color.items()} - normal = HTMLStream.normal.decode('ascii') - - def __init__(self): - self.clear() - - def flush(self): - pass - - def prints(self, level, *args, **kwargs): - col = self.color[level] - if col != self.last_col: - if self.data: - self.data.append(self.normal) - self.data.append(col) - self.last_col = col - + fobj = kwargs.get('file', sys.stdout) sep = kwargs.get('sep', ' ') + enc = ('utf-8' if os.getenv('CALIBRE_WORKER') + else constants_old.preferred_encoding) + if isinstance(sep, bytes): + sep = sep.decode(enc) end = kwargs.get('end', '\n') - - for arg in args: + if isinstance(end, bytes): + end = end.decode(enc) + count = 0 + for i, arg in enumerate(args): if isinstance(arg, bytes): - arg = force_unicode(arg) - elif not isinstance(arg, str): - arg = str(arg) - self.data.append(arg+sep) - self.plain_text.append(arg+sep) - self.data.append(end) - self.plain_text.append(end) + arg = arg.decode(enc) + arg = repr(arg) + try: + fobj.write(arg) + count += len(arg) + except Exception: + arg = repr(arg) + fobj.write(arg) + count += len(arg) + if i != len(args)-1: + fobj.write(sep) + count += len(sep) + count += len(end) - def clear(self): - self.data = [] - self.plain_text = [] - self.last_col = self.color[INFO] - - @property - def html(self): - end = self.normal if self.data else '' - return ''.join(self.data) + end - - def dump(self): - return [self.data, self.plain_text, self.last_col] - - def load(self, dump): - self.data, self.plain_text, self.last_col = dump - - def append_dump(self, dump): - d, p, lc = dump - self.data.extend(d) - self.plain_text.extend(p) - self.last_col = lc + def flush(self): + self.stream.flush() class Log(object): @@ -192,80 +129,4 @@ class Log(object): o.close() -class DevNull(Log): - - def __init__(self): - Log.__init__(self, level=Log.ERROR) - self.outputs = [] - - -class ThreadSafeLog(Log): - exception_traceback_level = Log.DEBUG - - def __init__(self, level=Log.INFO): - Log.__init__(self, level=level) - self._lock = Lock() - - def prints(self, *args, **kwargs): - with self._lock: - Log.prints(self, *args, **kwargs) - - def print_with_flush(self, *args, **kwargs): - with self._lock: - Log.print_with_flush(self, *args, **kwargs) - - def exception(self, *args, **kwargs): - limit = kwargs.pop('limit', None) - with self._lock: - Log.print_with_flush(self, ERROR, *args, **kwargs) - Log.print_with_flush(self, self.exception_traceback_level, - traceback.format_exc(limit)) - - -class ThreadSafeWrapper(Log): - - def __init__(self, other_log): - Log.__init__(self, level=other_log.filter_level) - self.outputs = list(other_log.outputs) - self._lock = Lock() - - def prints(self, *args, **kwargs): - with self._lock: - Log.prints(self, *args, **kwargs) - - def print_with_flush(self, *args, **kwargs): - with self._lock: - Log.print_with_flush(self, *args, **kwargs) - - -class GUILog(ThreadSafeLog): - """ - Logs in HTML and plain text as unicode. Ideal for display in a GUI context. - """ - - def __init__(self): - ThreadSafeLog.__init__(self, level=self.DEBUG) - self.outputs = [UnicodeHTMLStream()] - - def clear(self): - self.outputs[0].clear() - - @property - def html(self): - return self.outputs[0].html - - @property - def plain_text(self): - return u''.join(self.outputs[0].plain_text) - - def dump(self): - return self.outputs[0].dump() - - def load(self, dump): - return self.outputs[0].load(dump) - - def append_dump(self, dump): - return self.outputs[0].append_dump(dump) - - default_log = Log()