mirror of
https://github.com/9001/copyparty.git
synced 2025-11-09 16:15:58 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd49979f4a | ||
|
|
7e606cdd9f | ||
|
|
8b4b7fa794 | ||
|
|
05345ddf8b | ||
|
|
66adb470ad | ||
|
|
e15c8fd146 | ||
|
|
0f09b98a39 | ||
|
|
b4d6f4e24d | ||
|
|
3217fa625b | ||
|
|
e719ff8a47 | ||
|
|
9fcf528d45 | ||
|
|
1ddbf5a158 | ||
|
|
64bf4574b0 |
@@ -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
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ ebi('op_up2k').innerHTML = (
|
|||||||
' <tr>\n' +
|
' <tr>\n' +
|
||||||
' <td>\n' +
|
' <td>\n' +
|
||||||
' <a href="#" id="nthread_sub">–</a><input\n' +
|
' <a href="#" id="nthread_sub">–</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 /> \n' +
|
' href="#" id="nthread_add">+</a><br /> \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 == '-') {
|
||||||
|
|||||||
@@ -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 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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>',
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user