allow uploading empty files

This commit is contained in:
ed 2021-10-02 23:34:12 +02:00
parent 63eb08ba9f
commit a6935b0293
3 changed files with 96 additions and 66 deletions

View file

@ -1362,53 +1362,56 @@ class Up2k(object):
# del self.registry[ptop][wark]
return ret, dst
# windows cant rename open files
if not ANYWIN or src == dst:
self.finish_upload(ptop, wark)
# windows cant rename open files
if not ANYWIN or src == dst:
self._finish_upload(ptop, wark)
return ret, dst
def finish_upload(self, ptop, wark):
with self.mutex:
try:
job = self.registry[ptop][wark]
pdir = os.path.join(job["ptop"], job["prel"])
src = os.path.join(pdir, job["tnam"])
dst = os.path.join(pdir, job["name"])
except Exception as ex:
return "finish_upload, wark, " + repr(ex)
self._finish_upload(ptop, wark)
# self.log("--- " + wark + " " + dst + " finish_upload atomic " + dst, 4)
atomic_move(src, dst)
def _finish_upload(self, ptop, wark):
try:
job = self.registry[ptop][wark]
pdir = os.path.join(job["ptop"], job["prel"])
src = os.path.join(pdir, job["tnam"])
dst = os.path.join(pdir, job["name"])
except Exception as ex:
return "finish_upload, wark, " + repr(ex)
if ANYWIN:
a = [dst, job["size"], (int(time.time()), int(job["lmod"]))]
self.lastmod_q.put(a)
# self.log("--- " + wark + " " + dst + " finish_upload atomic " + dst, 4)
atomic_move(src, dst)
a = [job[x] for x in "ptop wark prel name lmod size addr".split()]
a += [job.get("at") or time.time()]
if self.idx_wark(*a):
# self.log("pop " + wark + " " + dst + " finish_upload idx_wark", 4)
del self.registry[ptop][wark]
# in-memory registry is reserved for unfinished uploads
if ANYWIN:
a = [dst, job["size"], (int(time.time()), int(job["lmod"]))]
self.lastmod_q.put(a)
dupes = self.dupesched.pop(dst, [])
if not dupes:
return
a = [job[x] for x in "ptop wark prel name lmod size addr".split()]
a += [job.get("at") or time.time()]
if self.idx_wark(*a):
# self.log("pop " + wark + " " + dst + " finish_upload idx_wark", 4)
del self.registry[ptop][wark]
# in-memory registry is reserved for unfinished uploads
cur = self.cur.get(ptop)
for rd, fn in dupes:
d2 = os.path.join(ptop, rd, fn)
if os.path.exists(d2):
continue
dupes = self.dupesched.pop(dst, [])
if not dupes:
return
self._symlink(dst, d2)
if cur:
self.db_rm(cur, rd, fn)
self.db_add(cur, wark, rd, fn, *a[-4:])
cur = self.cur.get(ptop)
for rd, fn in dupes:
d2 = os.path.join(ptop, rd, fn)
if os.path.exists(d2):
continue
self._symlink(dst, d2)
if cur:
cur.connection.commit()
self.db_rm(cur, rd, fn)
self.db_add(cur, wark, rd, fn, *a[-4:])
if cur:
cur.connection.commit()
def idx_wark(self, ptop, wark, rd, fn, lmod, sz, ip, at):
cur = self.cur.get(ptop)
@ -1768,7 +1771,13 @@ class Up2k(object):
except:
cj["lmod"] = int(time.time())
wark = up2k_wark_from_hashlist(self.salt, cj["size"], cj["hash"])
if cj["hash"]:
wark = up2k_wark_from_hashlist(self.salt, cj["size"], cj["hash"])
else:
wark = up2k_wark_from_metadata(
self.salt, cj["size"], cj["lmod"], cj["prel"], cj["name"]
)
return wark
def _hashlist_from_file(self, path):
@ -1811,6 +1820,8 @@ class Up2k(object):
if self.args.nw:
job["tnam"] = tnam
if not job["hash"]:
del self.registry[job["ptop"]][job["wark"]]
return
suffix = ".{:.6f}-{}".format(job["t0"], job["addr"])
@ -1827,8 +1838,12 @@ class Up2k(object):
except:
self.log("could not sparse [{}]".format(fp), 3)
f.seek(job["size"] - 1)
f.write(b"e")
if job["hash"]:
f.seek(job["size"] - 1)
f.write(b"e")
if not job["hash"]:
self._finish_upload(job["ptop"], job["wark"])
def _lastmodder(self):
while True:

View file

@ -744,11 +744,14 @@ function up2k_init(subtle) {
more_one_file();
var bad_files = [],
nil_files = [],
good_files = [],
dirs = [];
for (var a = 0; a < files.length; a++) {
var fobj = files[a];
var fobj = files[a],
dst = good_files;
if (is_itemlist) {
if (fobj.kind !== 'file')
continue;
@ -765,16 +768,15 @@ function up2k_init(subtle) {
}
try {
if (fobj.size < 1)
throw 1;
dst = nil_files;
}
catch (ex) {
bad_files.push(fobj.name);
continue;
dst = bad_files;
}
good_files.push([fobj, fobj.name]);
dst.push([fobj, fobj.name]);
}
if (dirs) {
return read_dirs(null, [], dirs, good_files, bad_files);
return read_dirs(null, [], dirs, good_files, nil_files, bad_files);
}
}
@ -788,7 +790,7 @@ function up2k_init(subtle) {
}
var rd_missing_ref = [];
function read_dirs(rd, pf, dirs, good, bad, spins) {
function read_dirs(rd, pf, dirs, good, nil, bad, spins) {
spins = spins || 0;
if (++spins == 5)
rd_missing_ref = rd_flatten(pf, dirs);
@ -809,7 +811,7 @@ function up2k_init(subtle) {
msg.push('<li>' + esc(missing[a]) + '</li>');
return modal.alert(msg.join('') + '</ul>', function () {
read_dirs(rd, [], [], good, bad, spins);
read_dirs(rd, [], [], good, nil, bad, spins);
});
}
spins = 0;
@ -817,11 +819,11 @@ function up2k_init(subtle) {
if (!dirs.length) {
if (!pf.length)
return gotallfiles(good, bad);
return gotallfiles(good, nil, bad);
console.log("retry pf, " + pf.length);
setTimeout(function () {
read_dirs(rd, pf, dirs, good, bad, spins);
read_dirs(rd, pf, dirs, good, nil, bad, spins);
}, 50);
return;
}
@ -843,14 +845,15 @@ function up2k_init(subtle) {
pf.push(name);
dn.file(function (fobj) {
apop(pf, name);
var dst = good;
try {
if (fobj.size > 0) {
good.push([fobj, name]);
return;
}
if (fobj.size < 1)
dst = nil;
}
catch (ex) { }
bad.push(name);
catch (ex) {
dst = bad;
}
dst.push([fobj, name]);
});
}
ngot += 1;
@ -859,23 +862,33 @@ function up2k_init(subtle) {
dirs.shift();
rd = null;
}
return read_dirs(rd, pf, dirs, good, bad, spins);
return read_dirs(rd, pf, dirs, good, nil, bad, spins);
});
}
function gotallfiles(good_files, bad_files) {
function gotallfiles(good_files, nil_files, bad_files) {
var ntot = good_files.concat(nil_files, bad_files).length;
if (bad_files.length) {
var ntot = bad_files.length + good_files.length,
msg = 'These {0} files (of {1} total) were skipped because they are empty:\n'.format(bad_files.length, ntot);
var msg = 'These {0} files (of {1} total) were skipped, possibly due to filesystem permissions:\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';
if (good_files.length - bad_files.length <= 1 && ANDROID)
msg += '\nFirefox-Android has a bug which prevents selecting multiple files. Try selecting one file at a time. For more info, see firefox bug 1456557';
msg += '-- ' + bad_files[a][1] + '\n';
msg += '\nMaybe it works better if you select just one file';
return modal.alert(msg, function () {
gotallfiles(good_files, []);
gotallfiles(good_files, nil_files, []);
});
}
if (nil_files.length) {
var msg = 'These {0} files (of {1} total) are blank/empty; upload them anyways?\n'.format(nil_files.length, ntot);
for (var a = 0, aa = Math.min(20, nil_files.length); a < aa; a++)
msg += '-- ' + nil_files[a][1] + '\n';
msg += '\nMaybe it works better if you select just one file';
return modal.confirm(msg, function () {
gotallfiles(good_files.concat(nil_files), [], []);
}, function () {
gotallfiles(good_files, [], []);
});
}
@ -921,7 +934,7 @@ function up2k_init(subtle) {
"t0": now,
"fobj": fobj,
"name": name,
"size": fobj.size,
"size": fobj.size || 0,
"lmod": lmod / 1000,
"purl": fdir,
"done": false,
@ -946,7 +959,9 @@ function up2k_init(subtle) {
st.bytes.total += fobj.size;
st.files.push(entry);
if (uc.turbo)
if (!entry.size)
push_t(st.todo.handshake, entry);
else if (uc.turbo)
push_t(st.todo.head, entry);
else
push_t(st.todo.hash, entry);

View file

@ -1049,7 +1049,7 @@ var modal = (function () {
}
function _confirm(html, cok, cng, fun) {
cb_ok = cok;
cb_ng = cng === undefined ? cok : null;
cb_ng = cng === undefined ? cok : cng;
cb_up = fun;
html += '<div id="modalb">' + ok_cancel + '</div>';
r.show(html);