mirror of
https://github.com/9001/copyparty.git
synced 2025-08-17 09:02:15 -06:00
mv/del: recursive rmdir
This commit is contained in:
parent
1ad7a3f378
commit
129d33f1a0
|
@ -30,6 +30,7 @@ from .util import (
|
|||
vsplit,
|
||||
s3enc,
|
||||
s3dec,
|
||||
rmdirs,
|
||||
statdir,
|
||||
s2hms,
|
||||
min_ex,
|
||||
|
@ -1305,27 +1306,25 @@ class Up2k(object):
|
|||
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])
|
||||
ptop = vn.realpath
|
||||
atop = vn.canonical(rem)
|
||||
adir, fn = os.path.split(atop)
|
||||
st = bos.lstat(atop)
|
||||
scandir = not self.args.no_scandir
|
||||
if stat.S_ISLNK(st.st_mode) or stat.S_ISREG(st.st_mode):
|
||||
dbv, vrem = self.asrv.vfs.get(vpath, uname, *permsets[0])
|
||||
dbv, vrem = dbv.get_dbv(vrem)
|
||||
g = [[dbv, vrem, 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 dbv, vrem, _, adir, files, rd, vd in g:
|
||||
for fn in [x[0] for x in files]:
|
||||
n_files += 1
|
||||
abspath = os.path.join(atop, fn)
|
||||
abspath = os.path.join(adir, fn)
|
||||
vpath = "{}/{}".format(vrem, fn).strip("/")
|
||||
self.log("rm {}\n {}".format(vpath, abspath))
|
||||
_ = dbv.get(vrem, uname, *permsets[0])
|
||||
|
@ -1339,15 +1338,10 @@ class Up2k(object):
|
|||
|
||||
bos.unlink(abspath)
|
||||
|
||||
n_dirs = 0
|
||||
for d in dirs.keys():
|
||||
try:
|
||||
bos.rmdir(d)
|
||||
n_dirs += 1
|
||||
except:
|
||||
pass
|
||||
|
||||
return "deleted {} files (and {}/{} folders)".format(n_files, n_dirs, len(dirs))
|
||||
rm = rmdirs(self.log_func, scandir, True, atop)
|
||||
ok = len(rm[0])
|
||||
ng = len(rm[1])
|
||||
return "deleted {} files (and {}/{} folders)".format(n_files, ok, ok + ng)
|
||||
|
||||
def handle_mv(self, uname, svp, dvp):
|
||||
svn, srem = self.asrv.vfs.get(svp, uname, True, False, True)
|
||||
|
@ -1372,14 +1366,12 @@ class Up2k(object):
|
|||
# fail early (prevent partial moves)
|
||||
raise Pebkac(400, "mv: source folder contains other volumes")
|
||||
|
||||
dirs = {}
|
||||
g = svn.walk("", srem, [], uname, permsets, True, scandir, True)
|
||||
for dbv, vrem, _, atop, files, rd, vd in g:
|
||||
if dbv != jail:
|
||||
# the actual check (avoid toctou)
|
||||
raise Pebkac(400, "mv: source folder contains other volumes")
|
||||
|
||||
dirs[atop] = 1
|
||||
for fn in files:
|
||||
svpf = "/".join(x for x in [dbv.vpath, vrem, fn[0]] if x)
|
||||
if not svpf.startswith(svp + "/"): # assert
|
||||
|
@ -1388,12 +1380,7 @@ class Up2k(object):
|
|||
dvpf = dvp + svpf[len(svp) :]
|
||||
self._mv_file(uname, svpf, dvpf)
|
||||
|
||||
for d in list(dirs.keys()) + [sabs]:
|
||||
try:
|
||||
bos.rmdir(d)
|
||||
except:
|
||||
pass
|
||||
|
||||
rmdirs(self.log_func, scandir, True, sabs)
|
||||
return "k"
|
||||
|
||||
def _mv_file(self, uname, svp, dvp):
|
||||
|
|
|
@ -4,6 +4,7 @@ from __future__ import print_function, unicode_literals
|
|||
import re
|
||||
import os
|
||||
import sys
|
||||
import stat
|
||||
import time
|
||||
import base64
|
||||
import select
|
||||
|
@ -1061,6 +1062,26 @@ def statdir(logger, scandir, lstat, top):
|
|||
logger(src, "{} @ {}".format(repr(ex), top), 1)
|
||||
|
||||
|
||||
def rmdirs(logger, scandir, lstat, top):
|
||||
dirs = statdir(logger, scandir, lstat, top)
|
||||
dirs = [x[0] for x in dirs if stat.S_ISDIR(x[1].st_mode)]
|
||||
dirs = [os.path.join(top, x) for x in dirs]
|
||||
ok = []
|
||||
ng = []
|
||||
for d in dirs[::-1]:
|
||||
a, b = rmdirs(logger, scandir, lstat, d)
|
||||
ok += a
|
||||
ng += b
|
||||
|
||||
try:
|
||||
os.rmdir(fsenc(top))
|
||||
ok.append(top)
|
||||
except:
|
||||
ng.append(top)
|
||||
|
||||
return ok, ng
|
||||
|
||||
|
||||
def unescape_cookie(orig):
|
||||
# mw=idk; doot=qwe%2Crty%3Basd+fgh%2Bjkl%25zxc%26vbn # qwe,rty;asd fgh+jkl%zxc&vbn
|
||||
ret = ""
|
||||
|
|
|
@ -1555,7 +1555,7 @@ var fileman = (function () {
|
|||
treectl.goto(get_evpath());
|
||||
return;
|
||||
}
|
||||
toast.inf(2, 'deleting ' + (vps.length + 1) + ' items\n\n' + vp);
|
||||
toast.inf(0, 'deleting ' + (vps.length + 1) + ' items\n\n' + vp);
|
||||
|
||||
xhr.open('GET', vp + '?delete', true);
|
||||
xhr.onreadystatechange = delete_cb;
|
||||
|
@ -1642,7 +1642,7 @@ var fileman = (function () {
|
|||
r.tx(srcdir);
|
||||
return;
|
||||
}
|
||||
toast.inf(2, 'pasting ' + (req.length + 1) + ' items\n\n' + vp);
|
||||
toast.inf(0, 'pasting ' + (req.length + 1) + ' items\n\n' + vp);
|
||||
|
||||
var dst = get_evpath() + vp.split('/').slice(-1)[0];
|
||||
|
||||
|
@ -2034,8 +2034,10 @@ document.onkeydown = function (e) {
|
|||
if (ctrl(e))
|
||||
document.documentElement.scrollTop += (d == 'next' ? 1 : -1) * el.offsetHeight;
|
||||
|
||||
if (e.shiftKey)
|
||||
if (e.shiftKey) {
|
||||
clmod(el, 'sel', 't');
|
||||
msel.selui();
|
||||
}
|
||||
|
||||
return ev(e);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue