copyparty 1.19.4__tar.gz → 1.19.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {copyparty-1.19.4 → copyparty-1.19.5}/PKG-INFO +85 -7
- {copyparty-1.19.4 → copyparty-1.19.5}/README.md +84 -6
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/__main__.py +3 -1
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/__version__.py +2 -2
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/authsrv.py +12 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/ftpd.py +4 -4
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/httpcli.py +3 -3
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/stolen/qrcodegen.py +19 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/svchub.py +9 -2
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/tcpsrv.py +33 -1
- copyparty-1.19.5/copyparty/web/browser.css.gz +0 -0
- copyparty-1.19.5/copyparty/web/browser.js.gz +0 -0
- copyparty-1.19.5/copyparty/web/md.js.gz +0 -0
- copyparty-1.19.5/copyparty/web/up2k.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty.egg-info/PKG-INFO +85 -7
- copyparty-1.19.4/copyparty/web/browser.css.gz +0 -0
- copyparty-1.19.4/copyparty/web/browser.js.gz +0 -0
- copyparty-1.19.4/copyparty/web/md.js.gz +0 -0
- copyparty-1.19.4/copyparty/web/up2k.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/LICENSE +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/__init__.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/bos/__init__.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/bos/bos.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/bos/path.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/broker_mp.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/broker_mpw.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/broker_thr.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/broker_util.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/cert.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/cfg.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/dxml.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/fsutil.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/httpconn.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/httpsrv.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/ico.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/mdns.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/metrics.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/mtag.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/multicast.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/pwhash.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/res/COPYING.txt +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/res/__init__.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/res/insecure.pem +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/smbd.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/ssdp.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/star.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/stolen/__init__.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/stolen/dnslib/__init__.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/stolen/dnslib/bimap.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/stolen/dnslib/bit.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/stolen/dnslib/buffer.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/stolen/dnslib/dns.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/stolen/dnslib/label.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/stolen/dnslib/lex.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/stolen/dnslib/ranges.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/stolen/ifaddr/__init__.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/stolen/ifaddr/_posix.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/stolen/ifaddr/_shared.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/stolen/ifaddr/_win32.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/stolen/surrogateescape.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/sutil.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/szip.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/tftpd.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/th_cli.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/th_srv.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/u2idx.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/up2k.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/util.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/a/__init__.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/a/partyfuse.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/a/u2c.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/a/webdav-cfg.bat +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/baguettebox.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/browser.html +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/browser2.html +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/cf.html +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/dbg-audio.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/deps/__init__.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/deps/busy.mp3.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/deps/easymde.css.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/deps/easymde.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/deps/fuse.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/deps/marked.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/deps/mini-fa.css.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/deps/mini-fa.woff +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/deps/prism.css.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/deps/prism.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/deps/prismd.css.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/deps/scp.woff2 +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/deps/sha512.ac.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/deps/sha512.hw.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/idp.html +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/md.css.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/md.html +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/md2.css.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/md2.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/mde.css.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/mde.html +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/mde.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/msg.css.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/msg.html +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/rups.css.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/rups.html +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/rups.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/shares.css.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/shares.html +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/shares.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/splash.css.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/splash.html +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/splash.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/svcs.html +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/svcs.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/ui.css.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/util.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty/web/w.hash.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty.egg-info/SOURCES.txt +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty.egg-info/dependency_links.txt +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty.egg-info/entry_points.txt +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty.egg-info/requires.txt +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/copyparty.egg-info/top_level.txt +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/pyproject.toml +0 -0
- {copyparty-1.19.4 → copyparty-1.19.5}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: copyparty
|
3
|
-
Version: 1.19.
|
3
|
+
Version: 1.19.5
|
4
4
|
Summary: Portable file server with accelerated resumable uploads, deduplication, WebDAV, FTP, zeroconf, media indexer, video thumbnails, audio transcoding, and write-only folders
|
5
5
|
Author-email: ed <copyparty@ocv.me>
|
6
6
|
License: MIT
|
@@ -177,6 +177,7 @@ made in Norway 🇳🇴
|
|
177
177
|
* [packages](#packages) - the party might be closer than you think
|
178
178
|
* [arch package](#arch-package) - `pacman -S copyparty` (in [arch linux extra](https://archlinux.org/packages/extra/any/copyparty/))
|
179
179
|
* [fedora package](#fedora-package) - does not exist yet
|
180
|
+
* [homebrew formulae](#homebrew-formulae) - `brew install copyparty ffmpeg`
|
180
181
|
* [nix package](#nix-package) - `nix profile install github:9001/copyparty`
|
181
182
|
* [nixos module](#nixos-module)
|
182
183
|
* [browser support](#browser-support) - TLDR: yes
|
@@ -206,6 +207,7 @@ made in Norway 🇳🇴
|
|
206
207
|
* [copyparty.exe](#copypartyexe) - download [copyparty.exe](https://github.com/9001/copyparty/releases/latest/download/copyparty.exe) (win8+) or [copyparty32.exe](https://github.com/9001/copyparty/releases/latest/download/copyparty32.exe) (win7+)
|
207
208
|
* [zipapp](#zipapp) - another emergency alternative, [copyparty.pyz](https://github.com/9001/copyparty/releases/latest/download/copyparty.pyz)
|
208
209
|
* [install on android](#install-on-android)
|
210
|
+
* [install on iOS](#install-on-iOS)
|
209
211
|
* [reporting bugs](#reporting-bugs) - ideas for context to include, and where to submit them
|
210
212
|
* [devnotes](#devnotes) - for build instructions etc, see [./docs/devnotes.md](./docs/devnotes.md)
|
211
213
|
|
@@ -220,6 +222,7 @@ just run **[copyparty-sfx.py](https://github.com/9001/copyparty/releases/latest/
|
|
220
222
|
* or if you cannot install python, you can use [copyparty.exe](#copypartyexe) instead
|
221
223
|
* or install [on arch](#arch-package) ╱ [on NixOS](#nixos-module) ╱ [through nix](#nix-package)
|
222
224
|
* or if you are on android, [install copyparty in termux](#install-on-android)
|
225
|
+
* or maybe an iPhone or iPad? [install in a-Shell on iOS](#install-on-iOS)
|
223
226
|
* or maybe you have a [synology nas / dsm](./docs/synology-dsm.md)
|
224
227
|
* or if you have [uv](https://docs.astral.sh/uv/) installed, run `uv tool run copyparty`
|
225
228
|
* or if your computer is messed up and nothing else works, [try the pyz](#zipapp)
|
@@ -306,7 +309,7 @@ also see [comparison to similar software](./docs/versus.md)
|
|
306
309
|
* ☑ [upnp / zeroconf / mdns / ssdp](#zeroconf)
|
307
310
|
* ☑ [event hooks](#event-hooks) / script runner
|
308
311
|
* ☑ [reverse-proxy support](https://github.com/9001/copyparty#reverse-proxy)
|
309
|
-
* ☑ cross-platform (Windows, Linux, Macos, Android, FreeBSD, arm32/arm64, ppc64le, s390x, risc-v/riscv64)
|
312
|
+
* ☑ cross-platform (Windows, Linux, Macos, Android, iOS, FreeBSD, arm32/arm64, ppc64le, s390x, risc-v/riscv64)
|
310
313
|
* upload
|
311
314
|
* ☑ basic: plain multipart, ie6 support
|
312
315
|
* ☑ [up2k](#uploading): js, resumable, multithreaded
|
@@ -329,7 +332,7 @@ also see [comparison to similar software](./docs/versus.md)
|
|
329
332
|
* ☑ play video files as audio (converted on server)
|
330
333
|
* ☑ create and play [m3u8 playlists](#playlists)
|
331
334
|
* ☑ image gallery with webm player
|
332
|
-
* ☑ [textfile browser](#textfile-viewer) with syntax
|
335
|
+
* ☑ [textfile browser](#textfile-viewer) with syntax highlighting
|
333
336
|
* ☑ realtime streaming of growing files (logfiles and such)
|
334
337
|
* ☑ [thumbnails](#thumbnails)
|
335
338
|
* ☑ ...of images using Pillow, pyvips, or FFmpeg
|
@@ -896,7 +899,7 @@ the up2k UI is the epitome of polished intuitive experiences:
|
|
896
899
|
* `[🔎]` switch between upload and [file-search](#file-search) mode
|
897
900
|
* ignore `[🔎]` if you add files by dragging them into the browser
|
898
901
|
|
899
|
-
and then
|
902
|
+
and then there's the tabs below it,
|
900
903
|
* `[ok]` is the files which completed successfully
|
901
904
|
* `[ng]` is the ones that failed / got rejected (already exists, ...)
|
902
905
|
* `[done]` shows a combined list of `[ok]` and `[ng]`, chronological order
|
@@ -1128,7 +1131,7 @@ plays almost every audio format there is (if the server has FFmpeg installed fo
|
|
1128
1131
|
|
1129
1132
|
the following audio formats are usually always playable, even without FFmpeg: `aac|flac|m4a|mp3|ogg|opus|wav`
|
1130
1133
|
|
1131
|
-
some
|
1134
|
+
some highlights:
|
1132
1135
|
* OS integration; control playback from your phone's lockscreen ([windows](https://user-images.githubusercontent.com/241032/233213022-298a98ba-721a-4cf1-a3d4-f62634bc53d5.png) // [iOS](https://user-images.githubusercontent.com/241032/142711926-0700be6c-3e31-47b3-9928-53722221f722.png) // [android](https://user-images.githubusercontent.com/241032/233212311-a7368590-08c7-4f9f-a1af-48ccf3f36fad.png))
|
1133
1136
|
* shows the audio waveform in the seekbar
|
1134
1137
|
* not perfectly gapless but can get really close (see settings + eq below); good enough to enjoy gapless albums as intended
|
@@ -1359,6 +1362,12 @@ print a qr-code [(screenshot)](https://user-images.githubusercontent.com/241032/
|
|
1359
1362
|
* `--qrl lootbox/?pw=hunter2` appends to the url, linking to the `lootbox` folder with password `hunter2`
|
1360
1363
|
* `--qrz 1` forces 1x zoom instead of autoscaling to fit the terminal size
|
1361
1364
|
* 1x may render incorrectly on some terminals/fonts, but 2x should always work
|
1365
|
+
* `--qr-pin 1` makes the qr-code stick to the bottom of the console (never scrolls away)
|
1366
|
+
* `--qr-file qr.txt:1:2` writes a small qr-code to `qr.txt`
|
1367
|
+
* `--qr-file qr.txt:2:2` writes a big qr-code to `qr.txt`
|
1368
|
+
* `--qr-file qr.svg:1:2` writes a vector-graphics qr-code to `qr.svg`
|
1369
|
+
* `--qr-file qr.png:8:4:333333:ffcc55` writes an 8x-magnified yellow-on-gray `qr.png`
|
1370
|
+
* `--qr-file qr.png:8:4::ffffff` writes an 8x-magnified white-on-transparent `qr.png`
|
1362
1371
|
|
1363
1372
|
it uses the server hostname if [mdns](#mdns) is enabled, otherwise it'll use your external ip (default route) unless `--qri` specifies a specific ip-prefix or domain
|
1364
1373
|
|
@@ -1383,6 +1392,14 @@ some recommended FTP / FTPS clients; `wark` = example password:
|
|
1383
1392
|
* `lftp -u k,wark -p 3921 127.0.0.1 -e ls`
|
1384
1393
|
* `lftp -u k,wark -p 3990 127.0.0.1 -e 'set ssl:verify-certificate no; ls'`
|
1385
1394
|
|
1395
|
+
config file example, which restricts FTP to only use ports 3921 and 12000-12099 so all of those ports must be opened in your firewall:
|
1396
|
+
|
1397
|
+
```yaml
|
1398
|
+
[global]
|
1399
|
+
ftp: 3921
|
1400
|
+
ftp-pr: 12000-12099
|
1401
|
+
```
|
1402
|
+
|
1386
1403
|
|
1387
1404
|
## webdav server
|
1388
1405
|
|
@@ -2225,7 +2242,7 @@ when connecting the reverse-proxy to `127.0.0.1` instead (the basic and/or old-f
|
|
2225
2242
|
|
2226
2243
|
in summary, `haproxy > caddy > traefik > nginx > apache > lighttpd`, and use uds when possible (traefik does not support it yet)
|
2227
2244
|
|
2228
|
-
* if these results are bullshit because my config
|
2245
|
+
* if these results are bullshit because my config examples are bad, please submit corrections!
|
2229
2246
|
|
2230
2247
|
|
2231
2248
|
## permanent cloudflare tunnel
|
@@ -2396,6 +2413,15 @@ after installing, start either the system service or the user service and naviga
|
|
2396
2413
|
does not exist yet; there are rumours that it is being packaged! keep an eye on this space...
|
2397
2414
|
|
2398
2415
|
|
2416
|
+
## homebrew formulae
|
2417
|
+
|
2418
|
+
`brew install copyparty ffmpeg` -- https://formulae.brew.sh/formula/copyparty
|
2419
|
+
|
2420
|
+
should work on all macs (both intel and apple silicon) and all relevant macos versions
|
2421
|
+
|
2422
|
+
the homebrew package is maintained by the homebrew team (thanks!)
|
2423
|
+
|
2424
|
+
|
2399
2425
|
## nix package
|
2400
2426
|
|
2401
2427
|
`nix profile install github:9001/copyparty`
|
@@ -2409,7 +2435,7 @@ some recommended dependencies are enabled by default; [override the package](htt
|
|
2409
2435
|
|
2410
2436
|
## nixos module
|
2411
2437
|
|
2412
|
-
for
|
2438
|
+
for [flake-enabled](https://nixos.wiki/wiki/Flakes) installations of NixOS:
|
2413
2439
|
|
2414
2440
|
```nix
|
2415
2441
|
{
|
@@ -2436,6 +2462,33 @@ for this setup, you will need a [flake-enabled](https://nixos.wiki/wiki/Flakes)
|
|
2436
2462
|
}
|
2437
2463
|
```
|
2438
2464
|
|
2465
|
+
if you don't use a flake in your configuration, you can use other dependency management tools like [npins](https://github.com/andir/npins), [niv](https://github.com/nmattia/niv), or even plain [`fetchTarball`](https://nix.dev/manual/nix/stable/language/builtins#builtins-fetchTarball), like so:
|
2466
|
+
|
2467
|
+
```nix
|
2468
|
+
{ pkgs, ... }:
|
2469
|
+
|
2470
|
+
let
|
2471
|
+
# npins example, adjust for your setup. copyparty should be a path to the downloaded repo
|
2472
|
+
# for niv, just replace the npins folder import with the sources.nix file
|
2473
|
+
copyparty = (import ./npins).copyparty;
|
2474
|
+
|
2475
|
+
# or with fetchTarball:
|
2476
|
+
copyparty = fetchTarball "https://github.com/9001/copyparty/archive/hovudstraum.tar.gz";
|
2477
|
+
in
|
2478
|
+
|
2479
|
+
{
|
2480
|
+
# load the copyparty NixOS module
|
2481
|
+
imports = [ "${copyparty}/contrib/nixos/modules/copyparty.nix" ];
|
2482
|
+
|
2483
|
+
# add the copyparty overlay to expose the package to the module
|
2484
|
+
nixpkgs.overlays = [ (import "${copyparty}/contrib/package/nix/overlay.nix") ];
|
2485
|
+
# (optional) install the package globally
|
2486
|
+
environment.systemPackages = [ pkgs.copyparty ];
|
2487
|
+
# configure the copyparty module
|
2488
|
+
services.copyparty.enable = true;
|
2489
|
+
}
|
2490
|
+
```
|
2491
|
+
|
2439
2492
|
copyparty on NixOS is configured via `services.copyparty` options, for example:
|
2440
2493
|
```nix
|
2441
2494
|
services.copyparty = {
|
@@ -2622,6 +2675,8 @@ sync folders to/from copyparty
|
|
2622
2675
|
|
2623
2676
|
NOTE: full bidirectional sync, like what [nextcloud](https://docs.nextcloud.com/server/latest/user_manual/sv/files/desktop_mobile_sync.html) and [syncthing](https://syncthing.net/) does, will never be supported! Only single-direction sync (server-to-client, or client-to-server) is possible with copyparty
|
2624
2677
|
|
2678
|
+
* if you want bidirectional sync, then copyparty and syncthing *should* be entirely safe to combine; they should be able to collaborate on the same folders without causing any trouble for eachother. Many people do this, and there have been no issues so far. But, if you *do* encounter any problems, please [file a copyparty bug](https://github.com/9001/copyparty/issues/new/choose) and I'll try to help -- just keep in mind I've never used syncthing before :-)
|
2679
|
+
|
2625
2680
|
the commandline uploader [u2c.py](https://github.com/9001/copyparty/tree/hovudstraum/bin#u2cpy) with `--dr` is the best way to sync a folder to copyparty; verifies checksums and does files in parallel, and deletes unexpected files on the server after upload has finished which makes file-renames really cheap (it'll rename serverside and skip uploading)
|
2626
2681
|
|
2627
2682
|
alternatively there is [rclone](./docs/rclone.md) which allows for bidirectional sync and is *way* more flexible (stream files straight from sftp/s3/gcs to copyparty, ...), although there is no integrity check and it won't work with files over 100 MiB if copyparty is behind cloudflare
|
@@ -2668,6 +2723,8 @@ there is no iPhone app, but the following shortcuts are almost as good:
|
|
2668
2723
|
* can download links and rehost the target file on copyparty (see first comment inside the shortcut)
|
2669
2724
|
* pics become lowres if you share from gallery to shortcut, so better to launch the shortcut and pick stuff from there
|
2670
2725
|
|
2726
|
+
if you want to run the copyparty server on your iPhone or iPad, see [install on iOS](#install-on-iOS)
|
2727
|
+
|
2671
2728
|
|
2672
2729
|
# performance
|
2673
2730
|
|
@@ -3001,6 +3058,27 @@ if you want thumbnails (photos+videos) and you're okay with spending another 132
|
|
3001
3058
|
* or if you want to use `vips` for photo-thumbs instead, `pkg install libvips && python -m pip install --user -U wheel && python -m pip install --user -U pyvips && (cd /data/data/com.termux/files/usr/lib/; ln -s libgobject-2.0.so{,.0}; ln -s libvips.so{,.42})`
|
3002
3059
|
|
3003
3060
|
|
3061
|
+
# install on iOS
|
3062
|
+
|
3063
|
+
first install one of the following:
|
3064
|
+
* [a-Shell mini](https://apps.apple.com/us/app/a-shell-mini/id1543537943) gives you the essential features
|
3065
|
+
* [a-Shell](https://apps.apple.com/us/app/a-shell/id1473805438) also enables audio transcoding and better thubmnails
|
3066
|
+
|
3067
|
+
and then copypaste the following command into `a-Shell`:
|
3068
|
+
|
3069
|
+
```sh
|
3070
|
+
curl https://github.com/9001/copyparty/raw/refs/heads/hovudstraum/contrib/setup-ashell.sh | sh
|
3071
|
+
```
|
3072
|
+
|
3073
|
+
what this does:
|
3074
|
+
* creates a basic [config file](#accounts-and-volumes) named `cpc` which you can edit with `vim cpc`
|
3075
|
+
* adds the command `cpp` to launch copyparty with that config file
|
3076
|
+
|
3077
|
+
known issues:
|
3078
|
+
* cannot run in the background; it needs to be on-screen to accept connections / uploads / downloads
|
3079
|
+
* the best way to exit copyparty is to swipe away the app
|
3080
|
+
|
3081
|
+
|
3004
3082
|
# reporting bugs
|
3005
3083
|
|
3006
3084
|
ideas for context to include, and where to submit them
|
@@ -112,6 +112,7 @@ made in Norway 🇳🇴
|
|
112
112
|
* [packages](#packages) - the party might be closer than you think
|
113
113
|
* [arch package](#arch-package) - `pacman -S copyparty` (in [arch linux extra](https://archlinux.org/packages/extra/any/copyparty/))
|
114
114
|
* [fedora package](#fedora-package) - does not exist yet
|
115
|
+
* [homebrew formulae](#homebrew-formulae) - `brew install copyparty ffmpeg`
|
115
116
|
* [nix package](#nix-package) - `nix profile install github:9001/copyparty`
|
116
117
|
* [nixos module](#nixos-module)
|
117
118
|
* [browser support](#browser-support) - TLDR: yes
|
@@ -141,6 +142,7 @@ made in Norway 🇳🇴
|
|
141
142
|
* [copyparty.exe](#copypartyexe) - download [copyparty.exe](https://github.com/9001/copyparty/releases/latest/download/copyparty.exe) (win8+) or [copyparty32.exe](https://github.com/9001/copyparty/releases/latest/download/copyparty32.exe) (win7+)
|
142
143
|
* [zipapp](#zipapp) - another emergency alternative, [copyparty.pyz](https://github.com/9001/copyparty/releases/latest/download/copyparty.pyz)
|
143
144
|
* [install on android](#install-on-android)
|
145
|
+
* [install on iOS](#install-on-iOS)
|
144
146
|
* [reporting bugs](#reporting-bugs) - ideas for context to include, and where to submit them
|
145
147
|
* [devnotes](#devnotes) - for build instructions etc, see [./docs/devnotes.md](./docs/devnotes.md)
|
146
148
|
|
@@ -155,6 +157,7 @@ just run **[copyparty-sfx.py](https://github.com/9001/copyparty/releases/latest/
|
|
155
157
|
* or if you cannot install python, you can use [copyparty.exe](#copypartyexe) instead
|
156
158
|
* or install [on arch](#arch-package) ╱ [on NixOS](#nixos-module) ╱ [through nix](#nix-package)
|
157
159
|
* or if you are on android, [install copyparty in termux](#install-on-android)
|
160
|
+
* or maybe an iPhone or iPad? [install in a-Shell on iOS](#install-on-iOS)
|
158
161
|
* or maybe you have a [synology nas / dsm](./docs/synology-dsm.md)
|
159
162
|
* or if you have [uv](https://docs.astral.sh/uv/) installed, run `uv tool run copyparty`
|
160
163
|
* or if your computer is messed up and nothing else works, [try the pyz](#zipapp)
|
@@ -241,7 +244,7 @@ also see [comparison to similar software](./docs/versus.md)
|
|
241
244
|
* ☑ [upnp / zeroconf / mdns / ssdp](#zeroconf)
|
242
245
|
* ☑ [event hooks](#event-hooks) / script runner
|
243
246
|
* ☑ [reverse-proxy support](https://github.com/9001/copyparty#reverse-proxy)
|
244
|
-
* ☑ cross-platform (Windows, Linux, Macos, Android, FreeBSD, arm32/arm64, ppc64le, s390x, risc-v/riscv64)
|
247
|
+
* ☑ cross-platform (Windows, Linux, Macos, Android, iOS, FreeBSD, arm32/arm64, ppc64le, s390x, risc-v/riscv64)
|
245
248
|
* upload
|
246
249
|
* ☑ basic: plain multipart, ie6 support
|
247
250
|
* ☑ [up2k](#uploading): js, resumable, multithreaded
|
@@ -264,7 +267,7 @@ also see [comparison to similar software](./docs/versus.md)
|
|
264
267
|
* ☑ play video files as audio (converted on server)
|
265
268
|
* ☑ create and play [m3u8 playlists](#playlists)
|
266
269
|
* ☑ image gallery with webm player
|
267
|
-
* ☑ [textfile browser](#textfile-viewer) with syntax
|
270
|
+
* ☑ [textfile browser](#textfile-viewer) with syntax highlighting
|
268
271
|
* ☑ realtime streaming of growing files (logfiles and such)
|
269
272
|
* ☑ [thumbnails](#thumbnails)
|
270
273
|
* ☑ ...of images using Pillow, pyvips, or FFmpeg
|
@@ -831,7 +834,7 @@ the up2k UI is the epitome of polished intuitive experiences:
|
|
831
834
|
* `[🔎]` switch between upload and [file-search](#file-search) mode
|
832
835
|
* ignore `[🔎]` if you add files by dragging them into the browser
|
833
836
|
|
834
|
-
and then
|
837
|
+
and then there's the tabs below it,
|
835
838
|
* `[ok]` is the files which completed successfully
|
836
839
|
* `[ng]` is the ones that failed / got rejected (already exists, ...)
|
837
840
|
* `[done]` shows a combined list of `[ok]` and `[ng]`, chronological order
|
@@ -1063,7 +1066,7 @@ plays almost every audio format there is (if the server has FFmpeg installed fo
|
|
1063
1066
|
|
1064
1067
|
the following audio formats are usually always playable, even without FFmpeg: `aac|flac|m4a|mp3|ogg|opus|wav`
|
1065
1068
|
|
1066
|
-
some
|
1069
|
+
some highlights:
|
1067
1070
|
* OS integration; control playback from your phone's lockscreen ([windows](https://user-images.githubusercontent.com/241032/233213022-298a98ba-721a-4cf1-a3d4-f62634bc53d5.png) // [iOS](https://user-images.githubusercontent.com/241032/142711926-0700be6c-3e31-47b3-9928-53722221f722.png) // [android](https://user-images.githubusercontent.com/241032/233212311-a7368590-08c7-4f9f-a1af-48ccf3f36fad.png))
|
1068
1071
|
* shows the audio waveform in the seekbar
|
1069
1072
|
* not perfectly gapless but can get really close (see settings + eq below); good enough to enjoy gapless albums as intended
|
@@ -1294,6 +1297,12 @@ print a qr-code [(screenshot)](https://user-images.githubusercontent.com/241032/
|
|
1294
1297
|
* `--qrl lootbox/?pw=hunter2` appends to the url, linking to the `lootbox` folder with password `hunter2`
|
1295
1298
|
* `--qrz 1` forces 1x zoom instead of autoscaling to fit the terminal size
|
1296
1299
|
* 1x may render incorrectly on some terminals/fonts, but 2x should always work
|
1300
|
+
* `--qr-pin 1` makes the qr-code stick to the bottom of the console (never scrolls away)
|
1301
|
+
* `--qr-file qr.txt:1:2` writes a small qr-code to `qr.txt`
|
1302
|
+
* `--qr-file qr.txt:2:2` writes a big qr-code to `qr.txt`
|
1303
|
+
* `--qr-file qr.svg:1:2` writes a vector-graphics qr-code to `qr.svg`
|
1304
|
+
* `--qr-file qr.png:8:4:333333:ffcc55` writes an 8x-magnified yellow-on-gray `qr.png`
|
1305
|
+
* `--qr-file qr.png:8:4::ffffff` writes an 8x-magnified white-on-transparent `qr.png`
|
1297
1306
|
|
1298
1307
|
it uses the server hostname if [mdns](#mdns) is enabled, otherwise it'll use your external ip (default route) unless `--qri` specifies a specific ip-prefix or domain
|
1299
1308
|
|
@@ -1318,6 +1327,14 @@ some recommended FTP / FTPS clients; `wark` = example password:
|
|
1318
1327
|
* `lftp -u k,wark -p 3921 127.0.0.1 -e ls`
|
1319
1328
|
* `lftp -u k,wark -p 3990 127.0.0.1 -e 'set ssl:verify-certificate no; ls'`
|
1320
1329
|
|
1330
|
+
config file example, which restricts FTP to only use ports 3921 and 12000-12099 so all of those ports must be opened in your firewall:
|
1331
|
+
|
1332
|
+
```yaml
|
1333
|
+
[global]
|
1334
|
+
ftp: 3921
|
1335
|
+
ftp-pr: 12000-12099
|
1336
|
+
```
|
1337
|
+
|
1321
1338
|
|
1322
1339
|
## webdav server
|
1323
1340
|
|
@@ -2160,7 +2177,7 @@ when connecting the reverse-proxy to `127.0.0.1` instead (the basic and/or old-f
|
|
2160
2177
|
|
2161
2178
|
in summary, `haproxy > caddy > traefik > nginx > apache > lighttpd`, and use uds when possible (traefik does not support it yet)
|
2162
2179
|
|
2163
|
-
* if these results are bullshit because my config
|
2180
|
+
* if these results are bullshit because my config examples are bad, please submit corrections!
|
2164
2181
|
|
2165
2182
|
|
2166
2183
|
## permanent cloudflare tunnel
|
@@ -2331,6 +2348,15 @@ after installing, start either the system service or the user service and naviga
|
|
2331
2348
|
does not exist yet; there are rumours that it is being packaged! keep an eye on this space...
|
2332
2349
|
|
2333
2350
|
|
2351
|
+
## homebrew formulae
|
2352
|
+
|
2353
|
+
`brew install copyparty ffmpeg` -- https://formulae.brew.sh/formula/copyparty
|
2354
|
+
|
2355
|
+
should work on all macs (both intel and apple silicon) and all relevant macos versions
|
2356
|
+
|
2357
|
+
the homebrew package is maintained by the homebrew team (thanks!)
|
2358
|
+
|
2359
|
+
|
2334
2360
|
## nix package
|
2335
2361
|
|
2336
2362
|
`nix profile install github:9001/copyparty`
|
@@ -2344,7 +2370,7 @@ some recommended dependencies are enabled by default; [override the package](htt
|
|
2344
2370
|
|
2345
2371
|
## nixos module
|
2346
2372
|
|
2347
|
-
for
|
2373
|
+
for [flake-enabled](https://nixos.wiki/wiki/Flakes) installations of NixOS:
|
2348
2374
|
|
2349
2375
|
```nix
|
2350
2376
|
{
|
@@ -2371,6 +2397,33 @@ for this setup, you will need a [flake-enabled](https://nixos.wiki/wiki/Flakes)
|
|
2371
2397
|
}
|
2372
2398
|
```
|
2373
2399
|
|
2400
|
+
if you don't use a flake in your configuration, you can use other dependency management tools like [npins](https://github.com/andir/npins), [niv](https://github.com/nmattia/niv), or even plain [`fetchTarball`](https://nix.dev/manual/nix/stable/language/builtins#builtins-fetchTarball), like so:
|
2401
|
+
|
2402
|
+
```nix
|
2403
|
+
{ pkgs, ... }:
|
2404
|
+
|
2405
|
+
let
|
2406
|
+
# npins example, adjust for your setup. copyparty should be a path to the downloaded repo
|
2407
|
+
# for niv, just replace the npins folder import with the sources.nix file
|
2408
|
+
copyparty = (import ./npins).copyparty;
|
2409
|
+
|
2410
|
+
# or with fetchTarball:
|
2411
|
+
copyparty = fetchTarball "https://github.com/9001/copyparty/archive/hovudstraum.tar.gz";
|
2412
|
+
in
|
2413
|
+
|
2414
|
+
{
|
2415
|
+
# load the copyparty NixOS module
|
2416
|
+
imports = [ "${copyparty}/contrib/nixos/modules/copyparty.nix" ];
|
2417
|
+
|
2418
|
+
# add the copyparty overlay to expose the package to the module
|
2419
|
+
nixpkgs.overlays = [ (import "${copyparty}/contrib/package/nix/overlay.nix") ];
|
2420
|
+
# (optional) install the package globally
|
2421
|
+
environment.systemPackages = [ pkgs.copyparty ];
|
2422
|
+
# configure the copyparty module
|
2423
|
+
services.copyparty.enable = true;
|
2424
|
+
}
|
2425
|
+
```
|
2426
|
+
|
2374
2427
|
copyparty on NixOS is configured via `services.copyparty` options, for example:
|
2375
2428
|
```nix
|
2376
2429
|
services.copyparty = {
|
@@ -2557,6 +2610,8 @@ sync folders to/from copyparty
|
|
2557
2610
|
|
2558
2611
|
NOTE: full bidirectional sync, like what [nextcloud](https://docs.nextcloud.com/server/latest/user_manual/sv/files/desktop_mobile_sync.html) and [syncthing](https://syncthing.net/) does, will never be supported! Only single-direction sync (server-to-client, or client-to-server) is possible with copyparty
|
2559
2612
|
|
2613
|
+
* if you want bidirectional sync, then copyparty and syncthing *should* be entirely safe to combine; they should be able to collaborate on the same folders without causing any trouble for eachother. Many people do this, and there have been no issues so far. But, if you *do* encounter any problems, please [file a copyparty bug](https://github.com/9001/copyparty/issues/new/choose) and I'll try to help -- just keep in mind I've never used syncthing before :-)
|
2614
|
+
|
2560
2615
|
the commandline uploader [u2c.py](https://github.com/9001/copyparty/tree/hovudstraum/bin#u2cpy) with `--dr` is the best way to sync a folder to copyparty; verifies checksums and does files in parallel, and deletes unexpected files on the server after upload has finished which makes file-renames really cheap (it'll rename serverside and skip uploading)
|
2561
2616
|
|
2562
2617
|
alternatively there is [rclone](./docs/rclone.md) which allows for bidirectional sync and is *way* more flexible (stream files straight from sftp/s3/gcs to copyparty, ...), although there is no integrity check and it won't work with files over 100 MiB if copyparty is behind cloudflare
|
@@ -2603,6 +2658,8 @@ there is no iPhone app, but the following shortcuts are almost as good:
|
|
2603
2658
|
* can download links and rehost the target file on copyparty (see first comment inside the shortcut)
|
2604
2659
|
* pics become lowres if you share from gallery to shortcut, so better to launch the shortcut and pick stuff from there
|
2605
2660
|
|
2661
|
+
if you want to run the copyparty server on your iPhone or iPad, see [install on iOS](#install-on-iOS)
|
2662
|
+
|
2606
2663
|
|
2607
2664
|
# performance
|
2608
2665
|
|
@@ -2936,6 +2993,27 @@ if you want thumbnails (photos+videos) and you're okay with spending another 132
|
|
2936
2993
|
* or if you want to use `vips` for photo-thumbs instead, `pkg install libvips && python -m pip install --user -U wheel && python -m pip install --user -U pyvips && (cd /data/data/com.termux/files/usr/lib/; ln -s libgobject-2.0.so{,.0}; ln -s libvips.so{,.42})`
|
2937
2994
|
|
2938
2995
|
|
2996
|
+
# install on iOS
|
2997
|
+
|
2998
|
+
first install one of the following:
|
2999
|
+
* [a-Shell mini](https://apps.apple.com/us/app/a-shell-mini/id1543537943) gives you the essential features
|
3000
|
+
* [a-Shell](https://apps.apple.com/us/app/a-shell/id1473805438) also enables audio transcoding and better thubmnails
|
3001
|
+
|
3002
|
+
and then copypaste the following command into `a-Shell`:
|
3003
|
+
|
3004
|
+
```sh
|
3005
|
+
curl https://github.com/9001/copyparty/raw/refs/heads/hovudstraum/contrib/setup-ashell.sh | sh
|
3006
|
+
```
|
3007
|
+
|
3008
|
+
what this does:
|
3009
|
+
* creates a basic [config file](#accounts-and-volumes) named `cpc` which you can edit with `vim cpc`
|
3010
|
+
* adds the command `cpp` to launch copyparty with that config file
|
3011
|
+
|
3012
|
+
known issues:
|
3013
|
+
* cannot run in the background; it needs to be on-screen to accept connections / uploads / downloads
|
3014
|
+
* the best way to exit copyparty is to swipe away the app
|
3015
|
+
|
3016
|
+
|
2939
3017
|
# reporting bugs
|
2940
3018
|
|
2941
3019
|
ideas for context to include, and where to submit them
|
@@ -767,7 +767,7 @@ def get_sects():
|
|
767
767
|
\033[36mc0\033[35m show all process output (default)
|
768
768
|
\033[36mc1\033[35m show only stderr
|
769
769
|
\033[36mc2\033[35m show only stdout
|
770
|
-
\033[36mc3\033[35m mute all process
|
770
|
+
\033[36mc3\033[35m mute all process output
|
771
771
|
\033[0m
|
772
772
|
examples:
|
773
773
|
|
@@ -1106,6 +1106,8 @@ def add_qr(ap, tty):
|
|
1106
1106
|
ap2.add_argument("--qrp", metavar="CELLS", type=int, default=4, help="padding (spec says 4 or more, but 1 is usually fine)")
|
1107
1107
|
ap2.add_argument("--qrz", metavar="N", type=int, default=0, help="[\033[32m1\033[0m]=1x, [\033[32m2\033[0m]=2x, [\033[32m0\033[0m]=auto (try [\033[32m2\033[0m] on broken fonts)")
|
1108
1108
|
ap2.add_argument("--qr-pin", metavar="N", type=int, default=0, help="sticky/pin the qr-code to always stay on-screen; [\033[32m0\033[0m]=disabled, [\033[32m1\033[0m]=with-url, [\033[32m2\033[0m]=just-qr")
|
1109
|
+
ap2.add_argument("--qr-wait", metavar="SEC", type=float, default=0, help="wait \033[33mSEC\033[0m before printing the qr-code to the log")
|
1110
|
+
ap2.add_argument("--qr-file", metavar="TXT", type=u, action="append", help="\033[34mREPEATABLE:\033[0m write qr-code to file.\n └─To create txt or svg, \033[33mTXT\033[0m is Filepath:Zoom:Pad, for example [\033[32mqr.txt:1:2\033[0m]\n └─To create png or gif, \033[33mTXT\033[0m is Filepath:Zoom:Pad:Foreground:Background, for example [\033[32mqr.png:8:2:333333:ffcc55\033[0m], or [\033[32mqr.png:8:2::ffcc55\033[0m] for transparent")
|
1109
1111
|
|
1110
1112
|
|
1111
1113
|
def add_fs(ap):
|
@@ -1320,6 +1320,10 @@ class AuthSrv(object):
|
|
1320
1320
|
zt = split_cfg_ln(ln)
|
1321
1321
|
for zs, za in zt.items():
|
1322
1322
|
zs = zs.lstrip("-")
|
1323
|
+
if "=" in zs:
|
1324
|
+
t = "WARNING: found an option named [%s] in your [global] config; did you mean to say [%s: %s] instead?"
|
1325
|
+
zs1, zs2 = zs.split("=", 1)
|
1326
|
+
self.log(t % (zs, zs1, zs2), 3)
|
1323
1327
|
if za is True:
|
1324
1328
|
self._e("└─argument [{}]".format(zs))
|
1325
1329
|
else:
|
@@ -1329,6 +1333,10 @@ class AuthSrv(object):
|
|
1329
1333
|
if cat == cata:
|
1330
1334
|
try:
|
1331
1335
|
u, p = [zs.strip() for zs in ln.split(":", 1)]
|
1336
|
+
if "=" in u and not p:
|
1337
|
+
t = "WARNING: found username [%s] in your [accounts] config; did you mean to say [%s: %s] instead?"
|
1338
|
+
zs1, zs2 = u.split("=", 1)
|
1339
|
+
self.log(t % (u, zs1, zs2), 3)
|
1332
1340
|
self._l(ln, 5, "account [{}], password [{}]".format(u, p))
|
1333
1341
|
acct[u] = p
|
1334
1342
|
except:
|
@@ -1399,6 +1407,10 @@ class AuthSrv(object):
|
|
1399
1407
|
zd = split_cfg_ln(ln)
|
1400
1408
|
fstr = ""
|
1401
1409
|
for sk, sv in zd.items():
|
1410
|
+
if "=" in sk:
|
1411
|
+
t = "WARNING: found a volflag named [%s] in your config; did you mean to say [%s: %s] instead?"
|
1412
|
+
zs1, zs2 = sk.split("=", 1)
|
1413
|
+
self.log(t % (sk, zs1, zs2), 3)
|
1402
1414
|
bad = re.sub(r"[a-z0-9_-]", "", sk).lstrip("-")
|
1403
1415
|
if bad:
|
1404
1416
|
err = "bad characters [{}] in volflag name [{}]; "
|
@@ -64,13 +64,13 @@ class FtpAuth(DummyAuthorizer):
|
|
64
64
|
if ip.startswith("::ffff:"):
|
65
65
|
ip = ip[7:]
|
66
66
|
|
67
|
-
|
67
|
+
ipn = ipnorm(ip)
|
68
68
|
bans = self.hub.bans
|
69
|
-
if
|
70
|
-
rt = bans[
|
69
|
+
if ipn in bans:
|
70
|
+
rt = bans[ipn] - time.time()
|
71
71
|
if rt < 0:
|
72
72
|
logging.info("client unbanned")
|
73
|
-
del bans[
|
73
|
+
del bans[ipn]
|
74
74
|
else:
|
75
75
|
raise AuthenticationFailed("banned")
|
76
76
|
|
@@ -389,10 +389,10 @@ class HttpCli(object):
|
|
389
389
|
zsl = [
|
390
390
|
" rproxy: %d if this client's IP-address is [%s]"
|
391
391
|
% (-1 - zd, zs.strip())
|
392
|
-
for zd, zs in enumerate(zsl)
|
392
|
+
for zd, zs in enumerate(zsl[::-1])
|
393
393
|
]
|
394
|
-
t = 'could not determine the client\'s IP-address because the global-option --rproxy has not been configured, so the request-header [%s] specified by global-option --xff-hdr cannot be used safely! Please see the "reverse-proxy" section in the readme. The best approach is to configure your reverse-proxy to give copyparty the exact IP-address to assume (perhaps in another header), but you may also try the following:'
|
395
|
-
t = t % (self.args.xff_hdr,)
|
394
|
+
t = 'could not determine the client\'s IP-address because the global-option --rproxy has not been configured, so the request-header [%s] specified by global-option --xff-hdr cannot be used safely! The raw header value was [%s]. Please see the "reverse-proxy" section in the readme. The best approach is to configure your reverse-proxy to give copyparty the exact IP-address to assume (perhaps in another header), but you may also try the following:'
|
395
|
+
t = t % (self.args.xff_hdr, zso)
|
396
396
|
self.log("%s\n\n%s\n" % (t, "\n".join(zsl)), 3)
|
397
397
|
|
398
398
|
pip = self.conn.addr[0]
|
@@ -195,6 +195,25 @@ class QrCode(object):
|
|
195
195
|
|
196
196
|
return "\n".join(rows)
|
197
197
|
|
198
|
+
def to_png(self, zoom, pad, bg, fg, ap) :
|
199
|
+
from PIL import Image
|
200
|
+
|
201
|
+
tab = self.modules
|
202
|
+
sz = self.size
|
203
|
+
psz = sz + pad * 2
|
204
|
+
if bg:
|
205
|
+
img = Image.new("RGB", (psz, psz), bg)
|
206
|
+
else:
|
207
|
+
img = Image.new("RGBA", (psz, psz), (0, 0, 0, 0))
|
208
|
+
fg = (fg[0], fg[1], fg[2], 255)
|
209
|
+
for y in range(sz):
|
210
|
+
for x in range(sz):
|
211
|
+
if tab[y][x]:
|
212
|
+
img.putpixel((x + pad, y + pad), fg)
|
213
|
+
if zoom != 1:
|
214
|
+
img = img.resize((sz * zoom, sz * zoom), Image.Resampling.NEAREST)
|
215
|
+
img.save(ap)
|
216
|
+
|
198
217
|
def _draw_function_patterns(self) :
|
199
218
|
# Draw horizontal and vertical timing patterns
|
200
219
|
for i in range(self.size):
|
@@ -427,7 +427,7 @@ class SvcHub(object):
|
|
427
427
|
|
428
428
|
# create netmaps early to avoid firewall gaps,
|
429
429
|
# but the mutex blocks multiprocessing startup
|
430
|
-
for zs in "
|
430
|
+
for zs in "ipu_nm ftp_ipa_nm tftp_ipa_nm".split():
|
431
431
|
try:
|
432
432
|
getattr(args, zs).mutex = threading.Lock()
|
433
433
|
except:
|
@@ -809,6 +809,10 @@ class SvcHub(object):
|
|
809
809
|
t = "%s\033[s\033[1;%dr\033[%dH%s%s\033[u" % (t, sh - 1, sh, qr, url)
|
810
810
|
self.pr(t, file=sys.stderr)
|
811
811
|
|
812
|
+
def sleepy_qr(self):
|
813
|
+
time.sleep(self.args.qr_wait)
|
814
|
+
self.log("qr-code", self.tcpsrv.qr)
|
815
|
+
|
812
816
|
def cb_httpsrv_up(self) :
|
813
817
|
self.httpsrv_up += 1
|
814
818
|
if self.httpsrv_up != self.broker.num_workers:
|
@@ -824,7 +828,10 @@ class SvcHub(object):
|
|
824
828
|
if self.args.qr_pin:
|
825
829
|
self.sticky_qr()
|
826
830
|
else:
|
827
|
-
|
831
|
+
if self.args.qr_wait:
|
832
|
+
Daemon(self.sleepy_qr, "qr_w8")
|
833
|
+
else:
|
834
|
+
self.log("qr-code", self.tcpsrv.qr)
|
828
835
|
else:
|
829
836
|
self.log("root", "workers OK\n")
|
830
837
|
|
@@ -9,7 +9,7 @@ import time
|
|
9
9
|
|
10
10
|
from .__init__ import ANYWIN, PY2, TYPE_CHECKING, unicode
|
11
11
|
from .cert import gencert
|
12
|
-
from .stolen.qrcodegen import QrCode
|
12
|
+
from .stolen.qrcodegen import QrCode, qr2svg
|
13
13
|
from .util import (
|
14
14
|
E_ACCESS,
|
15
15
|
E_ADDR_IN_USE,
|
@@ -618,6 +618,10 @@ class TcpSrv(object):
|
|
618
618
|
pad = self.args.qrp
|
619
619
|
zoom = self.args.qrz
|
620
620
|
qrc = QrCode.encode_binary(btxt)
|
621
|
+
|
622
|
+
for zs in self.args.qr_file or []:
|
623
|
+
self._qr2file(qrc, zs)
|
624
|
+
|
621
625
|
if zoom == 0:
|
622
626
|
try:
|
623
627
|
tw, th = termsize()
|
@@ -633,6 +637,8 @@ class TcpSrv(object):
|
|
633
637
|
halfc = "\033[40;48;5;{0}m{1}\033[47;48;5;{2}m"
|
634
638
|
if not fg:
|
635
639
|
halfc = "\033[0;40m{1}\033[0;47m"
|
640
|
+
if nocolor:
|
641
|
+
halfc = "\033[0;7m{1}\033[0m"
|
636
642
|
|
637
643
|
def ansify(m ) :
|
638
644
|
return halfc.format(fg, " " * len(m.group(1)), bg)
|
@@ -651,3 +657,29 @@ class TcpSrv(object):
|
|
651
657
|
t = t.replace("\n", "`\n`")
|
652
658
|
|
653
659
|
return txt + t
|
660
|
+
|
661
|
+
def _qr2file(self, qrc , txt ):
|
662
|
+
if ".txt:" in txt or ".svg:" in txt:
|
663
|
+
ap, zs1, zs2 = txt.rsplit(":", 2)
|
664
|
+
bg = fg = ""
|
665
|
+
else:
|
666
|
+
ap, zs1, zs2, bg, fg = txt.rsplit(":", 4)
|
667
|
+
zoom = int(zs1)
|
668
|
+
pad = int(zs2)
|
669
|
+
|
670
|
+
if ap.endswith(".txt"):
|
671
|
+
if zoom not in (1, 2):
|
672
|
+
raise Exception("invalid zoom for qr.txt; must be 1 or 2")
|
673
|
+
with open(ap, "wb") as f:
|
674
|
+
f.write(qrc.render(zoom, pad).encode("utf-8"))
|
675
|
+
elif ap.endswith(".svg"):
|
676
|
+
with open(ap, "wb") as f:
|
677
|
+
f.write(qr2svg(qrc, pad).encode("utf-8"))
|
678
|
+
else:
|
679
|
+
qrc.to_png(zoom, pad, self._h2i(bg), self._h2i(fg), ap)
|
680
|
+
|
681
|
+
def _h2i(self, hs):
|
682
|
+
try:
|
683
|
+
return tuple(int(hs[i : i + 2], 16) for i in (0, 2, 4))
|
684
|
+
except:
|
685
|
+
return None
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|