mirror of
				https://github.com/9001/copyparty.git
				synced 2025-11-03 21:43:12 +00:00 
			
		
		
		
	Compare commits
	
		
			16 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					231a03bcfd | ||
| 
						 | 
					bc85723657 | ||
| 
						 | 
					be32b743c6 | ||
| 
						 | 
					83c9843059 | ||
| 
						 | 
					11cf43626d | ||
| 
						 | 
					a6dc5e2ce3 | ||
| 
						 | 
					38593a0394 | ||
| 
						 | 
					95309afeea | ||
| 
						 | 
					c2bf6fe2a3 | ||
| 
						 | 
					99ac324fbd | ||
| 
						 | 
					5562de330f | ||
| 
						 | 
					95014236ac | ||
| 
						 | 
					6aa7386138 | ||
| 
						 | 
					3226a1f588 | ||
| 
						 | 
					b4cf890cd8 | ||
| 
						 | 
					ce09e323af | 
@@ -1,8 +1,8 @@
 | 
			
		||||
# coding: utf-8
 | 
			
		||||
 | 
			
		||||
VERSION = (0, 13, 12)
 | 
			
		||||
VERSION = (0, 13, 13)
 | 
			
		||||
CODENAME = "future-proof"
 | 
			
		||||
BUILD_DT = (2021, 9, 1)
 | 
			
		||||
BUILD_DT = (2021, 9, 3)
 | 
			
		||||
 | 
			
		||||
S_VERSION = ".".join(map(str, VERSION))
 | 
			
		||||
S_BUILD_DT = "{0:04d}-{1:02d}-{2:02d}".format(*BUILD_DT)
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@ import gzip
 | 
			
		||||
import time
 | 
			
		||||
import copy
 | 
			
		||||
import json
 | 
			
		||||
import base64
 | 
			
		||||
import string
 | 
			
		||||
import socket
 | 
			
		||||
import ctypes
 | 
			
		||||
@@ -192,7 +193,21 @@ class HttpCli(object):
 | 
			
		||||
        self.cookies = cookies
 | 
			
		||||
        self.vpath = unquotep(vpath)  # not query, so + means +
 | 
			
		||||
 | 
			
		||||
        pwd = uparam.get("pw")
 | 
			
		||||
        pwd = None
 | 
			
		||||
        ba = self.headers.get("authorization")
 | 
			
		||||
        if ba:
 | 
			
		||||
            try:
 | 
			
		||||
                ba = ba.split(" ")[1].encode("ascii")
 | 
			
		||||
                ba = base64.b64decode(ba).decode("utf-8")
 | 
			
		||||
                # try "pwd", "x:pwd", "pwd:x"
 | 
			
		||||
                for ba in [ba] + ba.split(":", 1)[::-1]:
 | 
			
		||||
                    if self.asrv.iacct.get(ba):
 | 
			
		||||
                        pwd = ba
 | 
			
		||||
                        break
 | 
			
		||||
            except:
 | 
			
		||||
                pass
 | 
			
		||||
 | 
			
		||||
        pwd = uparam.get("pw") or pwd
 | 
			
		||||
        self.uname = self.asrv.iacct.get(pwd, "*")
 | 
			
		||||
        self.rvol = self.asrv.vfs.aread[self.uname]
 | 
			
		||||
        self.wvol = self.asrv.vfs.awrite[self.uname]
 | 
			
		||||
 
 | 
			
		||||
@@ -270,13 +270,14 @@ class ThumbSrv(object):
 | 
			
		||||
                fmts += ["RGBA", "LA"]
 | 
			
		||||
                args["method"] = 6
 | 
			
		||||
            else:
 | 
			
		||||
                pass  # default q = 75
 | 
			
		||||
                # default q = 75
 | 
			
		||||
                args["progressive"] = True
 | 
			
		||||
 | 
			
		||||
            if im.mode not in fmts:
 | 
			
		||||
                # print("conv {}".format(im.mode))
 | 
			
		||||
                im = im.convert("RGB")
 | 
			
		||||
 | 
			
		||||
            im.save(tpath, quality=40, method=6)
 | 
			
		||||
            im.save(tpath, **args)
 | 
			
		||||
 | 
			
		||||
    def conv_ffmpeg(self, abspath, tpath):
 | 
			
		||||
        ret, _ = ffprobe(abspath)
 | 
			
		||||
 
 | 
			
		||||
@@ -815,8 +815,6 @@ input.eq_gain {
 | 
			
		||||
	width: 1em;
 | 
			
		||||
	border-radius: .2em;
 | 
			
		||||
	margin: -1.2em auto 0 auto;
 | 
			
		||||
	top: 2em;
 | 
			
		||||
	position: relative;
 | 
			
		||||
	background: #444;
 | 
			
		||||
}
 | 
			
		||||
#files th span {
 | 
			
		||||
@@ -1544,6 +1542,7 @@ html.light #bbox-overlay figcaption a {
 | 
			
		||||
 | 
			
		||||
#op_up2k {
 | 
			
		||||
	padding: 0 1em 1em 1em;
 | 
			
		||||
	min-height: 60em;
 | 
			
		||||
}
 | 
			
		||||
#u2form {
 | 
			
		||||
	position: absolute;
 | 
			
		||||
 
 | 
			
		||||
@@ -1788,7 +1788,7 @@ var fileman = (function () {
 | 
			
		||||
 | 
			
		||||
		html = html.concat([
 | 
			
		||||
			'<button id="rn_cancel" tt="abort and close this window">❌ cancel</button>',
 | 
			
		||||
			'<button id="rn_apply">✅ apply rename</button>',
 | 
			
		||||
			'<button id="rn_apply">✅ APPLY RENAME</button>',
 | 
			
		||||
			'<a id="rn_adv" class="tgl btn" href="#" tt="batch / metadata / pattern renaming">advanced</a>',
 | 
			
		||||
			'<a id="rn_case" class="tgl btn" href="#" tt="case-sensitive regex">case</a>',
 | 
			
		||||
			'</div>',
 | 
			
		||||
@@ -1880,18 +1880,21 @@ var fileman = (function () {
 | 
			
		||||
			f[n].inew.focus();
 | 
			
		||||
			f[n].inew.setSelectionRange(0, f[n].inew.value.lastIndexOf('.'), "forward");
 | 
			
		||||
		}
 | 
			
		||||
		function rn_cancel() {
 | 
			
		||||
		function rn_cancel(e) {
 | 
			
		||||
			ev(e);
 | 
			
		||||
			rui.parentNode.removeChild(rui);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ebi('rn_cancel').onclick = rn_cancel;
 | 
			
		||||
		ebi('rn_apply').onclick = rn_apply;
 | 
			
		||||
		ebi('rn_adv').onclick = function () {
 | 
			
		||||
		ebi('rn_adv').onclick = function (e) {
 | 
			
		||||
			ev(e);
 | 
			
		||||
			adv = !adv;
 | 
			
		||||
			bcfg_set('rn_adv', adv);
 | 
			
		||||
			sadv();
 | 
			
		||||
		};
 | 
			
		||||
		ebi('rn_case').onclick = function () {
 | 
			
		||||
		ebi('rn_case').onclick = function (e) {
 | 
			
		||||
			ev(e);
 | 
			
		||||
			cs = !cs;
 | 
			
		||||
			bcfg_set('rn_case', cs);
 | 
			
		||||
		};
 | 
			
		||||
@@ -1918,7 +1921,8 @@ var fileman = (function () {
 | 
			
		||||
				ipre.appendChild(o);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		inew.onclick = function () {
 | 
			
		||||
		inew.onclick = function (e) {
 | 
			
		||||
			ev(e);
 | 
			
		||||
			modal.prompt('provide a name for your new preset', ifmt.value, function (name) {
 | 
			
		||||
				if (!name)
 | 
			
		||||
					return toast.warn(3, 'aborted');
 | 
			
		||||
@@ -1929,7 +1933,8 @@ var fileman = (function () {
 | 
			
		||||
				ipre.value = name;
 | 
			
		||||
			});
 | 
			
		||||
		};
 | 
			
		||||
		idel.onclick = function () {
 | 
			
		||||
		idel.onclick = function (e) {
 | 
			
		||||
			ev(e);
 | 
			
		||||
			delete presets[ipre.value];
 | 
			
		||||
			jwrite('rn_pre', presets);
 | 
			
		||||
			spresets();
 | 
			
		||||
@@ -1987,7 +1992,8 @@ var fileman = (function () {
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		function rn_apply() {
 | 
			
		||||
		function rn_apply(e) {
 | 
			
		||||
			ev(e);
 | 
			
		||||
			while (f.length && (!f[0].ok || f[0].ofn == f[0].inew.value))
 | 
			
		||||
				f.shift();
 | 
			
		||||
 | 
			
		||||
@@ -2390,7 +2396,8 @@ var thegrid = (function () {
 | 
			
		||||
		}
 | 
			
		||||
		var uns = QS('#ggrid a[ref="unsearch"]');
 | 
			
		||||
		if (uns)
 | 
			
		||||
			uns.onclick = function () {
 | 
			
		||||
			uns.onclick = function (e) {
 | 
			
		||||
				ev(e);
 | 
			
		||||
				ebi('unsearch').click();
 | 
			
		||||
			};
 | 
			
		||||
	};
 | 
			
		||||
@@ -3587,6 +3594,7 @@ var filecols = (function () {
 | 
			
		||||
			if (ttv) {
 | 
			
		||||
				th.setAttribute("tt", ttv);
 | 
			
		||||
				th.setAttribute("ttd", "u");
 | 
			
		||||
				th.setAttribute("ttm", "12");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
@@ -4150,6 +4158,7 @@ var unpost = (function () {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ct.onclick = function (e) {
 | 
			
		||||
		ev(e);
 | 
			
		||||
		var tgt = e.target.closest('a[me]');
 | 
			
		||||
		if (!tgt)
 | 
			
		||||
			return;
 | 
			
		||||
@@ -4191,7 +4200,8 @@ var unpost = (function () {
 | 
			
		||||
		tfilt = setTimeout(r.load, 250);
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	ebi('unpost_nofilt').onclick = function () {
 | 
			
		||||
	ebi('unpost_nofilt').onclick = function (e) {
 | 
			
		||||
		ev(e);
 | 
			
		||||
		filt.value = '';
 | 
			
		||||
		r.load();
 | 
			
		||||
	};
 | 
			
		||||
 
 | 
			
		||||
@@ -239,3 +239,6 @@ html.light #tt em {
 | 
			
		||||
#modali:focus {
 | 
			
		||||
	border-color: #06d;
 | 
			
		||||
}
 | 
			
		||||
#repl_pre {
 | 
			
		||||
	max-width: 24em;
 | 
			
		||||
}
 | 
			
		||||
@@ -1880,17 +1880,18 @@ function up2k_init(subtle) {
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    ebi('nthread').onkeydown = bumpthread2;
 | 
			
		||||
    ebi('nthread').addEventListener('input', bumpthread, false);
 | 
			
		||||
    ebi('multitask').addEventListener('click', tgl_multitask, false);
 | 
			
		||||
    ebi('ask_up').addEventListener('click', tgl_ask_up, false);
 | 
			
		||||
    ebi('flag_en').addEventListener('click', tgl_flag_en, false);
 | 
			
		||||
    ebi('u2turbo').addEventListener('click', tgl_turbo, false);
 | 
			
		||||
    ebi('u2tdate').addEventListener('click', tgl_datechk, false);
 | 
			
		||||
    ebi('nthread').oninput = bumpthread;
 | 
			
		||||
    ebi('multitask').onclick = tgl_multitask;
 | 
			
		||||
    ebi('ask_up').onclick = tgl_ask_up;
 | 
			
		||||
    ebi('flag_en').onclick = tgl_flag_en;
 | 
			
		||||
    ebi('u2turbo').onclick = tgl_turbo;
 | 
			
		||||
    ebi('u2tdate').onclick = tgl_datechk;
 | 
			
		||||
    var o = ebi('fsearch');
 | 
			
		||||
    if (o)
 | 
			
		||||
        o.addEventListener('click', tgl_fsearch, false);
 | 
			
		||||
 | 
			
		||||
    ebi('u2etas').onclick = function () {
 | 
			
		||||
    ebi('u2etas').onclick = function (e) {
 | 
			
		||||
        ev(e);
 | 
			
		||||
        clmod(ebi('u2etas'), 'o', 't');
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,8 @@ if (!window['console'])
 | 
			
		||||
 | 
			
		||||
var is_touch = 'ontouchstart' in window,
 | 
			
		||||
    IPHONE = /iPhone|iPad|iPod/i.test(navigator.userAgent),
 | 
			
		||||
    ANDROID = /android/i.test(navigator.userAgent);
 | 
			
		||||
    ANDROID = /android/i.test(navigator.userAgent),
 | 
			
		||||
    WINDOWS = navigator.platform ? navigator.platform == 'Win32' : /Windows/.test(navigator.userAgent);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
var ebi = document.getElementById.bind(document),
 | 
			
		||||
@@ -28,6 +29,35 @@ function esc(txt) {
 | 
			
		||||
        }[c];
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
window.onunhandledrejection = function (e) {
 | 
			
		||||
    console.log("REJ: " + e.reason);
 | 
			
		||||
};
 | 
			
		||||
try {
 | 
			
		||||
    console.hist = [];
 | 
			
		||||
    var hook = function (t) {
 | 
			
		||||
        var orig = console[t].bind(console),
 | 
			
		||||
            cfun = function () {
 | 
			
		||||
                console.hist.push(Date.now() + ' ' + t + ': ' + Array.from(arguments).join(', '));
 | 
			
		||||
                if (console.hist.length > 100)
 | 
			
		||||
                    console.hist = console.hist.slice(50);
 | 
			
		||||
 | 
			
		||||
                orig.apply(console, arguments);
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
        console['std' + t] = orig;
 | 
			
		||||
        console[t] = cfun;
 | 
			
		||||
    };
 | 
			
		||||
    hook('log');
 | 
			
		||||
    console.log('log-capture ok');
 | 
			
		||||
    hook('debug');
 | 
			
		||||
    hook('warn');
 | 
			
		||||
    hook('error');
 | 
			
		||||
}
 | 
			
		||||
catch (ex) {
 | 
			
		||||
    if (console.stdlog)
 | 
			
		||||
        console.log = console.stdlog;
 | 
			
		||||
    console.log(ex);
 | 
			
		||||
}
 | 
			
		||||
var crashed = false, ignexd = {};
 | 
			
		||||
function vis_exh(msg, url, lineNo, columnNo, error) {
 | 
			
		||||
    if ((msg + '').indexOf('ResizeObserver') !== -1)
 | 
			
		||||
@@ -39,14 +69,13 @@ function vis_exh(msg, url, lineNo, columnNo, error) {
 | 
			
		||||
 | 
			
		||||
    crashed = true;
 | 
			
		||||
    window.onerror = undefined;
 | 
			
		||||
    var con = is_touch ? '' : '<br />  (and if you can, press F12 and include the "Console" tab in the screenshot too)',
 | 
			
		||||
        html = [
 | 
			
		||||
            '<h1>you hit a bug!</h1>',
 | 
			
		||||
            '<p style="font-size:1.3em;margin:0">try to <a href="#" onclick="localStorage.clear();location.reload();">reset copyparty settings</a> if you are stuck here, or <a href="#" onclick="ignex();">ignore this</a> / <a href="#" onclick="ignex(true);">ignore all</a></p>',
 | 
			
		||||
            '<p style="color:#fff">please send me a screenshot arigathanks gozaimuch: <code>ed/irc.rizon.net</code> or <code>ed#2644</code>' + con + '</p>',
 | 
			
		||||
            '<p class="b">' + esc(url + ' @' + lineNo + ':' + columnNo), '<br />' + esc(String(msg)) + '</p>',
 | 
			
		||||
            '<p><b>UA:</b> ' + esc(navigator.userAgent + '')
 | 
			
		||||
        ];
 | 
			
		||||
    var html = [
 | 
			
		||||
        '<h1>you hit a bug!</h1>',
 | 
			
		||||
        '<p style="font-size:1.3em;margin:0">try to <a href="#" onclick="localStorage.clear();location.reload();">reset copyparty settings</a> if you are stuck here, or <a href="#" onclick="ignex();">ignore this</a> / <a href="#" onclick="ignex(true);">ignore all</a></p>',
 | 
			
		||||
        '<p style="color:#fff">please send me a screenshot arigathanks gozaimuch: <code>ed/irc.rizon.net</code> or <code>ed#2644</code></p>',
 | 
			
		||||
        '<p class="b">' + esc(url + ' @' + lineNo + ':' + columnNo), '<br />' + esc(String(msg)) + '</p>',
 | 
			
		||||
        '<p><b>UA:</b> ' + esc(navigator.userAgent + '')
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
        var ua = '',
 | 
			
		||||
@@ -54,7 +83,7 @@ function vis_exh(msg, url, lineNo, columnNo, error) {
 | 
			
		||||
            adb = ad.brands;
 | 
			
		||||
 | 
			
		||||
        for (var a = 0; a < adb.length; a++)
 | 
			
		||||
            if (adb[a].brand.indexOf('Not;A') < 0)
 | 
			
		||||
            if (!/Not.*A.*Brand/.exec(adb[a].brand))
 | 
			
		||||
                ua += adb[a].brand + '/' + adb[a].version + ', ';
 | 
			
		||||
        ua += ad.platform;
 | 
			
		||||
 | 
			
		||||
@@ -86,6 +115,13 @@ function vis_exh(msg, url, lineNo, columnNo, error) {
 | 
			
		||||
    }
 | 
			
		||||
    catch (e) { }
 | 
			
		||||
 | 
			
		||||
    if (console.hist.length) {
 | 
			
		||||
        html.push('<p class="b"><b>console:</b><ul><li>' + Date.now() + ' @</li>');
 | 
			
		||||
        for (var a = console.hist.length - 1, aa = Math.max(0, console.hist.length - 20); a >= aa; a--)
 | 
			
		||||
            html.push('<li>' + esc(console.hist[a]) + '</li>');
 | 
			
		||||
        html.push('</ul>')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
        var exbox = ebi('exbox');
 | 
			
		||||
        if (!exbox) {
 | 
			
		||||
@@ -101,11 +137,12 @@ function vis_exh(msg, url, lineNo, columnNo, error) {
 | 
			
		||||
                '#exbox a{text-decoration:underline;color:#fc0} ' +
 | 
			
		||||
                '#exbox h1{margin:.5em 1em 0 0;padding:0} ' +
 | 
			
		||||
                '#exbox p.b{border-top:1px solid #999;margin:1em 0 0 0;font-size:1em} ' +
 | 
			
		||||
                '#exbox ul, #exbox li {margin:0 0 0 .5em;padding:0} ' +
 | 
			
		||||
                '#exbox b{color:#fff}'
 | 
			
		||||
            );
 | 
			
		||||
            document.head.appendChild(s);
 | 
			
		||||
        }
 | 
			
		||||
        exbox.innerHTML = html.join('\n').replace(/https?:\/\/[^ \/]+\//g, '/');
 | 
			
		||||
        exbox.innerHTML = html.join('\n').replace(/https?:\/\/[^ \/]+\//g, '/').replace(/js\?_=[a-zA-Z]{4}/g, 'js');
 | 
			
		||||
        exbox.style.display = 'block';
 | 
			
		||||
    }
 | 
			
		||||
    catch (e) {
 | 
			
		||||
@@ -613,6 +650,9 @@ var timer = (function () {
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    function doevents() {
 | 
			
		||||
        if (crashed)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (Date.now() - r.last < 69)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -658,6 +698,7 @@ var tt = (function () {
 | 
			
		||||
        r.el = this;
 | 
			
		||||
        var pos = this.getBoundingClientRect(),
 | 
			
		||||
            dir = this.getAttribute('ttd') || '',
 | 
			
		||||
            margin = parseFloat(this.getAttribute('ttm') || 0),
 | 
			
		||||
            top = pos.top < window.innerHeight / 2,
 | 
			
		||||
            big = this.className.indexOf(' ttb') !== -1;
 | 
			
		||||
 | 
			
		||||
@@ -669,23 +710,22 @@ var tt = (function () {
 | 
			
		||||
        r.tt.style.top = '0';
 | 
			
		||||
 | 
			
		||||
        r.tt.innerHTML = msg.replace(/\$N/g, "<br />");
 | 
			
		||||
        var tw = r.tt.offsetWidth,
 | 
			
		||||
            x = pos.left + (pos.right - pos.left) / 2 - tw / 2;
 | 
			
		||||
 | 
			
		||||
        if (x < 0)
 | 
			
		||||
            x = 8;
 | 
			
		||||
 | 
			
		||||
        if (x + tw >= window.innerWidth - 8) {
 | 
			
		||||
            x = window.innerWidth - tw - 8;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        r.tt.style.left = x + 'px';
 | 
			
		||||
        r.tt.style.top = top ? pos.bottom + 'px' : 'auto';
 | 
			
		||||
        r.tt.style.bottom = top ? 'auto' : (window.innerHeight - pos.top) + 'px';
 | 
			
		||||
 | 
			
		||||
        r.el.addEventListener('mouseleave', r.hide);
 | 
			
		||||
        window.addEventListener('scroll', r.hide);
 | 
			
		||||
        clmod(r.tt, 'show', 1);
 | 
			
		||||
 | 
			
		||||
        var tw = r.tt.offsetWidth,
 | 
			
		||||
            x = pos.left + (pos.right - pos.left) / 2 - tw / 2;
 | 
			
		||||
 | 
			
		||||
        if (x + tw >= window.innerWidth - 24)
 | 
			
		||||
            x = window.innerWidth - tw - 24;
 | 
			
		||||
 | 
			
		||||
        if (x < 0)
 | 
			
		||||
            x = 12;
 | 
			
		||||
 | 
			
		||||
        r.tt.style.left = x + 'px';
 | 
			
		||||
        r.tt.style.top = top ? (margin + pos.bottom) + 'px' : 'auto';
 | 
			
		||||
        r.tt.style.bottom = top ? 'auto' : (margin + window.innerHeight - pos.top) + 'px';
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    r.hide = function (e) {
 | 
			
		||||
@@ -838,8 +878,12 @@ var modal = (function () {
 | 
			
		||||
    var r = {},
 | 
			
		||||
        q = [],
 | 
			
		||||
        o = null,
 | 
			
		||||
        cb_up = null,
 | 
			
		||||
        cb_ok = null,
 | 
			
		||||
        cb_ng = null;
 | 
			
		||||
        cb_ng = null,
 | 
			
		||||
        prim = '<a href="#" id="modal-ok">OK</a>',
 | 
			
		||||
        sec = '<a href="#" id="modal-ng">Cancel</a>',
 | 
			
		||||
        ok_cancel = WINDOWS ? prim + sec : sec + prim;
 | 
			
		||||
 | 
			
		||||
    r.busy = false;
 | 
			
		||||
 | 
			
		||||
@@ -867,6 +911,8 @@ var modal = (function () {
 | 
			
		||||
 | 
			
		||||
        document.addEventListener('focus', onfocus);
 | 
			
		||||
        timer.add(onfocus);
 | 
			
		||||
        if (cb_up)
 | 
			
		||||
            setTimeout(cb_up, 1);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    r.hide = function () {
 | 
			
		||||
@@ -921,41 +967,44 @@ var modal = (function () {
 | 
			
		||||
            q.shift()();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    r.alert = function (html, cb) {
 | 
			
		||||
    r.alert = function (html, cb, fun) {
 | 
			
		||||
        q.push(function () {
 | 
			
		||||
            _alert(lf2br(html), cb);
 | 
			
		||||
            _alert(lf2br(html), cb, fun);
 | 
			
		||||
        });
 | 
			
		||||
        next();
 | 
			
		||||
    };
 | 
			
		||||
    function _alert(html, cb) {
 | 
			
		||||
    function _alert(html, cb, fun) {
 | 
			
		||||
        cb_ok = cb_ng = cb;
 | 
			
		||||
        cb_up = fun;
 | 
			
		||||
        html += '<div id="modalb"><a href="#" id="modal-ok">OK</a></div>';
 | 
			
		||||
        r.show(html);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    r.confirm = function (html, cok, cng) {
 | 
			
		||||
    r.confirm = function (html, cok, cng, fun) {
 | 
			
		||||
        q.push(function () {
 | 
			
		||||
            _confirm(lf2br(html), cok, cng);
 | 
			
		||||
            _confirm(lf2br(html), cok, cng, fun);
 | 
			
		||||
        });
 | 
			
		||||
        next();
 | 
			
		||||
    }
 | 
			
		||||
    function _confirm(html, cok, cng) {
 | 
			
		||||
    function _confirm(html, cok, cng, fun) {
 | 
			
		||||
        cb_ok = cok;
 | 
			
		||||
        cb_ng = cng === undefined ? cok : null;
 | 
			
		||||
        html += '<div id="modalb"><a href="#" id="modal-ok">OK</a><a href="#" id="modal-ng">Cancel</a></div>';
 | 
			
		||||
        cb_up = fun;
 | 
			
		||||
        html += '<div id="modalb">' + ok_cancel + '</div>';
 | 
			
		||||
        r.show(html);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    r.prompt = function (html, v, cok, cng) {
 | 
			
		||||
    r.prompt = function (html, v, cok, cng, fun) {
 | 
			
		||||
        q.push(function () {
 | 
			
		||||
            _prompt(lf2br(html), v, cok, cng);
 | 
			
		||||
            _prompt(lf2br(html), v, cok, cng, fun);
 | 
			
		||||
        });
 | 
			
		||||
        next();
 | 
			
		||||
    }
 | 
			
		||||
    function _prompt(html, v, cok, cng) {
 | 
			
		||||
    function _prompt(html, v, cok, cng, fun) {
 | 
			
		||||
        cb_ok = cok;
 | 
			
		||||
        cb_ng = cng === undefined ? cok : null;
 | 
			
		||||
        html += '<input id="modali" type="text" /><div id="modalb"><a href="#" id="modal-ok">OK</a><a href="#" id="modal-ng">Cancel</a></div>';
 | 
			
		||||
        cb_up = fun;
 | 
			
		||||
        html += '<input id="modali" type="text" /><div id="modalb">' + ok_cancel + '</div>';
 | 
			
		||||
        r.show(html);
 | 
			
		||||
 | 
			
		||||
        ebi('modali').value = v || '';
 | 
			
		||||
@@ -976,9 +1025,69 @@ function winpopup(txt) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
var last_repl = null;
 | 
			
		||||
function repl_load() {
 | 
			
		||||
    var ipre = ebi('repl_pre'),
 | 
			
		||||
        tb = ebi('modali');
 | 
			
		||||
 | 
			
		||||
    function getpres() {
 | 
			
		||||
        var o, ret = jread("repl_pre", []);
 | 
			
		||||
        if (!ret.length)
 | 
			
		||||
            ret = [
 | 
			
		||||
                'var v=Object.keys(localStorage); v.sort(); JSON.stringify(v)',
 | 
			
		||||
                'console.hist.slice(-10).join("\\n")'
 | 
			
		||||
            ];
 | 
			
		||||
 | 
			
		||||
        ipre.innerHTML = '<option value=""></option>';
 | 
			
		||||
        for (var a = 0; a < ret.length; a++) {
 | 
			
		||||
            o = mknod('option');
 | 
			
		||||
            o.setAttribute('value', ret[a]);
 | 
			
		||||
            o.textContent = ret[a];
 | 
			
		||||
            ipre.appendChild(o);
 | 
			
		||||
        }
 | 
			
		||||
        last_repl = ipre.value = (last_repl || (ret.length ? ret.slice(-1)[0] : ''));
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
    ebi('repl_pdel').onclick = function (e) {
 | 
			
		||||
        var val = ipre.value,
 | 
			
		||||
            pres = getpres();
 | 
			
		||||
 | 
			
		||||
        apop(pres, val);
 | 
			
		||||
        jwrite('repl_pre', pres);
 | 
			
		||||
        getpres();
 | 
			
		||||
    };
 | 
			
		||||
    ebi('repl_pnew').onclick = function (e) {
 | 
			
		||||
        var val = tb.value,
 | 
			
		||||
            pres = getpres();
 | 
			
		||||
 | 
			
		||||
        apop(pres, ipre.value);
 | 
			
		||||
        pres.push(val);
 | 
			
		||||
        jwrite('repl_pre', pres);
 | 
			
		||||
        getpres();
 | 
			
		||||
        ipre.value = val;
 | 
			
		||||
    };
 | 
			
		||||
    ipre.oninput = ipre.onchange = function () {
 | 
			
		||||
        tb.value = last_repl = ipre.value;
 | 
			
		||||
    };
 | 
			
		||||
    tb.oninput = function () {
 | 
			
		||||
        last_repl = this.value;
 | 
			
		||||
    };
 | 
			
		||||
    getpres();
 | 
			
		||||
    tb.value = last_repl;
 | 
			
		||||
    setTimeout(function () {
 | 
			
		||||
        tb.setSelectionRange(0, tb.value.length, "forward");
 | 
			
		||||
    }, 10);
 | 
			
		||||
}
 | 
			
		||||
function repl(e) {
 | 
			
		||||
    ev(e);
 | 
			
		||||
    modal.prompt('js repl (prefix with <code>,</code> to allow raise)', 'var v=Object.keys(localStorage); v.sort(); JSON.stringify(v)', function (cmd) {
 | 
			
		||||
    var html = [
 | 
			
		||||
        '<p>js repl (prefix with <code>,</code> to allow raise)</p>',
 | 
			
		||||
        '<p><select id="repl_pre"></select>',
 | 
			
		||||
        '   <button id="repl_pdel">❌ del</button>',
 | 
			
		||||
        '   <button id="repl_pnew">💾 SAVE</button></p>'
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    modal.prompt(html.join(''), '', function (cmd) {
 | 
			
		||||
        if (!cmd)
 | 
			
		||||
            return toast.inf(3, 'eval aborted');
 | 
			
		||||
 | 
			
		||||
@@ -991,7 +1100,7 @@ function repl(e) {
 | 
			
		||||
        catch (ex) {
 | 
			
		||||
            modal.alert('<h6>exception</h6>' + esc(ex + ''));
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
    }, undefined, repl_load);
 | 
			
		||||
}
 | 
			
		||||
if (ebi('repl'))
 | 
			
		||||
    ebi('repl').onclick = repl;
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,9 @@
 | 
			
		||||
    /* adjust the button area a bit */
 | 
			
		||||
    #u2conf.has_btn {width: 35em !important; margin: 5em auto}
 | 
			
		||||
 | 
			
		||||
    /* a */
 | 
			
		||||
    #op_up2k {min-height: 0}
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
 | 
			
		||||
<a href="#" onclick="this.parentNode.innerHTML='';">show advanced options</a>
 | 
			
		||||
 
 | 
			
		||||
@@ -38,6 +38,7 @@ gtar=$(command -v gtar || command -v gnutar) || true
 | 
			
		||||
	find() { gfind "$@"; }
 | 
			
		||||
	sort() { gsort "$@"; }
 | 
			
		||||
	shuf() { gshuf "$@"; }
 | 
			
		||||
	nproc() { gnproc; }
 | 
			
		||||
	sha1sum() { shasum "$@"; }
 | 
			
		||||
	unexpand() { gunexpand "$@"; }
 | 
			
		||||
	command -v grealpath >/dev/null &&
 | 
			
		||||
@@ -145,6 +146,7 @@ tmpdir="$(
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ver=
 | 
			
		||||
[ -z "$repack" ] &&
 | 
			
		||||
git describe --tags >/dev/null 2>/dev/null && {
 | 
			
		||||
	git_ver="$(git describe --tags)";  # v0.5.5-2-gb164aa0
 | 
			
		||||
	ver="$(printf '%s\n' "$git_ver" | sed -r 's/^v//')";
 | 
			
		||||
@@ -225,7 +227,7 @@ done
 | 
			
		||||
	rm -rf copyparty/web/dd
 | 
			
		||||
	f=copyparty/web/browser.css
 | 
			
		||||
	gzip -d "$f"
 | 
			
		||||
	sed -r 's/(cursor: )url\([^)]+\), (pointer)/\1\2/; /[0-9]+% \{cursor:/d; /animation: cursor/d' <$f >t
 | 
			
		||||
	sed -r 's/(cursor: ?)url\([^)]+\), ?(pointer)/\1\2/; /[0-9]+% \{cursor:/d; /animation: ?cursor/d' <$f >t
 | 
			
		||||
	tmv "$f"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -263,14 +265,27 @@ done
 | 
			
		||||
 | 
			
		||||
gzres() {
 | 
			
		||||
	command -v pigz &&
 | 
			
		||||
		pk='pigz -11 -I 256' ||
 | 
			
		||||
		pk='pigz -11 -I 2560' ||
 | 
			
		||||
		pk='gzip'
 | 
			
		||||
 | 
			
		||||
	echo "$pk"
 | 
			
		||||
	find | grep -E '\.(js|css)$' | grep -vF /deps/ | while IFS= read -r f; do
 | 
			
		||||
	np=$(nproc)
 | 
			
		||||
	echo "$pk #$np"
 | 
			
		||||
 | 
			
		||||
	while IFS=' ' read -r _ f; do
 | 
			
		||||
		while true; do
 | 
			
		||||
			na=$(ps auxwww | grep -F "$pk" | wc -l)
 | 
			
		||||
			[ $na -le $np ] && break
 | 
			
		||||
			sleep 0.2
 | 
			
		||||
		done
 | 
			
		||||
		echo -n .
 | 
			
		||||
		$pk "$f"
 | 
			
		||||
	done
 | 
			
		||||
		$pk "$f" &
 | 
			
		||||
	done < <(
 | 
			
		||||
		find -printf '%s %p\n' |
 | 
			
		||||
		grep -E '\.(js|css)$' |
 | 
			
		||||
		grep -vF /deps/ |
 | 
			
		||||
		sort -nr
 | 
			
		||||
	)
 | 
			
		||||
	wait
 | 
			
		||||
	echo
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user