From 1a09e3db84e9b1e733fb2c9922be494e4813029b Mon Sep 17 00:00:00 2001 From: gryf Date: Wed, 17 Jun 2020 19:23:52 +0200 Subject: [PATCH] Removed Windows bits. --- README.rst | 4 + ebook_converter/__init__.py | 6 +- ebook_converter/constants_old.py | 117 ++----- ebook_converter/customize/__init__.py | 17 +- ebook_converter/customize/builtins.py | 4 +- ebook_converter/customize/conversion.py | 4 +- ebook_converter/customize/profiles.py | 4 +- ebook_converter/devices/interface.py | 20 +- ebook_converter/ebooks/docx/images.py | 3 - ebook_converter/ebooks/html/input.py | 4 - ebook_converter/ebooks/html/to_zip.py | 2 +- ebook_converter/ebooks/metadata/archive.py | 4 +- ebook_converter/ebooks/metadata/pdf.py | 6 +- ebook_converter/ebooks/mobi/writer8/exth.py | 6 +- .../ebooks/oeb/polish/container.py | 13 +- .../ebooks/oeb/transforms/jacket.py | 3 - ebook_converter/ebooks/pdf/pdftohtml.py | 9 +- ebook_converter/library/catalogs/bibtex.py | 2 +- ebook_converter/library/catalogs/csv_xml.py | 2 +- ebook_converter/library/catalogs/epub_mobi.py | 2 +- ebook_converter/ptempfile.py | 22 +- ebook_converter/startup.py | 60 +--- ebook_converter/utils/config.py | 4 +- ebook_converter/utils/config_base.py | 3 +- ebook_converter/utils/date.py | 60 ++-- ebook_converter/utils/filenames.py | 301 +----------------- ebook_converter/utils/fonts/scanner.py | 10 +- ebook_converter/utils/fonts/sfnt/cmap.py | 4 - ebook_converter/utils/img.py | 12 +- ebook_converter/utils/ipc/__init__.py | 36 +-- ebook_converter/utils/localunzip.py | 18 +- ebook_converter/utils/shared_file.py | 6 +- ebook_converter/utils/terminal.py | 193 +---------- ebook_converter/utils/zipfile.py | 6 +- 34 files changed, 147 insertions(+), 820 deletions(-) diff --git a/README.rst b/README.rst index ec7b5f5..ac4417b 100644 --- a/README.rst +++ b/README.rst @@ -38,6 +38,10 @@ modifications from third parties (external modules copied into Calibre project for instance), and make a huge cleanup. I'm not sure if I find time and strength for doing it completely, but I'll try. +Windows is not currently supported, because of the original spaghetti code. +This may change in the future, after cleanup of mentioned pasta would be +completed. + Input formats ~~~~~~~~~~~~~ diff --git a/ebook_converter/__init__.py b/ebook_converter/__init__.py index 16ffdf4..e330839 100644 --- a/ebook_converter/__init__.py +++ b/ebook_converter/__init__.py @@ -16,18 +16,16 @@ except EnvironmentError: from ebook_converter import constants_old from ebook_converter.constants_old import islinux, isfrozen, \ isbsd, __appname__, __version__, __author__, \ - win32event, win32api, winerror, fcntl, \ config_dir from ebook_converter.startup import winutil, winutilerror from ebook_converter.utils.icu import safe_chr -from ebook_converter.utils.terminal import Detect if False: # Prevent pyflakes from complaining winutil, winutilerror, __appname__, islinux, __version__ - fcntl, win32event, isfrozen, __author__ - winerror, win32api, isbsd, config_dir + isfrozen, __author__ + isbsd, config_dir def init_mimetypes(): diff --git a/ebook_converter/constants_old.py b/ebook_converter/constants_old.py index d635578..6526cce 100644 --- a/ebook_converter/constants_old.py +++ b/ebook_converter/constants_old.py @@ -18,7 +18,6 @@ Various run time constants. _plat = sys.platform.lower() -iswindows = 'win32' in _plat or 'win64' in _plat isosx = 'darwin' in _plat isnewosx = isosx and getattr(sys, 'new_app_bundle', False) isfreebsd = 'freebsd' in _plat @@ -26,15 +25,11 @@ isnetbsd = 'netbsd' in _plat isdragonflybsd = 'dragonfly' in _plat isbsd = isfreebsd or isnetbsd or isdragonflybsd ishaiku = 'haiku1' in _plat -islinux = not(iswindows or isosx or isbsd or ishaiku) +islinux = True isfrozen = hasattr(sys, 'frozen') isunix = isosx or islinux or ishaiku isportable = os.getenv('CALIBRE_PORTABLE_BUILD') is not None isxp = isoldvista = False -if iswindows: - wver = sys.getwindowsversion() - isxp = wver.major < 6 - isoldvista = wver.build < 6002 is64bit = sys.maxsize > (1 << 32) FAKE_PROTOCOL, FAKE_HOST = 'clbr', 'internal.invalid' VIEWER_APP_UID = 'com.calibre-ebook.viewer' @@ -48,10 +43,7 @@ try: except: preferred_encoding = 'utf-8' -win32event = importlib.import_module('win32event') if iswindows else None -winerror = importlib.import_module('winerror') if iswindows else None -win32api = importlib.import_module('win32api') if iswindows else None -fcntl = None if iswindows else importlib.import_module('fcntl') +fcntl = importlib.import_module('fcntl') dark_link_color = '#6cb4ee' _osx_ver = None @@ -116,23 +108,14 @@ def _get_cache_dir(): if err.errno == errno.EEXIST: return ans - if iswindows: - w = plugins['winutil'][0] + candidate = os.getenv('XDG_CACHE_HOME', '~/.cache') + candidate = os.path.join(os.path.expanduser(candidate), + __appname__) + if isinstance(candidate, bytes): try: - candidate = os.path.join(w.special_folder_path(w.CSIDL_LOCAL_APPDATA), '%s-cache'%__appname__) + candidate = candidate.decode(filesystem_encoding) except ValueError: - return confcache - elif isosx: - candidate = os.path.join(os.path.expanduser('~/Library/Caches'), __appname__) - else: - candidate = os.getenv('XDG_CACHE_HOME', '~/.cache') - candidate = os.path.join(os.path.expanduser(candidate), - __appname__) - if isinstance(candidate, bytes): - try: - candidate = candidate.decode(filesystem_encoding) - except ValueError: - candidate = confcache + candidate = confcache try: os.makedirs(candidate) except EnvironmentError as err: @@ -200,39 +183,27 @@ CONFIG_DIR_MODE = 0o700 cconfd = os.getenv('CALIBRE_CONFIG_DIRECTORY') if cconfd is not None: config_dir = os.path.abspath(cconfd) -elif iswindows: - if plugins['winutil'][0] is None: - raise Exception(plugins['winutil'][1]) - try: - config_dir = plugins['winutil'][0].special_folder_path(plugins['winutil'][0].CSIDL_APPDATA) - except ValueError: - config_dir = None - if not config_dir or not os.access(config_dir, os.W_OK|os.X_OK): - config_dir = os.path.expanduser('~') - config_dir = os.path.join(config_dir, 'calibre') -elif isosx: - config_dir = os.path.expanduser('~/Library/Preferences/calibre') -else: - bdir = os.path.abspath(os.path.expanduser(os.getenv('XDG_CONFIG_HOME', '~/.config'))) - config_dir = os.path.join(bdir, 'calibre') - try: - os.makedirs(config_dir, mode=CONFIG_DIR_MODE) - except: - pass - if not os.path.exists(config_dir) or \ - not os.access(config_dir, os.W_OK) or not \ - os.access(config_dir, os.X_OK): - print('No write acces to', config_dir, 'using a temporary dir instead') - import tempfile, atexit - config_dir = tempfile.mkdtemp(prefix='calibre-config-') - def cleanup_cdir(): - try: - import shutil - shutil.rmtree(config_dir) - except: - pass - atexit.register(cleanup_cdir) +bdir = os.path.abspath(os.path.expanduser(os.getenv('XDG_CONFIG_HOME', '~/.config'))) +config_dir = os.path.join(bdir, 'calibre') +try: + os.makedirs(config_dir, mode=CONFIG_DIR_MODE) +except: + pass +if not os.path.exists(config_dir) or \ + not os.access(config_dir, os.W_OK) or not \ + os.access(config_dir, os.X_OK): + print('No write acces to', config_dir, 'using a temporary dir instead') + import tempfile, atexit + config_dir = tempfile.mkdtemp(prefix='calibre-config-') + + def cleanup_cdir(): + try: + import shutil + shutil.rmtree(config_dir) + except: + pass + atexit.register(cleanup_cdir) # }}} @@ -251,8 +222,6 @@ def get_version(): v = v[:-2] if is_running_from_develop: v += '*' - if iswindows and is64bit: - v += ' [64bit]' return v @@ -261,33 +230,3 @@ def get_portable_base(): 'Return path to the directory that contains calibre-portable.exe or None' if isportable: return os.path.dirname(os.path.dirname(os.getenv('CALIBRE_PORTABLE_BUILD'))) - - -def get_windows_username(): - ''' - Return the user name of the currently logged in user as a unicode string. - Note that usernames on windows are case insensitive, the case of the value - returned depends on what the user typed into the login box at login time. - ''' - username = plugins['winutil'][0].username - return username() - - -def get_windows_temp_path(): - temp_path = plugins['winutil'][0].temp_path - return temp_path() - - -def get_windows_user_locale_name(): - locale_name = plugins['winutil'][0].locale_name - return locale_name() - - -def get_windows_number_formats(): - ans = getattr(get_windows_number_formats, 'ans', None) - if ans is None: - localeconv = plugins['winutil'][0].localeconv - d = localeconv() - thousands_sep, decimal_point = d['thousands_sep'], d['decimal_point'] - ans = get_windows_number_formats.ans = thousands_sep, decimal_point - return ans diff --git a/ebook_converter/customize/__init__.py b/ebook_converter/customize/__init__.py index 8967a0f..e7183a5 100644 --- a/ebook_converter/customize/__init__.py +++ b/ebook_converter/customize/__init__.py @@ -2,14 +2,13 @@ import importlib import sys import zipfile -from ebook_converter.constants_old import numeric_version, iswindows, isosx +from ebook_converter.constants_old import numeric_version, isosx from ebook_converter.ptempfile import PersistentTemporaryFile platform = 'linux' -if iswindows: - platform = 'windows' -elif isosx: + +if isosx: platform = 'osx' @@ -331,7 +330,7 @@ class MetadataReaderPlugin(Plugin): #: For example: ``set(['lit', 'mobi', 'prc'])`` file_types = set() - supported_platforms = ['windows', 'osx', 'linux'] + supported_platforms = ['osx', 'linux'] version = numeric_version author = 'Kovid Goyal' @@ -363,7 +362,7 @@ class MetadataWriterPlugin(Plugin): #: For example: ``set(['lit', 'mobi', 'prc'])`` file_types = set() - supported_platforms = ['windows', 'osx', 'linux'] + supported_platforms = ['osx', 'linux'] version = numeric_version author = 'Kovid Goyal' @@ -509,7 +508,7 @@ class CatalogPlugin(Plugin): class InterfaceActionBase(Plugin): - supported_platforms = ['windows', 'osx', 'linux'] + supported_platforms = ['osx', 'linux'] author = 'Kovid Goyal' type = 'User interface action' can_be_disabled = False @@ -542,7 +541,7 @@ class PreferencesPlugin(Plugin): various fields of the plugin control how it is categorized in the UI. """ - supported_platforms = ['windows', 'osx', 'linux'] + supported_platforms = ['osx', 'linux'] author = 'Kovid Goyal' type = 'Preferences' can_be_disabled = False @@ -594,7 +593,7 @@ class PreferencesPlugin(Plugin): class StoreBase(Plugin): - supported_platforms = ['windows', 'osx', 'linux'] + supported_platforms = ['osx', 'linux'] author = 'John Schember' type = 'Store' # Information about the store. Should be in the primary language diff --git a/ebook_converter/customize/builtins.py b/ebook_converter/customize/builtins.py index db347b0..847dbee 100644 --- a/ebook_converter/customize/builtins.py +++ b/ebook_converter/customize/builtins.py @@ -28,7 +28,7 @@ class PML2PMLZ(FileTypePlugin): 'a PML file to the library.') version = numeric_version file_types = {'pml'} - supported_platforms = ['windows', 'osx', 'linux'] + supported_platforms = ['osx', 'linux'] on_import = True def run(self, pmlfile): @@ -60,7 +60,7 @@ class TXT2TXTZ(FileTypePlugin): 'the archive.') version = numeric_version file_types = {'txt', 'text'} - supported_platforms = ['windows', 'osx', 'linux'] + supported_platforms = ['osx', 'linux'] on_import = True def _get_image_references(self, txt, base_dir): diff --git a/ebook_converter/customize/conversion.py b/ebook_converter/customize/conversion.py index ba00714..397128b 100644 --- a/ebook_converter/customize/conversion.py +++ b/ebook_converter/customize/conversion.py @@ -103,7 +103,7 @@ class InputFormatPlugin(Plugin): type = 'Conversion input' can_be_disabled = False - supported_platforms = ['windows', 'osx', 'linux'] + supported_platforms = ['osx', 'linux'] commit_name = None # unique name under which options for this plugin are saved ui_data = None @@ -241,7 +241,7 @@ class OutputFormatPlugin(Plugin): type = 'Conversion output' can_be_disabled = False - supported_platforms = ['windows', 'osx', 'linux'] + supported_platforms = ['osx', 'linux'] commit_name = None # unique name under which options for this plugin are saved ui_data = None diff --git a/ebook_converter/customize/profiles.py b/ebook_converter/customize/profiles.py index 9d426dd..7ce17d8 100644 --- a/ebook_converter/customize/profiles.py +++ b/ebook_converter/customize/profiles.py @@ -41,7 +41,7 @@ class Plugin(_Plugin): class InputProfile(Plugin): author = 'Kovid Goyal' - supported_platforms = {'windows', 'osx', 'linux'} + supported_platforms = {'osx', 'linux'} can_be_disabled = False type = 'Input profile' @@ -239,7 +239,7 @@ input_profiles.sort(key=lambda x: x.name.lower()) class OutputProfile(Plugin): author = 'Kovid Goyal' - supported_platforms = {'windows', 'osx', 'linux'} + supported_platforms = {'osx', 'linux'} can_be_disabled = False type = 'Output profile' diff --git a/ebook_converter/devices/interface.py b/ebook_converter/devices/interface.py index 0c0727c..de10efb 100644 --- a/ebook_converter/devices/interface.py +++ b/ebook_converter/devices/interface.py @@ -2,7 +2,6 @@ import os from collections import namedtuple from ebook_converter import prints -from ebook_converter.constants_old import iswindows from ebook_converter.customize import Plugin @@ -153,7 +152,7 @@ class DevicePlugin(Plugin): else: products = self.PRODUCT_ID if hasattr(self.PRODUCT_ID, '__len__') else [self.PRODUCT_ID] - ch = self.can_handle_windows if iswindows else self.can_handle + ch = self.can_handle for vid in vendors_on_system.intersection(vendors): for dev in devices_on_system: cvid, pid, bcd = dev[:3] @@ -226,23 +225,6 @@ class DevicePlugin(Plugin): """ raise NotImplementedError() - def can_handle_windows(self, usbdevice, debug=False): - ''' - Optional method to perform further checks on a device to see if this driver - is capable of handling it. If it is not it should return False. This method - is only called after the vendor, product ids and the bcd have matched, so - it can do some relatively time intensive checks. The default implementation - returns True. This method is called only on Windows. See also - :meth:`can_handle`. - - Note that for devices based on USBMS this method by default delegates - to :meth:`can_handle`. So you only need to override :meth:`can_handle` - in your subclass of USBMS. - - :param usbdevice: A usbdevice as returned by :func:`calibre.devices.winusb.scan_usb_devices` - ''' - return True - def can_handle(self, device_info, debug=False): ''' Unix version of :meth:`can_handle_windows`. diff --git a/ebook_converter/ebooks/docx/images.py b/ebook_converter/ebooks/docx/images.py index ead223a..548b517 100644 --- a/ebook_converter/ebooks/docx/images.py +++ b/ebook_converter/ebooks/docx/images.py @@ -2,7 +2,6 @@ import os from lxml.html.builder import IMG, HR -from ebook_converter.constants_old import iswindows from ebook_converter.ebooks.docx.names import barename from ebook_converter.utils.filenames import ascii_filename from ebook_converter.utils.img import resize_to_fit, image_to_data @@ -123,8 +122,6 @@ class Images(object): def read_image_data(self, fname, base=None): if fname.startswith('file://'): src = fname[len('file://'):] - if iswindows and src and src[0] == '/': - src = src[1:] if not src or not os.path.exists(src): raise LinkedImageNotFound(src) with open(src, 'rb') as rawsrc: diff --git a/ebook_converter/ebooks/html/input.py b/ebook_converter/ebooks/html/input.py index 58b69bc..6baabd4 100644 --- a/ebook_converter/ebooks/html/input.py +++ b/ebook_converter/ebooks/html/input.py @@ -9,7 +9,6 @@ import urllib.parse from ebook_converter.ebooks.oeb.base import urlunquote from ebook_converter.ebooks.chardet import detect_xml_encoding -from ebook_converter.constants_old import iswindows from ebook_converter import unicode_path, replace_entities @@ -22,9 +21,6 @@ class Link(object): def url_to_local_path(cls, url, base): path = url.path isabs = False - if iswindows and path.startswith('/'): - path = path[1:] - isabs = True path = urllib.parse.urlunparse(('', '', path, url.params, url.query, '')) path = urlunquote(path) diff --git a/ebook_converter/ebooks/html/to_zip.py b/ebook_converter/ebooks/html/to_zip.py index 9cdb276..4f4f2d5 100644 --- a/ebook_converter/ebooks/html/to_zip.py +++ b/ebook_converter/ebooks/html/to_zip.py @@ -19,7 +19,7 @@ class HTML2ZIP(FileTypePlugin): ''') version = numeric_version file_types = {'html', 'htm', 'xhtml', 'xhtm', 'shtm', 'shtml'} - supported_platforms = ['windows', 'osx', 'linux'] + supported_platforms = ['osx', 'linux'] on_import = True def run(self, htmlfile): diff --git a/ebook_converter/ebooks/metadata/archive.py b/ebook_converter/ebooks/metadata/archive.py index 33deeeb..0ded173 100644 --- a/ebook_converter/ebooks/metadata/archive.py +++ b/ebook_converter/ebooks/metadata/archive.py @@ -44,7 +44,7 @@ class KPFExtract(FileTypePlugin): 'KPF files. Note this will not contain any edits made in ' 'the Kindle Create program itself.') file_types = {'kpf'} - supported_platforms = ['windows', 'osx', 'linux'] + supported_platforms = ['osx', 'linux'] on_import = True def run(self, archive): @@ -67,7 +67,7 @@ class ArchiveExtract(FileTypePlugin): 'RAR). Also try to autodetect if they are actually CBZ/CBR ' 'files.') file_types = {'zip', 'rar'} - supported_platforms = ['windows', 'osx', 'linux'] + supported_platforms = ['osx', 'linux'] on_import = True def run(self, archive): diff --git a/ebook_converter/ebooks/metadata/pdf.py b/ebook_converter/ebooks/metadata/pdf.py index f8a09d1..5456ef9 100644 --- a/ebook_converter/ebooks/metadata/pdf.py +++ b/ebook_converter/ebooks/metadata/pdf.py @@ -5,7 +5,6 @@ import os, subprocess, shutil, re from functools import partial from ebook_converter import prints -from ebook_converter.constants_old import iswindows from ebook_converter.ptempfile import TemporaryDirectory from ebook_converter.ebooks.metadata import ( MetaInformation, string_to_authors, check_isbn, check_doi) @@ -18,7 +17,7 @@ __copyright__ = '2008, Kovid Goyal ' def get_tools(): from ebook_converter.ebooks.pdf.pdftohtml import PDFTOHTML base = os.path.dirname(PDFTOHTML) - suffix = '.exe' if iswindows else '' + suffix = '' pdfinfo = os.path.join(base, 'pdfinfo') + suffix pdftoppm = os.path.join(base, 'pdftoppm') + suffix return pdfinfo, pdftoppm @@ -87,9 +86,6 @@ def page_images(pdfpath, outputdir='.', first=1, last=1, image_format='jpeg', pr pdftoppm = get_tools()[1] outputdir = os.path.abspath(outputdir) args = {} - if iswindows: - import win32process as w - args['creationflags'] = w.HIGH_PRIORITY_CLASS | w.CREATE_NO_WINDOW try: subprocess.check_call([ pdftoppm, '-cropbox', '-' + image_format, '-f', str(first), diff --git a/ebook_converter/ebooks/mobi/writer8/exth.py b/ebook_converter/ebooks/mobi/writer8/exth.py index 4c3ed6e..cf6fc5b 100644 --- a/ebook_converter/ebooks/mobi/writer8/exth.py +++ b/ebook_converter/ebooks/mobi/writer8/exth.py @@ -3,7 +3,7 @@ from struct import pack from io import BytesIO from ebook_converter.ebooks.oeb import base -from ebook_converter.constants_old import iswindows, isosx +from ebook_converter.constants_old import isosx from ebook_converter.ebooks.mobi.utils import (utf8_text, to_base) from ebook_converter.utils.localization import lang_as_iso639_1 from ebook_converter.ebooks.metadata import authors_to_sort_string @@ -150,8 +150,8 @@ def build_exth(metadata, prefer_author_sort=False, is_periodical=False, nrecs += 1 if be_kindlegen2: - mv = 200 if iswindows else 202 if isosx else 201 - vals = {204:mv, 205:2, 206:9, 207:0} + mv = 201 + vals = {204: mv, 205: 2, 206: 9, 207: 0} elif is_periodical: # Pretend to be amazon's super secret periodical generator vals = {204:201, 205:2, 206:0, 207:101} diff --git a/ebook_converter/ebooks/oeb/polish/container.py b/ebook_converter/ebooks/oeb/polish/container.py index f4fb288..1119f15 100644 --- a/ebook_converter/ebooks/oeb/polish/container.py +++ b/ebook_converter/ebooks/oeb/polish/container.py @@ -8,7 +8,6 @@ import os import re import shutil import sys -import time import unicodedata import urllib.parse import uuid @@ -18,7 +17,6 @@ from lxml import etree from ebook_converter import constants as const from ebook_converter import CurrentDir, walk -from ebook_converter.constants_old import iswindows from ebook_converter.customize.ui import plugin_for_input_format, plugin_for_output_format from ebook_converter.ebooks import escape_xpath_attr from ebook_converter.ebooks.chardet import xml_to_unicode @@ -109,10 +107,7 @@ def href_to_name(href, root, base=None): if purl.scheme or not purl.path: return None href = oeb_base.urlunquote(purl.path) - if iswindows and ':' in href: - # path manipulations on windows fail for paths with : in them, so we - # assume all such paths are invalid/absolute paths. - return None + fullpath = os.path.join(base, *href.split('/')) return unicodedata.normalize('NFC', abspath_to_name(fullpath, root)) @@ -1040,10 +1035,8 @@ class Container(ContainerBase): # {{{ try: os.unlink(path) except EnvironmentError: - if not iswindows: - raise - time.sleep(1) # Wait for whatever has locked the file to release it - os.unlink(path) + raise + os.rename(temp, path) return path diff --git a/ebook_converter/ebooks/oeb/transforms/jacket.py b/ebook_converter/ebooks/oeb/transforms/jacket.py index 6781c3b..d0b94ee 100644 --- a/ebook_converter/ebooks/oeb/transforms/jacket.py +++ b/ebook_converter/ebooks/oeb/transforms/jacket.py @@ -9,7 +9,6 @@ from xml.sax import saxutils from ebook_converter import constants as const from ebook_converter.utils import date -from ebook_converter.constants_old import iswindows from ebook_converter.ebooks.oeb import base from ebook_converter.ebooks.oeb.base import XPath, xml2text, urlnormalize from ebook_converter.library.comments import comments_to_html, markdown @@ -419,7 +418,5 @@ def referenced_images(root): src = img.get('src') if src.startswith('file://'): path = src[7:] - if iswindows and path.startswith('/'): - path = path[1:] if os.path.exists(path): yield img, path diff --git a/ebook_converter/ebooks/pdf/pdftohtml.py b/ebook_converter/ebooks/pdf/pdftohtml.py index 554dc37..42f1014 100644 --- a/ebook_converter/ebooks/pdf/pdftohtml.py +++ b/ebook_converter/ebooks/pdf/pdftohtml.py @@ -8,7 +8,7 @@ import sys from lxml import etree from ebook_converter import CurrentDir, xml_replace_entities, prints -from ebook_converter.constants_old import isbsd, islinux, isosx, iswindows +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 from ebook_converter.ptempfile import PersistentTemporaryFile @@ -20,8 +20,6 @@ PDFTOHTML = 'pdftohtml' def popen(cmd, **kw): - if iswindows: - kw['creationflags'] = 0x08 return subprocess.Popen(cmd, **kw) @@ -29,11 +27,6 @@ if isosx and hasattr(sys, 'frameworks_dir'): base = os.path.join(os.path.dirname(sys.frameworks_dir), 'utils.app', 'Contents', 'MacOS') PDFTOHTML = os.path.join(base, PDFTOHTML) -if iswindows and hasattr(sys, 'frozen'): - base = os.path.dirname(sys.executable) - if hasattr(sys, 'new_app_layout'): - base = sys.extensions_location - PDFTOHTML = os.path.join(base, 'pdftohtml.exe') if (islinux or isbsd) and getattr(sys, 'frozen', False): PDFTOHTML = os.path.join(sys.executables_location, 'bin', 'pdftohtml') diff --git a/ebook_converter/library/catalogs/bibtex.py b/ebook_converter/library/catalogs/bibtex.py index ea5568b..651e4c1 100644 --- a/ebook_converter/library/catalogs/bibtex.py +++ b/ebook_converter/library/catalogs/bibtex.py @@ -20,7 +20,7 @@ class BIBTEX(CatalogPlugin): name = 'Catalog_BIBTEX' description = 'BIBTEX catalog generator' - supported_platforms = ['windows', 'osx', 'linux'] + supported_platforms = ['osx', 'linux'] author = 'Sengian' version = (1, 0, 0) file_types = {'bib'} diff --git a/ebook_converter/library/catalogs/csv_xml.py b/ebook_converter/library/catalogs/csv_xml.py index 909b25e..a3bc814 100644 --- a/ebook_converter/library/catalogs/csv_xml.py +++ b/ebook_converter/library/catalogs/csv_xml.py @@ -19,7 +19,7 @@ class CSV_XML(CatalogPlugin): name = 'Catalog_CSV_XML' description = 'CSV/XML catalog generator' - supported_platforms = ['windows', 'osx', 'linux'] + supported_platforms = ['osx', 'linux'] author = 'Greg Riker' version = (1, 0, 0) file_types = {'csv', 'xml'} diff --git a/ebook_converter/library/catalogs/epub_mobi.py b/ebook_converter/library/catalogs/epub_mobi.py index 2dae664..8cad0ed 100644 --- a/ebook_converter/library/catalogs/epub_mobi.py +++ b/ebook_converter/library/catalogs/epub_mobi.py @@ -19,7 +19,7 @@ class EPUB_MOBI(CatalogPlugin): name = 'Catalog_EPUB_MOBI' description = 'AZW3/EPUB/MOBI catalog generator' - supported_platforms = ['windows', 'osx', 'linux'] + supported_platforms = ['osx', 'linux'] minimum_calibre_version = (0, 7, 40) author = 'Greg Riker' version = (1, 0, 0) diff --git a/ebook_converter/ptempfile.py b/ebook_converter/ptempfile.py index 97d645e..ba7d964 100644 --- a/ebook_converter/ptempfile.py +++ b/ebook_converter/ptempfile.py @@ -6,8 +6,8 @@ being closed. """ import tempfile, os, atexit -from ebook_converter.constants_old import (__version__, __appname__, filesystem_encoding, - iswindows, get_windows_temp_path, isosx) +from ebook_converter.constants_old import __version__, __appname__, \ + filesystem_encoding, isosx def cleanup(path): @@ -52,9 +52,7 @@ def determined_remove_dir(x): def app_prefix(prefix): - if iswindows: - return '%s_'%__appname__ - return '%s_%s_%s'%(__appname__, __version__, prefix) + return '%s_%s_%s' % (__appname__, __version__, prefix) _osx_cache_dir = None @@ -99,19 +97,9 @@ def base_dir(): _base_dir = td else: base = os.environ.get('CALIBRE_TEMP_DIR', None) - if base is not None and iswindows: - base = os.getenv('CALIBRE_TEMP_DIR') prefix = app_prefix('tmp_') if base is None: - if iswindows: - # On windows, if the TMP env var points to a path that - # cannot be encoded using the mbcs encoding, then the - # python 2 tempfile algorithm for getting the temporary - # directory breaks. So we use the win32 api to get a - # unicode temp path instead. See - # https://bugs.launchpad.net/bugs/937389 - base = get_windows_temp_path() - elif isosx: + if isosx: # Use the cache dir rather than the temp dir for temp files as Apple # thinks deleting unused temp files is a good idea. See note under # _CS_DARWIN_USER_TEMP_DIR here @@ -119,7 +107,7 @@ def base_dir(): base = osx_cache_dir() _base_dir = tempfile.mkdtemp(prefix=prefix, dir=base) - atexit.register(determined_remove_dir if iswindows else remove_dir, _base_dir) + atexit.register(remove_dir, _base_dir) try: tempfile.gettempdir() diff --git a/ebook_converter/startup.py b/ebook_converter/startup.py index fbfb960..157a9ee 100644 --- a/ebook_converter/startup.py +++ b/ebook_converter/startup.py @@ -1,12 +1,8 @@ -__license__ = 'GPL v3' -__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' -__docformat__ = 'restructuredtext en' - -''' +""" Perform various initialization tasks. -''' - +""" import builtins +import fcntl import locale import sys @@ -16,7 +12,6 @@ from ebook_converter import constants_old builtins.__dict__['dynamic_property'] = lambda func: func(None) - _run_once = False winutil = winutilerror = None @@ -36,18 +31,8 @@ if not _run_once: spec = m.__spec__ return spec - sys.meta_path.insert(0, DeVendor()) - # - # Platform specific modules - if constants_old.iswindows: - winutil, winutilerror = constants_old.plugins['winutil'] - if not winutil: - raise RuntimeError('Failed to load the winutil plugin: %s'%winutilerror) - if len(sys.argv) > 1 and not isinstance(sys.argv[1], str): - sys.argv[1:] = winutil.argv()[1-len(sys.argv):] - # Ensure that all temp files/dirs are created under a calibre tmp dir from ebook_converter.ptempfile import base_dir try: @@ -66,20 +51,16 @@ if not _run_once: # # Ensure that the max number of open files is at least 1024 - if constants_old.iswindows: - # See https://msdn.microsoft.com/en-us/library/6e3b887c.aspx - if hasattr(winutil, 'setmaxstdio'): - winutil.setmaxstdio(max(1024, winutil.getmaxstdio())) - else: - import resource - soft, hard = resource.getrlimit(resource.RLIMIT_NOFILE) - if soft < 1024: - try: - resource.setrlimit(resource.RLIMIT_NOFILE, (min(1024, hard), hard)) - except Exception: - if constants_old.DEBUG: - import traceback - traceback.print_exc() + + import resource + soft, hard = resource.getrlimit(resource.RLIMIT_NOFILE) + if soft < 1024: + try: + resource.setrlimit(resource.RLIMIT_NOFILE, (min(1024, hard), hard)) + except Exception: + if constants_old.DEBUG: + import traceback + traceback.print_exc() # # Setup resources @@ -152,18 +133,9 @@ def test_lopen(): n = 'f\xe4llen' print('testing open()') - if constants_old.iswindows: - import msvcrt, win32api - - def assert_not_inheritable(f): - if win32api.GetHandleInformation(msvcrt.get_osfhandle(f.fileno())) & 0b1: - raise SystemExit('File handle is inheritable!') - else: - import fcntl - - def assert_not_inheritable(f): - if not fcntl.fcntl(f, fcntl.F_GETFD) & fcntl.FD_CLOEXEC: - raise SystemExit('File handle is inheritable!') + def assert_not_inheritable(f): + if not fcntl.fcntl(f, fcntl.F_GETFD) & fcntl.FD_CLOEXEC: + raise SystemExit('File handle is inheritable!') def copen(*args): ans = open(*args) diff --git a/ebook_converter/utils/config.py b/ebook_converter/utils/config.py index 2c9f528..0a37c7f 100644 --- a/ebook_converter/utils/config.py +++ b/ebook_converter/utils/config.py @@ -88,9 +88,7 @@ class OptionParser(optparse.OptionParser): fg='cyan') usage += ('\n\nWhenever you pass arguments to %prog that have spaces ' 'in them, enclose the arguments in quotation marks. For ' - 'example: "{}"\n\n').format("C:\\some path with spaces" - if constants_old.iswindows - else '/some path/with spaces') + 'example: "{}"\n\n').format('/some path/with spaces') if version is None: version = '%%prog (%s %s)' % (constants_old.__appname__, constants.VERSION) diff --git a/ebook_converter/utils/config_base.py b/ebook_converter/utils/config_base.py index f1e94bd..eb7b68e 100644 --- a/ebook_converter/utils/config_base.py +++ b/ebook_converter/utils/config_base.py @@ -14,7 +14,6 @@ import base64 from ebook_converter.constants_old import CONFIG_DIR_MODE from ebook_converter.constants_old import config_dir from ebook_converter.constants_old import filesystem_encoding -from ebook_converter.constants_old import iswindows from ebook_converter.constants_old import preferred_encoding from ebook_converter.utils.date import isoformat from ebook_converter.utils import iso8601 @@ -79,7 +78,7 @@ def from_json(obj): def force_unicode(x): try: - return x.decode('mbcs' if iswindows else preferred_encoding) + return x.decode(preferred_encoding) except UnicodeDecodeError: try: return x.decode(filesystem_encoding) diff --git a/ebook_converter/utils/date.py b/ebook_converter/utils/date.py index 34ba4dc..0058a4a 100644 --- a/ebook_converter/utils/date.py +++ b/ebook_converter/utils/date.py @@ -3,7 +3,7 @@ import datetime import time import functools -from ebook_converter.constants_old import iswindows, isosx, plugins, preferred_encoding +from ebook_converter.constants_old import isosx, plugins, preferred_encoding from ebook_converter.utils.iso8601 import utc_tz, local_tz, UNDEFINED_DATE from ebook_converter.utils.localization import lcdata @@ -13,38 +13,21 @@ _local_tz = local_tz # When parsing ambiguous dates that could be either dd-MM Or MM-dd use the # user's locale preferences -if iswindows: - import ctypes - LOCALE_SSHORTDATE, LOCALE_USER_DEFAULT = 0x1f, 0 - buf = ctypes.create_string_buffer(b'\0', 255) - try: - ctypes.windll.kernel32.GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SSHORTDATE, buf, 255) - parse_date_day_first = buf.value.index(b'd') < buf.value.index(b'M') - except: - parse_date_day_first = False - del ctypes, LOCALE_SSHORTDATE, buf, LOCALE_USER_DEFAULT -elif isosx: - try: - date_fmt = plugins['usbobserver'][0].date_format() - parse_date_day_first = date_fmt.index('d') < date_fmt.index('M') - except: - parse_date_day_first = False -else: - try: - def first_index(raw, queries): - for q in queries: - try: - return raw.index(q) - except ValueError: - pass - return -1 +try: + def first_index(raw, queries): + for q in queries: + try: + return raw.index(q) + except ValueError: + pass + return -1 - import locale - raw = locale.nl_langinfo(locale.D_FMT) - parse_date_day_first = first_index(raw, ('%d', '%a', '%A')) < first_index(raw, ('%m', '%b', '%B')) - del raw, first_index - except: - parse_date_day_first = False + import locale + raw = locale.nl_langinfo(locale.D_FMT) + parse_date_day_first = first_index(raw, ('%d', '%a', '%A')) < first_index(raw, ('%m', '%b', '%B')) + del raw, first_index +except: + parse_date_day_first = False DEFAULT_DATE = datetime.datetime(2000,1,1, tzinfo=utc_tz) EPOCH = datetime.datetime(1970, 1, 1, tzinfo=_utc_tz) @@ -214,15 +197,10 @@ def strftime(fmt, t=None): t[0] = replacement t = time.struct_time(t) ans = None - if iswindows: - if isinstance(fmt, bytes): - fmt = fmt.decode('mbcs', 'replace') - fmt = fmt.replace('%e', '%#d') - ans = plugins['winutil'][0].strftime(fmt, t) - else: - ans = time.strftime(fmt, t) - if isinstance(ans, bytes): - ans = ans.decode(preferred_encoding, 'replace') + + ans = time.strftime(fmt, t) + if isinstance(ans, bytes): + ans = ans.decode(preferred_encoding, 'replace') if early_year: ans = ans.replace('_early year hack##', str(orig_year)) return ans diff --git a/ebook_converter/utils/filenames.py b/ebook_converter/utils/filenames.py index 7e590c6..88ba177 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, prints, sanitize_file_name from ebook_converter.constants_old import ( - filesystem_encoding, iswindows, plugins, preferred_encoding, isosx + filesystem_encoding, plugins, preferred_encoding, isosx ) from ebook_converter.utils.localization import get_udc @@ -47,9 +47,9 @@ def shorten_component(s, by_what): def limit_component(x, limit=254): - # windows and macs use ytf-16 codepoints for length, linux uses arbitrary + # windows and macs use utf-16 codepoints for length, linux uses arbitrary # binary data, but we will assume utf-8 - filename_encoding_for_length = 'utf-16' if iswindows or isosx else 'utf-8' + filename_encoding_for_length = 'utf-8' def encoded_length(): q = x if isinstance(x, bytes) else x.encode(filename_encoding_for_length) @@ -100,7 +100,7 @@ def shorten_components_to(length, components, more_to_take=0, last_has_extension def find_executable_in_path(name, path=None): if path is None: path = os.environ.get('PATH', '') - exts = '.exe .cmd .bat'.split() if iswindows and not name.endswith('.exe') else ('',) + exts = ('',) path = path.split(os.pathsep) for x in path: for ext in exts: @@ -118,15 +118,14 @@ def is_case_sensitive(path): apply to the filesystem containing the directory in path. ''' is_case_sensitive = False - if not iswindows: - name1, name2 = ('calibre_test_case_sensitivity.txt', - 'calibre_TesT_CaSe_sensitiVitY.Txt') - f1, f2 = os.path.join(path, name1), os.path.join(path, name2) - if os.path.exists(f1): - os.remove(f1) - open(f1, 'w').close() - is_case_sensitive = not os.path.exists(f2) + name1, name2 = ('calibre_test_case_sensitivity.txt', + 'calibre_TesT_CaSe_sensitiVitY.Txt') + f1, f2 = os.path.join(path, name1), os.path.join(path, name2) + if os.path.exists(f1): os.remove(f1) + open(f1, 'w').close() + is_case_sensitive = not os.path.exists(f2) + os.remove(f1) return is_case_sensitive @@ -162,10 +161,6 @@ def case_preserving_open_file(path, mode='wb', mkdir_mode=0o777): raise ValueError('Invalid path: %r'%path) cpath = sep - if iswindows: - # Always upper case the drive letter and add a trailing slash so that - # the first os.listdir works correctly - cpath = components[0].upper() + sep bdir = path if mode is None else os.path.dirname(path) if not os.path.exists(bdir): @@ -215,37 +210,6 @@ def case_preserving_open_file(path, mode='wb', mkdir_mode=0o777): return ans, fpath -def windows_get_fileid(path): - ''' The fileid uniquely identifies actual file contents (it is the same for - all hardlinks to a file). Similar to inode number on linux. ''' - import win32file - from pywintypes import error - if isinstance(path, bytes): - path = path.decode(filesystem_encoding) - try: - h = win32file.CreateFileW(path, 0, 0, None, win32file.OPEN_EXISTING, - win32file.FILE_FLAG_BACKUP_SEMANTICS, 0) - try: - data = win32file.GetFileInformationByHandle(h) - finally: - win32file.CloseHandle(h) - except (error, EnvironmentError): - return None - return data[4], data[8], data[9] - - -def samefile_windows(src, dst): - samestring = (os.path.normcase(os.path.abspath(src)) == - os.path.normcase(os.path.abspath(dst))) - if samestring: - return True - - a, b = windows_get_fileid(src), windows_get_fileid(dst) - if a is None and b is None: - return False - return a == b - - def samefile(src, dst): ''' Check if two paths point to the same actual file on the filesystem. Handles @@ -257,9 +221,6 @@ def samefile(src, dst): case) even if the file does not exist. This is because I have no way of knowing how reliable the GetFileInformationByHandle method is. ''' - if iswindows: - return samefile_windows(src, dst) - if hasattr(os.path, 'samefile'): # Unix try: @@ -273,243 +234,20 @@ def samefile(src, dst): return samestring -def windows_get_size(path): - ''' On windows file sizes are only accurately stored in the actual file, - not in the directory entry (which could be out of date). So we open the - file, and get the actual size. ''' - import win32file - if isinstance(path, bytes): - path = path.decode(filesystem_encoding) - h = win32file.CreateFileW( - path, 0, win32file.FILE_SHARE_READ | win32file.FILE_SHARE_WRITE | win32file.FILE_SHARE_DELETE, - None, win32file.OPEN_EXISTING, 0, None) - try: - return win32file.GetFileSize(h) - finally: - win32file.CloseHandle(h) - - -def windows_hardlink(src, dest): - import win32file, pywintypes - try: - win32file.CreateHardLink(dest, src) - except pywintypes.error as e: - msg = 'Creating hardlink from %s to %s failed: %%s' % (src, dest) - raise OSError(msg % e) - src_size = os.path.getsize(src) - # We open and close dest, to ensure its directory entry is updated - # see http://blogs.msdn.com/b/oldnewthing/archive/2011/12/26/10251026.aspx - for i in range(10): - # If we are on a network filesystem, we have to wait for some indeterminate time, since - # network file systems are the best thing since sliced bread - try: - if windows_get_size(dest) == src_size: - return - except EnvironmentError: - pass - time.sleep(0.3) - - sz = windows_get_size(dest) - if sz != src_size: - msg = 'Creating hardlink from %s to %s failed: %%s' % (src, dest) - raise OSError(msg % ('hardlink size: %d not the same as source size' % sz)) - - -def windows_fast_hardlink(src, dest): - import win32file, pywintypes - try: - win32file.CreateHardLink(dest, src) - except pywintypes.error as e: - msg = 'Creating hardlink from %s to %s failed: %%s' % (src, dest) - raise OSError(msg % e) - ssz, dsz = windows_get_size(src), windows_get_size(dest) - if ssz != dsz: - msg = 'Creating hardlink from %s to %s failed: %%s' % (src, dest) - raise OSError(msg % ('hardlink size: %d not the same as source size: %s' % (dsz, ssz))) - - -def windows_nlinks(path): - import win32file - dwFlagsAndAttributes = win32file.FILE_FLAG_BACKUP_SEMANTICS if os.path.isdir(path) else 0 - if isinstance(path, bytes): - path = path.decode(filesystem_encoding) - handle = win32file.CreateFileW(path, win32file.GENERIC_READ, win32file.FILE_SHARE_READ, None, win32file.OPEN_EXISTING, dwFlagsAndAttributes, None) - try: - return win32file.GetFileInformationByHandle(handle)[7] - finally: - handle.Close() - - -class WindowsAtomicFolderMove(object): - - ''' - Move all the files inside a specified folder in an atomic fashion, - preventing any other process from locking a file while the operation is - incomplete. Raises an IOError if another process has locked a file before - the operation starts. Note that this only operates on the files in the - folder, not any sub-folders. - ''' - - def __init__(self, path): - self.handle_map = {} - - import win32file, winerror - from pywintypes import error - from collections import defaultdict - - if isinstance(path, bytes): - path = path.decode(filesystem_encoding) - - if not os.path.exists(path): - return - - names = os.listdir(path) - name_to_fileid = {x:windows_get_fileid(os.path.join(path, x)) for x in names} - fileid_to_names = defaultdict(set) - for name, fileid in name_to_fileid.items(): - fileid_to_names[fileid].add(name) - - for x in names: - f = os.path.normcase(os.path.abspath(os.path.join(path, x))) - if not os.path.isfile(f): - continue - try: - # Ensure the file is not read-only - win32file.SetFileAttributes(f, win32file.FILE_ATTRIBUTE_NORMAL) - except: - pass - - try: - h = win32file.CreateFileW(f, win32file.GENERIC_READ, - win32file.FILE_SHARE_DELETE, None, - win32file.OPEN_EXISTING, win32file.FILE_FLAG_SEQUENTIAL_SCAN, 0) - except error as e: - if getattr(e, 'winerror', 0) == winerror.ERROR_SHARING_VIOLATION: - # The file could be a hardlink to an already opened file, - # in which case we use the same handle for both files - fileid = name_to_fileid[x] - found = False - if fileid is not None: - for other in fileid_to_names[fileid]: - other = os.path.normcase(os.path.abspath(os.path.join(path, other))) - if other in self.handle_map: - self.handle_map[f] = self.handle_map[other] - found = True - break - if found: - continue - - self.close_handles() - if getattr(e, 'winerror', 0) == winerror.ERROR_SHARING_VIOLATION: - err = IOError(errno.EACCES, - 'File is open in another process') - err.filename = f - raise err - prints('CreateFile failed for: %r' % f) - raise - except: - self.close_handles() - prints('CreateFile failed for: %r' % f) - raise - self.handle_map[f] = h - - def copy_path_to(self, path, dest): - import win32file - handle = None - for p, h in self.handle_map.items(): - if samefile_windows(path, p): - handle = h - break - if handle is None: - if os.path.exists(path): - raise ValueError('The file %r did not exist when this move' - ' operation was started'%path) - else: - raise ValueError('The file %r does not exist'%path) - try: - windows_hardlink(path, dest) - return - except: - pass - - win32file.SetFilePointer(handle, 0, win32file.FILE_BEGIN) - with open(dest, 'wb') as f: - while True: - hr, raw = win32file.ReadFile(handle, 1024*1024) - if hr != 0: - raise IOError(hr, 'Error while reading from %r'%path) - if not raw: - break - f.write(raw) - - def release_file(self, path): - ' Release the lock on the file pointed to by path. Will also release the lock on any hardlinks to path ' - key = None - for p, h in self.handle_map.items(): - if samefile_windows(path, p): - key = (p, h) - break - if key is not None: - import win32file - win32file.CloseHandle(key[1]) - remove = [f for f, h in self.handle_map.items() if h is key[1]] - for x in remove: - self.handle_map.pop(x) - - def close_handles(self): - import win32file - for h in self.handle_map.values(): - win32file.CloseHandle(h) - self.handle_map = {} - - def delete_originals(self): - import win32file - for path in self.handle_map: - win32file.DeleteFile(path) - self.close_handles() - - def hardlink_file(src, dest): - if iswindows: - windows_hardlink(src, dest) - return os.link(src, dest) def nlinks_file(path): ' Return number of hardlinks to the file ' - if iswindows: - return windows_nlinks(path) return os.stat(path).st_nlink -if iswindows: - def rename_file(a, b): - move_file = plugins['winutil'][0].move_file - if isinstance(a, bytes): - a = a.decode('mbcs') - if isinstance(b, bytes): - b = b.decode('mbcs') - move_file(a, b) - - def atomic_rename(oldpath, newpath): '''Replace the file newpath with the file oldpath. Can fail if the files are on different volumes. If succeeds, guaranteed to be atomic. newpath may or may not exist. If it exists, it is replaced. ''' - if iswindows: - for i in range(10): - try: - rename_file(oldpath, newpath) - break - except Exception: - if i > 8: - raise - # Try the rename repeatedly in case something like a virus - # scanner has opened one of the files (I love windows) - time.sleep(1) - else: - os.rename(oldpath, newpath) + os.rename(oldpath, newpath) def remove_dir_if_empty(path, ignore_metadata_caches=False): @@ -572,20 +310,7 @@ def copyfile(src, dest): def get_hardlink_function(src, dest): - if iswindows: - import win32file, win32api - colon = b':' if isinstance(dest, bytes) else ':' - root = dest[0] + colon - try: - is_suitable = win32file.GetDriveType(root) not in (win32file.DRIVE_REMOTE, win32file.DRIVE_CDROM) - # See https://msdn.microsoft.com/en-us/library/windows/desktop/aa364993(v=vs.85).aspx - supports_hard_links = win32api.GetVolumeInformation(root + os.sep)[3] & 0x00400000 - except Exception: - supports_hard_links = is_suitable = False - hardlink = windows_fast_hardlink if is_suitable and supports_hard_links and src[0].lower() == dest[0].lower() else None - else: - hardlink = os.link - return hardlink + return os.link def copyfile_using_links(path, dest, dest_is_dir=True, filecopyfunc=copyfile): diff --git a/ebook_converter/utils/fonts/scanner.py b/ebook_converter/utils/fonts/scanner.py index 2c1a6b4..0178461 100644 --- a/ebook_converter/utils/fonts/scanner.py +++ b/ebook_converter/utils/fonts/scanner.py @@ -3,7 +3,7 @@ from collections import defaultdict from threading import Thread from ebook_converter import walk, prints -from ebook_converter.constants_old import iswindows, isosx +from ebook_converter.constants_old import isosx from ebook_converter.constants_old import plugins, DEBUG from ebook_converter.constants_old import filesystem_encoding from ebook_converter.utils.fonts.metadata import FontMetadata, UnsupportedFont @@ -90,14 +90,6 @@ def fc_list(): def font_dirs(): - if iswindows: - winutil, err = plugins['winutil'] - if err: - raise RuntimeError('Failed to load winutil: %s' % err) - try: - return [winutil.special_folder_path(winutil.CSIDL_FONTS)] - except ValueError: - return [r'C:\Windows\Fonts'] if isosx: return [ '/Library/Fonts', diff --git a/ebook_converter/utils/fonts/sfnt/cmap.py b/ebook_converter/utils/fonts/sfnt/cmap.py index cfcdf0d..3751436 100644 --- a/ebook_converter/utils/fonts/sfnt/cmap.py +++ b/ebook_converter/utils/fonts/sfnt/cmap.py @@ -6,10 +6,6 @@ from ebook_converter.utils.fonts.sfnt import UnknownTable, max_power_of_two from ebook_converter.utils.fonts.sfnt.errors import UnsupportedFont -__license__ = 'GPL v3' -__copyright__ = '2012, Kovid Goyal ' -__docformat__ = 'restructuredtext en' - # Note that the code for creating a BMP table (cmap format 4) is taken with # thanks from the fonttools project (BSD licensed). diff --git a/ebook_converter/utils/img.py b/ebook_converter/utils/img.py index b65d943..3550c08 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_old import iswindows, plugins +from ebook_converter.constants_old import plugins from ebook_converter.ptempfile import TemporaryDirectory from ebook_converter.utils.config_base import tweaks from ebook_converter.utils.filenames import atomic_rename @@ -38,8 +38,6 @@ def normalize_format_name(fmt): def get_exe_path(name): from ebook_converter.ebooks.pdf.pdftohtml import PDFTOHTML base = os.path.dirname(PDFTOHTML) - if iswindows: - name += '-calibre.exe' if not base: return name return os.path.join(base, name) @@ -47,12 +45,10 @@ def get_exe_path(name): def load_jxr_data(data): with TemporaryDirectory() as tdir: - if iswindows and isinstance(tdir, str): - tdir = tdir.encode('mbcs') with open(os.path.join(tdir, 'input.jxr'), 'wb') as f: f.write(data) cmd = [get_exe_path('JxrDecApp'), '-i', 'input.jxr', '-o', 'output.tif'] - creationflags = 0x08 if iswindows else 0 + creationflags = 0 subprocess.Popen(cmd, cwd=tdir, stdout=open(os.devnull, 'wb'), stderr=subprocess.STDOUT, creationflags=creationflags).wait() i = QImage() if not i.load(os.path.join(tdir, 'output.tif')): @@ -548,7 +544,7 @@ def run_optimizer(file_path, cmd, as_filter=False, input_data=None): stdin = subprocess.PIPE if as_filter else None stderr = subprocess.PIPE if as_filter else subprocess.STDOUT - creationflags = 0x08 if iswindows else 0 + creationflags = 0 p = subprocess.Popen(cmd, cwd=cwd, stdout=subprocess.PIPE, stderr=stderr, stdin=stdin, creationflags=creationflags) stderr = p.stderr if as_filter else p.stdout if as_filter: @@ -652,7 +648,7 @@ def test(): # {{{ despeckle_image(img) remove_borders_from_image(img) image_to_data(img, fmt='GIF') - raw = subprocess.Popen([get_exe_path('JxrDecApp'), '-h'], creationflags=0x08 if iswindows else 0, stdout=subprocess.PIPE).stdout.read() + raw = subprocess.Popen([get_exe_path('JxrDecApp'), '-h'], creationflags=0, stdout=subprocess.PIPE).stdout.read() if b'JPEG XR Decoder Utility' not in raw: raise SystemExit('Failed to run JxrDecApp') # }}} diff --git a/ebook_converter/utils/ipc/__init__.py b/ebook_converter/utils/ipc/__init__.py index 1bbb0fb..7285615 100644 --- a/ebook_converter/utils/ipc/__init__.py +++ b/ebook_converter/utils/ipc/__init__.py @@ -6,16 +6,10 @@ import threading from ebook_converter import force_unicode from ebook_converter.constants_old import filesystem_encoding -from ebook_converter.constants_old import get_windows_username from ebook_converter.constants_old import islinux -from ebook_converter.constants_old import iswindows from ebook_converter.utils.filenames import ascii_filename -__license__ = 'GPL v3' -__copyright__ = '2009, Kovid Goyal ' -__docformat__ = 'restructuredtext en' - VADDRESS = None @@ -31,34 +25,24 @@ def eintr_retry_call(func, *args, **kwargs): @functools.lru_cache() def socket_address(which): - if iswindows: - ans = r'\\.\pipe\Calibre' + which - try: - user = get_windows_username() - except Exception: - user = None - if user: - user = ascii_filename(user).replace(' ', '_') - if user: - ans += '-' + user[:100] + 'x' + + user = force_unicode(os.environ.get('USER') or os.path.basename(os.path.expanduser('~')), filesystem_encoding) + sock_name = '{}-calibre-{}.socket'.format(ascii_filename(user).replace(' ', '_'), which) + if islinux: + ans = '\0' + sock_name else: - user = force_unicode(os.environ.get('USER') or os.path.basename(os.path.expanduser('~')), filesystem_encoding) - sock_name = '{}-calibre-{}.socket'.format(ascii_filename(user).replace(' ', '_'), which) - if islinux: - ans = '\0' + sock_name - else: - from tempfile import gettempdir - tmp = force_unicode(gettempdir(), filesystem_encoding) - ans = os.path.join(tmp, sock_name) + from tempfile import gettempdir + tmp = force_unicode(gettempdir(), filesystem_encoding) + ans = os.path.join(tmp, sock_name) return ans def gui_socket_address(): - return socket_address('GUI' if iswindows else 'gui') + return socket_address('gui') def viewer_socket_address(): - return socket_address('Viewer' if iswindows else 'viewer') + return socket_address('viewer') class RC(threading.Thread): diff --git a/ebook_converter/utils/localunzip.py b/ebook_converter/utils/localunzip.py index 548bd0e..241fa29 100644 --- a/ebook_converter/utils/localunzip.py +++ b/ebook_converter/utils/localunzip.py @@ -10,10 +10,6 @@ from collections import namedtuple, OrderedDict from tempfile import SpooledTemporaryFile -__license__ = 'GPL v3' -__copyright__ = '2012, Kovid Goyal ' -__docformat__ = 'restructuredtext en' - HEADER_SIG = 0x04034b50 HEADER_BYTE_SIG = pack(b'= 128: - # Retry with a smaller chunk size (give up if chunk < 128) - chunk = chunk // 2 - text = t + text - continue - if err == winerror.ERROR_GEN_FAILURE: - # On newer windows, this happens when trying to write - # non-ascii chars to the console and the console is set - # to use raster fonts (the default). In this case - # rather than failing, write an informative error - # message and the asciized version of the text. - print('Non-ASCII text detected. You must set your Console\'s font to' - ' Lucida Console or Consolas or some other TrueType font to see this text', file=self.stream, end=' -- ') - from ebook_converter.utils.filenames import ascii_text - print(ascii_text(t + text), file=self.stream, end='') - continue - if not ignore_errors: - raise ctypes.WinError(err) class ColoredStream(Detect): @@ -178,10 +85,6 @@ class ColoredStream(Detect): stream = getattr(stream, 'buffer', stream) Detect.__init__(self, stream) self.fg, self.bg, self.bold = fg, bg, bold - if self.set_console is not None: - self.wval = to_flag(self.fg, self.bg, bold) - if not self.bg: - self.wval |= self.default_console_text_attributes & 0xF0 def cwrite(self, what): if not isinstance(what, bytes): @@ -286,13 +189,6 @@ class ANSIStream(Detect): def write_plain_text(self, text, start, end): if start < end: text = text[start:end] - if self.is_console and isinstance(text, bytes): - try: - utext = text.decode(self.encoding) - except ValueError: - pass - else: - return self.write_unicode_text(utext) self.polyglot_write(text) def convert_ansi(self, paramstring, command): @@ -326,60 +222,11 @@ class ANSIStream(Detect): fg, bg, bold = None, None, False self.last_state = (fg, bg, bold) - if fg or bg or bold: - val = to_flag(fg, bg, bold) - if not bg: - val |= self.default_console_text_attributes & 0xF0 - self.set_console(self.file_handle, val) - else: - self.set_console(self.file_handle, self.default_console_text_attributes) - -def windows_terminfo(): - from ctypes import Structure, byref - from ctypes.wintypes import SHORT, WORD - - class COORD(Structure): - - """struct in wincon.h""" - _fields_ = [ - ('X', SHORT), - ('Y', SHORT), - ] - - class SMALL_RECT(Structure): - - """struct in wincon.h.""" - _fields_ = [ - ("Left", SHORT), - ("Top", SHORT), - ("Right", SHORT), - ("Bottom", SHORT), - ] - - class CONSOLE_SCREEN_BUFFER_INFO(Structure): - - """struct in wincon.h.""" - _fields_ = [ - ("dwSize", COORD), - ("dwCursorPosition", COORD), - ("wAttributes", WORD), - ("srWindow", SMALL_RECT), - ("dwMaximumWindowSize", COORD), - ] - csbi = CONSOLE_SCREEN_BUFFER_INFO() - import msvcrt - file_handle = msvcrt.get_osfhandle(sys.stdout.fileno()) - from ctypes import windll - success = windll.kernel32.GetConsoleScreenBufferInfo(file_handle, - byref(csbi)) - if not success: - raise Exception('stdout is not a console?') - return csbi + self.set_console(self.file_handle, self.default_console_text_attributes) def get_term_geometry(): - import fcntl, termios, struct def ioctl_GWINSZ(fd): try: @@ -405,30 +252,10 @@ def get_term_geometry(): def geometry(): - if iswindows: - try: - - ti = windows_terminfo() - return (ti.dwSize.X or 80, ti.dwSize.Y or 25) - except: - return 80, 25 - else: - try: - lines, cols = get_term_geometry() - if lines is not None: - return cols, lines - except Exception: - pass - return 80, 25 - - -def test(): - s = ANSIStream() - - text = [colored(t, fg=t)+'. '+colored(t, fg=t, bold=True)+'.' for t in - ('red', 'yellow', 'green', 'white', 'cyan', 'magenta', 'blue',)] - s.write('\n'.join(text)) - u = u'\u041c\u0438\u0445\u0430\u0438\u043b fällen' - print() - s.write_unicode_text(u) - print() + try: + lines, cols = get_term_geometry() + if lines is not None: + return cols, lines + except Exception: + pass + return 80, 25 diff --git a/ebook_converter/utils/zipfile.py b/ebook_converter/utils/zipfile.py index b08d006..2a780f8 100644 --- a/ebook_converter/utils/zipfile.py +++ b/ebook_converter/utils/zipfile.py @@ -340,11 +340,7 @@ class ZipInfo (object): self.compress_type = ZIP_STORED # Type of compression for the file self.comment = b"" # Comment for each file self.extra = b"" # ZIP extra data - if sys.platform == 'win32': - self.create_system = 0 # System which created ZIP archive - else: - # Assume everything else is unix-y - self.create_system = 3 # System which created ZIP archive + self.create_system = 3 # System which created ZIP archive self.create_version = 20 # Version which created ZIP archive self.extract_version = 20 # Version needed to extract archive self.reserved = 0 # Must be zero