mirror of
https://github.com/9001/copyparty.git
synced 2025-08-17 17:12:13 -06:00
up2k: add folder upload
This commit is contained in:
parent
871dde79a9
commit
c8f59fb978
|
@ -54,6 +54,7 @@ class VFS(object):
|
||||||
self.uwrite,
|
self.uwrite,
|
||||||
self.flags,
|
self.flags,
|
||||||
)
|
)
|
||||||
|
self._trk(vn)
|
||||||
self.nodes[name] = vn
|
self.nodes[name] = vn
|
||||||
return self._trk(vn.add(src, dst))
|
return self._trk(vn.add(src, dst))
|
||||||
|
|
||||||
|
|
|
@ -424,15 +424,18 @@ class HttpCli(object):
|
||||||
if "srch" in self.uparam or "srch" in body:
|
if "srch" in self.uparam or "srch" in body:
|
||||||
return self.handle_search(body)
|
return self.handle_search(body)
|
||||||
|
|
||||||
# prefer this over undot; no reason to allow traversion
|
|
||||||
if "/" in body["name"]:
|
|
||||||
raise Pebkac(400, "folders verboten")
|
|
||||||
|
|
||||||
# up2k-php compat
|
# up2k-php compat
|
||||||
for k in "chunkpit.php", "handshake.php":
|
for k in "chunkpit.php", "handshake.php":
|
||||||
if self.vpath.endswith(k):
|
if self.vpath.endswith(k):
|
||||||
self.vpath = self.vpath[: -len(k)]
|
self.vpath = self.vpath[: -len(k)]
|
||||||
|
|
||||||
|
sub = None
|
||||||
|
name = undot(body["name"])
|
||||||
|
if "/" in name:
|
||||||
|
sub, name = name.rsplit("/", 1)
|
||||||
|
self.vpath = "/".join([self.vpath, sub]).strip("/")
|
||||||
|
body["name"] = name
|
||||||
|
|
||||||
vfs, rem = self.conn.auth.vfs.get(self.vpath, self.uname, False, True)
|
vfs, rem = self.conn.auth.vfs.get(self.vpath, self.uname, False, True)
|
||||||
|
|
||||||
body["vtop"] = vfs.vpath
|
body["vtop"] = vfs.vpath
|
||||||
|
@ -441,12 +444,22 @@ class HttpCli(object):
|
||||||
body["addr"] = self.ip
|
body["addr"] = self.ip
|
||||||
body["vcfg"] = vfs.flags
|
body["vcfg"] = vfs.flags
|
||||||
|
|
||||||
x = self.conn.hsrv.broker.put(True, "up2k.handle_json", body)
|
if sub:
|
||||||
response = x.get()
|
try:
|
||||||
response = json.dumps(response)
|
dst = os.path.join(vfs.realpath, rem)
|
||||||
|
os.makedirs(dst)
|
||||||
|
except:
|
||||||
|
if not os.path.isdir(dst):
|
||||||
|
raise Pebkac(400, "some file got your folder name")
|
||||||
|
|
||||||
self.log(response)
|
x = self.conn.hsrv.broker.put(True, "up2k.handle_json", body)
|
||||||
self.reply(response.encode("utf-8"), mime="application/json")
|
ret = x.get()
|
||||||
|
if sub:
|
||||||
|
ret["name"] = "/".join([sub, ret["name"]])
|
||||||
|
|
||||||
|
ret = json.dumps(ret)
|
||||||
|
self.log(ret)
|
||||||
|
self.reply(ret.encode("utf-8"), mime="application/json")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def handle_search(self, body):
|
def handle_search(self, body):
|
||||||
|
|
|
@ -284,12 +284,21 @@ function up2k_init(have_crypto) {
|
||||||
more_one_file();
|
more_one_file();
|
||||||
var bad_files = [];
|
var bad_files = [];
|
||||||
var good_files = [];
|
var good_files = [];
|
||||||
|
var dirs = [];
|
||||||
for (var a = 0; a < files.length; a++) {
|
for (var a = 0; a < files.length; a++) {
|
||||||
var fobj = files[a];
|
var fobj = files[a];
|
||||||
if (is_itemlist) {
|
if (is_itemlist) {
|
||||||
if (fobj.kind !== 'file')
|
if (fobj.kind !== 'file')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
try {
|
||||||
|
var wi = fobj.webkitGetAsEntry();
|
||||||
|
if (wi.isDirectory) {
|
||||||
|
dirs.push(wi);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ex) { }
|
||||||
fobj = fobj.getAsFile();
|
fobj = fobj.getAsFile();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
@ -300,12 +309,69 @@ function up2k_init(have_crypto) {
|
||||||
bad_files.push(fobj.name);
|
bad_files.push(fobj.name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
good_files.push(fobj);
|
good_files.push([fobj, fobj.name]);
|
||||||
|
}
|
||||||
|
if (dirs) {
|
||||||
|
return read_dirs(null, [], dirs, good_files, bad_files);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function read_dirs(rd, pf, dirs, good, bad) {
|
||||||
|
if (!dirs.length) {
|
||||||
|
if (!pf.length)
|
||||||
|
return gotallfiles(good, bad);
|
||||||
|
|
||||||
|
console.log("retry pf, " + pf.length);
|
||||||
|
setTimeout(function () {
|
||||||
|
read_dirs(rd, pf, dirs, good, bad);
|
||||||
|
}, 50);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!rd)
|
||||||
|
rd = dirs[0].createReader();
|
||||||
|
|
||||||
|
rd.readEntries(function (ents) {
|
||||||
|
var ngot = 0;
|
||||||
|
ents.forEach(function (dn) {
|
||||||
|
if (dn.isDirectory) {
|
||||||
|
dirs.push(dn);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var name = dn.fullPath;
|
||||||
|
if (name.indexOf('/') === 0)
|
||||||
|
name = name.slice(1);
|
||||||
|
|
||||||
|
pf.push(name);
|
||||||
|
dn.file(function (fobj) {
|
||||||
|
var idx = pf.indexOf(name);
|
||||||
|
pf.splice(idx, 1);
|
||||||
|
try {
|
||||||
|
if (fobj.size > 0) {
|
||||||
|
good.push([fobj, name]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ex) { }
|
||||||
|
bad.push(name);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
ngot += 1;
|
||||||
|
});
|
||||||
|
// console.log("ngot: " + ngot);
|
||||||
|
if (!ngot) {
|
||||||
|
dirs.shift();
|
||||||
|
rd = null;
|
||||||
|
}
|
||||||
|
return read_dirs(rd, pf, dirs, good, bad);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function gotallfiles(good_files, bad_files) {
|
||||||
if (bad_files.length > 0) {
|
if (bad_files.length > 0) {
|
||||||
var msg = 'These {0} files (of {1} total) were skipped because they are empty:\n'.format(bad_files.length, files.length);
|
var ntot = bad_files.length + good_files.length;
|
||||||
for (var a = 0; a < bad_files.length; a++)
|
var msg = 'These {0} files (of {1} total) were skipped because they are empty:\n'.format(bad_files.length, ntot);
|
||||||
|
for (var a = 0, aa = Math.min(20, bad_files.length); a < aa; a++)
|
||||||
msg += '-- ' + bad_files[a] + '\n';
|
msg += '-- ' + bad_files[a] + '\n';
|
||||||
|
|
||||||
if (files.length - bad_files.length <= 1 && /(android)/i.test(navigator.userAgent))
|
if (files.length - bad_files.length <= 1 && /(android)/i.test(navigator.userAgent))
|
||||||
|
@ -315,21 +381,21 @@ function up2k_init(have_crypto) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var msg = ['upload these ' + good_files.length + ' files?'];
|
var msg = ['upload these ' + good_files.length + ' files?'];
|
||||||
for (var a = 0; a < good_files.length; a++)
|
for (var a = 0, aa = Math.min(20, good_files.length); a < aa; a++)
|
||||||
msg.push(good_files[a].name);
|
msg.push(good_files[a][1]);
|
||||||
|
|
||||||
if (ask_up && !fsearch && !confirm(msg.join('\n')))
|
if (ask_up && !fsearch && !confirm(msg.join('\n')))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (var a = 0; a < good_files.length; a++) {
|
for (var a = 0; a < good_files.length; a++) {
|
||||||
var fobj = good_files[a];
|
var fobj = good_files[a][0];
|
||||||
var now = new Date().getTime();
|
var now = new Date().getTime();
|
||||||
var lmod = fobj.lastModified || now;
|
var lmod = fobj.lastModified || now;
|
||||||
var entry = {
|
var entry = {
|
||||||
"n": parseInt(st.files.length.toString()),
|
"n": parseInt(st.files.length.toString()),
|
||||||
"t0": now, // TODO remove probably
|
"t0": now,
|
||||||
"fobj": fobj,
|
"fobj": fobj,
|
||||||
"name": fobj.name,
|
"name": good_files[a][1],
|
||||||
"size": fobj.size,
|
"size": fobj.size,
|
||||||
"lmod": lmod / 1000,
|
"lmod": lmod / 1000,
|
||||||
"purl": get_evpath(),
|
"purl": get_evpath(),
|
||||||
|
|
|
@ -88,7 +88,7 @@
|
||||||
width: 30em;
|
width: 30em;
|
||||||
}
|
}
|
||||||
#u2conf.has_btn {
|
#u2conf.has_btn {
|
||||||
width: 46em;
|
width: 48em;
|
||||||
}
|
}
|
||||||
#u2conf * {
|
#u2conf * {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
|
@ -73,7 +73,8 @@
|
||||||
<div id="u2btn_ct">
|
<div id="u2btn_ct">
|
||||||
<div id="u2btn">
|
<div id="u2btn">
|
||||||
<span id="u2bm"></span><br />
|
<span id="u2bm"></span><br />
|
||||||
drop files here<br />
|
drag/drop files<br />
|
||||||
|
and folders here<br />
|
||||||
(or click me)
|
(or click me)
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue