mirror of
https://github.com/9001/copyparty.git
synced 2025-08-18 09:22:31 -06:00
fix dl from shares with -j0
; closes #146
`write_dls` assumed `vfs.all_nodes` included shares; make it so shares now also appear in the active-downloads list, but the URL is hidden unless the viewer definitely already knows the share exists (which is why vfs-nodes now have `shr_owner`) also adds PRTY_FORCE_MP, a beefybit (opposite of chickenbit) to allow multiprocessing on known-buggy platforms (macos)
This commit is contained in:
parent
25974d660d
commit
8417098c68
10
README.md
10
README.md
|
@ -100,6 +100,7 @@ turn almost any device into a file server with resumable uploads/downloads using
|
||||||
* [custom mimetypes](#custom-mimetypes) - change the association of a file extension
|
* [custom mimetypes](#custom-mimetypes) - change the association of a file extension
|
||||||
* [GDPR compliance](#GDPR-compliance) - imagine using copyparty professionally...
|
* [GDPR compliance](#GDPR-compliance) - imagine using copyparty professionally...
|
||||||
* [feature chickenbits](#feature-chickenbits) - buggy feature? rip it out
|
* [feature chickenbits](#feature-chickenbits) - buggy feature? rip it out
|
||||||
|
* [feature beefybits](#feature-beefybits) - force-enable incompatible features
|
||||||
* [packages](#packages) - the party might be closer than you think
|
* [packages](#packages) - the party might be closer than you think
|
||||||
* [arch package](#arch-package) - now [available on aur](https://aur.archlinux.org/packages/copyparty) maintained by [@icxes](https://github.com/icxes)
|
* [arch package](#arch-package) - now [available on aur](https://aur.archlinux.org/packages/copyparty) maintained by [@icxes](https://github.com/icxes)
|
||||||
* [fedora package](#fedora-package) - does not exist yet
|
* [fedora package](#fedora-package) - does not exist yet
|
||||||
|
@ -2137,6 +2138,15 @@ buggy feature? rip it out by setting any of the following environment variables
|
||||||
example: `PRTY_NO_IFADDR=1 python3 copyparty-sfx.py`
|
example: `PRTY_NO_IFADDR=1 python3 copyparty-sfx.py`
|
||||||
|
|
||||||
|
|
||||||
|
### feature beefybits
|
||||||
|
|
||||||
|
force-enable features with known issues on your OS/env by setting any of the following environment variables, also affectionately knnown as `fuckitbits` or `hail-mary-bits`
|
||||||
|
|
||||||
|
| env-var | what it does |
|
||||||
|
| ------------------------ | ------------ |
|
||||||
|
| `PRTY_FORCE_MP` | force-enable multiprocessing (real multithreading) on MacOS and other broken platforms |
|
||||||
|
|
||||||
|
|
||||||
# packages
|
# packages
|
||||||
|
|
||||||
the party might be closer than you think
|
the party might be closer than you think
|
||||||
|
|
|
@ -359,6 +359,7 @@ class VFS(object):
|
||||||
self.lim: Optional[Lim] = None # upload limits; only set for dbv
|
self.lim: Optional[Lim] = None # upload limits; only set for dbv
|
||||||
self.shr_src: Optional[tuple[VFS, str]] = None # source vfs+rem of a share
|
self.shr_src: Optional[tuple[VFS, str]] = None # source vfs+rem of a share
|
||||||
self.shr_files: set[str] = set() # filenames to include from shr_src
|
self.shr_files: set[str] = set() # filenames to include from shr_src
|
||||||
|
self.shr_owner: str = "" # uname
|
||||||
self.aread: dict[str, list[str]] = {}
|
self.aread: dict[str, list[str]] = {}
|
||||||
self.awrite: dict[str, list[str]] = {}
|
self.awrite: dict[str, list[str]] = {}
|
||||||
self.amove: dict[str, list[str]] = {}
|
self.amove: dict[str, list[str]] = {}
|
||||||
|
@ -376,7 +377,7 @@ class VFS(object):
|
||||||
vp = vpath + ("/" if vpath else "")
|
vp = vpath + ("/" if vpath else "")
|
||||||
self.histpath = os.path.join(realpath, ".hist") # db / thumbcache
|
self.histpath = os.path.join(realpath, ".hist") # db / thumbcache
|
||||||
self.all_vols = {vpath: self} # flattened recursive
|
self.all_vols = {vpath: self} # flattened recursive
|
||||||
self.all_nodes = {vpath: self} # also jumpvols
|
self.all_nodes = {vpath: self} # also jumpvols/shares
|
||||||
self.all_aps = [(rp, self)]
|
self.all_aps = [(rp, self)]
|
||||||
self.all_vps = [(vp, self)]
|
self.all_vps = [(vp, self)]
|
||||||
else:
|
else:
|
||||||
|
@ -2327,11 +2328,6 @@ class AuthSrv(object):
|
||||||
for x, y in vfs.all_vols.items()
|
for x, y in vfs.all_vols.items()
|
||||||
if x != shr and not x.startswith(shrs)
|
if x != shr and not x.startswith(shrs)
|
||||||
}
|
}
|
||||||
vfs.all_nodes = {
|
|
||||||
x: y
|
|
||||||
for x, y in vfs.all_nodes.items()
|
|
||||||
if x != shr and not x.startswith(shrs)
|
|
||||||
}
|
|
||||||
|
|
||||||
assert db and cur and cur2 and shv # type: ignore
|
assert db and cur and cur2 and shv # type: ignore
|
||||||
for row in cur.execute("select * from sh"):
|
for row in cur.execute("select * from sh"):
|
||||||
|
@ -2361,6 +2357,7 @@ class AuthSrv(object):
|
||||||
else:
|
else:
|
||||||
shn.ls = shn._ls
|
shn.ls = shn._ls
|
||||||
|
|
||||||
|
shn.shr_owner = s_un
|
||||||
shn.shr_src = (s_vfs, s_rem)
|
shn.shr_src = (s_vfs, s_rem)
|
||||||
shn.realpath = s_vfs.canonical(s_rem)
|
shn.realpath = s_vfs.canonical(s_rem)
|
||||||
|
|
||||||
|
@ -2386,7 +2383,9 @@ class AuthSrv(object):
|
||||||
|
|
||||||
self.js_ls = {}
|
self.js_ls = {}
|
||||||
self.js_htm = {}
|
self.js_htm = {}
|
||||||
for vn in self.vfs.all_nodes.values():
|
for vp, vn in self.vfs.all_nodes.items():
|
||||||
|
if enshare and vp.startswith(shrs):
|
||||||
|
continue # propagates later in this func
|
||||||
vf = vn.flags
|
vf = vn.flags
|
||||||
vn.js_ls = {
|
vn.js_ls = {
|
||||||
"idx": "e2d" in vf,
|
"idx": "e2d" in vf,
|
||||||
|
@ -2444,8 +2443,12 @@ class AuthSrv(object):
|
||||||
vols = list(vfs.all_nodes.values())
|
vols = list(vfs.all_nodes.values())
|
||||||
if enshare:
|
if enshare:
|
||||||
assert shv # type: ignore # !rm
|
assert shv # type: ignore # !rm
|
||||||
vols.append(shv)
|
for vol in shv.nodes.values():
|
||||||
vols.extend(list(shv.nodes.values()))
|
if vol.vpath not in vfs.all_nodes:
|
||||||
|
self.log("BUG: /%s not in all_nodes" % (vol.vpath,), 1)
|
||||||
|
vols.append(vol)
|
||||||
|
if shr in vfs.all_nodes:
|
||||||
|
self.log("BUG: %s found in all_nodes" % (shr,), 1)
|
||||||
|
|
||||||
for vol in vols:
|
for vol in vols:
|
||||||
dbv = vol.get_dbv("")[0]
|
dbv = vol.get_dbv("")[0]
|
||||||
|
|
|
@ -5012,6 +5012,8 @@ class HttpCli(object):
|
||||||
def get_dls(self) -> list[list[Any]]:
|
def get_dls(self) -> list[list[Any]]:
|
||||||
ret = []
|
ret = []
|
||||||
dls = self.conn.hsrv.tdls
|
dls = self.conn.hsrv.tdls
|
||||||
|
enshare = self.args.shr
|
||||||
|
shrs = enshare[1:]
|
||||||
for dl_id, (t0, sz, vn, vp, uname) in self.conn.hsrv.tdli.items():
|
for dl_id, (t0, sz, vn, vp, uname) in self.conn.hsrv.tdli.items():
|
||||||
t1, sent = dls[dl_id]
|
t1, sent = dls[dl_id]
|
||||||
if sent > 0x100000: # 1m; buffers 2~4
|
if sent > 0x100000: # 1m; buffers 2~4
|
||||||
|
@ -5020,6 +5022,15 @@ class HttpCli(object):
|
||||||
vp = ""
|
vp = ""
|
||||||
elif self.uname not in vn.axs.udot and (vp.startswith(".") or "/." in vp):
|
elif self.uname not in vn.axs.udot and (vp.startswith(".") or "/." in vp):
|
||||||
vp = ""
|
vp = ""
|
||||||
|
elif (
|
||||||
|
enshare
|
||||||
|
and vp.startswith(shrs)
|
||||||
|
and self.uname != vn.shr_owner
|
||||||
|
and self.uname not in vn.axs.uadmin
|
||||||
|
and self.uname not in self.args.shr_adm
|
||||||
|
and not dl_id.startswith(self.ip + ":")
|
||||||
|
):
|
||||||
|
vp = ""
|
||||||
if self.uname not in vn.axs.uadmin:
|
if self.uname not in vn.axs.uadmin:
|
||||||
dl_id = uname = ""
|
dl_id = uname = ""
|
||||||
|
|
||||||
|
|
|
@ -1260,7 +1260,7 @@ class SvcHub(object):
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def check_mp_support(self) -> str:
|
def check_mp_support(self) -> str:
|
||||||
if MACOS:
|
if MACOS and not os.environ.get("PRTY_FORCE_MP"):
|
||||||
return "multiprocessing is wonky on mac osx;"
|
return "multiprocessing is wonky on mac osx;"
|
||||||
elif sys.version_info < (3, 3):
|
elif sys.version_info < (3, 3):
|
||||||
return "need python 3.3 or newer for multiprocessing;"
|
return "need python 3.3 or newer for multiprocessing;"
|
||||||
|
@ -1280,7 +1280,7 @@ class SvcHub(object):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if mp.cpu_count() <= 1:
|
if mp.cpu_count() <= 1 and not os.environ.get("PRTY_FORCE_MP"):
|
||||||
raise Exception()
|
raise Exception()
|
||||||
except:
|
except:
|
||||||
self.log("svchub", "only one CPU detected; multiprocessing disabled")
|
self.log("svchub", "only one CPU detected; multiprocessing disabled")
|
||||||
|
|
Loading…
Reference in a new issue