1
0
mirror of https://github.com/gryf/ebook-converter.git synced 2026-03-06 01:05:52 +01:00

Removed prints and extract function from init module

This commit is contained in:
2020-07-13 21:38:06 +02:00
parent 025878dfe5
commit 4216fef20e
20 changed files with 97 additions and 336 deletions

View File

@@ -14,9 +14,7 @@ from ebook_converter.constants_old import islinux, isfrozen, \
isbsd, __appname__, __version__, __author__, \ isbsd, __appname__, __version__, __author__, \
config_dir config_dir
from ebook_converter.ebooks.html_entities import html5_entities 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.startup import winutil, winutilerror
from ebook_converter.utils.unrar import extract as rarextract
if False: if False:
@@ -72,45 +70,6 @@ def sanitize_file_name(name, substitute='_'):
return one 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): def setup_cli_handlers(logger, level):
if os.getenv('CALIBRE_WORKER') and logger.handlers: if os.getenv('CALIBRE_WORKER') and logger.handlers:
return return
@@ -132,27 +91,6 @@ def setup_cli_handlers(logger, level):
logger.addHandler(handler) 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): def fit_image(width, height, pwidth, pheight):
""" """
Fit image in box of width pwidth and height pheight. Fit image in box of width pwidth and height pheight.

View File

@@ -12,7 +12,6 @@ from ebook_converter.customize import profiles
from ebook_converter.customize import builtins from ebook_converter.customize import builtins
from ebook_converter.ebooks import metadata from ebook_converter.ebooks import metadata
from ebook_converter.utils import config as cfg from ebook_converter.utils import config as cfg
from ebook_converter import prints
builtin_names = frozenset(p.name for p in builtins.plugins) 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 break
except Exception: except Exception:
if report_error is None: if report_error is None:
prints('Failed to set metadata for the', ftype.upper(), print('Failed to set metadata for the', ftype.upper(),
'format of:', getattr(mi, 'title', ''), 'format of:', getattr(mi, 'title', ''))
file=sys.stderr)
traceback.print_exc() traceback.print_exc()
else: else:
report_error(mi, ftype, traceback.format_exc()) report_error(mi, ftype, traceback.format_exc())

View File

@@ -1,7 +1,6 @@
import os import os
from collections import namedtuple from collections import namedtuple
from ebook_converter import prints
from ebook_converter.customize import Plugin from ebook_converter.customize import Plugin
@@ -170,7 +169,7 @@ class DevicePlugin(Plugin):
cbcd = self.BCD cbcd = self.BCD
if self.test_bcd(bcd, cbcd): if self.test_bcd(bcd, cbcd):
if debug: if debug:
prints(dev) print(dev)
if ch(dev, debug=debug): if ch(dev, debug=debug):
return True, dev return True, dev
return False, None return False, None

View File

@@ -5,11 +5,9 @@ from various formats.
import numbers import numbers
import os import os
import re import re
import sys
from lxml import etree from lxml import etree
from ebook_converter import prints
from ebook_converter.ebooks.chardet import xml_to_unicode from ebook_converter.ebooks.chardet import xml_to_unicode
@@ -123,13 +121,14 @@ def render_html_data(path_to_html, width, height):
result = {} result = {}
def report_error(text=''): def report_error(text=''):
prints('Failed to render', path_to_html, 'with errors:', __import__('pdb').set_trace()
file=sys.stderr) print(f'Failed to render {path_to_html}')
# file=sys.stderr)
if text: if text:
prints(text, file=sys.stderr) print(text) # , file=sys.stderr)
if result and result['stdout_stderr']: if result and result['stdout_stderr']:
with open(result['stdout_stderr'], 'rb') as f: 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: with TemporaryDirectory('-render-html') as tdir:
try: try:

View File

@@ -14,7 +14,6 @@ from ebook_converter.ebooks.conversion.preprocess import HTMLPreProcessor
from ebook_converter.ptempfile import PersistentTemporaryDirectory from ebook_converter.ptempfile import PersistentTemporaryDirectory
from ebook_converter.utils.date import parse_date from ebook_converter.utils.date import parse_date
from ebook_converter.utils.zipfile import ZipFile from ebook_converter.utils.zipfile import ZipFile
from ebook_converter import extract, walk
from ebook_converter import constants from ebook_converter import constants
from ebook_converter.constants_old import filesystem_encoding from ebook_converter.constants_old import filesystem_encoding
@@ -694,11 +693,6 @@ OptionRecommendation(name='search_replace',
input_fmt = 'epub' input_fmt = 'epub'
self.archive_input_tdir = None self.archive_input_tdir = None
self.changed_options = set() 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): if os.access(self.input, os.R_OK):
nfp = run_plugins_on_preprocess(self.input, input_fmt) nfp = run_plugins_on_preprocess(self.input, input_fmt)
if nfp != self.input: if nfp != self.input:
@@ -761,25 +755,6 @@ OptionRecommendation(name='search_replace',
if merge_plugin_recs: if merge_plugin_recs:
self.merge_plugin_recommendations() 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 @classmethod
def find_html_index(self, files): def find_html_index(self, files):
''' '''

View File

@@ -8,7 +8,7 @@ import sys
import urllib.parse import urllib.parse
from ebook_converter.ebooks.chardet import detect_xml_encoding 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): class Link(object):

View File

@@ -24,7 +24,6 @@ class HTML2ZIP(FileTypePlugin):
def run(self, htmlfile): def run(self, htmlfile):
import codecs import codecs
from ebook_converter import prints
from ebook_converter.ptempfile import TemporaryDirectory from ebook_converter.ptempfile import TemporaryDirectory
from ebook_converter.gui2.convert.gui_conversion import gui_convert from ebook_converter.gui2.convert.gui_conversion import gui_convert
from ebook_converter.customize.conversion import OptionRecommendation from ebook_converter.customize.conversion import OptionRecommendation
@@ -40,7 +39,8 @@ class HTML2ZIP(FileTypePlugin):
try: try:
codecs.lookup(enc) codecs.lookup(enc)
except Exception: except Exception:
prints('Ignoring invalid input encoding for HTML:', enc) print('Ignoring invalid input encoding for HTML: %s',
enc)
else: else:
recs.append(['input_encoding', enc, OptionRecommendation.HIGH]) recs.append(['input_encoding', enc, OptionRecommendation.HIGH])
if bf == 'bf': if bf == 'bf':

View File

@@ -8,7 +8,7 @@ import re
import sys import sys
import urllib.parse 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.utils.config_base import tweaks
from ebook_converter.polyglot.urllib import unquote from ebook_converter.polyglot.urllib import unquote
@@ -16,8 +16,8 @@ from ebook_converter.polyglot.urllib import unquote
try: try:
_author_pat = re.compile(tweaks['authors_split_regex']) _author_pat = re.compile(tweaks['authors_split_regex'])
except Exception: except Exception:
prints('Author split regexp:', tweaks['authors_split_regex'], print(f"Author split regexp: {tweaks['authors_split_regex']}, is invalid, "
'is invalid, using default') f"using default")
_author_pat = re.compile(r'(?i),?\s+(and|with)\s+') _author_pat = re.compile(r'(?i),?\s+(and|with)\s+')

View File

@@ -1,6 +1,5 @@
import copy, traceback import copy, traceback
from ebook_converter import prints
from ebook_converter.constants_old import DEBUG from ebook_converter.constants_old import DEBUG
from ebook_converter.ebooks.metadata.book import (SC_COPYABLE_FIELDS, from ebook_converter.ebooks.metadata.book import (SC_COPYABLE_FIELDS,
SC_FIELDS_COPY_NOT_NULL, STANDARD_METADATA_FIELDS, SC_FIELDS_COPY_NOT_NULL, STANDARD_METADATA_FIELDS,
@@ -453,12 +452,12 @@ class Metadata(object):
# Old Metadata API {{{ # Old Metadata API {{{
def print_all_attributes(self): def print_all_attributes(self):
for x in STANDARD_METADATA_FIELDS: 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(): for x in self.custom_field_keys():
meta = self.get_user_metadata(x, make_copy=False) meta = self.get_user_metadata(x, make_copy=False)
if meta is not None: if meta is not None:
prints(x, meta) print(x, meta)
prints('--------------') print('--------------')
def smart_update(self, other, replace_metadata=False): def smart_update(self, other, replace_metadata=False):
''' '''

View File

@@ -12,7 +12,7 @@ from lxml import etree
from ebook_converter.utils.date import parse_only_date from ebook_converter.utils.date import parse_only_date
from ebook_converter.utils.img import save_cover_data_to from ebook_converter.utils.img import save_cover_data_to
from ebook_converter.utils.imghdr import identify 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.metadata import MetaInformation, check_isbn
from ebook_converter.ebooks.chardet import xml_to_unicode from ebook_converter.ebooks.chardet import xml_to_unicode
from ebook_converter.polyglot.binary import as_base64_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] fmt = identify(cdata)[0]
mi.cover_data = (fmt, cdata) mi.cover_data = (fmt, cdata)
else: else:
prints("WARNING: Unsupported coverpage mime-type '%s' (id=#%s)" % print(f"WARNING: Unsupported coverpage mime-type '{mimetype}' "
(mimetype, imgid)) f"(id=#{imgid})")
def _parse_tags(root, mi, ctx): def _parse_tags(root, mi, ctx):

View File

@@ -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.ebooks.metadata.book.base import Metadata
from ebook_converter.utils.date import parse_date, isoformat from ebook_converter.utils.date import parse_date, isoformat
from ebook_converter.utils.localization import get_lang, canonicalize_lang 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.cleantext import clean_ascii_chars, clean_xml_chars
from ebook_converter.utils.config import tweaks from ebook_converter.utils.config import tweaks
from ebook_converter.polyglot.urllib import unquote 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 = object_to_unicode(fm)
fm = json.dumps(fm, default=to_json, ensure_ascii=False) fm = json.dumps(fm, default=to_json, ensure_ascii=False)
except Exception: except Exception:
prints('Failed to write user metadata:', name) print('Failed to write user metadata: {name}')
traceback.print_exc() traceback.print_exc()
continue continue
meta = metadata_elem.makeelement('meta') meta = metadata_elem.makeelement('meta')
@@ -671,7 +670,7 @@ class OPF(object): # {{{
decode_is_multiple(fm) decode_is_multiple(fm)
temp.set_user_metadata(name, fm) temp.set_user_metadata(name, fm)
except Exception: except Exception:
prints('Failed to read user metadata:', name) print('Failed to read user metadata: {name}')
traceback.print_exc() traceback.print_exc()
continue continue
self._user_metadata_ = temp.get_all_user_metadata(True) self._user_metadata_ = temp.get_all_user_metadata(True)

View File

@@ -6,7 +6,6 @@ import re
from lxml import etree from lxml import etree
from ebook_converter import constants as const 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 authors_to_string
from ebook_converter.ebooks.metadata import check_isbn from ebook_converter.ebooks.metadata import check_isbn
from ebook_converter.ebooks.metadata import string_to_authors 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) decode_is_multiple(fm)
ans[name] = fm ans[name] = fm
except Exception: except Exception:
prints('Failed to read user metadata:', name) print('Failed to read user metadata: {name}')
import traceback import traceback
traceback.print_exc() traceback.print_exc()
continue continue

View File

@@ -4,7 +4,6 @@ Read meta information from PDF files
import os, subprocess, shutil, re import os, subprocess, shutil, re
from functools import partial from functools import partial
from ebook_converter import prints
from ebook_converter.ptempfile import TemporaryDirectory from ebook_converter.ptempfile import TemporaryDirectory
from ebook_converter.ebooks.metadata import ( from ebook_converter.ebooks.metadata import (
MetaInformation, string_to_authors, check_isbn, check_doi) 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', raw = subprocess.check_output([pdfinfo, '-enc', 'UTF-8', '-isodates',
source_file]) source_file])
except subprocess.CalledProcessError as e: 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 return None
try: try:
info_raw = raw.decode('utf-8') info_raw = raw.decode('utf-8')
except UnicodeDecodeError: except UnicodeDecodeError:
prints('pdfinfo returned no UTF-8 data') print('pdfinfo returned no UTF-8 data')
return None return None
for line in info_raw.splitlines(): for line in info_raw.splitlines():
@@ -63,7 +62,8 @@ def read_info(outputdir, get_cover):
try: try:
raw = subprocess.check_output([pdfinfo, '-meta', source_file]).strip() raw = subprocess.check_output([pdfinfo, '-meta', source_file]).strip()
except subprocess.CalledProcessError as e: 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: else:
parts = re.split(br'^Metadata:', raw, 1, flags=re.MULTILINE) parts = re.split(br'^Metadata:', raw, 1, flags=re.MULTILINE)
if len(parts) > 1: if len(parts) > 1:
@@ -77,7 +77,7 @@ def read_info(outputdir, get_cover):
subprocess.check_call([pdftoppm, '-singlefile', '-jpeg', subprocess.check_call([pdftoppm, '-singlefile', '-jpeg',
'-cropbox', source_file, cover_file]) '-cropbox', source_file, cover_file])
except subprocess.CalledProcessError as e: 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 return ans

View File

@@ -4,11 +4,11 @@ import itertools
import json import json
import re import re
import sys import sys
import traceback
from lxml import etree from lxml import etree
from lxml.builder import ElementMaker 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 import check_isbn, check_doi
from ebook_converter.ebooks.metadata.book.base import Metadata from ebook_converter.ebooks.metadata.book.base import Metadata
from ebook_converter.ebooks.metadata.opf2 import dump_dict 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) mi.set_user_metadata(name, fm)
fields.add(name) fields.add(name)
except Exception: except Exception:
prints('Failed to read user metadata:', name) print(f'Failed to read user metadata: {name}')
import traceback import traceback
traceback.print_exc() traceback.print_exc()
@@ -467,8 +467,7 @@ def create_user_metadata(calibre, all_user_metadata):
fm = object_to_unicode(fm) fm = object_to_unicode(fm)
fm = json.dumps(fm, default=to_json, ensure_ascii=False) fm = json.dumps(fm, default=to_json, ensure_ascii=False)
except Exception: except Exception:
prints('Failed to write user metadata:', name) print('Failed to write user metadata: {name}')
import traceback
traceback.print_exc() traceback.print_exc()
continue continue
li = bag.makeelement(expand('rdf:li')) li = bag.makeelement(expand('rdf:li'))

View File

@@ -7,7 +7,7 @@ import sys
from lxml import etree 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.constants_old import isbsd, islinux, isosx
from ebook_converter.ebooks import ConversionError, DRMError from ebook_converter.ebooks import ConversionError, DRMError
from ebook_converter.ebooks.chardet import xml_to_unicode 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: ' raise ConversionError('pdftohtml failed with return code: '
'%d\n%s' % (ret, out)) '%d\n%s' % (ret, out))
if out: if out:
prints("pdftohtml log:") print("pdftohtml log:")
prints(out) print(out)
if not os.path.exists(index) or os.stat(index).st_size < 100: if not os.path.exists(index) or os.stat(index).st_size < 100:
raise DRMError() raise DRMError()

View File

@@ -5,13 +5,11 @@ meaning as possible.
import errno import errno
import os import os
import shutil import shutil
import time
from math import ceil from math import ceil
from ebook_converter import force_unicode, prints, sanitize_file_name from ebook_converter import force_unicode, sanitize_file_name
from ebook_converter.constants_old import ( from ebook_converter.constants_old import (filesystem_encoding,
filesystem_encoding, plugins, preferred_encoding, isosx preferred_encoding)
)
from ebook_converter.utils.localization import get_udc from ebook_converter.utils.localization import get_udc

View File

@@ -2,7 +2,7 @@ import os
from collections import defaultdict from collections import defaultdict
from threading import Thread 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 isosx
from ebook_converter.constants_old import plugins, DEBUG from ebook_converter.constants_old import plugins, DEBUG
from ebook_converter.constants_old import filesystem_encoding from ebook_converter.constants_old import filesystem_encoding
@@ -67,7 +67,7 @@ def fc_list():
try: try:
ans.append(d.decode(filesystem_encoding)) ans.append(d.decode(filesystem_encoding))
except ValueError: except ValueError:
prints('Ignoring undecodeable font path: %r' % d) print(f'Ignoring undecodeable font path: {d}')
continue continue
end(str_list) end(str_list)
if len(ans) < 3: if len(ans) < 3:
@@ -309,7 +309,7 @@ class FontScanner(Thread):
files = tuple(walk(folder)) files = tuple(walk(folder))
except EnvironmentError as e: except EnvironmentError as e:
if DEBUG: if DEBUG:
prints('Failed to walk font folder:', folder, str(e)) print(f'Failed to walk font folder: {folder}, {e}')
continue continue
for candidate in files: for candidate in files:
if (candidate.rpartition('.')[-1].lower() not in if (candidate.rpartition('.')[-1].lower() not in
@@ -332,8 +332,8 @@ class FontScanner(Thread):
self.read_font_metadata(candidate, fileid) self.read_font_metadata(candidate, fileid)
except Exception as e: except Exception as e:
if DEBUG: if DEBUG:
prints('Failed to read metadata from font file:', print(f'Failed to read metadata from font file '
candidate, str(e)) f'{candidate}: {e}')
continue continue
if frozenset(cached_fonts) != frozenset(self.cached_fonts): if frozenset(cached_fonts) != frozenset(self.cached_fonts):
@@ -369,18 +369,18 @@ class FontScanner(Thread):
def dump_fonts(self): def dump_fonts(self):
self.join() self.join()
for family in self.font_families: for family in self.font_families:
prints(family) print(family)
for font in self.fonts_for_family(family): for font in self.fonts_for_family(family):
prints('\t%s: %s' % (font['full_name'], font['path'])) print('\t%s: %s' % (font['full_name'], font['path']))
prints(end='\t') print(end='\t')
for key in ('font-stretch', 'font-weight', 'font-style'): for key in ('font-stretch', 'font-weight', 'font-style'):
prints('%s: %s' % (key, font[key]), end=' ') print('%s: %s' % (key, font[key]))
prints() print()
prints('\tSub-family:', font['wws_subfamily_name'] or print('\tSub-family: %s' % (font['wws_subfamily_name'] or
font['preferred_subfamily_name'] or font['preferred_subfamily_name']
font['subfamily_name']) or font['subfamily_name']))
prints() print()
prints() print()
font_scanner = FontScanner() font_scanner = FontScanner()

View File

@@ -204,15 +204,13 @@ def option_parser():
def print_stats(old_stats, new_stats): def print_stats(old_stats, new_stats):
from ebook_converter import prints print('========= Table comparison (original vs. subset) =========')
prints('========= Table comparison (original vs. subset) =========') print('Table Size Percent New Size New Percent')
prints('Table', ' ', '%10s'%'Size', ' ', 'Percent', ' ', '%10s'%'New Size', print('='*80)
' New Percent')
prints('='*80)
old_total = sum(old_stats.values()) old_total = sum(old_stats.values())
new_total = sum(new_stats.values()) new_total = sum(new_stats.values())
tables = sorted(old_stats, key=lambda x:old_stats[x], tables = sorted(old_stats, key=lambda x: old_stats[x],
reverse=True) reverse=True)
for table in tables: for table in tables:
osz = old_stats[table] osz = old_stats[table]
op = osz/old_total * 100 op = osz/old_total * 100
@@ -220,15 +218,14 @@ def print_stats(old_stats, new_stats):
np = nsz/new_total * 100 np = nsz/new_total * 100
suffix = ' | same size' suffix = ' | same size'
if nsz != osz: if nsz != osz:
suffix = ' | reduced to %.1f %%'%(nsz/osz * 100) suffix = ' | reduced to %.1f %%' % (nsz/osz * 100)
prints('%4s'%table, ' ', '%10s'%osz, ' ', '%5.1f %%'%op, ' ', print('%4s %10s %5.1f %% %10s %5.1f %% %s' %
'%10s'%nsz, ' ', '%5.1f %%'%np, suffix) (table, osz, op, nsz, np, suffix))
prints('='*80) print('='*80)
def main(args): def main(args):
import sys, time import sys, time
from ebook_converter import prints
parser = option_parser() parser = option_parser()
opts, args = parser.parse_args(args) opts, args = parser.parse_args(args)
if len(args) < 4 or len(args) > 4: if len(args) < 4 or len(args) > 4:
@@ -243,7 +240,7 @@ def main(args):
def not_single(c): def not_single(c):
if len(c) > 1: 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) raise SystemExit(1)
def conv_code(c): def conv_code(c):
@@ -255,7 +252,7 @@ def main(args):
if '-' in c: if '-' in c:
parts = [x.strip() for x in c.split('-')] parts = [x.strip() for x in c.split('-')]
if len(parts) != 2: if len(parts) != 2:
prints('Invalid range:', c, file=sys.stderr) print(f'Invalid range: {c}')
raise SystemExit(1) raise SystemExit(1)
if opts.codes: if opts.codes:
parts = tuple(map(conv_code, parts)) parts = tuple(map(conv_code, parts))
@@ -272,13 +269,14 @@ def main(args):
reduced = (len(sf)/len(orig)) * 100 reduced = (len(sf)/len(orig)) * 100
def sz(x): def sz(x):
return '%gKB'%(len(x)/1024.) return '%gKB' % (len(x)/1024.)
print_stats(old_stats, new_stats) print_stats(old_stats, new_stats)
prints('Original size:', sz(orig), 'Subset size:', sz(sf), 'Reduced to: %g%%'%(reduced)) print('Original size:', sz(orig), 'Subset size:', sz(sf),
prints('Subsetting took %g seconds'%taken) 'Reduced to: %g%%' % (reduced))
print('Subsetting took %g seconds' % taken)
with open(off, 'wb') as f: with open(off, 'wb') as f:
f.write(sf) f.write(sf)
prints('Subset font written to:', off) print('Subset font written to:', off)
if __name__ == '__main__': if __name__ == '__main__':

View File

@@ -5,7 +5,6 @@ Created on 23 Sep 2010
""" """
import re, string, traceback, numbers import re, string, traceback, numbers
from ebook_converter import prints
from ebook_converter.constants_old import DEBUG from ebook_converter.constants_old import DEBUG
from ebook_converter.utils.formatter_functions import formatter_functions 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): if DEBUG: # and getattr(e, 'is_locking_error', False):
traceback.print_exc() traceback.print_exc()
if column_name: if column_name:
prints('Error evaluating column named:', column_name) print('Error evaluating column named: {column_name}')
ans = error_value + ' ' + str(e) ans = error_value + ' ' + str(e)
return ans return ans

View File

@@ -4,10 +4,10 @@ A simplified logging system
import sys import sys
import traceback import traceback
import io import io
import os
from functools import partial from functools import partial
from threading import Lock
from ebook_converter import force_unicode, prints from ebook_converter import constants_old
DEBUG = 0 DEBUG = 0
@@ -22,13 +22,13 @@ class Stream(object):
if stream is None: if stream is None:
stream = io.BytesIO() stream = io.BytesIO()
self.stream = getattr(stream, 'buffer', stream) 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): def flush(self):
self.stream.flush() self.stream.flush()
def prints(self, level, *args, **kwargs): def prints(self, level, *args, **kwargs):
self._prints(*args, **kwargs) raise NotImplementedError()
class ANSIStream(Stream): class ANSIStream(Stream):
@@ -43,97 +43,34 @@ class ANSIStream(Stream):
} }
def prints(self, level, *args, **kwargs): def prints(self, level, *args, **kwargs):
from ebook_converter.utils.terminal import ColoredStream fobj = kwargs.get('file', sys.stdout)
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'<span style="color:green">',
INFO: b'<span>',
WARN: b'<span style="color:blue">',
ERROR: b'<span style="color:red">'}
normal = b'</span>'
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
sep = kwargs.get('sep', ' ') 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') end = kwargs.get('end', '\n')
if isinstance(end, bytes):
for arg in args: end = end.decode(enc)
count = 0
for i, arg in enumerate(args):
if isinstance(arg, bytes): if isinstance(arg, bytes):
arg = force_unicode(arg) arg = arg.decode(enc)
elif not isinstance(arg, str): arg = repr(arg)
arg = str(arg) try:
self.data.append(arg+sep) fobj.write(arg)
self.plain_text.append(arg+sep) count += len(arg)
self.data.append(end) except Exception:
self.plain_text.append(end) 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): def flush(self):
self.data = [] self.stream.flush()
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
class Log(object): class Log(object):
@@ -192,80 +129,4 @@ class Log(object):
o.close() 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() default_log = Log()