mirror of
https://github.com/9001/copyparty.git
synced 2026-02-26 21:43:08 -07:00
Merge branch '9001:hovudstraum' into nix-webdebs-but-better
This commit is contained in:
commit
6a906021e1
1
.gitattributes
vendored
1
.gitattributes
vendored
|
|
@ -4,3 +4,4 @@
|
|||
|
||||
*.png binary
|
||||
*.gif binary
|
||||
*.gz binary
|
||||
|
|
|
|||
22
README.md
22
README.md
|
|
@ -87,6 +87,7 @@ built in Norway 🇳🇴 with contributions from [not-norway](https://github.com
|
|||
* [other flags](#other-flags)
|
||||
* [database location](#database-location) - in-volume (`.hist/up2k.db`, default) or somewhere else
|
||||
* [metadata from audio files](#metadata-from-audio-files) - set `-e2t` to index tags on upload
|
||||
* [metadata from xattrs](#metadata-from-xattrs) - unix extended file attributes
|
||||
* [file parser plugins](#file-parser-plugins) - provide custom parsers to index additional tags
|
||||
* [event hooks](#event-hooks) - trigger a program on uploads, renames etc ([examples](./bin/hooks/))
|
||||
* [zeromq](#zeromq) - event-hooks can send zeromq messages
|
||||
|
|
@ -398,6 +399,8 @@ same order here too
|
|||
|
||||
* [Firefox issue 1790500](https://bugzilla.mozilla.org/show_bug.cgi?id=1790500) -- entire browser can crash after uploading ~4000 small files
|
||||
|
||||
* Windows: Uploading from a webbrowser may fail with "directory iterator got stuck" due to the [max path length](https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry); try moving the files somewhere shorter before uploading
|
||||
|
||||
* Android: music playback randomly stops due to [battery usage settings](#fix-unreliable-playback-on-android)
|
||||
|
||||
* iPhones: the volume control doesn't work because [apple doesn't want it to](https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html#//apple_ref/doc/uid/TP40009523-CH5-SW11)
|
||||
|
|
@ -1877,6 +1880,23 @@ see the beautiful mess of a dictionary in [mtag.py](https://github.com/9001/copy
|
|||
`--mtag-to` sets the tag-scan timeout; very high default (60 sec) to cater for zfs and other randomly-freezing filesystems. Lower values like 10 are usually safe, allowing for faster processing of tricky files
|
||||
|
||||
|
||||
### metadata from xattrs
|
||||
|
||||
unix extended file attributes (Linux-only) can be indexed into the db and made searchable;
|
||||
|
||||
* `--db-xattr user.foo,user.bar` will index the xattrs `user.foo` and `user.bar`,
|
||||
* `--db-xattr user.foo=foo,user.bar=bar` will index them with the names `foo` and `bar`,
|
||||
* `--db-xattr ~~user.foo,user.bar` will index everything *except* `user.foo` and `user.bar`,
|
||||
* `--db-xattr ~~` will index everything
|
||||
|
||||
however note that the tags must also be enabled with `-mte` so here are some complete examples:
|
||||
* `-e2ts --db-xattr user.foo,user.bar -mte +user.foo,user.bar`
|
||||
* `-e2ts --db-xattr user.foo=foo,user.bar=bar -mte +foo,bar`
|
||||
|
||||
as for actually adding the xattr `user.foo` to a file in the first place,
|
||||
* `setfattr -n user.foo -v 'utsikt fra fløytoppen' photo.jpg`
|
||||
|
||||
|
||||
## file parser plugins
|
||||
|
||||
provide custom parsers to index additional tags, also see [./bin/mtag/README.md](./bin/mtag/README.md)
|
||||
|
|
@ -2235,7 +2255,7 @@ example webserver / reverse-proxy configs:
|
|||
* [lighttpd subdomain](contrib/lighttpd/subdomain.conf) -- entire domain/subdomain
|
||||
* [lighttpd subpath](contrib/lighttpd/subpath.conf) -- location-based (not optimal, but in case you need it)
|
||||
* [nginx config](contrib/nginx/copyparty.conf) -- recommended
|
||||
* [traefik config](contrib/traefik/copyparty.yaml)
|
||||
* [traefik config](contrib/traefik/copyparty.yaml) -- only use v3.6.7 or newer [due to CVE-2025-66490](https://github.com/9001/copyparty/issues/1205)
|
||||
|
||||
|
||||
### real-ip
|
||||
|
|
|
|||
24
bin/u2c.py
24
bin/u2c.py
|
|
@ -1,8 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
S_VERSION = "2.18"
|
||||
S_BUILD_DT = "2026-01-02"
|
||||
S_VERSION = "2.19"
|
||||
S_BUILD_DT = "2026-01-18"
|
||||
|
||||
"""
|
||||
u2c.py: upload to copyparty
|
||||
|
|
@ -100,7 +100,7 @@ except:
|
|||
ub64enc = base64.urlsafe_b64encode
|
||||
|
||||
|
||||
class BadAuth(Exception):
|
||||
class Fatal(Exception):
|
||||
pass
|
||||
|
||||
|
||||
|
|
@ -835,10 +835,15 @@ def handshake(ar, file, search):
|
|||
url = ""
|
||||
url = ar.vtop + url
|
||||
|
||||
t0 = time.time()
|
||||
tmax = t0 + ar.t_hs
|
||||
while True:
|
||||
sc = 600
|
||||
txt = ""
|
||||
t0 = time.time()
|
||||
t1 = time.time()
|
||||
if t1 >= tmax:
|
||||
print("\nERROR: server offline for longer than --t-hs; giving up")
|
||||
raise Fatal()
|
||||
try:
|
||||
zs = json.dumps(req, separators=(",\n", ": "))
|
||||
sc, txt = web.req("POST", url, {}, zs.encode("utf-8"), MJ)
|
||||
|
|
@ -861,11 +866,11 @@ def handshake(ar, file, search):
|
|||
return [], False
|
||||
elif sc == 403 or sc == 401:
|
||||
print("\nERROR: login required, or wrong password:\n%s" % (txt,))
|
||||
raise BadAuth()
|
||||
raise Fatal()
|
||||
|
||||
t = "handshake failed, retrying: %s\n t0=%.3f t1=%.3f td=%.3f\n %s\n\n"
|
||||
t = "handshake failed, retrying: %s\n t0=%.3f t1=%.3f t2=%.3f td1=%.3f td2=%.3f\n %s\n\n"
|
||||
now = time.time()
|
||||
eprint(t % (file.name, t0, now, now - t0, em))
|
||||
eprint(t % (file.name, t0, t1, now, now - t0, now - t1, em))
|
||||
time.sleep(ar.cd)
|
||||
|
||||
try:
|
||||
|
|
@ -1051,7 +1056,7 @@ class Ctl(object):
|
|||
print(" hs...")
|
||||
try:
|
||||
hs, _ = handshake(self.ar, file, search)
|
||||
except BadAuth:
|
||||
except Fatal:
|
||||
sys.exit(1)
|
||||
|
||||
if search:
|
||||
|
|
@ -1356,7 +1361,7 @@ class Ctl(object):
|
|||
|
||||
try:
|
||||
hs, sprs = handshake(self.ar, file, search)
|
||||
except BadAuth:
|
||||
except Fatal:
|
||||
self.panik = 1
|
||||
break
|
||||
|
||||
|
|
@ -1591,6 +1596,7 @@ NOTE: if server has --usernames enabled, then password is "username:password"
|
|||
ap.add_argument("-ns", action="store_true", help="no status panel (for slow consoles and macos)")
|
||||
ap.add_argument("--cxp", type=float, metavar="SEC", default=57, help="assume http connections expired after SEConds")
|
||||
ap.add_argument("--cd", type=float, metavar="SEC", default=5, help="delay before reattempting a failed handshake/upload")
|
||||
ap.add_argument("--t-hs", type=float, metavar="SEC", default=186, help="crash if handshakes fail due to server-offline for this long")
|
||||
ap.add_argument("--safe", action="store_true", help="use simple fallback approach")
|
||||
ap.add_argument("-z", action="store_true", help="ZOOMIN' (skip uploading files if they exist at the destination with the ~same last-modified timestamp, so same as yolo / turbo with date-chk but even faster)")
|
||||
|
||||
|
|
|
|||
|
|
@ -69,11 +69,8 @@ in
|
|||
options.services.copyparty = {
|
||||
enable = mkEnableOption "web-based file manager";
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.copyparty;
|
||||
defaultText = "pkgs.copyparty";
|
||||
description = ''
|
||||
package = mkPackageOption pkgs "copyparty" {
|
||||
extraDescription = ''
|
||||
Package of the application to run, exposed for overriding purposes.
|
||||
'';
|
||||
};
|
||||
|
|
@ -82,7 +79,7 @@ in
|
|||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Make a shell script wrapper called 'copyparty-hash' with all options set here,
|
||||
Make a shell script wrapper called {command}`copyparty-hash` with all options set here,
|
||||
that launches the hashing cli.
|
||||
'';
|
||||
};
|
||||
|
|
@ -117,9 +114,9 @@ in
|
|||
type = types.attrs;
|
||||
description = ''
|
||||
Global settings to apply.
|
||||
Directly maps to values in the [global] section of the copyparty config.
|
||||
Directly maps to values in the `[global]` section of the copyparty config.
|
||||
Cannot set "c" or "hist", those are set by this module.
|
||||
See `${getExe cfg.package} --help` for more details.
|
||||
See {command}`copyparty --help` for more details.
|
||||
'';
|
||||
default = {
|
||||
i = "127.0.0.1";
|
||||
|
|
@ -138,7 +135,7 @@ in
|
|||
globalExtraConfig = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = "Appended to the end of the [global] section verbatim. This is useful for flags which are used in a repeating manner (e.g. ipu: 255.255.255.1=user) which can't be repeated in the settings = {} attribute set.";
|
||||
description = "Appended to the end of the `[global]` section verbatim. This is useful for flags which are used in a repeating manner (e.g. `ipu: 255.255.255.1=user`) which can't be repeated in the settings = {} attribute set.";
|
||||
};
|
||||
|
||||
accounts = mkOption {
|
||||
|
|
@ -201,21 +198,21 @@ in
|
|||
Attribute list of permissions and the users to apply them to.
|
||||
|
||||
The key must be a string containing any combination of allowed permission:
|
||||
"r" (read): list folder contents, download files
|
||||
"w" (write): upload files; need "r" to see the uploads
|
||||
"m" (move): move files and folders; need "w" at destination
|
||||
"d" (delete): permanently delete files and folders
|
||||
"g" (get): download files, but cannot see folder contents
|
||||
"G" (upget): "get", but can see filekeys of their own uploads
|
||||
"h" (html): "get", but folders return their index.html
|
||||
"a" (admin): can see uploader IPs, config-reload
|
||||
* "r" (read): list folder contents, download files
|
||||
* "w" (write): upload files; need "r" to see the uploads
|
||||
* "m" (move): move files and folders; need "w" at destination
|
||||
* "d" (delete): permanently delete files and folders
|
||||
* "g" (get): download files, but cannot see folder contents
|
||||
* "G" (upget): "get", but can see filekeys of their own uploads
|
||||
* "h" (html): "get", but folders return their index.html
|
||||
* "a" (admin): can see uploader IPs, config-reload
|
||||
|
||||
For example: "rwmd"
|
||||
|
||||
The value must be one of:
|
||||
an account name, defined in `accounts`
|
||||
a list of account names
|
||||
"*", which means "any account"
|
||||
* an account name, defined in `accounts`
|
||||
* a list of account names
|
||||
* "*", which means "any account"
|
||||
'';
|
||||
example = literalExpression ''
|
||||
{
|
||||
|
|
@ -230,7 +227,7 @@ in
|
|||
type = types.attrs;
|
||||
description = ''
|
||||
Attribute list of volume flags to apply.
|
||||
See `${getExe cfg.package} --help-flags` for more details.
|
||||
See {command}`copyparty --help-flags` for more details.
|
||||
'';
|
||||
example = literalExpression ''
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
pkgname=copyparty
|
||||
pkgver="1.20.1"
|
||||
pkgver="1.20.4"
|
||||
pkgrel=1
|
||||
pkgdesc="File server with accelerated resumable uploads, dedup, WebDAV, SFTP, FTP, TFTP, zeroconf, media indexer, thumbnails++"
|
||||
arch=("any")
|
||||
|
|
@ -24,7 +24,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")
|
||||
backup=("etc/${pkgname}/copyparty.conf" )
|
||||
sha256sums=("4f513ca9e3d1c11a7bb4e1a8a925dda2449b9565e91f6ef7cbe10367fa4e2935")
|
||||
sha256sums=("25dac1edc91c5228d24ef4d07c31c07331cf697951afe31883fba74e2d102cc2")
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/${pkgname}-${pkgver}/copyparty/web"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
|
||||
pkgname=copyparty
|
||||
pkgver=1.20.1
|
||||
pkgver=1.20.4
|
||||
pkgrel=1
|
||||
pkgdesc="File server with accelerated resumable uploads, dedup, WebDAV, SFTP, FTP, TFTP, zeroconf, media indexer, thumbnails++"
|
||||
arch=("any")
|
||||
|
|
@ -21,7 +21,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")
|
||||
backup=("/etc/${pkgname}.d/init" )
|
||||
sha256sums=("4f513ca9e3d1c11a7bb4e1a8a925dda2449b9565e91f6ef7cbe10367fa4e2935")
|
||||
sha256sums=("25dac1edc91c5228d24ef4d07c31c07331cf697951afe31883fba74e2d102cc2")
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/${pkgname}-${pkgver}/copyparty/web"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"url": "https://github.com/9001/copyparty/releases/download/v1.20.1/copyparty-1.20.1.tar.gz",
|
||||
"version": "1.20.1",
|
||||
"hash": "sha256-T1E8qePRwRp7tOGoqSXdokSblWXpH273y+EDZ/pOKTU="
|
||||
"url": "https://github.com/9001/copyparty/releases/download/v1.20.4/copyparty-1.20.4.tar.gz",
|
||||
"version": "1.20.4",
|
||||
"hash": "sha256-JdrB7ckcUijSTvTQfDHAczHPaXlRr+MYg/unTi0QLMI="
|
||||
}
|
||||
|
|
@ -1173,6 +1173,7 @@ def add_general(ap, nc, srvname):
|
|||
ap2.add_argument("--name", metavar="TXT", type=u, default=srvname, help="server name (displayed topleft in browser and in mDNS)")
|
||||
ap2.add_argument("--name-url", metavar="TXT", type=u, help="URL for server name hyperlink (displayed topleft in browser)")
|
||||
ap2.add_argument("--name-html", type=u, help=argparse.SUPPRESS)
|
||||
ap2.add_argument("--site", metavar="URL", type=u, default="", help="public URL to assume when creating links; example: [\033[32mhttps://example.com/\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("--rmagic", action="store_true", help="do expensive analysis to improve accuracy of returned mimetypes; will make file-downloads, rss, and webdav slower (volflag=rmagic)")
|
||||
|
|
@ -1220,6 +1221,7 @@ def add_share(ap):
|
|||
ap2.add_argument("--shr-who", metavar="TXT", type=u, default="auth", help="who can create a share? [\033[32mno\033[0m]=nobody, [\033[32ma\033[0m]=admin-permission, [\033[32mauth\033[0m]=authenticated (volflag=shr_who)")
|
||||
ap2.add_argument("--shr-adm", metavar="U,U", type=u, default="", help="comma-separated list of users allowed to view/delete any share")
|
||||
ap2.add_argument("--shr-rt", metavar="MIN", type=int, default=1440, help="shares can be revived by their owner if they expired less than MIN minutes ago; [\033[32m60\033[0m]=hour, [\033[32m1440\033[0m]=day, [\033[32m10080\033[0m]=week")
|
||||
ap2.add_argument("--shr-site", metavar="URL", type=u, default="--site", help="public URL to assume when creating share-links; example: [\033[32mhttps://example.com/\033[0m]")
|
||||
ap2.add_argument("--shr-v", action="store_true", help="debug")
|
||||
|
||||
|
||||
|
|
@ -1227,6 +1229,7 @@ def add_upload(ap):
|
|||
ap2 = ap.add_argument_group("upload options")
|
||||
ap2.add_argument("--dotpart", action="store_true", help="dotfile incomplete uploads, hiding them from clients unless \033[33m-ed\033[0m")
|
||||
ap2.add_argument("--plain-ip", action="store_true", help="when avoiding filename collisions by appending the uploader's ip to the filename: append the plaintext ip instead of salting and hashing the ip")
|
||||
ap2.add_argument("--up-site", metavar="URL", type=u, default="--site", help="public URL to assume when creating links to uploaded files; example: [\033[32mhttps://example.com/\033[0m]")
|
||||
ap2.add_argument("--put-name", metavar="TXT", type=u, default="put-{now.6f}-{cip}.bin", help="filename for nameless uploads (when uploader doesn't provide a name); default is [\033[32mput-UNIXTIME-IP.bin\033[0m] (the \033[32m.6f\033[0m means six decimal places) (volflag=put_name)")
|
||||
ap2.add_argument("--put-ck", metavar="ALG", type=u, default="sha512", help="default checksum-hasher for PUT/WebDAV uploads: no / md5 / sha1 / sha256 / sha512 / b2 / blake2 / b2s / blake2s (volflag=put_ck)")
|
||||
ap2.add_argument("--bup-ck", metavar="ALG", type=u, default="sha512", help="default checksum-hasher for bup/basic-uploader: no / md5 / sha1 / sha256 / sha512 / b2 / blake2 / b2s / blake2s (volflag=bup_ck)")
|
||||
|
|
@ -1559,6 +1562,7 @@ def add_optouts(ap):
|
|||
ap2.add_argument("-nih", action="store_true", help="no info hostname -- don't show in UI")
|
||||
ap2.add_argument("-nid", action="store_true", help="no info disk-usage -- don't show in UI. This is the same as --du-who no")
|
||||
ap2.add_argument("-nb", action="store_true", help="no powered-by-copyparty branding in UI")
|
||||
ap2.add_argument("--smsg", metavar="T,T", type=u, default="POST", help="HTTP-methods to allow ?smsg for; will execute xm hooks like urlform / message-to-serverlog; dangerous example: [\033[32mGET,POST\033[0m]. \033[1;31mWARNING:\033[0m The default (POST) is safe, but GET is dangerous; security/CSRF hazard")
|
||||
ap2.add_argument("--zipmaxn", metavar="N", type=u, default="0", help="reject download-as-zip if more than \033[33mN\033[0m files in total; optionally takes a unit suffix: [\033[32m256\033[0m], [\033[32m9K\033[0m], [\033[32m4G\033[0m] (volflag=zipmaxn)")
|
||||
ap2.add_argument("--zipmaxs", metavar="SZ", type=u, default="0", help="reject download-as-zip if total download size exceeds \033[33mSZ\033[0m bytes; optionally takes a unit suffix: [\033[32m256M\033[0m], [\033[32m4G\033[0m], [\033[32m2T\033[0m] (volflag=zipmaxs)")
|
||||
ap2.add_argument("--zipmaxt", metavar="TXT", type=u, default="", help="custom errormessage when download size exceeds max (volflag=zipmaxt)")
|
||||
|
|
@ -1582,6 +1586,8 @@ def add_safety(ap):
|
|||
ap2.add_argument("--ls", metavar="U[,V[,F]]", type=u, default="", help="do a sanity/safety check of all volumes on startup; arguments \033[33mUSER\033[0m,\033[33mVOL\033[0m,\033[33mFLAGS\033[0m (see \033[33m--help-ls\033[0m); example [\033[32m**,*,ln,p,r\033[0m]")
|
||||
ap2.add_argument("--xvol", action="store_true", help="never follow symlinks leaving the volume root, unless the link is into another volume where the user has similar access (volflag=xvol)")
|
||||
ap2.add_argument("--xdev", action="store_true", help="stay within the filesystem of the volume root; do not descend into other devices (symlink or bind-mount to another HDD, ...) (volflag=xdev)")
|
||||
ap2.add_argument("--vol-nospawn", action="store_true", help="if a volume's folder does not exist on the HDD, then do not create it (continue with warning) (volflag=nospawn)")
|
||||
ap2.add_argument("--vol-or-crash", action="store_true", help="if a volume's folder does not exist on the HDD, then burst into flames (volflag=assert_root)")
|
||||
ap2.add_argument("--no-dot-mv", action="store_true", help="disallow moving dotfiles; makes it impossible to move folders containing dotfiles")
|
||||
ap2.add_argument("--no-dot-ren", action="store_true", help="disallow renaming dotfiles; makes it impossible to turn something into a dotfile")
|
||||
ap2.add_argument("--no-logues", action="store_true", help="disable rendering .prologue/.epilogue.html into directory listings")
|
||||
|
|
@ -1591,7 +1597,7 @@ def add_safety(ap):
|
|||
ap2.add_argument("--no-robots", action="store_true", help="adds http and html headers asking search engines to not index anything (volflag=norobots)")
|
||||
ap2.add_argument("--logout", metavar="H", type=float, default=8086.0, help="logout clients after \033[33mH\033[0m hours of inactivity; [\033[32m0.0028\033[0m]=10sec, [\033[32m0.1\033[0m]=6min, [\033[32m24\033[0m]=day, [\033[32m168\033[0m]=week, [\033[32m720\033[0m]=month, [\033[32m8760\033[0m]=year)")
|
||||
ap2.add_argument("--dont-ban", metavar="TXT", type=u, default="no", help="anyone at this accesslevel or above will not get banned: [\033[32mav\033[0m]=admin-in-volume, [\033[32maa\033[0m]=has-admin-anywhere, [\033[32mrw\033[0m]=read-write, [\033[32mauth\033[0m]=authenticated, [\033[32many\033[0m]=disable-all-bans, [\033[32mno\033[0m]=anyone-can-get-banned")
|
||||
ap2.add_argument("--banmsg", metavar="TXT", type=u, default="thank you for playing \u00a0 (see serverlog and readme)", help="the response to send to banned users; can be @ban.html to send the contents of ban.html")
|
||||
ap2.add_argument("--banmsg", metavar="TXT", type=u, default="thank you for playing \u00a0 (see fileserver log and readme)", help="the response to send to banned users; can be @ban.html to send the contents of ban.html")
|
||||
ap2.add_argument("--ban-pw", metavar="N,W,B", type=u, default="9,60,1440", help="more than \033[33mN\033[0m wrong passwords in \033[33mW\033[0m minutes = ban for \033[33mB\033[0m minutes; disable with [\033[32mno\033[0m]")
|
||||
ap2.add_argument("--ban-pwc", metavar="N,W,B", type=u, default="5,60,1440", help="more than \033[33mN\033[0m password-changes in \033[33mW\033[0m minutes = ban for \033[33mB\033[0m minutes; disable with [\033[32mno\033[0m]")
|
||||
ap2.add_argument("--ban-404", metavar="N,W,B", type=u, default="50,60,1440", help="hitting more than \033[33mN\033[0m 404's in \033[33mW\033[0m minutes = ban for \033[33mB\033[0m minutes; only affects users who cannot see directory listings because their access is either g/G/h")
|
||||
|
|
@ -1634,6 +1640,7 @@ def add_logging(ap):
|
|||
ap2 = ap.add_argument_group("logging options")
|
||||
ap2.add_argument("-q", action="store_true", help="quiet; disable most STDOUT messages")
|
||||
ap2.add_argument("-lo", metavar="PATH", type=u, default="", help="logfile; use .txt for plaintext or .xz for compressed. Example: \033[32mcpp-%%Y-%%m%%d-%%H%%M%%S.txt.xz\033[0m (NB: some errors may appear on STDOUT only)")
|
||||
ap2.add_argument("--flo", metavar="N", type=int, default=1, help="log format for \033[33m-lo\033[0m; [\033[32m1\033[0m]=classic/colors, [\033[32m2\033[0m]=no-color")
|
||||
ap2.add_argument("--no-ansi", action="store_true", default=not VT100, help="disable colors; same as environment-variable NO_COLOR")
|
||||
ap2.add_argument("--ansi", action="store_true", help="force colors; overrides environment-variable NO_COLOR")
|
||||
ap2.add_argument("--no-logflush", action="store_true", help="don't flush the logfile after each write; tiny bit faster")
|
||||
|
|
@ -1781,10 +1788,12 @@ def add_db_metadata(ap):
|
|||
ap2.add_argument("--mtag-mt", metavar="CORES", type=int, default=CORES, help="num cpu cores to use for tag scanning")
|
||||
ap2.add_argument("--mtag-v", action="store_true", help="verbose tag scanning; print errors from mtp subprocesses and such")
|
||||
ap2.add_argument("--mtag-vv", action="store_true", help="debug mtp settings and mutagen/FFprobe parsers")
|
||||
ap2.add_argument("--db-xattr", metavar="t,t", type=u, default="", help="read file xattrs as metadata tags; [\033[32ma,b\033[0m] reads keys \033[33ma\033[0m and \033[33mb\033[0m as tags \033[33ma\033[0m and \033[33mb\033[0m, [\033[32ma=foo,b=bar\033[0m] reads keys \033[33ma\033[0m and \033[33mb\033[0m as tags \033[33mfoo\033[0m and \033[33mbar\033[0m, [\033[32m~~a,b\033[0m] does everything except \033[33ma\033[0m and \033[33mb\033[0m, [\033[32m~~\033[0m] does everything. NOTE: Each tag must also be enabled with \033[33m-mte\033[0m (volflag=db_xattr)")
|
||||
ap2.add_argument("-mtm", metavar="M=t,t,t", type=u, action="append", help="\033[34mREPEATABLE:\033[0m add/replace metadata mapping")
|
||||
ap2.add_argument("-mte", metavar="M,M,M", type=u, help="tags to index/display (comma-sep.); either an entire replacement list, or add/remove stuff on the default-list with +foo or /bar", default=DEF_MTE)
|
||||
ap2.add_argument("-mth", metavar="M,M,M", type=u, help="tags to hide by default (comma-sep.); assign/add/remove same as \033[33m-mte\033[0m", default=DEF_MTH)
|
||||
ap2.add_argument("-mtp", metavar="M=[f,]BIN", type=u, action="append", help="\033[34mREPEATABLE:\033[0m read tag \033[33mM\033[0m using program \033[33mBIN\033[0m to parse the file")
|
||||
ap2.add_argument("--have-db-xattr", action="store_true", help=argparse.SUPPRESS)
|
||||
|
||||
|
||||
def add_txt(ap):
|
||||
|
|
@ -1825,6 +1834,7 @@ def add_ui(ap, retry: int):
|
|||
ap2.add_argument("--gsel", action="store_true", help="select files in grid by ctrl-click (volflag=gsel)")
|
||||
ap2.add_argument("--localtime", action="store_true", help="default to local timezone instead of UTC")
|
||||
ap2.add_argument("--ui-filesz", metavar="FMT", type=u, default="1", help="default filesize format; one of these: 0, 1, 2, 2c, 3, 3c, 4, 4c, 5, 5c, fuzzy (see UI)")
|
||||
ap2.add_argument("--rcm", metavar="TXT", default="yy", help="rightclick-menu; two yes/no options: 1st y/n is enable-custom-menu, 2nd y/n is enable-double")
|
||||
ap2.add_argument("--lang", metavar="LANG", type=u, default="eng", help="language, for example \033[32meng\033[0m / \033[32mnor\033[0m / ...")
|
||||
ap2.add_argument("--theme", metavar="NUM", type=int, default=0, help="default theme to use (0..%d)" % (THEMES - 1,))
|
||||
ap2.add_argument("--themes", metavar="NUM", type=int, default=THEMES, help="number of themes installed")
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
# coding: utf-8
|
||||
|
||||
VERSION = (1, 20, 1)
|
||||
VERSION = (1, 20, 4)
|
||||
CODENAME = "sftp is fine too"
|
||||
BUILD_DT = (2026, 1, 9)
|
||||
BUILD_DT = (2026, 1, 23)
|
||||
|
||||
S_VERSION = ".".join(map(str, VERSION))
|
||||
S_BUILD_DT = "{0:04d}-{1:02d}-{2:02d}".format(*BUILD_DT)
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ from .util import (
|
|||
DEF_MTH,
|
||||
EXTS,
|
||||
FAVICON_MIMES,
|
||||
FN_EMB,
|
||||
HAVE_SQLITE3,
|
||||
IMPLICATIONS,
|
||||
META_NOBOTS,
|
||||
|
|
@ -101,7 +102,7 @@ UP_MTE_MAP = { # db-order
|
|||
}
|
||||
|
||||
SEE_LOG = "see log for details"
|
||||
SEESLOG = " (see serverlog for details)"
|
||||
SEESLOG = " (see fileserver log for details)"
|
||||
SSEELOG = " ({})".format(SEE_LOG)
|
||||
BAD_CFG = "invalid config; {}".format(SEE_LOG)
|
||||
SBADCFG = " ({})".format(BAD_CFG)
|
||||
|
|
@ -1070,6 +1071,7 @@ class AuthSrv(object):
|
|||
"tcolor": self.args.tcolor,
|
||||
"du_iwho": self.args.du_iwho,
|
||||
"shr_who": self.args.shr_who if self.args.shr else "no",
|
||||
"emb_all": FN_EMB,
|
||||
"ls_q_m": ("", ""),
|
||||
}
|
||||
self._vf0 = self._vf0b.copy()
|
||||
|
|
@ -2090,6 +2092,49 @@ class AuthSrv(object):
|
|||
t = "WARNING: the account [%s] is not mentioned in any volume definitions and thus has the same access-level and privileges that guests have; please see --help-accounts for details. For example, if you intended to give that user full access to the current directory, you could do this: -v .::A,%s"
|
||||
self.log(t % (usr, usr), 1)
|
||||
|
||||
dropvols = []
|
||||
errors = False
|
||||
for vol in vfs.all_vols.values():
|
||||
if (
|
||||
not vol.realpath
|
||||
or (
|
||||
"assert_root" not in vol.flags
|
||||
and "nospawn" not in vol.flags
|
||||
and not self.args.vol_or_crash
|
||||
and not self.args.vol_nospawn
|
||||
)
|
||||
or bos.path.exists(vol.realpath)
|
||||
):
|
||||
pass
|
||||
elif "assert_root" in vol.flags or self.args.vol_or_crash:
|
||||
t = "ERROR: volume [/%s] root folder %r does not exist on server HDD; will now crash due to volflag 'assert_root'"
|
||||
self.log(t % (vol.vpath, vol.realpath), 1)
|
||||
errors = True
|
||||
else:
|
||||
t = "WARNING: volume [/%s] root folder %r does not exist on server HDD; volume will be unavailable due to volflag 'nospawn'"
|
||||
self.log(t % (vol.vpath, vol.realpath), 3)
|
||||
dropvols.append(vol)
|
||||
if errors:
|
||||
sys.exit(1)
|
||||
for vol in dropvols:
|
||||
vol.axs = AXS()
|
||||
vol.uaxs = {}
|
||||
vfs.all_vols.pop(vol.vpath, None)
|
||||
vfs.all_nodes.pop(vol.vpath, None)
|
||||
for zv in vfs.all_nodes.values():
|
||||
try:
|
||||
zv.all_aps.remove(vol.realpath)
|
||||
zv.all_vps.remove(vol.vpath)
|
||||
# pointless but might as well:
|
||||
zv.all_vols.pop(vol.vpath)
|
||||
zv.all_nodes.pop(vol.vpath)
|
||||
except:
|
||||
pass
|
||||
zs = next((x for x, y in zv.nodes.items() if y == vol), "")
|
||||
if zs:
|
||||
zv.nodes.pop(zs)
|
||||
vol.realpath = ""
|
||||
|
||||
promote = []
|
||||
demote = []
|
||||
for vol in vfs.all_vols.values():
|
||||
|
|
@ -2538,16 +2583,22 @@ class AuthSrv(object):
|
|||
t = "WARNING: volume [/%s]: invalid value specified for ext-th: %s"
|
||||
self.log(t % (vol.vpath, etv), 3)
|
||||
|
||||
emb_all = vol.flags["emb_all"] = set()
|
||||
|
||||
zsl1 = [x for x in vol.flags["preadmes"].split(",") if x]
|
||||
zsl2 = [x for x in vol.flags["readmes"].split(",") if x]
|
||||
zsl3 = list(set([x.lower() for x in zsl1]))
|
||||
zsl4 = list(set([x.lower() for x in zsl2]))
|
||||
emb_all.update(zsl3)
|
||||
emb_all.update(zsl4)
|
||||
vol.flags["emb_mds"] = [[0, zsl1, zsl3], [1, zsl2, zsl4]]
|
||||
|
||||
zsl1 = [x for x in vol.flags["prologues"].split(",") if x]
|
||||
zsl2 = [x for x in vol.flags["epilogues"].split(",") if x]
|
||||
zsl3 = list(set([x.lower() for x in zsl1]))
|
||||
zsl4 = list(set([x.lower() for x in zsl2]))
|
||||
emb_all.update(zsl3)
|
||||
emb_all.update(zsl4)
|
||||
vol.flags["emb_lgs"] = [[0, zsl1, zsl3], [1, zsl2, zsl4]]
|
||||
|
||||
zs = str(vol.flags.get("html_head") or "")
|
||||
|
|
@ -2591,6 +2642,19 @@ class AuthSrv(object):
|
|||
|
||||
vol.check_landmarks()
|
||||
|
||||
if vol.flags.get("db_xattr"):
|
||||
self.args.have_db_xattr = True
|
||||
zs = str(vol.flags["db_xattr"])
|
||||
neg = zs.startswith("~~")
|
||||
if neg:
|
||||
zs = zs[2:]
|
||||
zsl = [x.strip() for x in zs.split(",")]
|
||||
zsl = [x for x in zsl if x]
|
||||
if neg:
|
||||
vol.flags["db_xattr_no"] = set(zsl)
|
||||
else:
|
||||
vol.flags["db_xattr_yes"] = zsl
|
||||
|
||||
# d2d drops all database features for a volume
|
||||
for grp, rm in [["d2d", "e2d"], ["d2t", "e2t"], ["d2d", "e2v"]]:
|
||||
if not vol.flags.get(grp, False):
|
||||
|
|
@ -2709,7 +2773,7 @@ class AuthSrv(object):
|
|||
for zs in zs.split():
|
||||
vol.flags.pop(zs, None)
|
||||
|
||||
for vol in vfs.all_nodes.values():
|
||||
for vol in vfs.all_vols.values():
|
||||
if not vol.realpath or vol.flags.get("is_file"):
|
||||
continue
|
||||
ccs = vol.flags["casechk"][:1].lower()
|
||||
|
|
@ -3145,6 +3209,7 @@ class AuthSrv(object):
|
|||
"dsort": vf["sort"],
|
||||
"dcrop": vf["crop"],
|
||||
"dth3x": vf["th3x"],
|
||||
"drcm": self.args.rcm,
|
||||
"dvol": self.args.au_vol,
|
||||
"idxh": int(self.args.ih),
|
||||
"dutc": not self.args.localtime,
|
||||
|
|
@ -3168,6 +3233,11 @@ class AuthSrv(object):
|
|||
for zs in zs.split():
|
||||
if getattr(self.args, zs, False):
|
||||
js_htm[zs] = 1
|
||||
zs = "up_site"
|
||||
for zs in zs.split():
|
||||
zs2 = getattr(self.args, zs, "")
|
||||
if zs2:
|
||||
js_htm[zs] = zs2
|
||||
vn.js_htm = json_hesc(json.dumps(js_htm))
|
||||
|
||||
vols = list(vfs.all_nodes.values())
|
||||
|
|
|
|||
|
|
@ -106,14 +106,14 @@ def utime(
|
|||
def utime_c(
|
||||
log: Union["NamedLogger", Any],
|
||||
p: str,
|
||||
ts: int,
|
||||
ts: float,
|
||||
follow_symlinks: bool = True,
|
||||
throw: bool = False,
|
||||
) -> Optional[int]:
|
||||
) -> Optional[float]:
|
||||
clamp = 0
|
||||
ov = ts
|
||||
bp = fsenc(p)
|
||||
now = int(time.time())
|
||||
now = time.time()
|
||||
while True:
|
||||
try:
|
||||
if SYMTIME:
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ def vf_bmap() -> dict[str, str]:
|
|||
"no_thumb": "dthumb",
|
||||
"no_vthumb": "dvthumb",
|
||||
"no_athumb": "dathumb",
|
||||
"vol_nospawn": "nospawn",
|
||||
"vol_or_crash": "assert_root",
|
||||
}
|
||||
for k in (
|
||||
"dedup",
|
||||
|
|
@ -101,6 +103,7 @@ def vf_vmap() -> dict[str, str]:
|
|||
"chmod_d",
|
||||
"chmod_f",
|
||||
"dbd",
|
||||
"db_xattr",
|
||||
"du_who",
|
||||
"epilogues",
|
||||
"ufavico",
|
||||
|
|
@ -286,6 +289,7 @@ flagcats = {
|
|||
"dotsrch": "show dotfiles in search results",
|
||||
"nodotsrch": "hide dotfiles in search results (default)",
|
||||
"srch_excl": "exclude search results with URL matching this regex",
|
||||
"db_xattr=user.foo,user.bar": "index file xattrs as media-tags",
|
||||
},
|
||||
'database, audio tags\n"mte", "mth", "mtp", "mtm" all work the same as -mte, -mth, ...': {
|
||||
"mte=artist,title": "media-tags to index/display",
|
||||
|
|
@ -425,6 +429,8 @@ flagcats = {
|
|||
"cachectl=no-cache": "controls caching in webbrowsers",
|
||||
"mv_retry": "ms-windows: timeout for renaming busy files",
|
||||
"rm_retry": "ms-windows: timeout for deleting busy files",
|
||||
"nospawn": "don't create volume's folder if not exist",
|
||||
"assert_root": "crash on startup if volume's folder not exist",
|
||||
"davauth": "ask webdav clients to login for all folders",
|
||||
"davrt": "show lastmod time of symlink destination, not the link itself\n(note: this option is always enabled for recursive listings)",
|
||||
},
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ from .__init__ import PY2, TYPE_CHECKING
|
|||
from .authsrv import VFS
|
||||
from .bos import bos
|
||||
from .util import (
|
||||
FN_EMB,
|
||||
VF_CAREFUL,
|
||||
Daemon,
|
||||
ODict,
|
||||
|
|
@ -179,7 +178,7 @@ class FtpFs(AbstractedFS):
|
|||
vfs, rem = self.hub.asrv.vfs.get(vpath, self.uname, r, w, m, d)
|
||||
if (
|
||||
w
|
||||
and fn.lower() in FN_EMB
|
||||
and fn.lower() in vfs.flags["emb_all"]
|
||||
and self.h.uname not in vfs.axs.uread
|
||||
and "wo_up_readme" not in vfs.flags
|
||||
):
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ from .util import (
|
|||
BITNESS,
|
||||
DAV_ALLPROPS,
|
||||
E_SCK_WR,
|
||||
FN_EMB,
|
||||
HAVE_SQLITE3,
|
||||
HTTPCODE,
|
||||
UTC,
|
||||
|
|
@ -161,6 +160,7 @@ H_CONN_CLOSE = "Connection: Close"
|
|||
|
||||
RSS_SORT = {"m": "mt", "u": "at", "n": "fn", "s": "sz"}
|
||||
ACODE2_FMT = set(["opus", "owa", "caf", "mp3", "flac", "wav"])
|
||||
IDX_HTML = set(["index.htm", "index.html"])
|
||||
|
||||
A_FILE = os.stat_result(
|
||||
(0o644, -1, -1, 1, 1000, 1000, 8, 0x39230101, 0x39230101, 0x39230101)
|
||||
|
|
@ -285,12 +285,6 @@ class HttpCli(object):
|
|||
uname = self.asrv.iacct.get(b) or self.asrv.sesa.get(b)
|
||||
return "%s\033[7m %s \033[27m%s" % (a, uname, c)
|
||||
|
||||
def _check_nonfatal(self, ex: Pebkac, post: bool) -> bool:
|
||||
if post:
|
||||
return ex.code < 300
|
||||
|
||||
return ex.code < 400 or ex.code in [404, 429]
|
||||
|
||||
def _assert_safe_rem(self, rem: str) -> None:
|
||||
# sanity check to prevent any disasters
|
||||
# (this function hopefully serves no purpose; validation has already happened at this point, this only exists as a last-ditch effort just in case)
|
||||
|
|
@ -348,11 +342,6 @@ class HttpCli(object):
|
|||
if not headerlines:
|
||||
return False
|
||||
|
||||
if not headerlines[0]:
|
||||
# seen after login with IE6.0.2900.5512.xpsp.080413-2111 (xp-sp3)
|
||||
self.log("BUG: trailing newline from previous request", c="1;31")
|
||||
headerlines.pop(0)
|
||||
|
||||
try:
|
||||
self.mode, self.req, self.http_ver = headerlines[0].split(" ")
|
||||
|
||||
|
|
@ -361,6 +350,8 @@ class HttpCli(object):
|
|||
for header_line in headerlines[1:]:
|
||||
k, zs = header_line.split(":", 1)
|
||||
self.headers[k.lower()] = zs.strip()
|
||||
if zs.endswith(" HTTP/1.1"):
|
||||
raise Exception()
|
||||
except:
|
||||
headerlines = [repr(x) for x in headerlines]
|
||||
msg = "#[ " + " ]\n#[ ".join(headerlines) + " ]"
|
||||
|
|
@ -405,6 +396,7 @@ class HttpCli(object):
|
|||
if n:
|
||||
zso = self.headers.get(self.args.xff_hdr)
|
||||
if zso:
|
||||
self.keepalive = False
|
||||
if n > 0:
|
||||
n -= 1
|
||||
|
||||
|
|
@ -854,7 +846,7 @@ class HttpCli(object):
|
|||
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)"
|
||||
self.log(t % (self.mode, origin, proto, self.host, host, guess), 3)
|
||||
raise Pebkac(403, "rejected by cors-check (see serverlog)")
|
||||
raise Pebkac(403, "rejected by cors-check (see fileserver log)")
|
||||
|
||||
# getattr(self.mode) is not yet faster than this
|
||||
if self.mode == "POST":
|
||||
|
|
@ -889,8 +881,8 @@ class HttpCli(object):
|
|||
self.terse_reply(b"", 500)
|
||||
return False
|
||||
|
||||
post = self.mode in ["POST", "PUT"] or "content-length" in self.headers
|
||||
if not self._check_nonfatal(pex, post):
|
||||
post = self.mode in ("POST", "PUT") or "content-length" in self.headers
|
||||
if pex.code >= (300 if post else 400):
|
||||
self.keepalive = False
|
||||
|
||||
em = str(ex)
|
||||
|
|
@ -997,8 +989,8 @@ class HttpCli(object):
|
|||
|
||||
rt = bans[ip] - time.time()
|
||||
if rt < 0:
|
||||
self.log("client unbanned", 3)
|
||||
del bans[ip]
|
||||
self.log("client unbanned", 3)
|
||||
return False
|
||||
|
||||
self.log("banned for {:.0f} sec".format(rt), 6)
|
||||
|
|
@ -1434,6 +1426,9 @@ class HttpCli(object):
|
|||
|
||||
self.uparam["h"] = ""
|
||||
|
||||
if "smsg" in self.uparam:
|
||||
return self.handle_smsg()
|
||||
|
||||
if "tree" in self.uparam:
|
||||
return self.tx_tree()
|
||||
|
||||
|
|
@ -1835,7 +1830,9 @@ class HttpCli(object):
|
|||
|
||||
zi = (
|
||||
vn.flags["du_iwho"]
|
||||
if vn.realpath and "quota-available-bytes" in props
|
||||
if vn.realpath
|
||||
and "quota-available-bytes" in props
|
||||
and "quotaused" not in props # macos finder; ingnore it
|
||||
else 0
|
||||
)
|
||||
if zi and (
|
||||
|
|
@ -1866,10 +1863,6 @@ class HttpCli(object):
|
|||
"quota-available-bytes": str(bfree),
|
||||
"quota-used-bytes": str(btot - bfree),
|
||||
}
|
||||
if "quotaused" in props: # macos finder crazytalk
|
||||
df["quotaused"] = df["quota-used-bytes"]
|
||||
if "quota" in props:
|
||||
df["quota"] = df["quota-available-bytes"] # idk, makes it happy
|
||||
else:
|
||||
df = {}
|
||||
else:
|
||||
|
|
@ -2210,7 +2203,7 @@ class HttpCli(object):
|
|||
raise Pebkac(403 if self.pw else 401, t % (self.uname, self.vn.vpath))
|
||||
|
||||
if not self.args.no_dav and self._applesan():
|
||||
return self.headers.get("content-length") == "0"
|
||||
return False
|
||||
|
||||
if self.headers.get("expect", "").lower() == "100-continue":
|
||||
try:
|
||||
|
|
@ -2246,6 +2239,9 @@ class HttpCli(object):
|
|||
):
|
||||
return self.handle_post_json()
|
||||
|
||||
if "smsg" in self.uparam:
|
||||
return self.handle_smsg()
|
||||
|
||||
if "move" in self.uparam:
|
||||
return self.handle_mv()
|
||||
|
||||
|
|
@ -2332,6 +2328,37 @@ class HttpCli(object):
|
|||
|
||||
raise Pebkac(405, "don't know how to handle POST(%r)" % (ctype,))
|
||||
|
||||
def handle_smsg(self) -> bool:
|
||||
if self.mode not in self.args.smsg_set:
|
||||
raise Pebkac(403, "smsg is disabled for this http-method in server config")
|
||||
|
||||
msg = self.uparam["smsg"]
|
||||
self.log("smsg %d @ %r\n %r\n" % (len(msg), "/" + self.vpath, msg))
|
||||
|
||||
xm = self.vn.flags.get("xm")
|
||||
if xm:
|
||||
xm_rsp = runhook(
|
||||
self.log,
|
||||
self.conn.hsrv.broker,
|
||||
None,
|
||||
"xm",
|
||||
xm,
|
||||
self.vn.canonical(self.rem),
|
||||
self.vpath,
|
||||
self.host,
|
||||
self.uname,
|
||||
self.asrv.vfs.get_perms(self.vpath, self.uname),
|
||||
time.time(),
|
||||
len(msg),
|
||||
self.ip,
|
||||
time.time(),
|
||||
[msg, msg],
|
||||
)
|
||||
self.loud_reply(xm_rsp.get("stdout") or "", status=202)
|
||||
else:
|
||||
self.loud_reply("k", status=202)
|
||||
return True
|
||||
|
||||
def get_xml_enc(self, txt: str) -> str:
|
||||
ofs = txt[:512].find(' encoding="')
|
||||
enc = ""
|
||||
|
|
@ -2586,7 +2613,7 @@ class HttpCli(object):
|
|||
at = mt = time.time() - lifetime
|
||||
cli_mt = self.headers.get("x-oc-mtime")
|
||||
if cli_mt:
|
||||
bos.utime_c(self.log, path, int(cli_mt), False)
|
||||
bos.utime_c(self.log, path, float(cli_mt), False)
|
||||
|
||||
if nameless and "magic" in vfs.flags:
|
||||
try:
|
||||
|
|
@ -2683,11 +2710,20 @@ class HttpCli(object):
|
|||
vpath = "/".join([x for x in [vfs.vpath, rem, fn] if x])
|
||||
vpath = quotep(vpath)
|
||||
|
||||
url = "{}://{}/{}".format(
|
||||
"https" if self.is_https else "http",
|
||||
self.host,
|
||||
self.args.RS + vpath + vsuf,
|
||||
)
|
||||
if self.args.up_site:
|
||||
url = "%s%s%s" % (
|
||||
self.args.up_site,
|
||||
vpath,
|
||||
vsuf,
|
||||
)
|
||||
else:
|
||||
url = "%s://%s/%s%s%s" % (
|
||||
"https" if self.is_https else "http",
|
||||
self.host,
|
||||
self.args.RS,
|
||||
vpath,
|
||||
vsuf,
|
||||
)
|
||||
|
||||
return post_sz, halg, sha_hex, sha_b64, remains, path, url
|
||||
|
||||
|
|
@ -2912,7 +2948,7 @@ class HttpCli(object):
|
|||
if (
|
||||
not self.can_read
|
||||
and self.can_write
|
||||
and name.lower() in FN_EMB
|
||||
and name.lower() in dbv.flags["emb_all"]
|
||||
and "wo_up_readme" not in dbv.flags
|
||||
):
|
||||
name = "_wo_" + name
|
||||
|
|
@ -2961,7 +2997,7 @@ class HttpCli(object):
|
|||
raise Pebkac(500, t % zt)
|
||||
ret["purl"] = vp_req + ret["purl"][len(vp_vfs) :]
|
||||
|
||||
if self.is_vproxied:
|
||||
if self.is_vproxied and not self.args.up_site:
|
||||
if "purl" in ret:
|
||||
ret["purl"] = self.args.SR + ret["purl"]
|
||||
|
||||
|
|
@ -3229,7 +3265,7 @@ class HttpCli(object):
|
|||
if num_left < 0:
|
||||
if bail1:
|
||||
return False
|
||||
raise Pebkac(500, "unconfirmed; see serverlog")
|
||||
raise Pebkac(500, "unconfirmed; see fileserver log")
|
||||
|
||||
if not num_left and fpool:
|
||||
with self.u2mutex:
|
||||
|
|
@ -3839,9 +3875,9 @@ class HttpCli(object):
|
|||
errmsg = "ERROR: " + errmsg
|
||||
|
||||
if halg:
|
||||
file_fmt = '{0}: {1} // {2} // {3} bytes // <a href="/{4}">{5}</a> {6}\n'
|
||||
file_fmt = '{0}: {1} // {2} // {3} bytes // <a href="{4}">{5}</a> {6}\n'
|
||||
else:
|
||||
file_fmt = '{3} bytes // <a href="/{4}">{5}</a> {6}\n'
|
||||
file_fmt = '{3} bytes // <a href="{4}">{5}</a> {6}\n'
|
||||
|
||||
for sz, sha_hex, sha_b64, ofn, lfn, ap in files:
|
||||
vsuf = ""
|
||||
|
|
@ -3859,25 +3895,31 @@ class HttpCli(object):
|
|||
if "media" in self.uparam or "medialinks" in vfs.flags:
|
||||
vsuf += "&v" if vsuf else "?v"
|
||||
|
||||
vpath = "{}/{}".format(upload_vpath, lfn).strip("/")
|
||||
rel_url = quotep(self.args.RS + vpath) + vsuf
|
||||
vpath = vjoin(upload_vpath, lfn)
|
||||
if self.args.up_site:
|
||||
ah_url = j_url = self.args.up_site + quotep(vpath) + vsuf
|
||||
rel_url = "/" + j_url.split("//", 1)[-1].split("/", 1)[-1]
|
||||
else:
|
||||
ah_url = rel_url = "/%s%s%s" % (self.args.RS, quotep(vpath), vsuf)
|
||||
j_url = "%s://%s%s" % (
|
||||
"https" if self.is_https else "http",
|
||||
self.host,
|
||||
rel_url,
|
||||
)
|
||||
|
||||
msg += file_fmt.format(
|
||||
halg,
|
||||
sha_hex[:56],
|
||||
sha_b64,
|
||||
sz,
|
||||
rel_url,
|
||||
ah_url,
|
||||
html_escape(ofn, crlf=True),
|
||||
vsuf,
|
||||
)
|
||||
# truncated SHA-512 prevents length extension attacks;
|
||||
# using SHA-512/224, optionally SHA-512/256 = :64
|
||||
jpart = {
|
||||
"url": "{}://{}/{}".format(
|
||||
"https" if self.is_https else "http",
|
||||
self.host,
|
||||
rel_url,
|
||||
),
|
||||
"url": j_url,
|
||||
"sz": sz,
|
||||
"fn": lfn,
|
||||
"fn_orig": ofn,
|
||||
|
|
@ -5434,8 +5476,8 @@ class HttpCli(object):
|
|||
|
||||
if self.args.have_unlistc:
|
||||
allvols = self.asrv.vfs.all_nodes
|
||||
rvol = [x for x in rvol if "unlistcr" not in allvols[x[1:-1]].flags]
|
||||
wvol = [x for x in wvol if "unlistcw" not in allvols[x[1:-1]].flags]
|
||||
rvol = [x for x in rvol if "unlistcr" not in allvols[x.strip("/")].flags]
|
||||
wvol = [x for x in wvol if "unlistcw" not in allvols[x.strip("/")].flags]
|
||||
|
||||
fmt = self.uparam.get("ls", "")
|
||||
if not fmt and self.ua.startswith(("curl/", "fetch")):
|
||||
|
|
@ -6169,8 +6211,20 @@ class HttpCli(object):
|
|||
zsl = [html_escape(zst[0]) for zst in zstl]
|
||||
r[4] = "<br />".join(zsl)
|
||||
|
||||
if self.args.shr_site:
|
||||
site = self.args.shr_site[:-1]
|
||||
elif self.is_vproxied:
|
||||
site = self.args.SR
|
||||
else:
|
||||
site = ""
|
||||
|
||||
html = self.j2s(
|
||||
"shares", this=self, shr=self.args.shr, rows=rows, now=int(time.time())
|
||||
"shares",
|
||||
this=self,
|
||||
shr=self.args.shr,
|
||||
site=site,
|
||||
rows=rows,
|
||||
now=int(time.time()),
|
||||
)
|
||||
self.reply(html.encode("utf-8"), status=200)
|
||||
return True
|
||||
|
|
@ -6325,14 +6379,22 @@ class HttpCli(object):
|
|||
fn = quotep(fns[0]) if len(fns) == 1 else ""
|
||||
|
||||
# NOTE: several clients (frontend, party-up) expect url at response[15:]
|
||||
surl = "created share: %s://%s%s%s%s/%s" % (
|
||||
"https" if self.is_https else "http",
|
||||
self.host,
|
||||
self.args.SR,
|
||||
self.args.shr,
|
||||
skey,
|
||||
fn,
|
||||
)
|
||||
if self.args.shr_site:
|
||||
surl = "created share: %s%s%s/%s" % (
|
||||
self.args.shr_site,
|
||||
self.args.shr[1:],
|
||||
skey,
|
||||
fn,
|
||||
)
|
||||
else:
|
||||
surl = "created share: %s://%s%s%s%s/%s" % (
|
||||
"https" if self.is_https else "http",
|
||||
self.host,
|
||||
self.args.SR,
|
||||
self.args.shr,
|
||||
skey,
|
||||
fn,
|
||||
)
|
||||
self.loud_reply(surl, status=201)
|
||||
return True
|
||||
|
||||
|
|
@ -6450,11 +6512,12 @@ class HttpCli(object):
|
|||
if self.args.have_unlistc:
|
||||
rvol = [x for x in rvol if "unlistcr" not in allvols[x].flags]
|
||||
wvol = [x for x in wvol if "unlistcw" not in allvols[x].flags]
|
||||
vols = list(set(rvol + wvol))
|
||||
vols = [(x, allvols[x]) for x in list(set(rvol + wvol))]
|
||||
if self.vpath:
|
||||
zs = "%s/" % (self.vpath,)
|
||||
vols = [x[len(zs) :] for x in vols if x.startswith(zs)]
|
||||
vols = [x.split("/", 1)[0] for x in vols if x]
|
||||
vols = [(x[len(zs) :], y) for x, y in vols if x.startswith(zs)]
|
||||
vols = [(x.split("/", 1)[0], y) for x, y in vols]
|
||||
vols = list(({x: y for x, y in vols if x}).items())
|
||||
if not vols and self.vpath:
|
||||
return self.tx_404(True)
|
||||
dirs = [
|
||||
|
|
@ -6467,9 +6530,9 @@ class HttpCli(object):
|
|||
"tags": e_d,
|
||||
"dt": 0,
|
||||
"name": 0,
|
||||
"perms": allvols[x].get_perms("", self.uname),
|
||||
"perms": vn.get_perms("", self.uname),
|
||||
}
|
||||
for x in sorted(vols)
|
||||
for x, vn in sorted(vols)
|
||||
]
|
||||
ls = {
|
||||
"dirs": dirs,
|
||||
|
|
@ -6722,7 +6785,7 @@ class HttpCli(object):
|
|||
vrem = vjoin(vrem, fn)
|
||||
abspath = ap2
|
||||
break
|
||||
elif self.vpath.rsplit("/", 1)[-1] in ("index.htm", "index.html"):
|
||||
elif self.vpath.rsplit("/", 1)[-1] in IDX_HTML:
|
||||
fk_pass = True
|
||||
|
||||
if not is_dir and (self.can_read or self.can_get):
|
||||
|
|
@ -6910,6 +6973,14 @@ class HttpCli(object):
|
|||
if "zip" in self.uparam or "tar" in self.uparam:
|
||||
raise Pebkac(403)
|
||||
|
||||
zsl = j2a["files"] = []
|
||||
if is_js:
|
||||
j2a["ls0"] = cgv["ls0"] = {
|
||||
"dirs": zsl,
|
||||
"files": zsl,
|
||||
"taglist": zsl,
|
||||
}
|
||||
|
||||
html = self.j2s(tpl, **j2a)
|
||||
self.reply(html.encode("utf-8", "replace"))
|
||||
return True
|
||||
|
|
@ -7092,13 +7163,16 @@ class HttpCli(object):
|
|||
and "v" not in self.uparam
|
||||
and not is_opds
|
||||
):
|
||||
idx_html = set(["index.htm", "index.html"])
|
||||
for item in files:
|
||||
if item["name"] in idx_html:
|
||||
if item["name"] in IDX_HTML:
|
||||
# do full resolve in case of shadowed file
|
||||
vp = vjoin(self.vpath.split("?")[0], item["name"])
|
||||
vn, rem = self.asrv.vfs.get(vp, self.uname, True, False)
|
||||
ap = vn.canonical(rem)
|
||||
if not self.trailing_slash and bos.path.isfile(ap):
|
||||
return self.redirect(
|
||||
self.vpath + "/", flavor="redirecting to", use302=True
|
||||
)
|
||||
return self.tx_file(ap) # is no-cache
|
||||
|
||||
if icur:
|
||||
|
|
|
|||
|
|
@ -465,6 +465,8 @@ class MTag(object):
|
|||
"ffprobe" if args.no_mutagen or (HAVE_FFPROBE and EXE) else "mutagen"
|
||||
)
|
||||
self.can_ffprobe = HAVE_FFPROBE and not args.no_mtag_ff
|
||||
self.read_xattrs = args.have_db_xattr
|
||||
self.get = self._get_xattr if self.read_xattrs else self._get_main
|
||||
mappings = args.mtm
|
||||
or_ffprobe = " or FFprobe"
|
||||
|
||||
|
|
@ -486,7 +488,13 @@ class MTag(object):
|
|||
msg = "found FFprobe but it was disabled by --no-mtag-ff"
|
||||
self.log(msg, c=3)
|
||||
|
||||
if self.read_xattrs and not self.usable:
|
||||
t = "don't have the necessary dependencies to read conventional media tags, but will read xattrs"
|
||||
self.log(t)
|
||||
self.usable = True
|
||||
|
||||
if not self.usable:
|
||||
self._get = None
|
||||
if EXE:
|
||||
t = "copyparty.exe cannot use mutagen; need ffprobe.exe to read media tags: "
|
||||
self.log(t + FFMPEG_URL)
|
||||
|
|
@ -645,7 +653,36 @@ class MTag(object):
|
|||
|
||||
return r1
|
||||
|
||||
def get(self, abspath: str) -> dict[str, Union[str, float]]:
|
||||
def _get_xattr(
|
||||
self, abspath: str, vf: dict[str, Any]
|
||||
) -> dict[str, Union[str, float]]:
|
||||
ret = self._get_main(abspath, vf) if self._get else {}
|
||||
if "db_xattr_no" in vf:
|
||||
try:
|
||||
neg = vf["db_xattr_no"]
|
||||
zsl = os.listxattr(abspath)
|
||||
zsl = [x for x in zsl if x not in neg]
|
||||
for xattr in zsl:
|
||||
zb = os.getxattr(abspath, xattr)
|
||||
ret[xattr] = zb.decode("utf-8", "replace")
|
||||
except:
|
||||
self.log("failed to read xattrs from [%s]\n%s", abspath, min_ex(), 3)
|
||||
elif "db_xattr_yes" in vf:
|
||||
for xattr in vf["db_xattr_yes"]:
|
||||
if "=" in xattr:
|
||||
xattr, name = xattr.split("=", 1)
|
||||
else:
|
||||
name = xattr
|
||||
try:
|
||||
zs = os.getxattr(abspath, xattr)
|
||||
ret[name] = zs.decode("utf-8", "replace")
|
||||
except:
|
||||
pass
|
||||
return ret
|
||||
|
||||
def _get_main(
|
||||
self, abspath: str, vf: dict[str, Any]
|
||||
) -> dict[str, Union[str, float]]:
|
||||
ext = abspath.split(".")[-1].lower()
|
||||
if ext not in self.args.au_unpk:
|
||||
return self._get(abspath)
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ from .__init__ import ANYWIN, TYPE_CHECKING
|
|||
from .authsrv import LEELOO_DALLAS, VFS, AuthSrv
|
||||
from .bos import bos
|
||||
from .util import (
|
||||
FN_EMB,
|
||||
VF_CAREFUL,
|
||||
Daemon,
|
||||
ODict,
|
||||
|
|
@ -328,7 +327,7 @@ class SFTP_Srv(paramiko.SFTPServerInterface):
|
|||
vn, rem = self.hub.asrv.vfs.get(vpath, self.uname, r, w, m, d)
|
||||
if (
|
||||
w
|
||||
and fn.lower() in FN_EMB
|
||||
and fn.lower() in vn.flags["emb_all"]
|
||||
and self.uname not in vn.axs.uread
|
||||
and "wo_up_readme" not in vn.flags
|
||||
):
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ class SvcHub(object):
|
|||
self.argv = argv
|
||||
self.E: EnvParams = args.E
|
||||
self.no_ansi = args.no_ansi
|
||||
self.flo = args.flo
|
||||
self.tz = UTC if args.log_utc else None
|
||||
self.logf: Optional[typing.TextIO] = None
|
||||
self.logf_base_fn = ""
|
||||
|
|
@ -315,6 +316,10 @@ class SvcHub(object):
|
|||
args.doctitle = args.doctitle.replace("--name", args.vname)
|
||||
args.bname = args.bname.replace("--name", args.vname) or args.vname
|
||||
|
||||
for zs in "shr_site up_site".split():
|
||||
if getattr(args, zs) == "--site":
|
||||
setattr(args, zs, args.site)
|
||||
|
||||
if args.log_fk:
|
||||
args.log_fk = re.compile(args.log_fk)
|
||||
|
||||
|
|
@ -1113,6 +1118,12 @@ class SvcHub(object):
|
|||
vsa = [x.lower() for x in vsa if x]
|
||||
setattr(al, k + "_set", set(vsa))
|
||||
|
||||
for k in "smsg".split(" "):
|
||||
vs = getattr(al, k)
|
||||
vsa = [x.strip() for x in vs.split(",")]
|
||||
vsa = [x.upper() for x in vsa if x]
|
||||
setattr(al, k + "_set", set(vsa))
|
||||
|
||||
zs = "dav_ua1 sus_urls nonsus_urls ua_nodav ua_nodoc ua_nozip"
|
||||
for k in zs.split(" "):
|
||||
vs = getattr(al, k)
|
||||
|
|
@ -1567,21 +1578,38 @@ class SvcHub(object):
|
|||
dt.microsecond // self.log_div,
|
||||
)
|
||||
|
||||
if c and not self.args.no_ansi:
|
||||
if isinstance(c, int):
|
||||
if self.flo == 1:
|
||||
fmt = "@%s [%-21s] %s\n"
|
||||
if not c:
|
||||
if "\033" in msg:
|
||||
msg += "\033[0m"
|
||||
elif isinstance(c, int):
|
||||
msg = "\033[3%sm%s\033[0m" % (c, msg)
|
||||
elif "\033" not in c:
|
||||
msg = "\033[%sm%s\033[0m" % (c, msg)
|
||||
else:
|
||||
msg = "%s%s\033[0m" % (c, msg)
|
||||
|
||||
if "\033" in src:
|
||||
src += "\033[0m"
|
||||
if "\033" in src:
|
||||
src += "\033[0m"
|
||||
else:
|
||||
if not c:
|
||||
fmt = "@%s LOG [%-21s] %s\n"
|
||||
elif c == 1:
|
||||
fmt = "@%s CRIT [%-21s] %s\n"
|
||||
elif c == 3:
|
||||
fmt = "@%s WARN [%-21s] %s\n"
|
||||
elif c == 6:
|
||||
fmt = "@%s BTW [%-21s] %s\n"
|
||||
else:
|
||||
fmt = "@%s LOG [%-21s] %s\n"
|
||||
|
||||
if "\033" in msg:
|
||||
msg += "\033[0m"
|
||||
if "\033" in src:
|
||||
src = RE_ANSI.sub("", src)
|
||||
if "\033" in msg:
|
||||
msg = RE_ANSI.sub("", msg)
|
||||
|
||||
self.logf.write("@%s [%-21s] %s\n" % (ts, src, msg))
|
||||
self.logf.write(fmt % (ts, src, msg))
|
||||
if not self.args.no_logflush:
|
||||
self.logf.flush()
|
||||
|
||||
|
|
@ -1611,9 +1639,10 @@ class SvcHub(object):
|
|||
if self.logf:
|
||||
self.logf.write(zs)
|
||||
|
||||
fmt = "\033[36m%s \033[33m%-21s \033[0m%s\n"
|
||||
if self.no_ansi:
|
||||
if c == 1:
|
||||
if not c:
|
||||
fmt = "%s %-21s LOG: %s\n"
|
||||
elif c == 1:
|
||||
fmt = "%s %-21s CRIT: %s\n"
|
||||
elif c == 3:
|
||||
fmt = "%s %-21s WARN: %s\n"
|
||||
|
|
@ -1621,12 +1650,16 @@ class SvcHub(object):
|
|||
fmt = "%s %-21s BTW: %s\n"
|
||||
else:
|
||||
fmt = "%s %-21s LOG: %s\n"
|
||||
|
||||
if "\033" in msg:
|
||||
msg = RE_ANSI.sub("", msg)
|
||||
if "\033" in src:
|
||||
src = RE_ANSI.sub("", src)
|
||||
elif c:
|
||||
if isinstance(c, int):
|
||||
else:
|
||||
fmt = "\033[36m%s \033[33m%-21s \033[0m%s\n"
|
||||
if not c:
|
||||
pass
|
||||
elif isinstance(c, int):
|
||||
msg = "\033[3%sm%s\033[0m" % (c, msg)
|
||||
elif "\033" not in c:
|
||||
msg = "\033[%sm%s\033[0m" % (c, msg)
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@ from .__init__ import EXE, PY2, TYPE_CHECKING
|
|||
from .authsrv import VFS
|
||||
from .bos import bos
|
||||
from .util import (
|
||||
FN_EMB,
|
||||
UTC,
|
||||
BytesIO,
|
||||
Daemon,
|
||||
|
|
@ -268,7 +267,7 @@ class Tftpd(object):
|
|||
vfs, rem = self.asrv.vfs.get(vpath, "*", *perms)
|
||||
if perms[1] and "*" not in vfs.axs.uread and "wo_up_readme" not in vfs.flags:
|
||||
zs, fn = vsplit(vpath)
|
||||
if fn.lower() in FN_EMB:
|
||||
if fn.lower() in vfs.flags["emb_all"]:
|
||||
vpath = vjoin(zs, "_wo_" + fn)
|
||||
vfs, rem = self.asrv.vfs.get(vpath, "*", *perms)
|
||||
|
||||
|
|
|
|||
|
|
@ -61,6 +61,8 @@ from .util import (
|
|||
s3dec,
|
||||
s3enc,
|
||||
sanitize_fn,
|
||||
set_ap_perms,
|
||||
set_fperms,
|
||||
sfsenc,
|
||||
spack,
|
||||
statdir,
|
||||
|
|
@ -130,6 +132,7 @@ class Mpqe(object):
|
|||
self,
|
||||
mtp: dict[str, MParser],
|
||||
entags: set[str],
|
||||
vf: dict[str, Any],
|
||||
w: str,
|
||||
abspath: str,
|
||||
oth_tags: dict[str, Any],
|
||||
|
|
@ -137,6 +140,7 @@ class Mpqe(object):
|
|||
# mtp empty = mtag
|
||||
self.mtp = mtp
|
||||
self.entags = entags
|
||||
self.vf = vf
|
||||
self.w = w
|
||||
self.abspath = abspath
|
||||
self.oth_tags = oth_tags
|
||||
|
|
@ -1148,7 +1152,7 @@ class Up2k(object):
|
|||
ft = "\033[0;32m{}{:.0}"
|
||||
ff = "\033[0;35m{}{:.0}"
|
||||
fv = "\033[0;36m{}:\033[90m{}"
|
||||
zs = "bcasechk du_iwho emb_lgs emb_mds ext_th_d html_head html_head_d html_head_s ls_q_m put_name2 mv_re_r mv_re_t rm_re_r rm_re_t srch_re_dots srch_re_nodot zipmax zipmaxn_v zipmaxs_v"
|
||||
zs = "bcasechk du_iwho emb_all emb_lgs emb_mds ext_th_d html_head html_head_d html_head_s ls_q_m put_name2 mv_re_r mv_re_t rm_re_r rm_re_t srch_re_dots srch_re_nodot zipmax zipmaxn_v zipmaxs_v"
|
||||
fx = set(zs.split())
|
||||
fd = vf_bmap()
|
||||
fd.update(vf_cmap())
|
||||
|
|
@ -2199,7 +2203,7 @@ class Up2k(object):
|
|||
abspath = djoin(ptop, rd, fn)
|
||||
self.pp.msg = "c%d %s" % (nq, abspath)
|
||||
if not mpool:
|
||||
n_tags = self._tagscan_file(cur, entags, w, abspath, ip, at, un)
|
||||
n_tags = self._tagscan_file(cur, entags, flags, w, abspath, ip, at, un)
|
||||
else:
|
||||
oth_tags = {}
|
||||
if ip:
|
||||
|
|
@ -2209,7 +2213,7 @@ class Up2k(object):
|
|||
if un:
|
||||
oth_tags["up_by"] = un
|
||||
|
||||
mpool.put(Mpqe({}, entags, w, abspath, oth_tags))
|
||||
mpool.put(Mpqe({}, entags, flags, w, abspath, oth_tags))
|
||||
with self.mutex:
|
||||
n_tags = len(self._flush_mpool(cur))
|
||||
|
||||
|
|
@ -2316,9 +2320,10 @@ class Up2k(object):
|
|||
return
|
||||
|
||||
entags = self.entags[ptop]
|
||||
vf = self.flags[ptop]
|
||||
|
||||
parsers = {}
|
||||
for parser in self.flags[ptop]["mtp"]:
|
||||
for parser in vf["mtp"]:
|
||||
try:
|
||||
parser = MParser(parser)
|
||||
except:
|
||||
|
|
@ -2393,7 +2398,7 @@ class Up2k(object):
|
|||
if un:
|
||||
oth_tags["up_by"] = un
|
||||
|
||||
jobs.append(Mpqe(parsers, set(), w, abspath, oth_tags))
|
||||
jobs.append(Mpqe(parsers, set(), vf, w, abspath, oth_tags))
|
||||
in_progress[w] = True
|
||||
|
||||
with self.mutex:
|
||||
|
|
@ -2524,7 +2529,7 @@ class Up2k(object):
|
|||
return
|
||||
|
||||
for _ in range(mpool.maxsize):
|
||||
mpool.put(Mpqe({}, set(), "", "", {}))
|
||||
mpool.put(Mpqe({}, set(), {}, "", "", {}))
|
||||
|
||||
mpool.join()
|
||||
|
||||
|
|
@ -2543,7 +2548,7 @@ class Up2k(object):
|
|||
t = "tag-thr: {}({})"
|
||||
self.log(t.format(self.mtag.backend, qe.abspath), "90")
|
||||
|
||||
tags = self.mtag.get(qe.abspath) if st.st_size else {}
|
||||
tags = self.mtag.get(qe.abspath, qe.vf) if st.st_size else {}
|
||||
else:
|
||||
if self.args.mtag_vv:
|
||||
t = "tag-thr: {}({})"
|
||||
|
|
@ -2576,6 +2581,7 @@ class Up2k(object):
|
|||
self,
|
||||
write_cur: "sqlite3.Cursor",
|
||||
entags: set[str],
|
||||
vf: dict[str, Any],
|
||||
wark: str,
|
||||
abspath: str,
|
||||
ip: str,
|
||||
|
|
@ -2594,7 +2600,7 @@ class Up2k(object):
|
|||
return 0
|
||||
|
||||
try:
|
||||
tags = self.mtag.get(abspath) if st.st_size else {}
|
||||
tags = self.mtag.get(abspath, vf) if st.st_size else {}
|
||||
except Exception as ex:
|
||||
self._log_tag_err("", abspath, ex)
|
||||
return 0
|
||||
|
|
@ -3542,7 +3548,7 @@ class Up2k(object):
|
|||
if self.args.nw:
|
||||
return
|
||||
|
||||
linked = False
|
||||
linked = 0
|
||||
try:
|
||||
if rm and bos.path.exists(dst):
|
||||
wunlink(self.log, dst, flags)
|
||||
|
|
@ -3556,6 +3562,8 @@ class Up2k(object):
|
|||
try:
|
||||
with open(fsenc(src), "rb") as fi, open(fsenc(dst), "wb") as fo:
|
||||
fcntl.ioctl(fo.fileno(), fcntl.FICLONE, fi.fileno())
|
||||
if "fperms" in flags:
|
||||
set_fperms(fo, flags)
|
||||
except:
|
||||
if bos.path.exists(dst):
|
||||
wunlink(self.log, dst, flags)
|
||||
|
|
@ -3593,7 +3601,7 @@ class Up2k(object):
|
|||
try:
|
||||
if "hardlink" in flags:
|
||||
os.link(fsenc(absreal(src)), fsenc(dst))
|
||||
linked = True
|
||||
linked = 2
|
||||
except Exception as ex:
|
||||
self.log("cannot hardlink: " + repr(ex))
|
||||
if "hardlinkonly" in flags:
|
||||
|
|
@ -3612,7 +3620,7 @@ class Up2k(object):
|
|||
else:
|
||||
os.symlink(fsenc(lsrc), fsenc(ldst))
|
||||
|
||||
linked = True
|
||||
linked = 1
|
||||
except Exception as ex:
|
||||
if str(ex) != "reflink":
|
||||
self.log("cannot link; creating copy: " + repr(ex))
|
||||
|
|
@ -3626,8 +3634,11 @@ class Up2k(object):
|
|||
raise Exception(t % (src, fsrc, dst))
|
||||
trystat_shutil_copy2(self.log, fsenc(csrc), fsenc(dst))
|
||||
|
||||
if lmod and (not linked or SYMTIME):
|
||||
bos.utime_c(self.log, dst, int(lmod), False)
|
||||
if linked < 2 and (linked < 1 or SYMTIME):
|
||||
if lmod:
|
||||
bos.utime_c(self.log, dst, int(lmod), False)
|
||||
if "fperms" in flags:
|
||||
set_ap_perms(dst, flags)
|
||||
|
||||
def handle_chunks(
|
||||
self, ptop: str, wark: str, chashes: list[str]
|
||||
|
|
@ -4503,6 +4514,8 @@ class Up2k(object):
|
|||
bos.utime(dabs, times, False)
|
||||
except:
|
||||
pass
|
||||
if "fperms" in dvn.flags:
|
||||
set_ap_perms(dabs, dvn.flags)
|
||||
|
||||
if xac:
|
||||
runhook(
|
||||
|
|
@ -4788,6 +4801,8 @@ class Up2k(object):
|
|||
wunlink(self.log, sabs, svn.flags)
|
||||
else:
|
||||
atomic_move(self.log, sabs, dabs, svn.flags)
|
||||
if svn != dvn and "fperms" in dvn.flags:
|
||||
set_ap_perms(dabs, dvn.flags)
|
||||
|
||||
except OSError as ex:
|
||||
if ex.errno != errno.EXDEV:
|
||||
|
|
@ -4821,6 +4836,8 @@ class Up2k(object):
|
|||
bos.utime(dabs, times, False)
|
||||
except:
|
||||
pass
|
||||
if "fperms" in dvn.flags:
|
||||
set_ap_perms(dabs, dvn.flags)
|
||||
|
||||
wunlink(self.log, sabs, svn.flags)
|
||||
|
||||
|
|
@ -5404,7 +5421,7 @@ class Up2k(object):
|
|||
# self.log("\n " + repr([ptop, rd, fn]))
|
||||
abspath = djoin(ptop, rd, fn)
|
||||
try:
|
||||
tags = self.mtag.get(abspath) if sz else {}
|
||||
tags = self.mtag.get(abspath, self.flags[ptop]) if sz else {}
|
||||
ntags1 = len(tags)
|
||||
parsers = self._get_parsers(ptop, tags, abspath)
|
||||
if self.args.mtag_vv:
|
||||
|
|
|
|||
|
|
@ -961,11 +961,13 @@ class _Unrecv(object):
|
|||
self.s = s
|
||||
self.log = log
|
||||
self.buf: bytes = b""
|
||||
self.nb = 0
|
||||
|
||||
def recv(self, nbytes: int, spins: int = 1) -> bytes:
|
||||
if self.buf:
|
||||
ret = self.buf[:nbytes]
|
||||
self.buf = self.buf[nbytes:]
|
||||
self.nb += len(ret)
|
||||
return ret
|
||||
|
||||
while True:
|
||||
|
|
@ -985,6 +987,7 @@ class _Unrecv(object):
|
|||
if not ret:
|
||||
raise UnrecvEOF("client stopped sending data")
|
||||
|
||||
self.nb += len(ret)
|
||||
return ret
|
||||
|
||||
def recv_ex(self, nbytes: int, raise_on_trunc: bool = True) -> bytes:
|
||||
|
|
@ -1012,6 +1015,7 @@ class _Unrecv(object):
|
|||
|
||||
def unrecv(self, buf: bytes) -> None:
|
||||
self.buf = buf + self.buf
|
||||
self.nb -= len(buf)
|
||||
|
||||
|
||||
# !rm.yes>
|
||||
|
|
@ -1024,6 +1028,7 @@ class _LUnrecv(object):
|
|||
self.s = s
|
||||
self.log = log
|
||||
self.buf = b""
|
||||
self.nb = 0
|
||||
|
||||
def recv(self, nbytes: int, spins: int) -> bytes:
|
||||
if self.buf:
|
||||
|
|
@ -1031,6 +1036,7 @@ class _LUnrecv(object):
|
|||
self.buf = self.buf[nbytes:]
|
||||
t = "\033[0;7mur:pop:\033[0;1;32m {}\n\033[0;7mur:rem:\033[0;1;35m {}\033[0m"
|
||||
print(t.format(ret, self.buf))
|
||||
self.nb += len(ret)
|
||||
return ret
|
||||
|
||||
ret = self.s.recv(nbytes)
|
||||
|
|
@ -1039,6 +1045,7 @@ class _LUnrecv(object):
|
|||
if not ret:
|
||||
raise UnrecvEOF("client stopped sending data")
|
||||
|
||||
self.nb += len(ret)
|
||||
return ret
|
||||
|
||||
def recv_ex(self, nbytes: int, raise_on_trunc: bool = True) -> bytes:
|
||||
|
|
@ -1067,6 +1074,7 @@ class _LUnrecv(object):
|
|||
|
||||
def unrecv(self, buf: bytes) -> None:
|
||||
self.buf = buf + self.buf
|
||||
self.nb -= len(buf)
|
||||
t = "\033[0;7mur:push\033[0;1;31m {}\n\033[0;7mur:rem:\033[0;1;35m {}\033[0m"
|
||||
print(t.format(buf, self.buf))
|
||||
|
||||
|
|
@ -1807,6 +1815,11 @@ class MultipartParser(object):
|
|||
self.log = log_func
|
||||
self.args = args
|
||||
self.headers = http_headers
|
||||
try:
|
||||
self.clen = int(http_headers["content-length"])
|
||||
sr.nb = 0
|
||||
except:
|
||||
self.clen = 0
|
||||
|
||||
self.re_ctype = RE_CTYPE
|
||||
self.re_cdisp = RE_CDISP
|
||||
|
|
@ -1962,7 +1975,10 @@ class MultipartParser(object):
|
|||
|
||||
if tail == b"--":
|
||||
# EOF indicated by this immediately after final boundary
|
||||
tail = self.sr.recv_ex(2, False)
|
||||
if self.clen == self.sr.nb:
|
||||
tail = b"\r\n" # dillo doesn't terminate with trailing \r\n
|
||||
else:
|
||||
tail = self.sr.recv_ex(2, False)
|
||||
run = False
|
||||
|
||||
if tail != b"\r\n":
|
||||
|
|
@ -1980,6 +1996,8 @@ class MultipartParser(object):
|
|||
|
||||
def parse(self) -> None:
|
||||
boundary = get_boundary(self.headers)
|
||||
if boundary.startswith('"') and boundary.endswith('"'):
|
||||
boundary = boundary[1:-1] # dillo uses quotes
|
||||
self.log("boundary=%r" % (boundary,))
|
||||
|
||||
# spec says there might be junk before the first boundary,
|
||||
|
|
@ -2721,6 +2739,14 @@ def set_fperms(f: Union[typing.BinaryIO, typing.IO[Any]], vf: dict[str, Any]) ->
|
|||
os.fchown(fno, vf["uid"], vf["gid"])
|
||||
|
||||
|
||||
def set_ap_perms(ap: str, vf: dict[str, Any]) -> None:
|
||||
zb = fsenc(ap)
|
||||
if "chmod_f" in vf:
|
||||
os.chmod(zb, vf["chmod_f"])
|
||||
if "chown" in vf:
|
||||
os.chown(zb, vf["uid"], vf["gid"])
|
||||
|
||||
|
||||
def trystat_shutil_copy2(log: "NamedLogger", src: bytes, dst: bytes) -> bytes:
|
||||
try:
|
||||
return shutil.copy2(src, dst)
|
||||
|
|
|
|||
|
|
@ -4168,4 +4168,14 @@ html.e #detree {
|
|||
border-color: var(--a);
|
||||
border-radius: .2em;
|
||||
padding: .2em .3em;
|
||||
}
|
||||
}
|
||||
|
||||
.selbox {
|
||||
position: fixed;
|
||||
border: .5em solid #f0f;
|
||||
border: .2em solid var(--btn-1h-bg);
|
||||
background-color: rgba(128, 128, 128, 0.6);
|
||||
background-color: rgb(from var(--btn-1h-bg) r g b / 0.5);
|
||||
pointer-events: none;
|
||||
z-index: 99;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang="en" id="ht_brw">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
var J_BRW = 1;
|
||||
|
||||
if (!window.drcm) alert('FATAL ERROR: receiving stale data from the server; this may be due to a broken reverse-proxy (stuck cache). Try restarting copyparty and press CTRL-SHIFT-R in the browser');
|
||||
|
||||
var XHR = XMLHttpRequest,
|
||||
img_re = /\.(a?png|avif|bmp|gif|heif|jpe?g|jfif|svg|webp|webm|mkv|mp4|m4v|mov)(\?|$)/i;
|
||||
|
||||
|
|
@ -231,6 +233,7 @@ if (1)
|
|||
"ct_ttips": '◔ ◡ ◔">ℹ️ tooltips',
|
||||
"ct_thumb": 'in grid-view, toggle icons or thumbnails$NHotkey: T">🖼️ thumbs',
|
||||
"ct_csel": 'use CTRL and SHIFT for file selection in grid-view">sel',
|
||||
"ct_dsel": 'use drag-selection in grid-view">dsel',
|
||||
"ct_dl": 'force download (don\'t display inline) when a file is clicked">dl',
|
||||
"ct_ihop": 'when the image viewer is closed, scroll down to the last viewed file">g⮯',
|
||||
"ct_dots": 'show hidden files (if server permits)">dotfiles',
|
||||
|
|
@ -360,6 +363,7 @@ if (1)
|
|||
"f_anota": "only {0} of the {1} items were selected;\nto select the full folder, first scroll to the bottom",
|
||||
|
||||
"f_dls": 'the file links in the current folder have\nbeen changed into download links',
|
||||
"f_dl_nd": 'skipping folder (use zip/tar download instead):\n',
|
||||
|
||||
"f_partial": "To safely download a file which is currently being uploaded, please click the file which has the same filename, but without the <code>.PARTIAL</code> file extension. Please press CANCEL or Escape to do this.\n\nPressing OK / Enter will ignore this warning and continue downloading the <code>.PARTIAL</code> scratchfile instead, which will almost definitely give you corrupted data.",
|
||||
|
||||
|
|
@ -664,6 +668,8 @@ if (1)
|
|||
"rc_nfi": "new file",
|
||||
"rc_sal": "select all",
|
||||
"rc_sin": "invert selection",
|
||||
"rc_shf": "share this folder",
|
||||
"rc_shs": "share selection",
|
||||
|
||||
"lang_set": "refresh to make the change take effect?",
|
||||
};
|
||||
|
|
@ -909,6 +915,7 @@ ebi('op_cfg').innerHTML = (
|
|||
' <a id="griden" class="tgl btn" href="#" tt="' + L.wt_grid + '">' + L.ct_grid + '</a>\n' +
|
||||
' <a id="thumbs" class="tgl btn" href="#" tt="' + L.ct_thumb + '</a>\n' +
|
||||
' <a id="csel" class="tgl btn" href="#" tt="' + L.ct_csel + '</a>\n' +
|
||||
' <a id="dsel" class="tgl btn" href="#" tt="' + L.ct_dsel + '</a>\n' +
|
||||
' <a id="dlni" class="tgl btn" href="#" tt="' + L.ct_dl + '</a>\n' +
|
||||
' <a id="ihop" class="tgl btn" href="#" tt="' + L.ct_ihop + '</a>\n' +
|
||||
' <a id="dotfiles" class="tgl btn" href="#" tt="' + L.ct_dots + '</a>\n' +
|
||||
|
|
@ -992,7 +999,7 @@ ebi('op_cfg').innerHTML = (
|
|||
' </div>\n' +
|
||||
'</div>\n' +
|
||||
'<div><h3>' + L.cl_keytype + '</h3><div><select id="key_notation"></select></div></div>\n' +
|
||||
(!MOBILE ? '<div><h3>' + L.cl_rcm + '</h3><div><a id="ren" class="tgl btn" href="#" tt="' + L.cdt_ren + '">enable</a><a id="rdb" class="tgl btn" href="#" tt="' + L.cdt_rdb + '">double</a></div></div>' : '') +
|
||||
(!MOBILE ? '<div><h3>' + L.cl_rcm + '</h3><div><a id="rcm_en" class="tgl btn" href="#" tt="' + L.cdt_ren + '">enable</a><a id="rcm_db" class="tgl btn" href="#" tt="' + L.cdt_rdb + '">double</a></div></div>' : '') +
|
||||
'<div><h3>' + L.cl_hiddenc + ' ' + (MOBILE ? '<a href="#" id="hcolsh">' + L.cl_hidec + '</a> / ' : '') + '<a href="#" id="hcolsr">' + L.cl_reset + '</a></h3><div id="hcols"></div></div>'
|
||||
);
|
||||
|
||||
|
|
@ -1048,7 +1055,8 @@ ebi('rcm').innerHTML = (
|
|||
: '') +
|
||||
'<div id="rs4" class="sep"></div>' +
|
||||
'<a href="#" id="rsal">' + L.rc_sal + '</a>' +
|
||||
'<a href="#" id="rsin">' + L.rc_sin + '</a>'
|
||||
'<a href="#" id="rsin">' + L.rc_sin + '</a>' +
|
||||
'<a id="rshr" href="#"></a>'
|
||||
);
|
||||
|
||||
(function () {
|
||||
|
|
@ -4850,7 +4858,7 @@ var showfile = (function () {
|
|||
'nrend': 0,
|
||||
};
|
||||
r.map = {
|
||||
'.ahk': 'autohotkey',
|
||||
'.asm': 'nasm',
|
||||
'.bas': 'basic',
|
||||
'.bat': 'batch',
|
||||
'.cxx': 'cpp',
|
||||
|
|
@ -4873,6 +4881,8 @@ var showfile = (function () {
|
|||
'.rs': 'rust',
|
||||
'.sh': 'bash',
|
||||
'.service': 'systemd',
|
||||
'.socket': 'systemd',
|
||||
'.timer': 'systemd',
|
||||
'.txt': 'ans',
|
||||
'.vb': 'vbnet',
|
||||
'.v': 'verilog',
|
||||
|
|
@ -4881,10 +4891,9 @@ var showfile = (function () {
|
|||
'.yml': 'yaml'
|
||||
};
|
||||
r.nmap = {
|
||||
'cmakelists.txt': 'cmake',
|
||||
'dockerfile': 'docker'
|
||||
};
|
||||
var x = txt_ext + ' ans c cfg conf cpp cs css diff glsl go html ini java js json jsx kt kts latex less lisp lua makefile md nim py r rss rb ruby sass scss sql svg swift tex toml ts vhdl xml yaml zig';
|
||||
var x = txt_ext + ' ans c cfg conf cpp cs css diff glsl go html ini java js json jsx kt kts latex less lisp lua makefile md nasm nim nix py r rss rb ruby sass scss sql svg swift tex toml ts vhdl xml yaml zig';
|
||||
x = x.split(/ +/g);
|
||||
for (var a = 0; a < x.length; a++)
|
||||
if (!r.map["." + x[a]])
|
||||
|
|
@ -6518,7 +6527,7 @@ var search_ui = (function () {
|
|||
if (ext.length > 8)
|
||||
ext = '%';
|
||||
|
||||
var links = linksplit(r.rp + '', id).join('<span>/</span>'),
|
||||
var links = linksplit(r.rp + '', null, id).join('<span>/</span>'),
|
||||
nodes = ['<tr><td>-</td><td><div>' + links +
|
||||
'</div></td><td sortv="' + sz + '">' + hsz];
|
||||
|
||||
|
|
@ -6744,6 +6753,7 @@ var treectl = (function () {
|
|||
bcfg_bind(r, 'idxh', 'idxh', idxh, setidxh);
|
||||
bcfg_bind(r, 'dyn', 'dyntree', true, onresize);
|
||||
bcfg_bind(r, 'csel', 'csel', dgsel);
|
||||
bcfg_bind(r, 'dsel', 'dsel', !MOBILE);
|
||||
bcfg_bind(r, 'dlni', 'dlni', dlni, resort);
|
||||
bcfg_bind(r, 'dots', 'dotfiles', see_dots, function (v) {
|
||||
r.goto();
|
||||
|
|
@ -7551,9 +7561,10 @@ var treectl = (function () {
|
|||
qsr('#bbsw');
|
||||
srvinf = ebi('srv_info').innerHTML.slice(6, -7);
|
||||
if (ls0 === null) {
|
||||
setck('js=y');
|
||||
r.ls_cb = showfile.addlinks;
|
||||
return r.reqls(get_evpath(), false, undefined, true);
|
||||
return setck('js=y', function () {
|
||||
r.reqls(get_evpath(), false, undefined, true);
|
||||
});
|
||||
}
|
||||
ls0.unlist = unlist0;
|
||||
ls0.u2ts = u2ts;
|
||||
|
|
@ -8503,9 +8514,13 @@ var msel = (function () {
|
|||
|
||||
for (var a = 0, aa = links.length; a < aa; a++) {
|
||||
var qhref = links[a].getAttribute('href'),
|
||||
href = qhref.split('?')[0].replace(/\/$/, ""),
|
||||
href = qhref.split('?')[0],
|
||||
item = {};
|
||||
|
||||
if (href.endsWith('/')) {
|
||||
href = href.slice(0, -1);
|
||||
item.isd = true;
|
||||
}
|
||||
item.id = links[a].getAttribute('id');
|
||||
item.sel = clgot(links[a].closest('tr'), 'sel');
|
||||
item.vp = href.indexOf('/') !== -1 ? href : vbase + href;
|
||||
|
|
@ -8668,7 +8683,10 @@ var msel = (function () {
|
|||
ev(e);
|
||||
var sel = r.getsel();
|
||||
for (var a = 0; a < sel.length; a++)
|
||||
dl_file(sel[a].vp + sel[a].q);
|
||||
if (sel[a].isd)
|
||||
toast.warn(7, L.f_dl_nd + esc(sel[a].vp));
|
||||
else
|
||||
dl_file(sel[a].vp + sel[a].q);
|
||||
};
|
||||
r.render = function () {
|
||||
var tds = QSA('#files tbody td+td+td'),
|
||||
|
|
@ -9480,31 +9498,38 @@ var rcm = (function () {
|
|||
if (MOBILE)
|
||||
return {enabled: false}
|
||||
|
||||
var r = {
|
||||
enabled: true,
|
||||
double: false
|
||||
};
|
||||
bcfg_bind(r, 'enabled', 'ren', true);
|
||||
bcfg_bind(r, 'double', 'rdb', false);
|
||||
var r = {};
|
||||
bcfg_bind(r, 'enabled', 'rcm_en', drcm.charAt(0)=='y');
|
||||
bcfg_bind(r, 'double', 'rcm_db', drcm.charAt(1)=='y');
|
||||
|
||||
var menu = ebi('rcm');
|
||||
var nsFile = {
|
||||
elem: null,
|
||||
type: null,
|
||||
path: null,
|
||||
dpath: null,
|
||||
url: null,
|
||||
id: null,
|
||||
relpath: null,
|
||||
name: null,
|
||||
no_dsel: false
|
||||
};
|
||||
var selFile = jcp(nsFile);
|
||||
|
||||
function mktemp(is_dir) {
|
||||
var row = mknod('tr', 'temp',
|
||||
'<td>-new-</td>' +
|
||||
'<td colspan="' + (QSA("#files thead th").length - 1) + '"><input id="tempname" class="i" type="text" placeholder="' + (is_dir ? 'Folder' : "File") + ' Name"></td>'
|
||||
);
|
||||
QS("#files tbody").appendChild(row);
|
||||
qsr('#rcm_tmp');
|
||||
if (!thegrid.en) {
|
||||
var row = mknod('tr', 'rcm_tmp',
|
||||
'<td>-new-</td><td colspan="' + (QSA("#files thead th").length - 1) + '"><input id="tempname" class="i" type="text" placeholder="' + (is_dir ? 'Folder' : 'File') + ' Name"></td>');
|
||||
QS("#files tbody").appendChild(row);
|
||||
}
|
||||
else {
|
||||
var row = mknod('a', 'rcm_tmp',
|
||||
'<span class="dir" style="align-self:end"><input id="tempname" class="dir" type="text" placeholder="' + (is_dir ? 'Folder' : 'File') + ' Name"></span>');
|
||||
if (is_dir)
|
||||
row.className = 'dir';
|
||||
row.style.display = 'flex';
|
||||
QS("#ggrid").appendChild(row);
|
||||
}
|
||||
|
||||
function sendit(name) {
|
||||
name = ('' + name).trim();
|
||||
|
|
@ -9556,9 +9581,9 @@ var rcm = (function () {
|
|||
a.target = selFile.type == "dir" ? '' : '_blank';
|
||||
a.click();
|
||||
break;
|
||||
case 'ply': selFile.type == 'gf' ? thegrid.imshow(selFile.relpath) : play('f-' + selFile.id); break;
|
||||
case 'ply': selFile.type == 'gf' ? thegrid.imshow(selFile.name) : play('f-' + selFile.id); break;
|
||||
case 'pla': play('f-' + selFile.id); break;
|
||||
case 'txt': location = '?doc=' + selFile.relpath; break;
|
||||
case 'txt': location = selFile.dpath + '?doc=' + selFile.name; break;
|
||||
case 'md': location = selFile.path + (has(selFile.path, '?') ? '&v' : '?v'); break;
|
||||
case 'cpl': cliptxt(selFile.url, function() {toast.ok(2, L.clipped)}); break;
|
||||
case 'dl': ebi('seldl').click(); break;
|
||||
|
|
@ -9578,6 +9603,7 @@ var rcm = (function () {
|
|||
selFile.no_dsel = true;
|
||||
break;
|
||||
case 'sin': msel.evsel(null, 't'); break;
|
||||
case 'shr': fileman.share(); break;
|
||||
}
|
||||
r.hide(true);
|
||||
};
|
||||
|
|
@ -9591,24 +9617,30 @@ var rcm = (function () {
|
|||
var ref = ebi(target.getAttribute('ref'));
|
||||
file = ref && ref.closest('#files tbody tr');
|
||||
}
|
||||
if (file) {
|
||||
var fa = file && file.children[1].querySelector('a[id]');
|
||||
if (fa && fa.id != 'unsearch') {
|
||||
selFile.no_dsel = clgot(file, "sel");
|
||||
clmod(file, "sel", true);
|
||||
selFile.elem = file;
|
||||
|
||||
selFile.url = file.children[1].firstChild.href;
|
||||
selFile.url = fa.href;
|
||||
selFile.path = basenames(selFile.url).replace(/(&|\?)v/, '');
|
||||
selFile.relpath = selFile.path.split('/').slice(-1)[0].split("?")[0];
|
||||
if (noq_href(file.children[1].firstChild).endsWith("/"))
|
||||
var url = selFile.url.split("?")[0],
|
||||
vsp = vsplit(url);
|
||||
selFile.dpath = vsp[0];
|
||||
selFile.name = vsp[1];
|
||||
if (url.endsWith("/"))
|
||||
selFile.type = "dir";
|
||||
else {
|
||||
var lead = file.firstChild.firstChild;
|
||||
selFile.id = lead.id.split('-')[1];
|
||||
selFile.type = lead.innerHTML[0] == '(' ? 'gf' : lead.id.split('-')[0];
|
||||
if (lead.id === undefined)
|
||||
selFile.type = "tf";
|
||||
else {
|
||||
selFile.id = lead.id.split('-')[1];
|
||||
selFile.type = lead.innerHTML[0] == '(' ? 'gf' : lead.id.split('-')[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log(selFile);
|
||||
msel.selui();
|
||||
|
||||
var has_sel = msel.getsel().length;
|
||||
|
|
@ -9619,7 +9651,7 @@ var rcm = (function () {
|
|||
clmod(ebi('rpla'), 'hide', selFile.type != 'gf');
|
||||
clmod(ebi('rtxt'), 'hide', !selFile.id);
|
||||
clmod(ebi('rs1'), 'hide', !selFile.path);
|
||||
clmod(ebi('rmd'), 'hide', !selFile.id || selFile.relpath.slice(-3) != ".md");
|
||||
clmod(ebi('rmd'), 'hide', !selFile.name || selFile.name.slice(-3) != ".md");
|
||||
clmod(ebi('rcpl'), 'hide', !selFile.path);
|
||||
clmod(ebi('rdl'), 'hide', !has_sel);
|
||||
clmod(ebi('rzip'), 'hide', !has_sel);
|
||||
|
|
@ -9631,6 +9663,9 @@ var rcm = (function () {
|
|||
clmod(ebi('rrnm'), 'hide', !has_sel);
|
||||
clmod(ebi('rs3'), 'hide', !has_sel);
|
||||
clmod(ebi('rs4'), 'hide', !has_sel && !has(perms, "write"));
|
||||
var shr = ebi('rshr');
|
||||
clmod(shr, 'hide', !can_shr || !get_evpath().indexOf(have_shr));
|
||||
shr.innerHTML = has_sel ? L.rc_shs : L.rc_shf;
|
||||
|
||||
menu.style.left = x + 5 + 'px';
|
||||
menu.style.top = y + 5 + 'px';
|
||||
|
|
@ -9650,10 +9685,11 @@ var rcm = (function () {
|
|||
}
|
||||
|
||||
ebi('wrap').oncontextmenu = function(e) {
|
||||
r.hide(true);
|
||||
if (!r.enabled || e.shiftKey || (r.double && menu.style.display)) {
|
||||
r.hide(true);
|
||||
return true;
|
||||
}
|
||||
r.hide(true);
|
||||
if (selFile.elem && !selFile.no_dsel) {
|
||||
clmod(selFile.elem, "sel", false);
|
||||
msel.selui();
|
||||
|
|
@ -9737,6 +9773,157 @@ function reload_browser() {
|
|||
thegrid.setdirty();
|
||||
msel.render();
|
||||
}
|
||||
|
||||
(function() {
|
||||
var is_selma = false;
|
||||
var dragging = false;
|
||||
|
||||
var startx, starty;
|
||||
var fwrap = null;
|
||||
var selbox = null;
|
||||
var ttimer = null;
|
||||
|
||||
var lpdelay = 250;
|
||||
var mvthresh = 44;
|
||||
|
||||
function unbox() {
|
||||
qsr('.selbox');
|
||||
ebi('gfiles').style.removeProperty('pointer-events')
|
||||
ebi('wrap').style.removeProperty('user-select')
|
||||
|
||||
if (selbox) {
|
||||
console.log(selbox)
|
||||
window.getSelection().removeAllRanges();
|
||||
}
|
||||
|
||||
is_selma = false;
|
||||
dragging = false;
|
||||
fwrap = null;
|
||||
selbox = null;
|
||||
ttimer = null;
|
||||
}
|
||||
|
||||
function getpp(e) {
|
||||
var touch = (e.touches && e.touches[0]) || e;
|
||||
return { x: touch.clientX, y: touch.clientY };
|
||||
}
|
||||
|
||||
function sel_toggle(el, m) {
|
||||
clmod(el, 'sel', m);
|
||||
var eref = el.getAttribute('ref');
|
||||
if (eref) {
|
||||
var ehidden = ebi(eref);
|
||||
if (ehidden) {
|
||||
var tr = ehidden.closest('tr');
|
||||
if (tr) clmod(tr, 'sel', m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function bob(b1, b2) {
|
||||
return !(b1.right < b2.left || b1.left > b2.right ||
|
||||
b1.bottom < b2.top || b1.top > b2.bottom);
|
||||
}
|
||||
|
||||
function sel_start(e) {
|
||||
if (e.button !== 0 && e.type !== 'touchstart') return;
|
||||
if (!thegrid.en || !treectl.dsel) return;
|
||||
if (e.target.closest('#widget,#ops,.opview,.doc')) return;
|
||||
|
||||
if (e.target.closest('#gfiles'))
|
||||
ebi('gfiles').style.userSelect = "none"
|
||||
|
||||
var pos = getpp(e);
|
||||
startx = pos.x;
|
||||
starty = pos.y;
|
||||
is_selma = true;
|
||||
ttimer = null;
|
||||
|
||||
if (e.type === 'touchstart') {
|
||||
ttimer = setTimeout(function() {
|
||||
ttimer = null;
|
||||
start_drag();
|
||||
}, lpdelay);
|
||||
}
|
||||
}
|
||||
|
||||
function start_drag() {
|
||||
if (dragging) return;
|
||||
|
||||
dragging = true;
|
||||
selbox = document.createElement('div');
|
||||
selbox.className = 'selbox';
|
||||
document.body.appendChild(selbox);
|
||||
|
||||
ebi('gfiles').style.pointerEvents = 'none';
|
||||
}
|
||||
|
||||
function sel_move(e) {
|
||||
if (!is_selma) return;
|
||||
var pos = getpp(e);
|
||||
var dist = Math.sqrt(Math.pow(pos.x - startx, 2) + Math.pow(pos.y - starty, 2));
|
||||
|
||||
if (e.type === 'touchmove' && ttimer) {
|
||||
if (dist > mvthresh) {
|
||||
clearTimeout(ttimer);
|
||||
ttimer = null;
|
||||
is_selma = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!dragging && dist > mvthresh && !window.getSelection().toString()) {
|
||||
if (fwrap = e.target.closest('#wrap'))
|
||||
fwrap.style.userSelect = 'none';
|
||||
else return;
|
||||
start_drag();
|
||||
}
|
||||
|
||||
if (!dragging || !selbox) return;
|
||||
ev(e);
|
||||
|
||||
selbox.style.width = Math.abs(pos.x - startx) + 'px';
|
||||
selbox.style.height = Math.abs(pos.y - starty) + 'px';
|
||||
selbox.style.left = Math.min(pos.x, startx) + 'px';
|
||||
selbox.style.top = Math.min(pos.y, starty) + 'px';
|
||||
|
||||
if (IE && window.getSelection)
|
||||
window.getSelection().removeAllRanges();
|
||||
}
|
||||
|
||||
function sel_end(e) {
|
||||
clearTimeout(ttimer);
|
||||
if (dragging && selbox) {
|
||||
var sbrect = selbox.getBoundingClientRect();
|
||||
var faf = QSA('#ggrid a');
|
||||
var sadmode = e.shiftKey ? true : e.altKey ? false : "t";
|
||||
for (var a = 0, aa = faf.length; a < aa; a++)
|
||||
if (bob(sbrect, faf[a].getBoundingClientRect()))
|
||||
sel_toggle(faf[a], sadmode);
|
||||
msel.selui();
|
||||
ev(e);
|
||||
}
|
||||
unbox();
|
||||
}
|
||||
|
||||
function dsel_init() {
|
||||
window.addEventListener('mousedown', sel_start);
|
||||
window.addEventListener('mousemove', sel_move);
|
||||
window.addEventListener('mouseup', sel_end);
|
||||
|
||||
window.addEventListener('touchstart', sel_start, { passive: true });
|
||||
window.addEventListener('touchmove', sel_move, { passive: false });
|
||||
window.addEventListener('touchend', sel_end, { passive: true });
|
||||
|
||||
window.addEventListener('dragstart', function(e) {
|
||||
if (treectl.dsel && (is_selma || dragging)) {
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
dsel_init();
|
||||
})();
|
||||
|
||||
treectl.hydrate();
|
||||
|
||||
J_BRW = 2;
|
||||
|
|
|
|||
18
copyparty/web/deps/README.md
Normal file
18
copyparty/web/deps/README.md
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
this folder *mostly* contains third-party dependencies; run `make -C scripts/deps-docker` to build the following files and have them appear here:
|
||||
|
||||
* `easymde.css.gz` and `easymde.js.gz` is the fancy markdown editor, [EasyMDE](https://github.com/Ionaru/easy-markdown-editor)
|
||||
* `marked.js.gz` is the markdown rendering library [Marked](https://github.com/markedjs/marked)
|
||||
* `mini-fa.css.gz` and `mini-fa.woff` is a small subset of [fontawesome](https://github.com/FortAwesome/Font-Awesome)
|
||||
* `prism.css.gz` and `prism.js.gz` is the syntax highlighter [PrismJS](https://prismjs.com/)
|
||||
* `scp.woff2` is a subset of the monospace font [Source Code Pro](https://github.com/adobe-fonts/source-code-pro)
|
||||
* `sha512.hw.js.gz` is the Wasm sha512 library [hash-wasm](https://github.com/Daninet/hash-wasm)
|
||||
|
||||
additionally, the following files are vendored into the copyparty git repository, but do NOT originate from the copyparty project (as mentioned in `--license`):
|
||||
|
||||
* `sha512.ac.js.gz` is a compiled and slightly golfed/modified [asmcrypto.js](https://github.com/asmcrypto/asmcrypto.js), © 2013 Artem S Vybornov (MIT-Licensed)
|
||||
* vendored because it no longer builds with modern versions of NodeJS/npm
|
||||
* is only loaded by *really old* webbrowsers (ie11, firefox 51, chrome 56)
|
||||
|
||||
finally, there is also the following files which *does* originate from the copyparty project, yet appear here for technical reasons:
|
||||
|
||||
* `busy.mp3.gz` is a short mp3-file to make iphones stop glitching out
|
||||
BIN
copyparty/web/deps/sha512.ac.js.gz
Normal file
BIN
copyparty/web/deps/sha512.ac.js.gz
Normal file
Binary file not shown.
|
|
@ -1,5 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang="en" id="ht_idp">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
<!DOCTYPE html><html><head>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" id="ht_md">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>📝 {{ title }}</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
|
|
@ -11,6 +14,7 @@
|
|||
{%- endif %}
|
||||
{{ html_head }}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="mn"></div>
|
||||
<div id="mh">
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
<!DOCTYPE html><html><head>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" id="ht_mde">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>📝 {{ title }}</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
|
|
@ -10,6 +13,7 @@
|
|||
<link rel="stylesheet" href="{{ r }}/.cpr/deps/easymde.css?_={{ ts }}">
|
||||
{{ html_head }}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="mw">
|
||||
<div id="mn"></div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang="en" id="ht_msg">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang="en" id="ht_rup">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>{{ s_doctitle }}</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.8">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<meta name="theme-color" content="#{{ tcolor }}">
|
||||
<link rel="stylesheet" media="screen" href="{{ r }}/.cpr/rups.css?_={{ ts }}">
|
||||
<link rel="stylesheet" media="screen" href="{{ r }}/.cpr/ui.css?_={{ ts }}">
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang="en" id="ht_shr">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>{{ s_doctitle }}</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.8">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<meta name="theme-color" content="#{{ tcolor }}">
|
||||
<link rel="stylesheet" media="screen" href="{{ r }}/.cpr/shares.css?_={{ ts }}">
|
||||
<link rel="stylesheet" media="screen" href="{{ r }}/.cpr/ui.css?_={{ ts }}">
|
||||
|
|
@ -40,8 +40,8 @@
|
|||
{%- for k, pw, vp, pr, st, un, t0, t1 in rows %}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{{ r }}{{ shr }}{{ k }}?qr">qr</a>
|
||||
<a href="{{ r }}{{ shr }}{{ k }}">{{ k }}</a>
|
||||
<a href="{{ site }}{{ shr }}{{ k }}/?qr">qr</a>
|
||||
<a href="{{ r }}{{ shr }}{{ k }}/">{{ k }}</a>
|
||||
</td>
|
||||
<td><a href="#" k="{{ k }}">delete</a></td>
|
||||
<td>{{ "yes" if pw else "--" }}</td>
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ function rm() {
|
|||
}
|
||||
|
||||
function bump() {
|
||||
var k = this.closest('tr').getElementsByTagName('a')[2].getAttribute('k'),
|
||||
var k = this.closest('tr').querySelector('a[k]').getAttribute('k'),
|
||||
u = SR + '/?skey=' + uricom_enc(k) + '&eshare=' + this.value,
|
||||
xhr = new XHR();
|
||||
|
||||
|
|
@ -63,7 +63,17 @@ function showqr(href) {
|
|||
|
||||
var buf = [];
|
||||
for (var a = 0; a < tr.length; a++) {
|
||||
tr[a].cells[0].getElementsByTagName('a')[0].onclick = qr;
|
||||
var td = tr[a].cells[0],
|
||||
sa = td.getElementsByTagName('a'),
|
||||
h0 = sa[0].href,
|
||||
h1 = sa[1].href;
|
||||
sa[0].onclick = qr;
|
||||
if (!h0.startsWith(h1)) {
|
||||
var a2 = mknod('a', '', sa[1].innerHTML);
|
||||
a2.href = h0.slice(0, -3);
|
||||
sa[1].innerHTML = 'LAN';
|
||||
td.appendChild(a2);
|
||||
}
|
||||
for (var b = 7; b < 9; b++)
|
||||
buf.push(parseInt(tr[a].cells[b].innerHTML));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang="en" id="ht_spl">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang="en" id="ht_svc">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
|
|
|||
|
|
@ -226,6 +226,7 @@ Ls.chi = {
|
|||
"ct_ttips": '◔ ◡ ◔">ℹ️ 工具提示',
|
||||
"ct_thumb": '在网格视图中,切换图标或缩略图$N快捷键: T">🖼️ 缩略图',
|
||||
"ct_csel": '在网格视图中使用 CTRL 和 SHIFT 进行文件选择">CTRL',
|
||||
"ct_dsel": '在网格视图中使用拖动选择">拖动', //m
|
||||
"ct_dl": '点击文件时强制下载(不内联显示)">dl', //m
|
||||
"ct_ihop": '当图像查看器关闭时,滚动到最后查看的文件">滚动',
|
||||
"ct_dots": '显示隐藏文件(如果服务器允许)">隐藏文件',
|
||||
|
|
@ -264,6 +265,7 @@ Ls.chi = {
|
|||
"cdt_ask": "滚动到底部时,$N不会加载更多文件,$N而是询问你该怎么做",
|
||||
"cdt_hsort": "包含在媒体 URL 中的排序规则 (<code>,sorthref</code>) 数量。将其设置为 0 时,点击媒体链接时也会忽略排序规则。", //m
|
||||
"cdt_ren": "启用自定义右键菜单,按住 shift 键并右键单击仍可访问常规菜单", //m
|
||||
"cdt_rdb": "当自定义右键菜单已打开并再次右键点击时显示常规右键菜单", //m
|
||||
|
||||
"tt_entree": "显示导航面板(目录树侧边栏)$N快捷键: B",
|
||||
"tt_detree": "显示面包屑导航$N快捷键: B",
|
||||
|
|
@ -354,6 +356,7 @@ Ls.chi = {
|
|||
"f_anota": "仅选择了 {0} 个项目,共 {1} 个;\n要选择整个文件夹,请先滚动到底部", //m
|
||||
|
||||
"f_dls": '当前文件夹中的文件链接已\n更改为下载链接',
|
||||
"f_dl_nd": '跳过文件夹(请改用 zip/tar 下载):\n', //m
|
||||
|
||||
"f_partial": "要安全下载正在上传的文件,请点击没有 <code>.PARTIAL</code> 文件扩展名的同名文件。请按取消或 Escape 执行此操作。\n\n按 确定 / Enter 将忽略此警告并继续下载 <code>.PARTIAL</code> 临时文件,这几乎肯定会导致数据损坏。",
|
||||
|
||||
|
|
@ -653,10 +656,13 @@ Ls.chi = {
|
|||
"rc_cut": "剪切", //m
|
||||
"rc_cpy": "复制", //m
|
||||
"rc_pst": "粘贴", //m
|
||||
"rc_rnm": "重命名", //m
|
||||
"rc_nfo": "新建文件夹", //m
|
||||
"rc_nfi": "新建文件", //m
|
||||
"rc_sal": "全选", //m
|
||||
"rc_sin": "反选", //m
|
||||
"rc_shf": "共享此文件夹", //m
|
||||
"rc_shs": "共享所选内容", //m
|
||||
|
||||
"lang_set": "刷新以使更改生效?",
|
||||
|
||||
|
|
|
|||
|
|
@ -230,6 +230,7 @@ Ls.cze = {
|
|||
"ct_ttips": '◔ ◡ ◔">ℹ️ nápovědy',
|
||||
"ct_thumb": 'v zobrazení mřížky přepnout ikony nebo náhledy$NKlávesová zkratka: T">🖼️ náhledy',
|
||||
"ct_csel": 'použít CTRL a SHIFT pro výběr souborů v zobrazení mřížky">výběr',
|
||||
"ct_dsel": 'použít tažený výběr v zobrazení mřížky">tažení', //m
|
||||
"ct_dl": 'vynutit stažení (nezobrazovat inline) při kliknutí na soubor">dl', //m
|
||||
"ct_ihop": 'když se zavře prohlížeč obrázků, posunout dolů k naposledy zobrazenému souboru">g⮯',
|
||||
"ct_dots": 'zobrazit skryté soubory (pokud to server povoluje)">dotfiles',
|
||||
|
|
@ -268,6 +269,7 @@ Ls.cze = {
|
|||
"cdt_ask": "při posunování na konec,$Nmísto načítání více souborů,$N se zeptat co dělat",
|
||||
"cdt_hsort": "kolik pravidel řazení (<code>,sorthref</code>) zahrnout do media-URL. Nastavení na 0 bude také ignorovat pravidla řazení zahrnutá v media odkazech při kliknutí na ně",
|
||||
"cdt_ren": "povolit vlastní kontextovou nabídku, běžnou nabídku lze otevřít podržením klávesy shift a kliknutím pravým tlačítkem", //m
|
||||
"cdt_rdb": "zobrazit běžné menu pravého tlačítka, když je vlastní již otevřené a znovu se klikne pravým", //m
|
||||
|
||||
"tt_entree": "zobrazit navigační panel (postranní strom adresářů)$NKlávesová zkratka: B",
|
||||
"tt_detree": "zobrazit drobečkovou navigaci$NKlávesová zkratka: B",
|
||||
|
|
@ -358,6 +360,7 @@ Ls.cze = {
|
|||
"f_anota": "pouze {0} z {1} položek bylo vybráno;\npro výběr celé složky nejprve přejděte na konec",
|
||||
|
||||
"f_dls": 'odkazy na soubory v aktuální složce byly\nzměněny na odkazy ke stažení',
|
||||
"f_dl_nd": 'přeskakuje se složka (místo toho použijte stažení zip/tar):\n', //m
|
||||
|
||||
"f_partial": "Pro bezpečné stažení souboru, který se aktuálně nahrává, klikněte prosím na soubor se stejným názvem, ale bez přípony <code>.PARTIAL</code>. Stiskněte prosím Zrušit nebo Escape.\n\nStisknutím OK / Enter ignorujete toto varování a pokračujete ve stahování <code>.PARTIAL</code> dočasného souboru, což téměř jistě vyústí jako poškozená data.",
|
||||
|
||||
|
|
@ -657,10 +660,13 @@ Ls.cze = {
|
|||
"rc_cut": "vyjmout", //m
|
||||
"rc_cpy": "kopírovat", //m
|
||||
"rc_pst": "vložit", //m
|
||||
"rc_rnm": "přejmenovat", //m
|
||||
"rc_nfo": "nová složka", //m
|
||||
"rc_nfi": "nový soubor", //m
|
||||
"rc_sal": "vybrat vše", //m
|
||||
"rc_sin": "invertovat výběr", //m
|
||||
"rc_shf": "sdílet tuto složku", //m
|
||||
"rc_shs": "sdílet výběr", //m
|
||||
|
||||
"lang_set": "obnovit stránku, aby se změna projevila?",
|
||||
|
||||
|
|
|
|||
|
|
@ -226,6 +226,7 @@ Ls.deu = {
|
|||
"ct_ttips": '◔ ◡ ◔">ℹ️ Tooltips',
|
||||
"ct_thumb": 'In Raster-Ansicht, zwischen Icons und Vorschau wechseln$NHotkey: T">🖼️ Vorschaubilder',
|
||||
"ct_csel": 'Benutze STRG und UMSCHALT für Dateiauswahl in Raster-Ansicht">sel',
|
||||
"ct_dsel": 'Ziehauswahl in Raster-Ansicht verwenden">ziehen', //m
|
||||
"ct_dl": 'Beim Klick auf Dateien sie immer herunterladen (nicht einbetten)">dl',
|
||||
"ct_ihop": 'Wenn die Bildanzeige geschlossen ist, scrolle runter zu den zuletzt angesehenen Dateien">g⮯',
|
||||
"ct_dots": 'Verstecke Dateien anzeigen (wenn durch den Server erlaubt)">dotfiles',
|
||||
|
|
@ -264,6 +265,7 @@ Ls.deu = {
|
|||
"cdt_ask": "beim Runterscrollen nach $NAktion fragen statt mehr,$NDateien zu laden",
|
||||
"cdt_hsort": "Menge an Sortierregeln (<code>,sorthref</code>) in Media-URLs enthalten sein sollen. Ein Wert von 0 sorgt dafür, dass Sortierregeln in Media-URLs ignoriert werden",
|
||||
"cdt_ren": "spezielles Rechtsklick-Menü aktivieren, das Browser-Menü ist weiterhin mit Shift + Rechtsklick erreichbar",
|
||||
"cdt_rdb": "normales Rechtsklick-Menü anzeigen, wenn das benutzerdefinierte bereits offen ist und erneut rechts geklickt wird", //m
|
||||
|
||||
"tt_entree": "Navpane anzeigen (Ordnerbaum Sidebar)$NHotkey: B",
|
||||
"tt_detree": "Breadcrumbs anzeigen$NHotkey: B",
|
||||
|
|
@ -354,6 +356,7 @@ Ls.deu = {
|
|||
"f_anota": "nur {0} der {1} Elemente wurden ausgewählt;\num den gesamten Ordner auszuwählen, zuerst nach unten scrollen",
|
||||
|
||||
"f_dls": 'die Dateilinks im aktuellen Ordner wurden\nin Downloadlinks geändert',
|
||||
"f_dl_nd": 'ordner wird übersprungen (bitte zip/tar-download verwenden):\n', //m
|
||||
|
||||
"f_partial": "Um eine Datei sicher herunterzuladen, die gerade hochgeladen wird, klicke bitte die Datei mit dem gleichen Namen, aber ohne die <code>.PARTIAL</code>-Endung. Bitte drücke Abbrechen oder Escape, um dies zu tun.\n\nWenn du auf OK / Eingabe drückst, ignorierst du diese Warnung und lädst die <code>.PARTIAL</code>-Datei herunter, die ziemlich sicher beschädigte Daten enthält.",
|
||||
|
||||
|
|
@ -653,10 +656,13 @@ Ls.deu = {
|
|||
"rc_cut": "ausschneiden",
|
||||
"rc_cpy": "kopieren",
|
||||
"rc_pst": "einfügen",
|
||||
"rc_rnm": "umbenennen", //m
|
||||
"rc_nfo": "neuer Ordner",
|
||||
"rc_nfi": "neue Datei",
|
||||
"rc_sal": "alles auswählen",
|
||||
"rc_sin": "auswahl umkehren",
|
||||
"rc_shf": "diesen ordner teilen", //m
|
||||
"rc_shs": "auswahl teilen", //m
|
||||
|
||||
"lang_set": "Neuladen um Änderungen anzuwenden?",
|
||||
|
||||
|
|
|
|||
|
|
@ -84,8 +84,8 @@ Ls.epo = {
|
|||
["M", "fermi dosieron"],
|
||||
["E", "redakti dosieron"],
|
||||
["S", "elekti dosieron (por eltondado/kopiado/alinomado)"],
|
||||
["Y", "elŝuti tekstodosieron"], //m
|
||||
["⇧ J", "beligi json"], //m
|
||||
["Y", "elŝuti tekstodosieron"],
|
||||
["⇧ J", "beligi JSONon"],
|
||||
]
|
||||
],
|
||||
|
||||
|
|
@ -118,7 +118,7 @@ Ls.epo = {
|
|||
"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_mkdir": "mkdir: krei novan dosierujon",
|
||||
"ot_md": "new-file: krei novan tekstodosieron", //m
|
||||
"ot_md": "new-file: krei novan tekstodosieron",
|
||||
"ot_msg": "msg: sendi mesaĝon al servila protokolo",
|
||||
"ot_mp": "agordoj de medialudilo",
|
||||
"ot_cfg": "aliaj agordoj",
|
||||
|
|
@ -127,7 +127,7 @@ Ls.epo = {
|
|||
"ot_noie": 'Bonvolu uzi retumilojn Chrome / Firefox / Edge',
|
||||
|
||||
"ab_mkdir": "krei dosierujon",
|
||||
"ab_mkdoc": "krei tekstodosieron", //m
|
||||
"ab_mkdoc": "krei tekstodosieron",
|
||||
"ab_msg": "sendi mesaĝon al protokolo",
|
||||
|
||||
"ay_path": "iri al dosierujoj",
|
||||
|
|
@ -155,7 +155,7 @@ Ls.epo = {
|
|||
"ul_par": "paralelaj alŝutoj:",
|
||||
"ut_rand": "hazardigi dosiernomojn",
|
||||
"ut_u2ts": "kopii la tempon de lasta modifo$Nel via dosiersistemo al la servilo\">📅",
|
||||
"ut_ow": "ĉu anstataŭigi dosierojn ĉe la servilo?$N🛡️: neniam (dosiero estos alŝutita kun nova dosiernomo)$N🕒: anstataŭigi, se servila dosiero estas pli malnova ol via$N♻️: ĉiam anstataŭigi, se dosieroj estas malsamaj$N⏭️: senkondiĉe preterlasi ĉiujn ekzistantajn dosierojn", //m
|
||||
"ut_ow": "ĉu anstataŭigi dosierojn ĉe la servilo?$N🛡️: neniam (dosiero estos alŝutita kun nova dosiernomo)$N🕒: anstataŭigi, se servila dosiero estas pli malnova ol via$N♻️: ĉiam anstataŭigi, se dosieroj estas malsamaj$N⏭️: senkondiĉe preterlasi ĉiujn ekzistantajn dosierojn",
|
||||
"ut_mt": "daŭri kalkuladon de kontrolsumoj por aliaj dosieroj dum alŝutado$N$Nmalŝaltinda, se via procesoro aŭ disko ne estas sufiĉe rapidaj",
|
||||
"ut_ask": 'peti konfirmon antaŭ komenco de alŝutado">💭',
|
||||
"ut_pot": "plirapidigi alŝutadon por malrapidaj komputiloj$Nper malkomplikado de fasado",
|
||||
|
|
@ -220,13 +220,14 @@ Ls.epo = {
|
|||
"cl_reset": "restarigi",
|
||||
"cl_hpick": "alklaki la kapojn de kolumnoj por kasi en la suban tabelon",
|
||||
"cl_hcancel": "kaŝado de kolumno nuligita",
|
||||
"cl_rcm": "dekstra-klaka menuo", //m
|
||||
"cl_rcm": "dekstra-klaka menuo",
|
||||
|
||||
"ct_grid": '田 krado',
|
||||
"ct_ttips": '◔ ◡ ◔">ℹ️ ŝpruchelpiloj',
|
||||
"ct_thumb": 'dum krado-vido, baskuli montradon de simboloj aŭ bildetoj$NFulmoklavo: T">🖼️ bildetoj',
|
||||
"ct_csel": 'uzi STIR kaj MAJ por elekti dosierojn en krado-vido">elekto',
|
||||
"ct_dl": 'devigi elŝuton (ne montri enkadre) kiam dosiero estas alklakita">dl', //m
|
||||
"ct_dsel": 'uzi tren-elekton en krado-vido">treni',
|
||||
"ct_dl": 'devigi elŝuton (ne montri enkadre), kiam dosiero estas alklakita">dl',
|
||||
"ct_ihop": 'montri la lastan viditan bildo-dosieron post fermado de bildo-vidilo">g⮯',
|
||||
"ct_dots": 'montri kaŝitajn dosierojn (se servilo permesas)">kaŝitaj',
|
||||
"ct_qdel": 'peti konfirmon nur unufoje antaŭ forigado">rapid-forig.',
|
||||
|
|
@ -263,7 +264,8 @@ Ls.epo = {
|
|||
"cdt_lim": "maks. nombro de dosieroj por montri en dosierujo",
|
||||
"cdt_ask": "je malsupro de paĝo, peti por ago$Nanstataŭ ŝarĝi pli da dosieroj",
|
||||
"cdt_hsort": "kiom da ordigo-reguloj (<code>,sorthref</code>) inkludi en adreso de la paĝo. Se agordita kiel 0, reguloj, inkluditaj en la adreso, estos ignoritaj",
|
||||
"cdt_ren": "ebligi propran dekstra-klakan menuon, la normala menuo restas alirebla per shift + dekstra klako", //m
|
||||
"cdt_ren": "ebligi propran dekstra-klakan menuon, la normala menuo restas alirebla per MAJ + dekstra klako",
|
||||
"cdt_rdb": "montri la normalan dekstraklakan menuon, kiam la propra jam estas malfermita kaj oni denove dekstre klakas",
|
||||
|
||||
"tt_entree": "montri arbovidan navig-panelon$NFulmoklavo: B",
|
||||
"tt_detree": "montri paĝnivelan navig-panelon$NFulmoklavo: B",
|
||||
|
|
@ -354,6 +356,7 @@ Ls.epo = {
|
|||
"f_anota": "nur {0} de {1} eroj estis elektita;\nrulumi al la malsupro por elekti la tutan dosierujon",
|
||||
|
||||
"f_dls": 'la ligiloj de dosieroj en ĉi tiu dosierujo estis\nanstataŭigitaj per elŝuto-ligiloj',
|
||||
"f_dl_nd": 'preterlasante dosierujon (uzu zip/tar-elŝuton anstataŭe):\n', //m
|
||||
|
||||
"f_partial": "Por sendifekta elŝuto de nune-alŝutata dosiero, elektu dosieron kun sama nomo, sed sen etendaĵo <code>.PARTIAL</code>. Bonvolu uzi la butonon \"Rezigni\" aŭ klavon ESK por fari tion.\n\nSe vi uzas OK / Enter, la provizora dosiero <code>.PARTIAL</code> estos elŝutita, kiu tre probable enhavas nekompletajn datumojn.",
|
||||
|
||||
|
|
@ -456,7 +459,7 @@ Ls.epo = {
|
|||
"tvt_prev": "montri malsekvan dokumenton$NFulmoklavo: i\">⬆ malsekva",
|
||||
"tvt_next": "montri sekvan dokumenton$NFulmoklavo: K\">⬇ sekva",
|
||||
"tvt_sel": "elekti dosieron ( por eltondado / kopiado / forigado / ... )$NFulmoklavo: S\">elekti",
|
||||
"tvt_j": "beligi json$NFulmoklavo: shift-J\">j", //m
|
||||
"tvt_j": "beligi JSONon$NFulmoklavo: MAJ-J\">j",
|
||||
"tvt_edit": "malfermi dosieron en teksto-redaktilo$NFulmoklavo: E\">✏️ redakti",
|
||||
"tvt_tail": "observi ŝanĝojn en dosiero; novaj linioj estos tuje montritaj\">📡 gvati",
|
||||
"tvt_wrap": "linifaldo\">↵",
|
||||
|
|
@ -653,10 +656,13 @@ Ls.epo = {
|
|||
"rc_cut": "eltondi", //m
|
||||
"rc_cpy": "kopii", //m
|
||||
"rc_pst": "alglui", //m
|
||||
"rc_rnm": "alinomi", //m
|
||||
"rc_nfo": "nova dosierujo", //m
|
||||
"rc_nfi": "nova dosiero", //m
|
||||
"rc_sal": "elekti ĉion", //m
|
||||
"rc_sin": "inversigi elekton", //m
|
||||
"rc_shf": "kunhavigi ĉi tiun dosierujon", //m
|
||||
"rc_shs": "kunhavigi elekton", //m
|
||||
|
||||
"lang_set": "ĉu reŝargi paĝon por efektivigi lingvo-ŝanĝon?",
|
||||
|
||||
|
|
|
|||
|
|
@ -226,6 +226,7 @@ Ls.fin = {
|
|||
"ct_ttips": '◔ ◡ ◔">ℹ️ vihjelaatikot',
|
||||
"ct_thumb": 'valitse kuvakkeiden / pienoiskuvien välillä kuvanäkymässä $NPikanäppäin: T">🖼️ pienoiskuvat',
|
||||
"ct_csel": 'käytä CTRL ja SHIFT tiedostojen valintaan kuvanäkymässä">valitse',
|
||||
"ct_dsel": 'käytä aluevalintaa tiedostojen valintaan kuvanäkymässä">aluevalinta',
|
||||
"ct_dl": 'pakota lataus (älä näytä upotettuna), kun tiedostoa napsautetaan">dl', //m
|
||||
"ct_ihop": 'kun kuvakatselin suljetaan, vieritä alas viimeksi katsottuun tiedostoon">g⮯',
|
||||
"ct_dots": 'näytä piilotetut tiedostot (jos palvelin sallii)">piilotiedostot',
|
||||
|
|
@ -264,6 +265,7 @@ Ls.fin = {
|
|||
"cdt_ask": "sivun lopussa, sen sijaan että lataa $Nautomaattisesti lisää tiedostoja, kysy mitä tehdä",
|
||||
"cdt_hsort": "kuinka monta lajittelusääntöä (<code>,sorthref</code>) sisällyttää media-URL:eihin. Tämän asettaminen nollaan jättää myös huomioimatta media-linkeissä sisällytetyt lajittelusäännöt kun napsautat niitä",
|
||||
"cdt_ren": "ota käyttöön mukautettu valikko, tavallinen valikko on käytettävissä painamalla shift ja napsauttamalla oikealla", //m
|
||||
"cdt_rdb": "näytä tavallinen oikean painikkeen valikko, kun mukautettu on jo auki ja oikeaa painiketta painetaan uudelleen", //m
|
||||
|
||||
"tt_entree": "näytä navigointipaneeli$NPikanäppäin: B",
|
||||
"tt_detree": "näytä linkkipolku$NPikanäppäin: B",
|
||||
|
|
@ -354,6 +356,7 @@ Ls.fin = {
|
|||
"f_anota": "vain {0} / {1} kohdetta valittiin;\nvalitaksesi koko hakemiston, vieritä ensin loppuun",
|
||||
|
||||
"f_dls": 'nykyisen hakemiston tiedostolinkit on\nvaihdettu latauslinkeiksi',
|
||||
"f_dl_nd": 'ohitetaan kansio (käytä zip/tar-latausta sen sijaan):\n', //m
|
||||
|
||||
"f_partial": "Ladataksesi turvallisesti tiedoston joka on parhaillaan latautumassa, klikkaa tiedostoa jolla on sama nimi mutta ilman <code>.PARTIAL</code> päätettä. Paina PERUUTA tai Escape tehdäksesi tämän.\n\nOK / Enter painaminen sivuuttaa tämän varoituksen ja jatkaa <code>.PARTIAL</code> väliaikaistiedoston lataamista, mikä todennäköisesti antaa sinulle vioittunutta dataa.",
|
||||
|
||||
|
|
@ -653,10 +656,13 @@ Ls.fin = {
|
|||
"rc_cut": "Leikkaa", //m
|
||||
"rc_cpy": "kopioi", //m
|
||||
"rc_pst": "Liitä", //m
|
||||
"rc_rnm": "nimeä uudelleen", //m
|
||||
"rc_nfo": "uusi kansio", //m
|
||||
"rc_nfi": "uusi tiedosto", //m
|
||||
"rc_sal": "valitse kaikki", //m
|
||||
"rc_sin": "käännä valinta", //m
|
||||
"rc_shf": "jaa tämä kansio", //m
|
||||
"rc_shs": "jaa valinta", //m
|
||||
|
||||
"lang_set": "ladataanko sivu uudestaan kielen vaihtamiseksi?",
|
||||
|
||||
|
|
|
|||
|
|
@ -226,6 +226,7 @@ Ls.fra = {
|
|||
"ct_ttips": '◔ ◡ ◔">ℹ️ infobulles',
|
||||
"ct_thumb": 'vue en grille, activer les icônes ou les miniatures$NHotkey: T">🖼️ minia',
|
||||
"ct_csel": 'utiliser CTRL et MAJ pour selectioner des fichiers en vue en grille">sel',
|
||||
"ct_dsel": 'utiliser la sélection par glisser en vue en grille">glisser', //m
|
||||
"ct_dl": 'forcer le téléchargement (ne pas afficher en ligne) lorsqu’un fichier est cliqué">dl', //m
|
||||
"ct_ihop": 'quand le visionneuse d\'image est fermé, faire defiller vers le bas jusqu\'au dernier fichier">g⮯',
|
||||
"ct_dots": 'voir les fichiers caché (si le serveur le permet)">dotfiles',
|
||||
|
|
@ -264,6 +265,7 @@ Ls.fra = {
|
|||
"cdt_ask": "lorsque vous faites défiler vers le bas,$Nau lieu de charger plus de fichiers,$Ndemander quoi faire",
|
||||
"cdt_hsort": "combien de règles de tri (<code>,sorthref</code>) à inclure dans les media-URLs. Définir cette valeur à 0 ignorera également les règles de tri incluses dans les liens média lorsque vous cliquez dessus.",
|
||||
"cdt_ren": "activer le menu contextuel personnalisé, le menu normal reste accessible avec shift + clic droit", //m
|
||||
"cdt_rdb": "afficher le menu clic droit normal lorsque le menu personnalisé est déjà ouvert et qu’on clique à nouveau", //m
|
||||
|
||||
"tt_entree": "afficher le panneau de navigation (arborescence des dossiers)$NHotkey: B",
|
||||
"tt_detree": "afficher le fil d’Ariane$NHotkey: B",
|
||||
|
|
@ -354,6 +356,7 @@ Ls.fra = {
|
|||
"f_anota": "seulement {0} des {1} elements sont selectioné;\npour selectioner le dossier entier, fait défiler jusqu'au fond",
|
||||
|
||||
"f_dls": 'le lien de fichier dans le répertoire actuel\nà été changé en lien de téléchargement',
|
||||
"f_dl_nd": 'dossier ignoré (utilisez le téléchargement zip/tar à la place):\n', //m
|
||||
|
||||
"f_partial": "Pour télécharger de façon sécurisée un fichier qui est entrain de se faire téléverser, cliquez sur le fichier qui a le même nom, mais sans l'extension de fichier <code>.PARTIAL</code>. Choisissez ANNULER ou appuiez sur la touche Échap pour faire cela.\n\nAppuyer sur OK / Entrée ignorera cet avertissement et continuera à télécharger le fichier temporaire <code>.PARTIAL</code> à la place, ce qui donnera presque certainement des données corrompues.",
|
||||
|
||||
|
|
@ -653,10 +656,13 @@ Ls.fra = {
|
|||
"rc_cut": "couper", //m
|
||||
"rc_cpy": "copier", //m
|
||||
"rc_pst": "coller", //m
|
||||
"rc_rnm": "renommer", //m
|
||||
"rc_nfo": "nouveau dossier", //m
|
||||
"rc_nfi": "nouveau fichier", //m
|
||||
"rc_sal": "tout sélectionner", //m
|
||||
"rc_sin": "inverser la sélection", //m
|
||||
"rc_shf": "partager ce dossier", //m
|
||||
"rc_shs": "partager la sélection", //m
|
||||
|
||||
"lang_set": "rafraîchir pour que les changements prennent effet ?",
|
||||
|
||||
|
|
|
|||
|
|
@ -226,6 +226,7 @@ Ls.grc = {
|
|||
"ct_ttips": '◔ ◡ ◔">ℹ️ συμβουλές εργαλείων',
|
||||
"ct_thumb": 'σε προβολή πλέγματος, εναλλαγή εικονιδίων ή μικρογραφιών$NΠλήκτρο συντόμευσης: T">🖼️ μικρογραφίες',
|
||||
"ct_csel": 'χρησιμοποίησε CTRL και SHIFT για επιλογή αρχείων σε προβολή πλέγματος">επιλογή',
|
||||
"ct_dsel": 'χρησιμοποίησε επιλογή με σύρσιμο σε προβολή πλέγματος">σύρσιμο', //m
|
||||
"ct_dl": 'εξαναγκασμός λήψης (να μην εμφανίζεται ενσωματωμένα) όταν γίνεται κλικ σε ένα αρχείο">dl', //m
|
||||
"ct_ihop": 'όταν η προβολή εικόνων κλείνει, κάνε scroll στο τελευταίο προβαλλόμενο αρχείο">g⮯',
|
||||
"ct_dots": 'εμφάνιση κρυφών αρχείων (αν το επιτρέπει ο server)">dotfiles',
|
||||
|
|
@ -264,6 +265,7 @@ Ls.grc = {
|
|||
"cdt_ask": "όταν φτάνεις στο τέλος,$Nαντί να φορτώσει περισσότερα αρχεία,$Nρωτά τι να κάνει",
|
||||
"cdt_hsort": "πόσους κανόνες ταξινόμησης (<code>,sorthref</code>) να συμπεριλάβει σε URLs πολυμέσων. Αν το βάλεις 0 αγνοεί και κανόνες ταξινόμησης στους συνδέσμους πολυμέσων",
|
||||
"cdt_ren": "ενεργοποίηση προσαρμοσμένου μενού δεξιού κλικ, το κανονικό μενού είναι προσβάσιμο με shift + δεξί κλικ", //m
|
||||
"cdt_rdb": "εμφάνιση του κανονικού μενού δεξιού κλικ όταν το προσαρμοσμένο είναι ήδη ανοιχτό και γίνεται ξανά δεξί κλικ", //m
|
||||
|
||||
"tt_entree": "εμφάνιση navpane (δέντρο διαδρομών)$NΠλήκτρο συντόμευσης: B",
|
||||
"tt_detree": "εμφάνιση breadcrumbs (καρτέλες διαδρομών)$NΠλήκτρο συντόμευσης: B",
|
||||
|
|
@ -354,6 +356,7 @@ Ls.grc = {
|
|||
"f_anota": "μόνο {0} από τα {1} αντικείμενα επιλέχθηκαν;\nγια να επιλέξεις ολόκληρο το φάκελο, κύλησε πρώτα μέχρι κάτω",
|
||||
|
||||
"f_dls": 'οι σύνδεσμοι αρχείων στον τρέχοντα φάκελο έχουν\nμετατραπεί σε συνδέσμους λήψης',
|
||||
"f_dl_nd": 'παράλειψη φακέλου (χρησιμοποιήστε λήψη zip/tar αντί γι’ αυτό):\n', //m
|
||||
|
||||
"f_partial": "Για να κατεβάσεις με ασφάλεια ένα αρχείο που ανεβαίνει, κλίκαρε το αρχείο με το ίδιο όνομα, αλλά χωρίς την κατάληξη <code>.PARTIAL</code>. Πάτα Άκυρο ή Escape για να σταματήσεις.\n\nΠάτα Εντάξει / Enter αν αγνοείς την προειδοποίηση και κατέβασε το <code>.PARTIAL</code> αρχείο, που σχεδόν σίγουρα θα είναι κατεστραμμένο.",
|
||||
|
||||
|
|
@ -653,10 +656,13 @@ Ls.grc = {
|
|||
"rc_cut": "αποκοπή", //m
|
||||
"rc_cpy": "αντιγραφή", //m
|
||||
"rc_pst": "επικόλληση", //m
|
||||
"rc_rnm": "μετονομασία", //m
|
||||
"rc_nfo": "νέος φάκελος", //m
|
||||
"rc_nfi": "νέο αρχείο", //m
|
||||
"rc_sal": "επιλογή όλων", //m
|
||||
"rc_sin": "αντιστροφή επιλογής", //m
|
||||
"rc_shf": "κοινή χρήση αυτού του φακέλου", //m
|
||||
"rc_shs": "κοινή χρήση επιλογής", //m
|
||||
|
||||
"lang_set": "ανανέωση σελίδας για εφαρμογή της αλλαγής;",
|
||||
|
||||
|
|
|
|||
|
|
@ -226,6 +226,7 @@ Ls.ita = {
|
|||
"ct_ttips": '◔ ◡ ◔">ℹ️ tooltip',
|
||||
"ct_thumb": 'nella vista griglia, alterna icone o miniature$NTasto rapido: T">🖼️ miniature',
|
||||
"ct_csel": 'usa CTRL e SHIFT per la selezione file nella vista griglia">sel',
|
||||
"ct_dsel": 'usa la selezione tramite trascinamento nella vista griglia">trascina', //m
|
||||
"ct_dl": 'forza il download (non visualizzare inline) quando si clicca su un file">dl', //m
|
||||
"ct_ihop": 'quando il visualizzatore immagini è chiuso, scorri fino all\'ultimo file visualizzato">g⮯',
|
||||
"ct_dots": 'mostra file nascosti (se il server lo permette)">dotfile',
|
||||
|
|
@ -264,6 +265,7 @@ Ls.ita = {
|
|||
"cdt_ask": "quando scorri verso il fondo,$Ninvece di caricare più file,$Nchiedi cosa fare",
|
||||
"cdt_hsort": "quante regole di ordinamento (<code>,sorthref</code>) includere negli URL multimediali. Impostandolo a 0 ignorerà anche le regole di ordinamento incluse nei link multimediali quando li clicchi",
|
||||
"cdt_ren": "abilita il menu contestuale personalizzato, il menu normale è accessibile con shift + clic destro", //m
|
||||
"cdt_rdb": "mostra il menu normale con il tasto destro quando quello personalizzato è già aperto e si clicca di nuovo", //m
|
||||
|
||||
"tt_entree": "mostra pannello nav (barra laterale albero directory)$NTasto rapido: B",
|
||||
"tt_detree": "mostra breadcrumb$NTasto rapido: B",
|
||||
|
|
@ -354,6 +356,7 @@ Ls.ita = {
|
|||
"f_anota": "solo {0} dei {1} elementi sono stati selezionati;\nper selezionare l'intera cartella, prima scorri fino in fondo",
|
||||
|
||||
"f_dls": 'i link dei file nella cartella corrente sono stati\ncambiati in link di download',
|
||||
"f_dl_nd": 'cartella ignorata (usa invece il download zip/tar):\n', //m
|
||||
|
||||
"f_partial": "Per scaricare in sicurezza un file che è attualmente in fase di caricamento, clicca il file che ha lo stesso nome, ma senza l'estensione <code>.PARTIAL</code>. Premi ANNULLA o Escape per farlo.\n\nPremendo OK / Invio ignorerai questo avviso e continuerai a scaricare il file <code>.PARTIAL</code> scratch, che quasi sicuramente ti darà dati corrotti.",
|
||||
|
||||
|
|
@ -653,10 +656,13 @@ Ls.ita = {
|
|||
"rc_cut": "taglia", //m
|
||||
"rc_cpy": "copia", //m
|
||||
"rc_pst": "incolla", //m
|
||||
"rc_rnm": "rinomina", //m
|
||||
"rc_nfo": "nuova cartella", //m
|
||||
"rc_nfi": "nuovo file", //m
|
||||
"rc_sal": "seleziona tutto", //m
|
||||
"rc_sin": "inverti selezione", //m
|
||||
"rc_shf": "condividi questa cartella", //m
|
||||
"rc_shs": "condividi selezione", //m
|
||||
|
||||
"lang_set": "aggiornare per rendere effettivo il cambiamento?",
|
||||
|
||||
|
|
|
|||
|
|
@ -226,6 +226,7 @@ Ls.jpn = {
|
|||
"ct_ttips": '◔ ◡ ◔">ℹ️ ツールチップ',
|
||||
"ct_thumb": 'グリッドビューではアイコンまたはサムネイルを切り替える$Nホットキー: T">🖼️ サムネイル',
|
||||
"ct_csel": 'グリッドビューでファイルを選択するにはCtrlとShiftを使用する。">選択',
|
||||
"ct_dsel": 'グリッドビューでドラッグ選択を使用する。">ドラッグ', //m
|
||||
"ct_dl": 'ファイルをクリックしたときに強制的にダウンロードする(インラインで表示しない)">dl',
|
||||
"ct_ihop": '画像ビューアを閉じたら最後に表示したファイルまでスクロールする。">g⮯',
|
||||
"ct_dots": '隠しファイルを表示する(サーバーが許可している場合)">隠しファイル',
|
||||
|
|
@ -264,6 +265,7 @@ Ls.jpn = {
|
|||
"cdt_ask": "一番下までスクロールしたときに$N更にファイルを読み込む代わりに$N何をするか尋ねる",
|
||||
"cdt_hsort": "メディアURLに含めるソートルール (<code>,sorthref</code>) の数。0に設定するとメディアリンクをクリックした際にそのリンクに含まれるソートルールも無視されます。",
|
||||
"cdt_ren": "カスタム右クリックメニューを有効にしてもShiftキーを押しながら右クリックすることで通常のメニューにアクセスできます。",
|
||||
"cdt_rdb": "カスタム右クリックメニューが開いている状態で再度右クリックしたときに通常のメニューを表示する", //m
|
||||
|
||||
"tt_entree": "ナビペインを表示(ディレクトリツリーサイドバー)$Nホットキー: B",
|
||||
"tt_detree": "パンくずリストを表示$Nホットキー: B",
|
||||
|
|
@ -354,6 +356,7 @@ Ls.jpn = {
|
|||
"f_anota": "{1}件のアイテムのうち {0}件が選択されました;\nフォルダ全体を選択するには、まず一番下までスクロールします",
|
||||
|
||||
"f_dls": '現在のフォルダ内のファイルリンクは\nダウンロードリンクに変更されました',
|
||||
"f_dl_nd": 'フォルダーをスキップしています(代わりに zip/tar ダウンロードを使用してください):\n', //m
|
||||
|
||||
"f_partial": "現在アップロード中のファイルを安全にダウンロードするには、同じファイル名で<code>.PARTIAL</code>拡張子がないファイルをクリックしてください。これを行うにはキャンセルまたはEscキーを押してください。\n\nOK / Enter を押すとこの警告は無視され、代わりに<code>.PARTIAL</code>スクラッチファイルのダウンロードが続行されますが、ほとんどの場合データが破損することになります。",
|
||||
|
||||
|
|
@ -653,10 +656,13 @@ Ls.jpn = {
|
|||
"rc_cut": "切り取り",
|
||||
"rc_cpy": "コピー",
|
||||
"rc_pst": "貼り付け",
|
||||
"rc_rnm": "名前を変更", //m
|
||||
"rc_nfo": "新しいフォルダ",
|
||||
"rc_nfi": "新しいファイル",
|
||||
"rc_sal": "すべて選択",
|
||||
"rc_sin": "選択を反転",
|
||||
"rc_shf": "このフォルダを共有", //m
|
||||
"rc_shs": "選択項目を共有", //m
|
||||
|
||||
"lang_set": "変更を反映させるために更新しますか?",
|
||||
|
||||
|
|
|
|||
|
|
@ -226,6 +226,7 @@ Ls.kor = {
|
|||
"ct_ttips": '◔ ◡ ◔">ℹ️ 도움말',
|
||||
"ct_thumb": '그리드 보기에서 아이콘 또는 미리보기 이미지 전환$N단축키: T">🖼️ 미리보기',
|
||||
"ct_csel": '그리드 보기에서 CTRL과 SHIFT를 사용하여 파일 선택">선택',
|
||||
"ct_dsel": '그리드 보기에서 드래그 선택 사용">드래그', //m
|
||||
"ct_dl": '파일을 클릭하면 다운로드를 강제로 수행 (인라인으로 표시하지 않음)">dl', //m
|
||||
"ct_ihop": '이미지 뷰어를 닫으면 마지막으로 본 파일로 스크롤">g⮯',
|
||||
"ct_dots": '숨김 파일 표시 (서버가 허용하는 경우)">숨김파일',
|
||||
|
|
@ -264,6 +265,7 @@ Ls.kor = {
|
|||
"cdt_ask": "맨 아래로 스크롤할 때$N더 많은 파일을 불러오는 대신$N무엇을 할지 묻기",
|
||||
"cdt_hsort": "미디어 URL에 포함할 정렬 규칙 (<code>,sorthref</code>)의 수. 0으로 설정하면 미디어 링크를 클릭할 때 포함된 정렬 규칙도 무시됩니다.",
|
||||
"cdt_ren": "사용자 지정 우클릭 메뉴를 활성화합니다. shift 키를 누른 채 우클릭하면 기본 메뉴를 사용할 수 있습니다", //m
|
||||
"cdt_rdb": "사용자 정의 우클릭 메뉴가 이미 열려 있을 때 다시 우클릭하면 기본 메뉴 표시", //m
|
||||
|
||||
"tt_entree": "탐색 창 (디렉터리 트리 사이드바) 표시$N단축키: B",
|
||||
"tt_detree": "이동 경로 표시$N단축키: B",
|
||||
|
|
@ -354,6 +356,7 @@ Ls.kor = {
|
|||
"f_anota": "{1}개 항목 중 {0}개만 선택되었습니다.\n전체 폴더를 선택하려면 먼저 맨 아래로 스크롤하세요.",
|
||||
|
||||
"f_dls": '현재 폴더의 파일 링크가\n다운로드 링크로 변경되었습니다',
|
||||
"f_dl_nd": '폴더를 건너뜁니다 (대신 zip/tar 다운로드를 사용하세요):\n', //m
|
||||
|
||||
"f_partial": "현재 업로드 중인 파일을 안전하게 다운로드하려면, 파일 이름이 같지만 <code>.PARTIAL</code> 확장자가 없는 파일을 클릭하세요. 이 경고를 무시하려면 \"취소\" 또는 ESC를 누르세요.\n\n\"확인\"/Enter를 누르면 이 경고를 무시하고 <code>.PARTIAL</code> 임시 파일을 계속 다운로드하며, 이 경우 거의 확실히 손상된 데이터를 받게 됩니다.",
|
||||
|
||||
|
|
@ -653,10 +656,13 @@ Ls.kor = {
|
|||
"rc_cut": "잘라내기", //m
|
||||
"rc_cpy": "복사", //m
|
||||
"rc_pst": "붙여넣기", //m
|
||||
"rc_rnm": "이름 변경", //m
|
||||
"rc_nfo": "새 폴더", //m
|
||||
"rc_nfi": "새 파일", //m
|
||||
"rc_sal": "모두 선택", //m
|
||||
"rc_sin": "선택 반전", //m
|
||||
"rc_shf": "이 폴더 공유", //m
|
||||
"rc_shs": "선택 항목 공유", //m
|
||||
|
||||
"lang_set": '변경 사항을 적용하기 위해 새로고침하시겠습니까?',
|
||||
|
||||
|
|
|
|||
|
|
@ -226,6 +226,7 @@ Ls.nld = {
|
|||
"ct_ttips": '◔ ◡ ◔">ℹ️ tooltips',
|
||||
"ct_thumb": 'In grid-overzicht, wissel tussen iconen of thumbnails$NHotkey: T">🖼️ thumbs',
|
||||
"ct_csel": 'Gebruik CTRL en SHIFT voor de bestand selectie in grid-overzicht>sel',
|
||||
"ct_dsel": 'Gebruik slepen om te selecteren in grid-overzicht>slepen', //m
|
||||
"ct_dl": 'download afdwingen (niet inline weergeven) wanneer op een bestand wordt geklikt">dl', //m
|
||||
"ct_ihop": 'Als je afbeeldingviewer afsluit, scroll omlaag naar de laatst bekeken bestand">g⮯',
|
||||
"ct_dots": 'Laat verborgen bestanden zien (als de server dat toestaat)">dotfiles',
|
||||
|
|
@ -264,6 +265,7 @@ Ls.nld = {
|
|||
"cdt_ask": "Als helemaal naar beneden gescrolld bent,$Nin plaats van meer inladen,$Nvraag wat het moet doen",
|
||||
"cdt_hsort": "Hoeveel sorteerregels (<code>,sorthref</code>) moeten er in media-URL's worden opgenomen? Als je dit op 0 instelt, worden de sorteerregels in medialinks ook genegeerd wanneer erop geklikt word.",
|
||||
"cdt_ren": "Aangepast rechtermuisknopmenu inschakelen, het normale menu blijft beschikbaar met shift + rechtermuisknop", //m
|
||||
"cdt_rdb": "toon het normale rechtermuisknopmenu wanneer het aangepaste al open is en opnieuw wordt geklikt", //m
|
||||
|
||||
"tt_entree": "Laat navpane zien (directoryboom zijbalk)$NHotkey: B",
|
||||
"tt_detree": "Laat breadcrumbs zien$NHotkey: B",
|
||||
|
|
@ -354,6 +356,7 @@ Ls.nld = {
|
|||
"f_anota": "Alleen {0} van de {1} items zijn geselecteerd;\nom de volledige map te selecteren, scrol je eerst naar beneden",
|
||||
|
||||
"f_dls": 'de bestandslinks in de huidige map zijn veranderd in downloadlinks',
|
||||
"f_dl_nd": 'map wordt overgeslagen (gebruik in plaats daarvan zip/tar-download):\n', //m
|
||||
|
||||
"f_partial": "Om een bestand dat momenteel wordt geüpload veilig te downloaden, klikt u op het bestand met dezelfde bestandsnaam, maar zonder de bestandsextensie <code>.PARTIAL</code>. Druk op Annuleren of Escape om dit te doen.\n\nAls u op OK / Enter drukt, wordt deze waarschuwing genegeerd en gaat u verder met het downloaden van het gedeeltelijke <code>.PARTIAL</code> scratchbestand, waardoor u vrijwel zeker beschadigde gegevens krijgt.",
|
||||
|
||||
|
|
@ -653,10 +656,13 @@ Ls.nld = {
|
|||
"rc_cut": "Knippen", //m
|
||||
"rc_cpy": "Kopiëren", //m
|
||||
"rc_pst": "Plakken", //m
|
||||
"rc_rnm": "hernoemen", //m
|
||||
"rc_nfo": "Nieuwe map", //m
|
||||
"rc_nfi": "Nieuw bestand", //m
|
||||
"rc_sal": "Alles selecteren", //m
|
||||
"rc_sin": "Selectie omkeren", //m
|
||||
"rc_shf": "deel deze map", //m
|
||||
"rc_shs": "deel selectie", //m
|
||||
|
||||
"lang_set": "Vernieuw de pagina om de wijziging door te voeren?",
|
||||
|
||||
|
|
|
|||
|
|
@ -223,6 +223,7 @@ Ls.nno = {
|
|||
"ct_ttips": 'vis hjelpetekst ved å holde musa over ting">ℹ️ tips',
|
||||
"ct_thumb": 'vis miniatyrbilder i staden for ikon$NSnarvei: T">🖼️ bilder',
|
||||
"ct_csel": 'bruk tastane CTRL og SHIFT for markering av filer i ikonvising">merk',
|
||||
"ct_dsel": 'klikk-og-dra for å merke filer i ikonvising">dra',
|
||||
"ct_dl": 'last ned filer (ikkje vis i nettleseren)">dl',
|
||||
"ct_ihop": 'bla ned åt sist viste bilde når bildevisaren lukkast">g⮯',
|
||||
"ct_dots": 'vis skjulte filer (gitt at serveren tillèt det)">.synlig',
|
||||
|
|
@ -261,6 +262,7 @@ Ls.nno = {
|
|||
"cdt_ask": "vis knappar for å laste fleire filer nederst på sida i staden for å gradvis laste meir av mappea når man scroller ned",
|
||||
"cdt_hsort": "antall sorteringsreglar (<code>,sorthref</code>) som skal inkluderast når media-URL'ar genererast. Dersom denne er 0 så vil sorteringsreglar i URL'ar korkje bli generert eller lest",
|
||||
"cdt_ren": "slå på tilpassa høgreklikkmeny (den vanlege menyen er tilgjengeleg med shift + høgreklikk)",
|
||||
"cdt_rdb": "høgreklikk to gonger for å vise den vanlege høgreklikkmenyen",
|
||||
|
||||
"tt_entree": "bytt åt mappehierarki$NSnarvei: B",
|
||||
"tt_detree": "bytt åt tradisjonell stivising$NSnarvei: B",
|
||||
|
|
@ -351,6 +353,7 @@ Ls.nno = {
|
|||
"f_anota": "kun {0} av totalt {1} element blei markert;\nfor å velje alt må du bla åt bunnen av mappa først",
|
||||
|
||||
"f_dls": 'lenkane i denne mappa er no\nomgjort åt nedlastingsknappar',
|
||||
"f_dl_nd": 'hoppar over mappe (bruk zip/tar-nedlasting i staden):\n',
|
||||
|
||||
"f_partial": "For å laste ned ei fil som enda ikkje er ferdig opplasta, klikk på filen som har same filnamn som denne, men uten <code>.PARTIAL</code> på slutten. Da vil serveren passe på at nedlastinga går bra. Derfor anbefalast det sterkt å trykkje AVBRYT eller Escape-tasten.\n\nViss du verkelig ønskjer å laste ned denne <code>.PARTIAL</code>-filen på ein ukontrollert måte, trykk OK / Enter for å ignorere denne advarselen. Slik vil du høgst sannsynleg motta korrupt data.",
|
||||
|
||||
|
|
@ -650,10 +653,13 @@ Ls.nno = {
|
|||
"rc_cut": "klipp ut",
|
||||
"rc_cpy": "kopier",
|
||||
"rc_pst": "Lim inn",
|
||||
"rc_rnm": "endre namn",
|
||||
"rc_nfo": "ny mappe",
|
||||
"rc_nfi": "ny fil",
|
||||
"rc_sal": "vel alle",
|
||||
"rc_sin": "inverter val",
|
||||
"rc_shf": "del denne mappa",
|
||||
"rc_shs": "del markering",
|
||||
|
||||
"lang_set": "passar det å laste sida på nytt?",
|
||||
|
||||
|
|
|
|||
|
|
@ -223,6 +223,7 @@ Ls.nor = {
|
|||
"ct_ttips": 'vis hjelpetekst ved å holde musen over ting">ℹ️ tips',
|
||||
"ct_thumb": 'vis miniatyrbilder istedenfor ikoner$NSnarvei: T">🖼️ bilder',
|
||||
"ct_csel": 'bruk tastene CTRL og SHIFT for markering av filer i ikonvisning">merk',
|
||||
"ct_dsel": 'marker filer med klikk-og-dra i ikonvisning">dsel',
|
||||
"ct_dl": 'last ned filer (ikke vis i nettleseren)">dl',
|
||||
"ct_ihop": 'bla ned til sist viste bilde når bildeviseren lukkes">g⮯',
|
||||
"ct_dots": 'vis skjulte filer (gitt at serveren tillater det)">.synlig',
|
||||
|
|
@ -261,6 +262,7 @@ Ls.nor = {
|
|||
"cdt_ask": "vis knapper for å laste flere filer nederst på siden istedenfor å gradvis laste mer av mappen når man scroller ned",
|
||||
"cdt_hsort": "antall sorterings-regler (<code>,sorthref</code>) som skal inkluderes når media-URL'er genereres. Hvis denne er 0 så vil sorterings-regler i URL'er hverken bli generert eller lest",
|
||||
"cdt_ren": "bruk egendefinert høyreklikkmeny (den vanlige menyen er tilgjengelig med shift + høyreklikk)",
|
||||
"cdt_rdb": "høyreklikk to ganger for å vise den vanlige høyreklikkmenyen",
|
||||
|
||||
"tt_entree": "bytt til mappehierarki$NSnarvei: B",
|
||||
"tt_detree": "bytt til tradisjonell sti-visning$NSnarvei: B",
|
||||
|
|
@ -351,6 +353,7 @@ Ls.nor = {
|
|||
"f_anota": "kun {0} av totalt {1} elementer ble markert;\nfor å velge alt må du bla til bunnen av mappen først",
|
||||
|
||||
"f_dls": 'linkene i denne mappen er nå\nomgjort til nedlastningsknapper',
|
||||
"f_dl_nd": 'hopper over mappe (bruk zip/tar-nedlasting i stedet):\n',
|
||||
|
||||
"f_partial": "For å laste ned en fil som enda ikke er ferdig opplastet, klikk på filen som har samme filnavn som denne, men uten <code>.PARTIAL</code> på slutten. Da vil serveren passe på at nedlastning går bra. Derfor anbefales det sterkt å trykke AVBRYT eller Escape-tasten.\n\nHvis du virkelig ønsker å laste ned denne <code>.PARTIAL</code>-filen på en ukontrollert måte, trykk OK / Enter for å ignorere denne advarselen. Slik vil du høyst sannsynlig motta korrupt data.",
|
||||
|
||||
|
|
@ -650,10 +653,13 @@ Ls.nor = {
|
|||
"rc_cut": "klipp ut",
|
||||
"rc_cpy": "kopier",
|
||||
"rc_pst": "Lim inn",
|
||||
"rc_rnm": "gi nytt navn",
|
||||
"rc_nfo": "ny mappe",
|
||||
"rc_nfi": "ny fil",
|
||||
"rc_sal": "velg alle",
|
||||
"rc_sin": "inverter utvalg",
|
||||
"rc_shf": "del denne mappen",
|
||||
"rc_shs": "del markering",
|
||||
|
||||
"lang_set": "passer det å laste siden på nytt?",
|
||||
|
||||
|
|
|
|||
|
|
@ -229,6 +229,7 @@ Ls.pol = {
|
|||
"ct_ttips": '◔ ◡ ◔">ℹ️ podpowiedzi',
|
||||
"ct_thumb": 'w widoku siatki, przełącz ikony i miniaturki$NSkrót: T">🖼️ miniaturki',
|
||||
"ct_csel": 'użyj CTRL i SHIFT do wybierania plików w widoku siatki">wybierz',
|
||||
"ct_dsel": 'użyj zaznaczania przez przeciąganie w widoku siatki">przeciągnij', //m
|
||||
"ct_dl": 'wymuś pobieranie (nie wyświetlaj inline) po kliknięciu pliku">dl', //m
|
||||
"ct_ihop": 'przejdź do ostatniego pliku po zamknięciu przeglądarki obrazów">g⮯',
|
||||
"ct_dots": 'pokaż ukryte pliki (jeśli pozwala serwer)">ukryte',
|
||||
|
|
@ -267,6 +268,7 @@ Ls.pol = {
|
|||
"cdt_ask": "przy przewijaniu w dół,$Nzapytaj co robić,$Nzamiast wczytywać kolejne pliki",
|
||||
"cdt_hsort": "ile zasad sortowania (<code>,sorthref</code>) zawierać w generowanych linkach multimediów. Wartość 0 sprawi, że zasady sortowania zawarte w linkach multimediów przy otwarciu również będą ignorowane",
|
||||
"cdt_ren": "włącz niestandardowe menu kontekstowe, standardowe menu jest dostępne po wciśnięciu shift i kliknięciu prawym przyciskiem", //m
|
||||
"cdt_rdb": "pokaż standardowe menu prawego przycisku, gdy niestandardowe jest już otwarte i nastąpi ponowne kliknięcie", //m
|
||||
|
||||
"tt_entree": "pokaż panel nawigacyjny (panel boczny z drzewem folderów)$NSkrót: B",
|
||||
"tt_detree": "pokaż ślad nawigacyjny$NSkrót: B",
|
||||
|
|
@ -357,6 +359,7 @@ Ls.pol = {
|
|||
"f_anota": "{0} z {1} elementów zostało wybranych;\naby pokazać cały folder, zjedź na dół",
|
||||
|
||||
"f_dls": 'linki do plików w aktualnym folderze\nzostały zmienione w linki pobierania',
|
||||
"f_dl_nd": 'pomijanie folderu (użyj zamiast tego pobierania zip/tar):\n', //m
|
||||
|
||||
"f_partial": "Aby bezpiecznie pobrać plik, który aktualnie jest przesyłany, wybierz plik o tej samej nazwie, lecz bez rozszerzenia <code>.PARTIAL</code>. Żeby to zrobić, naciśnij ANULUJ lub klawisz ESC.\n\nWciśnięcie OK / Enter zignoruje to ostrzeżenie i pobierze plik tymczasowy <code>.PARTIAL</code>, który prawie z pewnością będzie zepsuty",
|
||||
|
||||
|
|
@ -656,10 +659,13 @@ Ls.pol = {
|
|||
"rc_cut": "wytnij", //m
|
||||
"rc_cpy": "kopiuj", //m
|
||||
"rc_pst": "wklej", //m
|
||||
"rc_rnm": "zmień nazwę", //m
|
||||
"rc_nfo": "nowy folder", //m
|
||||
"rc_nfi": "nowy plik", //m
|
||||
"rc_sal": "zaznacz wszystko", //m
|
||||
"rc_sin": "odwróć zaznaczenie", //m
|
||||
"rc_shf": "udostępnij ten folder", //m
|
||||
"rc_shs": "udostępnij zaznaczenie", //m
|
||||
|
||||
"lang_set": "odśwież stronę (F5), aby zastosować zmianę.",
|
||||
|
||||
|
|
|
|||
|
|
@ -84,8 +84,8 @@ Ls.por = {
|
|||
["M", "fechar arquivo de texto"],
|
||||
["E", "editar arquivo de texto"],
|
||||
["S", "selecionar arquivo (para recortar/copiar/renomear)"],
|
||||
["Y", "baixar arquivo de texto"], //m
|
||||
["⇧ J", "embelezar json"], //m
|
||||
["Y", "baixar arquivo de texto"],
|
||||
["⇧ J", "embelezar json"],
|
||||
]
|
||||
],
|
||||
|
||||
|
|
@ -118,7 +118,7 @@ Ls.por = {
|
|||
"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_mkdir": "mkdir: criar um novo diretório",
|
||||
"ot_md": "new-file: criar um novo ficheiro de texto", //m
|
||||
"ot_md": "new-file: criar um novo arquivo de texto",
|
||||
"ot_msg": "msg: enviar uma mensagem para o log do servidor",
|
||||
"ot_mp": "opções do reprodutor de mídia",
|
||||
"ot_cfg": "opções de configuração",
|
||||
|
|
@ -127,7 +127,7 @@ Ls.por = {
|
|||
"ot_noie": 'Por favor, use Chrome / Firefox / Edge',
|
||||
|
||||
"ab_mkdir": "criar diretório",
|
||||
"ab_mkdoc": "novo ficheiro de texto", //m
|
||||
"ab_mkdoc": "novo arquivo de texto",
|
||||
"ab_msg": "enviar msg para o log do srv",
|
||||
|
||||
"ay_path": "pular para pastas",
|
||||
|
|
@ -155,12 +155,12 @@ Ls.por = {
|
|||
"ul_par": "uploads paralelos:",
|
||||
"ut_rand": "randomizar nomes de arquivos",
|
||||
"ut_u2ts": "copiar o carimbo de data/hora de última modificação$Ndo seu sistema de arquivos para o servidor\">📅",
|
||||
"ut_ow": "substituir arquivos existentes no servidor?$N🛡️: nunca (irá gerar um novo nome de arquivo em vez disso)$N🕒: substituir se o arquivo no servidor for mais antigo que o seu$N♻️: sempre substituir se os arquivos forem diferentes$N⏭️: ignorar incondicionalmente todos os arquivos existentes", //m
|
||||
"ut_ow": "substituir arquivos existentes no servidor?$N🛡️: nunca (irá gerar um novo nome de arquivo em vez disso)$N🕒: substituir se o arquivo no servidor for mais antigo que o seu$N♻️: sempre substituir se os arquivos forem diferentes$N⏭️: ignorar incondicionalmente todos os arquivos existentes",
|
||||
"ut_mt": "continuar a fazer o hash de outros arquivos enquanto faz upload$N$Ntalvez desativar se sua CPU ou HDD for um gargalo",
|
||||
"ut_ask": 'pedir confirmação antes do upload começar">💭',
|
||||
"ut_pot": "melhorar a velocidade de upload em dispositivos lentos$Ntornando a UI menos complexa",
|
||||
"ut_srch": "não fazer upload, em vez disso verificar se os arquivos já$N existem no servidor (irá escanear todas as pastas que você pode ler)",
|
||||
"ut_par": "pausar uploads definindo para 0$N$naumentar se sua conexão for lenta / alta latência$N$nmanter em 1 em LAN ou se o HDD do servidor for um gargalo",
|
||||
"ut_par": "pausar uploads definindo para 0$N$Naumentar se sua conexão for lenta / alta latência$N$Nmanter em 1 em LAN ou se o HDD do servidor for um gargalo",
|
||||
"ul_btn": "soltar arquivos / pastas<br>aqui (ou clique em mim)",
|
||||
"ul_btnu": "U P L O A D",
|
||||
"ul_btns": "B U S C A R",
|
||||
|
|
@ -206,7 +206,7 @@ Ls.por = {
|
|||
"u_nav_b": '<a href="#" id="modal-ok">Arquivos</a><a href="#" id="modal-ng">Uma pasta</a>',
|
||||
|
||||
"cl_opts": "interruptores",
|
||||
"cl_hfsz": "tamanho do arquivo", //m
|
||||
"cl_hfsz": "tamanho do arquivo",
|
||||
"cl_themes": "tema",
|
||||
"cl_langs": "idioma",
|
||||
"cl_ziptype": "download de pasta",
|
||||
|
|
@ -220,13 +220,14 @@ Ls.por = {
|
|||
"cl_reset": "resetar",
|
||||
"cl_hpick": "toque nos cabeçalhos das colunas para ocultá-los na tabela abaixo",
|
||||
"cl_hcancel": "ocultar coluna abortado",
|
||||
"cl_rcm": "menu de clique direito", //m
|
||||
"cl_rcm": "menu de clique direito",
|
||||
|
||||
"ct_grid": '田 a grade',
|
||||
"ct_ttips": '◔ ◡ ◔">ℹ️ dicas de ferramentas',
|
||||
"ct_thumb": 'na visualização de grade, alternar entre ícones ou miniaturas$NHotkey: T">🖼️ miniaturas',
|
||||
"ct_csel": 'usar CTRL e SHIFT para seleção de arquivo na visualização de grade">sel',
|
||||
"ct_dl": 'forçar download (não exibir inline) ao clicar em um arquivo">dl', //m
|
||||
"ct_dsel": 'usar seleção por arrasto na visualização de grade">arrastar',
|
||||
"ct_dl": 'forçar download (não exibir na página) ao clicar em um arquivo">dl',
|
||||
"ct_ihop": 'quando o visualizador de imagens for fechado, rolar para o último arquivo visualizado">g⮯',
|
||||
"ct_dots": 'mostrar arquivos ocultos (se o servidor permitir)">dotfiles',
|
||||
"ct_qdel": 'ao excluir arquivos, pedir confirmação apenas uma vez">qdel',
|
||||
|
|
@ -241,18 +242,18 @@ Ls.por = {
|
|||
|
||||
"cut_turbo": "o botão yolo, você provavelmente NÃO quer habilitar isso:$N$Nuse isto se você estava fazendo upload de uma enorme quantidade de arquivos e teve que reiniciar por algum motivo, e quer continuar o upload o mais rápido possível$N$Nisto substitui a verificação de hash por uma simples <em>"este arquivo tem o mesmo tamanho no servidor?"</em> então se o conteúdo do arquivo for diferente ele NÃO será enviado$N$Nvocê deve desativar isso quando o upload estiver concluído, e então "enviar" os mesmos arquivos novamente para permitir que o cliente os verifique\">turbo",
|
||||
|
||||
"cut_datechk": "não tem efeito a menos que o botão turbo esteja ativado$N$Nreduz o fator yolo por uma pequena quantidade; verifica se os carimbos de data/hora dos arquivos no servidor correspondem aos seus$N$ndeve <em>teoricamente</em> pegar a maioria dos uploads incompletos / corrompidos, mas não é um substituto para fazer uma verificação com o turbo desativado depois\">date-chk",
|
||||
"cut_datechk": "não tem efeito a menos que o botão turbo esteja ativado$N$Nreduz o fator yolo por uma pequena quantidade; verifica se os carimbos de data/hora dos arquivos no servidor correspondem aos seus$N$Ndeve <em>teoricamente</em> pegar a maioria dos uploads incompletos / corrompidos, mas não é um substituto para fazer uma verificação com o turbo desativado depois\">date-chk",
|
||||
|
||||
"cut_u2sz": "tamanho (em MiB) de cada bloco de upload; valores grandes voam melhor pelo atlântico. Tente valores baixos em conexões muito não confiáveis",
|
||||
|
||||
"cut_flag": "garantir que apenas uma aba esteja fazendo upload por vez $N -- outras abas devem ter isso ativado também $N -- só afeta abas no mesmo domínio",
|
||||
|
||||
"cut_az": "enviar arquivos em ordem alfabética, em vez de o menor primeiro$N$na ordem alfabética pode tornar mais fácil de verificar se algo deu errado no servidor, mas torna o upload um pouco mais lento em fibra / LAN",
|
||||
"cut_az": "enviar arquivos em ordem alfabética, em vez de o menor primeiro$N$Na ordem alfabética pode tornar mais fácil de verificar se algo deu errado no servidor, mas torna o upload um pouco mais lento em fibra / LAN",
|
||||
|
||||
"cut_nag": "notificação do SO quando o upload for concluído$N(somente se o navegador ou aba não estiver ativo)",
|
||||
"cut_sfx": "alerta audível quando o upload for concluído$N(somente se o navegador ou aba não estiver ativo)",
|
||||
|
||||
"cut_mt": "usar multithreading para acelerar o hash de arquivos$N$nisto usa web-workers e requer$Nmais RAM (até 512 MiB extras)$N$ntorna https 30% mais rápido, http 4.5x mais rápido\">mt",
|
||||
"cut_mt": "usar multithreading para acelerar o hash de arquivos$N$Nisto usa web-workers e requer$Nmais RAM (até 512 MiB extras)$N$Ntorna https 30% mais rápido, http 4.5x mais rápido\">mt",
|
||||
|
||||
"cut_wasm": "usar wasm em vez do hasher embutido do navegador; melhora a velocidade em navegadores baseados em chrome mas aumenta a carga da CPU, e muitas versões antigas do chrome têm bugs que fazem o navegador consumir toda a RAM e travar se isso for ativado\">wasm",
|
||||
|
||||
|
|
@ -261,9 +262,10 @@ Ls.por = {
|
|||
"cft_bg": "cor do fundo",
|
||||
|
||||
"cdt_lim": "número máximo de arquivos para mostrar em uma pasta",
|
||||
"cdt_ask": "ao rolar para o final,$nem vez de carregar mais arquivos,$nperguntar o que fazer",
|
||||
"cdt_ask": "ao rolar para o final,$Nem vez de carregar mais arquivos,$Nperguntar o que fazer",
|
||||
"cdt_hsort": "quantas regras de ordenação (<code>,sorthref</code>) incluir em URLs de mídia. Definir isso para 0 também ignorará as regras de ordenação incluídas em links de mídia quando você clicar neles",
|
||||
"cdt_ren": "ativar menu de clique direito personalizado, o menu normal permanece acessível com shift + clique direito", //m
|
||||
"cdt_ren": "ativar menu de clique direito personalizado, o menu normal permanece acessível com shift + clique direito",
|
||||
"cdt_rdb": "mostrar o menu padrão do botão direito quando o menu personalizado já estiver aberto e houver um novo clique",
|
||||
|
||||
"tt_entree": "mostrar painel de navegação (árvore de diretórios)$NHotkey: B",
|
||||
"tt_detree": "mostrar breadcrumbs$NHotkey: B",
|
||||
|
|
@ -285,7 +287,7 @@ Ls.por = {
|
|||
"mt_loop": "loop/repetir uma música\">🔁",
|
||||
"mt_one": "parar depois de uma música\">1️⃣",
|
||||
"mt_shuf": "embaralhar as músicas em cada pasta\">🔀",
|
||||
"mt_aplay": "reproduzir automaticamente se houver um ID de música no link que você clicou para acessar o servidor$N$ndesativar isso também impedirá que a URL da página seja atualizada com IDs de música ao tocar música, para evitar a reprodução automática se essas configurações forem perdidas mas a URL permanecer\">a▶",
|
||||
"mt_aplay": "reproduzir automaticamente se houver um ID de música no link que você clicou para acessar o servidor$N$Ndesativar isso também impedirá que a URL da página seja atualizada com IDs de música ao tocar música, para evitar a reprodução automática se essas configurações forem perdidas mas a URL permanecer\">a▶",
|
||||
"mt_preload": "começar a carregar a próxima música perto do final para uma reprodução sem interrupções\">preload",
|
||||
"mt_prescan": "ir para a próxima pasta antes que a última música$Ntermine, mantendo o navegador feliz$Npara que ele não pare a reprodução\">nav",
|
||||
"mt_fullpre": "tentar pré-carregar a música inteira;$N✅ ativar em conexões <b>não confiáveis</b>,$N❌ <b>desativar</b> em conexões lentas provavelmente\">full",
|
||||
|
|
@ -294,7 +296,7 @@ Ls.por = {
|
|||
"mt_npclip": "mostrar botões para copiar a música que está tocando para a área de transferência\">/np",
|
||||
"mt_m3u_c": "mostrar botões para copiar as$Nmúsicas selecionadas como entradas de playlist m3u8 para a área de transferência\">📻",
|
||||
"mt_octl": "integração com o SO (atalhos de mídia / osd)\">os-ctl",
|
||||
"mt_oseek": "permitir busca através da integração com o SO$N$nnota: em alguns dispositivos (iPhones),$nisto substitui o botão de próxima música\">seek",
|
||||
"mt_oseek": "permitir busca através da integração com o SO$N$Nnota: em alguns dispositivos (iPhones),$Nisto substitui o botão de próxima música\">seek",
|
||||
"mt_oscv": "mostrar capa do álbum no osd\">art",
|
||||
"mt_follow": "manter a faixa que está tocando rolando à vista\">🎯",
|
||||
"mt_compact": "controles compactos\">⟎",
|
||||
|
|
@ -316,8 +318,8 @@ Ls.por = {
|
|||
"mt_c2ng": "seu dispositivo não parece suportar este formato de saída, mas vamos tentar mesmo assim",
|
||||
"mt_xowa": "existem bugs no iOS que impedem a reprodução em segundo plano usando este formato; por favor, use caf ou mp3 em vez disso",
|
||||
"mt_tint": "nível de fundo (0-100) na barra de busca$Npara tornar o buffer menos distrativo",
|
||||
"mt_eq": "ativa o equalizador e o controle de ganho;$N$nimpulsão <code>0</code> = volume padrão de 100% (não modificado)$N$nlargura <code>1 </code> = estéreo padrão (não modificado)$nlargura <code>0.5</code> = 50% de crossfeed esquerda-direita$nlargura <code>0 </code> = mono$N$nimpulsão <code>-0.8</code> & largura <code>10</code> = remoção de vocal :^)$N$natvar o equalizador torna os álbuns sem interrupções totalmente sem interrupções, então deixe-o ligado com todos os valores em zero (exceto largura = 1) se você se importa com isso",
|
||||
"mt_drc": "ativa o compressor de faixa dinâmica (nivelador de volume / brickwaller); também ativará o EQ para equilibrar o spaghetti, então defina todos os campos EQ exceto 'width' para 0 se você não quiser$N$nabaixa o volume do áudio acima do THRESHOLD dB; para cada RATIO dB após o THRESHOLD há 1 dB de saída, então os valores padrão de tresh -24 e ratio 12 significam que nunca deve ficar mais alto que -22 dB e é seguro aumentar o impulso do equalizador para 0.8, ou até 1.8 com ATK 0 e um enorme RLS como 90 (só funciona no firefox; RLS é no máximo 1 em outros navegadores)$N$n(veja a wikipedia, eles explicam muito melhor)",
|
||||
"mt_eq": "ativa o equalizador e o controle de ganho;$N$Nimpulsão <code>0</code> = volume padrão de 100% (não modificado)$N$Nlargura <code>1 </code> = estéreo padrão (não modificado)$Nlargura <code>0.5</code> = 50% de crossfeed esquerda-direita$Nlargura <code>0 </code> = mono$N$Nimpulsão <code>-0.8</code> & largura <code>10</code> = remoção de vocal :^)$N$Natvar o equalizador torna os álbuns sem interrupções totalmente sem interrupções, então deixe-o ligado com todos os valores em zero (exceto largura = 1) se você se importa com isso",
|
||||
"mt_drc": "ativa o compressor de faixa dinâmica (nivelador de volume / brickwaller); também ativará o EQ para equilibrar o spaghetti, então defina todos os campos EQ exceto 'width' para 0 se você não quiser$N$Nabaixa o volume do áudio acima do THRESHOLD dB; para cada RATIO dB após o THRESHOLD há 1 dB de saída, então os valores padrão de tresh -24 e ratio 12 significam que nunca deve ficar mais alto que -22 dB e é seguro aumentar o impulso do equalizador para 0.8, ou até 1.8 com ATK 0 e um enorme RLS como 90 (só funciona no firefox; RLS é no máximo 1 em outros navegadores)$N$N(veja a wikipedia, eles explicam muito melhor)",
|
||||
|
||||
"mb_play": "reproduzir",
|
||||
"mm_hashplay": "reproduzir este arquivo de áudio?",
|
||||
|
|
@ -334,7 +336,7 @@ Ls.por = {
|
|||
"mm_eunk": "Erro Desconhecido",
|
||||
"mm_e404": "Não foi possível reproduzir áudio; erro 404: Arquivo não encontrado.",
|
||||
"mm_e403": "Não foi possível reproduzir áudio; erro 403: Acesso negado.\n\nTente pressionar F5 para recarregar, talvez você tenha saído da conta",
|
||||
"mm_e415": "Não foi possível reproduzir áudio; erro 415: Falha na conversão do ficheiro; verifique os logs do servidor.", //m
|
||||
"mm_e415": "Não foi possível reproduzir áudio; erro 415: Falha na conversão do arquivo; verifique os logs do servidor.",
|
||||
"mm_e500": "Não foi possível reproduzir áudio; erro 500: Verifique os logs do servidor.",
|
||||
"mm_e5xx": "Não foi possível reproduzir áudio; erro do servidor ",
|
||||
"mm_nof": "não encontrando mais arquivos de áudio por perto",
|
||||
|
|
@ -354,6 +356,7 @@ Ls.por = {
|
|||
"f_anota": "apenas {0} dos {1} itens foram selecionados;\npara selecionar a pasta inteira, primeiro role para o final",
|
||||
|
||||
"f_dls": 'os links de arquivo na pasta atual foram\nalterados para links de download',
|
||||
"f_dl_nd": 'pulando pasta (use o download zip/tar em vez disso):\n',
|
||||
|
||||
"f_partial": "Para baixar com segurança um arquivo que está sendo enviado, por favor, clique no arquivo que tem o mesmo nome, mas sem a extensão <code>.PARTIAL</code>. Por favor, pressione CANCELAR ou Escape para fazer isso.\n\nPressionar OK / Enter irá ignorar este aviso e continuar baixando o arquivo temporário <code>.PARTIAL</code>, o que quase certamente lhe dará dados corrompidos.",
|
||||
|
||||
|
|
@ -422,10 +425,10 @@ Ls.por = {
|
|||
"fcc_warn": 'copiado {0} itens para a área de transferência\n\nmas: apenas <b>esta</b> aba do navegador pode colá-los\n(já que a seleção é tão absolutamente massiva)',
|
||||
|
||||
"fp_apply": "usar estes nomes",
|
||||
"fp_skip": "pular conflitos", //m
|
||||
"fp_skip": "pular conflitos",
|
||||
"fp_ecut": "primeiro recorte ou copie alguns arquivos / pastas para colar / mover\n\nnota: você pode recortar / colar entre abas diferentes do navegador",
|
||||
"fp_ename": "{0} itens não podem ser movidos para cá porque os nomes já estão em uso. Dê a eles novos nomes abaixo para continuar, ou deixe o nome em branco (\"pular conflitos\") para pular:", //m
|
||||
"fcp_ename": "{0} itens não podem ser copiados para cá porque os nomes já estão em uso. Dê a eles novos nomes abaixo para continuar, ou deixe o nome em branco (\"pular conflitos\") para pular:", //m
|
||||
"fp_ename": "{0} itens não podem ser movidos para cá porque os nomes já estão em uso. Dê a eles novos nomes abaixo para continuar, ou deixe o nome em branco (\"pular conflitos\") para pular:",
|
||||
"fcp_ename": "{0} itens não podem ser copiados para cá porque os nomes já estão em uso. Dê a eles novos nomes abaixo para continuar, ou deixe o nome em branco (\"pular conflitos\") para pular:",
|
||||
"fp_emore": "ainda há algumas colisões de nome de arquivo para consertar",
|
||||
"fp_ok": "movimento OK",
|
||||
"fcp_ok": "cópia OK",
|
||||
|
|
@ -444,8 +447,8 @@ Ls.por = {
|
|||
"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",
|
||||
"nmd_i1": "também pode adicionar a extensão desejada, por exemplo <code>.md</code>", //m
|
||||
"nmd_i2": "só pode criar ficheiros <code>.md</code> porque não tem permissão para apagar", //m
|
||||
"nmd_i1": "também adicione a extensão desejada, por exemplo <code>.md</code>",
|
||||
"nmd_i2": "só pode criar arquivos <code>.md</code> porque não tem permissão para apagar",
|
||||
|
||||
"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 ",
|
||||
|
|
@ -456,7 +459,7 @@ Ls.por = {
|
|||
"tvt_prev": "mostrar documento anterior$NHotkey: i\">⬆ anterior",
|
||||
"tvt_next": "mostrar próximo documento$NHotkey: K\">⬇ próximo",
|
||||
"tvt_sel": "selecionar arquivo ( para recortar / copiar / excluir / ... )$NHotkey: S\">sel",
|
||||
"tvt_j": "embelezar json$NHotkey: shift-J\">j", //m
|
||||
"tvt_j": "embelezar json$NHotkey: shift-J\">j",
|
||||
"tvt_edit": "abrir arquivo no editor de texto$NHotkey: E\">✏️ editar",
|
||||
"tvt_tail": "monitorar arquivo para alterações; mostrar novas linhas em tempo real\">📡 seguir",
|
||||
"tvt_wrap": "quebra de linha\">↵",
|
||||
|
|
@ -469,7 +472,7 @@ Ls.por = {
|
|||
"m3u_clip": "playlist m3u agora copiada para a área de transferência\n\nvocê deve criar um novo arquivo de texto chamado something.m3u e colar a playlist nesse documento; isso a tornará reproduzível",
|
||||
|
||||
"gt_vau": "não mostrar vídeos, apenas tocar o áudio\">🎧",
|
||||
"gt_msel": "ativar seleção de arquivo; ctrl-clique em um arquivo para substituir$N$n<em>quando ativo: clique duas vezes em um arquivo / pasta para abri-lo&>t;/em>$N$nHotkey: S\">multisseleção",
|
||||
"gt_msel": "ativar seleção de arquivo; ctrl-clique em um arquivo para substituir$N$N<em>quando ativo: clique duas vezes em um arquivo / pasta para abri-lo&>t;/em>$N$NHotkey: S\">multisseleção",
|
||||
"gt_crop": "cortar miniaturas ao centro\">cortar",
|
||||
"gt_3x": "miniaturas de alta resolução\">3x",
|
||||
"gt_zoom": "zoom",
|
||||
|
|
@ -527,11 +530,11 @@ Ls.por = {
|
|||
|
||||
"fz_tar": "arquivo gnu-tar não comprimido (linux / mac)",
|
||||
"fz_pax": "tar de formato pax não comprimido (mais lento)",
|
||||
"fz_targz": "gnu-tar com compressão gzip nível 3$N$nisto é geralmente muito lento, então$nuse tar não comprimido em vez disso",
|
||||
"fz_tarxz": "gnu-tar com compressão xz nível 1$N$nisto é geralmente muito lento, então$nuse tar não comprimido em vez disso",
|
||||
"fz_targz": "gnu-tar com compressão gzip nível 3$N$Nisto é geralmente muito lento, então$Nuse tar não comprimido em vez disso",
|
||||
"fz_tarxz": "gnu-tar com compressão xz nível 1$N$Nisto é geralmente muito lento, então$Nuse tar não comprimido em vez disso",
|
||||
"fz_zip8": "zip com nomes de arquivos utf8 (pode ser instável no windows 7 e mais antigos)",
|
||||
"fz_zipd": "zip com nomes de arquivos cp437 tradicionais, para software realmente antigo",
|
||||
"fz_zipc": "cp437 com crc32 calculado antecipadamente,$npara MS-DOS PKZIP v2.04g (outubro de 1993)$n(leva mais tempo para processar antes que o download possa começar)",
|
||||
"fz_zipc": "cp437 com crc32 calculado antecipadamente,$Npara MS-DOS PKZIP v2.04g (outubro de 1993)$N(leva mais tempo para processar antes que o download possa começar)",
|
||||
|
||||
"un_m1": "você pode excluir seus uploads recentes (ou abortar os que não foram concluídos) abaixo",
|
||||
"un_upd": "atualizar",
|
||||
|
|
@ -641,22 +644,25 @@ Ls.por = {
|
|||
"ur_um": "Concluído;\n{0} uploads OK,\n{1} uploads falharam, desculpe",
|
||||
"ur_sm": "Concluído;\n{0} arquivos encontrados no servidor,\n{1} arquivos NÃO encontrados no servidor",
|
||||
|
||||
"rc_opn": "abrir", //m
|
||||
"rc_ply": "reproduzir", //m
|
||||
"rc_pla": "reproduzir como áudio", //m
|
||||
"rc_txt": "abrir no visualizador de arquivos", //m
|
||||
"rc_md": "abrir no editor de texto", //m
|
||||
"rc_dl": "baixar", //m
|
||||
"rc_zip": "baixar como arquivo", //m
|
||||
"rc_cpl": "copiar link", //m
|
||||
"rc_del": "excluir", //m
|
||||
"rc_cut": "recortar", //m
|
||||
"rc_cpy": "copiar", //m
|
||||
"rc_pst": "colar", //m
|
||||
"rc_nfo": "nova pasta", //m
|
||||
"rc_nfi": "novo arquivo", //m
|
||||
"rc_sal": "selecionar tudo", //m
|
||||
"rc_sin": "inverter seleção", //m
|
||||
"rc_opn": "abrir",
|
||||
"rc_ply": "reproduzir",
|
||||
"rc_pla": "reproduzir como áudio",
|
||||
"rc_txt": "abrir no leitor de texto",
|
||||
"rc_md": "abrir no leitor markdown",
|
||||
"rc_dl": "baixar",
|
||||
"rc_zip": "baixar compactado",
|
||||
"rc_cpl": "copiar link",
|
||||
"rc_del": "excluir",
|
||||
"rc_cut": "recortar",
|
||||
"rc_cpy": "copiar",
|
||||
"rc_pst": "colar",
|
||||
"rc_rnm": "renomear",
|
||||
"rc_nfo": "nova pasta",
|
||||
"rc_nfi": "novo arquivo",
|
||||
"rc_sal": "selecionar tudo",
|
||||
"rc_sin": "inverter seleção",
|
||||
"rc_shf": "compartilhar esta pasta",
|
||||
"rc_shs": "compartilhar seleção",
|
||||
|
||||
"lang_set": "atualizar para a mudança ter efeito?",
|
||||
|
||||
|
|
@ -699,8 +705,8 @@ Ls.por = {
|
|||
"ta1": "primeiro digite sua nova senha",
|
||||
"ta2": "repita para confirmar a nova senha:",
|
||||
"ta3": "há um erro; por favor, tente novamente",
|
||||
"nop": "ERRO: A senha não pode estar em branco", //m
|
||||
"nou": "ERRO: O nome de usuário e/ou a senha não podem estar em branco", //m
|
||||
"nop": "ERRO: A senha não pode estar em branco",
|
||||
"nou": "ERRO: O nome de usuário e/ou a senha não podem estar em branco",
|
||||
"aa1": "arquivos de entrada:",
|
||||
"ab1": "desativar no304",
|
||||
"ac1": "ativar no304",
|
||||
|
|
|
|||
|
|
@ -226,6 +226,7 @@ Ls.rus = {
|
|||
"ct_ttips": '◔ ◡ ◔">ℹ️ подсказки',
|
||||
"ct_thumb": 'переключение между иконками и миниатюрами в режиме сетки$NГорячая клавиша: T">🖼️ миниат.',
|
||||
"ct_csel": 'держите CTRL или SHIFT для выделения файлов в режиме сетки">выбор',
|
||||
"ct_dsel": 'использовать выделение перетаскиванием в режиме сетки">перетащить', //m
|
||||
"ct_dl": 'принудительная загрузка (не показывать встроенно) при щелчке по файлу">dl', //m
|
||||
"ct_ihop": 'показывать последний открытый файл после закрытия просмотрщика изображений">g⮯',
|
||||
"ct_dots": 'показывать скрытые файлы (если есть доступ)">скрыт.',
|
||||
|
|
@ -264,6 +265,7 @@ Ls.rus = {
|
|||
"cdt_ask": "внизу страницы спрашивать о действии вместо автоматической загрузки следующих файлов",
|
||||
"cdt_hsort": "сколько правил сортировки (<code>,sorthref</code>) включать в адрес страницы. Если значение равно 0, по нажатии на ссылки будут игнорироваться правила, включённые в них",
|
||||
"cdt_ren": "включить настраиваемое контекстное меню, обычное меню доступно при нажатии shift и правой кнопки мыши", //m
|
||||
"cdt_rdb": "показывать обычное меню правого клика, если пользовательское уже открыто и выполняется повторный клик", //m
|
||||
|
||||
"tt_entree": "показать панель навигации$NГорячая клавиша: B",
|
||||
"tt_detree": "скрыть панель навигации$NГорячая клавиша: B",
|
||||
|
|
@ -354,6 +356,7 @@ Ls.rus = {
|
|||
"f_anota": "только {0} из {1} файлов было выделено;\nчтобы выделить всё папку, отмотайте до низа",
|
||||
|
||||
"f_dls": 'ссылки на файлы в данной папке были\nзаменены ссылками на скачивание',
|
||||
"f_dl_nd": 'пропуск папки (используйте загрузку zip/tar вместо этого):\n', //m
|
||||
|
||||
"f_partial": "Чтобы безопасно скачать файл, который в текущий момент загружается, нажмите на файл с таким же названием, но без расширения <code>.PARTIAL</code>. Пожалуйста, нажмите Отмена или ESC, чтобы сделать это.\n\nПри нажатии OK / Enter, вы скачаете этот временный файл, который с огромной вероятностью содержит лишь неполные данные.",
|
||||
|
||||
|
|
@ -653,10 +656,13 @@ Ls.rus = {
|
|||
"rc_cut": "вырезать", //m
|
||||
"rc_cpy": "копировать", //m
|
||||
"rc_pst": "вставить", //m
|
||||
"rc_rnm": "переименовать", //m
|
||||
"rc_nfo": "новая папка", //m
|
||||
"rc_nfi": "новый файл", //m
|
||||
"rc_sal": "выбрать всё", //m
|
||||
"rc_sin": "инвертировать выделение", //m
|
||||
"rc_shf": "поделиться этой папкой", //m
|
||||
"rc_shs": "поделиться выделенным", //m
|
||||
|
||||
"lang_set": "перезагрузить страницу, чтобы применить изменения?",
|
||||
|
||||
|
|
|
|||
|
|
@ -225,6 +225,7 @@ Ls.spa = {
|
|||
"ct_ttips": '◔ ◡ ◔">ℹ️ tooltips',
|
||||
"ct_thumb": 'en vista de cuadrícula, alternar iconos o miniaturas$NAtajo: T">🖼️ miniaturas',
|
||||
"ct_csel": 'usa CTRL y SHIFT para seleccionar archivos en la vista de cuadrícula">sel',
|
||||
"ct_dsel": 'usa la selección por arrastre en la vista de cuadrícula">arrastrar', //m
|
||||
"ct_dl": 'forzar descarga (no mostrar en línea) al hacer clic en un archivo">dl', //m
|
||||
"ct_ihop": 'al cerrar el visor de imágenes, desplazarse hasta el último archivo visto">g⮯',
|
||||
"ct_dots": 'mostrar archivos ocultos (si el servidor lo permite)">archivos ocultos',
|
||||
|
|
@ -263,6 +264,7 @@ Ls.spa = {
|
|||
"cdt_ask": "al llegar al final,$Nen lugar de cargar más archivos,$Npreguntar qué hacer",
|
||||
"cdt_hsort": "cuántas reglas de ordenación (<code>,sorthref</code>) incluir en las URLs de medios. Ponerlo a 0 también ignorará las reglas de ordenación incluidas en los enlaces de medios al hacer clic en ellos",
|
||||
"cdt_ren": "habilitar menú contextual personalizado, el menú normal sigue siendo accesible con shift + clic derecho", //m
|
||||
"cdt_rdb": "mostrar el menú normal de clic derecho cuando el personalizado ya está abierto y se vuelve a hacer clic", //m
|
||||
|
||||
"tt_entree": "mostrar panel de navegación (barra lateral con árbol de directorios)$NAtajo: B",
|
||||
"tt_detree": "mostrar breadcrumbs$NAtajo: B",
|
||||
|
|
@ -353,6 +355,7 @@ Ls.spa = {
|
|||
"f_anota": "solo {0} de los {1} elementos fueron seleccionados;\npara seleccionar la carpeta completa, primero desplázate hasta el final",
|
||||
|
||||
"f_dls": "los enlaces a archivos en la carpeta actual se han\nconvertido en enlaces de descarga",
|
||||
"f_dl_nd": 'omitiendo carpeta (use la descarga zip/tar en su lugar):\n', //m
|
||||
|
||||
"f_partial": "Para descargar de forma segura un archivo que se está subiendo actualmente, por favor haz clic en el archivo con el mismo nombre, pero sin la extensión <code>.PARTIAL</code>. Por favor, pulsa CANCELAR o Escape para hacer esto.\n\nPulsar ACEPTAR o Intro ignorará esta advertencia y continuará descargando el archivo temporal <code>.PARTIAL</code>, lo que casi con toda seguridad te dará datos corruptos.",
|
||||
|
||||
|
|
@ -652,10 +655,13 @@ Ls.spa = {
|
|||
"rc_cut": "cortar", //m
|
||||
"rc_cpy": "copiar", //m
|
||||
"rc_pst": "pegar", //m
|
||||
"rc_rnm": "renombrar", //m
|
||||
"rc_nfo": "nueva carpeta", //m
|
||||
"rc_nfi": "nuevo archivo", //m
|
||||
"rc_sal": "seleccionar todo", //m
|
||||
"rc_sin": "invertir selección", //m
|
||||
"rc_shf": "compartir esta carpeta", //m
|
||||
"rc_shs": "compartir selección", //m
|
||||
|
||||
"lang_set": "¿refrescar para que el cambio surta efecto?",
|
||||
|
||||
|
|
|
|||
|
|
@ -226,6 +226,7 @@ Ls.swe = {
|
|||
"ct_ttips": '◔ ◡ ◔">ℹ️ tips',
|
||||
"ct_thumb": 'växla mellan miniatyrer och ikoner i rutnätsvyn$NSnabbtangent: T">🖼️ miniatyrer',
|
||||
"ct_csel": 'använd CTRL och SKIFT för urval av filer i rutnätsvyn">val',
|
||||
"ct_dsel": 'använd dra-urval i rutnätsvyn">dra', //m
|
||||
"ct_dl": 'tvinga nedladdning (visa inte inline) när en fil klickas">dl', //m
|
||||
"ct_ihop": 'skrolla till den senast visade filen när bildvisaren stängs">g⮯',
|
||||
"ct_dots": 'visa dolda filer (om servern tillåter detta)">dolda',
|
||||
|
|
@ -264,6 +265,7 @@ Ls.swe = {
|
|||
"cdt_ask": "när du når botten av vyn,$Nbe om en åtgärd istället för att ladda fler filer",
|
||||
"cdt_hsort": "hur många sorteringsregler (<code>,sorthref</code>) att inkludera i media-URL:er. Sätts detta till 0 kommer regler i klickade medialänkar även att ignoreras",
|
||||
"cdt_ren": "aktivera anpassad högerklicksmeny, den vanliga menyn är tillgänglig med shift + högerklick", //m
|
||||
"cdt_rdb": "visa den vanliga högerklicksmenyn när den anpassade redan är öppen och man högerklickar igen", //m
|
||||
|
||||
"tt_entree": "visa trädvy$NSnabbtangent: B",
|
||||
"tt_detree": "visa brödsmulor$NSnabbtangent: B",
|
||||
|
|
@ -354,6 +356,7 @@ Ls.swe = {
|
|||
"f_anota": "endast {0} av {1} objekt valdes;\nför att välja hela mappen, skrolla först till botten av vyn",
|
||||
|
||||
"f_dls": 'fillänkarna i den öppna mappen har\nbytts till nedladdningslänkar',
|
||||
"f_dl_nd": 'hoppar över mapp (använd zip/tar-nedladdning istället):\n', //m
|
||||
|
||||
"f_partial": "För att säkert ladda ner en fil som för tillfället laddas upp, vänligen klicka på filen som har samma filnamn men utan <code>.PARTIAL</code>-filändelsen. Vänligen tryck Avbryt eller Escape för att göra detta.\n\nOm du bortser från denna varning och trycker OK eller Enter kommer den tillfälliga <code>.PARTIAL</code>-filen istället att laddas ner, vilket är nästan garanterat att ge dig korrumperad data.",
|
||||
|
||||
|
|
@ -653,10 +656,13 @@ Ls.swe = {
|
|||
"rc_cut": "klipp ut", //m
|
||||
"rc_cpy": "kopiera", //m
|
||||
"rc_pst": "klistra in", //m
|
||||
"rc_rnm": "byt namn", //m
|
||||
"rc_nfo": "ny mapp", //m
|
||||
"rc_nfi": "ny fil", //m
|
||||
"rc_sal": "markera alla", //m
|
||||
"rc_sin": "invertera markering", //m
|
||||
"rc_shf": "dela denna mapp", //m
|
||||
"rc_shs": "dela urval", //m
|
||||
|
||||
"lang_set": "uppdatera för att ändringen ska ta effekt?",
|
||||
|
||||
|
|
|
|||
|
|
@ -226,6 +226,7 @@ Ls.tur = {
|
|||
"ct_ttips": '◔ ◡ ◔">ℹ️ ipuçları',
|
||||
"ct_thumb": 'ızgara görünümünde, simgeler ve küçük resimler arasında geçiş yapın$NKısayol: T">🖼️ küçük resimler',
|
||||
"ct_csel": 'ızgara görünümünde dosya seçimi için CTRL ve SHIFT tuşlarını kullanın">seç',
|
||||
"ct_dsel": 'ızgara görünümünde sürükleyerek seçimi kullanın">sürükle', //m
|
||||
"ct_dl": 'dosyaya tıklandığında indirmeyi zorla (satır içinde görüntüleme)">dl', //m
|
||||
"ct_ihop": 'resim görüntüleyici kapatıldığında, en son görüntülenen dosyaya kaydırın">g⮯',
|
||||
"ct_dots": 'gizli dosyaları göster (sunucu izin veriyorsa)">nokta dosyaları',
|
||||
|
|
@ -264,6 +265,7 @@ Ls.tur = {
|
|||
"cdt_ask": "aşağı kaydırırken,$Ndaha fazla dosya yüklemek yerine,$Nne yapılacağını sor",
|
||||
"cdt_hsort": "medya-URL'lerinde dahil edilecek sıralama kurallarının sayısı (<code>,sorthref</code>). Bunu 0 olarak ayarlamak, tıklanırken medya bağlantılarına dahil edilen sıralama kurallarını da yok sayacaktır",
|
||||
"cdt_ren": "özel sağ tık menüsünü etkinleştir, normal menü shift + sağ tık ile erişilebilir", //m
|
||||
"cdt_rdb": "özel menü zaten açıkken tekrar sağ tıklanınca normal sağ tık menüsünü göster", //m
|
||||
|
||||
"tt_entree": "navigasyon panosunu göster (yan dizin panosu)$NHotkey: B",
|
||||
"tt_detree": "içerik haritasını göster$Kısayol: B",
|
||||
|
|
@ -354,6 +356,7 @@ Ls.tur = {
|
|||
"f_anota": "{1} dosyadan sadece {0} tanesi seçildi;\nTüm klasörü seçmek için önce en alta kaydırın.",
|
||||
|
||||
"f_dls": 'bu klasördeki dosya linkleri\nindirme linklerine dönüştürüldü',
|
||||
"f_dl_nd": 'klasör atlanıyor (bunun yerine zip/tar indirmesini kullanın):\n', //m
|
||||
|
||||
"f_partial": "Mevcutta yüklenen bir dosyayı güvenli bir şekilde indirmek için lütfen aynı adlı ama <code>.PARTIAL</code> uzantısına sahip olmayan dosyaya tıklayın. Lütfen bunu yapmak için İPTAL veya Esc tuşuna basın.\n\nTamam / Enter tuşuna basmak, bu uyarıyı yok sayacak ve bunun yerine <code>.PARTIAL</code> geçici dosyasını indirmeye devam edecektir ki bu da elinize bozuk veriler sunacaktır.",
|
||||
|
||||
|
|
@ -653,10 +656,13 @@ Ls.tur = {
|
|||
"rc_cut": "kes", //m
|
||||
"rc_cpy": "kopyala", //m
|
||||
"rc_pst": "yapıştır", //m
|
||||
"rc_rnm": "yeniden adlandır", //m
|
||||
"rc_nfo": "yeni klasör", //m
|
||||
"rc_nfi": "yeni dosya", //m
|
||||
"rc_sal": "tümünü seç", //m
|
||||
"rc_sin": "seçimi tersine çevir", //m
|
||||
"rc_shf": "bu klasörü paylaş", //m
|
||||
"rc_shs": "seçimi paylaş", //m
|
||||
|
||||
"lang_set": "Değişikliklerin etki göstermesi için sayfa yenilensin mi?",
|
||||
|
||||
|
|
|
|||
|
|
@ -226,6 +226,7 @@ Ls.ukr = {
|
|||
"ct_ttips": '◔ ◡ ◔">ℹ️ підказки',
|
||||
"ct_thumb": 'у режимі сітки, перемкнути іконки або мініатюри$NГаряча клавіша: T">🖼️ мініатюри',
|
||||
"ct_csel": 'використовувати CTRL і SHIFT для вибору файлів у режимі сітки">вибір',
|
||||
"ct_dsel": 'використовувати вибір перетягуванням у режимі сітки">перетягнути', //m
|
||||
"ct_dl": 'примусове завантаження (не показувати вбудовано) під час натискання на файл">dl', //m
|
||||
"ct_ihop": 'коли переглядач зображень закрито, прокрутити вниз до останнього переглянутого файлу">g⮯',
|
||||
"ct_dots": 'показати приховані файли (якщо сервер дозволяє)">приховані файли',
|
||||
|
|
@ -264,6 +265,7 @@ Ls.ukr = {
|
|||
"cdt_ask": "при прокрутці до низу,$Nзамість завантаження більше файлів,$Nзапитати, що робити",
|
||||
"cdt_hsort": "скільки правил сортування (<code>,sorthref</code>) включати в медіа-URL. Встановлення цього в 0 також буде ігнорувати правила сортування, включені в медіа посилання при їх натисканні",
|
||||
"cdt_ren": "увімкнути користувацьке контекстне меню, звичайне меню доступне при натисканні shift і правої кнопки миші", //m
|
||||
"cdt_rdb": "показувати звичайне меню правої кнопки, якщо власне меню вже відкрите і відбувається повторне клацання", //m
|
||||
|
||||
"tt_entree": "показати панель навігації (бічна панель дерева каталогів)$NГаряча клавіша: B",
|
||||
"tt_detree": "показати хлібні крихти$NГаряча клавіша: B",
|
||||
|
|
@ -354,6 +356,7 @@ Ls.ukr = {
|
|||
"f_anota": "лише {0} з {1} елементів було вибрано;\nщоб вибрати всю папку, спочатку прокрутіть до низу",
|
||||
|
||||
"f_dls": 'посилання на файли в поточній папці були\nзмінені на посилання для завантаження',
|
||||
"f_dl_nd": 'пропуск папки (скористайтеся завантаженням zip/tar замість цього):\n', //m
|
||||
|
||||
"f_partial": "Щоб безпечно завантажити файл, який зараз завантажується, будь ласка, клацніть на файл, який має таке саме ім'я, але без розширення <code>.PARTIAL</code>. Будь ласка, натисніть Скасувати або Escape, щоб зробити це.\n\nНатиснення Гаразд / Enter проігнорує це попередження і продовжить завантаження <code>.PARTIAL</code> робочого файлу замість цього, що майже напевно дасть вам пошкоджені дані.",
|
||||
|
||||
|
|
@ -653,10 +656,13 @@ Ls.ukr = {
|
|||
"rc_cut": "вирізати", //m
|
||||
"rc_cpy": "копіювати", //m
|
||||
"rc_pst": "вставити", //m
|
||||
"rc_rnm": "перейменувати", //m
|
||||
"rc_nfo": "нова папка", //m
|
||||
"rc_nfi": "новий файл", //m
|
||||
"rc_sal": "вибрати все", //m
|
||||
"rc_sin": "інвертувати вибір", //m
|
||||
"rc_shf": "поділитися цією папкою", //m
|
||||
"rc_shs": "поділитися вибраним", //m
|
||||
|
||||
"lang_set": "оновити сторінку, щоб зміни набули чинності?",
|
||||
|
||||
|
|
|
|||
|
|
@ -227,6 +227,7 @@ Ls.vie = {
|
|||
"ct_ttips": '༼ ◕_◕ ༽">ℹ️ tooltips',
|
||||
"ct_thumb": 'ở chế độ lưới, chuyển biểu tượng hoặc hình thu nhỏ$NPhím tắt: T">🖼️ ảnh thu nhỏ',
|
||||
"ct_csel": 'dùng CTRL và SHIFT để chọn tệp trong chế độ lưới">sel',
|
||||
"ct_dsel": 'dùng chọn bằng cách kéo trong chế độ lưới">kéo', //m
|
||||
"ct_dl": 'cưỡng chế tải xuống (không hiện thị trong dòng) khi nhấp vào tệp">dl',
|
||||
"ct_ihop": 'khi đóng trình xem ảnh, cuộn xuống tệp đã xem gần nhất">g⮯',
|
||||
"ct_dots": 'hiển thị tệp ẩn (nếu máy chủ cho phép)">dotfiles',
|
||||
|
|
@ -268,6 +269,7 @@ Ls.vie = {
|
|||
"cdt_ask": "khi cuộn xuống cuối,$Nthay vì tải thêm tệp,$Nhỏi người dùng muốn làm gì",
|
||||
"cdt_hsort": "số lượng luật sắp xếp(<code>,sorthref</code>) được đưa vào URL media. Đặt bằng 0 cũng sẽ bỏ qua các quy tắc sắp xếp trong liên kết media khi nhấp vào chúng",
|
||||
"cdt_ren": "bật menu chuột phải tùy chỉnh, menu mặc định vẫn truy cập được bằng shift + chuột phải", //m
|
||||
"cdt_rdb": "hiển thị menu chuột phải thông thường khi menu tùy chỉnh đã mở và nhấp chuột phải lần nữa", //m
|
||||
|
||||
"tt_entree": "hiển thị thanh điều hướng (cây thư mục)$NPhím tắt: B",
|
||||
"tt_detree": "hiển thị đường dẫn$NPhím tắt: B",
|
||||
|
|
@ -363,6 +365,7 @@ Ls.vie = {
|
|||
"f_anota": "chỉ {0} trong {1} tệp được chọn;\nđể chọn toàn bộ thư mục, trước tiên hãy kéo xuống cuối",
|
||||
|
||||
"f_dls": 'những đường dẫn đến tệp trong thư mục này\nđã được chuyển thành đường dẫn tải trực tiếp',
|
||||
"f_dl_nd": 'bỏ qua thư mục (hãy dùng tải zip/tar thay thế):\n', //m
|
||||
|
||||
"f_partial": "Để tải an toàn một tệp đang được tải lên, hãy bấm vào tệp có cùng tên nhưng *không* có phần mở rộng <code>.PARTIAL</code>. Hãy nhấn CANCEL hoặc Escape để thực hiện.\n\nNếu nhấn OK / Enter, cảnh báo sẽ bị bỏ qua và bạn sẽ tải tệp tạm <code>.PARTIAL</code> thay vào đó, gần như chắc chắn dẫn đến dữ liệu bị hỏng.",
|
||||
|
||||
|
|
@ -686,10 +689,13 @@ Ls.vie = {
|
|||
"rc_cut": "cắt", //m
|
||||
"rc_cpy": "sao chép", //m
|
||||
"rc_pst": "dán", //m
|
||||
"rc_rnm": "đổi tên", //m
|
||||
"rc_nfo": "thư mục mới", //m
|
||||
"rc_nfi": "tệp mới", //m
|
||||
"rc_sal": "chọn tất cả", //m
|
||||
"rc_sin": "đảo ngược lựa chọn", //m
|
||||
"rc_shf": "chia sẻ thư mục này", //m
|
||||
"rc_shs": "chia sẻ lựa chọn", //m
|
||||
|
||||
"lang_set": "tải lại trang để áp dụng thay đổi ngôn ngữ",
|
||||
|
||||
|
|
|
|||
|
|
@ -1535,7 +1535,7 @@ function up2k_init(subtle) {
|
|||
|
||||
pvis.addfile([
|
||||
uc.fsearch ? esc(entry.name) : linksplit(
|
||||
entry.purl + uricom_enc(entry.name)).join(' / '),
|
||||
entry.purl + uricom_enc(entry.name), window.up_site).join(' / '),
|
||||
'📐 ' + L.u_hashing,
|
||||
''
|
||||
], entry.size, draw_each);
|
||||
|
|
@ -1575,8 +1575,8 @@ function up2k_init(subtle) {
|
|||
more_one_file();
|
||||
|
||||
function linklist() {
|
||||
var ret = [],
|
||||
base = location.origin.replace(/\/$/, '');
|
||||
var ret = [],
|
||||
base = (window.up_site || location.origin).replace(/\/$/, '');
|
||||
|
||||
for (var a = 0; a < st.files.length; a++) {
|
||||
var t = st.files[a],
|
||||
|
|
@ -2562,7 +2562,7 @@ function up2k_init(subtle) {
|
|||
cdiff = (Math.abs(diff) <= 2) ? '3c0' : 'f0b',
|
||||
sdiff = '<span style="color:#' + cdiff + '">diff ' + diff;
|
||||
|
||||
msg.push(linksplit(hit.rp).join(' / ') + '<br /><small>' + tr + ' (srv), ' + tu + ' (You), ' + sdiff + '</small></span>');
|
||||
msg.push(linksplit(hit.rp, window.up_site).join(' / ') + '<br /><small>' + tr + ' (srv), ' + tu + ' (You), ' + sdiff + '</small></span>');
|
||||
}
|
||||
msg = msg.join('<br />\n');
|
||||
}
|
||||
|
|
@ -2596,7 +2596,7 @@ function up2k_init(subtle) {
|
|||
url += '?k=' + fk;
|
||||
}
|
||||
|
||||
pvis.seth(t.n, 0, linksplit(url).join(' / '));
|
||||
pvis.seth(t.n, 0, linksplit(url, window.up_site).join(' / '));
|
||||
}
|
||||
|
||||
var chunksize = get_chunksize(t.size),
|
||||
|
|
|
|||
|
|
@ -766,9 +766,9 @@ function assert_vp(path) {
|
|||
}
|
||||
|
||||
|
||||
function linksplit(rp, id) {
|
||||
function linksplit(rp, base, id) {
|
||||
var ret = [],
|
||||
apath = '/',
|
||||
apath = base || '/',
|
||||
q = null;
|
||||
|
||||
if (rp && rp.indexOf('?') + 1) {
|
||||
|
|
@ -1326,9 +1326,10 @@ function scfg_bind(obj, oname, cname, defval, cb) {
|
|||
return v;
|
||||
}
|
||||
|
||||
function setck(v) {
|
||||
function setck(v, cb) {
|
||||
var xhr = new XHR();
|
||||
xhr.open('GET', SR + '/?setck=' + v, true);
|
||||
xhr.onload = cb;
|
||||
xhr.send();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,107 @@
|
|||
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
|
||||
# 2026-0121-0505 `v1.20.3` dillo approves
|
||||
|
||||
## 🧪 new features
|
||||
|
||||
* send-message-to-serverlog now also available as url-parameter `?smsg=foo` 6dcb1efb
|
||||
* option `smsg` configures which HTTP-methods to allow; can be set to `GET,POST` but default is only `POST` because `GET` is dangerous (CSRF)
|
||||
|
||||
## 🩹 bugfixes
|
||||
|
||||
* #1227 [dillo](https://dillo-browser.github.io/) was not able to login because dillo is more standards-compliant than every other browser (nice) b4df8fa2
|
||||
* a web-scraper which got banned for making malicious requests could remain banned for one request longer than intended (wait why did I fix this) ba67b279
|
||||
* `?ls` was still a bit jank 0a3a8072
|
||||
|
||||
## 🌠 fun facts
|
||||
|
||||
* this 6AM release was [powered by void/mournfinale](https://www.youtube.com/watch?v=lFEEXloqk9Q&list=PLlEk36g9RI8Ppjr3HhaO3wjjmA6HnSo2U)
|
||||
* was going to name the release "dilla på dillo" but somehow google-translate thinks that means "fuck on fuck" which would have been inappropriate
|
||||
|
||||
|
||||
|
||||
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
|
||||
# 2026-0119-0126 `v1.20.2` xattrs + range-select
|
||||
|
||||
## 🧪 new features
|
||||
|
||||
* #1212, #1214 range-select in the grid-view by click-and-drag (thx @icxes!) 3e3228e0 72c59405
|
||||
* #134 xattrs (linux extended file attributes) can now be indexed and searchable 8240ef61
|
||||
* rightclick-menu:
|
||||
* #1184 add rename option (thx @stackxp!) 25a8b96f
|
||||
* #1216 add sharing options (thx @stackxp!) ffb25603
|
||||
* #1198, #1206 also works in the search-results view (thx @hackysphere!) 04f612ff d32704ed
|
||||
* option to override the domain in certain links, so copyparty returns an external URL even if you're accessing it by a LAN address:
|
||||
* #1211 newly created shares 41d3bae9
|
||||
* #255 newly uploaded files d9255538
|
||||
* new option `vol-nospawn` (volflag `nospawn`) to *not* automatically create the volume's folder on the server's HDD if it doesn't exist
|
||||
* new option `vol-or-crash` (volflag `assert_root`) to intentionally crash on startup if a volume's folder doesn't already exist on the server HDD
|
||||
* new option `--flo` to tweak the log-format used by the `-lo` option for logging to a file 826e84c8
|
||||
* #1197 u2c ([commandline uploader](https://github.com/9001/copyparty/tree/hovudstraum/bin#u2cpy)): give up and crash if server is offline for longer than 3 minutes (configurable) 67c5d8da
|
||||
|
||||
## 🩹 bugfixes
|
||||
|
||||
* #1203 configured chmod/chown rules were not applied when a file was being deduped bef07720
|
||||
* the `unlistc*` volflags could not be specified for single-file volumes 26648911
|
||||
* the defensive renaming of uploaded readmes/logues would assume the default filenames, not considering the recently added option to customize these names c17c3be0
|
||||
* #1191 the `ipu` option can once again be used to reject connections from certain IP-ranges caf831fc
|
||||
* this was a regression in v1.19.21 causing the server to crash on startup if such a config was attempted
|
||||
* some empty folders could be created during startup in certain server-configs with nested volumes 4e67b467
|
||||
* api: trying to `?ls` nested virtual folders could return an error 66750391
|
||||
* ui/ux:
|
||||
* #1179 improve errormessage if audio transcoding fails 7357d46f
|
||||
* ensure a trailing slash when viewing a folder with the `h` permission; good for relative links in html-files
|
||||
|
||||
## 🔧 other changes
|
||||
|
||||
* #1193, #1194: NixOS improvements (thx @toast003!) 9d223d6c d5a8a34b
|
||||
* truncate huge errormessages from ffmpeg so the log doesn't get flooded 3aebfabd
|
||||
* ui/ux:
|
||||
* the `dl` button (to download selected files individually) now skips folders, since that never worked bc24604a
|
||||
* #1200 add html classes to make custom styling easier c46cd7f5
|
||||
* rephrase errormessages from `see serverlog` to `see fileserver log`
|
||||
* docs:
|
||||
* mention in the readme that uploading files from a deeply nested folder using a webbrowser on Windows can fail because browsers don't handle the max-pathlen limitation of Windows optimally (not a copyparty-specific issue, but still hits us)
|
||||
|
||||
## 🌠 fun facts
|
||||
|
||||
* n/a; no fun has been had since [v1.20.0](https://github.com/9001/copyparty/releases/tag/v1.20.0)
|
||||
* (that's a lie btw, [sniffing the airwaves](https://a.ocv.me/pub/g/2026/01/PXL_20260117_192619830.jpg?cache) *is* pretty darn fun 😁)
|
||||
|
||||
|
||||
|
||||
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
|
||||
# 2026-0109-0052 `v1.20.1` sftp fixes
|
||||
|
||||
## 🧪 new features
|
||||
|
||||
* #1174 add Japanese translation (thx @tkymmm!) b918b592
|
||||
* #1164 rightclick-menu now works in the gridview too (thx @Foox-dev!) feabbf3e
|
||||
* #1176 IP to bind can be specified per protocol 87a5c22a
|
||||
|
||||
## 🩹 bugfixes
|
||||
|
||||
* various SFTP fixes (i blame the single [tschunk](https://germanfoods.org/tschunk/) on day 3):
|
||||
* #1170 be more lenient regarding `stat` permissions 90308284
|
||||
* #1170 deletes could return EPERM when ENOENT was more appropriate 8c9e1016
|
||||
* #1170 files would be created with an extremely restrictive chmod 2f4a30b6
|
||||
* certified octal moment
|
||||
* write-only folders could return ENOENT 6c41bac6
|
||||
* #1177 disk-usage quotas became incompatible with shares in v1.20.0 038af507
|
||||
* appending to existing files with `?apnd` was possible in volumes with non-reflink dedup, where it could propagate to deduped copies of the file 738a419b
|
||||
* (was only possible for users with write+delete perms, so at least it couldn't be used for nefarious purposes)
|
||||
* rightclick-menu: "copy link" would strip filekeys 3a16d346
|
||||
|
||||
## 🔧 other changes
|
||||
|
||||
* copyparty.exe: updated pillow to 12.1.0 a9ae6d51
|
||||
|
||||
## 🌠 fun facts
|
||||
|
||||
* [tschunk](https://germanfoods.org/tschunk/) is the sound a hacker makes as they faceplant onto the table after having one too many
|
||||
* also see the funfacts in [the previous release](https://github.com/9001/copyparty/releases/tag/v1.20.0) for more CCC hijinks :p
|
||||
|
||||
|
||||
|
||||
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
|
||||
# 2026-0102-0007 `v1.20.0` sftp is fine too
|
||||
|
||||
|
|
|
|||
|
|
@ -289,6 +289,7 @@ upload modifiers:
|
|||
| GET | `?imgs=0` | ui: show list-view |
|
||||
| GET | `?thumb` | ui, grid-mode: show thumbnails |
|
||||
| GET | `?thumb=0` | ui, grid-mode: show icons |
|
||||
| POST | `?smsg=foo` | send-msg-to-serverlog / run xm hook |
|
||||
|
||||
|
||||
# event hooks
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ https://github.com/Daninet/hash-wasm/
|
|||
C: 2020 Dani Biró
|
||||
L: MIT
|
||||
|
||||
https://github.com/openpgpjs/asmcrypto.js/
|
||||
https://github.com/asmcrypto/asmcrypto.js/
|
||||
C: 2013 Artem S Vybornov
|
||||
L: MIT
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
FROM alpine:3.18
|
||||
FROM alpine:3.23
|
||||
WORKDIR /z
|
||||
ENV ver_asmcrypto=c72492f4a66e17a0e5dd8ad7874de354f3ccdaa5 \
|
||||
ver_hashwasm=4.12.0 \
|
||||
ENV ver_hashwasm=4.12.0 \
|
||||
ver_marked=4.3.0 \
|
||||
ver_dompf=3.3.1 \
|
||||
ver_mde=2.18.0 \
|
||||
ver_codemirror=5.65.18 \
|
||||
ver_fontawesome=5.13.0 \
|
||||
ver_prism=1.29.0 \
|
||||
ver_prism=1.30.0 \
|
||||
ver_zopfli=1.0.3
|
||||
|
||||
# versioncheck:
|
||||
|
|
@ -16,7 +15,6 @@ ENV ver_asmcrypto=c72492f4a66e17a0e5dd8ad7874de354f3ccdaa5 \
|
|||
# https://github.com/codemirror/codemirror5/releases
|
||||
# https://github.com/cure53/DOMPurify/releases
|
||||
# https://github.com/Daninet/hash-wasm/releases
|
||||
# https://github.com/openpgpjs/asmcrypto.js/commits/main/
|
||||
# https://github.com/google/zopfli/tags
|
||||
|
||||
|
||||
|
|
@ -28,7 +26,6 @@ RUN mkdir -p /z/dist/no-pk \
|
|||
bash brotli cmake make g++ git gzip lame npm patch pigz \
|
||||
python3 python3-dev py3-brotli sox tar unzip wget \
|
||||
&& rm -f /usr/lib/python3*/EXTERNALLY-MANAGED \
|
||||
&& wget https://github.com/openpgpjs/asmcrypto.js/archive/$ver_asmcrypto.tar.gz -O asmcrypto.tgz \
|
||||
&& wget https://github.com/markedjs/marked/archive/v$ver_marked.tar.gz -O marked.tgz \
|
||||
&& wget https://github.com/Ionaru/easy-markdown-editor/archive/$ver_mde.tar.gz -O mde.tgz \
|
||||
&& wget https://github.com/codemirror/codemirror5/archive/$ver_codemirror.tar.gz -O codemirror.tgz \
|
||||
|
|
@ -41,9 +38,6 @@ RUN mkdir -p /z/dist/no-pk \
|
|||
&& (mkdir hash-wasm \
|
||||
&& cd hash-wasm \
|
||||
&& unzip ../hash-wasm.zip) \
|
||||
&& (tar --no-same-owner -xf asmcrypto.tgz \
|
||||
&& cd asmcrypto.js-$ver_asmcrypto \
|
||||
&& npm install ) \
|
||||
&& (tar --no-same-owner -xf marked.tgz \
|
||||
&& cd marked-$ver_marked \
|
||||
&& npm install \
|
||||
|
|
@ -71,6 +65,7 @@ RUN /z/busy-mp3.sh \
|
|||
RUN tar --no-same-owner -xf zopfli.tgz \
|
||||
&& cd zopfli* \
|
||||
&& cmake \
|
||||
-DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DZOPFLI_BUILD_SHARED=ON \
|
||||
-B build \
|
||||
|
|
@ -81,13 +76,6 @@ RUN tar --no-same-owner -xf zopfli.tgz \
|
|||
&& python3 -m pip install fonttools zopfli
|
||||
|
||||
|
||||
# build asmcrypto
|
||||
RUN cd asmcrypto.js-$ver_asmcrypto \
|
||||
&& echo "export { Sha512 } from './hash/sha512/sha512';" > src/entry-export_all.ts \
|
||||
&& node -r esm build.js \
|
||||
&& awk '/HMAC state/{o=1} /var HEAP/{o=0} /function hmac_reset/{o=1} /return \{/{o=0} /var __extends =/{o=1} /var Hash =/{o=0} /hmac_|pbkdf2_/{next} o{next} {gsub(/IllegalStateError/,"Exception")} {sub(/^ +/,"");sub(/^\/\/ .*/,"");sub(/;$/," ;")} 1' < asmcrypto.all.es5.js > /z/dist/sha512.ac.js
|
||||
|
||||
|
||||
# build hash-wasm
|
||||
RUN cd hash-wasm/dist \
|
||||
&& mv sha512.umd.min.js /z/dist/sha512.hw.js
|
||||
|
|
|
|||
|
|
@ -1,63 +1,320 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
plugins=(
|
||||
line-highlight
|
||||
line-numbers
|
||||
autolinker
|
||||
)
|
||||
|
||||
langs=(
|
||||
markup
|
||||
css
|
||||
clike
|
||||
javascript
|
||||
autohotkey
|
||||
# abap
|
||||
# abnf
|
||||
# actionscript
|
||||
# ada
|
||||
# agda
|
||||
# al
|
||||
# antlr4
|
||||
# apacheconf
|
||||
# apex
|
||||
# apl
|
||||
# applescript
|
||||
# aql
|
||||
# arduino
|
||||
# arff
|
||||
# armasm
|
||||
# arturo
|
||||
# asciidoc
|
||||
# aspnet
|
||||
# asm6502
|
||||
# asmatmel
|
||||
# autohotkey
|
||||
# autoit
|
||||
# avisynth
|
||||
# avro-idl
|
||||
# awk
|
||||
bash
|
||||
basic
|
||||
batch
|
||||
# bbcode
|
||||
# bbj
|
||||
# bicep
|
||||
# birb
|
||||
# bison
|
||||
# bnf
|
||||
# bqn
|
||||
# brainfuck
|
||||
# brightscript
|
||||
# bro
|
||||
# bsl
|
||||
c
|
||||
csharp
|
||||
cpp
|
||||
cmake
|
||||
# cfscript
|
||||
# chaiscript
|
||||
# cil
|
||||
# cilkc
|
||||
# cilkcpp
|
||||
# clojure
|
||||
# cmake
|
||||
# cobol
|
||||
# coffeescript
|
||||
# concurnas
|
||||
# csp
|
||||
# cooklang
|
||||
# coq
|
||||
# crystal
|
||||
# css-extras
|
||||
# csv
|
||||
# cue
|
||||
# cypher
|
||||
# d
|
||||
# dart
|
||||
# dataweave
|
||||
# dax
|
||||
# dhall
|
||||
diff
|
||||
# django
|
||||
# dns-zone-file
|
||||
docker
|
||||
# dot
|
||||
# ebnf
|
||||
# editorconfig
|
||||
# eiffel
|
||||
# ejs
|
||||
elixir
|
||||
# elm
|
||||
# etlua
|
||||
# erb
|
||||
# erlang
|
||||
# excel-formula
|
||||
# fsharp
|
||||
# factor
|
||||
# false
|
||||
# firestore-security-rules
|
||||
# flow
|
||||
# fortran
|
||||
# ftl
|
||||
# gml
|
||||
# gap
|
||||
# gcode
|
||||
# gdscript
|
||||
# gedcom
|
||||
# gettext
|
||||
# gherkin
|
||||
# git
|
||||
glsl
|
||||
# gn
|
||||
# linker-script
|
||||
go
|
||||
# go-module
|
||||
# gradle
|
||||
# graphql
|
||||
# groovy
|
||||
# haml
|
||||
# handlebars
|
||||
# haskell
|
||||
# haxe
|
||||
# hcl
|
||||
# hlsl
|
||||
# hoon
|
||||
# http
|
||||
# hpkp
|
||||
# hsts
|
||||
# ichigojam
|
||||
# icon
|
||||
# icu-message-format
|
||||
# idris
|
||||
# ignore
|
||||
# inform7
|
||||
ini
|
||||
# io
|
||||
# j
|
||||
java
|
||||
# javadoc
|
||||
# javadoclike
|
||||
# javastacktrace
|
||||
# jexl
|
||||
# jolie
|
||||
# jq
|
||||
# jsdoc
|
||||
# js-extras
|
||||
json
|
||||
# json5
|
||||
# jsonp
|
||||
# jsstacktrace
|
||||
# js-templates
|
||||
# julia
|
||||
# keepalived
|
||||
# keyman
|
||||
kotlin
|
||||
# kumir
|
||||
# kusto
|
||||
latex
|
||||
# latte
|
||||
less
|
||||
# lilypond
|
||||
# liquid
|
||||
lisp
|
||||
# livescript
|
||||
# llvm
|
||||
# log
|
||||
# lolcode
|
||||
lua
|
||||
# magma
|
||||
makefile
|
||||
# markdown
|
||||
# markup-templating
|
||||
# mata
|
||||
matlab
|
||||
# maxscript
|
||||
# mel
|
||||
# mermaid
|
||||
# metafont
|
||||
# mizar
|
||||
# mongodb
|
||||
# monkey
|
||||
moonscript
|
||||
# n1ql
|
||||
# n4js
|
||||
# nand2tetris-hdl
|
||||
# naniscript
|
||||
nasm
|
||||
# neon
|
||||
# nevod
|
||||
# nginx
|
||||
nim
|
||||
# nix
|
||||
# nsis
|
||||
objectivec
|
||||
# ocaml
|
||||
# odin
|
||||
# opencl
|
||||
# openqasm
|
||||
# oz
|
||||
# parigp
|
||||
# parser
|
||||
# pascal
|
||||
# pascaligo
|
||||
# psl
|
||||
# pcaxis
|
||||
# peoplecode
|
||||
perl
|
||||
# php
|
||||
# phpdoc
|
||||
# php-extras
|
||||
# plant-uml
|
||||
# plsql
|
||||
# powerquery
|
||||
powershell
|
||||
# processing
|
||||
# prolog
|
||||
# promql
|
||||
# properties
|
||||
# protobuf
|
||||
# pug
|
||||
# puppet
|
||||
# pure
|
||||
# purebasic
|
||||
# purescript
|
||||
python
|
||||
# qsharp
|
||||
# q
|
||||
# qml
|
||||
# qore
|
||||
r
|
||||
# racket
|
||||
# cshtml
|
||||
jsx
|
||||
# tsx
|
||||
# reason
|
||||
# regex
|
||||
# rego
|
||||
# renpy
|
||||
# rescript
|
||||
# rest
|
||||
# rip
|
||||
# roboconf
|
||||
# robotframework
|
||||
ruby
|
||||
rust
|
||||
# sas
|
||||
sass
|
||||
scss
|
||||
# scala
|
||||
# scheme
|
||||
# shell-session
|
||||
# smali
|
||||
# smalltalk
|
||||
# smarty
|
||||
# sml
|
||||
# solidity
|
||||
# solution-file
|
||||
# soy
|
||||
# sparql
|
||||
# splunk-spl
|
||||
# sqf
|
||||
sql
|
||||
# squirrel
|
||||
# stan
|
||||
# stata
|
||||
# iecst
|
||||
# stylus
|
||||
# supercollider
|
||||
swift
|
||||
systemd
|
||||
# t4-templating
|
||||
# t4-cs
|
||||
# t4-vb
|
||||
# tap
|
||||
# tcl
|
||||
# tt2
|
||||
# textile
|
||||
toml
|
||||
# tremor
|
||||
# turtle
|
||||
# twig
|
||||
typescript
|
||||
# typoscript
|
||||
# unrealscript
|
||||
# uorazor
|
||||
# uri
|
||||
# v
|
||||
# vala
|
||||
vbnet
|
||||
# velocity
|
||||
verilog
|
||||
vhdl
|
||||
# vim
|
||||
# visual-basic
|
||||
# warpscript
|
||||
# wasm
|
||||
# web-idl
|
||||
# wgsl
|
||||
# wiki
|
||||
# wolfram
|
||||
# wren
|
||||
# xeora
|
||||
# xml-doc
|
||||
# xojo
|
||||
# xquery
|
||||
yaml
|
||||
# yang
|
||||
zig
|
||||
)
|
||||
|
||||
slangs="${langs[*]}"
|
||||
slangs="${slangs// /+}"
|
||||
|
||||
splugins="${plugins[*]}"
|
||||
splugins="${splugins// /+}"
|
||||
|
||||
for theme in prism-funky prism ; do
|
||||
u="https://prismjs.com/download.html#themes=$theme&languages=$slangs&plugins=line-highlight+line-numbers+autolinker"
|
||||
u="https://prismjs.com/download.html#themes=$theme&languages=$slangs&plugins=$splugins"
|
||||
echo "$u"
|
||||
./genprism.py --dir prism-$1 --js-out prism.js --css-out $theme.css "$u"
|
||||
done
|
||||
|
|
|
|||
|
|
@ -151,6 +151,7 @@ done
|
|||
rm -rf contrib
|
||||
[ $fast ] && sed -ri s/573/10/ copyparty/web/Makefile
|
||||
(cd copyparty/web && make -j$(nproc) && rm Makefile)
|
||||
rm -f copyparty/web/deps/README.md
|
||||
|
||||
# build
|
||||
python3 -m build
|
||||
|
|
|
|||
|
|
@ -435,7 +435,7 @@ find -name py.typed -delete
|
|||
find -type f \( -name .DS_Store -or -name ._.DS_Store \) -delete
|
||||
find -type f -name ._\* | while IFS= read -r f; do cmp <(printf '\x00\x05\x16') <(head -c 3 -- "$f") && rm -fv -- "$f"; done
|
||||
|
||||
rm -f copyparty/web/deps/*.full.* copyparty/web/dbg-* copyparty/web/Makefile
|
||||
rm -f copyparty/web/deps/*.full.* copyparty/web/deps/README.md copyparty/web/dbg-* copyparty/web/Makefile
|
||||
|
||||
find copyparty | LC_ALL=C sort | sed -r 's/\.gz$//;s/$/,/' > have
|
||||
cat have | while IFS= read -r x; do
|
||||
|
|
|
|||
|
|
@ -91,7 +91,8 @@ grep -qE "^VERSION *= \(${commaver}\)$" copyparty/__version__.py ||
|
|||
}
|
||||
|
||||
rm -rf .vscode
|
||||
rm \
|
||||
rm -f \
|
||||
copyparty/web/deps/README.md \
|
||||
.gitattributes \
|
||||
.gitignore
|
||||
|
||||
|
|
|
|||
|
|
@ -255,6 +255,7 @@ Ls.hmn = {
|
|||
"ct_ttips": '◔ ◡ ◔">ℹ️ tooltips',
|
||||
"ct_thumb": 'in grid-view, toggle icons or thumbnails$NHotkey: T">🖼️ thumbs',
|
||||
"ct_csel": 'use CTRL and SHIFT for file selection in grid-view">sel',
|
||||
"ct_dsel": 'use drag-selection in grid-view">dsel',
|
||||
"ct_dl": 'force download (don\'t display inline) when a file is clicked">dl',
|
||||
"ct_ihop": 'when the image viewer is closed, scroll down to the last viewed file">g⮯',
|
||||
"ct_dots": 'show hidden files (if server permits)">dotfiles',
|
||||
|
|
@ -293,6 +294,7 @@ Ls.hmn = {
|
|||
"cdt_ask": "when scrolling to the bottom,$Ninstead of loading more files,$Nask what to do",
|
||||
"cdt_hsort": "how many sorting rules (<code>,sorthref</code>) to include in media-URLs. Setting this to 0 will also ignore sorting-rules included in media links when clicking them",
|
||||
"cdt_ren": "enable custom right-click menu, you can still access the regular menu by pressing the shift key and right-clicking",
|
||||
"cdt_rdb": "show the regular right-click menu when the custom one is already open and right-clicking again",
|
||||
|
||||
"tt_entree": "show navpane (directory tree sidebar)$NHotkey: B",
|
||||
"tt_detree": "show breadcrumbs$NHotkey: B",
|
||||
|
|
@ -383,6 +385,7 @@ Ls.hmn = {
|
|||
"f_anota": "only {0} of the {1} items were selected;\nto select the full folder, first scroll to the bottom",
|
||||
|
||||
"f_dls": 'the file links in the current folder have\nbeen changed into download links',
|
||||
"f_dl_nd": 'skipping folder (use zip/tar download instead):\n',
|
||||
|
||||
"f_partial": "To safely download a file which is currently being uploaded, please click the file which has the same filename, but without the <code>.PARTIAL</code> file extension. Please press CANCEL or Escape to do this.\n\nPressing OK / Enter will ignore this warning and continue downloading the <code>.PARTIAL</code> scratchfile instead, which will almost definitely give you corrupted data.",
|
||||
|
||||
|
|
@ -674,7 +677,7 @@ Ls.hmn = {
|
|||
"rc_ply": "play",
|
||||
"rc_pla": "play as audio",
|
||||
"rc_txt": "open in textfile viewer",
|
||||
"rc_md": "open in text editor",
|
||||
"rc_md": "open in markdown viewer",
|
||||
"rc_dl": "download",
|
||||
"rc_zip": "download as archive",
|
||||
"rc_cpl": "copy link",
|
||||
|
|
@ -682,10 +685,13 @@ Ls.hmn = {
|
|||
"rc_cut": "cut",
|
||||
"rc_cpy": "copy",
|
||||
"rc_pst": "paste",
|
||||
"rc_rnm": "rename",
|
||||
"rc_nfo": "new folder",
|
||||
"rc_nfi": "new file",
|
||||
"rc_sal": "select all",
|
||||
"rc_sin": "invert selection",
|
||||
"rc_shf": "share this folder",
|
||||
"rc_shs": "share selection",
|
||||
|
||||
"lang_set": "refresh to make the change take effect?",
|
||||
|
||||
|
|
|
|||
|
|
@ -63,6 +63,20 @@ Accept-Encoding: gzip
|
|||
fgsfds"""
|
||||
|
||||
|
||||
RCLONE_PUT_FLOAT = """PUT /%s HTTP/1.1
|
||||
Host: 127.0.0.1:3923
|
||||
User-Agent: rclone/v1.67.0
|
||||
Content-Length: 6
|
||||
Authorization: Basic azp1
|
||||
Content-Type: application/octet-stream
|
||||
Oc-Checksum: SHA1:f5e3dc3fb27af53cd0005a1184e2df06481199e8
|
||||
Referer: http://127.0.0.1:3923/
|
||||
X-Oc-Mtime: 1689453578.123
|
||||
Accept-Encoding: gzip
|
||||
|
||||
fgsfds"""
|
||||
|
||||
|
||||
# tcpdump of `rclone delete dav:/a/d1/` (it does propfind recursively and then this on each file)
|
||||
# (note: `rclone rmdirs dav:/a/d1/` does the same thing but just each folder after asserting they're empty)
|
||||
RCLONE_DELETE = """DELETE /%s HTTP/1.1
|
||||
|
|
@ -201,6 +215,11 @@ class TestHttpCli(TC):
|
|||
h, b = self.req(RCLONE_PUT % ("a/fa",))
|
||||
self.assertStart("HTTP/1.1 201 Created\r", h)
|
||||
|
||||
# float x-oc-mtime should be accepted
|
||||
h, b = self.req(RCLONE_PUT_FLOAT % ("a/fb",))
|
||||
self.assertStart("HTTP/1.1 201 Created\r", h)
|
||||
self.assertAlmostEqual(os.path.getmtime("a/fb"), 1689453578.123, places=3)
|
||||
|
||||
# then it does a propfind to confirm
|
||||
h, b = self.req(RCLONE_PROPFIND % ("a/fa",))
|
||||
fns = pfind2ls(b)
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ class Cfg(Namespace):
|
|||
def __init__(self, a=None, v=None, c=None, **ka0):
|
||||
ka = {}
|
||||
|
||||
ex = "allow_flac allow_wav chpw cookie_lax daw dav_auth dav_mac dav_rt dlni e2d e2ds e2dsa e2t e2ts e2tsr e2v e2vu e2vp early_ban ed emp exp force_js getmod grid gsel hardlink hardlink_only http_no_tcp ih ihead localtime log_badxml magic md_no_br nid nih no_acode no_athumb no_bauth no_clone no_cp no_dav no_db_ip no_del no_dirsz no_dupe no_dupe_m no_fnugg no_lifetime no_logues no_mv no_pipe no_poll no_readme no_robots no_sb_md no_sb_lg no_scandir no_tail no_tarcmp no_thumb no_vthumb no_u2abrt no_zip no_zls nrand nsort nw og og_no_head og_s_title ohead opds q rand re_dirsz reflink rm_partial rmagic rss smb srch_dbg srch_excl srch_icase stats ui_noacci ui_nocpla ui_noctxb ui_nolbar ui_nombar ui_nonav ui_notree ui_norepl ui_nosrvi uqe usernames vague_403 vc ver wo_up_readme write_uplog xdev xlink xvol zipmaxu zs"
|
||||
ex = "allow_flac allow_wav chpw cookie_lax daw dav_auth dav_mac dav_rt dlni e2d e2ds e2dsa e2t e2ts e2tsr e2v e2vu e2vp early_ban ed emp exp force_js getmod grid gsel hardlink hardlink_only http_no_tcp ih ihead localtime log_badxml magic md_no_br nid nih no_acode no_athumb no_bauth no_clone no_cp no_dav no_db_ip no_del no_dirsz no_dupe no_dupe_m no_fnugg no_lifetime no_logues no_mv no_pipe no_poll no_readme no_robots no_sb_md no_sb_lg no_scandir no_tail no_tarcmp no_thumb no_vthumb no_u2abrt no_zip no_zls nrand nsort nw og og_no_head og_s_title ohead opds q rand re_dirsz reflink rm_partial rmagic rss smb srch_dbg srch_excl srch_icase stats ui_noacci ui_nocpla ui_noctxb ui_nolbar ui_nombar ui_nonav ui_notree ui_norepl ui_nosrvi uqe usernames vague_403 vc ver vol_nospawn vol_or_crash wo_up_readme write_uplog xdev xlink xvol zipmaxu zs"
|
||||
ka.update(**{k: False for k in ex.split()})
|
||||
|
||||
ex = "dav_inf dedup dotpart dotsrch hook_v no_dhash no_fastboot no_fpool no_htp no_rescan no_sendfile no_ses no_snap no_up_list no_voldump wram re_dhash see_dots plain_ip"
|
||||
|
|
@ -164,10 +164,10 @@ class Cfg(Namespace):
|
|||
ex = "ctl_re db_act forget_ip idp_cookie idp_store k304 loris no304 nosubtle qr_pin qr_wait re_maxage rproxy rsp_jtr rsp_slp s_wr_slp snap_wri theme themes turbo u2ow zipmaxn zipmaxs"
|
||||
ka.update(**{k: 0 for k in ex.split()})
|
||||
|
||||
ex = "ah_alg bname chdir chmod_f chpw_db doctitle df epilogues exit favico ipa ipar html_head html_head_d html_head_s idp_login idp_logout lg_sba lg_sbf log_date log_fk md_sba md_sbf name og_desc og_site og_th og_title og_title_a og_title_v og_title_i opds_exts preadmes prologues readmes shr tcolor textfiles txt_eol ufavico ufavico_h unlist vname xff_src zipmaxt R RS SR"
|
||||
ex = "ah_alg bname chdir chmod_f chpw_db db_xattr doctitle df epilogues exit favico ipa ipar html_head html_head_d html_head_s idp_login idp_logout lg_sba lg_sbf log_date log_fk md_sba md_sbf name og_desc og_site og_th og_title og_title_a og_title_v og_title_i opds_exts preadmes prologues readmes shr shr_site site smsg tcolor textfiles txt_eol ufavico ufavico_h unlist up_site vname xff_src zipmaxt R RS SR"
|
||||
ka.update(**{k: "" for k in ex.split()})
|
||||
|
||||
ex = "apnd_who ban_403 ban_404 ban_422 ban_pw ban_pwc ban_url dont_ban cachectl http_vary rss_fmt_d rss_fmt_t spinner"
|
||||
ex = "apnd_who ban_403 ban_404 ban_422 ban_pw ban_pwc ban_url dont_ban cachectl http_vary rcm rss_fmt_d rss_fmt_t spinner"
|
||||
ka.update(**{k: "no" for k in ex.split()})
|
||||
|
||||
ex = "ext_th grp idp_h_usr idp_hm_usr ipr on403 on404 qr_file xac xad xar xau xban xbc xbd xbr xbu xiu xm"
|
||||
|
|
|
|||
Loading…
Reference in a new issue