mirror of
https://github.com/9001/copyparty.git
synced 2025-08-20 02:12:20 -06:00
mv works (at least in trivial cases)
This commit is contained in:
parent
179d7a9ad8
commit
e648252479
|
@ -1560,8 +1560,8 @@ class HttpCli(object):
|
||||||
raise Pebkac(403, "disabled by argv")
|
raise Pebkac(403, "disabled by argv")
|
||||||
|
|
||||||
# full path of new loc (incl filename)
|
# full path of new loc (incl filename)
|
||||||
dst = self.uparam.get("to")
|
dst = self.uparam.get("move")
|
||||||
if dst is None:
|
if not dst:
|
||||||
raise Pebkac(400, "need dst vpath")
|
raise Pebkac(400, "need dst vpath")
|
||||||
|
|
||||||
x = self.conn.hsrv.broker.put(
|
x = self.conn.hsrv.broker.put(
|
||||||
|
|
|
@ -1302,9 +1302,12 @@ class Up2k(object):
|
||||||
# dbv, vrem = dbv.get_dbv(vrem)
|
# dbv, vrem = dbv.get_dbv(vrem)
|
||||||
_ = dbv.get(vrem, uname, *permsets[0])
|
_ = dbv.get(vrem, uname, *permsets[0])
|
||||||
with self.mutex:
|
with self.mutex:
|
||||||
ptop = dbv.realpath
|
try:
|
||||||
cur, wark = self._find_from_vpath(ptop, vrem)
|
ptop = dbv.realpath
|
||||||
self._forget_file(ptop, vpath, cur, wark)
|
cur, wark = self._find_from_vpath(ptop, vrem)
|
||||||
|
self._forget_file(ptop, vpath, cur, wark)
|
||||||
|
finally:
|
||||||
|
cur.connection.commit()
|
||||||
|
|
||||||
bos.unlink(abspath)
|
bos.unlink(abspath)
|
||||||
|
|
||||||
|
@ -1318,7 +1321,7 @@ class Up2k(object):
|
||||||
|
|
||||||
return "deleted {} files (and {}/{} folders)".format(n_files, n_dirs, len(dirs))
|
return "deleted {} files (and {}/{} folders)".format(n_files, n_dirs, len(dirs))
|
||||||
|
|
||||||
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)
|
dvn, drem = self.asrv.vfs.get(dvp, uname, False, True)
|
||||||
sabs = svn.canonical(srem)
|
sabs = svn.canonical(srem)
|
||||||
|
@ -1335,15 +1338,16 @@ class Up2k(object):
|
||||||
c2 = self.cur.get(dvn.realpath)
|
c2 = self.cur.get(dvn.realpath)
|
||||||
if c1 and c2:
|
if c1 and c2:
|
||||||
q = "select rd, fn from up where substr(w,1,16)=? and w=?"
|
q = "select rd, fn from up where substr(w,1,16)=? and w=?"
|
||||||
hit = c2.execute(q, (w[:16], w)).fetchone()
|
for rd, fn in c2.execute(q, (w[:16], w)):
|
||||||
if hit:
|
|
||||||
# found in dest vol, just need a symlink
|
|
||||||
rd, fn = hit
|
|
||||||
if rd.startswith("//") or fn.startswith("//"):
|
if rd.startswith("//") or fn.startswith("//"):
|
||||||
rd, fn = s3dec(rd, fn)
|
rd, fn = s3dec(rd, fn)
|
||||||
|
|
||||||
slabs = "{}/{}".join(rd, fn).strip("/")
|
slabs = "{}/{}".format(rd, fn).strip("/")
|
||||||
slabs = absreal(os.path.join(dvn.realpath, slabs))
|
slabs = absreal(os.path.join(dvn.realpath, slabs))
|
||||||
|
if slabs == sabs:
|
||||||
|
# hit is src
|
||||||
|
continue
|
||||||
|
|
||||||
if bos.path.exists(slabs):
|
if bos.path.exists(slabs):
|
||||||
self.log("mv: quick relink, nice")
|
self.log("mv: quick relink, nice")
|
||||||
self._symlink(slabs, dabs)
|
self._symlink(slabs, dabs)
|
||||||
|
@ -1355,6 +1359,8 @@ class Up2k(object):
|
||||||
bos.rename(sabs, slabs)
|
bos.rename(sabs, slabs)
|
||||||
|
|
||||||
self._forget_file(svn.realpath, srem, c1, w)
|
self._forget_file(svn.realpath, srem, c1, w)
|
||||||
|
c1.connection.commit()
|
||||||
|
c2.connection.commit()
|
||||||
return "k"
|
return "k"
|
||||||
|
|
||||||
# not found in dst db; copy info
|
# not found in dst db; copy info
|
||||||
|
@ -1366,9 +1372,11 @@ class Up2k(object):
|
||||||
|
|
||||||
if c1:
|
if c1:
|
||||||
self._forget_file(svn.realpath, srem, c1, w)
|
self._forget_file(svn.realpath, srem, c1, w)
|
||||||
|
c1.connection.commit()
|
||||||
|
|
||||||
if c2:
|
if c2:
|
||||||
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()
|
||||||
|
|
||||||
bos.rename(sabs, dabs)
|
bos.rename(sabs, dabs)
|
||||||
return "k"
|
return "k"
|
||||||
|
@ -1402,14 +1410,12 @@ class Up2k(object):
|
||||||
|
|
||||||
def _forget_file(self, ptop, vrem, cur, wark):
|
def _forget_file(self, ptop, vrem, cur, wark):
|
||||||
"""forgets file in db, fixes symlinks, does not delete"""
|
"""forgets file in db, fixes symlinks, does not delete"""
|
||||||
fn = vrem.split("/")[-1]
|
srd, sfn = vsplit(vrem)
|
||||||
wark = None
|
|
||||||
dupes = []
|
dupes = []
|
||||||
|
|
||||||
self.log("forgetting {}".format(vrem))
|
self.log("forgetting {}".format(vrem))
|
||||||
if wark:
|
if wark:
|
||||||
# found in db; find dupes
|
# found in db; find dupes
|
||||||
wark = wark[0]
|
|
||||||
self.log("found {} in db".format(wark))
|
self.log("found {} in db".format(wark))
|
||||||
|
|
||||||
q = "select rd, fn from up where substr(w,1,16)=? and w=?"
|
q = "select rd, fn from up where substr(w,1,16)=? and w=?"
|
||||||
|
@ -1425,10 +1431,11 @@ class Up2k(object):
|
||||||
if dupes:
|
if dupes:
|
||||||
# fix symlinks
|
# fix symlinks
|
||||||
self._relink(ptop, dupes, vrem, None)
|
self._relink(ptop, dupes, vrem, None)
|
||||||
else:
|
elif wark:
|
||||||
# drop tags
|
# thus cur; drop tags
|
||||||
q = "delete from mt where w=?"
|
q = "delete from mt where w=?"
|
||||||
cur.execute(q, (wark[:16],))
|
cur.execute(q, (wark[:16],))
|
||||||
|
self.db_rm(cur, srd, sfn)
|
||||||
|
|
||||||
reg = self.registry.get(ptop)
|
reg = self.registry.get(ptop)
|
||||||
if reg:
|
if reg:
|
||||||
|
|
|
@ -1546,7 +1546,7 @@ var fileman = (function () {
|
||||||
r.paste = function (e) {
|
r.paste = function (e) {
|
||||||
ev(e);
|
ev(e);
|
||||||
if (!r.clip.length)
|
if (!r.clip.length)
|
||||||
return alert('first cut some items to paste\n\nnote: you can cut/paste across different tabs');
|
return alert('first cut some items to paste\n\nnote: you can cut/paste across different browser tabs');
|
||||||
|
|
||||||
var req = [],
|
var req = [],
|
||||||
exists = [],
|
exists = [],
|
||||||
|
@ -1574,6 +1574,36 @@ var fileman = (function () {
|
||||||
if (!confirm('paste these ' + req.length + ' items here?\n\n' + req.join('\n')))
|
if (!confirm('paste these ' + req.length + ' items here?\n\n' + req.join('\n')))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
function paster() {
|
||||||
|
var xhr = new XMLHttpRequest(),
|
||||||
|
vp = req.shift();
|
||||||
|
|
||||||
|
if (!vp) {
|
||||||
|
toast.show('paste OK', 2000);
|
||||||
|
treectl.goto(get_evpath());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
toast.show('pasting ' + (req.length + 1) + ' items<br /><br />' + vp, 2000);
|
||||||
|
|
||||||
|
var dst = get_evpath() + vp.split('/').slice(-1)[0];
|
||||||
|
|
||||||
|
xhr.open('GET', vp + '?move=' + dst, true);
|
||||||
|
xhr.onreadystatechange = paste_cb;
|
||||||
|
xhr.send();
|
||||||
|
}
|
||||||
|
function paste_cb() {
|
||||||
|
if (this.readyState != XMLHttpRequest.DONE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (this.status !== 200) {
|
||||||
|
var msg = this.responseText;
|
||||||
|
toast.show('paste failed:<br />' + msg, 2000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
paster();
|
||||||
|
}
|
||||||
|
paster();
|
||||||
|
|
||||||
jwrite('fman_clip', []);
|
jwrite('fman_clip', []);
|
||||||
r.tx();
|
r.tx();
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue