mirror of
				https://github.com/9001/copyparty.git
				synced 2025-11-04 05:43:17 +00:00 
			
		
		
		
	mv/del: recursive rmdir
This commit is contained in:
		@@ -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);
 | 
			
		||||
			}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user