mirror of
https://github.com/9001/copyparty.git
synced 2025-08-17 09:02:15 -06:00
allow setting lifetimes from up2k ui
This commit is contained in:
parent
1882afb8b6
commit
0b87a4a810
13
README.md
13
README.md
|
@ -49,6 +49,7 @@ try the **[read-only demo server](https://a.ocv.me/pub/demo/)** 👀 running fro
|
||||||
* [uploading](#uploading) - drag files/folders into the web-browser to upload
|
* [uploading](#uploading) - drag files/folders into the web-browser to upload
|
||||||
* [file-search](#file-search) - dropping files into the browser also lets you see if they exist on the server
|
* [file-search](#file-search) - dropping files into the browser also lets you see if they exist on the server
|
||||||
* [unpost](#unpost) - undo/delete accidental uploads
|
* [unpost](#unpost) - undo/delete accidental uploads
|
||||||
|
* [self-destruct](#self-destruct) - uploads can be given a lifetime
|
||||||
* [file manager](#file-manager) - cut/paste, rename, and delete files/folders (if you have permission)
|
* [file manager](#file-manager) - cut/paste, rename, and delete files/folders (if you have permission)
|
||||||
* [batch rename](#batch-rename) - select some files and press `F2` to bring up the rename UI
|
* [batch rename](#batch-rename) - select some files and press `F2` to bring up the rename UI
|
||||||
* [markdown viewer](#markdown-viewer) - and there are *two* editors
|
* [markdown viewer](#markdown-viewer) - and there are *two* editors
|
||||||
|
@ -168,6 +169,7 @@ feature summary
|
||||||
* ☑ [up2k](#uploading): js, resumable, multithreaded
|
* ☑ [up2k](#uploading): js, resumable, multithreaded
|
||||||
* ☑ stash: simple PUT filedropper
|
* ☑ stash: simple PUT filedropper
|
||||||
* ☑ [unpost](#unpost): undo/delete accidental uploads
|
* ☑ [unpost](#unpost): undo/delete accidental uploads
|
||||||
|
* ☑ [self-destruct](#self-destruct) (specified server-side or client-side)
|
||||||
* ☑ symlink/discard existing files (content-matching)
|
* ☑ symlink/discard existing files (content-matching)
|
||||||
* download
|
* download
|
||||||
* ☑ single files in browser
|
* ☑ single files in browser
|
||||||
|
@ -543,6 +545,17 @@ undo/delete accidental uploads
|
||||||
you can unpost even if you don't have regular move/delete access, however only for files uploaded within the past `--unpost` seconds (default 12 hours) and the server must be running with `-e2d`
|
you can unpost even if you don't have regular move/delete access, however only for files uploaded within the past `--unpost` seconds (default 12 hours) and the server must be running with `-e2d`
|
||||||
|
|
||||||
|
|
||||||
|
### self-destruct
|
||||||
|
|
||||||
|
uploads can be given a lifetime, afer which they expire / self-destruct
|
||||||
|
|
||||||
|
the feature must be enabled per-volume with the `lifetime` [upload rule](#upload-rules) which sets the upper limit for how long a file gets to stay on the server
|
||||||
|
|
||||||
|
clients can specify a shorter expiration time using the [up2k ui](#uploading) -- the relevant options become visible upon navigating into a folder with `lifetimes` enabled -- or by using the `life` [upload modifier](#write)
|
||||||
|
|
||||||
|
specifying a custom expiration time client-side will affect the timespan in which unposts are permitted, so keep an eye on the estimates in the up2k ui
|
||||||
|
|
||||||
|
|
||||||
## file manager
|
## file manager
|
||||||
|
|
||||||
cut/paste, rename, and delete files/folders (if you have permission)
|
cut/paste, rename, and delete files/folders (if you have permission)
|
||||||
|
|
|
@ -1121,6 +1121,16 @@ class AuthSrv(object):
|
||||||
|
|
||||||
vol.flags = {k: v for k, v in vol.flags.items() if not k.startswith(rm)}
|
vol.flags = {k: v for k, v in vol.flags.items() if not k.startswith(rm)}
|
||||||
|
|
||||||
|
ints = ["lifetime"]
|
||||||
|
for k in list(vol.flags):
|
||||||
|
if k in ints:
|
||||||
|
vol.flags[k] = int(vol.flags[k])
|
||||||
|
|
||||||
|
if "lifetime" in vol.flags and "e2d" not in vol.flags:
|
||||||
|
t = 'removing lifetime config from volume "/{}" because e2d is disabled'
|
||||||
|
self.log(t.format(vol.vpath), 1)
|
||||||
|
del vol.flags["lifetime"]
|
||||||
|
|
||||||
# verify tags mentioned by -mt[mp] are used by -mte
|
# verify tags mentioned by -mt[mp] are used by -mte
|
||||||
local_mtp = {}
|
local_mtp = {}
|
||||||
local_only_mtp = {}
|
local_only_mtp = {}
|
||||||
|
|
|
@ -1313,7 +1313,7 @@ class HttpCli(object):
|
||||||
want_url = ac == "url"
|
want_url = ac == "url"
|
||||||
zs = self.uparam.get("life", self.headers.get("life", ""))
|
zs = self.uparam.get("life", self.headers.get("life", ""))
|
||||||
if zs:
|
if zs:
|
||||||
vlife = int(vfs.flags.get("lifetime") or 0)
|
vlife = vfs.flags.get("lifetime") or 0
|
||||||
lifetime = max(0, int(vlife - int(zs)))
|
lifetime = max(0, int(vlife - int(zs)))
|
||||||
else:
|
else:
|
||||||
lifetime = 0
|
lifetime = 0
|
||||||
|
@ -2495,6 +2495,7 @@ class HttpCli(object):
|
||||||
"srvinf": srv_infot,
|
"srvinf": srv_infot,
|
||||||
"acct": self.uname,
|
"acct": self.uname,
|
||||||
"idx": ("e2d" in vn.flags),
|
"idx": ("e2d" in vn.flags),
|
||||||
|
"lifetime": vn.flags.get("lifetime") or 0,
|
||||||
"perms": perms,
|
"perms": perms,
|
||||||
"logues": logues,
|
"logues": logues,
|
||||||
"readme": readme,
|
"readme": readme,
|
||||||
|
@ -2506,6 +2507,7 @@ class HttpCli(object):
|
||||||
"ls0": None,
|
"ls0": None,
|
||||||
"acct": self.uname,
|
"acct": self.uname,
|
||||||
"perms": json.dumps(perms),
|
"perms": json.dumps(perms),
|
||||||
|
"lifetime": ls_ret["lifetime"],
|
||||||
"taglist": [],
|
"taglist": [],
|
||||||
"def_hcols": [],
|
"def_hcols": [],
|
||||||
"have_emp": self.args.emp,
|
"have_emp": self.args.emp,
|
||||||
|
@ -2515,7 +2517,7 @@ class HttpCli(object):
|
||||||
"have_mv": (not self.args.no_mv),
|
"have_mv": (not self.args.no_mv),
|
||||||
"have_del": (not self.args.no_del),
|
"have_del": (not self.args.no_del),
|
||||||
"have_zip": (not self.args.no_zip),
|
"have_zip": (not self.args.no_zip),
|
||||||
"have_unpost": (self.args.unpost > 0),
|
"have_unpost": int(self.args.unpost),
|
||||||
"have_b_u": (self.can_write and self.uparam.get("b") == "u"),
|
"have_b_u": (self.can_write and self.uparam.get("b") == "u"),
|
||||||
"url_suf": url_suf,
|
"url_suf": url_suf,
|
||||||
"logues": logues,
|
"logues": logues,
|
||||||
|
|
|
@ -351,11 +351,9 @@ class Up2k(object):
|
||||||
if not cur:
|
if not cur:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
lifetime = int(lifetime)
|
|
||||||
timeout = min(timeout, now + lifetime)
|
|
||||||
|
|
||||||
nrm = 0
|
nrm = 0
|
||||||
deadline = time.time() - lifetime
|
deadline = time.time() - lifetime
|
||||||
|
timeout = min(timeout, now + lifetime)
|
||||||
q = "select rd, fn from up where at > 0 and at < ? limit 100"
|
q = "select rd, fn from up where at > 0 and at < ? limit 100"
|
||||||
while True:
|
while True:
|
||||||
with self.mutex:
|
with self.mutex:
|
||||||
|
@ -1960,6 +1958,7 @@ class Up2k(object):
|
||||||
"sprs": sprs, # dontcare; finished anyways
|
"sprs": sprs, # dontcare; finished anyways
|
||||||
"size": dsize,
|
"size": dsize,
|
||||||
"lmod": dtime,
|
"lmod": dtime,
|
||||||
|
"life": cj.get("life"),
|
||||||
"addr": ip,
|
"addr": ip,
|
||||||
"at": at,
|
"at": at,
|
||||||
"hash": [],
|
"hash": [],
|
||||||
|
@ -2072,6 +2071,7 @@ class Up2k(object):
|
||||||
"name",
|
"name",
|
||||||
"size",
|
"size",
|
||||||
"lmod",
|
"lmod",
|
||||||
|
"life",
|
||||||
"poke",
|
"poke",
|
||||||
]:
|
]:
|
||||||
job[k] = cj[k]
|
job[k] = cj[k]
|
||||||
|
@ -2293,12 +2293,30 @@ class Up2k(object):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
z2 = [job[x] for x in "ptop wark prel name lmod size addr".split()]
|
z2 = [job[x] for x in "ptop wark prel name lmod size addr".split()]
|
||||||
z2 += [job.get("at") or time.time()]
|
upt = job.get("at") or time.time()
|
||||||
|
wake_sr = False
|
||||||
|
try:
|
||||||
|
flt = job["life"]
|
||||||
|
vfs = self.asrv.vfs.all_vols[job["vtop"]]
|
||||||
|
vlt = vfs.flags["lifetime"]
|
||||||
|
if vlt and flt < vlt:
|
||||||
|
upt -= vlt - flt
|
||||||
|
wake_sr = True
|
||||||
|
t = "using client lifetime; at={:.0f} ({}-{})"
|
||||||
|
self.log(t.format(upt, vlt, flt))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
z2 += [upt]
|
||||||
if self.idx_wark(*z2):
|
if self.idx_wark(*z2):
|
||||||
del self.registry[ptop][wark]
|
del self.registry[ptop][wark]
|
||||||
else:
|
else:
|
||||||
self.regdrop(ptop, wark)
|
self.regdrop(ptop, wark)
|
||||||
|
|
||||||
|
if wake_sr:
|
||||||
|
with self.rescan_cond:
|
||||||
|
self.rescan_cond.notify_all()
|
||||||
|
|
||||||
dupes = self.dupesched.pop(dst, [])
|
dupes = self.dupesched.pop(dst, [])
|
||||||
if not dupes:
|
if not dupes:
|
||||||
return
|
return
|
||||||
|
|
|
@ -2498,13 +2498,34 @@ html.b #u2conf a.b:hover {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border: .2em dashed rgba(128, 128, 128, 0.3);
|
border: .2em dashed rgba(128, 128, 128, 0.3);
|
||||||
}
|
}
|
||||||
#u2foot {
|
#u2foot,
|
||||||
|
#u2life {
|
||||||
color: var(--fg-max);
|
color: var(--fg-max);
|
||||||
font-style: italic;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 1.2em;
|
|
||||||
margin: .8em 0;
|
margin: .8em 0;
|
||||||
}
|
}
|
||||||
|
#u2life {
|
||||||
|
margin: 2.5em 0;
|
||||||
|
line-height: 1.5em;
|
||||||
|
}
|
||||||
|
#u2life div {
|
||||||
|
display: inline-block;
|
||||||
|
white-space: nowrap;
|
||||||
|
margin: 0 2em;
|
||||||
|
}
|
||||||
|
#u2life div:first-child {
|
||||||
|
margin-bottom: .2em;
|
||||||
|
}
|
||||||
|
#u2life small {
|
||||||
|
opacity: .6;
|
||||||
|
}
|
||||||
|
#lifew {
|
||||||
|
border-bottom: 1px dotted var(--fg-max);
|
||||||
|
}
|
||||||
|
#u2foot {
|
||||||
|
font-size: 1.2em;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
#u2foot .warn {
|
#u2foot .warn {
|
||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
padding: .5em .8em;
|
padding: .5em .8em;
|
||||||
|
@ -2523,6 +2544,10 @@ html.b #u2conf a.b:hover {
|
||||||
#u2foot>*+* {
|
#u2foot>*+* {
|
||||||
margin-top: 1.5em;
|
margin-top: 1.5em;
|
||||||
}
|
}
|
||||||
|
#u2life input {
|
||||||
|
width: 4em;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
.prog {
|
.prog {
|
||||||
font-family: 'scp', monospace, monospace;
|
font-family: 'scp', monospace, monospace;
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,8 +146,9 @@
|
||||||
have_acode = {{ have_acode|tojson }},
|
have_acode = {{ have_acode|tojson }},
|
||||||
have_mv = {{ have_mv|tojson }},
|
have_mv = {{ have_mv|tojson }},
|
||||||
have_del = {{ have_del|tojson }},
|
have_del = {{ have_del|tojson }},
|
||||||
have_unpost = {{ have_unpost|tojson }},
|
have_unpost = {{ have_unpost }},
|
||||||
have_zip = {{ have_zip|tojson }},
|
have_zip = {{ have_zip|tojson }},
|
||||||
|
lifetime = {{ lifetime }},
|
||||||
turbolvl = {{ turbolvl }},
|
turbolvl = {{ turbolvl }},
|
||||||
u2sort = "{{ u2sort }}",
|
u2sort = "{{ u2sort }}",
|
||||||
have_emp = {{ have_emp|tojson }},
|
have_emp = {{ have_emp|tojson }},
|
||||||
|
|
|
@ -25,6 +25,12 @@ var Ls = {
|
||||||
"hz": "sample rate"
|
"hz": "sample rate"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"ht_s": "second!s",
|
||||||
|
"ht_m": "minute!s",
|
||||||
|
"ht_h": "hour!s",
|
||||||
|
"ht_d": "day!s",
|
||||||
|
"ht_and": " and ",
|
||||||
|
|
||||||
"goh": "control-panel",
|
"goh": "control-panel",
|
||||||
"logout": "Logout ",
|
"logout": "Logout ",
|
||||||
"access": " access",
|
"access": " access",
|
||||||
|
@ -311,7 +317,8 @@ var Ls = {
|
||||||
"u_badf": 'These {0} files (of {1} total) were skipped, possibly due to filesystem permissions:\n\n',
|
"u_badf": 'These {0} files (of {1} total) were skipped, possibly due to filesystem permissions:\n\n',
|
||||||
"u_blankf": 'These {0} files (of {1} total) are blank / empty; upload them anyways?\n\n',
|
"u_blankf": 'These {0} files (of {1} total) are blank / empty; upload them anyways?\n\n',
|
||||||
"u_just1": '\nMaybe it works better if you select just one file',
|
"u_just1": '\nMaybe it works better if you select just one file',
|
||||||
"u_ff_many": "This amount of files <em>may</em> cause Firefox to skip some files, or crash.\nPlease try again with fewer files (or use Chrome) if that happens.\n\n",
|
"u_ff_many": "This amount of files <em>may</em> cause Firefox to skip some files, or crash.\nPlease try again with fewer files (or use Chrome) if that happens.",
|
||||||
|
"u_up_life": "This upload will be deleted from the server\n{0} after it completes",
|
||||||
"u_asku": 'upload these {0} files to <code>{1}</code>',
|
"u_asku": 'upload these {0} files to <code>{1}</code>',
|
||||||
"u_unpt": "you can undo / delete this upload using the top-left 🧯",
|
"u_unpt": "you can undo / delete this upload using the top-left 🧯",
|
||||||
"u_etadone": 'Done ({0}, {1} files)',
|
"u_etadone": 'Done ({0}, {1} files)',
|
||||||
|
@ -338,6 +345,11 @@ var Ls = {
|
||||||
"u_expl": "explain",
|
"u_expl": "explain",
|
||||||
"u_tu": '<p class="warn">WARNING: turbo enabled, <span> client may not detect and resume incomplete uploads; see turbo-button tooltip</span></p>',
|
"u_tu": '<p class="warn">WARNING: turbo enabled, <span> client may not detect and resume incomplete uploads; see turbo-button tooltip</span></p>',
|
||||||
"u_ts": '<p class="warn">WARNING: turbo enabled, <span> search results can be incorrect; see turbo-button tooltip</span></p>',
|
"u_ts": '<p class="warn">WARNING: turbo enabled, <span> search results can be incorrect; see turbo-button tooltip</span></p>',
|
||||||
|
"u_life_cfg": 'autodelete after <input id="lifem" p="60" /> min (or <input id="lifeh" p="3600" /> hours)',
|
||||||
|
"u_life_est": 'upload will be deleted <span id="lifew" tt="local time">---</span>',
|
||||||
|
"u_life_max": 'this folder enforces a\nmax lifetime of {0}',
|
||||||
|
"u_unp_ok": 'unpost is allowed for {0}',
|
||||||
|
"u_unp_ng": 'unpost will NOT be allowed',
|
||||||
"ue_ro": 'your access to this folder is Read-Only\n\n',
|
"ue_ro": 'your access to this folder is Read-Only\n\n',
|
||||||
"ue_nl": 'you are currently not logged in',
|
"ue_nl": 'you are currently not logged in',
|
||||||
"ue_la": 'you are currently logged in as "{0}"',
|
"ue_la": 'you are currently logged in as "{0}"',
|
||||||
|
@ -379,6 +391,12 @@ var Ls = {
|
||||||
"hz": "lyd-oppløsning"
|
"hz": "lyd-oppløsning"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"ht_s": "sekund!er",
|
||||||
|
"ht_m": "minutt!er",
|
||||||
|
"ht_h": "time!r",
|
||||||
|
"ht_d": "dag!er",
|
||||||
|
"ht_and": " og ",
|
||||||
|
|
||||||
"goh": "kontrollpanel",
|
"goh": "kontrollpanel",
|
||||||
"logout": "Logg ut ",
|
"logout": "Logg ut ",
|
||||||
"access": " tilgang",
|
"access": " tilgang",
|
||||||
|
@ -665,7 +683,8 @@ var Ls = {
|
||||||
"u_badf": 'Disse {0} filene (av totalt {1}) kan ikke leses, kanskje pga rettighetsproblemer i filsystemet på datamaskinen din:\n\n',
|
"u_badf": 'Disse {0} filene (av totalt {1}) kan ikke leses, kanskje pga rettighetsproblemer i filsystemet på datamaskinen din:\n\n',
|
||||||
"u_blankf": 'Disse {0} filene (av totalt {1}) er blanke / uten innhold; ønsker du å laste dem opp uansett?\n\n',
|
"u_blankf": 'Disse {0} filene (av totalt {1}) er blanke / uten innhold; ønsker du å laste dem opp uansett?\n\n',
|
||||||
"u_just1": '\nFunker kanskje bedre hvis du bare tar én fil om gangen',
|
"u_just1": '\nFunker kanskje bedre hvis du bare tar én fil om gangen',
|
||||||
"u_ff_many": "Det var mange filer! Mulig at Firefox kommer til å krasje, eller\nhoppe over et par av dem. Smart å ha Chrome på lur i tilfelle.\n\n",
|
"u_ff_many": "Det var mange filer! Mulig at Firefox kommer til å krasje, eller\nhoppe over et par av dem. Smart å ha Chrome på lur i tilfelle.",
|
||||||
|
"u_up_life": "Filene slettes fra serveren {0}\netter at opplastningen er fullført",
|
||||||
"u_asku": 'Laste opp disse {0} filene til <code>{1}</code>',
|
"u_asku": 'Laste opp disse {0} filene til <code>{1}</code>',
|
||||||
"u_unpt": "Du kan angre / slette opplastningen med 🧯 oppe til venstre",
|
"u_unpt": "Du kan angre / slette opplastningen med 🧯 oppe til venstre",
|
||||||
"u_etadone": 'Ferdig ({0}, {1} filer)',
|
"u_etadone": 'Ferdig ({0}, {1} filer)',
|
||||||
|
@ -692,6 +711,11 @@ var Ls = {
|
||||||
"u_expl": "forklar",
|
"u_expl": "forklar",
|
||||||
"u_tu": '<p class="warn">ADVARSEL: turbo er på, <span> avbrutte opplastninger vil muligens ikke oppdages og gjenopptas; hold musepekeren over turbo-knappen for mer info</span></p>',
|
"u_tu": '<p class="warn">ADVARSEL: turbo er på, <span> avbrutte opplastninger vil muligens ikke oppdages og gjenopptas; hold musepekeren over turbo-knappen for mer info</span></p>',
|
||||||
"u_ts": '<p class="warn">ADVARSEL: turbo er på, <span> søkeresultater kan være feil; hold musepekeren over turbo-knappen for mer info</span></p>',
|
"u_ts": '<p class="warn">ADVARSEL: turbo er på, <span> søkeresultater kan være feil; hold musepekeren over turbo-knappen for mer info</span></p>',
|
||||||
|
"u_life_cfg": 'slett opplastning etter <input id="lifem" p="60" /> min (eller <input id="lifeh" p="3600" /> timer)',
|
||||||
|
"u_life_est": 'opplastningen slettes <span id="lifew" tt="lokal tid">---</span>',
|
||||||
|
"u_life_max": 'denne mappen tillater ikke å \noppbevare filer i mer enn {0}',
|
||||||
|
"u_unp_ok": 'opplastning kan angres i {0}',
|
||||||
|
"u_unp_ng": 'opplastning kan IKKE angres',
|
||||||
"ue_ro": 'du har ikke skrivetilgang i denne mappen\n\n',
|
"ue_ro": 'du har ikke skrivetilgang i denne mappen\n\n',
|
||||||
"ue_nl": 'du er ikke logget inn',
|
"ue_nl": 'du er ikke logget inn',
|
||||||
"ue_la": 'du er logget inn som "{0}"',
|
"ue_la": 'du er logget inn som "{0}"',
|
||||||
|
@ -837,6 +861,7 @@ ebi('op_up2k').innerHTML = (
|
||||||
'</table><div id="u2mu"></div></div>\n' +
|
'</table><div id="u2mu"></div></div>\n' +
|
||||||
|
|
||||||
'<p id="u2flagblock"><b>' + L.ul_flagblk + '</p>\n' +
|
'<p id="u2flagblock"><b>' + L.ul_flagblk + '</p>\n' +
|
||||||
|
'<div id="u2life"></div>' +
|
||||||
'<div id="u2foot"></div>'
|
'<div id="u2foot"></div>'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -4646,6 +4671,7 @@ var treectl = (function () {
|
||||||
|
|
||||||
r.hide();
|
r.hide();
|
||||||
ebi('path').style.display = '';
|
ebi('path').style.display = '';
|
||||||
|
ebi('treeul').innerHTML = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
r.hide = function () {
|
r.hide = function () {
|
||||||
|
@ -4865,10 +4891,18 @@ var treectl = (function () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QS('#treeul>li>a+a').textContent = '[root]';
|
|
||||||
despin('#tree');
|
despin('#tree');
|
||||||
reload_tree();
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
QS('#treeul>li>a+a').textContent = '[root]';
|
||||||
|
}
|
||||||
|
catch (ex) {
|
||||||
|
console.log('got no root yet');
|
||||||
|
r.dir_cb = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
reload_tree();
|
||||||
var fun = r.dir_cb;
|
var fun = r.dir_cb;
|
||||||
if (fun) {
|
if (fun) {
|
||||||
r.dir_cb = null;
|
r.dir_cb = null;
|
||||||
|
@ -5042,7 +5076,7 @@ var treectl = (function () {
|
||||||
if (this.hpush && !showfile.active())
|
if (this.hpush && !showfile.active())
|
||||||
hist_push(this.top);
|
hist_push(this.top);
|
||||||
|
|
||||||
if (!this.back && treectl.entreed) {
|
if (!this.back && !treectl.hidden) {
|
||||||
var dirs = [];
|
var dirs = [];
|
||||||
for (var a = 0; a < res.dirs.length; a++)
|
for (var a = 0; a < res.dirs.length; a++)
|
||||||
dirs.push(res.dirs[a].href.split('/')[0].split('?')[0]);
|
dirs.push(res.dirs[a].href.split('/')[0].split('?')[0]);
|
||||||
|
@ -5159,6 +5193,7 @@ var treectl = (function () {
|
||||||
if (res.acct) {
|
if (res.acct) {
|
||||||
acct = res.acct;
|
acct = res.acct;
|
||||||
have_up2k_idx = res.idx;
|
have_up2k_idx = res.idx;
|
||||||
|
lifetime = res.lifetime;
|
||||||
apply_perms(res.perms);
|
apply_perms(res.perms);
|
||||||
fileman.render();
|
fileman.render();
|
||||||
}
|
}
|
||||||
|
@ -6348,7 +6383,7 @@ var unpost = (function () {
|
||||||
|
|
||||||
for (var a = n; a < n2; a++)
|
for (var a = n; a < n2; a++)
|
||||||
if (QS('#op_unpost a.n' + a))
|
if (QS('#op_unpost a.n' + a))
|
||||||
req.push(uricom_dec(r.files[a].vp)[0]);
|
req.push(uricom_dec(r.files[a].vp));
|
||||||
|
|
||||||
var links = QSA('#op_unpost a.n' + n);
|
var links = QSA('#op_unpost a.n' + n);
|
||||||
for (var a = 0, aa = links.length; a < aa; a++) {
|
for (var a = 0, aa = links.length; a < aa; a++) {
|
||||||
|
|
|
@ -1179,8 +1179,11 @@ function up2k_init(subtle) {
|
||||||
|
|
||||||
var msg = [];
|
var msg = [];
|
||||||
|
|
||||||
|
if (lifetime)
|
||||||
|
msg.push('<b>' + L.u_up_life.format(lhumantime(st.lifetime || lifetime)) + '</b>\n\n');
|
||||||
|
|
||||||
if (FIREFOX && good_files.length > 3000)
|
if (FIREFOX && good_files.length > 3000)
|
||||||
msg.push(L.u_ff_many);
|
msg.push(L.u_ff_many + "\n\n");
|
||||||
|
|
||||||
msg.push(L.u_asku.format(good_files.length, esc(get_vpath())) + '<ul>');
|
msg.push(L.u_asku.format(good_files.length, esc(get_vpath())) + '<ul>');
|
||||||
for (var a = 0, aa = Math.min(20, good_files.length); a < aa; a++)
|
for (var a = 0, aa = Math.min(20, good_files.length); a < aa; a++)
|
||||||
|
@ -2226,6 +2229,7 @@ function up2k_init(subtle) {
|
||||||
"name": t.name,
|
"name": t.name,
|
||||||
"size": t.size,
|
"size": t.size,
|
||||||
"lmod": t.lmod,
|
"lmod": t.lmod,
|
||||||
|
"life": st.lifetime,
|
||||||
"hash": t.hash
|
"hash": t.hash
|
||||||
};
|
};
|
||||||
if (t.srch)
|
if (t.srch)
|
||||||
|
@ -2459,6 +2463,69 @@ function up2k_init(subtle) {
|
||||||
}
|
}
|
||||||
draw_turbo();
|
draw_turbo();
|
||||||
|
|
||||||
|
function draw_life() {
|
||||||
|
var el = ebi('u2life');
|
||||||
|
if (!lifetime) {
|
||||||
|
el.style.display = 'none';
|
||||||
|
el.innerHTML = '';
|
||||||
|
st.lifetime = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
el.style.display = uc.fsearch ? 'none' : '';
|
||||||
|
el.innerHTML = '<div>' + L.u_life_cfg + '</div><div>' + L.u_life_est + '</div><div id="undor"></div>';
|
||||||
|
set_life(Math.min(lifetime, icfg_get('lifetime', lifetime)));
|
||||||
|
ebi('lifem').oninput = ebi('lifeh').oninput = mod_life;
|
||||||
|
tt.att(ebi('u2life'));
|
||||||
|
}
|
||||||
|
draw_life();
|
||||||
|
|
||||||
|
function mod_life(e) {
|
||||||
|
var el = e.target,
|
||||||
|
pow = parseInt(el.getAttribute('p')),
|
||||||
|
v = parseInt(el.value);
|
||||||
|
|
||||||
|
if (!isNum(v))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (toast.tag == mod_life)
|
||||||
|
toast.hide();
|
||||||
|
|
||||||
|
v *= pow;
|
||||||
|
if (v > lifetime) {
|
||||||
|
v = lifetime;
|
||||||
|
toast.warn(20, L.u_life_max.format(lhumantime(lifetime)), mod_life);
|
||||||
|
}
|
||||||
|
|
||||||
|
swrite('lifetime', v);
|
||||||
|
set_life(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
function set_life(v) {
|
||||||
|
//ebi('lifes').value = v;
|
||||||
|
ebi('lifem').value = parseInt(v / 60);
|
||||||
|
ebi('lifeh').value = parseInt(v / 3600);
|
||||||
|
|
||||||
|
var undo = have_unpost - (v || lifetime);
|
||||||
|
ebi('undor').innerHTML = undo <= 0 ?
|
||||||
|
L.u_unp_ng : L.u_unp_ok.format(lhumantime(undo));
|
||||||
|
|
||||||
|
st.lifetime = v;
|
||||||
|
rel_life();
|
||||||
|
}
|
||||||
|
|
||||||
|
function rel_life() {
|
||||||
|
if (!lifetime)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
ebi('lifew').innerHTML = unix2iso((st.lifetime || lifetime) +
|
||||||
|
Date.now() / 1000 - new Date().getTimezoneOffset() * 60
|
||||||
|
).replace(' ', ', ').slice(0, -3);
|
||||||
|
}
|
||||||
|
catch (ex) { }
|
||||||
|
}
|
||||||
|
setInterval(rel_life, 9000);
|
||||||
|
|
||||||
function set_potato() {
|
function set_potato() {
|
||||||
pvis.potato();
|
pvis.potato();
|
||||||
set_fsearch();
|
set_fsearch();
|
||||||
|
@ -2509,6 +2576,7 @@ function up2k_init(subtle) {
|
||||||
ebi('u2mu').style.display = potato ? '' : 'none';
|
ebi('u2mu').style.display = potato ? '' : 'none';
|
||||||
|
|
||||||
draw_turbo();
|
draw_turbo();
|
||||||
|
draw_life();
|
||||||
onresize();
|
onresize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -626,7 +626,7 @@ function uricom_sdec(txt) {
|
||||||
function uricom_adec(arr, li) {
|
function uricom_adec(arr, li) {
|
||||||
var ret = [];
|
var ret = [];
|
||||||
for (var a = 0; a < arr.length; a++) {
|
for (var a = 0; a < arr.length; a++) {
|
||||||
var txt = uricom_dec(arr[a])[0];
|
var txt = uricom_dec(arr[a]);
|
||||||
ret.push(li ? '<li>' + esc(txt) + '</li>' : txt);
|
ret.push(li ? '<li>' + esc(txt) + '</li>' : txt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -682,7 +682,7 @@ var isNum = function (v) {
|
||||||
var n = parseFloat(v);
|
var n = parseFloat(v);
|
||||||
return !isNaN(v - n) && n === v;
|
return !isNaN(v - n) && n === v;
|
||||||
};
|
};
|
||||||
if (window.Number)
|
if (window.Number && Number.isFinite)
|
||||||
isNum = Number.isFinite;
|
isNum = Number.isFinite;
|
||||||
|
|
||||||
|
|
||||||
|
@ -717,7 +717,7 @@ function humantime(v) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function shumantime(v) {
|
function shumantime(v, long) {
|
||||||
if (v < 10)
|
if (v < 10)
|
||||||
return f2f(v, 2) + 's';
|
return f2f(v, 2) + 's';
|
||||||
if (v < 60)
|
if (v < 60)
|
||||||
|
@ -737,11 +737,27 @@ function shumantime(v) {
|
||||||
var v1 = parseInt(v / m1),
|
var v1 = parseInt(v / m1),
|
||||||
v2 = ('0' + parseInt((v % m1) / m2)).slice(-2);
|
v2 = ('0' + parseInt((v % m1) / m2)).slice(-2);
|
||||||
|
|
||||||
return v1 + ch + (v1 >= 10 ? '' : v2);
|
return v1 + ch + (v1 >= 10 || v2 == '00' ? '' : v2 + (
|
||||||
|
long && a < st.length - 1 ? st[a + 1][2] : ''));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function lhumantime(v) {
|
||||||
|
var t = shumantime(v, 1),
|
||||||
|
tp = t.replace(/([a-z])/g, " $1 ").split(/ /g).slice(0, -1);
|
||||||
|
|
||||||
|
if (!window.L || tp.length < 2 || tp[1].indexOf('$') + 1)
|
||||||
|
return t;
|
||||||
|
|
||||||
|
var ret = '';
|
||||||
|
for (var a = 0; a < tp.length; a += 2)
|
||||||
|
ret += tp[a] + ' ' + L['ht_' + tp[a + 1]].replace(tp[a] == 1 ? /!.*/ : /!/, '') + L.ht_and;
|
||||||
|
|
||||||
|
return ret.slice(0, -L.ht_and.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function clamp(v, a, b) {
|
function clamp(v, a, b) {
|
||||||
return Math.min(Math.max(v, a), b);
|
return Math.min(Math.max(v, a), b);
|
||||||
}
|
}
|
||||||
|
@ -812,7 +828,7 @@ function fcfg_get(name, defval) {
|
||||||
var o = ebi(name),
|
var o = ebi(name),
|
||||||
val = parseFloat(sread(name));
|
val = parseFloat(sread(name));
|
||||||
|
|
||||||
if (isNaN(val))
|
if (!isNum(val))
|
||||||
return parseFloat(o ? o.value : defval);
|
return parseFloat(o ? o.value : defval);
|
||||||
|
|
||||||
if (o)
|
if (o)
|
||||||
|
@ -1068,7 +1084,7 @@ var tt = (function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
r.hide = function (e) {
|
r.hide = function (e) {
|
||||||
ev(e);
|
//ev(e); // eats checkbox-label clicks
|
||||||
clearTimeout(tev);
|
clearTimeout(tev);
|
||||||
window.removeEventListener('scroll', r.hide);
|
window.removeEventListener('scroll', r.hide);
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
curl http://192.168.123.1:3923/cpp/scripts/pyinstaller/build.sh |
|
curl http://192.168.123.1:3923/cpp/scripts/pyinstaller/build.sh |
|
||||||
tee build2.sh | cmp build.sh || {
|
tee build2.sh | cmp build.sh && rm build2.sh || {
|
||||||
echo "new build script; upgrade y/n:"
|
echo "new build script; upgrade y/n:"
|
||||||
while true; do read -u1 -n1 -r r; [[ $r =~ [yYnN] ]] && break; done
|
while true; do read -u1 -n1 -r r; [[ $r =~ [yYnN] ]] && break; done
|
||||||
[[ $r =~ [yY] ]] && mv build{2,}.sh && exec ./build.sh
|
[[ $r =~ [yY] ]] && mv build{2,}.sh && exec ./build.sh
|
||||||
|
|
|
@ -6,11 +6,11 @@ this is the EXE edition of copyparty, compatible with Windows7-SP1
|
||||||
and later. To make this possible, the EXE was compiled with Python
|
and later. To make this possible, the EXE was compiled with Python
|
||||||
3.7.9, which is EOL and does not receive security patches anymore.
|
3.7.9, which is EOL and does not receive security patches anymore.
|
||||||
|
|
||||||
it is strongly recommended to use the python sfx instead:
|
if possible, for performance and security reasons, please use this instead:
|
||||||
https://github.com/9001/copyparty/releases/latest/download/copyparty-sfx.py
|
https://github.com/9001/copyparty/releases/latest/download/copyparty-sfx.py
|
||||||
"""
|
"""
|
||||||
|
|
||||||
print(v.replace("\n", "\n░▌ ")[1:] + "\n")
|
print(v.replace("\n", "\n▒▌ ")[1:] + "\n")
|
||||||
|
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
Loading…
Reference in a new issue