diff --git a/README.md b/README.md index f1d6e251..48b0cf0e 100644 --- a/README.md +++ b/README.md @@ -328,6 +328,12 @@ upgrade notes * can I make copyparty download a file to my server if I give it a URL? * yes, using [hooks](https://github.com/9001/copyparty/blob/hovudstraum/bin/hooks/wget.py) +* i want to learn python and/or programming and am considering looking at the copyparty source code in that occasion + ```bash + _| _ __ _ _|_ + (_| (_) | | (_) |_ + ``` + # accounts and volumes diff --git a/copyparty/broker_mp.py b/copyparty/broker_mp.py index bbadc3fe..371cfa67 100644 --- a/copyparty/broker_mp.py +++ b/copyparty/broker_mp.py @@ -69,7 +69,7 @@ class BrokerMp(object): while procs: if procs[-1].is_alive(): - time.sleep(0.1) + time.sleep(0.05) continue procs.pop() diff --git a/copyparty/svchub.py b/copyparty/svchub.py index 1c41cb72..74323898 100644 --- a/copyparty/svchub.py +++ b/copyparty/svchub.py @@ -339,7 +339,12 @@ class SvcHub(object): if self.httpsrv_up != self.broker.num_workers: return - time.sleep(0.1) # purely cosmetic dw + ar = self.args + for _ in range(10 if ar.ftp or ar.ftps else 0): + time.sleep(0.03) + if self.ftpd: + break + if self.tcpsrv.qr: self.log("qr-code", self.tcpsrv.qr) else: @@ -645,19 +650,25 @@ class SvcHub(object): ret = 1 try: self.pr("OPYTHAT") + tasks = [] slp = 0.0 if self.mdns: - Daemon(self.mdns.stop) + tasks.append(Daemon(self.mdns.stop, "mdns")) slp = time.time() + 0.5 if self.ssdp: - Daemon(self.ssdp.stop) + tasks.append(Daemon(self.ssdp.stop, "ssdp")) slp = time.time() + 0.5 self.broker.shutdown() self.tcpsrv.shutdown() self.up2k.shutdown() + + if hasattr(self, "smbd"): + slp = max(slp, time.time() + 0.5) + tasks.append(Daemon(self.smbd.stop, "smbd")) + if self.thumbsrv: self.thumbsrv.shutdown() @@ -667,17 +678,19 @@ class SvcHub(object): break if n == 3: - self.pr("waiting for thumbsrv (10sec)...") + self.log("root", "waiting for thumbsrv (10sec)...") if hasattr(self, "smbd"): - slp = max(slp, time.time() + 0.5) - Daemon(self.kill9, a=(1,)) - Daemon(self.smbd.stop) + zf = max(time.time() - slp, 0) + Daemon(self.kill9, a=(zf + 0.5,)) while time.time() < slp: - time.sleep(0.1) + if not next((x for x in tasks if x.is_alive), None): + break - self.pr("nailed it", end="") + time.sleep(0.05) + + self.log("root", "nailed it") ret = self.retcode except: self.pr("\033[31m[ error during shutdown ]\n{}\033[0m".format(min_ex())) @@ -687,7 +700,7 @@ class SvcHub(object): print("\033]0;\033\\", file=sys.stderr, end="") sys.stderr.flush() - self.pr("\033[0m") + self.pr("\033[0m", end="") if self.logf: self.logf.close() diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 694a6c16..cef56544 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -4699,6 +4699,39 @@ function hkhelp() { var fselgen, fselctr; +function fselfunw(e, ae, d, rem) { + fselctr = 0; + var gen = fselgen = Date.now(); + if (rem) + rem *= window.innerHeight; + + var selfun = function () { + var el = ae[d + 'ElementSibling']; + if (!el || gen != fselgen) + return; + + el.focus(); + var elh = el.offsetHeight; + if (ctrl(e)) + document.documentElement.scrollTop += (d == 'next' ? 1 : -1) * elh; + + if (e.shiftKey) { + clmod(el, 'sel', 't'); + msel.origin_tr(el); + msel.selui(); + } + + rem -= elh; + if (rem > 0) { + ae = document.activeElement; + if (++fselctr % 5 && rem > elh * (FIREFOX ? 5 : 2)) + selfun(); + else + setTimeout(selfun, 1); + } + } + selfun(); +} document.onkeydown = function (e) { if (e.altKey || e.isComposing) return; @@ -4749,37 +4782,7 @@ document.onkeydown = function (e) { if (k == 'PageUp') { d = 'previous'; rem = 0.6; } if (k == 'PageDown') { d = 'next'; rem = 0.6; } if (d) { - fselctr = 0; - var gen = fselgen = Date.now(); - if (rem) - rem *= window.innerHeight; - - function selfun() { - var el = ae[d + 'ElementSibling']; - if (!el || gen != fselgen) - return; - - el.focus(); - var elh = el.offsetHeight; - if (ctrl(e)) - document.documentElement.scrollTop += (d == 'next' ? 1 : -1) * elh; - - if (e.shiftKey) { - clmod(el, 'sel', 't'); - msel.origin_tr(el); - msel.selui(); - } - - rem -= elh; - if (rem > 0) { - ae = document.activeElement; - if (++fselctr % 5 && rem > elh * (FIREFOX ? 5 : 2)) - selfun(); - else - setTimeout(selfun, 1); - } - } - selfun(); + fselfunw(e, ae, d, rem); return ev(e); } if (k == 'Space') { @@ -5268,7 +5271,10 @@ var filecolwidth = (function () { return; lastwidth = w; - document.documentElement.style.setProperty('--file-td-w', w + 'em'); + try { + document.documentElement.style.setProperty('--file-td-w', w + 'em'); + } + catch (ex) { } } })(); onresize100.add(filecolwidth, true); @@ -6316,10 +6322,11 @@ var filecols = (function () { var ths = QSA('#files>thead th>span'); for (var a = 0, aa = ths.length; a < aa; a++) { var th = ths[a].parentElement, + toh = ths[a].outerHTML, // !ff10 ttv = L.cols[ths[a].textContent]; - if (!MOBILE) { - th.innerHTML = '
' + ths[a].outerHTML; + if (!MOBILE && toh) { + th.innerHTML = '' + toh; th.getElementsByTagName('a')[0].onclick = ev_row_tgl; } if (ttv) { @@ -7125,7 +7132,7 @@ function show_md(md, name, div, url, depth) { wfp_debounce.hide(); if (!marked) { if (depth) - return toast.warn(10, errmsg + 'failed to load marked.js') + return toast.warn(10, errmsg + (window.WebAssembly ? 'failed to load marked.js' : 'your browser is too old')); wfp_debounce.n--; return import_js(SR + '/.cpr/deps/marked.js', function () { diff --git a/copyparty/web/md.html b/copyparty/web/md.html index d9da972a..5e08d07a 100644 --- a/copyparty/web/md.html +++ b/copyparty/web/md.html @@ -31,7 +31,7 @@ L# {%- else %} edit (basic) - edit (fancy) + edit (fancy) view raw {%- endif %} diff --git a/copyparty/web/md.js b/copyparty/web/md.js index 3d20105c..2679a13b 100644 --- a/copyparty/web/md.js +++ b/copyparty/web/md.js @@ -52,7 +52,7 @@ var img_load = (function () { var r = {}; r.callbacks = []; - function fire() { + var fire = function () { for (var a = 0; a < r.callbacks.length; a++) r.callbacks[a](); } @@ -472,7 +472,7 @@ img_load.callbacks = [toc.refresh]; // scroll handler var redraw = (function () { var sbs = true; - function onresize() { + var onresize = function () { if (window.matchMedia) sbs = window.matchMedia('(min-width: 64em)').matches; @@ -485,7 +485,7 @@ var redraw = (function () { onscroll(); } - function onscroll() { + var onscroll = function () { toc.refresh(); } @@ -507,6 +507,12 @@ dom_navtgl.onclick = function () { redraw(); }; +if (!HTTPS) + ebi('edit2').onclick = function (e) { + toast.err(0, "the fancy editor is only available over https"); + return ev(e); + } + if (sread('hidenav') == 1) dom_navtgl.onclick(); diff --git a/copyparty/web/md2.js b/copyparty/web/md2.js index 77fbc300..0a965d33 100644 --- a/copyparty/web/md2.js +++ b/copyparty/web/md2.js @@ -92,7 +92,7 @@ var action_stack = null; var nlines = 0; var draw_md = (function () { var delay = 1; - function draw_md() { + var draw_md = function () { var t0 = Date.now(); var src = dom_src.value; convert_markdown(src, dom_pre); @@ -135,7 +135,7 @@ img_load.callbacks = [function () { // resize handler redraw = (function () { - function onresize() { + var onresize = function () { var y = (dom_hbar.offsetTop + dom_hbar.offsetHeight) + 'px'; dom_wrap.style.top = y; dom_swrap.style.top = y; @@ -143,12 +143,12 @@ redraw = (function () { map_src = genmap(dom_ref, map_src); map_pre = genmap(dom_pre, map_pre); } - function setsbs() { + var setsbs = function () { dom_wrap.className = ''; dom_swrap.className = ''; onresize(); } - function modetoggle() { + var modetoggle = function () { var mode = dom_nsbs.innerHTML; dom_nsbs.innerHTML = mode == 'editor' ? 'preview' : 'editor'; mode += ' single'; @@ -172,7 +172,7 @@ redraw = (function () { (function () { var skip_src = false, skip_pre = false; - function scroll(src, srcmap, dst, dstmap) { + var scroll = function (src, srcmap, dst, dstmap) { var y = src.scrollTop; if (y < 8) { dst.scrollTop = 0; @@ -900,12 +900,12 @@ var set_lno = (function () { pv = null, lno = ebi('lno'); - function poke() { + var poke = function () { clearTimeout(t); t = setTimeout(fire, 20); } - function fire() { + var fire = function () { try { clearTimeout(t); @@ -930,7 +930,7 @@ var set_lno = (function () { // hotkeys / toolbar (function () { - function keydown(ev) { + var keydown = function (ev) { ev = ev || window.event; var kc = ev.code || ev.keyCode || ev.which, editing = document.activeElement == dom_src; @@ -1058,7 +1058,7 @@ action_stack = (function () { var ignore = false; var ref = dom_src.value; - function diff(from, to, cpos) { + var diff = function (from, to, cpos) { if (from === to) return null; @@ -1089,14 +1089,14 @@ action_stack = (function () { }; } - function undiff(from, change) { + var undiff = function (from, change) { return { txt: from.substring(0, change.car) + change.txt + from.substring(change.cdr), cpos: change.cpos }; } - function apply(src, dst) { + var apply = function (src, dst) { dbg('undos(%d) redos(%d)', hist.un.length, hist.re.length); if (src.length === 0) @@ -1120,7 +1120,7 @@ action_stack = (function () { return true; } - function schedule_push() { + var schedule_push = function () { if (ignore) { ignore = false; return; @@ -1131,7 +1131,7 @@ action_stack = (function () { sched_timer = setTimeout(push, 500); } - function undo() { + var undo = function () { if (hist.re.length == 0) { clearTimeout(sched_timer); push(); @@ -1139,11 +1139,11 @@ action_stack = (function () { return apply(hist.un, hist.re); } - function redo() { + var redo = function () { return apply(hist.re, hist.un); } - function push() { + var push = function () { var newtxt = dom_src.value; var change = diff(ref, newtxt, sched_cpos); if (change !== null) diff --git a/copyparty/web/up2k.js b/copyparty/web/up2k.js index 0b84b8dc..15ae1585 100644 --- a/copyparty/web/up2k.js +++ b/copyparty/web/up2k.js @@ -588,7 +588,7 @@ function U2pvis(act, btns, uc, st) { btns[a].onclick = function (e) { ev(e); var newtab = this.getAttribute('act'); - function go() { + var go = function () { for (var b = 0; b < btns.length; b++) { btns[b].className = ( btns[b].getAttribute('act') == newtab) ? 'act' : ''; @@ -1654,11 +1654,11 @@ function up2k_init(subtle) { var running = false, was_busy = false; - function defer() { + var defer = function () { running = false; } - function taskerd() { + var taskerd = function () { if (running) return; @@ -1956,7 +1956,7 @@ function up2k_init(subtle) { st.bytes.hashed += cdr - car; st.etac.h++; - function orz(e) { + var orz = function (e) { bpend--; segm_next(); hash_calc(nch, e.target.result); @@ -2239,7 +2239,7 @@ function up2k_init(subtle) { st.todo.handshake.unshift(t); t.keepalive = keepalive; }; - function orz(e) { + var orz = function (e) { if (t.t_busied != me) { console.log('zombie handshake onload,', t.name, t); return; @@ -2523,7 +2523,7 @@ function up2k_init(subtle) { if (cdr >= t.size) cdr = t.size; - function orz(xhr) { + var orz = function (xhr) { var txt = ((xhr.response && xhr.response.err) || xhr.responseText) + ''; if (txt.indexOf('upload blocked by x') + 1) { apop(st.busy.upload, upt); @@ -2552,7 +2552,7 @@ function up2k_init(subtle) { } orz2(xhr); } - function orz2(xhr) { + var orz2 = function (xhr) { apop(st.busy.upload, upt); apop(t.postlist, npart); if (!t.postlist.length) { diff --git a/copyparty/web/util.js b/copyparty/web/util.js index bad1fd4c..e3dc3de2 100644 --- a/copyparty/web/util.js +++ b/copyparty/web/util.js @@ -140,29 +140,35 @@ catch (ex) { } var crashed = false, ignexd = {}, evalex_fatal = false; function vis_exh(msg, url, lineNo, columnNo, error) { - if ((msg + '').indexOf('ResizeObserver') + 1) + msg = String(msg); + url = String(url); + + if (msg.indexOf('ResizeObserver') + 1) return; // chrome issue 809574 (benign, from