Compare commits

...

27 commits

Author SHA1 Message Date
ed fb9f0441c9 fix possible deadlock on shutdown;
if a ?tar=w is hammering the thumbnailer queue on shutdown, give up
issuing sentinels (the workers will see !!stopping and abort anyways)
2025-11-23 21:45:03 +09:00
ed a359b89edd support thumbnail pregen for all output formats 2025-11-23 21:43:55 +09:00
Habetdin 77f74ddb2f
fix ongoing-xfer links in controlpanel (#977)
when viewing the controlpanel from a path other than the webroot,
the links to ongoing transfers were invalid
2025-11-19 16:52:31 +01:00
ed f7e7b03f6f reduce redirect delay 2025-11-20 00:48:34 +09:00
ed 7a291403ca contextual login caption; closes #1012 2025-11-20 00:46:19 +09:00
ed b427d7802a metrics: allow list of users 2025-11-20 00:37:36 +09:00
ed c424a55d6f more hints for invalid config 2025-11-20 00:26:44 +09:00
ed 7d62335c13 repurpose new-md to new-textfile 2025-11-20 00:24:28 +09:00
ed 9385daeae8 fix pypi packaging; closes #1003 2025-11-19 23:49:23 +09:00
ed 79e1078671 panic if unknown users in ipu; closes #959 2025-11-19 23:28:39 +09:00
ed cad15fbf60 warn against changing -j 2025-11-19 23:26:19 +09:00
Robert Ismo 9f08efcabd
inverse unix philosophy (#994)
Signed-off-by: Robert Ismo <robertismo@protonmail.com>
Signed-off-by: ed <s@ocv.me>
Co-authored-by: ed <s@ocv.me>
2025-11-19 15:24:52 +01:00
ed ac085b8149 mtag: fix geotag usage 2025-11-02 14:56:28 +00:00
ed 1c15c0d5d1 mtag: add geotag.py 2025-11-02 13:12:13 +00:00
Nicolas Mémeint 904c984bda
nixos: Only create and bind volumes without variables (#962) 2025-11-02 12:59:48 +00:00
Nicolas Mémeint 3242145e52
nixos: Use volume/global chmod-d for module directory creation (#963) 2025-11-02 12:59:41 +00:00
ed dff6aa2435 update pkgs to 1.19.20 2025-11-02 01:13:32 +00:00
ed 450cd86dc1 v1.19.20 2025-11-02 01:09:40 +00:00
ed db60951d9f apply per-vol (md|lg)_sb during nav 2025-11-02 00:58:13 +00:00
Carson c00314a292
apply per-volume sb_lg during navigation (#967)
Signed-off-by: Carson <57198646+carson-coder@users.noreply.github.com>
2025-11-02 00:29:12 +00:00
ed 2cc53ea151 list files in /?shares; closes #961 2025-10-31 23:09:14 +00:00
ed e9ab040ce8 docker: fix crossbuild from aarch64 2025-10-26 23:30:57 +01:00
ed e005930cd0 readme: pyvips on windows 2025-10-26 23:23:17 +01:00
ed 4fcd2c4193 update pkgs to 1.19.19 2025-10-25 19:21:56 +00:00
ed cec44aa1dd v1.19.19 2025-10-25 19:18:51 +00:00
ed e3524d85bd fix for archlinux pkgbuild 2025-10-25 19:02:06 +00:00
ed 1963ed1795 update pkgs to 1.19.18 2025-10-25 14:36:57 +00:00
46 changed files with 312 additions and 84 deletions

View file

@ -322,7 +322,7 @@ small collection of user feedback
project goals / philosophy project goals / philosophy
* inverse linux philosophy -- do all the things, and do an *okay* job * inverse unix philosophy -- do all the things, and do an *okay* job
* quick drop-in service to get a lot of features in a pinch * quick drop-in service to get a lot of features in a pinch
* some of [the alternatives](./docs/versus.md) might be a better fit for you * some of [the alternatives](./docs/versus.md) might be a better fit for you
* run anywhere, support everything * run anywhere, support everything
@ -634,7 +634,7 @@ the main tabs in the ui
* `[🧯]` [unpost](#unpost): undo/delete accidental uploads * `[🧯]` [unpost](#unpost): undo/delete accidental uploads
* `[🚀]` and `[🎈]` are the [uploaders](#uploading) * `[🚀]` and `[🎈]` are the [uploaders](#uploading)
* `[📂]` mkdir: create directories * `[📂]` mkdir: create directories
* `[📝]` new-md: create a new markdown document * `[📝]` new-file: create a new textfile
* `[📟]` send-msg: either to server-log or into textfiles if `--urlform save` * `[📟]` send-msg: either to server-log or into textfiles if `--urlform save`
* `[🎺]` audio-player config options * `[🎺]` audio-player config options
* `[⚙️]` general client config options * `[⚙️]` general client config options
@ -2982,7 +2982,9 @@ enable sending [zeromq messages](#zeromq) from event-hooks: `pyzmq`
enable [smb](#smb-server) support (**not** recommended): `impacket==0.12.0` enable [smb](#smb-server) support (**not** recommended): `impacket==0.12.0`
`pyvips` gives higher quality thumbnails than `Pillow` and is 320% faster, using 270% more ram: `sudo apt install libvips42 && python3 -m pip install --user -U pyvips` `pyvips` gives higher quality thumbnails than `Pillow` and is 320% faster, using 270% more ram
* to install `pyvips` on Linux: `sudo apt install libvips42 && python3 -m pip install --user -U pyvips`
* to install `pyvips` on windows: `pip install --user -U "pyvips[binary]"`
to install FFmpeg on Windows, grab [a recent build](https://www.gyan.dev/ffmpeg/builds/ffmpeg-git-full.7z) -- you need `ffmpeg.exe` and `ffprobe.exe` from inside the `bin` folder; copy them into `C:\Windows\System32` or any other folder that's in your `%PATH%` to install FFmpeg on Windows, grab [a recent build](https://www.gyan.dev/ffmpeg/builds/ffmpeg-git-full.7z) -- you need `ffmpeg.exe` and `ffprobe.exe` from inside the `bin` folder; copy them into `C:\Windows\System32` or any other folder that's in your `%PATH%`

View file

@ -68,3 +68,8 @@ instead of affecting all volumes, you can set the options for just one volume li
* `:c,mtp=key=f,audio-key.py` * `:c,mtp=key=f,audio-key.py`
* `:c,mtp=.bpm=f,audio-bpm.py` * `:c,mtp=.bpm=f,audio-bpm.py`
* `:c,mtp=ahash,vhash=f,media-hash.py` * `:c,mtp=ahash,vhash=f,media-hash.py`
# tips & tricks
* to delete tags for all files below `blog*` and rescan that, `sqlite3 .hist/up2k.db "delete from mt where w in (select substr(w,1,16) from up where rd like 'blog%')";`

53
bin/mtag/geotag.py Executable file
View file

@ -0,0 +1,53 @@
import json
import re
import sys
from copyparty.util import fsenc, runcmd
"""
uses exiftool to geotag images based on embedded gps coordinates in exif data
adds four new metadata keys:
.gps_lat = latitute
.gps_lon = longitude
.masl = meters above sea level
city = "city, subregion, region"
usage: -mtp .masl,.gps_lat,.gps_lon,city=ad,t10,bin/mtag/geotag.py
example: https://a.ocv.me/pub/blog/j7/8/?grid=0
"""
def main():
cmd = b"exiftool -api geolocation -n".split(b" ")
rc, so, se = runcmd(cmd + [fsenc(sys.argv[1])])
ptn = re.compile("([^:]*[^ :]) *: (.*)")
city = ["", "", ""]
ret = {}
for ln in so.split("\n"):
m = ptn.match(ln)
if not m:
continue
k, v = m.groups()
if k == "Geolocation City":
city[2] = v
elif k == "Geolocation Subregion":
city[1] = v
elif k == "Geolocation Region":
city[0] = v
elif k == "GPS Latitude":
ret[".gps_lat"] = "%.04f" % (float(v),)
elif k == "GPS Longitude":
ret[".gps_lon"] = "%.04f" % (float(v),)
elif k == "GPS Altitude":
ret[".masl"] = str(int(float(v)))
v = ", ".join(city).strip(", ")
if v:
ret["city"] = v
print(json.dumps(ret))
if __name__ == "__main__":
main()

View file

@ -48,6 +48,8 @@ let
accountsWithPlaceholders = mapAttrs (name: attrs: passwordPlaceholder name); accountsWithPlaceholders = mapAttrs (name: attrs: passwordPlaceholder name);
volumesWithoutVariables = filterAttrs (k: v: !(hasInfix "\${" v.path)) cfg.volumes;
configStr = '' configStr = ''
${mkSection "global" cfg.settings} ${mkSection "global" cfg.settings}
${cfg.globalExtraConfig} ${cfg.globalExtraConfig}
@ -325,7 +327,7 @@ in
BindPaths = BindPaths =
(if cfg.settings ? hist then [ cfg.settings.hist ] else [ ]) (if cfg.settings ? hist then [ cfg.settings.hist ] else [ ])
++ [ externalStateDir ] ++ [ externalStateDir ]
++ (mapAttrsToList (k: v: v.path) cfg.volumes); ++ (mapAttrsToList (k: v: v.path) volumesWithoutVariables);
# ProtectSystem = "strict"; # ProtectSystem = "strict";
# Note that unlike what 'ro' implies, # Note that unlike what 'ro' implies,
# this actually makes it impossible to read anything in the root FS, # this actually makes it impossible to read anything in the root FS,
@ -364,10 +366,20 @@ in
#: in front of things means it wont change it if the directory already exists. #: in front of things means it wont change it if the directory already exists.
group = ":${cfg.group}"; group = ":${cfg.group}";
user = ":${cfg.user}"; user = ":${cfg.user}";
mode = ":755"; mode = ":${
# Use volume permissions if set
if (value.flags ? chmod_d) then
value.flags.chmod_d
# Else, use global permission if set
else if (cfg.settings ? chmod-d) then
cfg.settings.chmod-d
# Else, use the default permission
else
"755"
}";
}; };
} }
) cfg.volumes ) volumesWithoutVariables
); );
users.groups = lib.mkIf (cfg.group == "copyparty") { users.groups = lib.mkIf (cfg.group == "copyparty") {

View file

@ -3,7 +3,7 @@
# NOTE: You generally shouldn't use this PKGBUILD on Arch, as it is mainly for testing purposes. Install copyparty using pacman instead. # NOTE: You generally shouldn't use this PKGBUILD on Arch, as it is mainly for testing purposes. Install copyparty using pacman instead.
pkgname=copyparty pkgname=copyparty
pkgver="1.19.17" pkgver="1.19.20"
pkgrel=1 pkgrel=1
pkgdesc="File server with accelerated resumable uploads, dedup, WebDAV, FTP, TFTP, zeroconf, media indexer, thumbnails++" pkgdesc="File server with accelerated resumable uploads, dedup, WebDAV, FTP, TFTP, zeroconf, media indexer, thumbnails++"
arch=("any") arch=("any")
@ -23,7 +23,7 @@ optdepends=("ffmpeg: thumbnails for videos, images (slower) and audio, music tag
) )
source=("https://github.com/9001/${pkgname}/releases/download/v${pkgver}/${pkgname}-${pkgver}.tar.gz") source=("https://github.com/9001/${pkgname}/releases/download/v${pkgver}/${pkgname}-${pkgver}.tar.gz")
backup=("etc/${pkgname}/copyparty.conf" ) backup=("etc/${pkgname}/copyparty.conf" )
sha256sums=("b29c66db6153963b74c7d131800208eb4b4ba3af5dc19336f180e5c8231a0d4e") sha256sums=("050ccc34554e59210aca7a67d87a186e69b3f4dbe013d5ee2f11a22c259a82a6")
build() { build() {
cd "${srcdir}/${pkgname}-${pkgver}/copyparty/web" cd "${srcdir}/${pkgname}-${pkgver}/copyparty/web"

View file

@ -2,7 +2,7 @@
pkgname=copyparty pkgname=copyparty
pkgver=1.19.17 pkgver=1.19.20
pkgrel=1 pkgrel=1
pkgdesc="File server with accelerated resumable uploads, dedup, WebDAV, FTP, TFTP, zeroconf, media indexer, thumbnails++" pkgdesc="File server with accelerated resumable uploads, dedup, WebDAV, FTP, TFTP, zeroconf, media indexer, thumbnails++"
arch=("any") arch=("any")
@ -20,7 +20,7 @@ optdepends=("ffmpeg: thumbnails for videos, images (slower) and audio, music tag
) )
source=("https://github.com/9001/${pkgname}/releases/download/v${pkgver}/${pkgname}-${pkgver}.tar.gz") source=("https://github.com/9001/${pkgname}/releases/download/v${pkgver}/${pkgname}-${pkgver}.tar.gz")
backup=("/etc/${pkgname}.d/init" ) backup=("/etc/${pkgname}.d/init" )
sha256sums=("b29c66db6153963b74c7d131800208eb4b4ba3af5dc19336f180e5c8231a0d4e") sha256sums=("050ccc34554e59210aca7a67d87a186e69b3f4dbe013d5ee2f11a22c259a82a6")
build() { build() {
cd "${srcdir}/${pkgname}-${pkgver}/copyparty/web" cd "${srcdir}/${pkgname}-${pkgver}/copyparty/web"

View file

@ -1,5 +1,5 @@
{ {
"url": "https://github.com/9001/copyparty/releases/download/v1.19.17/copyparty-1.19.17.tar.gz", "url": "https://github.com/9001/copyparty/releases/download/v1.19.20/copyparty-1.19.20.tar.gz",
"version": "1.19.17", "version": "1.19.20",
"hash": "sha256-spxm22FTljt0x9ExgAII60tLo69dwZM28YDlyCMaDU4=" "hash": "sha256-BQzMNFVOWSEKynpn2HoYbmmz9NvgE9XuLxGiLCWagqY="
} }

View file

@ -1160,7 +1160,6 @@ def add_general(ap, nc, srvname):
ap2 = ap.add_argument_group("general options") ap2 = ap.add_argument_group("general options")
ap2.add_argument("-c", metavar="PATH", type=u, default=CFG_DEF, action="append", help="\033[34mREPEATABLE:\033[0m add config file") ap2.add_argument("-c", metavar="PATH", type=u, default=CFG_DEF, action="append", help="\033[34mREPEATABLE:\033[0m add config file")
ap2.add_argument("-nc", metavar="NUM", type=int, default=nc, help="max num clients") ap2.add_argument("-nc", metavar="NUM", type=int, default=nc, help="max num clients")
ap2.add_argument("-j", metavar="CORES", type=int, default=1, help="max num cpu cores, 0=all")
ap2.add_argument("-a", metavar="ACCT", type=u, action="append", help="\033[34mREPEATABLE:\033[0m add account, \033[33mUSER\033[0m:\033[33mPASS\033[0m; example [\033[32med:wark\033[0m]") ap2.add_argument("-a", metavar="ACCT", type=u, action="append", help="\033[34mREPEATABLE:\033[0m add account, \033[33mUSER\033[0m:\033[33mPASS\033[0m; example [\033[32med:wark\033[0m]")
ap2.add_argument("-v", metavar="VOL", type=u, action="append", help="\033[34mREPEATABLE:\033[0m add volume, \033[33mSRC\033[0m:\033[33mDST\033[0m:\033[33mFLAG\033[0m; examples [\033[32m.::r\033[0m], [\033[32m/mnt/nas/music:/music:r:aed\033[0m], see --help-accounts") ap2.add_argument("-v", metavar="VOL", type=u, action="append", help="\033[34mREPEATABLE:\033[0m add volume, \033[33mSRC\033[0m:\033[33mDST\033[0m:\033[33mFLAG\033[0m; examples [\033[32m.::r\033[0m], [\033[32m/mnt/nas/music:/music:r:aed\033[0m], see --help-accounts")
ap2.add_argument("--grp", metavar="G:N,N", type=u, action="append", help="\033[34mREPEATABLE:\033[0m add group, \033[33mNAME\033[0m:\033[33mUSER1\033[0m,\033[33mUSER2\033[0m,\033[33m...\033[0m; example [\033[32madmins:ed,foo,bar\033[0m]") ap2.add_argument("--grp", metavar="G:N,N", type=u, action="append", help="\033[34mREPEATABLE:\033[0m add group, \033[33mNAME\033[0m:\033[33mUSER1\033[0m,\033[33mUSER2\033[0m,\033[33m...\033[0m; example [\033[32madmins:ed,foo,bar\033[0m]")
@ -1175,6 +1174,7 @@ def add_general(ap, nc, srvname):
ap2.add_argument("--mime", metavar="EXT=MIME", type=u, action="append", help="\033[34mREPEATABLE:\033[0m map file \033[33mEXT\033[0mension to \033[33mMIME\033[0mtype, for example [\033[32mjpg=image/jpeg\033[0m]") ap2.add_argument("--mime", metavar="EXT=MIME", type=u, action="append", help="\033[34mREPEATABLE:\033[0m map file \033[33mEXT\033[0mension to \033[33mMIME\033[0mtype, for example [\033[32mjpg=image/jpeg\033[0m]")
ap2.add_argument("--mimes", action="store_true", help="list default mimetype mapping and exit") ap2.add_argument("--mimes", action="store_true", help="list default mimetype mapping and exit")
ap2.add_argument("--rmagic", action="store_true", help="do expensive analysis to improve accuracy of returned mimetypes; will make file-downloads, rss, and webdav slower (volflag=rmagic)") ap2.add_argument("--rmagic", action="store_true", help="do expensive analysis to improve accuracy of returned mimetypes; will make file-downloads, rss, and webdav slower (volflag=rmagic)")
ap2.add_argument("-j", metavar="CORES", type=int, default=1, help="num cpu-cores for uploads/downloads (0=all); keeping the default is almost always best")
ap2.add_argument("--license", action="store_true", help="show licenses and exit") ap2.add_argument("--license", action="store_true", help="show licenses and exit")
ap2.add_argument("--version", action="store_true", help="show versions and exit") ap2.add_argument("--version", action="store_true", help="show versions and exit")
ap2.add_argument("--versionb", action="store_true", help="show version and exit") ap2.add_argument("--versionb", action="store_true", help="show version and exit")
@ -1491,6 +1491,7 @@ def add_hooks(ap):
def add_stats(ap): def add_stats(ap):
ap2 = ap.add_argument_group("grafana/prometheus metrics endpoint") ap2 = ap.add_argument_group("grafana/prometheus metrics endpoint")
ap2.add_argument("--stats", action="store_true", help="enable openmetrics at /.cpr/metrics for admin accounts") ap2.add_argument("--stats", action="store_true", help="enable openmetrics at /.cpr/metrics for admin accounts")
ap2.add_argument("--stats-u", metavar="U,U", type=u, default="", help="comma-separated list of users allowed to access /.cpr/metrics even if they aren't admin")
ap2.add_argument("--nos-hdd", action="store_true", help="disable disk-space metrics (used/free space)") ap2.add_argument("--nos-hdd", action="store_true", help="disable disk-space metrics (used/free space)")
ap2.add_argument("--nos-vol", action="store_true", help="disable volume size metrics (num files, total bytes, vmaxb/vmaxn)") ap2.add_argument("--nos-vol", action="store_true", help="disable volume size metrics (num files, total bytes, vmaxb/vmaxn)")
ap2.add_argument("--nos-vst", action="store_true", help="disable volume state metrics (indexing, analyzing, activity)") ap2.add_argument("--nos-vst", action="store_true", help="disable volume state metrics (indexing, analyzing, activity)")

View file

@ -1,8 +1,8 @@
# coding: utf-8 # coding: utf-8
VERSION = (1, 19, 18) VERSION = (1, 19, 20)
CODENAME = "usernames" CODENAME = "usernames"
BUILD_DT = (2025, 10, 25) BUILD_DT = (2025, 11, 2)
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

@ -1812,6 +1812,15 @@ class AuthSrv(object):
derive_args(self.args) derive_args(self.args)
self.setup_auth_ord() self.setup_auth_ord()
if self.args.ipu:
# syntax (CIDR=UNAME) is verified in load_ipu
zsl = [x.split("=", 1)[1] for x in self.args.ipu]
zsl = [x for x in zsl if x not in acct]
if zsl:
t = "ERROR: unknown users in ipu: %s" % (zsl,)
self.log(t, 1)
raise Exception(t)
self.setup_pwhash(acct) self.setup_pwhash(acct)
defpw = acct.copy() defpw = acct.copy()
self.setup_chpw(acct) self.setup_chpw(acct)
@ -3051,6 +3060,7 @@ class AuthSrv(object):
"lifetime": vf.get("lifetime") or 0, "lifetime": vf.get("lifetime") or 0,
"unlist": vf.get("unlist") or "", "unlist": vf.get("unlist") or "",
"sb_lg": "" if "no_sb_lg" in vf else (vf.get("lg_sbf") or "y"), "sb_lg": "" if "no_sb_lg" in vf else (vf.get("lg_sbf") or "y"),
"sb_md": "" if "no_sb_md" in vf else (vf.get("md_sbf") or "y"),
} }
if "ufavico_h" in vf: if "ufavico_h" in vf:
vn.js_ls["ufavico"] = vf["ufavico_h"] vn.js_ls["ufavico"] = vf["ufavico_h"]
@ -3072,7 +3082,8 @@ class AuthSrv(object):
"have_emp": int(self.args.emp), "have_emp": int(self.args.emp),
"md_no_br": int(vf.get("md_no_br") or 0), "md_no_br": int(vf.get("md_no_br") or 0),
"ext_th": vf.get("ext_th_d") or {}, "ext_th": vf.get("ext_th_d") or {},
"sb_md": "" if "no_sb_md" in vf else (vf.get("md_sbf") or "y"), "sb_lg": vn.js_ls["sb_lg"],
"sb_md": vn.js_ls["sb_md"],
"sba_md": vf.get("md_sba") or "", "sba_md": vf.get("md_sba") or "",
"sba_lg": vf.get("lg_sba") or "", "sba_lg": vf.get("lg_sba") or "",
"txt_ext": self.args.textfiles.replace(",", " "), "txt_ext": self.args.textfiles.replace(",", " "),

View file

@ -124,7 +124,17 @@ from .util import (
if True: # pylint: disable=using-constant-test if True: # pylint: disable=using-constant-test
import typing import typing
from typing import Any, Generator, Iterable, Match, Optional, Pattern, Type, Union from typing import (
Any,
Generator,
Iterable,
Match,
Optional,
Pattern,
Sequence,
Type,
Union,
)
if TYPE_CHECKING: if TYPE_CHECKING:
from .httpconn import HttpConn from .httpconn import HttpConn
@ -172,6 +182,18 @@ PERMS_rwh = [
] ]
def _build_zip_xcode() -> Sequence[str]:
ret = "opus mp3 flac wav p".split()
for codec in ("w", "j"):
for suf in ("", "f", "f3", "3"):
ret.append("%s%s" % (codec, suf))
return ret
ZIP_XCODE_L = _build_zip_xcode()
ZIP_XCODE_S = set(ZIP_XCODE_L)
class HttpCli(object): class HttpCli(object):
""" """
Spawned by HttpConn to process one http transaction Spawned by HttpConn to process one http transaction
@ -785,7 +807,7 @@ class HttpCli(object):
guess = "modifying" if (origin and host) else "stripping" guess = "modifying" if (origin and host) else "stripping"
t = "cors-reject %s because request-header Origin=%r does not match request-protocol %r and host %r based on request-header Host=%r (note: if this request is not malicious, check if your reverse-proxy is accidentally %s request headers, in particular 'Origin', for example by running copyparty with --ihead='*' to show all request headers)" t = "cors-reject %s because request-header Origin=%r does not match request-protocol %r and host %r based on request-header Host=%r (note: if this request is not malicious, check if your reverse-proxy is accidentally %s request headers, in particular 'Origin', for example by running copyparty with --ihead='*' to show all request headers)"
self.log(t % (self.mode, origin, proto, self.host, host, guess), 3) self.log(t % (self.mode, origin, proto, self.host, host, guess), 3)
raise Pebkac(403, "rejected by cors-check") raise Pebkac(403, "rejected by cors-check (see serverlog)")
# getattr(self.mode) is not yet faster than this # getattr(self.mode) is not yet faster than this
if self.mode == "POST": if self.mode == "POST":
@ -931,7 +953,7 @@ class HttpCli(object):
return False return False
self.log("banned for {:.0f} sec".format(rt), 6) self.log("banned for {:.0f} sec".format(rt), 6)
self.terse_reply(b"thank you for playing", 403) self.terse_reply(b"thank you for playing (see serverlog and readme)", 403)
return True return True
def permit_caching(self) -> None: def permit_caching(self) -> None:
@ -3308,9 +3330,9 @@ class HttpCli(object):
vfs, rem = self.asrv.vfs.get(self.vpath, self.uname, False, True) vfs, rem = self.asrv.vfs.get(self.vpath, self.uname, False, True)
self._assert_safe_rem(rem) self._assert_safe_rem(rem)
ext = "" if "." not in new_file else new_file.split(".")[-1] if not self.can_delete and not new_file.lower().endswith(".md"):
if not ext or len(ext) > 5 or not self.can_delete: t = "you can only create .md files because you don't have the delete-permission"
new_file += ".md" raise Pebkac(400, t)
sanitized = sanitize_fn(new_file, "") sanitized = sanitize_fn(new_file, "")
fdir = vfs.canonical(rem) fdir = vfs.canonical(rem)
@ -3349,7 +3371,6 @@ class HttpCli(object):
raise Pebkac(500, "that file exists already") raise Pebkac(500, "that file exists already")
with open(fsenc(fn), "wb") as f: with open(fsenc(fn), "wb") as f:
f.write(b"`GRUNNUR`\n")
if "fperms" in vfs.flags: if "fperms" in vfs.flags:
set_fperms(f, vfs.flags) set_fperms(f, vfs.flags)
@ -4943,8 +4964,11 @@ class HttpCli(object):
# for f in fgen: print(repr({k: f[k] for k in ["vp", "ap"]})) # for f in fgen: print(repr({k: f[k] for k in ["vp", "ap"]}))
cfmt = "" cfmt = ""
if self.thumbcli and not self.args.no_bacode: if self.thumbcli and not self.args.no_bacode:
for zs in ("opus", "mp3", "flac", "wav", "w", "j", "p"): if uarg in ZIP_XCODE_S:
if zs in self.ouparam or uarg == zs: cfmt = uarg
else:
for zs in ZIP_XCODE_L:
if zs in self.ouparam:
cfmt = zs cfmt = zs
if cfmt: if cfmt:
@ -6014,6 +6038,15 @@ class HttpCli(object):
if self.uname != self.args.shr_adm: if self.uname != self.args.shr_adm:
rows = [x for x in rows if x[5] == self.uname] rows = [x for x in rows if x[5] == self.uname]
q = "select vp from sf where k=? limit 99"
for r in rows:
if not r[4]:
r[4] = "---"
else:
zstl = cur.execute(q, (r[0],)).fetchall()
zsl = [html_escape(zst[0]) for zst in zstl]
r[4] = "<br />".join(zsl)
html = self.j2s( html = self.j2s(
"shares", this=self, shr=self.args.shr, rows=rows, now=int(time.time()) "shares", this=self, shr=self.args.shr, rows=rows, now=int(time.time())
) )

View file

@ -17,10 +17,10 @@ class Metrics(object):
self.hsrv = hsrv self.hsrv = hsrv
def tx(self, cli: "HttpCli") -> bool: def tx(self, cli: "HttpCli") -> bool:
if not cli.avol: args = cli.args
if not cli.avol and cli.uname.lower() not in args.stats_u_set:
raise Pebkac(403, "'stats' not allowed for user " + cli.uname) raise Pebkac(403, "'stats' not allowed for user " + cli.uname)
args = cli.args
if not args.stats: if not args.stats:
raise Pebkac(403, "the stats feature is not enabled in server config") raise Pebkac(403, "the stats feature is not enabled in server config")

View file

@ -1081,7 +1081,7 @@ class SvcHub(object):
vs = os.path.expandvars(os.path.expanduser(vs)) vs = os.path.expandvars(os.path.expanduser(vs))
setattr(al, k, vs) setattr(al, k, vs)
for k in "idp_adm".split(" "): for k in "idp_adm stats_u".split(" "):
vs = getattr(al, k) vs = getattr(al, k)
vsa = [x.strip() for x in vs.split(",")] vsa = [x.strip() for x in vs.split(",")]
vsa = [x.lower() for x in vsa if x] vsa = [x.lower() for x in vsa if x]

View file

@ -270,6 +270,9 @@ class ThumbSrv(object):
def shutdown(self) -> None: def shutdown(self) -> None:
self.stopping = True self.stopping = True
Daemon(self._fire_sentinels, "thumbstopper")
def _fire_sentinels(self):
for _ in range(self.nthr): for _ in range(self.nthr):
self.q.put(None) self.q.put(None)

View file

@ -3,11 +3,13 @@
# but then why are you using copyparty in the first place # but then why are you using copyparty in the first place
pk: $(addsuffix .gz, $(wildcard tl/*.js *.js *.css) \ pk: $(addsuffix .gz, $(wildcard tl/*.js *.js *.css) \
a/partyfuse.py a/u2c.py a/webdav-cfg.txt ) a/webdav-cfg.txt )
un: $(addsuffix .un, $(wildcard tl/*.gz *.gz a/*.gz)) un: $(addsuffix .un, $(wildcard tl/*.gz *.gz a/*.gz))
%.gz: % %.gz: %
pigz -11 -J 34 -I 573 $< pigz -c11 -J 34 -I 573 <$< >$@
touch -r $< $@
rm $<
%.un: % %.un: %
pigz -d $< pigz -d $<

View file

@ -51,8 +51,9 @@
<form method="post" enctype="multipart/form-data" accept-charset="utf-8" action="{{ url_suf }}"> <form method="post" enctype="multipart/form-data" accept-charset="utf-8" action="{{ url_suf }}">
<input type="hidden" name="act" value="new_md" /> <input type="hidden" name="act" value="new_md" />
📝<input type="text" name="name" class="i" placeholder="weekend-plans"> 📝<input type="text" name="name" class="i" placeholder="weekend-plans">
<input type="submit" value="new markdown doc"> <input type="submit" value="new file">
</form> </form>
<span id="new_mdi"></p>
</div> </div>
<div id="op_msg" class="opview opbox {% if not ls0 %}act{% endif %}"> <div id="op_msg" class="opview opbox {% if not ls0 %}act{% endif %}">
@ -137,7 +138,6 @@
lang = "{{ lang }}", lang = "{{ lang }}",
dfavico = "{{ favico }}", dfavico = "{{ favico }}",
have_tags_idx = {{ have_tags_idx }}, have_tags_idx = {{ have_tags_idx }},
sb_lg = "{{ sb_lg }}",
logues = {{ logues|tojson if sb_lg else "[]" }}, logues = {{ logues|tojson if sb_lg else "[]" }},
ls0 = {{ ls0|tojson }}; ls0 = {{ ls0|tojson }};

View file

@ -119,7 +119,7 @@ if (1)
"ot_unpost": "unpost: delete your recent uploads, or abort unfinished ones", "ot_unpost": "unpost: delete your recent uploads, or abort unfinished ones",
"ot_bup": "bup: basic uploader, even supports netscape 4.0", "ot_bup": "bup: basic uploader, even supports netscape 4.0",
"ot_mkdir": "mkdir: create a new directory", "ot_mkdir": "mkdir: create a new directory",
"ot_md": "new-md: create a new markdown document", "ot_md": "new-file: create a new textfile",
"ot_msg": "msg: send a message to the server log", "ot_msg": "msg: send a message to the server log",
"ot_mp": "media player options", "ot_mp": "media player options",
"ot_cfg": "configuration options", "ot_cfg": "configuration options",
@ -128,7 +128,7 @@ if (1)
"ot_noie": 'Please use Chrome / Firefox / Edge', "ot_noie": 'Please use Chrome / Firefox / Edge',
"ab_mkdir": "make directory", "ab_mkdir": "make directory",
"ab_mkdoc": "new markdown doc", "ab_mkdoc": "new textfile",
"ab_msg": "send msg to srv log", "ab_msg": "send msg to srv log",
"ay_path": "skip to folders", "ay_path": "skip to folders",
@ -440,6 +440,8 @@ if (1)
"fcp_both_b": '<a href="#" id="modal-ok">Copy</a><a href="#" id="modal-ng">Upload</a>', "fcp_both_b": '<a href="#" id="modal-ok">Copy</a><a href="#" id="modal-ng">Upload</a>',
"mk_noname": "type a name into the text field on the left before you do that :p", "mk_noname": "type a name into the text field on the left before you do that :p",
"nmd_i1": "also add the file extension you want, for example <code>.md</code>",
"nmd_i2": "you can only create <code>.md</code> files because you don't have the delete-permission",
"tv_load": "Loading text document:\n\n{0}\n\n{1}% ({2} of {3} MiB loaded)", "tv_load": "Loading text document:\n\n{0}\n\n{1}% ({2} of {3} MiB loaded)",
"tv_xe1": "could not load textfile:\n\nerror ", "tv_xe1": "could not load textfile:\n\nerror ",
@ -7148,6 +7150,8 @@ var treectl = (function () {
if (res.files[a].tags === undefined) if (res.files[a].tags === undefined)
res.files[a].tags = {}; res.files[a].tags = {};
sb_lg = res.sb_lg;
sb_md = res.sb_md;
dnsort = res.dnsort; dnsort = res.dnsort;
read_dsort(res.dsort); read_dsort(res.dsort);
dcrop = res.dcrop; dcrop = res.dcrop;
@ -7741,6 +7745,8 @@ function apply_perms(res) {
if (up2k) if (up2k)
up2k.set_fsearch(); up2k.set_fsearch();
ebi('new_mdi').innerHTML = has(perms, "delete") ? L.nmd_i1 : L.nmd_i2;
widget.setvis(); widget.setvis();
thegrid.setvis(); thegrid.setvis();
if (!have_read && have_write) if (!have_read && have_write)
@ -8797,7 +8803,7 @@ function show_md(md, name, div, url, depth) {
var els = QSA('#epi a'); var els = QSA('#epi a');
for (var a = 0, aa = els.length; a < aa; a++) { for (var a = 0, aa = els.length; a < aa; a++) {
var href = els[a].getAttribute('href'); var href = els[a].getAttribute('href');
if (!href.startsWith('#') || href.startsWith('#md-')) if (!href || !href.startsWith('#') || href.startsWith('#md-'))
continue; continue;
els[a].setAttribute('href', '#md-' + href.slice(1)); els[a].setAttribute('href', '#md-' + href.slice(1));

View file

@ -43,7 +43,7 @@
<script> <script>
setTimeout(function() { setTimeout(function() {
location.replace("{{ redir }}"); location.replace("{{ redir }}");
}, 1000); }, 600);
</script> </script>
{%- endif %} {%- endif %}
{%- if js %} {%- if js %}

View file

@ -58,6 +58,7 @@ th {
#wrap th { #wrap th {
padding: .3em .6em; padding: .3em .6em;
text-align: left; text-align: left;
vertical-align: top;
white-space: nowrap; white-space: nowrap;
} }
#wrap td+td+td+td+td+td+td+td { #wrap td+td+td+td+td+td+td+td {
@ -71,7 +72,10 @@ th {
#wrap td:last-child { #wrap td:last-child {
border-radius: 0 .5em .5em 0; border-radius: 0 .5em .5em 0;
} }
#wrap.terse td div {
height: 2.3em;
overflow-y: hidden;
}
html.z { html.z {

View file

@ -14,8 +14,9 @@
</head> </head>
<body> <body>
<div id="wrap"> <div id="wrap" class="terse">
<a href="{{ r }}/?shares">refresh</a> <a href="{{ r }}/?shares">refresh</a>
<a id="xpnd" href="#">files</a>
<a href="{{ r }}/?h">control-panel</a> <a href="{{ r }}/?h">control-panel</a>
<span>axs = perms (read,write,move,delet)</span> <span>axs = perms (read,write,move,delet)</span>
@ -46,7 +47,7 @@
<td>{{ "yes" if pw else "--" }}</td> <td>{{ "yes" if pw else "--" }}</td>
<td><a href="{{ r }}/{{ vp|e }}">/{{ vp|e }}</a></td> <td><a href="{{ r }}/{{ vp|e }}">/{{ vp|e }}</a></td>
<td>{{ pr }}</td> <td>{{ pr }}</td>
<td>{{ st }}</td> <td><div>{{ st }}</div></td>
<td>{{ un|e }}</td> <td>{{ un|e }}</td>
<td>{{ t0 }}</td> <td>{{ t0 }}</td>
<td>{{ t1 }}</td> <td>{{ t1 }}</td>

View file

@ -28,6 +28,11 @@ function cb() {
location = '?shares'; location = '?shares';
} }
ebi('xpnd').onclick = function (e) {
ev(e);
clmod(ebi('wrap'), 'terse', 't');
};
function qr(e) { function qr(e) {
ev(e); ev(e);
var href = this.href, var href = this.href,

View file

@ -42,7 +42,7 @@
<thead><tr><th>%</th><th>speed</th><th>eta</th><th>idle</th><th>dir</th><th>file</th></tr></thead> <thead><tr><th>%</th><th>speed</th><th>eta</th><th>idle</th><th>dir</th><th>file</th></tr></thead>
<tbody> <tbody>
{%- for u in ups %} {%- for u in ups %}
<tr><td>{{ u[0] }}</td><td>{{ u[1] }}</td><td>{{ u[2] }}</td><td>{{ u[3] }}</td><td><a href="{{ u[4] }}">{{ u[5]|e }}</a></td><td>{{ u[6]|e }}</td></tr> <tr><td>{{ u[0] }}</td><td>{{ u[1] }}</td><td>{{ u[2] }}</td><td>{{ u[3] }}</td><td><a href="{{ r }}/{{ u[4] }}">{{ u[5]|e }}</a></td><td>{{ u[6]|e }}</td></tr>
{%- endfor %} {%- endfor %}
</tbody> </tbody>
</table> </table>
@ -54,7 +54,7 @@
<thead><tr><th>%</th><th>sent</th><th>speed</th><th>eta</th><th>idle</th><th></th><th>dir</th><th>file</th></tr></thead> <thead><tr><th>%</th><th>sent</th><th>speed</th><th>eta</th><th>idle</th><th></th><th>dir</th><th>file</th></tr></thead>
<tbody> <tbody>
{%- for u in dls %} {%- for u in dls %}
<tr><td>{{ u[0] }}</td><td>{{ u[1] }}</td><td>{{ u[2] }}</td><td>{{ u[3] }}</td><td>{{ u[4] }}</td><td>{{ u[5] }}</td><td><a href="{{ u[6] }}">{{ u[7]|e }}</a></td><td>{{ u[8] }}</td></tr> <tr><td>{{ u[0] }}</td><td>{{ u[1] }}</td><td>{{ u[2] }}</td><td>{{ u[3] }}</td><td>{{ u[4] }}</td><td>{{ u[5] }}</td><td><a href="{{ r }}/{{ u[6] }}">{{ u[7]|e }}</a></td><td>{{ u[8] }}</td></tr>
{%- endfor %} {%- endfor %}
</tbody> </tbody>
</table> </table>
@ -120,7 +120,11 @@
</form> </form>
</div> </div>
{%- else %} {%- else %}
{%- if this.uname == '*' %}
<h1 id="l">login for more:</h1> <h1 id="l">login for more:</h1>
{%- else %}
<h1 id="l">change account:</h1>
{%- endif %}
<div> <div>
{%- if this.args.idp_login %} {%- if this.args.idp_login %}
<ul><li> <ul><li>

View file

@ -116,7 +116,7 @@ Ls.chi = {
"ot_unpost": "取消发布:删除最近上传的内容,或中止未完成的内容", "ot_unpost": "取消发布:删除最近上传的内容,或中止未完成的内容",
"ot_bup": "bup基础上传器甚至支持 Netscape 4.0", "ot_bup": "bup基础上传器甚至支持 Netscape 4.0",
"ot_mkdir": "mkdir创建新目录", "ot_mkdir": "mkdir创建新目录",
"ot_md": "new-md创建新 Markdown 文档", "ot_md": "new-file创建新的文本文件", //m
"ot_msg": "msg向服务器日志发送消息", "ot_msg": "msg向服务器日志发送消息",
"ot_mp": "媒体播放器选项", "ot_mp": "媒体播放器选项",
"ot_cfg": "配置选项", "ot_cfg": "配置选项",
@ -125,7 +125,7 @@ Ls.chi = {
"ot_noie": '请使用 Chrome / Firefox / Edge', "ot_noie": '请使用 Chrome / Firefox / Edge',
"ab_mkdir": "创建目录", "ab_mkdir": "创建目录",
"ab_mkdoc": "新建 Markdown 文档", "ab_mkdoc": "新建文本文件", //m
"ab_msg": "发送消息到服务器日志", "ab_msg": "发送消息到服务器日志",
"ay_path": "跳转到文件夹", "ay_path": "跳转到文件夹",
@ -437,6 +437,8 @@ Ls.chi = {
"fcp_both_b": '<a href="#" id="modal-ok">复制</a><a href="#" id="modal-ng">上传</a>', //m "fcp_both_b": '<a href="#" id="modal-ok">复制</a><a href="#" id="modal-ng">上传</a>', //m
"mk_noname": "在左侧文本框中输入名称,然后再执行此操作 :p", "mk_noname": "在左侧文本框中输入名称,然后再执行此操作 :p",
"nmd_i1": "还可以添加需要的文件扩展名,例如 <code>.txt</code>", //m
"nmd_i2": "由于没有删除权限,你只能创建 <code>.md</code> 文件", //m
"tv_load": "加载文本文件:\n\n{0}\n\n{1}% ({2} 的 {3} MiB 已加载)", "tv_load": "加载文本文件:\n\n{0}\n\n{1}% ({2} 的 {3} MiB 已加载)",
"tv_xe1": "无法加载文本文件:\n\n错误 ", "tv_xe1": "无法加载文本文件:\n\n错误 ",

View file

@ -120,7 +120,7 @@ Ls.cze = {
"ot_unpost": "unpost: smazat vaše nedávné nahrání nebo zrušit nedokončené", "ot_unpost": "unpost: smazat vaše nedávné nahrání nebo zrušit nedokončené",
"ot_bup": "bup: základní nahrávač, podporuje i netscape 4.0", "ot_bup": "bup: základní nahrávač, podporuje i netscape 4.0",
"ot_mkdir": "mkdir: vytvořit nový adresář", "ot_mkdir": "mkdir: vytvořit nový adresář",
"ot_md": "new-md: vytvořit nový markdown dokument", "ot_md": "new-file: vytvořit nový textový soubor", //m
"ot_msg": "msg: poslat zprávu do logu serveru", "ot_msg": "msg: poslat zprávu do logu serveru",
"ot_mp": "možnosti přehrávače médií", "ot_mp": "možnosti přehrávače médií",
"ot_cfg": "možnosti konfigurace", "ot_cfg": "možnosti konfigurace",
@ -129,7 +129,7 @@ Ls.cze = {
"ot_noie": 'Prosím použijte Chrome / Firefox / Edge', "ot_noie": 'Prosím použijte Chrome / Firefox / Edge',
"ab_mkdir": "vytvořit adresář", "ab_mkdir": "vytvořit adresář",
"ab_mkdoc": "nový markdown dokument", "ab_mkdoc": "nový textový soubor", //m
"ab_msg": "poslat zprávu do logu serveru", "ab_msg": "poslat zprávu do logu serveru",
"ay_path": "přejít na složky", "ay_path": "přejít na složky",
@ -441,6 +441,8 @@ Ls.cze = {
"fcp_both_b": '<a href="#" id="modal-ok">Kopírovat</a><a href="#" id="modal-ng">Nahrát</a>', "fcp_both_b": '<a href="#" id="modal-ok">Kopírovat</a><a href="#" id="modal-ng">Nahrát</a>',
"mk_noname": "napište název do textového pole vlevo předtím než to uděláte :p", "mk_noname": "napište název do textového pole vlevo předtím než to uděláte :p",
"nmd_i1": "můžeš také přidat příponu souboru, například <code>.txt</code>", //m
"nmd_i2": "můžeš vytvářet pouze <code>.md</code> soubory, protože nemáš oprávnění mazat", //m
"tv_load": "Načítání textového dokumentu:\n\n{0}\n\n{1}% ({2} z {3} MiB načteno)", "tv_load": "Načítání textového dokumentu:\n\n{0}\n\n{1}% ({2} z {3} MiB načteno)",
"tv_xe1": "nelze načíst textový soubor:\n\nchyba ", "tv_xe1": "nelze načíst textový soubor:\n\nchyba ",

View file

@ -116,7 +116,7 @@ Ls.deu = {
"ot_unpost": "unpost: lösche deine letzten Uploads oder breche unvollständige ab", "ot_unpost": "unpost: lösche deine letzten Uploads oder breche unvollständige ab",
"ot_bup": "bup: Basic Uploader, unterstützt sogar Neuheiten wie Netscape 4.0", "ot_bup": "bup: Basic Uploader, unterstützt sogar Neuheiten wie Netscape 4.0",
"ot_mkdir": "mkdir: Neuen Ordner erstellen", "ot_mkdir": "mkdir: Neuen Ordner erstellen",
"ot_md": "new-md: Neues Markdown-Dokument erstellen", "ot_md": "new-file: Neues Textdokument erstellen", //m
"ot_msg": "msg: Eine Nachricht an das Server-Log schicken", "ot_msg": "msg: Eine Nachricht an das Server-Log schicken",
"ot_mp": "Media Player-Optionen", "ot_mp": "Media Player-Optionen",
"ot_cfg": "Konfigurationsoptionen", "ot_cfg": "Konfigurationsoptionen",
@ -125,7 +125,7 @@ Ls.deu = {
"ot_noie": 'Bitte benutze Chrome / Firefox / Edge', "ot_noie": 'Bitte benutze Chrome / Firefox / Edge',
"ab_mkdir": "Ordner erstellen", "ab_mkdir": "Ordner erstellen",
"ab_mkdoc": "Markdown Doc erstellen", "ab_mkdoc": "Textdatei erstellen", //m
"ab_msg": "Nachricht an Server Log senden", "ab_msg": "Nachricht an Server Log senden",
"ay_path": "zu Ordnern springen", "ay_path": "zu Ordnern springen",
@ -437,6 +437,8 @@ Ls.deu = {
"fcp_both_b": '<a href="#" id="modal-ok">Kopieren</a><a href="#" id="modal-ng">Hochladen</a>', "fcp_both_b": '<a href="#" id="modal-ok">Kopieren</a><a href="#" id="modal-ng">Hochladen</a>',
"mk_noname": "Tipp' mal vorher lieber einen Namen in das Textfeld links, bevor du das machst :p", "mk_noname": "Tipp' mal vorher lieber einen Namen in das Textfeld links, bevor du das machst :p",
"nmd_i1": "Fügen Sie auch die gewünschte Dateiendung hinzu, z. B. <code>.txt</code>", //m
"nmd_i2": "Sie können nur <code>.md</code>-Dateien erstellen, da Ihnen die Löschberechtigung fehlt", //m
"tv_load": "Textdatei wird geladen:\n\n{0}\n\n{1}% ({2} von {3} MiB geladen)", "tv_load": "Textdatei wird geladen:\n\n{0}\n\n{1}% ({2} von {3} MiB geladen)",
"tv_xe1": "Konnte Textdatei nicht laden:\n\nFehler ", "tv_xe1": "Konnte Textdatei nicht laden:\n\nFehler ",

View file

@ -116,7 +116,7 @@ Ls.epo = {
"ot_unpost": "unpost: forigi viaj plej lastaj alŝutoj, aŭ ĉesigi nefinigitajn", "ot_unpost": "unpost: forigi viaj plej lastaj alŝutoj, aŭ ĉesigi nefinigitajn",
"ot_bup": "bup: fundamenta alŝutilo, funkias eĉ kun netscape 4.0", "ot_bup": "bup: fundamenta alŝutilo, funkias eĉ kun netscape 4.0",
"ot_mkdir": "mkdir: krei novan dosierujon", "ot_mkdir": "mkdir: krei novan dosierujon",
"ot_md": "new-md: krei novan markdown-dosieron", "ot_md": "new-file: krei novan tekstodosieron", //m
"ot_msg": "msg: sendi mesaĝon al servila protokolo", "ot_msg": "msg: sendi mesaĝon al servila protokolo",
"ot_mp": "agordoj de medialudilo", "ot_mp": "agordoj de medialudilo",
"ot_cfg": "aliaj agordoj", "ot_cfg": "aliaj agordoj",
@ -125,7 +125,7 @@ Ls.epo = {
"ot_noie": 'Bonvolu uzi retumilojn Chrome / Firefox / Edge', "ot_noie": 'Bonvolu uzi retumilojn Chrome / Firefox / Edge',
"ab_mkdir": "krei dosierujon", "ab_mkdir": "krei dosierujon",
"ab_mkdoc": "krei markdown-dosieron", "ab_mkdoc": "krei tekstodosieron", //m
"ab_msg": "sendi mesaĝon al protokolo", "ab_msg": "sendi mesaĝon al protokolo",
"ay_path": "iri al dosierujoj", "ay_path": "iri al dosierujoj",
@ -437,6 +437,8 @@ Ls.epo = {
"fcp_both_b": '<a href="#" id="modal-ok">Kopii</a><a href="#" id="modal-ng">Alŝuti</a>', "fcp_both_b": '<a href="#" id="modal-ok">Kopii</a><a href="#" id="modal-ng">Alŝuti</a>',
"mk_noname": "tajpu nomon en tekstokampo maldekstre antaŭ vi faras ĉi tion :p", "mk_noname": "tajpu nomon en tekstokampo maldekstre antaŭ vi faras ĉi tion :p",
"nmd_i1": "vi povas aldoni la deziratan sufikson, ekzemple <code>.txt</code>", //m
"nmd_i2": "vi povas krei nur <code>.md</code>-dosierojn ĉar vi ne havas forigan permeson", //m
"tv_load": "Ŝargado de teksto-dokumento:\n\n{0}\n\n{1}% ({2} da {3} MiB ŝargita)", "tv_load": "Ŝargado de teksto-dokumento:\n\n{0}\n\n{1}% ({2} da {3} MiB ŝargita)",
"tv_xe1": "ne povas ŝargi teksto-dosieron:\n\neraro ", "tv_xe1": "ne povas ŝargi teksto-dosieron:\n\neraro ",

View file

@ -116,7 +116,7 @@ Ls.fin = {
"ot_unpost": "unpost: poista viimeaikaiset tai keskeytä keskeneräiset lataukset", "ot_unpost": "unpost: poista viimeaikaiset tai keskeytä keskeneräiset lataukset",
"ot_bup": "bup: tiedostojen 'perus'lähetysohjelma, tukee jopa netscape 4.0", "ot_bup": "bup: tiedostojen 'perus'lähetysohjelma, tukee jopa netscape 4.0",
"ot_mkdir": "mkdir: luo uusi hakemisto", "ot_mkdir": "mkdir: luo uusi hakemisto",
"ot_md": "new-md: luo uusi markdown-dokumentti", "ot_md": "new-file: luo uusi tekstitiedosto", //m
"ot_msg": "msg: lähetä viesti palvelinlokiin", "ot_msg": "msg: lähetä viesti palvelinlokiin",
"ot_mp": "mediasoittimen asetukset", "ot_mp": "mediasoittimen asetukset",
"ot_cfg": "asetukset", "ot_cfg": "asetukset",
@ -125,7 +125,7 @@ Ls.fin = {
"ot_noie": 'Suosittelemme käyttämään uudempaa selainta.', "ot_noie": 'Suosittelemme käyttämään uudempaa selainta.',
"ab_mkdir": "luo hakemisto", "ab_mkdir": "luo hakemisto",
"ab_mkdoc": "luo markdown-tiedosto", "ab_mkdoc": "luo tekstitiedosto", //m
"ab_msg": "lähetä viesti palvelinlokiin", "ab_msg": "lähetä viesti palvelinlokiin",
"ay_path": "siirry hakemistoihin", "ay_path": "siirry hakemistoihin",
@ -437,6 +437,8 @@ Ls.fin = {
"fcp_both_b": '<a href="#" id="modal-ok">Kopioi</a><a href="#" id="modal-ng">Lähetä</a>', "fcp_both_b": '<a href="#" id="modal-ok">Kopioi</a><a href="#" id="modal-ng">Lähetä</a>',
"mk_noname": "kirjoita nimi vasemmalla olevaan tekstikenttään ennen kuin teet tuon :p", "mk_noname": "kirjoita nimi vasemmalla olevaan tekstikenttään ennen kuin teet tuon :p",
"nmd_i1": "voit myös lisätä haluamasi tiedostopäätteen, esimerkiksi <code>.txt</code>", //m
"nmd_i2": "voit luoda vain <code>.md</code>-tiedostoja, koska sinulla ei ole poistolupaa", //m
"tv_load": "Ladataan tekstidokumenttia:\n\n{0}\n\n{1}% ({2} / {3} Mt ladattu)", "tv_load": "Ladataan tekstidokumenttia:\n\n{0}\n\n{1}% ({2} / {3} Mt ladattu)",
"tv_xe1": "tekstitiedoston lataaminen epäonnistui:\n\nvirhe ", "tv_xe1": "tekstitiedoston lataaminen epäonnistui:\n\nvirhe ",

View file

@ -116,7 +116,7 @@ Ls.fra = {
"ot_unpost": "unpost: supprimer vos téléchargements récents, ou annuler ceux en cours", "ot_unpost": "unpost: supprimer vos téléchargements récents, ou annuler ceux en cours",
"ot_bup": "bup: téléverseur de base, prend même en charge netscape 4.0", "ot_bup": "bup: téléverseur de base, prend même en charge netscape 4.0",
"ot_mkdir": "mkdir: créer un nouveau répertoire", "ot_mkdir": "mkdir: créer un nouveau répertoire",
"ot_md": "new-md: créer un nouveau document markdown", "ot_md": "new-file: créer un nouveau fichier texte", //m
"ot_msg": "msg: envoyer un message au journal du serveur", "ot_msg": "msg: envoyer un message au journal du serveur",
"ot_mp": "options du lecteur multimedia", "ot_mp": "options du lecteur multimedia",
"ot_cfg": "options de configuration", "ot_cfg": "options de configuration",
@ -125,7 +125,7 @@ Ls.fra = {
"ot_noie": 'Utilisez Chrome / Firefox / Edge', "ot_noie": 'Utilisez Chrome / Firefox / Edge',
"ab_mkdir": "créer un nouveau répertoire", "ab_mkdir": "créer un nouveau répertoire",
"ab_mkdoc": "faire un nouveau document markdown", "ab_mkdoc": "nouveau fichier texte", //m
"ab_msg": "envoyer un message au journal du serveur", "ab_msg": "envoyer un message au journal du serveur",
"ay_path": "passer aux dossiers", "ay_path": "passer aux dossiers",
@ -437,6 +437,8 @@ Ls.fra = {
"fcp_both_b": '<a href="#" id="modal-ok">Copier</a><a href="#" id="modal-ng">Téléverser</a>', "fcp_both_b": '<a href="#" id="modal-ok">Copier</a><a href="#" id="modal-ng">Téléverser</a>',
"mk_noname": "entrez un nom dans le champ de texte à gauche avant de faire ça :p", "mk_noname": "entrez un nom dans le champ de texte à gauche avant de faire ça :p",
"nmd_i1": "ajoutez aussi lextension souhaitée, par exemple <code>.txt</code>", //m
"nmd_i2": "vous ne pouvez créer que des fichiers <code>.md</code> car vous navez pas la permission deffacer", //m
"tv_load": "Chargement du document texte:\n\n{0}\n\n{1}% ({2} de {3} MiB chargés)", "tv_load": "Chargement du document texte:\n\n{0}\n\n{1}% ({2} de {3} MiB chargés)",
"tv_xe1": "impossible de charger le fichier texte:\n\nerreur", "tv_xe1": "impossible de charger le fichier texte:\n\nerreur",

View file

@ -116,7 +116,7 @@ Ls.grc = {
"ot_unpost": "unpost: διαγραφή πρόσφατων μεταφορτώσεων ή ακύρωση ανολοκλήρωτων", "ot_unpost": "unpost: διαγραφή πρόσφατων μεταφορτώσεων ή ακύρωση ανολοκλήρωτων",
"ot_bup": "bup: βασικός uploader, υποστηρίζει μέχρι και netscape 4.0", "ot_bup": "bup: βασικός uploader, υποστηρίζει μέχρι και netscape 4.0",
"ot_mkdir": "mkdir: δημιουργία νέου φακέλου", "ot_mkdir": "mkdir: δημιουργία νέου φακέλου",
"ot_md": "new-md: δημιουργία νέου markdown εγγράφου", "ot_md": "new-file: δημιουργία νέου αρχείου κειμένου", //m
"ot_msg": "msg: αποστολή μηνύματος στο server log", "ot_msg": "msg: αποστολή μηνύματος στο server log",
"ot_mp": "επιλογές media player", "ot_mp": "επιλογές media player",
"ot_cfg": "επιλογές ρυθμίσεων", "ot_cfg": "επιλογές ρυθμίσεων",
@ -125,7 +125,7 @@ Ls.grc = {
"ot_noie": 'Χρησιμοποίησε Chrome / Firefox / Edge', "ot_noie": 'Χρησιμοποίησε Chrome / Firefox / Edge',
"ab_mkdir": "δημιουργία φακέλου", "ab_mkdir": "δημιουργία φακέλου",
"ab_mkdoc": "νέο markdown έγγραφο", "ab_mkdoc": "νέο αρχείο κειμένου", //m
"ab_msg": "στείλε μήνυμα στο server log", "ab_msg": "στείλε μήνυμα στο server log",
"ay_path": "πήγαινε σε φακέλους", "ay_path": "πήγαινε σε φακέλους",
@ -437,6 +437,8 @@ Ls.grc = {
"fcp_both_b": '<a href="#" id="modal-ok">Αντιγραφή</a><a href="#" id="modal-ng">Μεταφόρτωση</a>', "fcp_both_b": '<a href="#" id="modal-ok">Αντιγραφή</a><a href="#" id="modal-ng">Μεταφόρτωση</a>',
"mk_noname": "γράψε ένα όνομα στο πεδίο κειμένου αριστερά πριν το κάνεις :p", "mk_noname": "γράψε ένα όνομα στο πεδίο κειμένου αριστερά πριν το κάνεις :p",
"nmd_i1": "μπορείτε επίσης να προσθέσετε την κατάληξη που θέλετε, όπως <code>.txt</code>", //m
"nmd_i2": "μπορείτε να δημιουργήσετε μόνο αρχεία <code>.md</code> επειδή δεν έχετε δικαίωμα διαγραφής", //m
"tv_load": "Φόρτωση αρχείου κειμένου:\n\n{0}\n\n{1}% ({2} από {3} MiB φορτωμένα)", "tv_load": "Φόρτωση αρχείου κειμένου:\n\n{0}\n\n{1}% ({2} από {3} MiB φορτωμένα)",
"tv_xe1": "αδυναμία φόρτωσης αρχείου κειμένου:\n\nσφάλμα ", "tv_xe1": "αδυναμία φόρτωσης αρχείου κειμένου:\n\nσφάλμα ",

View file

@ -116,7 +116,7 @@ Ls.ita = {
"ot_unpost": "unpost: elimina i tuoi caricamenti recenti, o interrompi quelli non completati", "ot_unpost": "unpost: elimina i tuoi caricamenti recenti, o interrompi quelli non completati",
"ot_bup": "bup: uploader di base, supporta anche netscape 4.0", "ot_bup": "bup: uploader di base, supporta anche netscape 4.0",
"ot_mkdir": "mkdir: crea una nuova directory", "ot_mkdir": "mkdir: crea una nuova directory",
"ot_md": "new-md: crea un nuovo documento markdown", "ot_md": "new-file: crea un nuovo file di testo", //m
"ot_msg": "msg: invia un messaggio al log del server", "ot_msg": "msg: invia un messaggio al log del server",
"ot_mp": "opzioni lettore multimediale", "ot_mp": "opzioni lettore multimediale",
"ot_cfg": "opzioni di configurazione", "ot_cfg": "opzioni di configurazione",
@ -125,7 +125,7 @@ Ls.ita = {
"ot_noie": 'Perfavore usa Chrome / Firefox / Edge', "ot_noie": 'Perfavore usa Chrome / Firefox / Edge',
"ab_mkdir": "crea directory", "ab_mkdir": "crea directory",
"ab_mkdoc": "nuovo doc markdown", "ab_mkdoc": "nuovo file di testo", //m
"ab_msg": "invia msg al log srv", "ab_msg": "invia msg al log srv",
"ay_path": "salta alle cartelle", "ay_path": "salta alle cartelle",
@ -437,6 +437,8 @@ Ls.ita = {
"fcp_both_b": '<a href="#" id="modal-ok">Copia</a><a href="#" id="modal-ng">Carica</a>', "fcp_both_b": '<a href="#" id="modal-ok">Copia</a><a href="#" id="modal-ng">Carica</a>',
"mk_noname": "scrivi un nome nel campo di testo a sinistra prima di farlo :p", "mk_noname": "scrivi un nome nel campo di testo a sinistra prima di farlo :p",
"nmd_i1": "puoi anche aggiungere lestensione che vuoi, per esempio <code>.txt</code>", //m
"nmd_i2": "puoi creare solo file <code>.md</code> perché non hai il permesso di eliminare", //m
"tv_load": "Caricando documento di testo:\n\n{0}\n\n{1}% ({2} di {3} MiB caricati)", "tv_load": "Caricando documento di testo:\n\n{0}\n\n{1}% ({2} di {3} MiB caricati)",
"tv_xe1": "impossibile caricare file di testo:\n\nerrore ", "tv_xe1": "impossibile caricare file di testo:\n\nerrore ",

View file

@ -116,7 +116,7 @@ Ls.kor = {
"ot_unpost": "주워담기: 최근 업로드한 항목을 삭제하거나 미완료된 업로드를 중단합니다", "ot_unpost": "주워담기: 최근 업로드한 항목을 삭제하거나 미완료된 업로드를 중단합니다",
"ot_bup": "bup: 기본 업로더. 넷스케이프 4.0도 지원합니다", "ot_bup": "bup: 기본 업로더. 넷스케이프 4.0도 지원합니다",
"ot_mkdir": "mkdir: 새 디렉터리를 만듭니다", "ot_mkdir": "mkdir: 새 디렉터리를 만듭니다",
"ot_md": "new-md: 새 마크다운 문서를 만듭니다", "ot_md": "new-file: 새 텍스트 파일을 만듭니다", //m
"ot_msg": "msg: 서버 로그에 메시지를 보냅니다", "ot_msg": "msg: 서버 로그에 메시지를 보냅니다",
"ot_mp": "미디어 플레이어 옵션", "ot_mp": "미디어 플레이어 옵션",
"ot_cfg": "구성 옵션", "ot_cfg": "구성 옵션",
@ -125,7 +125,7 @@ Ls.kor = {
"ot_noie": 'Chrome / Firefox / Edge를 사용해주세요', "ot_noie": 'Chrome / Firefox / Edge를 사용해주세요',
"ab_mkdir": "디렉터리 만들기", "ab_mkdir": "디렉터리 만들기",
"ab_mkdoc": "새 마크다운 문서", "ab_mkdoc": "새 텍스트 파일", //m
"ab_msg": "서버 로그에 메시지 보내기", "ab_msg": "서버 로그에 메시지 보내기",
"ay_path": "폴더로 건너뛰기", "ay_path": "폴더로 건너뛰기",
@ -437,6 +437,8 @@ Ls.kor = {
"fcp_both_b": '<a href="#" id="modal-ok">복사</a><a href="#" id="modal-ng">업로드</a>', "fcp_both_b": '<a href="#" id="modal-ok">복사</a><a href="#" id="modal-ng">업로드</a>',
"mk_noname": "왼쪽 텍스트 필드에 이름을 먼저 입력해주세요 :p", "mk_noname": "왼쪽 텍스트 필드에 이름을 먼저 입력해주세요 :p",
"nmd_i1": "원하는 파일 확장자를 추가할 수 있습니다. 예: <code>.txt</code>", //m
"nmd_i2": "삭제 권한이 없어서 <code>.md</code> 파일만 만들 수 있습니다", //m
"tv_load": "텍스트 문서 불러오는 중:\n\n{0}\n\n{1}% ({3} MiB 중 {2} MiB 로드됨)", "tv_load": "텍스트 문서 불러오는 중:\n\n{0}\n\n{1}% ({3} MiB 중 {2} MiB 로드됨)",
"tv_xe1": "텍스트 파일을 불러올 수 없습니다:\n\n오류 ", "tv_xe1": "텍스트 파일을 불러올 수 없습니다:\n\n오류 ",

View file

@ -116,7 +116,7 @@ Ls.nld = {
"ot_unpost": "unpost: verwijder je recente uploads, of onvoltooide uploads afbreken", "ot_unpost": "unpost: verwijder je recente uploads, of onvoltooide uploads afbreken",
"ot_bup": "bup: Basisuploader, supports zelfs netscape 4.0", "ot_bup": "bup: Basisuploader, supports zelfs netscape 4.0",
"ot_mkdir": "mkdir: Maak een nieuwe map", "ot_mkdir": "mkdir: Maak een nieuwe map",
"ot_md": "new-md: Maak een nieuwe markdown bestand", "ot_md": "new-file: Maak een nieuw tekstbestand", //m
"ot_msg": "msg: Verstuur een bericht naar de server logs", "ot_msg": "msg: Verstuur een bericht naar de server logs",
"ot_mp": "Media speler opties", "ot_mp": "Media speler opties",
"ot_cfg": "Configuratie opties", "ot_cfg": "Configuratie opties",
@ -125,7 +125,7 @@ Ls.nld = {
"ot_noie": 'Gebruik alstublieft Chrome / Firefox / Edge', "ot_noie": 'Gebruik alstublieft Chrome / Firefox / Edge',
"ab_mkdir": "maak map", "ab_mkdir": "maak map",
"ab_mkdoc": "nieuw markdown doc", "ab_mkdoc": "nieuw tekstbestand", //m
"ab_msg": "verstuur msg naar srv log", "ab_msg": "verstuur msg naar srv log",
"ay_path": "skip naar mappen", "ay_path": "skip naar mappen",
@ -437,6 +437,8 @@ Ls.nld = {
"fcp_both_b": '<a href="#" id="modal-ok">Kopieer</a><a href="#" id="modal-ng">Upload</a>', "fcp_both_b": '<a href="#" id="modal-ok">Kopieer</a><a href="#" id="modal-ng">Upload</a>',
"mk_noname": "Voer een naam in het tekstveld aan de linkerkant voordat je verder gaat :p", "mk_noname": "Voer een naam in het tekstveld aan de linkerkant voordat je verder gaat :p",
"nmd_i1": "Voeg ook de gewenste extensie toe, bijvoorbeeld <code>.txt</code>", //m
"nmd_i2": "Je kunt alleen <code>.md</code>-bestanden maken omdat je geen verwijderrechten hebt", //m
"tv_load": "Tekstdocument laden:\n\n{0}\n\n{1}% ({2} van de {3} MiB geladen)", "tv_load": "Tekstdocument laden:\n\n{0}\n\n{1}% ({2} van de {3} MiB geladen)",
"tv_xe1": "Kon tekstbestand niet laden:\n\nfout ", "tv_xe1": "Kon tekstbestand niet laden:\n\nfout ",

View file

@ -114,7 +114,7 @@ Ls.nno = {
"ot_unpost": "unpost: slett filer som du nyleg har lastet opp; «angre-knappen»", "ot_unpost": "unpost: slett filer som du nyleg har lastet opp; «angre-knappen»",
"ot_bup": "bup: tradisjonell / primitiv filopplasting,$N$Nfungerar i om lag samtlege nettlesarar", "ot_bup": "bup: tradisjonell / primitiv filopplasting,$N$Nfungerar i om lag samtlege nettlesarar",
"ot_mkdir": "mkdir: lag ei ny mappe", "ot_mkdir": "mkdir: lag ei ny mappe",
"ot_md": "new-md: lag eit nytt markdown-dokument", "ot_md": "new-file: lag ein ny tekstfil",
"ot_msg": "msg: send ein beskjed åt serverloggen", "ot_msg": "msg: send ein beskjed åt serverloggen",
"ot_mp": "musikkspelarinstillinger", "ot_mp": "musikkspelarinstillinger",
"ot_cfg": "andre innstillinger", "ot_cfg": "andre innstillinger",
@ -123,7 +123,7 @@ Ls.nno = {
"ot_noie": 'Fungerer mye betre i Chrome / Firefox / Edge', "ot_noie": 'Fungerer mye betre i Chrome / Firefox / Edge',
"ab_mkdir": "lag mappe", "ab_mkdir": "lag mappe",
"ab_mkdoc": "nytt dokument", "ab_mkdoc": "ny tekstfil",
"ab_msg": "send melding", "ab_msg": "send melding",
"ay_path": "gå videre åt mapper", "ay_path": "gå videre åt mapper",
@ -435,6 +435,8 @@ Ls.nno = {
"fcp_both_b": '<a href="#" id="modal-ok">Kopiér</a><a href="#" id="modal-ng">Last opp</a>', "fcp_both_b": '<a href="#" id="modal-ok">Kopiér</a><a href="#" id="modal-ng">Last opp</a>',
"mk_noname": "skriv inn eit namn i tekstboksa åt venstre først :p", "mk_noname": "skriv inn eit namn i tekstboksa åt venstre først :p",
"nmd_i1": "leggja også til filendinga du vil, til dømes <code>.txt</code>", //m
"nmd_i2": "du kan berre laga <code>.md</code>-filer fordi du ikkje har delete-tilgang", //m
"tv_load": "Lastar inn tekstfil:\n\n{0}\n\n{1}% ({2} av {3} MiB lasta ned)", "tv_load": "Lastar inn tekstfil:\n\n{0}\n\n{1}% ({2} av {3} MiB lasta ned)",
"tv_xe1": "kunne ikkje laste tekstfil:\n\nfeil ", "tv_xe1": "kunne ikkje laste tekstfil:\n\nfeil ",

View file

@ -114,7 +114,7 @@ Ls.nor = {
"ot_unpost": "unpost: slett filer som du nylig har lastet opp; «angre-knappen»", "ot_unpost": "unpost: slett filer som du nylig har lastet opp; «angre-knappen»",
"ot_bup": "bup: tradisjonell / primitiv filopplastning,$N$Nfungerer i omtrent samtlige nettlesere", "ot_bup": "bup: tradisjonell / primitiv filopplastning,$N$Nfungerer i omtrent samtlige nettlesere",
"ot_mkdir": "mkdir: lag en ny mappe", "ot_mkdir": "mkdir: lag en ny mappe",
"ot_md": "new-md: lag et nytt markdown-dokument", "ot_md": "new-file: lag en ny tekstfil",
"ot_msg": "msg: send en beskjed til serverloggen", "ot_msg": "msg: send en beskjed til serverloggen",
"ot_mp": "musikkspiller-instillinger", "ot_mp": "musikkspiller-instillinger",
"ot_cfg": "andre innstillinger", "ot_cfg": "andre innstillinger",
@ -123,7 +123,7 @@ Ls.nor = {
"ot_noie": 'Fungerer mye bedre i Chrome / Firefox / Edge', "ot_noie": 'Fungerer mye bedre i Chrome / Firefox / Edge',
"ab_mkdir": "lag mappe", "ab_mkdir": "lag mappe",
"ab_mkdoc": "nytt dokument", "ab_mkdoc": "ny tekstfil",
"ab_msg": "send melding", "ab_msg": "send melding",
"ay_path": "gå videre til mapper", "ay_path": "gå videre til mapper",
@ -435,6 +435,8 @@ Ls.nor = {
"fcp_both_b": '<a href="#" id="modal-ok">Kopiér</a><a href="#" id="modal-ng">Last opp</a>', "fcp_both_b": '<a href="#" id="modal-ok">Kopiér</a><a href="#" id="modal-ng">Last opp</a>',
"mk_noname": "skriv inn et navn i tekstboksen til venstre først :p", "mk_noname": "skriv inn et navn i tekstboksen til venstre først :p",
"nmd_i1": "legg også til ønsket filtype, for eksempel <code>.txt</code>", //m
"nmd_i2": "du kan bare lage <code>.md</code>-filer fordi du ikke har delete-tilgang", //m
"tv_load": "Laster inn tekstfil:\n\n{0}\n\n{1}% ({2} av {3} MiB lastet ned)", "tv_load": "Laster inn tekstfil:\n\n{0}\n\n{1}% ({2} av {3} MiB lastet ned)",
"tv_xe1": "kunne ikke laste tekstfil:\n\nfeil ", "tv_xe1": "kunne ikke laste tekstfil:\n\nfeil ",

View file

@ -119,7 +119,7 @@ Ls.pol = {
"ot_unpost": "unpost: usuń ostatnio przesłane pliki lub przerwij przesyłanie", "ot_unpost": "unpost: usuń ostatnio przesłane pliki lub przerwij przesyłanie",
"ot_bup": "bup: podstawowe przesyłanie danych, wspiera nawet netscape 4.0", "ot_bup": "bup: podstawowe przesyłanie danych, wspiera nawet netscape 4.0",
"ot_mkdir": "mkdir: tworzy nowy folder", "ot_mkdir": "mkdir: tworzy nowy folder",
"ot_md": "new-md: tworzy nowy dokument markdown", "ot_md": "new-file: tworzy nowy plik tekstowy", //m
"ot_msg": "msg: wysyła wiadomość do loga serwera", "ot_msg": "msg: wysyła wiadomość do loga serwera",
"ot_mp": "opcje odtwarzacza multimediów", "ot_mp": "opcje odtwarzacza multimediów",
"ot_cfg": "opcje konfiguracji", "ot_cfg": "opcje konfiguracji",
@ -128,7 +128,7 @@ Ls.pol = {
"ot_noie": 'Użyj przeglądarki Chrome / Firefox / Edge', "ot_noie": 'Użyj przeglądarki Chrome / Firefox / Edge',
"ab_mkdir": "stwórz folder", "ab_mkdir": "stwórz folder",
"ab_mkdoc": "stwórz dok. markdown", "ab_mkdoc": "nowy plik tekstowy", //m
"ab_msg": "wyślij wiad. do logów serwera", "ab_msg": "wyślij wiad. do logów serwera",
"ay_path": "przejdź do folderów", "ay_path": "przejdź do folderów",
@ -440,6 +440,8 @@ Ls.pol = {
"fcp_both_b": '<a href="#" id="modal-ok">Kopiuj</a><a href="#" id="modal-ng">Prześlij</a>', "fcp_both_b": '<a href="#" id="modal-ok">Kopiuj</a><a href="#" id="modal-ng">Prześlij</a>',
"mk_noname": "wpisz nazwę do pola po lewej zanim to zrobisz :p", "mk_noname": "wpisz nazwę do pola po lewej zanim to zrobisz :p",
"nmd_i1": "możesz też dodać wybrane rozszerzenie, np. <code>.txt</code>", //m
"nmd_i2": "możesz tworzyć tylko pliki <code>.md</code>, ponieważ nie masz uprawnień do usuwania", //m
"tv_load": "Wczytywanie pliku tekstowego:\n\n{0}\n\n{1}% (wczytano {2} z {3} MiB)", "tv_load": "Wczytywanie pliku tekstowego:\n\n{0}\n\n{1}% (wczytano {2} z {3} MiB)",
"tv_xe1": "nie udało się wczytać pliku:\n\nbłąd ", "tv_xe1": "nie udało się wczytać pliku:\n\nbłąd ",

View file

@ -116,7 +116,7 @@ Ls.por = {
"ot_unpost": "despublicar: excluir seus uploads recentes, ou abortar os que não foram concluídos", "ot_unpost": "despublicar: excluir seus uploads recentes, ou abortar os que não foram concluídos",
"ot_bup": "bup: uploader básico, até suporta netscape 4.0", "ot_bup": "bup: uploader básico, até suporta netscape 4.0",
"ot_mkdir": "mkdir: criar um novo diretório", "ot_mkdir": "mkdir: criar um novo diretório",
"ot_md": "new-md: criar um novo documento markdown", "ot_md": "new-file: criar um novo ficheiro de texto", //m
"ot_msg": "msg: enviar uma mensagem para o log do servidor", "ot_msg": "msg: enviar uma mensagem para o log do servidor",
"ot_mp": "opções do reprodutor de mídia", "ot_mp": "opções do reprodutor de mídia",
"ot_cfg": "opções de configuração", "ot_cfg": "opções de configuração",
@ -125,7 +125,7 @@ Ls.por = {
"ot_noie": 'Por favor, use Chrome / Firefox / Edge', "ot_noie": 'Por favor, use Chrome / Firefox / Edge',
"ab_mkdir": "criar diretório", "ab_mkdir": "criar diretório",
"ab_mkdoc": "novo documento markdown", "ab_mkdoc": "novo ficheiro de texto", //m
"ab_msg": "enviar msg para o log do srv", "ab_msg": "enviar msg para o log do srv",
"ay_path": "pular para pastas", "ay_path": "pular para pastas",
@ -437,6 +437,8 @@ Ls.por = {
"fcp_both_b": '<a href="#" id="modal-ok">Copiar</a><a href="#" id="modal-ng">Enviar</a>', "fcp_both_b": '<a href="#" id="modal-ok">Copiar</a><a href="#" id="modal-ng">Enviar</a>',
"mk_noname": "digite um nome no campo de texto à esquerda antes de fazer isso :p", "mk_noname": "digite um nome no campo de texto à esquerda antes de fazer isso :p",
"nmd_i1": "também pode adicionar a extensão desejada, por exemplo <code>.txt</code>", //m
"nmd_i2": "só pode criar ficheiros <code>.md</code> porque não tem permissão para apagar", //m
"tv_load": "Carregando documento de texto:\n\n{0}\n\n{1}% ({2} de {3} MiB carregados)", "tv_load": "Carregando documento de texto:\n\n{0}\n\n{1}% ({2} de {3} MiB carregados)",
"tv_xe1": "não foi possível carregar o arquivo de texto:\n\nerro ", "tv_xe1": "não foi possível carregar o arquivo de texto:\n\nerro ",

View file

@ -116,7 +116,7 @@ Ls.rus = {
"ot_unpost": "unpost: удалить ваши недавние загрузки и отменить незавершённые", "ot_unpost": "unpost: удалить ваши недавние загрузки и отменить незавершённые",
"ot_bup": "bup: легковесный загрузчик файлов, поддерживает даже netscape 4.0", "ot_bup": "bup: легковесный загрузчик файлов, поддерживает даже netscape 4.0",
"ot_mkdir": "mkdir: создать новую папку", "ot_mkdir": "mkdir: создать новую папку",
"ot_md": "new-md: создать новый markdown-документ", "ot_md": "new-file: создать новый текстовый файл", //m
"ot_msg": "msg: отправить сообщение в лог сервера", "ot_msg": "msg: отправить сообщение в лог сервера",
"ot_mp": "настройка медиаплеера", "ot_mp": "настройка медиаплеера",
"ot_cfg": "остальные настройки", "ot_cfg": "остальные настройки",
@ -125,7 +125,7 @@ Ls.rus = {
"ot_noie": 'Пожалуйста, используйте Chrome / Firefox / Edge', "ot_noie": 'Пожалуйста, используйте Chrome / Firefox / Edge',
"ab_mkdir": "создать папку", "ab_mkdir": "создать папку",
"ab_mkdoc": "создать markdown-документ", "ab_mkdoc": "создать текстовый файл", //m
"ab_msg": "отправить сообщение в лог сервера", "ab_msg": "отправить сообщение в лог сервера",
"ay_path": "перейти к папкам", "ay_path": "перейти к папкам",
@ -437,6 +437,8 @@ Ls.rus = {
"fcp_both_b": '<a href="#" id="modal-ok">Скопировать</a><a href="#" id="modal-ng">Загрузить</a>', "fcp_both_b": '<a href="#" id="modal-ok">Скопировать</a><a href="#" id="modal-ng">Загрузить</a>',
"mk_noname": "введите имя в текстовое поле слева перед тем, как это делать :p", "mk_noname": "введите имя в текстовое поле слева перед тем, как это делать :p",
"nmd_i1": "вы также можете указать нужное расширение, например <code>.txt</code>", //m
"nmd_i2": "вы можете создавать только файлы <code>.md</code>, так как у вас нет разрешения на удаление", //m
"tv_load": "Загружаю текстовый документ:\n\n{0}\n\n{1}% ({2} из {3} МиБ загружено)", "tv_load": "Загружаю текстовый документ:\n\n{0}\n\n{1}% ({2} из {3} МиБ загружено)",
"tv_xe1": "не удалось загрузить текстовый файл:\n\nошибка ", "tv_xe1": "не удалось загрузить текстовый файл:\n\nошибка ",

View file

@ -116,7 +116,7 @@ Ls.spa = {
"ot_unpost": "dessubir: elimina tus subidas recientes, o aborta las inacabadas", "ot_unpost": "dessubir: elimina tus subidas recientes, o aborta las inacabadas",
"ot_bup": "bup: uploader básico, soporta hasta netscape 4.0", "ot_bup": "bup: uploader básico, soporta hasta netscape 4.0",
"ot_mkdir": "mkdir: crear un nuevo directorio", "ot_mkdir": "mkdir: crear un nuevo directorio",
"ot_md": "new-md: crear un nuevo documento markdown", "ot_md": "new-file: crear un nuevo archivo de texto", //m
"ot_msg": "msg: enviar un mensaje al registro del servidor", "ot_msg": "msg: enviar un mensaje al registro del servidor",
"ot_mp": "opciones del reproductor multimedia", "ot_mp": "opciones del reproductor multimedia",
"ot_cfg": "opciones de configuración", "ot_cfg": "opciones de configuración",
@ -125,7 +125,7 @@ Ls.spa = {
"ot_noie": "Por favor, usa Chrome / Firefox / Edge", "ot_noie": "Por favor, usa Chrome / Firefox / Edge",
"ab_mkdir": "crear directorio", "ab_mkdir": "crear directorio",
"ab_mkdoc": "nuevo documento markdown", "ab_mkdoc": "nuevo archivo de texto", //m
"ab_msg": "enviar msg al registro del servidor", "ab_msg": "enviar msg al registro del servidor",
"ay_path": "saltar a carpetas", "ay_path": "saltar a carpetas",
@ -436,6 +436,8 @@ Ls.spa = {
"fcp_both_b": "<a href=\"#\" id=\"modal-ok\">Copiar</a><a href=\"#\" id=\"modal-ng\">Subir</a>", "fcp_both_b": "<a href=\"#\" id=\"modal-ok\">Copiar</a><a href=\"#\" id=\"modal-ng\">Subir</a>",
"mk_noname": "escribe un nombre en el campo de texto de la izquierda antes de hacer eso :p", "mk_noname": "escribe un nombre en el campo de texto de la izquierda antes de hacer eso :p",
"nmd_i1": "también puedes añadir la extensión que quieras, por ejemplo <code>.txt</code>", //m
"nmd_i2": "solo puedes crear archivos <code>.md</code> porque no tienes permiso para borrar", //m
"tv_load": "Cargando documento de texto:\n\n{0}\n\n{1}% ({2} de {3} MiB cargados)", "tv_load": "Cargando documento de texto:\n\n{0}\n\n{1}% ({2} de {3} MiB cargados)",
"tv_xe1": "no se pudo cargar el archivo de texto:\n\nerror ", "tv_xe1": "no se pudo cargar el archivo de texto:\n\nerror ",

View file

@ -116,7 +116,7 @@ Ls.swe = {
"ot_unpost": "unpost: radera dina senaste uppladdningar, eller avbryt pågående sådana", "ot_unpost": "unpost: radera dina senaste uppladdningar, eller avbryt pågående sådana",
"ot_bup": "bup: enkel uppladdare, stödjer t o m netscape 4.0", "ot_bup": "bup: enkel uppladdare, stödjer t o m netscape 4.0",
"ot_mkdir": "mkdir: skapa en ny mapp", "ot_mkdir": "mkdir: skapa en ny mapp",
"ot_md": "new-md: skapa ett nytt markdown-dokument", "ot_md": "new-file: skapa en ny textfil",
"ot_msg": "msg: skicka ett meddelande till serverloggen", "ot_msg": "msg: skicka ett meddelande till serverloggen",
"ot_mp": "mediaspelarinställningar", "ot_mp": "mediaspelarinställningar",
"ot_cfg": "konfigurationsinställningar", "ot_cfg": "konfigurationsinställningar",
@ -125,7 +125,7 @@ Ls.swe = {
"ot_noie": 'Var vänlig använd Chrome / Firefox / Edge', "ot_noie": 'Var vänlig använd Chrome / Firefox / Edge',
"ab_mkdir": "skapa mapp", "ab_mkdir": "skapa mapp",
"ab_mkdoc": "nytt markdown-dokument", "ab_mkdoc": "ny textfil",
"ab_msg": "skicka medd. till serverlogg", "ab_msg": "skicka medd. till serverlogg",
"ay_path": "hoppa till mappar", "ay_path": "hoppa till mappar",
@ -437,6 +437,8 @@ Ls.swe = {
"fcp_both_b": '<a href="#" id="modal-ok">Kopiera</a><a href="#" id="modal-ng">Ladda upp</a>', "fcp_both_b": '<a href="#" id="modal-ok">Kopiera</a><a href="#" id="modal-ng">Ladda upp</a>',
"mk_noname": "skriv ett namn i fältet till vänster först :p", "mk_noname": "skriv ett namn i fältet till vänster först :p",
"nmd_i1": "lägg också till filändelsen du vill ha, till exempel <code>.txt</code>", //m
"nmd_i2": "du kan bara skapa <code>.md</code>-filer eftersom du inte har borttagningsbehörighet", //m
"tv_load": "Laddar textfil:\n\n{0}\n\n{1}% ({2} av {3} MiB laddat)", "tv_load": "Laddar textfil:\n\n{0}\n\n{1}% ({2} av {3} MiB laddat)",
"tv_xe1": "kunde ej ladda textfil:\n\nfel ", "tv_xe1": "kunde ej ladda textfil:\n\nfel ",

View file

@ -116,7 +116,7 @@ Ls.tur = {
"ot_unpost": "unpost: son yüklemelerinizi silin veya tamamlanmamış olanları iptal edin", "ot_unpost": "unpost: son yüklemelerinizi silin veya tamamlanmamış olanları iptal edin",
"ot_bup": "bup: temel yükleyici, hatta netscape 4.0'ı destekler", "ot_bup": "bup: temel yükleyici, hatta netscape 4.0'ı destekler",
"ot_mkdir": "mkdir: yeni bir dizin oluştur", "ot_mkdir": "mkdir: yeni bir dizin oluştur",
"ot_md": "new-md: yeni bir markdown belgesi oluştur", "ot_md": "new-file: yeni bir metin dosyası oluştur", //m
"ot_msg": "msg: sunucu günlüğüne bir mesaj gönder", "ot_msg": "msg: sunucu günlüğüne bir mesaj gönder",
"ot_mp": "medya oynatıcı seçenekleri", "ot_mp": "medya oynatıcı seçenekleri",
"ot_cfg": "konfigürasyon seçenekleri", "ot_cfg": "konfigürasyon seçenekleri",
@ -125,7 +125,7 @@ Ls.tur = {
"ot_noie": 'Lütfen Chrome / Firefox / Edge kullanın', "ot_noie": 'Lütfen Chrome / Firefox / Edge kullanın',
"ab_mkdir": "dizin oluştur", "ab_mkdir": "dizin oluştur",
"ab_mkdoc": "yeni markdown belgesi", "ab_mkdoc": "yeni metin dosyası", //m
"ab_msg": "sunucu günlüğüne mesaj gönder", "ab_msg": "sunucu günlüğüne mesaj gönder",
"ay_path": "klasörlere atla", "ay_path": "klasörlere atla",
@ -437,6 +437,8 @@ Ls.tur = {
"fcp_both_b": '<a href="#" id="modal-ok">Kopyala</a><a href="#" id="modal-ng">Yükle</a>', "fcp_both_b": '<a href="#" id="modal-ok">Kopyala</a><a href="#" id="modal-ng">Yükle</a>',
"mk_noname": "bunu yapmadan önce soldaki boşluğa bir şeyler yazsana :p", "mk_noname": "bunu yapmadan önce soldaki boşluğa bir şeyler yazsana :p",
"nmd_i1": "ayrıca istediğin dosya uzantısını ekleyebilirsin, örneğin <code>.txt</code>", //m
"nmd_i2": "silme iznin olmadığı için yalnızca <code>.md</code> dosyaları oluşturabilirsin", //m
"tv_load": "Metin belgesi yükleniyor:\n\n{0}\n\n{1}% ({2} of {3} MiB yüklendi)", "tv_load": "Metin belgesi yükleniyor:\n\n{0}\n\n{1}% ({2} of {3} MiB yüklendi)",
"tv_xe1": "metin dosyası yüklenemedi:\n\nhata ", "tv_xe1": "metin dosyası yüklenemedi:\n\nhata ",

View file

@ -116,7 +116,7 @@ Ls.ukr = {
"ot_unpost": "скасувати: видалити недавні завантаження або перервати незавершені", "ot_unpost": "скасувати: видалити недавні завантаження або перервати незавершені",
"ot_bup": "bup: основний завантажувач, підтримує навіть netscape 4.0", "ot_bup": "bup: основний завантажувач, підтримує навіть netscape 4.0",
"ot_mkdir": "mkdir: створити нову папку", "ot_mkdir": "mkdir: створити нову папку",
"ot_md": "new-md: створити новий markdown документ", "ot_md": "new-file: створити новий текстовий файл", //m
"ot_msg": "msg: надіслати повідомлення в лог сервера", "ot_msg": "msg: надіслати повідомлення в лог сервера",
"ot_mp": "налаштування медіаплеєра", "ot_mp": "налаштування медіаплеєра",
"ot_cfg": "параметри конфігурації", "ot_cfg": "параметри конфігурації",
@ -125,7 +125,7 @@ Ls.ukr = {
"ot_noie": 'Будь ласка, використовуйте Chrome / Firefox / Edge', "ot_noie": 'Будь ласка, використовуйте Chrome / Firefox / Edge',
"ab_mkdir": "створити папку", "ab_mkdir": "створити папку",
"ab_mkdoc": "новий markdown документ", "ab_mkdoc": "новий текстовий файл", //m
"ab_msg": "надіслати повідомлення в лог сервера", "ab_msg": "надіслати повідомлення в лог сервера",
"ay_path": "перейти до папок", "ay_path": "перейти до папок",
@ -437,6 +437,8 @@ Ls.ukr = {
"fcp_both_b": '<a href="#" id="modal-ok">Скопіювати</a><a href="#" id="modal-ng">Завантажити</a>', "fcp_both_b": '<a href="#" id="modal-ok">Скопіювати</a><a href="#" id="modal-ng">Завантажити</a>',
"mk_noname": "введіть ім'я в текстове поле зліва перед тим, як робити це :p", "mk_noname": "введіть ім'я в текстове поле зліва перед тим, як робити це :p",
"nmd_i1": "ви також можете додати потрібне розширення, наприклад <code>.txt</code>", //m
"nmd_i2": "ви можете створювати тільки файли <code>.md</code>, оскільки не маєте дозволу на видалення", //m
"tv_load": "Завантаження текстового документа:\n\n{0}\n\n{1}% ({2} з {3} MiB завантажено)", "tv_load": "Завантаження текстового документа:\n\n{0}\n\n{1}% ({2} з {3} MiB завантажено)",
"tv_xe1": "не вдалося завантажити текстовий файл:\n\nпомилка ", "tv_xe1": "не вдалося завантажити текстовий файл:\n\nпомилка ",

View file

@ -1,3 +1,43 @@
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
# 2025-1025-1918 `v1.19.19` copyparty.eu マークII
## 🩹 bugfixes
* fix building the archlinux package e3524d85
* otherwise identical to [v1.19.18](https://github.com/9001/copyparty/releases/tag/v1.19.18)
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
# 2025-1025-1434 `v1.19.18` copyparty.eu
## 🧪 new features
* #949 when all uploads have finished, the client (both the browser and u2c) sends a message to the server saying it's done db87ea5c
* #941 [copyparty-en.pyz](https://github.com/9001/copyparty/releases/latest/download/copyparty-en.pyz), yet another copyparty variant, with enterprise-friendly tweaks:
* does not include the smb-server, so antivirus doesn't think it's malware 7f5810f1
* english-only, because antivirus apparently hates certain translations too 7f5810f1
* renamed the webdav-config `.bat` to `.txt` because clearly only one of those are "dangerous" b624a387
* show volumes with permssion `h` in the navpane fff7291d
* #937 global-option `--notooltips` to default-disable tooltips a325353b
## 🩹 bugfixes
* #948 fix the u2c `--dr` option when the server is running on windows d3dd3456
* fix crash on startup when using volflags `unlistc*` and the parent folder is not a volume cdd5e78a
* `og` / opengraph / discord-embed fixes:
* using the `h` permission could result in unexpected 404 c9e45c12
* a single-file volume could make filenames in its parent volume unintentionally visible 36ab77e0
* this would only happen when combined with `--og`
* fix some harmless warnings from single-file volumes b1efc006
* fix filesize-colors in selected rows 1c17b63b
## 🔧 other changes
* releases can now also be downloaded from https://copyparty.eu/ 547a7ab1
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
# 2025-1017-2313 `v1.19.17` read:cbz + re:ftp # 2025-1017-2313 `v1.19.17` read:cbz + re:ftp

View file

@ -85,6 +85,11 @@ filt=
wget https://github.com/9001/copyparty/releases/latest/download/copyparty-sfx.py -O $fp wget https://github.com/9001/copyparty/releases/latest/download/copyparty-sfx.py -O $fp
} }
# enable arm32 crossbuild from aarch64 (macbook or whatever)
[ $(uname -m) = aarch64 ] && [ ! -e /proc/sys/fs/binfmt_misc/qemu-arm ] &&
echo ":qemu-arm:M:0:\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-arm-static:F" |
sudo tee >/dev/null /proc/sys/fs/binfmt_misc/register
# kill abandoned builders # kill abandoned builders
ps aux | awk '/bin\/qemu-[^-]+-static/{print$2}' | xargs -r kill -9 ps aux | awk '/bin\/qemu-[^-]+-static/{print$2}' | xargs -r kill -9

View file

@ -10,6 +10,7 @@ gtar=$(command -v gtar || command -v gnutar) || true
sed() { gsed "$@"; } sed() { gsed "$@"; }
find() { gfind "$@"; } find() { gfind "$@"; }
sort() { gsort "$@"; } sort() { gsort "$@"; }
nproc() { gnproc; }
command -v grealpath >/dev/null && command -v grealpath >/dev/null &&
realpath() { grealpath "$@"; } realpath() { grealpath "$@"; }
} }

View file

@ -584,7 +584,7 @@ gzres() {
$pk "$f" & $pk "$f" &
done < <( done < <(
find -printf '%s %p\n' | find -printf '%s %p\n' |
grep -E '\.(js|css)$|/web/a/[^_].*\.(py|txt)$' | grep -E '\.(js|css)$|/web/a/.*\.txt$' |
grep -vF /deps/ | grep -vF /deps/ |
sort -nr sort -nr
) )

View file

@ -145,7 +145,7 @@ Ls.hmn = {
"ot_unpost": "unpost: delete your recent uploads, or abort unfinished ones", "ot_unpost": "unpost: delete your recent uploads, or abort unfinished ones",
"ot_bup": "bup: basic uploader, even supports netscape 4.0", "ot_bup": "bup: basic uploader, even supports netscape 4.0",
"ot_mkdir": "mkdir: create a new directory", "ot_mkdir": "mkdir: create a new directory",
"ot_md": "new-md: create a new markdown document", "ot_md": "new-file: create a new textfile",
"ot_msg": "msg: send a message to the server log", "ot_msg": "msg: send a message to the server log",
"ot_mp": "media player options", "ot_mp": "media player options",
"ot_cfg": "configuration options", "ot_cfg": "configuration options",
@ -154,7 +154,7 @@ Ls.hmn = {
"ot_noie": 'Please use Chrome / Firefox / Edge', "ot_noie": 'Please use Chrome / Firefox / Edge',
"ab_mkdir": "make directory", "ab_mkdir": "make directory",
"ab_mkdoc": "new markdown doc", "ab_mkdoc": "new textfile",
"ab_msg": "send msg to srv log", "ab_msg": "send msg to srv log",
"ay_path": "skip to folders", "ay_path": "skip to folders",
@ -466,6 +466,8 @@ Ls.hmn = {
"fcp_both_b": '<a href="#" id="modal-ok">Copy</a><a href="#" id="modal-ng">Upload</a>', "fcp_both_b": '<a href="#" id="modal-ok">Copy</a><a href="#" id="modal-ng">Upload</a>',
"mk_noname": "type a name into the text field on the left before you do that :p", "mk_noname": "type a name into the text field on the left before you do that :p",
"nmd_i1": "also add the file extension you want, for example <code>.md</code>",
"nmd_i2": "you can only create <code>.md</code> files because you don't have the delete-permission",
"tv_load": "Loading text document:\n\n{0}\n\n{1}% ({2} of {3} MiB loaded)", "tv_load": "Loading text document:\n\n{0}\n\n{1}% ({2} of {3} MiB loaded)",
"tv_xe1": "could not load textfile:\n\nerror ", "tv_xe1": "could not load textfile:\n\nerror ",