diff --git a/ebook_converter/__init__.py b/ebook_converter/__init__.py index 4055a56..c920e9f 100644 --- a/ebook_converter/__init__.py +++ b/ebook_converter/__init__.py @@ -26,7 +26,7 @@ except EnvironmentError: from ebook_converter.constants import (iswindows, isosx, islinux, isfrozen, isbsd, preferred_encoding, __appname__, __version__, __author__, - win32event, win32api, winerror, fcntl, ispy3, + win32event, win32api, winerror, fcntl, filesystem_encoding, plugins, config_dir) from ebook_converter.startup import winutil, winutilerror from ebook_converter.utils.icu import safe_chr @@ -453,30 +453,11 @@ class CurrentDir(object): _ncpus = None -if ispy3: - def detect_ncpus(): - global _ncpus - if _ncpus is None: - _ncpus = max(1, os.cpu_count() or 1) - return _ncpus -else: - def detect_ncpus(): - """Detects the number of effective CPUs in the system""" - global _ncpus - if _ncpus is None: - if iswindows: - import win32api - ans = win32api.GetSystemInfo()[5] - else: - import multiprocessing - ans = -1 - try: - ans = multiprocessing.cpu_count() - except Exception: - from PyQt5.Qt import QThread - ans = QThread.idealThreadCount() - _ncpus = max(1, ans) - return _ncpus +def detect_ncpus(): + global _ncpus + if _ncpus is None: + _ncpus = max(1, os.cpu_count() or 1) + return _ncpus relpath = os.path.relpath diff --git a/ebook_converter/constants.py b/ebook_converter/constants.py index c9b7074..654a295 100644 --- a/ebook_converter/constants.py +++ b/ebook_converter/constants.py @@ -31,7 +31,6 @@ islinux = not(iswindows or isosx or isbsd or ishaiku) isfrozen = hasattr(sys, 'frozen') isunix = isosx or islinux or ishaiku isportable = hasenv('CALIBRE_PORTABLE_BUILD') -ispy3 = sys.version_info.major > 2 isxp = isoldvista = False if iswindows: wver = sys.getwindowsversion() @@ -153,10 +152,6 @@ def cache_dir(): return ans -# plugins_loc = sys.extensions_location -# if ispy3: - # plugins_loc = os.path.join(plugins_loc, '3') - # plugins {{{ @@ -165,45 +160,7 @@ class Plugins(collections.Mapping): def __init__(self): self._plugins = {} - plugins = [] - # plugins = [ - # 'pictureflow', - # 'lzx', - # 'msdes', - # 'podofo', - # 'cPalmdoc', - # 'progress_indicator', - # 'chmlib', - # 'icu', - # 'speedup', - # 'html_as_json', - # 'unicode_names', - # 'html_syntax_highlighter', - # 'hyphen', - # 'freetype', - # 'imageops', - # 'hunspell', - # '_patiencediff_c', - # 'bzzdec', - # 'matcher', - # 'tokenizer', - # 'certgen', - # 'lzma_binding', - # ] - # if not ispy3: - # plugins.extend([ - # 'monotonic', - # 'zlib2', - # ]) - if iswindows: - plugins.extend(['winutil', 'wpd', 'winfonts']) - if isosx: - plugins.append('usbobserver') - plugins.append('cocoa') - if isfreebsd or ishaiku or islinux or isosx: - plugins.append('libusb') - plugins.append('libmtp') - self.plugins = frozenset(plugins) + self.plugins = frozenset([]) def load_plugin(self, name): if name in self._plugins: diff --git a/ebook_converter/customize/zipplugin.py b/ebook_converter/customize/zipplugin.py index ddc9f10..29e3c01 100644 --- a/ebook_converter/customize/zipplugin.py +++ b/ebook_converter/customize/zipplugin.py @@ -8,7 +8,6 @@ from collections import OrderedDict from functools import partial from ebook_converter import as_unicode -from ebook_converter.constants import ispy3 from ebook_converter.customize import (Plugin, numeric_version, platform, InvalidPlugin, PluginNotFound) from ebook_converter.polyglot.builtins import reload @@ -108,8 +107,8 @@ def load_translations(namespace, zfp): from io import BytesIO trans = _translations_cache[zfp] = GNUTranslations(BytesIO(mo)) - namespace['_'] = getattr(trans, 'gettext' if ispy3 else 'ugettext') - namespace['ngettext'] = getattr(trans, 'ngettext' if ispy3 else 'ungettext') + namespace['_'] = getattr(trans, 'gettext') + namespace['ngettext'] = getattr(trans, 'ngettext') class PluginLoader(object): diff --git a/ebook_converter/ebooks/compression/cPalmdoc.cpython-36m-x86_64-linux-gnu.so b/ebook_converter/ebooks/compression/cPalmdoc.cpython-36m-x86_64-linux-gnu.so new file mode 100755 index 0000000..d0bbd0e Binary files /dev/null and b/ebook_converter/ebooks/compression/cPalmdoc.cpython-36m-x86_64-linux-gnu.so differ diff --git a/ebook_converter/ebooks/metadata/book/base.py b/ebook_converter/ebooks/metadata/book/base.py index 784a763..56c7571 100644 --- a/ebook_converter/ebooks/metadata/book/base.py +++ b/ebook_converter/ebooks/metadata/book/base.py @@ -1,7 +1,7 @@ import copy, traceback from ebook_converter import prints -from ebook_converter.constants import DEBUG, ispy3 +from ebook_converter.constants import DEBUG from ebook_converter.ebooks.metadata.book import (SC_COPYABLE_FIELDS, SC_FIELDS_COPY_NOT_NULL, STANDARD_METADATA_FIELDS, TOP_LEVEL_IDENTIFIERS, ALL_METADATA_FIELDS) @@ -789,13 +789,7 @@ class Metadata(object): ans[i] = '%s%s'%x return '%s
'%'\n'.join(ans) - if ispy3: - __str__ = __unicode__representation__ - else: - __unicode__ = __unicode__representation__ - - def __str__(self): - return self.__unicode__().encode('utf-8') + __str__ = __unicode__representation__ def __nonzero__(self): return bool(self.title or self.author or self.comments or self.tags) diff --git a/ebook_converter/ebooks/metadata/opf2.py b/ebook_converter/ebooks/metadata/opf2.py index 19f8a3c..e797b26 100644 --- a/ebook_converter/ebooks/metadata/opf2.py +++ b/ebook_converter/ebooks/metadata/opf2.py @@ -16,7 +16,7 @@ import uuid from lxml import etree from ebook_converter.ebooks import escape_xpath_attr -from ebook_converter.constants import __appname__, __version__, filesystem_encoding, ispy3 +from ebook_converter.constants import __appname__, __version__, filesystem_encoding from ebook_converter.ebooks.metadata.toc import TOC from ebook_converter.ebooks.metadata.utils import parse_opf, pretty_print_opf as _pretty_print from ebook_converter.ebooks.metadata import string_to_authors, MetaInformation, check_isbn @@ -212,13 +212,7 @@ class ManifestItem(Resource): # {{{ def __unicode__representation__(self): return u''%(self.id, self.href(), self.media_type) - if ispy3: - __str__ = __unicode__representation__ - else: - __unicode__ = __unicode__representation__ - - def __str__(self): - return str(self).encode('utf-8') + __str__ = __unicode__representation__ def __repr__(self): return str(self) diff --git a/ebook_converter/ebooks/metadata/pdf.py b/ebook_converter/ebooks/metadata/pdf.py index 20431a3..aff4f9c 100644 --- a/ebook_converter/ebooks/metadata/pdf.py +++ b/ebook_converter/ebooks/metadata/pdf.py @@ -5,7 +5,7 @@ import os, subprocess, shutil, re from functools import partial from ebook_converter import prints -from ebook_converter.constants import iswindows, ispy3 +from ebook_converter.constants import iswindows from ebook_converter.ptempfile import TemporaryDirectory from ebook_converter.ebooks.metadata import ( MetaInformation, string_to_authors, check_isbn, check_doi) @@ -101,8 +101,6 @@ def page_images(pdfpath, outputdir='.', first=1, last=1, image_format='jpeg', pr def is_pdf_encrypted(path_to_pdf): - if not ispy3 and not isinstance(path_to_pdf, bytes): - path_to_pdf = path_to_pdf.encode('mbcs' if iswindows else 'utf-8') pdfinfo = get_tools()[0] raw = subprocess.check_output([pdfinfo, path_to_pdf]) q = re.search(br'^Encrypted:\s*(\S+)', raw, flags=re.MULTILINE) diff --git a/ebook_converter/ebooks/oeb/base.py b/ebook_converter/ebooks/oeb/base.py index 824b6fb..9cf57c5 100644 --- a/ebook_converter/ebooks/oeb/base.py +++ b/ebook_converter/ebooks/oeb/base.py @@ -9,7 +9,7 @@ import urllib.parse from lxml import etree, html from ebook_converter import force_unicode -from ebook_converter.constants import filesystem_encoding, __version__, ispy3 +from ebook_converter.constants import filesystem_encoding, __version__ from ebook_converter.utils.xml_parse import safe_xml_fromstring from ebook_converter.ebooks.chardet import xml_to_unicode from ebook_converter.ebooks.conversion.preprocess import CSSPreProcessor @@ -753,15 +753,8 @@ class Metadata(object): return 'Item(term=%r, value=%r, attrib=%r)' \ % (barename(self.term), self.value, self.attrib) - if ispy3: - def __str__(self): - return as_unicode(self.value) - else: - def __str__(self): - return str(self.value).encode('ascii', 'xmlcharrefreplace') - - def __unicode__(self): - return as_unicode(self.value) + def __str__(self): + return as_unicode(self.value) def to_opf1(self, dcmeta=None, xmeta=None, nsrmap={}): attrib = {} @@ -1096,15 +1089,8 @@ class Manifest(object): def bytes_representation(self): return serialize(self.data, self.media_type, pretty_print=self.oeb.pretty_print) - if ispy3: - def __str__(self): - return self.unicode_representation - else: - def __unicode__(self): - return self.unicode_representation - - def __str__(self): - return self.bytes_representation + def __str__(self): + return self.unicode_representation def __eq__(self, other): return self is other @@ -1615,15 +1601,8 @@ class TOC(object): ans.extend(child.get_lines(lvl+1)) return ans - if ispy3: - def __str__(self): - return '\n'.join(self.get_lines()) - else: - def __unicode__(self): - return '\n'.join(self.get_lines()) - - def __str__(self): - return b'\n'.join([x.encode('utf-8') for x in self.get_lines()]) + def __str__(self): + return '\n'.join(self.get_lines()) def to_opf1(self, tour): for node in self.nodes: diff --git a/ebook_converter/ebooks/pdf/pdftohtml.py b/ebook_converter/ebooks/pdf/pdftohtml.py index 7353747..448d837 100644 --- a/ebook_converter/ebooks/pdf/pdftohtml.py +++ b/ebook_converter/ebooks/pdf/pdftohtml.py @@ -7,7 +7,7 @@ import sys from ebook_converter import CurrentDir, xml_replace_entities, prints from ebook_converter.constants import ( - filesystem_encoding, isbsd, islinux, isosx, ispy3, iswindows + filesystem_encoding, isbsd, islinux, isosx, iswindows ) from ebook_converter.ebooks import ConversionError, DRMError from ebook_converter.ebooks.chardet import xml_to_unicode @@ -20,8 +20,6 @@ PDFTOHTML = 'pdftohtml' def popen(cmd, **kw): - if not ispy3: - cmd = [x.encode(filesystem_encoding) if not isinstance(x, bytes) else x for x in cmd] if iswindows: kw['creationflags'] = 0x08 return subprocess.Popen(cmd, **kw) diff --git a/ebook_converter/ebooks/pdf/render/common.py b/ebook_converter/ebooks/pdf/render/common.py index 2407f0f..5dcd914 100644 --- a/ebook_converter/ebooks/pdf/render/common.py +++ b/ebook_converter/ebooks/pdf/render/common.py @@ -2,7 +2,6 @@ import codecs, zlib, numbers from io import BytesIO from datetime import datetime -from ebook_converter.constants import ispy3 from ebook_converter.utils.logging import default_log from ebook_converter.polyglot.binary import as_hex_bytes @@ -65,7 +64,7 @@ def serialize(o, stream): # Must check bool before int as bools are subclasses of int stream.write_raw(b'true' if o else b'false') elif isinstance(o, numbers.Integral): - stream.write_raw(str(o).encode('ascii') if ispy3 else bytes(o)) + stream.write_raw(str(o).encode('ascii')) elif hasattr(o, 'pdf_serialize'): o.pdf_serialize(stream) elif o is None: diff --git a/ebook_converter/ptempfile.py b/ebook_converter/ptempfile.py index b20a896..5dca4f7 100644 --- a/ebook_converter/ptempfile.py +++ b/ebook_converter/ptempfile.py @@ -7,7 +7,7 @@ being closed. import tempfile, os, atexit from ebook_converter.constants import (__version__, __appname__, filesystem_encoding, - iswindows, get_windows_temp_path, isosx, ispy3) + iswindows, get_windows_temp_path, isosx) def cleanup(path): @@ -263,23 +263,17 @@ class SpooledTemporaryFile(tempfile.SpooledTemporaryFile): suffix = '' if dir is None: dir = base_dir() - if ispy3: - self._name = None - tempfile.SpooledTemporaryFile.__init__(self, max_size=max_size, - suffix=suffix, prefix=prefix, dir=dir, mode=mode) - else: - tempfile.SpooledTemporaryFile.__init__(self, max_size=max_size, - suffix=suffix, prefix=prefix, dir=dir, mode=mode, - bufsize=bufsize) + self._name = None + tempfile.SpooledTemporaryFile.__init__(self, max_size=max_size, + suffix=suffix, prefix=prefix, dir=dir, mode=mode) - if ispy3: - @property - def name(self): - return self._name + @property + def name(self): + return self._name - @name.setter - def name(self, val): - self._name = val + @name.setter + def name(self, val): + self._name = val def truncate(self, *args): # The stdlib SpooledTemporaryFile implementation of truncate() doesn't diff --git a/ebook_converter/utils/config_base.py b/ebook_converter/utils/config_base.py index 4b61ab1..20ddee0 100644 --- a/ebook_converter/utils/config_base.py +++ b/ebook_converter/utils/config_base.py @@ -9,16 +9,13 @@ from copy import deepcopy import pkg_resources from ebook_converter.utils.lock import ExclusiveFile -from ebook_converter.constants import config_dir, CONFIG_DIR_MODE, ispy3, preferred_encoding, filesystem_encoding, iswindows +from ebook_converter.constants import config_dir, CONFIG_DIR_MODE, preferred_encoding, filesystem_encoding, iswindows plugin_dir = os.path.join(config_dir, 'plugins') def parse_old_style(src): - if ispy3: - import pickle as cPickle - else: - import cPickle + import pickle as cPickle options = {'cPickle':cPickle} try: if not isinstance(src, str): diff --git a/ebook_converter/utils/filenames.py b/ebook_converter/utils/filenames.py index aee812c..d45af47 100644 --- a/ebook_converter/utils/filenames.py +++ b/ebook_converter/utils/filenames.py @@ -10,7 +10,7 @@ from math import ceil from ebook_converter import force_unicode, isbytestring, prints, sanitize_file_name from ebook_converter.constants import ( - filesystem_encoding, iswindows, plugins, preferred_encoding, isosx, ispy3 + filesystem_encoding, iswindows, plugins, preferred_encoding, isosx ) from ebook_converter.utils.localization import get_udc @@ -624,16 +624,3 @@ def copytree_using_links(path, dest, dest_is_parent=True, filecopyfunc=copyfile) hardlink(src, df) except Exception: filecopyfunc(src, df) - - -if not ispy3 and not iswindows: - # On POSIX in python2 if you pass a unicode path to rmtree - # it tries to decode all filenames it encounters while walking - # the tree which leads to unicode errors on Linux where there - # can be non-decodeable filenames. - def rmtree(x, **kw): - if not isinstance(x, bytes): - x = x.encode('utf-8') - return shutil.rmtree(x, **kw) -else: - rmtree = shutil.rmtree diff --git a/ebook_converter/utils/img.py b/ebook_converter/utils/img.py index 7945d20..b9466c4 100644 --- a/ebook_converter/utils/img.py +++ b/ebook_converter/utils/img.py @@ -12,7 +12,7 @@ from threading import Thread #from PyQt5.QtGui import QColor, QImage, QImageReader, QImageWriter, QPixmap, QTransform from ebook_converter import fit_image, force_unicode -from ebook_converter.constants import iswindows, plugins, ispy3 +from ebook_converter.constants import iswindows, plugins from ebook_converter.ptempfile import TemporaryDirectory from ebook_converter.utils.config_base import tweaks from ebook_converter.utils.filenames import atomic_rename @@ -545,13 +545,7 @@ def run_optimizer(file_path, cmd, as_filter=False, input_data=None): cmd[cmd.index(q)] = r if not as_filter: repl(True, iname), repl(False, oname) - if iswindows and not ispy3: - # subprocess in python 2 cannot handle unicode strings that are not - # encodeable in mbcs, so we fail here, where it is more explicit, - # instead. - cmd = [x.encode('mbcs') if isinstance(x, str) else x for x in cmd] - if isinstance(cwd, str): - cwd = cwd.encode('mbcs') + stdin = subprocess.PIPE if as_filter else None stderr = subprocess.PIPE if as_filter else subprocess.STDOUT creationflags = 0x08 if iswindows else 0 diff --git a/ebook_converter/utils/imghdr.py b/ebook_converter/utils/imghdr.py index e046484..899e774 100644 --- a/ebook_converter/utils/imghdr.py +++ b/ebook_converter/utils/imghdr.py @@ -5,7 +5,6 @@ from struct import unpack, error import os from ebook_converter.utils.speedups import ReadOnlyFileBuffer -from ebook_converter.constants import ispy3 HSIZE = 120 @@ -122,12 +121,8 @@ def jpeg_dimensions(stream): raise ValueError('Truncated JPEG data') return ans - if ispy3: - def read_byte(): - return read(1)[0] - else: - def read_byte(): - return ord(read(1)[0]) + def read_byte(): + return read(1)[0] x = None while True: diff --git a/ebook_converter/utils/ipc/__init__.py b/ebook_converter/utils/ipc/__init__.py index ec395a8..a431a12 100644 --- a/ebook_converter/utils/ipc/__init__.py +++ b/ebook_converter/utils/ipc/__init__.py @@ -8,7 +8,6 @@ from ebook_converter import force_unicode from ebook_converter.constants import filesystem_encoding from ebook_converter.constants import get_windows_username from ebook_converter.constants import islinux -from ebook_converter.constants import ispy3 from ebook_converter.constants import iswindows from ebook_converter.utils.filenames import ascii_filename @@ -51,8 +50,6 @@ def socket_address(which): from tempfile import gettempdir tmp = force_unicode(gettempdir(), filesystem_encoding) ans = os.path.join(tmp, sock_name) - if not ispy3 and not isinstance(ans, bytes): - ans = ans.encode(filesystem_encoding) return ans diff --git a/ebook_converter/utils/ipc/launch.py b/ebook_converter/utils/ipc/launch.py index 0679788..689734b 100644 --- a/ebook_converter/utils/ipc/launch.py +++ b/ebook_converter/utils/ipc/launch.py @@ -1,7 +1,7 @@ import subprocess, os, sys, time from functools import partial -from ebook_converter.constants import isosx, isfrozen, filesystem_encoding, ispy3 +from ebook_converter.constants import isosx, isfrozen, filesystem_encoding from ebook_converter.utils.config import prefs from ebook_converter.ptempfile import PersistentTemporaryFile, base_dir from ebook_converter.utils.serialize import msgpack_dumps @@ -88,26 +88,7 @@ class Worker(object): @property def env(self): - if ispy3: - env = os.environ.copy() - else: - # We use this inefficient method of copying the environment variables - # because of non ascii env vars on windows. See https://bugs.launchpad.net/bugs/811191 - env = {} - for key in os.environ: - try: - val = os.environ[key] - if isinstance(val, str): - # On windows subprocess cannot handle unicode env vars - try: - val = val.encode(filesystem_encoding) - except ValueError: - val = val.encode('utf-8') - if isinstance(key, str): - key = key.encode('ascii') - env[key] = val - except: - pass + env = os.environ.copy() env[native_string_type('CALIBRE_WORKER')] = environ_item('1') td = as_hex_unicode(msgpack_dumps(base_dir())) env[native_string_type('CALIBRE_WORKER_TEMP_DIR')] = environ_item(td) @@ -158,22 +139,8 @@ class Worker(object): self._env = {} self.gui = gui self.job_name = job_name - if ispy3: - self._env = env.copy() - else: - # Windows cannot handle unicode env vars - for k, v in env.items(): - try: - if isinstance(k, str): - k = k.encode('ascii') - if isinstance(v, str): - try: - v = v.encode(filesystem_encoding) - except: - v = v.encode('utf-8') - self._env[k] = v - except: - pass + self._env = env.copy() + def __call__(self, redirect_output=True, cwd=None, priority=None): ''' diff --git a/ebook_converter/utils/lock.py b/ebook_converter/utils/lock.py index 0afd1e5..67d1c86 100644 --- a/ebook_converter/utils/lock.py +++ b/ebook_converter/utils/lock.py @@ -9,7 +9,7 @@ import time from functools import partial from ebook_converter.constants import ( - __appname__, fcntl, filesystem_encoding, islinux, isosx, iswindows, plugins, ispy3 + __appname__, fcntl, filesystem_encoding, islinux, isosx, iswindows, plugins ) from ebook_converter.utils.monotonic import monotonic @@ -156,8 +156,6 @@ elif islinux: ) name = name address = '\0' + name.replace(' ', '_') - if not ispy3: - address = address.encode('utf-8') sock = socket.socket(family=socket.AF_UNIX) try: eintr_retry_call(sock.bind, address) diff --git a/ebook_converter/utils/serialize.py b/ebook_converter/utils/serialize.py index a7297a2..e92d6ad 100644 --- a/ebook_converter/utils/serialize.py +++ b/ebook_converter/utils/serialize.py @@ -1,6 +1,3 @@ -from ebook_converter.constants import ispy3 - - MSGPACK_MIME = 'application/x-msgpack' CANARY = 'jPoAv3zOyHvQ5JFNYg4hJ9' @@ -111,22 +108,10 @@ def json_loads(data): return json.loads(data, object_hook=json_decoder) -if ispy3: +def pickle_dumps(data): + import pickle + return pickle.dumps(data, -1) - def pickle_dumps(data): - import pickle - return pickle.dumps(data, -1) - - def pickle_loads(dump): - import pickle - return pickle.loads(dump, encoding='utf-8') - -else: - - def pickle_dumps(data): - import cPickle as pickle - return pickle.dumps(data, -1) - - def pickle_loads(dump): - import cPickle as pickle - return pickle.loads(dump) +def pickle_loads(dump): + import pickle + return pickle.loads(dump, encoding='utf-8') diff --git a/ebook_converter/utils/shared_file.py b/ebook_converter/utils/shared_file.py index 251d6ff..995d6dd 100644 --- a/ebook_converter/utils/shared_file.py +++ b/ebook_converter/utils/shared_file.py @@ -17,7 +17,7 @@ file before deleting it. import os, sys from ebook_converter.polyglot.builtins import reraise -from ebook_converter.constants import iswindows, plugins, ispy3 +from ebook_converter.constants import iswindows, plugins __license__ = 'GPL v3' diff --git a/ebook_converter/utils/terminal.py b/ebook_converter/utils/terminal.py index 7ec0e54..75a5597 100644 --- a/ebook_converter/utils/terminal.py +++ b/ebook_converter/utils/terminal.py @@ -6,7 +6,6 @@ try: except ValueError: iswindows = False -from ebook_converter.constants import ispy3 from ebook_converter.polyglot.builtins import native_string_type @@ -152,12 +151,8 @@ class Detect(object): while text: t, text = text[:chunk], text[chunk:] wt = c_wchar_p(t) - if ispy3: - text_len = len(t.encode('utf-16')) - else: - # Use the fact that len(t) == wcslen(wt) in python 2.7 on - # windows where the python unicode type uses UTF-16 - text_len = len(t) + text_len = len(t.encode('utf-16')) + if not self.write_console(self.file_handle, wt, text_len, byref(written), None): # Older versions of windows can fail to write large strings # to console with WriteConsoleW (seen it happen on Win XP)