windows fixes

This commit is contained in:
ed 2020-04-20 03:19:58 +00:00
parent 82f2200f55
commit 5283837e6d
10 changed files with 66 additions and 27 deletions

View file

@ -5,11 +5,17 @@ import platform
import sys import sys
import os import os
WINDOWS = platform.system() == "Windows"
PY2 = sys.version_info[0] == 2 PY2 = sys.version_info[0] == 2
if PY2: if PY2:
sys.dont_write_bytecode = True sys.dont_write_bytecode = True
WINDOWS = False
if platform.system() == "Windows":
WINDOWS = [int(x) for x in platform.version().split(".")]
VT100 = not WINDOWS or WINDOWS >= [10, 0, 14393]
# introduced in anniversary update
class EnvParams(object): class EnvParams(object):
def __init__(self): def __init__(self):
@ -24,6 +30,7 @@ class EnvParams(object):
+ "/copyparty" + "/copyparty"
) )
self.cfg = self.cfg.replace("\\", "/")
try: try:
os.makedirs(self.cfg) os.makedirs(self.cfg)
except: except:

View file

@ -15,7 +15,7 @@ import locale
import argparse import argparse
from textwrap import dedent from textwrap import dedent
from .__init__ import E, WINDOWS from .__init__ import E, WINDOWS, VT100
from .__version__ import S_VERSION, S_BUILD_DT from .__version__ import S_VERSION, S_BUILD_DT
from .svchub import SvcHub from .svchub import SvcHub
from .util import py_desc from .util import py_desc
@ -28,6 +28,8 @@ class RiceFormatter(argparse.HelpFormatter):
except the help += [...] line now has colors except the help += [...] line now has colors
""" """
fmt = "\033[36m (default: \033[35m%(default)s\033[36m)\033[0m" fmt = "\033[36m (default: \033[35m%(default)s\033[36m)\033[0m"
if not VT100:
fmt = " (default: %(default)s)"
help = action.help help = action.help
if "%(default)" not in action.help: if "%(default)" not in action.help:

View file

@ -99,7 +99,8 @@ class VFS(object):
"""return user-readable [fsdir,real,virt] items at vpath""" """return user-readable [fsdir,real,virt] items at vpath"""
virt_vis = {} # nodes readable by user virt_vis = {} # nodes readable by user
abspath = self.canonical(rem) abspath = self.canonical(rem)
real = [fsdec(x) for x in os.listdir(fsenc(abspath))] items = os.listdir(fsenc(abspath))
real = [fsdec(x) for x in items]
real.sort() real.sort()
if not rem: if not rem:
for name, vn2 in sorted(self.nodes.items()): for name, vn2 in sorted(self.nodes.items()):

View file

@ -4,7 +4,7 @@ from __future__ import print_function, unicode_literals
import time import time
import threading import threading
from .__init__ import PY2, WINDOWS from .__init__ import PY2, WINDOWS, VT100
from .broker_util import try_exec from .broker_util import try_exec
from .broker_mpw import MpWorker from .broker_mpw import MpWorker
from .util import mp from .util import mp
@ -141,6 +141,8 @@ class BrokerMp(object):
def debug_load_balancer(self): def debug_load_balancer(self):
fmt = "\033[1m{}\033[0;36m{:4}\033[0m " fmt = "\033[1m{}\033[0;36m{:4}\033[0m "
if not VT100:
fmt = "({}{:4})"
last = "" last = ""
while self.procs: while self.procs:

View file

@ -5,12 +5,7 @@ from __future__ import print_function, unicode_literals
import traceback import traceback
from .__init__ import PY2 from .__init__ import PY2
from .util import Pebkac from .util import Pebkac, Queue
if not PY2:
from queue import Queue
else:
from Queue import Queue # pylint: disable=import-error,no-name-in-module
class ExceptionalQueue(Queue, object): class ExceptionalQueue(Queue, object):

View file

@ -699,8 +699,8 @@ class HttpCli(object):
try: try:
inf = os.stat(fsenc(fspath)) inf = os.stat(fsenc(fspath))
except FileNotFoundError: except:
self.log("broken symlink: {}".format(fspath)) self.log("broken symlink: {}".format(repr(fspath)))
continue continue
is_dir = stat.S_ISDIR(inf.st_mode) is_dir = stat.S_ISDIR(inf.st_mode)

View file

@ -10,11 +10,12 @@ Original source: misc/python/surrogateescape.py in https://bitbucket.org/haypo/m
# This code is released under the Python license and the BSD 2-clause license # This code is released under the Python license and the BSD 2-clause license
import platform
import codecs import codecs
import sys import sys
PY3 = sys.version_info[0] > 2 PY3 = sys.version_info[0] > 2
WINDOWS = platform.system() == "Windows"
FS_ERRORS = "surrogateescape" FS_ERRORS = "surrogateescape"
@ -168,6 +169,11 @@ FS_ENCODING = sys.getfilesystemencoding()
# FS_ENCODING = 'UTF-8'; fn = b('[abc\xff]'); encoded = u('[abc\udcff]') # FS_ENCODING = 'UTF-8'; fn = b('[abc\xff]'); encoded = u('[abc\udcff]')
if WINDOWS and not PY3:
# py2 thinks win* is mbcs, probably a bug? anyways this works
FS_ENCODING = 'utf-8'
# normalize the filesystem encoding name. # normalize the filesystem encoding name.
# For example, we expect "utf-8", not "UTF8". # For example, we expect "utf-8", not "UTF8".
FS_ENCODING = codecs.lookup(FS_ENCODING).name FS_ENCODING = codecs.lookup(FS_ENCODING).name

View file

@ -8,7 +8,7 @@ import threading
from datetime import datetime, timedelta from datetime import datetime, timedelta
import calendar import calendar
from .__init__ import PY2, WINDOWS from .__init__ import PY2, WINDOWS, VT100
from .tcpsrv import TcpSrv from .tcpsrv import TcpSrv
from .up2k import Up2k from .up2k import Up2k
from .util import mp from .util import mp
@ -84,13 +84,23 @@ class SvcHub(object):
dt = dt.replace(hour=0, minute=0, second=0) dt = dt.replace(hour=0, minute=0, second=0)
self.next_day = calendar.timegm(dt.utctimetuple()) self.next_day = calendar.timegm(dt.utctimetuple())
ts = datetime.utcfromtimestamp(now).strftime("%H:%M:%S.%f")[:-3]
fmt = "\033[36m{} \033[33m{:21} \033[0m{}" fmt = "\033[36m{} \033[33m{:21} \033[0m{}"
if not VT100:
fmt = "{} {:21} {}"
if "\033" in msg:
msg = self.ansi_re.sub("", msg)
if "\033" in src:
src = self.ansi_re.sub("", src)
ts = datetime.utcfromtimestamp(now).strftime("%H:%M:%S.%f")[:-3]
msg = fmt.format(ts, src, msg) msg = fmt.format(ts, src, msg)
try: try:
print(msg) print(msg)
except UnicodeEncodeError: except UnicodeEncodeError:
print(msg.encode("utf-8", "replace").decode()) try:
print(msg.encode("utf-8", "replace").decode())
except:
print(msg.encode("ascii", "replace").decode())
def check_mp_support(self): def check_mp_support(self):
vmin = sys.version_info[1] vmin = sys.version_info[1]

View file

@ -10,11 +10,10 @@ import shutil
import base64 import base64
import hashlib import hashlib
import threading import threading
from queue import Queue
from copy import deepcopy from copy import deepcopy
from .__init__ import WINDOWS from .__init__ import WINDOWS
from .util import Pebkac from .util import Pebkac, Queue
class Up2k(object): class Up2k(object):
@ -105,8 +104,8 @@ class Up2k(object):
try: try:
lsrc = src lsrc = src
ldst = dst ldst = dst
fs1 = os.stat(cj["rdir"]).st_dev fs1 = os.stat(os.path.split(src)[0]).st_dev
fs2 = os.stat(job["rdir"]).st_dev fs2 = os.stat(os.path.split(dst)[0]).st_dev
if fs1 == 0: if fs1 == 0:
# py2 on winxp or other unsupported combination # py2 on winxp or other unsupported combination
raise OSError() raise OSError()

View file

@ -10,7 +10,7 @@ import platform
import threading import threading
import subprocess as sp # nosec import subprocess as sp # nosec
from .__init__ import PY2 from .__init__ import PY2, WINDOWS
from .stolen import surrogateescape from .stolen import surrogateescape
FAKE_MP = False FAKE_MP = False
@ -27,12 +27,16 @@ except ImportError:
if not PY2: if not PY2:
from urllib.parse import unquote_to_bytes as unquote from urllib.parse import unquote_to_bytes as unquote
from urllib.parse import quote_from_bytes as quote from urllib.parse import quote_from_bytes as quote
from queue import Queue
else: else:
from urllib import unquote # pylint: disable=no-name-in-module from urllib import unquote # pylint: disable=no-name-in-module
from urllib import quote # pylint: disable=no-name-in-module from urllib import quote # pylint: disable=no-name-in-module
from Queue import Queue # pylint: disable=import-error,no-name-in-module
surrogateescape.register_surrogateescape() surrogateescape.register_surrogateescape()
FS_ENCODING = sys.getfilesystemencoding() FS_ENCODING = sys.getfilesystemencoding()
if WINDOWS and PY2:
FS_ENCODING = "utf-8"
HTTPCODE = { HTTPCODE = {
@ -362,24 +366,24 @@ def exclude_dotfiles(filepaths):
def quotep(txt): def quotep(txt):
"""url quoter which deals with bytes correctly""" """url quoter which deals with bytes correctly"""
btxt = fsenc(txt) btxt = w8enc(txt)
quot1 = quote(btxt, safe=b"/") quot1 = quote(btxt, safe=b"/")
if not PY2: if not PY2:
quot1 = quot1.encode("ascii") quot1 = quot1.encode("ascii")
quot2 = quot1.replace(b" ", b"+") quot2 = quot1.replace(b" ", b"+")
return fsdec(quot2) return w8dec(quot2)
def unquotep(txt): def unquotep(txt):
"""url unquoter which deals with bytes correctly""" """url unquoter which deals with bytes correctly"""
btxt = fsenc(txt) btxt = w8enc(txt)
unq1 = btxt.replace(b"+", b" ") unq1 = btxt.replace(b"+", b" ")
unq2 = unquote(unq1) unq2 = unquote(unq1)
return fsdec(unq2) return w8dec(unq2)
def fsdec(txt): def w8dec(txt):
"""decodes filesystem-bytes to wtf8""" """decodes filesystem-bytes to wtf8"""
if PY2: if PY2:
return surrogateescape.decodefilename(txt) return surrogateescape.decodefilename(txt)
@ -387,7 +391,7 @@ def fsdec(txt):
return txt.decode(FS_ENCODING, "surrogateescape") return txt.decode(FS_ENCODING, "surrogateescape")
def fsenc(txt): def w8enc(txt):
"""encodes wtf8 to filesystem-bytes""" """encodes wtf8 to filesystem-bytes"""
if PY2: if PY2:
return surrogateescape.encodefilename(txt) return surrogateescape.encodefilename(txt)
@ -395,6 +399,19 @@ def fsenc(txt):
return txt.encode(FS_ENCODING, "surrogateescape") return txt.encode(FS_ENCODING, "surrogateescape")
if PY2 and WINDOWS:
# moonrunes become \x3f with bytestrings,
# losing mojibake support is worth
def _not_actually_mbcs(txt):
return txt
fsenc = _not_actually_mbcs
fsdec = _not_actually_mbcs
else:
fsenc = w8enc
fsdec = w8dec
def read_socket(sr, total_size): def read_socket(sr, total_size):
remains = total_size remains = total_size
while remains > 0: while remains > 0: