From 76041fdba80a26cb9f32995f010466eef2356fef Mon Sep 17 00:00:00 2001 From: ed Date: Sat, 7 Feb 2026 20:29:38 +0000 Subject: [PATCH] hide dotvols in more apis; also default-set unlistcr/unlistcw to hide in controlpanel --- copyparty/authsrv.py | 7 ++++++- copyparty/httpcli.py | 28 ++++++++++++++++++---------- copyparty/util.py | 6 ++++++ 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/copyparty/authsrv.py b/copyparty/authsrv.py index cc350f3e..48f161a3 100644 --- a/copyparty/authsrv.py +++ b/copyparty/authsrv.py @@ -1286,9 +1286,14 @@ class AuthSrv(object): if not bos.path.exists(src): self.log("warning: filesystem-path did not exist: %r" % (src,), 3) + vf = {} + if dst.startswith(".") or "/." in dst: + vf["unlistcr"] = True + vf["unlistcw"] = True + mount[dst] = (src, dst0) daxs[dst] = AXS() - mflags[dst] = {} + mflags[dst] = vf return (src, dst) def _e(self, desc: Optional[str] = None) -> None: diff --git a/copyparty/httpcli.py b/copyparty/httpcli.py index c8c05215..d56d7b64 100644 --- a/copyparty/httpcli.py +++ b/copyparty/httpcli.py @@ -64,6 +64,7 @@ from .util import ( b64dec, eol_conv, exclude_dotfiles, + exclude_dotfiles_ls, formatdate, fsenc, gen_content_disposition, @@ -1842,11 +1843,14 @@ class HttpCli(object): if not self.can_read: vfs_ls = [] if not self.can_dot: - names = set(exclude_dotfiles([x[0] for x in vfs_ls])) - vfs_ls = [x for x in vfs_ls if x[0] in names] - + vfs_ls = exclude_dotfiles_ls(vfs_ls) fgen = [{"vp": vp, "st": st} for vp, st in vfs_ls] - fgen += [{"vp": v, "st": vst} for v in vfs_virt] + + if vfs_virt: + zsl = list(vfs_virt) + if not self.can_dot: + zsl = exclude_dotfiles(zsl) + fgen += [{"vp": v, "st": vst} for v in zsl] else: t = "invalid depth value '{}' (must be either '0' or '1'{})" @@ -5813,7 +5817,7 @@ class HttpCli(object): not self.args.no_scandir, PERMS_rwh, ) - dots = self.uname in vn.axs.udot + dots = self.uname in vn.axs.udot and "dots" in self.uparam dk_sz = vn.flags.get("dk") except: dk_sz = None @@ -5826,7 +5830,7 @@ class HttpCli(object): dirs = [x[0] for x in vfs_ls if stat.S_ISDIR(x[1].st_mode)] - if not dots or "dots" not in self.uparam: + if not dots: dirs = exclude_dotfiles(dirs) dirs = [quotep(x) for x in dirs if x != excl] @@ -5840,8 +5844,10 @@ class HttpCli(object): kdirs.append(dn + "?k=" + zs) dirs = kdirs - for x in vfs_virt: - if x != excl: + if vfs_virt: + for x in vfs_virt: + if x == excl: + continue try: dvn, drem = vfs.get(vjoin(top, x), self.uname, False, False) if ( @@ -5853,7 +5859,9 @@ class HttpCli(object): bos.stat(dvn.canonical(drem, False)) except: x += "\n" - dirs.append(x) + dirs.append(quotep(x)) + if not dots: + dirs = exclude_dotfiles(dirs) ret["a"] = dirs return ret @@ -7064,7 +7072,7 @@ class HttpCli(object): ) stats = {k: v for k, v in vfs_ls} ls_names = [x[0] for x in vfs_ls] - ls_names.extend(list(vfs_virt.keys())) + ls_names.extend(list(vfs_virt)) if add_og and og_fn and not self.can_read: ls_names = [og_fn] diff --git a/copyparty/util.py b/copyparty/util.py index 78d403f2..78ba922e 100644 --- a/copyparty/util.py +++ b/copyparty/util.py @@ -2372,6 +2372,12 @@ def exclude_dotfiles(filepaths: list[str]) -> list[str]: return [x for x in filepaths if not x.split("/")[-1].startswith(".")] +def exclude_dotfiles_ls( + vfs_ls: list[tuple[str, os.stat_result]] +) -> list[tuple[str, os.stat_result]]: + return [x for x in vfs_ls if not x[0].split("/")[-1].startswith(".")] + + def odfusion( base: Union[ODict[str, bool], ODict["LiteralString", bool]], oth: str ) -> ODict[str, bool]: