diff --git a/copyparty/authsrv.py b/copyparty/authsrv.py index caf2ff9c..daab6091 100644 --- a/copyparty/authsrv.py +++ b/copyparty/authsrv.py @@ -242,6 +242,7 @@ class VFS(object): """ fsroot, vfs_ls, vfs_virt = self.ls(rem, uname, scandir, permsets, lstat=lstat) + dbv, vrem = self.get_dbv(rem) if ( seen @@ -259,7 +260,7 @@ class VFS(object): rfiles.sort() rdirs.sort() - yield rel, fsroot, rfiles, rdirs, vfs_virt + yield dbv, vrem, rel, fsroot, rfiles, rdirs, vfs_virt for rdir, _ in rdirs: if not dots and rdir.startswith("."): @@ -287,7 +288,7 @@ class VFS(object): f2b = "{0}.hist{0}".format(os.sep) g = self.walk("", vrem, [], uname, [[True]], dots, scandir, False) - for vpath, apath, files, rd, vd in g: + for _, _, vpath, apath, files, rd, vd in g: if flt: files = [x for x in files if x[0] in flt] @@ -795,7 +796,7 @@ class AuthSrv(object): g = vn.walk( "", "", [], u, True, [[True]], not self.args.no_scandir, False ) - for vpath, apath, files, _, _ in g: + for _, _, vpath, apath, files, _, _ in g: fnames = [n[0] for n in files] vpaths = [vpath + "/" + n for n in fnames] if vpath else fnames vpaths = [vtop + x for x in vpaths] diff --git a/copyparty/httpcli.py b/copyparty/httpcli.py index 16fac16b..c672ddd4 100644 --- a/copyparty/httpcli.py +++ b/copyparty/httpcli.py @@ -1548,27 +1548,8 @@ class HttpCli(object): if self.args.no_del: raise Pebkac(403, "disabled by argv") - permsets = [[True, False, False, True]] - vn, rem = self.asrv.vfs.get(self.vpath, self.uname, *permsets[0]) - abspath = vn.canonical(rem) - - fun = os.lstat if os.supports_follow_symlinks else os.stat - st = fun(fsenc(abspath)) - if stat.S_ISLNK(st.st_mode) or stat.S_ISREG(st.st_mode): - self.log("rm file " + abspath) - return - - scandir = not self.args.no_scandir - g = vn.walk("", rem, [], self.uname, permsets, True, scandir, True) - for vpath, apath, files, rd, vd in g: - for fn in files: - m = "rm file {} / {}".format(apath, fn[0]) - if "yt" in m: - self.log(m) - - # build list of folders to rmdir after - - self.loud_reply("k") + x = self.conn.hsrv.broker.put(True, "up2k.handle_rm", self.uname, self.vpath) + self.loud_reply(x.get()) def handle_mv(self): if not self.can_move: @@ -1586,6 +1567,9 @@ class HttpCli(object): src = svn.canonical(srem) dst = dvn.canonical(drem) + if not srem: + raise Pebkac(400, "cannot move a mountpoint") + self.loud_reply("mv [{}] to [{}]".format(src, dst)) def tx_browser(self): diff --git a/copyparty/up2k.py b/copyparty/up2k.py index df984175..b293162c 100644 --- a/copyparty/up2k.py +++ b/copyparty/up2k.py @@ -32,6 +32,7 @@ from .util import ( s2hms, min_ex, ) +from .authsrv import AuthSrv from .mtag import MTag, MParser try: @@ -44,16 +45,9 @@ DB_VER = 4 class Up2k(object): - """ - TODO: - * documentation - * registry persistence - * ~/.config flatfiles for active jobs - """ - def __init__(self, hub): self.hub = hub - self.asrv = hub.asrv + self.asrv = hub.asrv # type: AuthSrv self.args = hub.args self.log_func = hub.log @@ -1279,6 +1273,64 @@ class Up2k(object): v = (wark, int(ts), sz, rd, fn) db.execute(sql, v) + def handle_rm(self, uname, vpath): + dirs = {} + permsets = [[True, False, False, True]] + vn, rem = self.asrv.vfs.get(vpath, uname, *permsets[0]) + atop = vn.canonical(rem) + adir, fn = os.path.split(atop) + + fun = os.lstat if os.supports_follow_symlinks else os.stat + st = fun(fsenc(atop)) + if stat.S_ISLNK(st.st_mode) or stat.S_ISREG(st.st_mode): + g = [[os.path.dirname(vpath), adir, [[fn, 0]], [], []]] + else: + scandir = not self.args.no_scandir + g = vn.walk("", rem, [], uname, permsets, True, scandir, True) + + n_files = 0 + for dbv, vrem, _, atop, files, rd, vd in g: + dirs[atop] = 1 + for fn in [x[0] for x in files]: + n_files += 1 + abspath = os.path.join(atop, fn) + vpath = "{}/{}".format(vrem, fn).strip("/") + self.log("rm file {}\n vpath: {}".format(abspath, vpath)) + # dbv, vrem = self.asrv.vfs.get(vpath, uname, *permsets[0]) + # dbv, vrem = dbv.get_dbv(vrem) + _ = dbv.get(vrem, uname, *permsets[0]) + with self.mutex: + self._drop_file(dbv.realpath, vpath) + + n_dirs = 0 + for d in dirs.keys(): + try: + os.rmdir(d) + n_dirs += 1 + except: + pass + + return "deleted {} files (and {}/{} folders)".format(n_files, n_dirs, len(dirs)) + + def _drop_file(self, ptop, vrem): + cur = self.cur.get(ptop) + if cur: + q = "delete from up where rd=? and fn=?" + rd, fn = os.path.split(vrem) + self.log("{}, [{}], [{}]".format(q, rd, fn)) + # self.db_rm(cur, rd, fn) + + reg = self.registry.get(ptop) + if reg: + wark = [ + x + for x, y in reg.items() + if fn in [y["name"], y.get("tnam")] and y["prel"] == vrem + ] + if wark: + self.log("forgetting wark {}".format(wark[0])) + del reg[wark[0]] + def _get_wark(self, cj): if len(cj["name"]) > 1024 or len(cj["hash"]) > 512 * 1024: # 16TiB raise Pebkac(400, "name or numchunks not according to spec") diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 812ae768..2c9e5091 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -383,7 +383,6 @@ html.light #ggrid a.sel { white-space: nowrap; top: -1.2em; right: 0; - width: 2.5em; height: 1em; font-size: 2em; line-height: 1em; @@ -392,7 +391,7 @@ html.light #ggrid a.sel { background: #3c3c3c; box-shadow: 0 0 .5em #222; border-radius: .3em 0 0 0; - padding: .2em 0 0 .07em; + padding: .2em .2em; color: #fff; } #wzip, #wnp { @@ -414,12 +413,6 @@ html.light #ggrid a.sel { #wtoggle * { line-height: 1em; } -#wtoggle.np { - width: 6.63em; -} -#wtoggle.sel { - width: 7.57em; -} #wtoggle.sel #wzip, #wtoggle.np #wnp { display: inline-block; @@ -427,15 +420,21 @@ html.light #ggrid a.sel { #wtoggle.sel.np #wnp { display: none; } +#wfm a, #wzip a { - font-size: .4em; + font-size: .5em; padding: 0 .3em; margin: -.3em .2em; position: relative; display: inline-block; } -#wzip a+a { - margin-left: .8em; +#wfm span { + font-size: .6em; + display: block; +} +#wzip a { + font-size: .4em; + margin: -.3em .3em; } #wtoggle.sel #wzip #selzip { top: -.6em; diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index d8682c3d..73e62dbc 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -29,7 +29,13 @@ ebi('ops').innerHTML = ( // media player ebi('widget').innerHTML = ( '