mirror of
https://github.com/9001/copyparty.git
synced 2025-08-18 01:22:13 -06:00
mv(folder) works
This commit is contained in:
parent
daa9dedcaa
commit
fb40a484c5
|
@ -555,10 +555,7 @@ class AuthSrv(object):
|
||||||
elif self.args.hist:
|
elif self.args.hist:
|
||||||
for nch in range(len(hid)):
|
for nch in range(len(hid)):
|
||||||
hpath = os.path.join(self.args.hist, hid[: nch + 1])
|
hpath = os.path.join(self.args.hist, hid[: nch + 1])
|
||||||
try:
|
|
||||||
bos.makedirs(hpath)
|
bos.makedirs(hpath)
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
powner = os.path.join(hpath, "owner.txt")
|
powner = os.path.join(hpath, "owner.txt")
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -22,8 +22,13 @@ def lstat(p):
|
||||||
return os.lstat(fsenc(p))
|
return os.lstat(fsenc(p))
|
||||||
|
|
||||||
|
|
||||||
def makedirs(name, mode=0o755):
|
def makedirs(name, mode=0o755, exist_ok=True):
|
||||||
return os.makedirs(fsenc(name), mode=mode)
|
bname = fsenc(name)
|
||||||
|
try:
|
||||||
|
os.makedirs(bname, mode=mode)
|
||||||
|
except:
|
||||||
|
if not exist_ok or not os.path.isdir(bname):
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
def mkdir(p, mode=0o755):
|
def mkdir(p, mode=0o755):
|
||||||
|
|
|
@ -155,10 +155,7 @@ class ThumbSrv(object):
|
||||||
self.log("wait {}".format(tpath))
|
self.log("wait {}".format(tpath))
|
||||||
except:
|
except:
|
||||||
thdir = os.path.dirname(tpath)
|
thdir = os.path.dirname(tpath)
|
||||||
try:
|
|
||||||
bos.makedirs(thdir)
|
bos.makedirs(thdir)
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
inf_path = os.path.join(thdir, "dir.txt")
|
inf_path = os.path.join(thdir, "dir.txt")
|
||||||
if not bos.path.exists(inf_path):
|
if not bos.path.exists(inf_path):
|
||||||
|
|
|
@ -375,10 +375,7 @@ class Up2k(object):
|
||||||
if not HAVE_SQLITE3 or "e2d" not in flags or "d2d" in flags:
|
if not HAVE_SQLITE3 or "e2d" not in flags or "d2d" in flags:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
try:
|
|
||||||
bos.makedirs(histpath)
|
bos.makedirs(histpath)
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cur = self._open_db(db_path)
|
cur = self._open_db(db_path)
|
||||||
|
@ -1323,16 +1320,65 @@ class Up2k(object):
|
||||||
|
|
||||||
def handle_mv(self, uname, svp, dvp):
|
def handle_mv(self, uname, svp, dvp):
|
||||||
svn, srem = self.asrv.vfs.get(svp, uname, True, False, True)
|
svn, srem = self.asrv.vfs.get(svp, uname, True, False, True)
|
||||||
dvn, drem = self.asrv.vfs.get(dvp, uname, False, True)
|
svn, srem = svn.get_dbv(srem)
|
||||||
sabs = svn.canonical(srem)
|
sabs = svn.canonical(srem)
|
||||||
dabs = dvn.canonical(drem)
|
|
||||||
drd, dfn = vsplit(drem)
|
|
||||||
|
|
||||||
if not srem:
|
if not srem:
|
||||||
raise Pebkac(400, "mv: cannot move a mountpoint")
|
raise Pebkac(400, "mv: cannot move a mountpoint")
|
||||||
|
|
||||||
|
st = bos.stat(sabs)
|
||||||
|
if stat.S_ISREG(st.st_mode):
|
||||||
|
return self._mv_file(uname, svp, dvp)
|
||||||
|
|
||||||
|
jail = svn.get_dbv(srem)[0]
|
||||||
|
permsets = [[True, False, True]]
|
||||||
|
scandir = not self.args.no_scandir
|
||||||
|
|
||||||
|
# following symlinks is too scary, TODO schedule rescans as needed
|
||||||
|
g = svn.walk("", srem, [], uname, permsets, True, scandir, True)
|
||||||
|
for dbv, vrem, _, atop, files, rd, vd in g:
|
||||||
|
if dbv != jail:
|
||||||
|
# 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
|
||||||
|
raise Pebkac(500, "mv: bug at {}, top {}".format(svpf, svp))
|
||||||
|
|
||||||
|
dvpf = dvp + svpf[len(svp) :]
|
||||||
|
self._mv_file(uname, svpf, dvpf)
|
||||||
|
|
||||||
|
for d in list(dirs.keys()) + [sabs]:
|
||||||
|
try:
|
||||||
|
bos.rmdir(d)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return "k"
|
||||||
|
|
||||||
|
def _mv_file(self, uname, svp, dvp):
|
||||||
|
svn, srem = self.asrv.vfs.get(svp, uname, True, False, True)
|
||||||
|
svn, srem = svn.get_dbv(srem)
|
||||||
|
|
||||||
|
dvn, drem = self.asrv.vfs.get(dvp, uname, False, True)
|
||||||
|
dvn, drem = dvn.get_dbv(drem)
|
||||||
|
|
||||||
|
sabs = svn.canonical(srem)
|
||||||
|
dabs = dvn.canonical(drem)
|
||||||
|
drd, dfn = vsplit(drem)
|
||||||
|
st = bos.stat(sabs)
|
||||||
|
|
||||||
if bos.path.exists(dabs):
|
if bos.path.exists(dabs):
|
||||||
raise Pebkac(400, "mv: target file exists")
|
raise Pebkac(400, "mv2: target file exists")
|
||||||
|
|
||||||
c1, w = self._find_from_vpath(svn.realpath, srem)
|
c1, w = self._find_from_vpath(svn.realpath, srem)
|
||||||
c2 = self.cur.get(dvn.realpath)
|
c2 = self.cur.get(dvn.realpath)
|
||||||
|
@ -1365,7 +1411,6 @@ class Up2k(object):
|
||||||
|
|
||||||
# not found in dst db; copy info
|
# not found in dst db; copy info
|
||||||
self.log("mv: plain move")
|
self.log("mv: plain move")
|
||||||
st = bos.stat(sabs)
|
|
||||||
|
|
||||||
if c1 and c2:
|
if c1 and c2:
|
||||||
self._copy_tags(c1, c2, w)
|
self._copy_tags(c1, c2, w)
|
||||||
|
@ -1378,6 +1423,7 @@ class Up2k(object):
|
||||||
self.db_add(c2, w, drd, dfn, st.st_mtime, st.st_size)
|
self.db_add(c2, w, drd, dfn, st.st_mtime, st.st_size)
|
||||||
c2.connection.commit()
|
c2.connection.commit()
|
||||||
|
|
||||||
|
bos.makedirs(os.path.dirname(dabs))
|
||||||
bos.rename(sabs, dabs)
|
bos.rename(sabs, dabs)
|
||||||
return "k"
|
return "k"
|
||||||
|
|
||||||
|
@ -1637,10 +1683,7 @@ class Up2k(object):
|
||||||
if etag == self.snap_prev.get(ptop):
|
if etag == self.snap_prev.get(ptop):
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
|
||||||
bos.makedirs(histpath)
|
bos.makedirs(histpath)
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
path2 = "{}.{}".format(path, os.getpid())
|
path2 = "{}.{}".format(path, os.getpid())
|
||||||
j = json.dumps(reg, indent=2, sort_keys=True).encode("utf-8")
|
j = json.dumps(reg, indent=2, sort_keys=True).encode("utf-8")
|
||||||
|
|
Loading…
Reference in a new issue