Compare commits

...

8 Commits

Author SHA1 Message Date
ed
5bb0e7e8b3 v1.0.4 2021-09-19 00:41:56 +02:00
ed
b78d207121 encourage statics caching 2021-09-19 00:36:48 +02:00
ed
0fcbcdd08c correctly ordered folders in initial listing 2021-09-19 00:08:29 +02:00
ed
ed6c683922 cosmetic 2021-09-19 00:07:49 +02:00
ed
9fe1edb02b support multiple volume flags in one group 2021-09-18 23:45:43 +02:00
ed
fb3811a708 bunch of filekey fixes 2021-09-18 23:44:44 +02:00
ed
18f8658eec insufficient navpane minsize 2021-09-18 18:55:19 +02:00
ed
3ead4676b0 add release script 2021-09-18 18:43:55 +02:00
15 changed files with 108 additions and 41 deletions

View File

@@ -583,12 +583,12 @@ through arguments:
* `-e2tsr` also deletes all existing tags, doing a full reindex
the same arguments can be set as volume flags, in addition to `d2d` and `d2t` for disabling:
* `-v ~/music::r:c,e2dsa:c,e2tsr` does a full reindex of everything on startup
* `-v ~/music::r:c,e2dsa,e2tsr` does a full reindex of everything on startup
* `-v ~/music::r:c,d2d` disables **all** indexing, even if any `-e2*` are on
* `-v ~/music::r:c,d2t` disables all `-e2t*` (tags), does not affect `-e2d*`
note:
* the parser currently can't handle `c,e2dsa,e2tsr` so you have to `c,e2dsa:c,e2tsr`
* the parser can finally handle `c,e2dsa,e2tsr` so you no longer have to `c,e2dsa:c,e2tsr`
* `e2tsr` is probably always overkill, since `e2ds`/`e2dsa` would pick up any file modifications and `e2ts` would then reindex those, unless there is a new copyparty version with new parsers and the release note says otherwise
* the rescan button in the admin panel has no effect unless the volume has `-e2ds` or higher
@@ -746,7 +746,7 @@ quick summary of more eccentric web-browsers trying to view a directory index:
| **w3m** (0.5.3/macports) | can browse, login, upload at 100kB/s, mkdir/msg |
| **netsurf** (3.10/arch) | is basically ie6 with much better css (javascript has almost no effect) |
| **opera** (11.60/winxp) | OK: thumbnails, image-viewer, zip-selection, rename/cut/paste. NG: up2k, navpane, markdown, audio |
| **ie4** and **netscape** 4.0 | can browse (text is yellow on white), upload with `?b=u` |
| **ie4** and **netscape** 4.0 | can browse, upload with `?b=u` |
| **SerenityOS** (7e98457) | hits a page fault, works with `?b=u`, file upload not-impl |

View File

@@ -6,7 +6,7 @@ application/x-www-form-urlencoded (for example using the
message/pager function on the website)
example copyparty config to use this:
--urlform save,get -vsrv/wget:wget:rwmd,ed:c,e2ts:c,mtp=title=ebin,t300,ad,bin/mtag/wget.py
--urlform save,get -vsrv/wget:wget:rwmd,ed:c,e2ts,mtp=title=ebin,t300,ad,bin/mtag/wget.py
explained:
for realpath srv/wget (served at /wget) with read-write-modify-delete for ed,

View File

@@ -17,7 +17,7 @@ it's probably best to use this through a config file; see res/yt-ipr.conf
but if you want to use plain arguments instead then:
-v srv/ytm:ytm:w:rw,ed
:c,e2ts:c,e2dsa
:c,e2ts,e2dsa
:c,sz=16k-1m:c,maxn=10,300:c,rotf=%Y-%m/%d-%H
:c,mtp=yt-id,yt-title,yt-author,yt-channel,yt-views,yt-private,yt-manifest,yt-expires=bin/mtag/yt-ipr.py
:c,mte=yt-id,yt-title,yt-author,yt-channel,yt-views,yt-private,yt-manifest,yt-expires

View File

@@ -1,8 +1,8 @@
# coding: utf-8
VERSION = (1, 0, 3)
VERSION = (1, 0, 4)
CODENAME = "sufficient"
BUILD_DT = (2021, 9, 18)
BUILD_DT = (2021, 9, 19)
S_VERSION = ".".join(map(str, VERSION))
S_BUILD_DT = "{0:04d}-{1:02d}-{2:02d}".format(*BUILD_DT)

View File

@@ -579,9 +579,17 @@ class AuthSrv(object):
raise Exception("invalid volume flag: {},{}".format(lvl, uname))
if lvl == "c":
cval = True
if "=" in uname:
try:
# volume flag with arguments, possibly with a preceding list of bools
uname, cval = uname.split("=", 1)
except:
# just one or more bools
cval = True
while "," in uname:
# one or more bools before the final flag; eat them
n1, uname = uname.split(",", 1)
self._read_volflag(flags, n1, True, False)
self._read_volflag(flags, uname, cval, False)
return

View File

@@ -12,6 +12,7 @@ import string
import socket
import ctypes
from datetime import datetime
from operator import itemgetter
import calendar
try:
@@ -1404,10 +1405,12 @@ class HttpCli(object):
#
# send reply
if not is_compressed and "cache" not in self.uparam:
self.out_headers.update(NO_CACHE)
if is_compressed:
self.out_headers["Cache-Control"] = "max-age=573"
elif "cache" in self.uparam:
self.out_headers["Cache-Control"] = "max-age=69"
else:
self.out_headers.pop("Cache-Control")
self.out_headers.update(NO_CACHE)
self.out_headers["Accept-Ranges"] = "bytes"
self.send_headers(
@@ -1533,6 +1536,10 @@ class HttpCli(object):
def tx_md(self, fs_path):
logmsg = "{:4} {} ".format("", self.req)
if not self.can_write:
if "edit" in self.uparam or "edit2" in self.uparam:
return self.tx_404()
tpl = "mde" if "edit2" in self.uparam else "md"
html_path = os.path.join(E.mod, "web", "{}.html".format(tpl))
template = self.j2(tpl)
@@ -1555,6 +1562,10 @@ class HttpCli(object):
self.out_headers.update(NO_CACHE)
status = 200 if do_send else 304
arg_base = "?"
if "k" in self.uparam:
arg_base = "?k={}&".format(self.uparam["k"])
boundary = "\roll\tide"
targs = {
"edit": "edit" in self.uparam,
@@ -1564,6 +1575,7 @@ class HttpCli(object):
"md_chk_rate": self.args.mcr,
"md": boundary,
"ts": self.conn.hsrv.cachebuster(),
"arg_base": arg_base,
}
html = template.render(**targs).encode("utf-8", "replace")
html = html.split(boundary.encode("utf-8"))
@@ -2141,6 +2153,11 @@ class HttpCli(object):
self.reply(ret.encode("utf-8", "replace"), mime="application/json")
return True
for d in dirs:
d["name"] += "/"
dirs.sort(key=itemgetter("name"))
j2a["files"] = dirs + files
j2a["logues"] = logues
j2a["taglist"] = taglist

View File

@@ -703,7 +703,6 @@ input.eq_gain {
left: 0;
bottom: 0;
top: 7em;
width: var(--nav-sz);
overflow-x: hidden;
overflow-y: auto;
-ms-scroll-chaining: none;

View File

@@ -368,7 +368,7 @@ var mpl = (function () {
for (var a = 0, aa = files.length; a < aa; a++) {
if (/^(cover|folder)\.(jpe?g|png|gif)$/.test(files[a].textContent)) {
cover = files[a].getAttribute('href');
cover = noq_href(files[a]);
break;
}
}
@@ -427,7 +427,7 @@ function MPlayer() {
link = tds[1].getElementsByTagName('a');
link = link[link.length - 1];
var url = link.getAttribute('href'),
var url = noq_href(link),
m = re_audio.exec(url);
if (m) {
@@ -2157,7 +2157,7 @@ var fileman = (function () {
links = QSA('#files tbody td:nth-child(2) a');
for (var a = 0, aa = links.length; a < aa; a++)
indir.push(vsplit(links[a].getAttribute('href'))[1]);
indir.push(vsplit(noq_href(links[a]))[1]);
for (var a = 0; a < r.clip.length; a++) {
var found = false;
@@ -2350,7 +2350,7 @@ var thegrid = (function () {
return true;
var oth = ebi(this.getAttribute('ref')),
href = this.getAttribute('href'),
href = noq_href(this),
aplay = ebi('a' + oth.getAttribute('id')),
is_img = /\.(gif|jpe?g|png|webp|webm|mp4)(\?|$)/i.test(href),
in_tree = null,
@@ -2358,7 +2358,7 @@ var thegrid = (function () {
td = oth.closest('td').nextSibling,
tr = td.parentNode;
if (/\/(\?|$)/.test(href)) {
if (href.endsWith('/')) {
var ta = QSA('#treeul a.hl+ul>li>a+a'),
txt = oth.textContent.slice(0, -1);
@@ -2397,7 +2397,7 @@ var thegrid = (function () {
var tr = ebi(ths[a].getAttribute('ref')).closest('tr'),
cl = tr.getAttribute('class') || '';
if (ths[a].getAttribute('href').endsWith('/'))
if (noq_href(ths[a]).endsWith('/'))
cl += ' dir';
ths[a].setAttribute('class', cl);
@@ -2461,15 +2461,16 @@ var thegrid = (function () {
var files = QSA('#files>tbody>tr>td:nth-child(2) a[id]');
for (var a = 0, aa = files.length; a < aa; a++) {
var ao = files[a],
href = esc(ao.getAttribute('href')),
ohref = esc(ao.getAttribute('href')),
href = ohref.split('?')[0],
name = uricom_dec(vsplit(href)[1])[0],
ref = ao.getAttribute('id'),
isdir = href.split('?')[0].slice(-1)[0] == '/',
isdir = href.endsWith('/'),
ac = isdir ? ' class="dir"' : '',
ihref = href;
if (r.thumbs) {
ihref += (ihref.indexOf('?') === -1 ? '?' : '&') + 'th=' + (have_webp ? 'w' : 'j');
ihref += '?th=' + (have_webp ? 'w' : 'j');
if (href == "#")
ihref = '/.cpr/ico/⏏️';
}
@@ -2477,7 +2478,7 @@ var thegrid = (function () {
ihref = '/.cpr/ico/folder';
}
else {
var ar = href.split('?')[0].split('.');
var ar = href.split('.');
if (ar.length > 1)
ar = ar.slice(1);
@@ -2495,7 +2496,7 @@ var thegrid = (function () {
ihref = '/.cpr/ico/' + ihref.slice(0, -1);
}
html.push('<a href="' + href + '" ref="' + ref +
html.push('<a href="' + ohref + '" ref="' + ref +
'"' + ac + ' ttt="' + esc(name) + '"><img src="' +
ihref + '" /><span' + ac + '>' + ao.innerHTML + '</span></a>');
}
@@ -3015,7 +3016,7 @@ var treectl = (function () {
prev_atop = null,
prev_winh = null,
mentered = null,
treesz = clamp(icfg_get('treesz', 16), 4, 50);
treesz = clamp(icfg_get('treesz', 16), 10, 50);
bcfg_bind(treectl, 'ireadme', 'ireadme', true);
bcfg_bind(treectl, 'dyn', 'dyntree', true, onresize);
@@ -3126,7 +3127,7 @@ var treectl = (function () {
return;
var q = '#tree',
nq = 0;
nq = -3;
while (treectl.dyn) {
nq++;
@@ -3134,13 +3135,12 @@ var treectl = (function () {
if (!QS(q))
break;
}
var w = (treesz + nq) + 'em';
var w = (treesz + Math.max(0, nq)) + 'em';
try {
document.documentElement.style.setProperty('--nav-sz', w);
}
catch (ex) {
ebi('tree').style.width = w;
}
catch (ex) { }
ebi('tree').style.width = w;
ebi('wrap').style.marginLeft = w;
onscroll();
}
@@ -3434,6 +3434,7 @@ var treectl = (function () {
if (isNaN(treesz))
treesz = 16;
treesz = clamp(treesz, 2, 120);
swrite('treesz', treesz);
onresize();
}
@@ -3982,7 +3983,7 @@ var msel = (function () {
vbase = get_evpath();
for (var a = 0, aa = links.length; a < aa; a++) {
var href = links[a].getAttribute('href').replace(/\/$/, ""),
var href = noq_href(links[a]).replace(/\/$/, ""),
item = {};
item.id = links[a].getAttribute('id');
@@ -4128,8 +4129,8 @@ if (readme)
for (var a = 0; a < tr.length; a++) {
var td = tr[a].cells[1],
ao = td.firstChild,
href = ao.getAttribute('href'),
isdir = href.split('?')[0].slice(-1)[0] == '/',
href = noq_href(ao),
isdir = href.endsWith('/'),
txt = ao.textContent;
td.setAttribute('sortv', (isdir ? '\t' : '') + txt);

View File

@@ -15,7 +15,7 @@
<a id="lightswitch" href="#">go dark</a>
<a id="navtoggle" href="#">hide nav</a>
{%- if edit %}
<a id="save" href="?edit" tt="Hotkey: ctrl-s">save</a>
<a id="save" href="{{ arg_base }}edit" tt="Hotkey: ctrl-s">save</a>
<a id="sbs" href="#" tt="editor and preview side by side">sbs</a>
<a id="nsbs" href="#" tt="switch between editor and preview$NHotkey: ctrl-e">editor</a>
<div id="toolsbox">
@@ -28,9 +28,9 @@
</div>
<span id="lno">L#</span>
{%- else %}
<a href="?edit" tt="good: higher performance$Ngood: same document width as viewer$Nbad: assumes you know markdown">edit (basic)</a>
<a href="?edit2" tt="not in-house so probably less buggy">edit (fancy)</a>
<a href="?raw">view raw</a>
<a href="{{ arg_base }}edit" tt="good: higher performance$Ngood: same document width as viewer$Nbad: assumes you know markdown">edit (basic)</a>
<a href="{{ arg_base }}edit2" tt="not in-house so probably less buggy">edit (fancy)</a>
<a href="{{ arg_base }}raw">view raw</a>
{%- endif %}
</div>
<div id="toc"></div>

View File

@@ -83,8 +83,8 @@ html.dark a {
}
html.dark input {
color: #fff;
background: #624;
border: 1px solid #c27;
background: #626;
border: 1px solid #c2c;
border-width: 1px 0 0 0;
border-radius: .5em;
padding: .5em .7em;

View File

@@ -1,5 +1,6 @@
@font-face {
font-family: 'scp';
font-display: swap;
src: local('Source Code Pro Regular'), local('SourceCodePro-Regular'), url(/.cpr/deps/scp.woff2) format('woff2');
}
html {

View File

@@ -494,6 +494,11 @@ function get_vpath() {
}
function noq_href(el) {
return el.getAttribute('href').split('?')[0];
}
function get_pwd() {
var pwd = ('; ' + document.cookie).split('; cppwd=');
if (pwd.length < 2)

View File

@@ -47,5 +47,5 @@ c e2d
c nodupe
# this entire config file can be replaced with these arguments:
# -u ed:123 -u k:k -v .::r:a,ed -v priv:priv:r,k:rw,ed -v /home/ed/Music:music:r -v /home/ed/inc:dump:w:c,e2d:c,nodupe
# -u ed:123 -u k:k -v .::r:a,ed -v priv:priv:r,k:rw,ed -v /home/ed/Music:music:r -v /home/ed/inc:dump:w:c,e2d,nodupe
# but note that the config file always wins in case of conflicts

36
scripts/rls.sh Executable file
View File

@@ -0,0 +1,36 @@
#!/bin/bash
set -e
cd ~/dev/copyparty/scripts
v=$1
printf '%s\n' "$v" | grep -qE '^[0-9\.]+$' || exit 1
grep -E "(${v//./, })" ../copyparty/__version__.py || exit 1
git tag v$v
git push origin --tags
rm -rf ../dist
./make-pypi-release.sh u
(cd .. && python3 ./setup.py clean2)
./make-tgz-release.sh $v
rm -f ../dist/copyparty-sfx.*
./make-sfx.sh no-sh
../dist/copyparty-sfx.py -h
ar=
while true; do
for ((a=0; a<100; a++)); do
for f in ../dist/copyparty-sfx.{py,sh}; do
[ -e $f ] || continue;
mv $f $f.$(wc -c <$f | awk '{print$1}')
done
./make-sfx.sh re $ar
done
ar=no-sh
done
# git tag -d v$v; git push --delete origin v$v

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# coding: utf-8
from __future__ import print_function