mv/del: recursive rmdir

This commit is contained in:
ed 2021-07-27 19:15:58 +02:00
parent 1ad7a3f378
commit 129d33f1a0
3 changed files with 35 additions and 25 deletions

View file

@ -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):

View file

@ -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 = ""

View file

@ -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);
}