copyparty 1.19.7__tar.gz → 1.19.9__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.7 → copyparty-1.19.9}/PKG-INFO +12 -1
- {copyparty-1.19.7 → copyparty-1.19.9}/README.md +11 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/__init__.py +2 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/__main__.py +60 -27
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/__version__.py +2 -2
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/authsrv.py +195 -14
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/bos/bos.py +38 -2
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/cfg.py +6 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/ftpd.py +7 -25
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/httpcli.py +84 -34
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/httpsrv.py +1 -1
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/mdns.py +3 -1
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/mtag.py +0 -1
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/smbd.py +1 -1
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/svchub.py +38 -3
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/tcpsrv.py +4 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/u2idx.py +29 -4
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/up2k.py +63 -29
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/util.py +49 -24
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/a/partyfuse.py +19 -11
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/a/u2c.py +6 -4
- copyparty-1.19.9/copyparty/web/baguettebox.js.gz +0 -0
- copyparty-1.19.9/copyparty/web/browser.css.gz +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/browser.html +1 -1
- copyparty-1.19.9/copyparty/web/browser.js.gz +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/dbg-audio.js.gz +0 -0
- copyparty-1.19.9/copyparty/web/deps/busy.mp3.gz +0 -0
- copyparty-1.19.9/copyparty/web/deps/easymde.css.gz +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/deps/easymde.js.gz +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/deps/marked.js.gz +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/deps/mini-fa.css.gz +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/deps/prism.css.gz +0 -0
- copyparty-1.19.9/copyparty/web/deps/prism.js.gz +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/deps/prismd.css.gz +0 -0
- copyparty-1.19.9/copyparty/web/deps/scp.woff2 +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/deps/sha512.ac.js.gz +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/idp.html +5 -5
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/md.css.gz +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/md.html +1 -1
- copyparty-1.19.9/copyparty/web/md.js.gz +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/md2.css.gz +0 -0
- copyparty-1.19.9/copyparty/web/md2.js.gz +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/mde.css.gz +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/mde.html +1 -1
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/mde.js.gz +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/msg.css.gz +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/msg.html +1 -1
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/rups.css.gz +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/rups.html +1 -1
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/rups.js.gz +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/shares.css.gz +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/shares.html +5 -5
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/shares.js.gz +0 -0
- copyparty-1.19.9/copyparty/web/splash.css.gz +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/splash.html +54 -38
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/splash.js.gz +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/svcs.html +80 -39
- copyparty-1.19.9/copyparty/web/svcs.js.gz +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/ui.css.gz +0 -0
- copyparty-1.19.9/copyparty/web/up2k.js.gz +0 -0
- copyparty-1.19.9/copyparty/web/util.js.gz +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/w.hash.js.gz +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty.egg-info/PKG-INFO +12 -1
- copyparty-1.19.7/copyparty/web/baguettebox.js.gz +0 -0
- copyparty-1.19.7/copyparty/web/browser.css.gz +0 -0
- copyparty-1.19.7/copyparty/web/browser.js.gz +0 -0
- copyparty-1.19.7/copyparty/web/deps/busy.mp3.gz +0 -0
- copyparty-1.19.7/copyparty/web/deps/easymde.css.gz +0 -0
- copyparty-1.19.7/copyparty/web/deps/prism.js.gz +0 -0
- copyparty-1.19.7/copyparty/web/deps/scp.woff2 +0 -0
- copyparty-1.19.7/copyparty/web/md.js.gz +0 -0
- copyparty-1.19.7/copyparty/web/md2.js.gz +0 -0
- copyparty-1.19.7/copyparty/web/splash.css.gz +0 -0
- copyparty-1.19.7/copyparty/web/svcs.js.gz +0 -0
- copyparty-1.19.7/copyparty/web/up2k.js.gz +0 -0
- copyparty-1.19.7/copyparty/web/util.js.gz +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/LICENSE +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/bos/__init__.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/bos/path.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/broker_mp.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/broker_mpw.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/broker_thr.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/broker_util.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/cert.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/dxml.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/fsutil.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/httpconn.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/ico.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/metrics.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/multicast.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/pwhash.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/res/COPYING.txt +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/res/__init__.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/res/insecure.pem +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/ssdp.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/star.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/stolen/__init__.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/stolen/dnslib/__init__.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/stolen/dnslib/bimap.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/stolen/dnslib/bit.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/stolen/dnslib/buffer.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/stolen/dnslib/dns.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/stolen/dnslib/label.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/stolen/dnslib/lex.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/stolen/dnslib/ranges.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/stolen/ifaddr/__init__.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/stolen/ifaddr/_posix.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/stolen/ifaddr/_shared.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/stolen/ifaddr/_win32.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/stolen/qrcodegen.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/stolen/surrogateescape.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/sutil.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/szip.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/tftpd.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/th_cli.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/th_srv.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/a/__init__.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/a/webdav-cfg.bat +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/browser2.html +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/cf.html +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/deps/__init__.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/deps/fuse.py +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/deps/mini-fa.woff +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty/web/deps/sha512.hw.js.gz +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty.egg-info/SOURCES.txt +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty.egg-info/dependency_links.txt +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty.egg-info/entry_points.txt +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty.egg-info/requires.txt +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/copyparty.egg-info/top_level.txt +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/pyproject.toml +0 -0
- {copyparty-1.19.7 → copyparty-1.19.9}/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.9
|
|
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
|
|
@@ -1393,6 +1393,8 @@ some recommended FTP / FTPS clients; `wark` = example password:
|
|
|
1393
1393
|
* https://rclone.org/ does FTPS with `tls=false explicit_tls=true`
|
|
1394
1394
|
* `lftp -u k,wark -p 3921 127.0.0.1 -e ls`
|
|
1395
1395
|
* `lftp -u k,wark -p 3990 127.0.0.1 -e 'set ssl:verify-certificate no; ls'`
|
|
1396
|
+
* `curl ftp://127.0.0.1:3921/` (plaintext ftp)
|
|
1397
|
+
* `curl --ssl-reqd ftp://127.0.0.1:3990/` (encrypted ftps)
|
|
1396
1398
|
|
|
1397
1399
|
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
1400
|
|
|
@@ -2005,6 +2007,10 @@ you can disable the built-in password-based login system, and instead replace it
|
|
|
2005
2007
|
|
|
2006
2008
|
* the regular config-defined users will be used as a fallback for requests which don't include a valid (trusted) IdP username header
|
|
2007
2009
|
|
|
2010
|
+
* `--auth-ord` configured auth precedence, for example to allow overriding the IdP with a copyparty password
|
|
2011
|
+
|
|
2012
|
+
* the login/logout links/buttons can be replaced with links to your IdP with `--idp-login` and `--idp-logout` , for example `--idp-login /idp/login/?redir={dst}` will expand `{dst}` to the page the user was on when clicking Login
|
|
2013
|
+
|
|
2008
2014
|
* if your IdP-server is slow, consider `--idp-cookie` and let requests with the cookie `cppws` bypass the IdP; experimental sessions-based feature added for a party
|
|
2009
2015
|
|
|
2010
2016
|
some popular identity providers are [Authelia](https://www.authelia.com/) (config-file based) and [authentik](https://goauthentik.io/) (GUI-based, more complex)
|
|
@@ -2381,6 +2387,7 @@ buggy feature? rip it out by setting any of the following environment variables
|
|
|
2381
2387
|
| `PRTY_NO_SQLITE` | disable all database-related functionality (file indexing, metadata indexing, most file deduplication logic) |
|
|
2382
2388
|
| `PRTY_NO_TLS` | disable native HTTPS support; if you still want to accept HTTPS connections then TLS must now be terminated by a reverse-proxy |
|
|
2383
2389
|
| `PRTY_NO_TPOKE` | disable systemd-tmpfilesd avoider |
|
|
2390
|
+
| `PRTY_UNSAFE_STATE` | allow storing secrets into emergency-fallback locations |
|
|
2384
2391
|
|
|
2385
2392
|
example: `PRTY_NO_IFADDR=1 python3 copyparty-sfx.py`
|
|
2386
2393
|
|
|
@@ -2763,6 +2770,10 @@ below are some tweaks roughly ordered by usefulness:
|
|
|
2763
2770
|
* using [pypy](https://www.pypy.org/) instead of [cpython](https://www.python.org/) *can* be 70% faster for some workloads, but slower for many others
|
|
2764
2771
|
* and pypy can sometimes crash on startup with `-j0` (TODO make issue)
|
|
2765
2772
|
|
|
2773
|
+
* if you are running the copyparty server **on Windows or Macos:**
|
|
2774
|
+
* `--casechk=y` makes it much faster, but also awakens [the usual surprises](https://github.com/9001/copyparty/issues/781) you expect from a case-insensitive filesystem
|
|
2775
|
+
* this is the same as `casechk: n` in a config-file
|
|
2776
|
+
|
|
2766
2777
|
|
|
2767
2778
|
## client-side
|
|
2768
2779
|
|
|
@@ -1328,6 +1328,8 @@ some recommended FTP / FTPS clients; `wark` = example password:
|
|
|
1328
1328
|
* https://rclone.org/ does FTPS with `tls=false explicit_tls=true`
|
|
1329
1329
|
* `lftp -u k,wark -p 3921 127.0.0.1 -e ls`
|
|
1330
1330
|
* `lftp -u k,wark -p 3990 127.0.0.1 -e 'set ssl:verify-certificate no; ls'`
|
|
1331
|
+
* `curl ftp://127.0.0.1:3921/` (plaintext ftp)
|
|
1332
|
+
* `curl --ssl-reqd ftp://127.0.0.1:3990/` (encrypted ftps)
|
|
1331
1333
|
|
|
1332
1334
|
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
1335
|
|
|
@@ -1940,6 +1942,10 @@ you can disable the built-in password-based login system, and instead replace it
|
|
|
1940
1942
|
|
|
1941
1943
|
* the regular config-defined users will be used as a fallback for requests which don't include a valid (trusted) IdP username header
|
|
1942
1944
|
|
|
1945
|
+
* `--auth-ord` configured auth precedence, for example to allow overriding the IdP with a copyparty password
|
|
1946
|
+
|
|
1947
|
+
* the login/logout links/buttons can be replaced with links to your IdP with `--idp-login` and `--idp-logout` , for example `--idp-login /idp/login/?redir={dst}` will expand `{dst}` to the page the user was on when clicking Login
|
|
1948
|
+
|
|
1943
1949
|
* if your IdP-server is slow, consider `--idp-cookie` and let requests with the cookie `cppws` bypass the IdP; experimental sessions-based feature added for a party
|
|
1944
1950
|
|
|
1945
1951
|
some popular identity providers are [Authelia](https://www.authelia.com/) (config-file based) and [authentik](https://goauthentik.io/) (GUI-based, more complex)
|
|
@@ -2316,6 +2322,7 @@ buggy feature? rip it out by setting any of the following environment variables
|
|
|
2316
2322
|
| `PRTY_NO_SQLITE` | disable all database-related functionality (file indexing, metadata indexing, most file deduplication logic) |
|
|
2317
2323
|
| `PRTY_NO_TLS` | disable native HTTPS support; if you still want to accept HTTPS connections then TLS must now be terminated by a reverse-proxy |
|
|
2318
2324
|
| `PRTY_NO_TPOKE` | disable systemd-tmpfilesd avoider |
|
|
2325
|
+
| `PRTY_UNSAFE_STATE` | allow storing secrets into emergency-fallback locations |
|
|
2319
2326
|
|
|
2320
2327
|
example: `PRTY_NO_IFADDR=1 python3 copyparty-sfx.py`
|
|
2321
2328
|
|
|
@@ -2698,6 +2705,10 @@ below are some tweaks roughly ordered by usefulness:
|
|
|
2698
2705
|
* using [pypy](https://www.pypy.org/) instead of [cpython](https://www.python.org/) *can* be 70% faster for some workloads, but slower for many others
|
|
2699
2706
|
* and pypy can sometimes crash on startup with `-j0` (TODO make issue)
|
|
2700
2707
|
|
|
2708
|
+
* if you are running the copyparty server **on Windows or Macos:**
|
|
2709
|
+
* `--casechk=y` makes it much faster, but also awakens [the usual surprises](https://github.com/9001/copyparty/issues/781) you expect from a case-insensitive filesystem
|
|
2710
|
+
* this is the same as `casechk: n` in a config-file
|
|
2711
|
+
|
|
2701
2712
|
|
|
2702
2713
|
## client-side
|
|
2703
2714
|
|
|
@@ -36,6 +36,7 @@ from .__init__ import (
|
|
|
36
36
|
)
|
|
37
37
|
from .__version__ import CODENAME, S_BUILD_DT, S_VERSION
|
|
38
38
|
from .authsrv import expand_config_file, split_cfg_ln, upgrade_cfg_fmt
|
|
39
|
+
from .bos import bos
|
|
39
40
|
from .cfg import flagcats, onedash
|
|
40
41
|
from .svchub import SvcHub
|
|
41
42
|
from .util import (
|
|
@@ -180,7 +181,7 @@ def init_E(EE ) :
|
|
|
180
181
|
|
|
181
182
|
E = EE # pylint: disable=redefined-outer-name
|
|
182
183
|
|
|
183
|
-
def get_unixdir()
|
|
184
|
+
def get_unixdir() :
|
|
184
185
|
paths = [
|
|
185
186
|
(os.environ.get, "XDG_CONFIG_HOME"),
|
|
186
187
|
(os.path.expanduser, "~/.config"),
|
|
@@ -191,6 +192,8 @@ def init_E(EE ) :
|
|
|
191
192
|
]
|
|
192
193
|
errs = []
|
|
193
194
|
for npath, (pf, pa) in enumerate(paths):
|
|
195
|
+
priv = npath < 2 # private/trusted location
|
|
196
|
+
ram = npath > 1 # "nonvolatile"; not semantically same as `not priv`
|
|
194
197
|
p = ""
|
|
195
198
|
try:
|
|
196
199
|
p = pf(pa)
|
|
@@ -200,15 +203,21 @@ def init_E(EE ) :
|
|
|
200
203
|
p = os.path.normpath(p)
|
|
201
204
|
mkdir = not os.path.isdir(p)
|
|
202
205
|
if mkdir:
|
|
203
|
-
os.mkdir(p)
|
|
206
|
+
os.mkdir(p, 0o700)
|
|
204
207
|
|
|
205
208
|
p = os.path.join(p, "copyparty")
|
|
209
|
+
if not priv and os.path.isdir(p):
|
|
210
|
+
uid = os.geteuid()
|
|
211
|
+
if os.stat(p).st_uid != uid:
|
|
212
|
+
p += ".%s" % (uid,)
|
|
213
|
+
if os.path.isdir(p) and os.stat(p).st_uid != uid:
|
|
214
|
+
raise Exception("filesystem has broken unix permissions")
|
|
206
215
|
try:
|
|
207
216
|
os.listdir(p)
|
|
208
217
|
except:
|
|
209
|
-
os.mkdir(p)
|
|
218
|
+
os.mkdir(p, 0o700)
|
|
210
219
|
|
|
211
|
-
if
|
|
220
|
+
if ram:
|
|
212
221
|
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
222
|
errs.append(t % (pa, p))
|
|
214
223
|
elif mkdir:
|
|
@@ -220,17 +229,19 @@ def init_E(EE ) :
|
|
|
220
229
|
if errs:
|
|
221
230
|
warn(". ".join(errs))
|
|
222
231
|
|
|
223
|
-
return p
|
|
232
|
+
return p, priv
|
|
224
233
|
except Exception as ex:
|
|
225
|
-
if p
|
|
234
|
+
if p:
|
|
226
235
|
t = "Unable to store config in %s [%s] due to %r"
|
|
227
236
|
errs.append(t % (pa, p, ex))
|
|
228
237
|
|
|
229
|
-
|
|
238
|
+
t = "could not find a writable path for runtime state:\n> %s"
|
|
239
|
+
raise Exception(t % ("\n> ".join(errs)))
|
|
230
240
|
|
|
231
241
|
E.mod = os.path.dirname(os.path.realpath(__file__))
|
|
232
242
|
if E.mod.endswith("__init__"):
|
|
233
243
|
E.mod = os.path.dirname(E.mod)
|
|
244
|
+
E.mod_ = os.path.join(E.mod, "")
|
|
234
245
|
|
|
235
246
|
try:
|
|
236
247
|
p = os.environ.get("XDG_CONFIG_HOME")
|
|
@@ -241,7 +252,7 @@ def init_E(EE ) :
|
|
|
241
252
|
p = os.path.abspath(os.path.realpath(p))
|
|
242
253
|
p = os.path.join(p, "copyparty")
|
|
243
254
|
if not os.path.isdir(p):
|
|
244
|
-
os.mkdir(p)
|
|
255
|
+
os.mkdir(p, 0o700)
|
|
245
256
|
os.listdir(p)
|
|
246
257
|
except:
|
|
247
258
|
p = ""
|
|
@@ -254,11 +265,11 @@ def init_E(EE ) :
|
|
|
254
265
|
elif sys.platform == "darwin":
|
|
255
266
|
E.cfg = os.path.expanduser("~/Library/Preferences/copyparty")
|
|
256
267
|
else:
|
|
257
|
-
E.cfg = get_unixdir()
|
|
268
|
+
E.cfg, E.scfg = get_unixdir()
|
|
258
269
|
|
|
259
270
|
E.cfg = E.cfg.replace("\\", "/")
|
|
260
271
|
try:
|
|
261
|
-
|
|
272
|
+
bos.makedirs(E.cfg, bos.MKD_700)
|
|
262
273
|
except:
|
|
263
274
|
if not os.path.isdir(E.cfg):
|
|
264
275
|
raise
|
|
@@ -879,6 +890,11 @@ def get_sects():
|
|
|
879
890
|
middleware and not by clients! and, as an extra precaution,
|
|
880
891
|
send a header named '\033[36mfinalmasterspark\033[0m' (a secret keyword)
|
|
881
892
|
and then \033[36m--idp-h-key finalmasterspark\033[0m to require that
|
|
893
|
+
|
|
894
|
+
the login/logout links/buttons can be replaced with links
|
|
895
|
+
going to your IdP's UI; \033[36m--idp-login /login/?redir={dst}\033[0m
|
|
896
|
+
will expand \033[36m{dst}\033[0m to the URL of the current page, so
|
|
897
|
+
the IdP can redirect the user back to where they were
|
|
882
898
|
"""
|
|
883
899
|
),
|
|
884
900
|
],
|
|
@@ -1153,11 +1169,14 @@ def add_qr(ap, tty):
|
|
|
1153
1169
|
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)")
|
|
1154
1170
|
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")
|
|
1155
1171
|
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")
|
|
1172
|
+
ap2.add_argument("--qr-stdout", action="store_true", help="always display the QR-code on STDOUT in the terminal, even if \033[33m-q\033[0m")
|
|
1173
|
+
ap2.add_argument("--qr-stderr", action="store_true", help="always display the QR-code on STDERR in the terminal, even if \033[33m-q\033[0m")
|
|
1156
1174
|
|
|
1157
1175
|
|
|
1158
1176
|
def add_fs(ap):
|
|
1159
1177
|
ap2 = ap.add_argument_group("filesystem options")
|
|
1160
1178
|
rm_re_def = "15/0.1" if ANYWIN else "0/0"
|
|
1179
|
+
ap2.add_argument("--casechk", metavar="N", type=u, default="auto", help="detect and prevent CI (case-insensitive) behavior if the underlying filesystem is CI? [\033[32my\033[0m] = detect and prevent, [\033[32mn\033[0m] = ignore and allow, [\033[32mauto\033[0m] = \033[32my\033[0m if CI fs detected. NOTE: \033[32my\033[0m is very slow but necessary for correct WebDAV behavior on Windows/Macos (volflag=casechk)")
|
|
1161
1180
|
ap2.add_argument("--rm-retry", metavar="T/R", type=u, default=rm_re_def, help="if a file cannot be deleted because it is busy, continue trying for \033[33mT\033[0m seconds, retry every \033[33mR\033[0m seconds; disable with 0/0 (volflag=rm_retry)")
|
|
1162
1181
|
ap2.add_argument("--mv-retry", metavar="T/R", type=u, default=rm_re_def, help="if a file cannot be renamed because it is busy, continue trying for \033[33mT\033[0m seconds, retry every \033[33mR\033[0m seconds; disable with 0/0 (volflag=mv_retry)")
|
|
1163
1182
|
ap2.add_argument("--iobuf", metavar="BYTES", type=int, default=256*1024, help="file I/O buffer-size; if your volumes are on a network drive, try increasing to \033[32m524288\033[0m or even \033[32m4194304\033[0m (and let me know if that improves your performance)")
|
|
@@ -1169,6 +1188,7 @@ def add_share(ap):
|
|
|
1169
1188
|
ap2 = ap.add_argument_group("share-url options")
|
|
1170
1189
|
ap2.add_argument("--shr", metavar="DIR", type=u, default="", help="toplevel virtual folder for shared files/folders, for example [\033[32m/share\033[0m]")
|
|
1171
1190
|
ap2.add_argument("--shr-db", metavar="FILE", type=u, default=db_path, help="database to store shares in")
|
|
1191
|
+
ap2.add_argument("--shr-who", metavar="TXT", type=u, default="auth", help="who can create a share? [\033[32mno\033[0m]=nobody, [\033[32ma\033[0m]=admin-permission, [\033[32mauth\033[0m]=authenticated (volflag=shr_who)")
|
|
1172
1192
|
ap2.add_argument("--shr-adm", metavar="U,U", type=u, default="", help="comma-separated list of users allowed to view/delete any share")
|
|
1173
1193
|
ap2.add_argument("--shr-rt", metavar="MIN", type=int, default=1440, help="shares can be revived by their owner if they expired less than MIN minutes ago; [\033[32m60\033[0m]=hour, [\033[32m1440\033[0m]=day, [\033[32m10080\033[0m]=week")
|
|
1174
1194
|
ap2.add_argument("--shr-v", action="store_true", help="debug")
|
|
@@ -1285,6 +1305,9 @@ def add_auth(ap):
|
|
|
1285
1305
|
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")
|
|
1286
1306
|
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)")
|
|
1287
1307
|
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)")
|
|
1308
|
+
ap2.add_argument("--idp-login", metavar="L", type=u, default="", help="replace all login-buttons with a link to URL \033[33mL\033[0m (unless \033[32mpw\033[0m is in \033[33m--auth-ord\033[0m then both will be shown); [\033[32m{dst}\033[0m] expands to url of current page")
|
|
1309
|
+
ap2.add_argument("--idp-login-t", metavar="T", type=u, default="Login with SSO", help="the label/text for the idp-login button")
|
|
1310
|
+
ap2.add_argument("--idp-logout", metavar="L", type=u, default="", help="replace all logout-buttons with a link to URL \033[33mL\033[0m")
|
|
1288
1311
|
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")
|
|
1289
1312
|
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")
|
|
1290
1313
|
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")
|
|
@@ -1299,7 +1322,7 @@ def add_auth(ap):
|
|
|
1299
1322
|
ap2.add_argument("--ao-idp-before-pw", type=u, default="", help=argparse.SUPPRESS)
|
|
1300
1323
|
ap2.add_argument("--ao-h-before-hm", type=u, default="", help=argparse.SUPPRESS)
|
|
1301
1324
|
ap2.add_argument("--ao-ipu-wins", type=u, default="", help=argparse.SUPPRESS)
|
|
1302
|
-
ap2.add_argument("--ao-
|
|
1325
|
+
ap2.add_argument("--ao-have-pw", type=u, default="", help=argparse.SUPPRESS)
|
|
1303
1326
|
|
|
1304
1327
|
|
|
1305
1328
|
def add_chpw(ap):
|
|
@@ -1445,6 +1468,7 @@ def add_yolo(ap):
|
|
|
1445
1468
|
ap2.add_argument("--no-fnugg", action="store_true", help="disable the smoketest for caching-related issues in the web-UI")
|
|
1446
1469
|
ap2.add_argument("--getmod", action="store_true", help="permit ?move=[...] and ?delete as GET")
|
|
1447
1470
|
ap2.add_argument("--wo-up-readme", action="store_true", help="allow users with write-only access to upload logues and readmes without adding the _wo_ filename prefix (volflag=wo_up_readme)")
|
|
1471
|
+
ap2.add_argument("--unsafe-state", action="store_true", help="when one of the emergency fallback locations are used for runtime state ($TMPDIR, /tmp), certain features will be force-disabled for security reasons by default. This option overrides that safeguard and allows unsafe storage of secrets")
|
|
1448
1472
|
|
|
1449
1473
|
|
|
1450
1474
|
def add_optouts(ap):
|
|
@@ -1458,7 +1482,7 @@ def add_optouts(ap):
|
|
|
1458
1482
|
ap2.add_argument("--no-fs-abrt", action="store_true", help="disable ability to abort ongoing copy/move")
|
|
1459
1483
|
ap2.add_argument("-nth", action="store_true", help="no title hostname; don't show \033[33m--name\033[0m in <title>")
|
|
1460
1484
|
ap2.add_argument("-nih", action="store_true", help="no info hostname -- don't show in UI")
|
|
1461
|
-
ap2.add_argument("-nid", action="store_true", help="no info disk-usage -- don't show in UI")
|
|
1485
|
+
ap2.add_argument("-nid", action="store_true", help="no info disk-usage -- don't show in UI. This is the same as --du-who no")
|
|
1462
1486
|
ap2.add_argument("-nb", action="store_true", help="no powered-by-copyparty branding in UI")
|
|
1463
1487
|
ap2.add_argument("--zipmaxn", metavar="N", type=u, default="0", help="reject download-as-zip if more than \033[33mN\033[0m files in total; optionally takes a unit suffix: [\033[32m256\033[0m], [\033[32m9K\033[0m], [\033[32m4G\033[0m] (volflag=zipmaxn)")
|
|
1464
1488
|
ap2.add_argument("--zipmaxs", metavar="SZ", type=u, default="0", help="reject download-as-zip if total download size exceeds \033[33mSZ\033[0m bytes; optionally takes a unit suffix: [\033[32m256M\033[0m], [\033[32m4G\033[0m], [\033[32m2T\033[0m] (volflag=zipmaxs)")
|
|
@@ -1652,6 +1676,7 @@ def add_db_general(ap, hcores):
|
|
|
1652
1676
|
ap2.add_argument("--hash-mt", metavar="CORES", type=int, default=hcores, help="num cpu cores to use for file hashing; set 0 or 1 for single-core hashing")
|
|
1653
1677
|
ap2.add_argument("--re-maxage", metavar="SEC", type=int, default=0, help="rescan filesystem for changes every \033[33mSEC\033[0m seconds; 0=off (volflag=scan)")
|
|
1654
1678
|
ap2.add_argument("--db-act", metavar="SEC", type=float, default=10.0, help="defer any scheduled volume reindexing until \033[33mSEC\033[0m seconds after last db write (uploads, renames, ...)")
|
|
1679
|
+
ap2.add_argument("--srch-icase", action="store_true", help="case-insensitive search for all unicode characters (the default is icase for just ascii). NOTE: will make searches much slower (around 4x), and NOTE: only applies to filenames/paths, not tags")
|
|
1655
1680
|
ap2.add_argument("--srch-time", metavar="SEC", type=int, default=45, help="search deadline -- terminate searches running for more than \033[33mSEC\033[0m seconds")
|
|
1656
1681
|
ap2.add_argument("--srch-hits", metavar="N", type=int, default=7999, help="max search results to allow clients to fetch; 125 results will be shown initially")
|
|
1657
1682
|
ap2.add_argument("--srch-excl", metavar="PTN", type=u, default="", help="regex: exclude files from search results if the file-URL matches \033[33mPTN\033[0m (case-sensitive). Example: [\033[32mpassword|logs/[0-9]\033[0m] any URL containing 'password' or 'logs/DIGIT' (volflag=srch_excl)")
|
|
@@ -1706,7 +1731,7 @@ def add_og(ap):
|
|
|
1706
1731
|
ap2.add_argument("--uqe", action="store_true", help="query-string parceling; translate a request for \033[33m/foo/.uqe/BASE64\033[0m into \033[33m/foo?TEXT\033[0m, or \033[33m/foo/?TEXT\033[0m if the first character in \033[33mTEXT\033[0m is a slash. Automatically enabled for \033[33m--og\033[0m")
|
|
1707
1732
|
|
|
1708
1733
|
|
|
1709
|
-
def add_ui(ap, retry):
|
|
1734
|
+
def add_ui(ap, retry ):
|
|
1710
1735
|
THEMES = 10
|
|
1711
1736
|
ap2 = ap.add_argument_group("ui options")
|
|
1712
1737
|
ap2.add_argument("--grid", action="store_true", help="show grid/thumbnails by default (volflag=grid)")
|
|
@@ -1736,7 +1761,11 @@ def add_ui(ap, retry):
|
|
|
1736
1761
|
ap2.add_argument("--doctitle", metavar="TXT", type=u, default="copyparty @ --name", help="title / service-name to show in html documents")
|
|
1737
1762
|
ap2.add_argument("--bname", metavar="TXT", type=u, default="--name", help="server name (displayed in filebrowser document title)")
|
|
1738
1763
|
ap2.add_argument("--pb-url", metavar="URL", type=u, default=URL_PRJ, help="powered-by link; disable with \033[33m-nb\033[0m")
|
|
1739
|
-
ap2.add_argument("--ver", action="store_true", help="show version on the control panel (incompatible with \033[33m-nb\033[0m)")
|
|
1764
|
+
ap2.add_argument("--ver", action="store_true", help="show version on the control panel (incompatible with \033[33m-nb\033[0m). This is the same as --ver-who all")
|
|
1765
|
+
ap2.add_argument("--ver-who", metavar="TXT", type=u, default="no", help="only show version for: [\033[32ma\033[0m]=admin-permission-anywhere, [\033[32mauth\033[0m]=authenticated, [\033[32mall\033[0m]=anyone")
|
|
1766
|
+
ap2.add_argument("--du-who", metavar="TXT", type=u, default="all", help="only show disk usage for: [\033[32mno\033[0m]=nobody, [\033[32ma\033[0m]=admin-permission, [\033[32mrw\033[0m]=read-write, [\033[32mw\033[0m]=write, [\033[32mauth\033[0m]=authenticated, [\033[32mall\033[0m]=anyone (volflag=du_who)")
|
|
1767
|
+
ap2.add_argument("--ver-iwho", type=int, default=0, help=argparse.SUPPRESS)
|
|
1768
|
+
ap2.add_argument("--du-iwho", type=int, default=0, help=argparse.SUPPRESS)
|
|
1740
1769
|
ap2.add_argument("--k304", metavar="NUM", type=int, default=0, help="configure the option to enable/disable k304 on the controlpanel (workaround for buggy reverse-proxies); [\033[32m0\033[0m] = hidden and default-off, [\033[32m1\033[0m] = visible and default-off, [\033[32m2\033[0m] = visible and default-on")
|
|
1741
1770
|
ap2.add_argument("--no304", metavar="NUM", type=int, default=0, help="configure the option to enable/disable no304 on the controlpanel (workaround for buggy caching in browsers); [\033[32m0\033[0m] = hidden and default-off, [\033[32m1\033[0m] = visible and default-off, [\033[32m2\033[0m] = visible and default-on")
|
|
1742
1771
|
ap2.add_argument("--ctl-re", metavar="SEC", type=int, default=1, help="the controlpanel Refresh-button will autorefresh every SEC; [\033[32m0\033[0m] = just once")
|
|
@@ -1844,18 +1873,21 @@ def run_argparse(
|
|
|
1844
1873
|
for k, h, _ in sects:
|
|
1845
1874
|
ap2.add_argument("--help-" + k, action="store_true", help=h)
|
|
1846
1875
|
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
raise Exception()
|
|
1850
|
-
|
|
1876
|
+
if retry:
|
|
1877
|
+
a = ["ascii", "replace"]
|
|
1851
1878
|
for x in ap._actions:
|
|
1852
|
-
|
|
1853
|
-
|
|
1879
|
+
try:
|
|
1880
|
+
x.default = x.default.encode(*a).decode(*a)
|
|
1881
|
+
except:
|
|
1882
|
+
pass
|
|
1854
1883
|
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1884
|
+
try:
|
|
1885
|
+
if x.help and x.help is not argparse.SUPPRESS:
|
|
1886
|
+
x.help = x.help.replace("└─", "`-").encode(*a).decode(*a)
|
|
1887
|
+
if retry > 2:
|
|
1888
|
+
x.help = RE_ANSI.sub("", x.help)
|
|
1889
|
+
except:
|
|
1890
|
+
pass
|
|
1859
1891
|
|
|
1860
1892
|
ret = ap.parse_args(args=argv[1:])
|
|
1861
1893
|
for k, h, t in sects:
|
|
@@ -1965,7 +1997,7 @@ def main(argv = None) :
|
|
|
1965
1997
|
except:
|
|
1966
1998
|
nc = 486 # mdns/ssdp restart headroom; select() maxfd is 512 on windows
|
|
1967
1999
|
|
|
1968
|
-
retry =
|
|
2000
|
+
retry = 0
|
|
1969
2001
|
for fmtr in [RiceFormatter, RiceFormatter, Dodge11874, BasicDodge11874]:
|
|
1970
2002
|
try:
|
|
1971
2003
|
al = run_argparse(argv, fmtr, retry, nc)
|
|
@@ -1974,8 +2006,9 @@ def main(argv = None) :
|
|
|
1974
2006
|
except SystemExit:
|
|
1975
2007
|
raise
|
|
1976
2008
|
except:
|
|
1977
|
-
retry
|
|
1978
|
-
|
|
2009
|
+
retry += 1
|
|
2010
|
+
t = "WARNING: due to limitations in your terminal and/or OS, the helptext cannot be displayed correctly. Will show a simplified version due to the following error:\n[ %s ]:\n%s\n"
|
|
2011
|
+
lprint(t % (fmtr, min_ex()))
|
|
1979
2012
|
|
|
1980
2013
|
try:
|
|
1981
2014
|
assert al # type: ignore
|