This commit is contained in:
ed 2022-06-07 23:08:43 +02:00
parent f79fcc7073
commit fe73f2d579
12 changed files with 75 additions and 75 deletions

View File

@ -25,9 +25,10 @@ import hashlib
import argparse import argparse
import platform import platform
import threading import threading
import requests
import datetime import datetime
import requests
# from copyparty/__init__.py # from copyparty/__init__.py
PY2 = sys.version_info[0] == 2 PY2 = sys.version_info[0] == 2
@ -150,13 +151,11 @@ if not VT100:
def termsize(): def termsize():
import os
env = os.environ env = os.environ
def ioctl_GWINSZ(fd): def ioctl_GWINSZ(fd):
try: try:
import fcntl, termios, struct, os import fcntl, termios, struct
cr = struct.unpack("hh", fcntl.ioctl(fd, termios.TIOCGWINSZ, "1234")) cr = struct.unpack("hh", fcntl.ioctl(fd, termios.TIOCGWINSZ, "1234"))
except: except:
@ -360,7 +359,7 @@ def get_hashlist(file, pcb):
def handshake(req_ses, url, file, pw, search): def handshake(req_ses, url, file, pw, search):
# type: (requests.Session, str, File, any, bool) -> List[str] # type: (requests.Session, str, File, any, bool) -> list[str]
""" """
performs a handshake with the server; reply is: performs a handshake with the server; reply is:
if search, a list of search results if search, a list of search results
@ -491,11 +490,34 @@ class Ctl(object):
self.filegen = walkdirs([], ar.files) self.filegen = walkdirs([], ar.files)
if ar.safe: if ar.safe:
self.safe() self._safe()
else: else:
self.fancy() self.hash_f = 0
self.hash_c = 0
self.hash_b = 0
self.up_f = 0
self.up_c = 0
self.up_b = 0
self.up_br = 0
self.hasher_busy = 1
self.handshaker_busy = 0
self.uploader_busy = 0
def safe(self): self.t0 = time.time()
self.t0_up = None
self.spd = None
self.mutex = threading.Lock()
self.q_handshake = Queue() # type: Queue[File]
self.q_recheck = Queue() # type: Queue[File] # partial upload exists [...]
self.q_upload = Queue() # type: Queue[tuple[File, str]]
self.st_hash = [None, "(idle, starting...)"] # type: tuple[File, int]
self.st_up = [None, "(idle, starting...)"] # type: tuple[File, int]
self._fancy()
def _safe(self):
"""minimal basic slow boring fallback codepath""" """minimal basic slow boring fallback codepath"""
search = self.ar.s search = self.ar.s
for nf, (top, rel, inf) in enumerate(self.filegen): for nf, (top, rel, inf) in enumerate(self.filegen):
@ -529,29 +551,7 @@ class Ctl(object):
print(" ok!") print(" ok!")
def fancy(self): def _fancy(self):
self.hash_f = 0
self.hash_c = 0
self.hash_b = 0
self.up_f = 0
self.up_c = 0
self.up_b = 0
self.up_br = 0
self.hasher_busy = 1
self.handshaker_busy = 0
self.uploader_busy = 0
self.t0 = time.time()
self.t0_up = None
self.spd = None
self.mutex = threading.Lock()
self.q_handshake = Queue() # type: Queue[File]
self.q_recheck = Queue() # type: Queue[File] # partial upload exists [...]
self.q_upload = Queue() # type: Queue[tuple[File, str]]
self.st_hash = [None, "(idle, starting...)"] # type: tuple[File, int]
self.st_up = [None, "(idle, starting...)"] # type: tuple[File, int]
if VT100: if VT100:
atexit.register(self.cleanup_vt100) atexit.register(self.cleanup_vt100)
ss.scroll_region(3) ss.scroll_region(3)
@ -619,7 +619,7 @@ class Ctl(object):
tail = "\033[K\033[u" if VT100 else "\r" tail = "\033[K\033[u" if VT100 else "\r"
m = "{0} eta @ {1}/s, {2}, {3}# left".format(eta, spd, sleft, nleft) m = "{0} eta @ {1}/s, {2}, {3}# left".format(eta, spd, sleft, nleft)
eprint(txt + "\033]0;{0}\033\\\r{1}{2}".format(m, m, tail)) eprint(txt + "\033]0;{0}\033\\\r{0}{1}".format(m, tail))
def cleanup_vt100(self): def cleanup_vt100(self):
ss.scroll_region(None) ss.scroll_region(None)

View File

@ -45,13 +45,13 @@ class RiceFormatter(argparse.HelpFormatter):
if not VT100: if not VT100:
fmt = " (default: %(default)s)" fmt = " (default: %(default)s)"
help = action.help ret = action.help
if "%(default)" not in action.help: if "%(default)" not in action.help:
if action.default is not argparse.SUPPRESS: if action.default is not argparse.SUPPRESS:
defaulting_nargs = [argparse.OPTIONAL, argparse.ZERO_OR_MORE] defaulting_nargs = [argparse.OPTIONAL, argparse.ZERO_OR_MORE]
if action.option_strings or action.nargs in defaulting_nargs: if action.option_strings or action.nargs in defaulting_nargs:
help += fmt ret += fmt
return help return ret
def _fill_text(self, text, width, indent): def _fill_text(self, text, width, indent):
"""same as RawDescriptionHelpFormatter(HelpFormatter)""" """same as RawDescriptionHelpFormatter(HelpFormatter)"""
@ -157,7 +157,7 @@ def configure_ssl_ver(al):
for k in ["ssl_flags_en", "ssl_flags_de"]: for k in ["ssl_flags_en", "ssl_flags_de"]:
num = getattr(al, k) num = getattr(al, k)
lprint("{}: {:8x} ({})".format(k, num, num)) lprint("{0}: {1:8x} ({1})".format(k, num))
# think i need that beer now # think i need that beer now

View File

@ -1003,7 +1003,7 @@ class AuthSrv(object):
if a == b: if a == b:
local = False local = False
for mtp in local_only_mtp.keys(): for mtp in local_only_mtp:
if mtp not in local_mte: if mtp not in local_mte:
m = 'volume "/{}" defines metadata tag "{}", but doesnt use it in "-mte" (or with "cmte" in its volume-flags)' m = 'volume "/{}" defines metadata tag "{}", but doesnt use it in "-mte" (or with "cmte" in its volume-flags)'
self.log(m.format(vol.vpath, mtp), 1) self.log(m.format(vol.vpath, mtp), 1)
@ -1090,7 +1090,7 @@ class AuthSrv(object):
raise Exception("user not found: " + u) raise Exception("user not found: " + u)
if vols == "*": if vols == "*":
vols = ["/" + x for x in self.vfs.all_vols.keys()] vols = ["/" + x for x in self.vfs.all_vols]
else: else:
vols = [vols] vols = [vols]

View File

@ -8,7 +8,7 @@ import threading
from .broker_util import ExceptionalQueue from .broker_util import ExceptionalQueue
from .httpsrv import HttpSrv from .httpsrv import HttpSrv
from .util import FAKE_MP from .util import FAKE_MP
from copyparty.authsrv import AuthSrv from .authsrv import AuthSrv
class MpWorker(object): class MpWorker(object):

View File

@ -11,7 +11,6 @@ class ExceptionalQueue(Queue, object):
def get(self, block=True, timeout=None): def get(self, block=True, timeout=None):
rv = super(ExceptionalQueue, self).get(block, timeout) rv = super(ExceptionalQueue, self).get(block, timeout)
# TODO: how expensive is this?
if isinstance(rv, list): if isinstance(rv, list):
if rv[0] == "exception": if rv[0] == "exception":
if rv[1] == "pebkac": if rv[1] == "pebkac":

View File

@ -6,8 +6,15 @@ import sys
import stat import stat
import time import time
import logging import logging
import argparse
import threading import threading
from pyftpdlib.authorizers import DummyAuthorizer, AuthenticationFailed
from pyftpdlib.filesystems import AbstractedFS, FilesystemError
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer
from pyftpdlib.log import config_logging
from .__init__ import E, PY2 from .__init__ import E, PY2
from .util import Pebkac, fsenc, exclude_dotfiles from .util import Pebkac, fsenc, exclude_dotfiles
from .bos import bos from .bos import bos
@ -20,12 +27,6 @@ except ImportError:
sys.path.append(p) sys.path.append(p)
from pyftpdlib.ioloop import IOLoop from pyftpdlib.ioloop import IOLoop
from pyftpdlib.authorizers import DummyAuthorizer, AuthenticationFailed
from pyftpdlib.filesystems import AbstractedFS, FilesystemError
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer
from pyftpdlib.log import config_logging
try: try:
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
@ -154,7 +155,7 @@ class FtpFs(AbstractedFS):
vfs_ls.sort() vfs_ls.sort()
return vfs_ls return vfs_ls
except Exception as ex: except:
if vpath: if vpath:
# display write-only folders as empty # display write-only folders as empty
return [] return []
@ -266,6 +267,9 @@ class FtpHandler(FTPHandler):
else: else:
super(FtpHandler, self).__init__(conn, server, ioloop) super(FtpHandler, self).__init__(conn, server, ioloop)
self.hub = None # type: SvcHub
self.args = None # type: argparse.Namespace
# abspath->vpath mapping to resolve log_transfer paths # abspath->vpath mapping to resolve log_transfer paths
self.vfs_map = {} self.vfs_map = {}
@ -278,7 +282,7 @@ class FtpHandler(FTPHandler):
# print("ftp_STOR: {} {} OK".format(vp, mode)) # print("ftp_STOR: {} {} OK".format(vp, mode))
return ret return ret
def log_transfer(self, cmd, filename, receive, completed, elapsed, bytes): def log_transfer(self, cmd, filename, receive, completed, elapsed, nbytes):
ap = filename.decode("utf-8", "replace") ap = filename.decode("utf-8", "replace")
vp = self.vfs_map.pop(ap, None) vp = self.vfs_map.pop(ap, None)
# print("xfer_end: {} => {}".format(ap, vp)) # print("xfer_end: {} => {}".format(ap, vp))
@ -298,7 +302,7 @@ class FtpHandler(FTPHandler):
) )
return FTPHandler.log_transfer( return FTPHandler.log_transfer(
self, cmd, filename, receive, completed, elapsed, bytes self, cmd, filename, receive, completed, elapsed, nbytes
) )

View File

@ -532,7 +532,6 @@ class HttpCli(object):
return self.handle_post_multipart() return self.handle_post_multipart()
if "text/plain" in ctype or "application/xml" in ctype: if "text/plain" in ctype or "application/xml" in ctype:
# TODO this will be intredasting
return self.handle_post_json() return self.handle_post_json()
if "application/octet-stream" in ctype: if "application/octet-stream" in ctype:

View File

@ -8,7 +8,7 @@ import shutil
import subprocess as sp import subprocess as sp
from .__init__ import PY2, WINDOWS, unicode from .__init__ import PY2, WINDOWS, unicode
from .util import fsenc, fsdec, uncyg, runcmd, retchk, REKOBO_LKEY from .util import fsenc, uncyg, runcmd, retchk, REKOBO_LKEY
from .bos import bos from .bos import bos
@ -91,7 +91,7 @@ def parse_ffprobe(txt):
"""ffprobe -show_format -show_streams""" """ffprobe -show_format -show_streams"""
streams = [] streams = []
fmt = {} fmt = {}
g = None g = {}
for ln in [x.rstrip("\r") for x in txt.split("\n")]: for ln in [x.rstrip("\r") for x in txt.split("\n")]:
try: try:
k, v = ln.split("=", 1) k, v = ln.split("=", 1)
@ -421,7 +421,7 @@ class MTag(object):
md = mutagen.File(fsenc(abspath), easy=True) md = mutagen.File(fsenc(abspath), easy=True)
if not md.info.length and not md.info.codec: if not md.info.length and not md.info.codec:
raise Exception() raise Exception()
except Exception as ex: except:
return self.get_ffprobe(abspath) if self.can_ffprobe else {} return self.get_ffprobe(abspath) if self.can_ffprobe else {}
sz = bos.path.getsize(abspath) sz = bos.path.getsize(abspath)

View File

@ -88,7 +88,7 @@ class StreamTar(object):
try: try:
self.ser(f) self.ser(f)
except Exception: except:
ex = min_ex(5, True).replace("\n", "\n-- ") ex = min_ex(5, True).replace("\n", "\n-- ")
errors.append([f["vp"], ex]) errors.append([f["vp"], ex])

View File

@ -1,7 +1,6 @@
# coding: utf-8 # coding: utf-8
from __future__ import print_function, unicode_literals from __future__ import print_function, unicode_literals
import time
import tempfile import tempfile
from datetime import datetime from datetime import datetime

View File

@ -257,7 +257,7 @@ class StreamZip(object):
try: try:
for x in self.ser(f): for x in self.ser(f):
yield x yield x
except Exception: except:
ex = min_ex(5, True).replace("\n", "\n-- ") ex = min_ex(5, True).replace("\n", "\n-- ")
errors.append([f["vp"], ex]) errors.append([f["vp"], ex])

View File

@ -297,7 +297,6 @@ class TcpSrv(object):
]: ]:
try: try:
s.connect((ip, 1)) s.connect((ip, 1))
# raise OSError(13, "a")
default_route = s.getsockname()[0] default_route = s.getsockname()[0]
break break
except (OSError, socket.error) as ex: except (OSError, socket.error) as ex:
@ -318,23 +317,23 @@ class TcpSrv(object):
return eps return eps
def _set_wintitle(self, vars): def _set_wintitle(self, vs):
vars["all"] = vars.get("all", {"Local-Only": 1}) vs["all"] = vs.get("all", {"Local-Only": 1})
vars["pub"] = vars.get("pub", vars["all"]) vs["pub"] = vs.get("pub", vs["all"])
vars2 = {} vs2 = {}
for k, eps in vars.items(): for k, eps in vs.items():
vars2[k] = { vs2[k] = {
ep: 1 ep: 1
for ep in eps.keys() for ep in eps.keys()
if ":" not in ep or ep.split(":")[0] not in eps if ":" not in ep or ep.split(":")[0] not in eps
} }
title = "" title = ""
vars = vars2 vs = vs2
for p in self.args.wintitle.split(" "): for p in self.args.wintitle.split(" "):
if p.startswith("$"): if p.startswith("$"):
p = " and ".join(sorted(vars.get(p[1:], {"(None)": 1}).keys())) p = " and ".join(sorted(vs.get(p[1:], {"(None)": 1}).keys()))
title += "{} ".format(p) title += "{} ".format(p)