copyparty 1.19.4__tar.gz → 1.19.6__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.6}/PKG-INFO +95 -7
- {copyparty-1.19.4 → copyparty-1.19.6}/README.md +94 -6
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/__main__.py +85 -32
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/__version__.py +2 -2
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/authsrv.py +28 -1
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/broker_util.py +0 -1
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/cert.py +1 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/cfg.py +2 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/ftpd.py +5 -5
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/httpcli.py +46 -30
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/mdns.py +2 -2
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/multicast.py +3 -3
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/pwhash.py +1 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/smbd.py +1 -1
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/stolen/qrcodegen.py +19 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/svchub.py +54 -10
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/tcpsrv.py +37 -4
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/up2k.py +13 -2
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/util.py +30 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/a/u2c.py +6 -6
- copyparty-1.19.6/copyparty/web/browser.css.gz +0 -0
- copyparty-1.19.6/copyparty/web/browser.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/md.html +2 -1
- copyparty-1.19.6/copyparty/web/md.js.gz +0 -0
- copyparty-1.19.6/copyparty/web/md2.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/mde.html +2 -1
- copyparty-1.19.6/copyparty/web/splash.js.gz +0 -0
- copyparty-1.19.6/copyparty/web/ui.css.gz +0 -0
- copyparty-1.19.6/copyparty/web/up2k.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty.egg-info/PKG-INFO +95 -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/md2.js.gz +0 -0
- copyparty-1.19.4/copyparty/web/splash.js.gz +0 -0
- copyparty-1.19.4/copyparty/web/ui.css.gz +0 -0
- copyparty-1.19.4/copyparty/web/up2k.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/LICENSE +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/__init__.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/bos/__init__.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/bos/bos.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/bos/path.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/broker_mp.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/broker_mpw.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/broker_thr.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/dxml.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/fsutil.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/httpconn.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/httpsrv.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/ico.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/metrics.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/mtag.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/res/COPYING.txt +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/res/__init__.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/res/insecure.pem +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/ssdp.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/star.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/stolen/__init__.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/stolen/dnslib/__init__.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/stolen/dnslib/bimap.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/stolen/dnslib/bit.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/stolen/dnslib/buffer.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/stolen/dnslib/dns.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/stolen/dnslib/label.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/stolen/dnslib/lex.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/stolen/dnslib/ranges.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/stolen/ifaddr/__init__.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/stolen/ifaddr/_posix.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/stolen/ifaddr/_shared.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/stolen/ifaddr/_win32.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/stolen/surrogateescape.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/sutil.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/szip.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/tftpd.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/th_cli.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/th_srv.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/u2idx.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/a/__init__.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/a/partyfuse.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/a/webdav-cfg.bat +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/baguettebox.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/browser.html +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/browser2.html +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/cf.html +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/dbg-audio.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/deps/__init__.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/deps/busy.mp3.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/deps/easymde.css.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/deps/easymde.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/deps/fuse.py +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/deps/marked.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/deps/mini-fa.css.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/deps/mini-fa.woff +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/deps/prism.css.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/deps/prism.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/deps/prismd.css.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/deps/scp.woff2 +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/deps/sha512.ac.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/deps/sha512.hw.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/idp.html +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/md.css.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/md2.css.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/mde.css.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/mde.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/msg.css.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/msg.html +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/rups.css.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/rups.html +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/rups.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/shares.css.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/shares.html +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/shares.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/splash.css.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/splash.html +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/svcs.html +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/svcs.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/util.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty/web/w.hash.js.gz +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty.egg-info/SOURCES.txt +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty.egg-info/dependency_links.txt +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty.egg-info/entry_points.txt +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty.egg-info/requires.txt +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/copyparty.egg-info/top_level.txt +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/pyproject.toml +0 -0
- {copyparty-1.19.4 → copyparty-1.19.6}/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.6
|
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
|
@@ -634,6 +637,8 @@ for example `-v /mnt::r -v /var/empty:web/certs:r` mounts the server folder `/mn
|
|
634
637
|
|
635
638
|
the example config file right above this section may explain this better; the first volume `/` is mapped to `/srv` which means http://127.0.0.1:3923/music would try to read `/srv/music` on the server filesystem, but since there's another volume at `/music` mapped to `/mnt/music` then it'll go to `/mnt/music` instead
|
636
639
|
|
640
|
+
> ℹ️ this also works for single files, because files can also be volumes
|
641
|
+
|
637
642
|
|
638
643
|
## dotfiles
|
639
644
|
|
@@ -896,7 +901,7 @@ the up2k UI is the epitome of polished intuitive experiences:
|
|
896
901
|
* `[🔎]` switch between upload and [file-search](#file-search) mode
|
897
902
|
* ignore `[🔎]` if you add files by dragging them into the browser
|
898
903
|
|
899
|
-
and then
|
904
|
+
and then there's the tabs below it,
|
900
905
|
* `[ok]` is the files which completed successfully
|
901
906
|
* `[ng]` is the ones that failed / got rejected (already exists, ...)
|
902
907
|
* `[done]` shows a combined list of `[ok]` and `[ng]`, chronological order
|
@@ -1128,7 +1133,7 @@ plays almost every audio format there is (if the server has FFmpeg installed fo
|
|
1128
1133
|
|
1129
1134
|
the following audio formats are usually always playable, even without FFmpeg: `aac|flac|m4a|mp3|ogg|opus|wav`
|
1130
1135
|
|
1131
|
-
some
|
1136
|
+
some highlights:
|
1132
1137
|
* 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
1138
|
* shows the audio waveform in the seekbar
|
1134
1139
|
* not perfectly gapless but can get really close (see settings + eq below); good enough to enjoy gapless albums as intended
|
@@ -1359,6 +1364,12 @@ print a qr-code [(screenshot)](https://user-images.githubusercontent.com/241032/
|
|
1359
1364
|
* `--qrl lootbox/?pw=hunter2` appends to the url, linking to the `lootbox` folder with password `hunter2`
|
1360
1365
|
* `--qrz 1` forces 1x zoom instead of autoscaling to fit the terminal size
|
1361
1366
|
* 1x may render incorrectly on some terminals/fonts, but 2x should always work
|
1367
|
+
* `--qr-pin 1` makes the qr-code stick to the bottom of the console (never scrolls away)
|
1368
|
+
* `--qr-file qr.txt:1:2` writes a small qr-code to `qr.txt`
|
1369
|
+
* `--qr-file qr.txt:2:2` writes a big qr-code to `qr.txt`
|
1370
|
+
* `--qr-file qr.svg:1:2` writes a vector-graphics qr-code to `qr.svg`
|
1371
|
+
* `--qr-file qr.png:8:4:333333:ffcc55` writes an 8x-magnified yellow-on-gray `qr.png`
|
1372
|
+
* `--qr-file qr.png:8:4::ffffff` writes an 8x-magnified white-on-transparent `qr.png`
|
1362
1373
|
|
1363
1374
|
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
1375
|
|
@@ -1383,6 +1394,14 @@ some recommended FTP / FTPS clients; `wark` = example password:
|
|
1383
1394
|
* `lftp -u k,wark -p 3921 127.0.0.1 -e ls`
|
1384
1395
|
* `lftp -u k,wark -p 3990 127.0.0.1 -e 'set ssl:verify-certificate no; ls'`
|
1385
1396
|
|
1397
|
+
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:
|
1398
|
+
|
1399
|
+
```yaml
|
1400
|
+
[global]
|
1401
|
+
ftp: 3921
|
1402
|
+
ftp-pr: 12000-12099
|
1403
|
+
```
|
1404
|
+
|
1386
1405
|
|
1387
1406
|
## webdav server
|
1388
1407
|
|
@@ -1477,6 +1496,7 @@ and some minor issues,
|
|
1477
1496
|
* win10 onwards does not allow connecting anonymously / without accounts
|
1478
1497
|
* python3 only
|
1479
1498
|
* slow (the builtin webdav support in windows is 5x faster, and rclone-webdav is 30x faster)
|
1499
|
+
* those numbers are specifically for copyparty's smb-server (because it sucks); other smb-servers should be similar to webdav
|
1480
1500
|
|
1481
1501
|
known client bugs:
|
1482
1502
|
* on win7 only, `--smb1` is much faster than smb2 (default) because it keeps rescanning folders on smb2
|
@@ -2225,7 +2245,7 @@ when connecting the reverse-proxy to `127.0.0.1` instead (the basic and/or old-f
|
|
2225
2245
|
|
2226
2246
|
in summary, `haproxy > caddy > traefik > nginx > apache > lighttpd`, and use uds when possible (traefik does not support it yet)
|
2227
2247
|
|
2228
|
-
* if these results are bullshit because my config
|
2248
|
+
* if these results are bullshit because my config examples are bad, please submit corrections!
|
2229
2249
|
|
2230
2250
|
|
2231
2251
|
## permanent cloudflare tunnel
|
@@ -2396,6 +2416,15 @@ after installing, start either the system service or the user service and naviga
|
|
2396
2416
|
does not exist yet; there are rumours that it is being packaged! keep an eye on this space...
|
2397
2417
|
|
2398
2418
|
|
2419
|
+
## homebrew formulae
|
2420
|
+
|
2421
|
+
`brew install copyparty ffmpeg` -- https://formulae.brew.sh/formula/copyparty
|
2422
|
+
|
2423
|
+
should work on all macs (both intel and apple silicon) and all relevant macos versions
|
2424
|
+
|
2425
|
+
the homebrew package is maintained by the homebrew team (thanks!)
|
2426
|
+
|
2427
|
+
|
2399
2428
|
## nix package
|
2400
2429
|
|
2401
2430
|
`nix profile install github:9001/copyparty`
|
@@ -2409,7 +2438,7 @@ some recommended dependencies are enabled by default; [override the package](htt
|
|
2409
2438
|
|
2410
2439
|
## nixos module
|
2411
2440
|
|
2412
|
-
for
|
2441
|
+
for [flake-enabled](https://nixos.wiki/wiki/Flakes) installations of NixOS:
|
2413
2442
|
|
2414
2443
|
```nix
|
2415
2444
|
{
|
@@ -2436,6 +2465,33 @@ for this setup, you will need a [flake-enabled](https://nixos.wiki/wiki/Flakes)
|
|
2436
2465
|
}
|
2437
2466
|
```
|
2438
2467
|
|
2468
|
+
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:
|
2469
|
+
|
2470
|
+
```nix
|
2471
|
+
{ pkgs, ... }:
|
2472
|
+
|
2473
|
+
let
|
2474
|
+
# npins example, adjust for your setup. copyparty should be a path to the downloaded repo
|
2475
|
+
# for niv, just replace the npins folder import with the sources.nix file
|
2476
|
+
copyparty = (import ./npins).copyparty;
|
2477
|
+
|
2478
|
+
# or with fetchTarball:
|
2479
|
+
copyparty = fetchTarball "https://github.com/9001/copyparty/archive/hovudstraum.tar.gz";
|
2480
|
+
in
|
2481
|
+
|
2482
|
+
{
|
2483
|
+
# load the copyparty NixOS module
|
2484
|
+
imports = [ "${copyparty}/contrib/nixos/modules/copyparty.nix" ];
|
2485
|
+
|
2486
|
+
# add the copyparty overlay to expose the package to the module
|
2487
|
+
nixpkgs.overlays = [ (import "${copyparty}/contrib/package/nix/overlay.nix") ];
|
2488
|
+
# (optional) install the package globally
|
2489
|
+
environment.systemPackages = [ pkgs.copyparty ];
|
2490
|
+
# configure the copyparty module
|
2491
|
+
services.copyparty.enable = true;
|
2492
|
+
}
|
2493
|
+
```
|
2494
|
+
|
2439
2495
|
copyparty on NixOS is configured via `services.copyparty` options, for example:
|
2440
2496
|
```nix
|
2441
2497
|
services.copyparty = {
|
@@ -2622,11 +2678,20 @@ sync folders to/from copyparty
|
|
2622
2678
|
|
2623
2679
|
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
2680
|
|
2681
|
+
* 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 :-)
|
2682
|
+
|
2625
2683
|
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
2684
|
|
2685
|
+
if you want to sync with `u2c.py` then:
|
2686
|
+
* the `e2dsa` option (either globally or volflag) must be enabled on the server for the volumes you're syncing into
|
2687
|
+
* ...but DON'T enable global-options `no-hash` or `no-idx` (or volflags `nohash` / `noidx`), or at least make sure they are configured so they do not affect anything you are syncing into
|
2688
|
+
* ...and u2c needs the delete-permission, so either `rwd` at minimum, or just `A` which is the same as `rwmd.a`
|
2689
|
+
* quick reminder that `a` and `A` are different permissions, and `.` is very useful for sync
|
2690
|
+
|
2627
2691
|
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
|
2628
2692
|
|
2629
2693
|
* starting from rclone v1.63, rclone is faster than u2c.py on low-latency connections
|
2694
|
+
* but this is only true for the initial upload; u2c will be faster for periodic syncing
|
2630
2695
|
|
2631
2696
|
|
2632
2697
|
## mount as drive
|
@@ -2668,6 +2733,8 @@ there is no iPhone app, but the following shortcuts are almost as good:
|
|
2668
2733
|
* can download links and rehost the target file on copyparty (see first comment inside the shortcut)
|
2669
2734
|
* pics become lowres if you share from gallery to shortcut, so better to launch the shortcut and pick stuff from there
|
2670
2735
|
|
2736
|
+
if you want to run the copyparty server on your iPhone or iPad, see [install on iOS](#install-on-iOS)
|
2737
|
+
|
2671
2738
|
|
2672
2739
|
# performance
|
2673
2740
|
|
@@ -3001,6 +3068,27 @@ if you want thumbnails (photos+videos) and you're okay with spending another 132
|
|
3001
3068
|
* 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
3069
|
|
3003
3070
|
|
3071
|
+
# install on iOS
|
3072
|
+
|
3073
|
+
first install one of the following:
|
3074
|
+
* [a-Shell mini](https://apps.apple.com/us/app/a-shell-mini/id1543537943) gives you the essential features
|
3075
|
+
* [a-Shell](https://apps.apple.com/us/app/a-shell/id1473805438) also enables audio transcoding and better thubmnails
|
3076
|
+
|
3077
|
+
and then copypaste the following command into `a-Shell`:
|
3078
|
+
|
3079
|
+
```sh
|
3080
|
+
curl https://github.com/9001/copyparty/raw/refs/heads/hovudstraum/contrib/setup-ashell.sh | sh
|
3081
|
+
```
|
3082
|
+
|
3083
|
+
what this does:
|
3084
|
+
* creates a basic [config file](#accounts-and-volumes) named `cpc` which you can edit with `vim cpc`
|
3085
|
+
* adds the command `cpp` to launch copyparty with that config file
|
3086
|
+
|
3087
|
+
known issues:
|
3088
|
+
* cannot run in the background; it needs to be on-screen to accept connections / uploads / downloads
|
3089
|
+
* the best way to exit copyparty is to swipe away the app
|
3090
|
+
|
3091
|
+
|
3004
3092
|
# reporting bugs
|
3005
3093
|
|
3006
3094
|
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
|
@@ -569,6 +572,8 @@ for example `-v /mnt::r -v /var/empty:web/certs:r` mounts the server folder `/mn
|
|
569
572
|
|
570
573
|
the example config file right above this section may explain this better; the first volume `/` is mapped to `/srv` which means http://127.0.0.1:3923/music would try to read `/srv/music` on the server filesystem, but since there's another volume at `/music` mapped to `/mnt/music` then it'll go to `/mnt/music` instead
|
571
574
|
|
575
|
+
> ℹ️ this also works for single files, because files can also be volumes
|
576
|
+
|
572
577
|
|
573
578
|
## dotfiles
|
574
579
|
|
@@ -831,7 +836,7 @@ the up2k UI is the epitome of polished intuitive experiences:
|
|
831
836
|
* `[🔎]` switch between upload and [file-search](#file-search) mode
|
832
837
|
* ignore `[🔎]` if you add files by dragging them into the browser
|
833
838
|
|
834
|
-
and then
|
839
|
+
and then there's the tabs below it,
|
835
840
|
* `[ok]` is the files which completed successfully
|
836
841
|
* `[ng]` is the ones that failed / got rejected (already exists, ...)
|
837
842
|
* `[done]` shows a combined list of `[ok]` and `[ng]`, chronological order
|
@@ -1063,7 +1068,7 @@ plays almost every audio format there is (if the server has FFmpeg installed fo
|
|
1063
1068
|
|
1064
1069
|
the following audio formats are usually always playable, even without FFmpeg: `aac|flac|m4a|mp3|ogg|opus|wav`
|
1065
1070
|
|
1066
|
-
some
|
1071
|
+
some highlights:
|
1067
1072
|
* 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
1073
|
* shows the audio waveform in the seekbar
|
1069
1074
|
* not perfectly gapless but can get really close (see settings + eq below); good enough to enjoy gapless albums as intended
|
@@ -1294,6 +1299,12 @@ print a qr-code [(screenshot)](https://user-images.githubusercontent.com/241032/
|
|
1294
1299
|
* `--qrl lootbox/?pw=hunter2` appends to the url, linking to the `lootbox` folder with password `hunter2`
|
1295
1300
|
* `--qrz 1` forces 1x zoom instead of autoscaling to fit the terminal size
|
1296
1301
|
* 1x may render incorrectly on some terminals/fonts, but 2x should always work
|
1302
|
+
* `--qr-pin 1` makes the qr-code stick to the bottom of the console (never scrolls away)
|
1303
|
+
* `--qr-file qr.txt:1:2` writes a small qr-code to `qr.txt`
|
1304
|
+
* `--qr-file qr.txt:2:2` writes a big qr-code to `qr.txt`
|
1305
|
+
* `--qr-file qr.svg:1:2` writes a vector-graphics qr-code to `qr.svg`
|
1306
|
+
* `--qr-file qr.png:8:4:333333:ffcc55` writes an 8x-magnified yellow-on-gray `qr.png`
|
1307
|
+
* `--qr-file qr.png:8:4::ffffff` writes an 8x-magnified white-on-transparent `qr.png`
|
1297
1308
|
|
1298
1309
|
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
1310
|
|
@@ -1318,6 +1329,14 @@ some recommended FTP / FTPS clients; `wark` = example password:
|
|
1318
1329
|
* `lftp -u k,wark -p 3921 127.0.0.1 -e ls`
|
1319
1330
|
* `lftp -u k,wark -p 3990 127.0.0.1 -e 'set ssl:verify-certificate no; ls'`
|
1320
1331
|
|
1332
|
+
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:
|
1333
|
+
|
1334
|
+
```yaml
|
1335
|
+
[global]
|
1336
|
+
ftp: 3921
|
1337
|
+
ftp-pr: 12000-12099
|
1338
|
+
```
|
1339
|
+
|
1321
1340
|
|
1322
1341
|
## webdav server
|
1323
1342
|
|
@@ -1412,6 +1431,7 @@ and some minor issues,
|
|
1412
1431
|
* win10 onwards does not allow connecting anonymously / without accounts
|
1413
1432
|
* python3 only
|
1414
1433
|
* slow (the builtin webdav support in windows is 5x faster, and rclone-webdav is 30x faster)
|
1434
|
+
* those numbers are specifically for copyparty's smb-server (because it sucks); other smb-servers should be similar to webdav
|
1415
1435
|
|
1416
1436
|
known client bugs:
|
1417
1437
|
* on win7 only, `--smb1` is much faster than smb2 (default) because it keeps rescanning folders on smb2
|
@@ -2160,7 +2180,7 @@ when connecting the reverse-proxy to `127.0.0.1` instead (the basic and/or old-f
|
|
2160
2180
|
|
2161
2181
|
in summary, `haproxy > caddy > traefik > nginx > apache > lighttpd`, and use uds when possible (traefik does not support it yet)
|
2162
2182
|
|
2163
|
-
* if these results are bullshit because my config
|
2183
|
+
* if these results are bullshit because my config examples are bad, please submit corrections!
|
2164
2184
|
|
2165
2185
|
|
2166
2186
|
## permanent cloudflare tunnel
|
@@ -2331,6 +2351,15 @@ after installing, start either the system service or the user service and naviga
|
|
2331
2351
|
does not exist yet; there are rumours that it is being packaged! keep an eye on this space...
|
2332
2352
|
|
2333
2353
|
|
2354
|
+
## homebrew formulae
|
2355
|
+
|
2356
|
+
`brew install copyparty ffmpeg` -- https://formulae.brew.sh/formula/copyparty
|
2357
|
+
|
2358
|
+
should work on all macs (both intel and apple silicon) and all relevant macos versions
|
2359
|
+
|
2360
|
+
the homebrew package is maintained by the homebrew team (thanks!)
|
2361
|
+
|
2362
|
+
|
2334
2363
|
## nix package
|
2335
2364
|
|
2336
2365
|
`nix profile install github:9001/copyparty`
|
@@ -2344,7 +2373,7 @@ some recommended dependencies are enabled by default; [override the package](htt
|
|
2344
2373
|
|
2345
2374
|
## nixos module
|
2346
2375
|
|
2347
|
-
for
|
2376
|
+
for [flake-enabled](https://nixos.wiki/wiki/Flakes) installations of NixOS:
|
2348
2377
|
|
2349
2378
|
```nix
|
2350
2379
|
{
|
@@ -2371,6 +2400,33 @@ for this setup, you will need a [flake-enabled](https://nixos.wiki/wiki/Flakes)
|
|
2371
2400
|
}
|
2372
2401
|
```
|
2373
2402
|
|
2403
|
+
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:
|
2404
|
+
|
2405
|
+
```nix
|
2406
|
+
{ pkgs, ... }:
|
2407
|
+
|
2408
|
+
let
|
2409
|
+
# npins example, adjust for your setup. copyparty should be a path to the downloaded repo
|
2410
|
+
# for niv, just replace the npins folder import with the sources.nix file
|
2411
|
+
copyparty = (import ./npins).copyparty;
|
2412
|
+
|
2413
|
+
# or with fetchTarball:
|
2414
|
+
copyparty = fetchTarball "https://github.com/9001/copyparty/archive/hovudstraum.tar.gz";
|
2415
|
+
in
|
2416
|
+
|
2417
|
+
{
|
2418
|
+
# load the copyparty NixOS module
|
2419
|
+
imports = [ "${copyparty}/contrib/nixos/modules/copyparty.nix" ];
|
2420
|
+
|
2421
|
+
# add the copyparty overlay to expose the package to the module
|
2422
|
+
nixpkgs.overlays = [ (import "${copyparty}/contrib/package/nix/overlay.nix") ];
|
2423
|
+
# (optional) install the package globally
|
2424
|
+
environment.systemPackages = [ pkgs.copyparty ];
|
2425
|
+
# configure the copyparty module
|
2426
|
+
services.copyparty.enable = true;
|
2427
|
+
}
|
2428
|
+
```
|
2429
|
+
|
2374
2430
|
copyparty on NixOS is configured via `services.copyparty` options, for example:
|
2375
2431
|
```nix
|
2376
2432
|
services.copyparty = {
|
@@ -2557,11 +2613,20 @@ sync folders to/from copyparty
|
|
2557
2613
|
|
2558
2614
|
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
2615
|
|
2616
|
+
* 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 :-)
|
2617
|
+
|
2560
2618
|
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
2619
|
|
2620
|
+
if you want to sync with `u2c.py` then:
|
2621
|
+
* the `e2dsa` option (either globally or volflag) must be enabled on the server for the volumes you're syncing into
|
2622
|
+
* ...but DON'T enable global-options `no-hash` or `no-idx` (or volflags `nohash` / `noidx`), or at least make sure they are configured so they do not affect anything you are syncing into
|
2623
|
+
* ...and u2c needs the delete-permission, so either `rwd` at minimum, or just `A` which is the same as `rwmd.a`
|
2624
|
+
* quick reminder that `a` and `A` are different permissions, and `.` is very useful for sync
|
2625
|
+
|
2562
2626
|
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
|
2563
2627
|
|
2564
2628
|
* starting from rclone v1.63, rclone is faster than u2c.py on low-latency connections
|
2629
|
+
* but this is only true for the initial upload; u2c will be faster for periodic syncing
|
2565
2630
|
|
2566
2631
|
|
2567
2632
|
## mount as drive
|
@@ -2603,6 +2668,8 @@ there is no iPhone app, but the following shortcuts are almost as good:
|
|
2603
2668
|
* can download links and rehost the target file on copyparty (see first comment inside the shortcut)
|
2604
2669
|
* pics become lowres if you share from gallery to shortcut, so better to launch the shortcut and pick stuff from there
|
2605
2670
|
|
2671
|
+
if you want to run the copyparty server on your iPhone or iPad, see [install on iOS](#install-on-iOS)
|
2672
|
+
|
2606
2673
|
|
2607
2674
|
# performance
|
2608
2675
|
|
@@ -2936,6 +3003,27 @@ if you want thumbnails (photos+videos) and you're okay with spending another 132
|
|
2936
3003
|
* 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
3004
|
|
2938
3005
|
|
3006
|
+
# install on iOS
|
3007
|
+
|
3008
|
+
first install one of the following:
|
3009
|
+
* [a-Shell mini](https://apps.apple.com/us/app/a-shell-mini/id1543537943) gives you the essential features
|
3010
|
+
* [a-Shell](https://apps.apple.com/us/app/a-shell/id1473805438) also enables audio transcoding and better thubmnails
|
3011
|
+
|
3012
|
+
and then copypaste the following command into `a-Shell`:
|
3013
|
+
|
3014
|
+
```sh
|
3015
|
+
curl https://github.com/9001/copyparty/raw/refs/heads/hovudstraum/contrib/setup-ashell.sh | sh
|
3016
|
+
```
|
3017
|
+
|
3018
|
+
what this does:
|
3019
|
+
* creates a basic [config file](#accounts-and-volumes) named `cpc` which you can edit with `vim cpc`
|
3020
|
+
* adds the command `cpp` to launch copyparty with that config file
|
3021
|
+
|
3022
|
+
known issues:
|
3023
|
+
* cannot run in the background; it needs to be on-screen to accept connections / uploads / downloads
|
3024
|
+
* the best way to exit copyparty is to swipe away the app
|
3025
|
+
|
3026
|
+
|
2939
3027
|
# reporting bugs
|
2940
3028
|
|
2941
3029
|
ideas for context to include, and where to submit them
|
@@ -190,35 +190,41 @@ def init_E(EE ) :
|
|
190
190
|
(unicode, "/tmp"),
|
191
191
|
]
|
192
192
|
errs = []
|
193
|
-
for
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
193
|
+
for npath, (pf, pa) in enumerate(paths):
|
194
|
+
p = ""
|
195
|
+
try:
|
196
|
+
p = pf(pa)
|
197
|
+
if not p or p.startswith("~"):
|
198
|
+
continue
|
199
|
+
|
200
|
+
p = os.path.normpath(p)
|
201
|
+
if os.path.isdir(p) and os.listdir(p):
|
202
|
+
mkdir = False
|
203
|
+
else:
|
204
|
+
mkdir = True
|
205
|
+
os.mkdir(p)
|
206
|
+
|
207
|
+
p = os.path.join(p, "copyparty")
|
208
|
+
if not os.path.isdir(p):
|
209
|
+
os.mkdir(p)
|
210
|
+
|
211
|
+
if npath > 1:
|
212
|
+
t = "Using %s/copyparty [%s] for config; filekeys/dirkeys will change on every restart. Consider setting XDG_CONFIG_HOME or giving the unix-user a ~/.config/"
|
213
|
+
errs.append(t % (pa, p))
|
214
|
+
elif mkdir:
|
215
|
+
t = "Using %s/copyparty [%s] for config%s (Warning: %s did not exist and was created just now)"
|
216
|
+
errs.append(t % (pa, p, " instead" if npath else "", pa))
|
217
|
+
elif errs:
|
218
|
+
errs.append("Using %s/copyparty [%s] instead" % (pa, p))
|
219
|
+
|
220
|
+
if errs:
|
221
|
+
warn(". ".join(errs))
|
222
|
+
|
223
|
+
return p # type: ignore
|
224
|
+
except Exception as ex:
|
225
|
+
if p and npath < 2:
|
226
|
+
t = "Unable to store config in %s [%s] due to %r"
|
227
|
+
errs.append(t % (pa, p, ex))
|
222
228
|
|
223
229
|
raise Exception("could not find a writable path for config")
|
224
230
|
|
@@ -662,6 +668,42 @@ def get_sects():
|
|
662
668
|
"""
|
663
669
|
),
|
664
670
|
],
|
671
|
+
[
|
672
|
+
"auth-ord",
|
673
|
+
"authentication precedence",
|
674
|
+
dedent(
|
675
|
+
"""
|
676
|
+
\033[33m--auth-ord\033[0m is a comma-separated list of auth options
|
677
|
+
(one or more of the [\033[35moptions\033[0m] below); first one wins
|
678
|
+
|
679
|
+
[\033[35mpw\033[0m] is conventional login, for example the "\033[36mPW\033[0m" header,
|
680
|
+
or the \033[36m?pw=\033[0m[...] URL-suffix, or a valid session cookie
|
681
|
+
(see \033[33m--help-auth\033[0m)
|
682
|
+
|
683
|
+
[\033[35midp\033[0m] is a username provided in the http-request-header
|
684
|
+
defined by \033[33m--idp-h-usr\033[0m and/or \033[33m--idp-hm-usr\033[0m, which is
|
685
|
+
provided by an authentication middleware such as
|
686
|
+
authentik, authelia, tailscale, ... (see \033[33m--help-idp\033[0m)
|
687
|
+
|
688
|
+
[\033[35midp-h\033[0m] is specifically an \033[33m--idp-h-usr\033[0m header,
|
689
|
+
[\033[35midp-hm\033[0m] is specifically an \033[33m--idp-hm-usr\033[0m header;
|
690
|
+
[\033[35midp\033[0m] is the same as [\033[35midp-hm,idp-h\033[0m]
|
691
|
+
|
692
|
+
[\033[35mipu\033[0m] is a mapping from an IP-address to a username,
|
693
|
+
auto-authing that client-IP to that account
|
694
|
+
(see the description of \033[36m--ipu\033[0m in \033[33m--help\033[0m)
|
695
|
+
|
696
|
+
NOTE: even if an option (\033[35mpw\033[0m/\033[35mipu\033[0m/...) is not in the list,
|
697
|
+
it may still be enabled and can still take effect if
|
698
|
+
none of the other alternatives identify the user
|
699
|
+
|
700
|
+
NOTE: if [\033[35mipu\033[0m] is in the list, it must be FIRST or LAST
|
701
|
+
|
702
|
+
NOTE: if [\033[35mpw\033[0m] is not in the list, the logout-button
|
703
|
+
will be hidden when any idp feature is enabled
|
704
|
+
"""
|
705
|
+
),
|
706
|
+
],
|
665
707
|
[
|
666
708
|
"flags",
|
667
709
|
"list of volflags",
|
@@ -767,7 +809,7 @@ def get_sects():
|
|
767
809
|
\033[36mc0\033[35m show all process output (default)
|
768
810
|
\033[36mc1\033[35m show only stderr
|
769
811
|
\033[36mc2\033[35m show only stdout
|
770
|
-
\033[36mc3\033[35m mute all process
|
812
|
+
\033[36mc3\033[35m mute all process output
|
771
813
|
\033[0m
|
772
814
|
examples:
|
773
815
|
|
@@ -1106,6 +1148,10 @@ def add_qr(ap, tty):
|
|
1106
1148
|
ap2.add_argument("--qrp", metavar="CELLS", type=int, default=4, help="padding (spec says 4 or more, but 1 is usually fine)")
|
1107
1149
|
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
1150
|
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")
|
1151
|
+
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")
|
1152
|
+
ap2.add_argument("--qr-every", metavar="SEC", type=float, default=0, help="print the qr-code every \033[33mSEC\033[0m (try this with/without --qr-pin in case of issues)")
|
1153
|
+
ap2.add_argument("--qr-winch", metavar="SEC", type=float, default=0, help="when --qr-pin is enabled, check for terminal size change every \033[33mSEC\033[0m")
|
1154
|
+
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
1155
|
|
1110
1156
|
|
1111
1157
|
def add_fs(ap):
|
@@ -1230,7 +1276,7 @@ def add_auth(ap):
|
|
1230
1276
|
ses_db = os.path.join(E.cfg, "sessions.db")
|
1231
1277
|
ap2 = ap.add_argument_group("IdP / identity provider / user authentication options")
|
1232
1278
|
ap2.add_argument("--idp-h-usr", metavar="HN", type=u, action="append", help="\033[34mREPEATABLE:\033[0m bypass the copyparty authentication checks if the request-header \033[33mHN\033[0m contains a username to associate the request with (for use with authentik/oauth/...)\n\033[1;31mWARNING:\033[0m if you enable this, make sure clients are unable to specify this header themselves; must be washed away and replaced by a reverse-proxy")
|
1233
|
-
ap2.add_argument("--idp-hm-usr", metavar="
|
1279
|
+
ap2.add_argument("--idp-hm-usr", metavar="T", type=u, action="append", help="\033[34mREPEATABLE:\033[0m bypass the copyparty authentication checks if the request-header \033[33mT\033[0m is provided, and its value exists in a mapping defined by this option; see --help-idp")
|
1234
1280
|
ap2.add_argument("--idp-h-grp", metavar="HN", type=u, default="", help="assume the request-header \033[33mHN\033[0m contains the groupname of the requesting user; can be referenced in config files for group-based access control")
|
1235
1281
|
ap2.add_argument("--idp-h-key", metavar="HN", type=u, default="", help="optional but recommended safeguard; your reverse-proxy will insert a secret header named \033[33mHN\033[0m into all requests, and the other IdP headers will be ignored if this header is not present")
|
1236
1282
|
ap2.add_argument("--idp-gsep", metavar="RE", type=u, default="|:;+,", help="if there are multiple groups in \033[33m--idp-h-grp\033[0m, they are separated by one of the characters in \033[33mRE\033[0m")
|
@@ -1238,6 +1284,7 @@ def add_auth(ap):
|
|
1238
1284
|
ap2.add_argument("--idp-store", metavar="N", type=int, default=1, help="how to use \033[33m--idp-db\033[0m; [\033[32m0\033[0m] = entirely disable, [\033[32m1\033[0m] = write-only (effectively disabled), [\033[32m2\033[0m] = remember users, [\033[32m3\033[0m] = remember users and groups.\nNOTE: Will remember and restore the IdP-volumes of all users for all eternity if set to 2 or 3, even when user is deleted from your IdP")
|
1239
1285
|
ap2.add_argument("--idp-adm", metavar="U,U", type=u, default="", help="comma-separated list of users allowed to use /?idp (the cache management UI)")
|
1240
1286
|
ap2.add_argument("--idp-cookie", metavar="S", type=int, default=0, help="generate a session-token for IdP users which is written to cookie \033[33mcppws\033[0m (or \033[33mcppwd\033[0m if plaintext), to reduce the load on the IdP server, lifetime \033[33mS\033[0m seconds.\n └─note: The expiration time is a client hint only; the actual lifetime of the session-token is infinite (until next restart with \033[33m--ses-db\033[0m wiped)")
|
1287
|
+
ap2.add_argument("--auth-ord", metavar="TXT", type=u, default="idp,ipu", help="controls auth precedence; examples: [\033[32mpw,idp,ipu\033[0m], [\033[32mipu,pw,idp\033[0m], see --help-auth-ord")
|
1241
1288
|
ap2.add_argument("--no-bauth", action="store_true", help="disable basic-authentication support; do not accept passwords from the 'Authenticate' header at all. NOTE: This breaks support for the android app")
|
1242
1289
|
ap2.add_argument("--bauth-last", action="store_true", help="keeps basic-authentication enabled, but only as a last-resort; if a cookie is also provided then the cookie wins")
|
1243
1290
|
ap2.add_argument("--ses-db", metavar="PATH", type=u, default=ses_db, help="where to store the sessions database (if you run multiple copyparty instances, make sure they use different DBs)")
|
@@ -1248,6 +1295,10 @@ def add_auth(ap):
|
|
1248
1295
|
ap2.add_argument("--ipr", metavar="CIDR=USR", type=u, action="append", help="\033[34mREPEATABLE:\033[0m username \033[33mUSR\033[0m can only connect from an IP matching one or more \033[33mCIDR\033[0m (comma-sep.); example: [\033[32m192.168.123.0/24,172.16.0.0/16=dave]")
|
1249
1296
|
ap2.add_argument("--have-idp-hdrs", type=u, default="", help=argparse.SUPPRESS)
|
1250
1297
|
ap2.add_argument("--have-ipu-or-ipr", type=u, default="", help=argparse.SUPPRESS)
|
1298
|
+
ap2.add_argument("--ao-idp-before-pw", type=u, default="", help=argparse.SUPPRESS)
|
1299
|
+
ap2.add_argument("--ao-h-before-hm", type=u, default="", help=argparse.SUPPRESS)
|
1300
|
+
ap2.add_argument("--ao-ipu-wins", type=u, default="", help=argparse.SUPPRESS)
|
1301
|
+
ap2.add_argument("--ao-has-pw", type=u, default="", help=argparse.SUPPRESS)
|
1251
1302
|
|
1252
1303
|
|
1253
1304
|
def add_chpw(ap):
|
@@ -1487,6 +1538,7 @@ def add_logging(ap):
|
|
1487
1538
|
ap2.add_argument("--log-utc", action="store_true", help="do not use local timezone; assume the TZ env-var is UTC (tiny bit faster)")
|
1488
1539
|
ap2.add_argument("--log-tdec", metavar="N", type=int, default=3, help="timestamp resolution / number of timestamp decimals")
|
1489
1540
|
ap2.add_argument("--log-badpwd", metavar="N", type=int, default=2, help="log failed login attempt passwords: 0=terse, 1=plaintext, 2=hashed")
|
1541
|
+
ap2.add_argument("--log-badxml", action="store_true", help="log any invalid XML received from a client")
|
1490
1542
|
ap2.add_argument("--log-conn", action="store_true", help="debug: print tcp-server msgs")
|
1491
1543
|
ap2.add_argument("--log-htp", action="store_true", help="debug: print http-server threadpool scaling")
|
1492
1544
|
ap2.add_argument("--ihead", metavar="HEADER", type=u, action='append', help="print request \033[33mHEADER\033[0m; [\033[32m*\033[0m]=all")
|
@@ -1624,6 +1676,7 @@ def add_db_metadata(ap):
|
|
1624
1676
|
|
1625
1677
|
def add_txt(ap):
|
1626
1678
|
ap2 = ap.add_argument_group("textfile options")
|
1679
|
+
ap2.add_argument("--md-no-br", action="store_true", help="markdown: disable newline-is-newline; will only render a newline into the html given two trailing spaces or a double-newline (volflag=md_no_br)")
|
1627
1680
|
ap2.add_argument("--md-hist", metavar="TXT", type=u, default="s", help="where to store old version of markdown files; [\033[32ms\033[0m]=subfolder, [\033[32mv\033[0m]=volume-histpath, [\033[32mn\033[0m]=nope/disabled (volflag=md_hist)")
|
1628
1681
|
ap2.add_argument("--txt-eol", metavar="TYPE", type=u, default="", help="enable EOL conversion when writing documents; supported: CRLF, LF (volflag=txt_eol)")
|
1629
1682
|
ap2.add_argument("-mcr", metavar="SEC", type=int, default=60, help="the textfile editor will check for serverside changes every \033[33mSEC\033[0m seconds")
|
@@ -1957,7 +2010,7 @@ def main(argv = None) :
|
|
1957
2010
|
if not HAVE_IPV6 and al.i == "::":
|
1958
2011
|
al.i = "0.0.0.0"
|
1959
2012
|
|
1960
|
-
al.i = al.i.split(",")
|
2013
|
+
al.i = [x.strip() for x in al.i.split(",")]
|
1961
2014
|
try:
|
1962
2015
|
if "-" in al.p:
|
1963
2016
|
lo, hi = [int(x) for x in al.p.split("-")]
|