Compare commits

...

13 Commits

Author SHA1 Message Date
ed
bd49979f4a v0.11.29 2021-06-30 01:51:57 +02:00
ed
7e606cdd9f make search rate-control less visually confusing 2021-06-30 01:44:25 +02:00
ed
8b4b7fa794 allow opening tree nodes in a new tab 2021-06-30 01:08:20 +02:00
ed
05345ddf8b add per-connection request counting 2021-06-30 01:00:00 +02:00
ed
66adb470ad optional progressbar tint 2021-06-30 00:55:57 +02:00
ed
e15c8fd146 add upload pause 2021-06-30 00:34:33 +02:00
ed
0f09b98a39 scan for additional folder thumbnails 2021-06-30 00:19:39 +02:00
ed
b4d6f4e24d american-friendly upload limits (allow additional bypass using manual text entry) 2021-06-30 00:11:23 +02:00
ed
3217fa625b more todo 2021-06-29 23:59:15 +02:00
ed
e719ff8a47 make sfx kipu-proof 2021-06-29 23:53:57 +02:00
ed
9fcf528d45 update readme 2021-06-29 23:32:21 +02:00
ed
1ddbf5a158 update todo 2021-06-29 23:00:28 +02:00
ed
64bf4574b0 add todo maybe 2021-06-28 20:38:59 +02:00
12 changed files with 91 additions and 23 deletions

View File

@@ -154,6 +154,8 @@ summary: all planned features work! now please enjoy the bloatening
* all volumes must exist / be available on startup; up2k (mtp especially) gets funky otherwise * all volumes must exist / be available on startup; up2k (mtp especially) gets funky otherwise
* cannot mount something at `/d1/d2/d3` unless `d2` exists inside `d1` * cannot mount something at `/d1/d2/d3` unless `d2` exists inside `d1`
* dupe files will not have metadata (audio tags etc) displayed in the file listing
* because they don't get `up` entries in the db (probably best fix) and `tx_browser` does not `lstat`
* probably more, pls let me know * probably more, pls let me know
## not my bugs ## not my bugs
@@ -613,13 +615,14 @@ in the `scripts` folder:
roughly sorted by priority roughly sorted by priority
* readme.md as epilogue * readme.md as epilogue
* single sha512 across all up2k chunks? maybe
* reduce up2k roundtrips * reduce up2k roundtrips
* start from a chunk index and just go * start from a chunk index and just go
* terminate client on bad data * terminate client on bad data
discarded ideas discarded ideas
* single sha512 across all up2k chunks?
* crypto.subtle cannot into streaming, would have to use hashwasm, expensive
* separate sqlite table per tag * separate sqlite table per tag
* performance fixed by skipping some indexes (`+mt.k`) * performance fixed by skipping some indexes (`+mt.k`)
* audio fingerprinting * audio fingerprinting

View File

@@ -305,6 +305,7 @@ def run_argparse(argv, formatter):
ap2.add_argument("--th-poke", metavar="SEC", type=int, default=300, help="activity labeling cooldown") ap2.add_argument("--th-poke", metavar="SEC", type=int, default=300, help="activity labeling cooldown")
ap2.add_argument("--th-clean", metavar="SEC", type=int, default=43200, help="cleanup interval") ap2.add_argument("--th-clean", metavar="SEC", type=int, default=43200, help="cleanup interval")
ap2.add_argument("--th-maxage", metavar="SEC", type=int, default=604800, help="max folder age") ap2.add_argument("--th-maxage", metavar="SEC", type=int, default=604800, help="max folder age")
ap2.add_argument("--th-covers", metavar="N,N", type=str, default="folder.png,folder.jpg,cover.png,cover.jpg", help="folder thumbnails to stat for")
ap2 = ap.add_argument_group('database options') ap2 = ap.add_argument_group('database options')
ap2.add_argument("-e2d", action="store_true", help="enable up2k database") ap2.add_argument("-e2d", action="store_true", help="enable up2k database")

View File

@@ -1,8 +1,8 @@
# coding: utf-8 # coding: utf-8
VERSION = (0, 11, 28) VERSION = (0, 11, 29)
CODENAME = "the grid" CODENAME = "the grid"
BUILD_DT = (2021, 6, 28) BUILD_DT = (2021, 6, 30)
S_VERSION = ".".join(map(str, VERSION)) S_VERSION = ".".join(map(str, VERSION))
S_BUILD_DT = "{0:04d}-{1:02d}-{2:02d}".format(*BUILD_DT) S_BUILD_DT = "{0:04d}-{1:02d}-{2:02d}".format(*BUILD_DT)

View File

@@ -499,7 +499,7 @@ class HttpCli(object):
spd1 = get_spd(nbytes, self.t0) spd1 = get_spd(nbytes, self.t0)
spd2 = get_spd(self.conn.nbyte, self.conn.t0) spd2 = get_spd(self.conn.nbyte, self.conn.t0)
return spd1 + " " + spd2 return "{} {} n{}".format(spd1, spd2, self.conn.nreq)
def handle_post_multipart(self): def handle_post_multipart(self):
self.parser = MultipartParser(self.log, self.sr, self.headers) self.parser = MultipartParser(self.log, self.sr, self.headers)
@@ -1562,7 +1562,7 @@ class HttpCli(object):
th_fmt = self.uparam.get("th") th_fmt = self.uparam.get("th")
if th_fmt is not None: if th_fmt is not None:
if is_dir: if is_dir:
for fn in ["folder.png", "folder.jpg"]: for fn in self.args.th_covers.split(","):
fp = os.path.join(abspath, fn) fp = os.path.join(abspath, fn)
if os.path.exists(fp): if os.path.exists(fp):
vrem = "{}/{}".format(vrem.rstrip("/"), fn) vrem = "{}/{}".format(vrem.rstrip("/"), fn)

View File

@@ -43,6 +43,7 @@ class HttpConn(object):
self.t0 = time.time() self.t0 = time.time()
self.stopping = False self.stopping = False
self.nreq = 0
self.nbyte = 0 self.nbyte = 0
self.workload = 0 self.workload = 0
self.u2idx = None self.u2idx = None
@@ -188,6 +189,7 @@ class HttpConn(object):
if self.workload >= 2 ** 31: if self.workload >= 2 ** 31:
self.workload = 100 self.workload = 100
self.nreq += 1
cli = HttpCli(self) cli = HttpCli(self)
if not cli.run(): if not cli.run():
return return

View File

@@ -119,7 +119,7 @@ window.baguetteBox = (function () {
var gallery = []; var gallery = [];
[].forEach.call(tagsNodeList, function (imageElement, imageIndex) { [].forEach.call(tagsNodeList, function (imageElement, imageIndex) {
var imageElementClickHandler = function (event) { var imageElementClickHandler = function (event) {
if (event && event.ctrlKey) if (event && (event.ctrlKey || event.metaKey))
return true; return true;
event.preventDefault ? event.preventDefault() : event.returnValue = false; event.preventDefault ? event.preventDefault() : event.returnValue = false;

View File

@@ -607,7 +607,7 @@ input.eq_gain {
#srch_q { #srch_q {
white-space: pre; white-space: pre;
color: #f80; color: #f80;
height: 1em; min-height: 1em;
margin: .2em 0 -1em 1.6em; margin: .2em 0 -1em 1.6em;
} }
#tq_raw { #tq_raw {

View File

@@ -78,7 +78,7 @@ ebi('op_up2k').innerHTML = (
' <tr>\n' + ' <tr>\n' +
' <td>\n' + ' <td>\n' +
' <a href="#" id="nthread_sub">&ndash;</a><input\n' + ' <a href="#" id="nthread_sub">&ndash;</a><input\n' +
' class="txtbox" id="nthread" value="2"/><a\n' + ' class="txtbox" id="nthread" value="2" tt="pause uploads by setting it to 0"/><a\n' +
' href="#" id="nthread_add">+</a><br />&nbsp;\n' + ' href="#" id="nthread_add">+</a><br />&nbsp;\n' +
' </td>\n' + ' </td>\n' +
' </tr>\n' + ' </tr>\n' +
@@ -237,6 +237,10 @@ var mpl = (function () {
'<a href="#" class="tgl btn" tt="load the next folder and continue">📂 next-folder</a>' + '<a href="#" class="tgl btn" tt="load the next folder and continue">📂 next-folder</a>' +
'</div></div>' + '</div></div>' +
'<div><h3>tint</h3><div>' +
'<input type="text" id="pb_tint" size="3" value="0" tt="background level (0-100) on the seekbar$Nto make buffering less distracting" />' +
'</div></div>' +
'<div><h3>audio equalizer</h3><div id="audio_eq"></div></div>'); '<div><h3>audio equalizer</h3><div id="audio_eq"></div></div>');
var r = { var r = {
@@ -290,6 +294,19 @@ var mpl = (function () {
draw_pb_mode(); draw_pb_mode();
} }
function set_tint() {
var tint = icfg_get('pb_tint', 0);
if (!tint)
ebi('barbuf').style.removeProperty('background');
else
ebi('barbuf').style.background = 'rgba(126,163,75,' + (tint / 100.0) + ')';
}
ebi('pb_tint').oninput = function (e) {
swrite('pb_tint', this.value);
set_tint();
};
set_tint();
r.pp = function () { r.pp = function () {
if (!r.os_ctl) if (!r.os_ctl)
return; return;
@@ -1528,7 +1545,7 @@ var thegrid = (function () {
setsz(); setsz();
function gclick(e) { function gclick(e) {
if (e && e.ctrlKey) if (e && (e.ctrlKey || e.metaKey))
return true; return true;
var oth = ebi(this.getAttribute('ref')), var oth = ebi(this.getAttribute('ref')),
@@ -1862,6 +1879,7 @@ document.onkeydown = function (e) {
} }
var search_timeout, var search_timeout,
defer_timeout,
search_in_progress = 0; search_in_progress = 0;
function ev_search_input() { function ev_search_input() {
@@ -1876,10 +1894,30 @@ document.onkeydown = function (e) {
if (id != "q_raw") if (id != "q_raw")
encode_query(); encode_query();
set_vq();
clearTimeout(defer_timeout);
defer_timeout = setTimeout(try_search, 2000);
try_search();
}
function try_search() {
if (Date.now() - search_in_progress > 30 * 1000) {
clearTimeout(defer_timeout);
clearTimeout(search_timeout); clearTimeout(search_timeout);
if (Date.now() - search_in_progress > 30 * 1000)
search_timeout = setTimeout(do_search, 200); search_timeout = setTimeout(do_search, 200);
} }
}
function set_vq() {
if (search_in_progress)
return;
var q = ebi('q_raw').value,
vq = ebi('files').getAttribute('q_raw');
srch_msg(false, (q == vq) ? '' : 'search results below are from a previous query:\n ' + (vq ? vq : '(*)'));
}
function encode_query() { function encode_query() {
var q = ''; var q = '';
@@ -1948,7 +1986,8 @@ document.onkeydown = function (e) {
xhr.setRequestHeader('Content-Type', 'text/plain'); xhr.setRequestHeader('Content-Type', 'text/plain');
xhr.onreadystatechange = xhr_search_results; xhr.onreadystatechange = xhr_search_results;
xhr.ts = Date.now(); xhr.ts = Date.now();
xhr.send(JSON.stringify({ "q": ebi('q_raw').value })); xhr.q_raw = ebi('q_raw').value;
xhr.send(JSON.stringify({ "q": xhr.q_raw }));
} }
function xhr_search_results() { function xhr_search_results() {
@@ -2019,6 +2058,8 @@ document.onkeydown = function (e) {
ofiles.innerHTML = html.join('\n'); ofiles.innerHTML = html.join('\n');
ofiles.setAttribute("ts", this.ts); ofiles.setAttribute("ts", this.ts);
ofiles.setAttribute("q_raw", this.q_raw);
set_vq();
mukey.render(); mukey.render();
reload_browser(); reload_browser();
filecols.set_style(['File Name']); filecols.set_style(['File Name']);
@@ -2030,6 +2071,7 @@ document.onkeydown = function (e) {
ev(e); ev(e);
treectl.show(); treectl.show();
ebi('files').innerHTML = orig_html; ebi('files').innerHTML = orig_html;
ebi('files').removeAttribute('q_raw');
orig_html = null; orig_html = null;
msel.render(); msel.render();
reload_browser(); reload_browser();
@@ -2248,6 +2290,9 @@ var treectl = (function () {
} }
function treego(e) { function treego(e) {
if (e && (e.ctrlKey || e.metaKey))
return true;
ev(e); ev(e);
if (this.getAttribute('class') == 'hl' && if (this.getAttribute('class') == 'hl' &&
this.previousSibling.textContent == '-') { this.previousSibling.textContent == '-') {

View File

@@ -1,7 +1,5 @@
"use strict"; "use strict";
window.onerror = vis_exh;
function goto_up2k() { function goto_up2k() {
if (up2k === false) if (up2k === false)
@@ -1309,6 +1307,17 @@ function up2k_init(subtle) {
} }
tt.init(); tt.init();
function bumpthread2(e) {
if (e.ctrlKey || e.altKey || e.metaKey || e.isComposing)
return;
if (e.code == 'ArrowUp')
bumpthread(1);
if (e.code == 'ArrowDown')
bumpthread(-1);
}
function bumpthread(dir) { function bumpthread(dir) {
try { try {
dir.stopPropagation(); dir.stopPropagation();
@@ -1319,7 +1328,7 @@ function up2k_init(subtle) {
if (dir.target) { if (dir.target) {
clmod(obj, 'err', 1); clmod(obj, 'err', 1);
var v = Math.floor(parseInt(obj.value)); var v = Math.floor(parseInt(obj.value));
if (v < 1 || v > 8 || v !== v) if (v < 0 || v > 64 || v !== v)
return; return;
parallel_uploads = v; parallel_uploads = v;
@@ -1330,11 +1339,11 @@ function up2k_init(subtle) {
parallel_uploads += dir; parallel_uploads += dir;
if (parallel_uploads < 1) if (parallel_uploads < 0)
parallel_uploads = 1; parallel_uploads = 0;
if (parallel_uploads > 8) if (parallel_uploads > 16)
parallel_uploads = 8; parallel_uploads = 16;
obj.value = parallel_uploads; obj.value = parallel_uploads;
bumpthread({ "target": 1 }) bumpthread({ "target": 1 })
@@ -1430,6 +1439,7 @@ function up2k_init(subtle) {
bumpthread(-1); bumpthread(-1);
}; };
ebi('nthread').onkeydown = bumpthread2;
ebi('nthread').addEventListener('input', bumpthread, false); ebi('nthread').addEventListener('input', bumpthread, false);
ebi('multitask').addEventListener('click', tgl_multitask, false); ebi('multitask').addEventListener('click', tgl_multitask, false);
ebi('ask_up').addEventListener('click', tgl_ask_up, false); ebi('ask_up').addEventListener('click', tgl_ask_up, false);
@@ -1443,7 +1453,10 @@ function up2k_init(subtle) {
nodes[a].addEventListener('touchend', nop, false); nodes[a].addEventListener('touchend', nop, false);
set_fsearch(); set_fsearch();
bumpthread({ "target": 1 }) bumpthread({ "target": 1 });
if (parallel_uploads < 1)
bumpthread(1);
return { "init_deps": init_deps, "set_fsearch": set_fsearch } return { "init_deps": init_deps, "set_fsearch": set_fsearch }
} }

View File

@@ -32,6 +32,9 @@ function esc(txt) {
}); });
} }
function vis_exh(msg, url, lineNo, columnNo, error) { function vis_exh(msg, url, lineNo, columnNo, error) {
if (!window.onerror)
return;
window.onerror = undefined; window.onerror = undefined;
window['vis_exh'] = null; window['vis_exh'] = null;
var html = ['<h1>you hit a bug!</h1><p>please screenshot this error and send me a copy arigathanks gozaimuch (ed/irc.rizon.net or ed#2644)</p><p>', var html = ['<h1>you hit a bug!</h1><p>please screenshot this error and send me a copy arigathanks gozaimuch (ed/irc.rizon.net or ed#2644)</p><p>',

View File

@@ -6,10 +6,10 @@ import re, os, sys, time, shutil, signal, threading, tarfile, hashlib, platform,
import subprocess as sp import subprocess as sp
""" """
run me with any version of python, i will unpack and run copyparty pls don't edit this file with a text editor,
it breaks the compressed stuff at the end
(but please don't edit this file with a text editor run me with any version of python, i will unpack and run copyparty
since that would probably corrupt the binary stuff at the end)
there's zero binaries! just plaintext python scripts all the way down there's zero binaries! just plaintext python scripts all the way down
so you can easily unpack the archive and inspect it for shady stuff so you can easily unpack the archive and inspect it for shady stuff

View File

@@ -121,6 +121,7 @@ class VHttpConn(object):
self.log_src = "a" self.log_src = "a"
self.lf_url = None self.lf_url = None
self.hsrv = VHttpSrv() self.hsrv = VHttpSrv()
self.nreq = 0
self.nbyte = 0 self.nbyte = 0
self.workload = 0 self.workload = 0
self.ico = None self.ico = None