Remove hardcoding of mbcs for filesystem names

This commit is contained in:
Kovid Goyal 2019-11-18 08:16:02 +05:30
parent f3062760ab
commit 36d81d74d5
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
11 changed files with 92 additions and 238 deletions

View File

@ -8,7 +8,7 @@ import os, subprocess, shutil, re
from functools import partial from functools import partial
from calibre import prints from calibre import prints
from calibre.constants import iswindows, ispy3 from calibre.constants import iswindows
from calibre.ptempfile import TemporaryDirectory from calibre.ptempfile import TemporaryDirectory
from calibre.ebooks.metadata import ( from calibre.ebooks.metadata import (
MetaInformation, string_to_authors, check_isbn, check_doi) MetaInformation, string_to_authors, check_isbn, check_doi)
@ -99,8 +99,6 @@ def page_images(pdfpath, outputdir='.', first=1, last=1, image_format='jpeg', pr
def is_pdf_encrypted(path_to_pdf): 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] pdfinfo = get_tools()[0]
raw = subprocess.check_output([pdfinfo, path_to_pdf]) raw = subprocess.check_output([pdfinfo, path_to_pdf])
q = re.search(br'^Encrypted:\s*(\S+)', raw, flags=re.MULTILINE) q = re.search(br'^Encrypted:\s*(\S+)', raw, flags=re.MULTILINE)

View File

@ -2,8 +2,6 @@
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai # vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
# License: GPLv3 Copyright: 2010, Kovid Goyal <kovid at kovidgoyal.net> # License: GPLv3 Copyright: 2010, Kovid Goyal <kovid at kovidgoyal.net>
import errno import errno
import json import json
import numbers import numbers
@ -50,7 +48,7 @@ if iswindows and not isportable:
exe_base = os.path.abspath(os.path.dirname(sys.executable)) exe_base = os.path.abspath(os.path.dirname(sys.executable))
exe = os.path.join(exe_base, 'calibre.exe') exe = os.path.join(exe_base, 'calibre.exe')
if isinstance(exe, bytes): if isinstance(exe, bytes):
exe = exe.decode('mbcs') exe = os.fsdecode(exe)
return exe return exe
def startup_shortcut_path(): def startup_shortcut_path():

View File

@ -30,10 +30,8 @@ def is_ok():
try: try:
from calibre.constants import filesystem_encoding
from calibre.utils.config import dynamic from calibre.utils.config import dynamic
except ImportError: except ImportError:
filesystem_encoding = 'mbcs'
dynamic = {} dynamic = {}
@ -112,7 +110,7 @@ class Loop(QEventLoop):
def process_path(x): def process_path(x):
if isinstance(x, bytes): if isinstance(x, bytes):
x = x.decode(filesystem_encoding) x = os.fsdecode(x)
return os.path.abspath(os.path.expanduser(x)) return os.path.abspath(os.path.expanduser(x))
@ -167,7 +165,7 @@ def run_file_dialog(
data.append(serialize_string('FOLDER', initial_folder)) data.append(serialize_string('FOLDER', initial_folder))
if filename: if filename:
if isinstance(filename, bytes): if isinstance(filename, bytes):
filename = filename.decode(filesystem_encoding) filename = os.fsdecode(filename)
data.append(serialize_string('FILENAME', filename)) data.append(serialize_string('FILENAME', filename))
if only_dirs: if only_dirs:
file_types = () # file types not allowed for dir only dialogs file_types = () # file types not allowed for dir only dialogs

View File

@ -125,7 +125,7 @@ def base_dir():
try: try:
tempfile.gettempdir() tempfile.gettempdir()
except: except Exception:
# Widows temp vars set to a path not encodable in mbcs # Widows temp vars set to a path not encodable in mbcs
# Use our temp dir # Use our temp dir
tempfile.tempdir = _base_dir tempfile.tempdir = _base_dir

View File

@ -20,7 +20,7 @@ from calibre.utils.shared_file import share_open, raise_winerror
from polyglot.builtins import iteritems, map, range from polyglot.builtins import iteritems, map, range
from polyglot import reprlib from polyglot import reprlib
from polyglot.http_cookie import SimpleCookie from polyglot.http_cookie import SimpleCookie
from polyglot.builtins import is_py3, unicode_type, as_bytes, as_unicode from polyglot.builtins import unicode_type, as_unicode
from polyglot.urllib import parse_qs, quote as urlquote from polyglot.urllib import parse_qs, quote as urlquote
from polyglot.binary import as_hex_unicode as encode_name, from_hex_unicode as decode_name from polyglot.binary import as_hex_unicode as encode_name, from_hex_unicode as decode_name
@ -523,10 +523,5 @@ def get_use_roman():
return _use_roman return _use_roman
if iswindows and not is_py3: def fast_now_strftime(fmt):
def fast_now_strftime(fmt):
fmt = as_bytes(fmt, encoding='mbcs')
return time.strftime(fmt).decode('mbcs', 'replace')
else:
def fast_now_strftime(fmt):
return as_unicode(time.strftime(fmt), errors='replace') return as_unicode(time.strftime(fmt), errors='replace')

View File

@ -7,7 +7,7 @@ __docformat__ = 'restructuredtext en'
Perform various initialization tasks. Perform various initialization tasks.
''' '''
import locale, sys, os import locale, sys
# Default translation is NOOP # Default translation is NOOP
from polyglot.builtins import builtins, is_py3, unicode_type from polyglot.builtins import builtins, is_py3, unicode_type
@ -21,7 +21,7 @@ builtins.__dict__['__'] = lambda s: s
builtins.__dict__['dynamic_property'] = lambda func: func(None) builtins.__dict__['dynamic_property'] = lambda func: func(None)
from calibre.constants import iswindows, preferred_encoding, plugins, isosx, islinux, isfrozen, DEBUG, isfreebsd, ispy3 from calibre.constants import iswindows, preferred_encoding, plugins, isosx, islinux, DEBUG, isfreebsd
_run_once = False _run_once = False
winutil = winutilerror = None winutil = winutilerror = None
@ -30,23 +30,8 @@ if not _run_once:
_run_once = True _run_once = True
from importlib import import_module from importlib import import_module
if not isfrozen and not ispy3:
# Prevent PyQt4 from being loaded
class PyQt4Ban(object):
def find_module(self, fullname, path=None):
if fullname.startswith('PyQt4'):
return self
def load_module(self, fullname):
raise ImportError('Importing PyQt4 is not allowed as calibre uses PyQt5')
sys.meta_path.insert(0, PyQt4Ban())
class DeVendor(object): class DeVendor(object):
if ispy3:
def find_spec(self, fullname, path, target=None): def find_spec(self, fullname, path, target=None):
spec = None spec = None
if fullname == 'calibre.web.feeds.feedparser': if fullname == 'calibre.web.feeds.feedparser':
@ -57,17 +42,6 @@ if not _run_once:
spec = m.__spec__ spec = m.__spec__
return spec return spec
else:
def find_module(self, fullname, path=None):
if fullname == 'calibre.web.feeds.feedparser' or fullname.startswith('calibre.ebooks.markdown'):
return self
def load_module(self, fullname):
if fullname == 'calibre.web.feeds.feedparser':
return import_module('feedparser')
return import_module(fullname[len('calibre.ebooks.'):])
sys.meta_path.insert(0, DeVendor()) sys.meta_path.insert(0, DeVendor())
# #
@ -79,25 +53,6 @@ if not _run_once:
if len(sys.argv) > 1 and not isinstance(sys.argv[1], unicode_type): if len(sys.argv) > 1 and not isinstance(sys.argv[1], unicode_type):
sys.argv[1:] = winutil.argv()[1-len(sys.argv):] sys.argv[1:] = winutil.argv()[1-len(sys.argv):]
if not ispy3:
# Python2's expanduser is broken for non-ASCII usernames
# and unicode paths
def expanduser(path):
if isinstance(path, bytes):
path = path.decode('mbcs')
if path[:1] != '~':
return path
i, n = 1, len(path)
while i < n and path[i] not in '/\\':
i += 1
userhome = winutil.special_folder_path(winutil.CSIDL_PROFILE)
if i != 1: # ~user
userhome = os.path.join(os.path.dirname(userhome), path[1:i])
return userhome + path[i:]
os.path.expanduser = expanduser
# Ensure that all temp files/dirs are created under a calibre tmp dir # Ensure that all temp files/dirs are created under a calibre tmp dir
from calibre.ptempfile import base_dir from calibre.ptempfile import base_dir
try: try:

View File

@ -1,8 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai # vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2011, Kovid Goyal <kovid@kovidgoyal.net>' __copyright__ = '2011, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'

View File

@ -490,9 +490,9 @@ if iswindows:
def rename_file(a, b): def rename_file(a, b):
move_file = plugins['winutil'][0].move_file move_file = plugins['winutil'][0].move_file
if isinstance(a, bytes): if isinstance(a, bytes):
a = a.decode('mbcs') a = os.fsdecode(a)
if isinstance(b, bytes): if isinstance(b, bytes):
b = b.decode('mbcs') b = os.fsdecode(b)
move_file(a, b) move_file(a, b)

View File

@ -17,7 +17,7 @@ from PyQt5.QtCore import QBuffer, QByteArray, Qt
from PyQt5.QtGui import QColor, QImage, QImageReader, QImageWriter, QPixmap, QTransform from PyQt5.QtGui import QColor, QImage, QImageReader, QImageWriter, QPixmap, QTransform
from calibre import fit_image, force_unicode from calibre import fit_image, force_unicode
from calibre.constants import iswindows, plugins, ispy3 from calibre.constants import iswindows, plugins
from calibre.ptempfile import TemporaryDirectory from calibre.ptempfile import TemporaryDirectory
from calibre.utils.config_base import tweaks from calibre.utils.config_base import tweaks
from calibre.utils.filenames import atomic_rename from calibre.utils.filenames import atomic_rename
@ -53,8 +53,8 @@ def get_exe_path(name):
def load_jxr_data(data): def load_jxr_data(data):
with TemporaryDirectory() as tdir: with TemporaryDirectory() as tdir:
if iswindows and isinstance(tdir, unicode_type): if isinstance(tdir, bytes):
tdir = tdir.encode('mbcs') tdir = os.fsdecode(tdir)
with lopen(os.path.join(tdir, 'input.jxr'), 'wb') as f: with lopen(os.path.join(tdir, 'input.jxr'), 'wb') as f:
f.write(data) f.write(data)
cmd = [get_exe_path('JxrDecApp'), '-i', 'input.jxr', '-o', 'output.tif'] cmd = [get_exe_path('JxrDecApp'), '-i', 'input.jxr', '-o', 'output.tif']
@ -542,13 +542,6 @@ def run_optimizer(file_path, cmd, as_filter=False, input_data=None):
cmd[cmd.index(q)] = r cmd[cmd.index(q)] = r
if not as_filter: if not as_filter:
repl(True, iname), repl(False, oname) 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, unicode_type) else x for x in cmd]
if isinstance(cwd, unicode_type):
cwd = cwd.encode('mbcs')
stdin = subprocess.PIPE if as_filter else None stdin = subprocess.PIPE if as_filter else None
stderr = subprocess.PIPE if as_filter else subprocess.STDOUT stderr = subprocess.PIPE if as_filter else subprocess.STDOUT
creationflags = 0x08 if iswindows else 0 creationflags = 0x08 if iswindows else 0

View File

@ -2,8 +2,6 @@
# vim:fileencoding=utf-8 # vim:fileencoding=utf-8
# License: GPLv3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net> # License: GPLv3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net>
import atexit import atexit
import errno import errno
import os import os
@ -50,7 +48,7 @@ def unix_retry(err):
def windows_open(path): def windows_open(path):
if isinstance(path, bytes): if isinstance(path, bytes):
path = path.decode('mbcs') path = os.fsdecode(path)
try: try:
h = win32file.CreateFileW( h = win32file.CreateFileW(
path, path,

View File

@ -2,8 +2,6 @@
# vim:fileencoding=utf-8 # vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net> # License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
import os import os
import sys import sys
@ -46,12 +44,15 @@ def only_unicode_recursive(x, encoding='utf-8', errors='strict'):
if isinstance(x, (set, list, tuple, frozenset)): if isinstance(x, (set, list, tuple, frozenset)):
return type(x)(only_unicode_recursive(i, encoding, errors) for i in x) return type(x)(only_unicode_recursive(i, encoding, errors) for i in x)
if isinstance(x, dict): if isinstance(x, dict):
return {only_unicode_recursive(k, encoding, errors): only_unicode_recursive(v, encoding, errors) for k, v in iteritems(x)} return {
only_unicode_recursive(k, encoding, errors):
only_unicode_recursive(v, encoding, errors)
for k, v in iteritems(x)
}
return x return x
if is_py3: def reraise(tp, value, tb=None):
def reraise(tp, value, tb=None):
try: try:
if value is None: if value is None:
value = tp() value = tp()
@ -62,141 +63,61 @@ if is_py3:
value = None value = None
tb = None tb = None
import builtins
zip = builtins.zip import builtins
map = builtins.map
filter = builtins.filter
range = builtins.range
codepoint_to_chr = chr zip = builtins.zip
unicode_type = str map = builtins.map
string_or_bytes = str, bytes filter = builtins.filter
string_or_unicode = str range = builtins.range
long_type = int
raw_input = input
getcwd = os.getcwd
getenv = os.getenv
def error_message(exc): codepoint_to_chr = chr
unicode_type = str
string_or_bytes = str, bytes
string_or_unicode = str
long_type = int
raw_input = input
getcwd = os.getcwd
getenv = os.getenv
def error_message(exc):
args = getattr(exc, 'args', None) args = getattr(exc, 'args', None)
if args and isinstance(args[0], unicode_type): if args and isinstance(args[0], unicode_type):
return args[0] return args[0]
return unicode_type(exc) return unicode_type(exc)
def iteritems(d):
def iteritems(d):
return iter(d.items()) return iter(d.items())
def itervalues(d):
def itervalues(d):
return iter(d.values()) return iter(d.values())
def environ_item(x):
def environ_item(x):
if isinstance(x, bytes): if isinstance(x, bytes):
x = x.decode('utf-8') x = x.decode('utf-8')
return x return x
def exec_path(path, ctx=None):
def exec_path(path, ctx=None):
ctx = ctx or {} ctx = ctx or {}
with open(path, 'rb') as f: with open(path, 'rb') as f:
code = f.read() code = f.read()
code = compile(code, f.name, 'exec') code = compile(code, f.name, 'exec')
exec(code, ctx) exec(code, ctx)
def cmp(a, b):
def cmp(a, b):
return (a > b) - (a < b) return (a > b) - (a < b)
def int_to_byte(x):
return bytes((x,))
def reload(module): def int_to_byte(x):
return bytes((x, ))
def reload(module):
import importlib import importlib
return importlib.reload(module) return importlib.reload(module)
else:
exec("""def reraise(tp, value, tb=None):
try:
raise tp, value, tb
finally:
tb = None
""")
from future_builtins import zip, map, filter # noqa
range = xrange
import __builtin__ as builtins
codepoint_to_chr = unichr
unicode_type = unicode
string_or_bytes = unicode, bytes
string_or_unicode = str, unicode
long_type = long
exec_path = execfile
raw_input = builtins.raw_input
cmp = builtins.cmp
int_to_byte = chr
getcwd = os.getcwdu
def error_message(exc):
ans = exc.message
if isinstance(ans, bytes):
ans = ans.decode('utf-8', 'replace')
return ans
def iteritems(d):
return d.iteritems()
def itervalues(d):
return d.itervalues()
def environ_item(x):
if isinstance(x, unicode_type):
x = x.encode('utf-8')
return x
if hasattr(sys, 'getwindowsversion'):
def getenv(x, default=None):
if isinstance(x, bytes):
x = x.decode('mbcs', 'replace')
if getenv.buf is None:
import ctypes
import ctypes.wintypes as w
getenv.cub = ctypes.create_unicode_buffer
getenv.buf = getenv.cub(1024)
getenv.gev = ctypes.windll.kernel32.GetEnvironmentVariableW
getenv.gev.restype = w.DWORD
getenv.gev.argtypes = [w.LPCWSTR, w.LPWSTR, w.DWORD]
res = getenv.gev(x, getenv.buf, len(getenv.buf))
if res == 0:
return default
if res > len(getenv.buf) - 4:
getenv.buf = getenv.cub(res + 8)
res = getenv.gev(x, getenv.buf, len(getenv.buf))
if res == 0:
return default
return getenv.buf.value
getenv.buf = None
else:
def getenv(x, default=None):
ans = os.getenv(x, default)
if isinstance(ans, bytes):
ans = ans.decode('utf-8', 'replace')
return ans
def reload(module):
return builtins.reload(module)
def print_to_binary_file(fileobj, encoding='utf-8'):
def print(*a, **kw):
f = kw.get('file', fileobj)
if a:
sep = as_bytes(kw.get('sep', ' '), encoding)
for x in a:
x = as_bytes(x, encoding)
f.write(x)
if x is not a[-1]:
f.write(sep)
f.write(as_bytes(kw.get('end', '\n')))
return print