copyparty 1.9.25__py3-none-any.whl → 1.9.27__py3-none-any.whl
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/__main__.py +66 -66
- copyparty/__version__.py +2 -2
- copyparty/bos/bos.py +4 -0
- copyparty/up2k.py +71 -22
- copyparty/web/a/u2c.py +19 -8
- {copyparty-1.9.25.dist-info → copyparty-1.9.27.dist-info}/METADATA +12 -4
- {copyparty-1.9.25.dist-info → copyparty-1.9.27.dist-info}/RECORD +11 -11
- {copyparty-1.9.25.dist-info → copyparty-1.9.27.dist-info}/LICENSE +0 -0
- {copyparty-1.9.25.dist-info → copyparty-1.9.27.dist-info}/WHEEL +0 -0
- {copyparty-1.9.25.dist-info → copyparty-1.9.27.dist-info}/entry_points.txt +0 -0
- {copyparty-1.9.25.dist-info → copyparty-1.9.27.dist-info}/top_level.txt +0 -0
copyparty/__main__.py
CHANGED
@@ -816,8 +816,8 @@ def add_general(ap, nc, srvname):
|
|
816
816
|
ap2.add_argument("-a", metavar="ACCT", type=u, action="append", help="add account, \033[33mUSER\033[0m:\033[33mPASS\033[0m; example [\033[32med:wark\033[0m]")
|
817
817
|
ap2.add_argument("-v", metavar="VOL", type=u, action="append", help="add volume, \033[33mSRC\033[0m:\033[33mDST\033[0m:\033[33mFLAG\033[0m; examples [\033[32m.::r\033[0m], [\033[32m/mnt/nas/music:/music:r:aed\033[0m]")
|
818
818
|
ap2.add_argument("-ed", action="store_true", help="enable the ?dots url parameter / client option which allows clients to see dotfiles / hidden files")
|
819
|
-
ap2.add_argument("--urlform", metavar="MODE", type=u, default="print,get", help="how to handle url-form POSTs; see --help-urlform")
|
820
|
-
ap2.add_argument("--wintitle", metavar="TXT", type=u, default="cpp @ $pub", help="
|
819
|
+
ap2.add_argument("--urlform", metavar="MODE", type=u, default="print,get", help="how to handle url-form POSTs; see \033[33m--help-urlform\033[0m")
|
820
|
+
ap2.add_argument("--wintitle", metavar="TXT", type=u, default="cpp @ $pub", help="server terminal title, for example [\033[32m$ip-10.1.2.\033[0m] or [\033[32m$ip-]")
|
821
821
|
ap2.add_argument("--name", metavar="TXT", type=u, default=srvname, help="server name (displayed topleft in browser and in mDNS)")
|
822
822
|
ap2.add_argument("--license", action="store_true", help="show licenses and exit")
|
823
823
|
ap2.add_argument("--version", action="store_true", help="show versions and exit")
|
@@ -837,12 +837,12 @@ def add_qr(ap, tty):
|
|
837
837
|
|
838
838
|
def add_upload(ap):
|
839
839
|
ap2 = ap.add_argument_group('upload options')
|
840
|
-
ap2.add_argument("--dotpart", action="store_true", help="dotfile incomplete uploads, hiding them from clients unless -ed")
|
840
|
+
ap2.add_argument("--dotpart", action="store_true", help="dotfile incomplete uploads, hiding them from clients unless \033[33m-ed\033[0m")
|
841
841
|
ap2.add_argument("--plain-ip", action="store_true", help="when avoiding filename collisions by appending the uploader's ip to the filename: append the plaintext ip instead of salting and hashing the ip")
|
842
|
-
ap2.add_argument("--unpost", metavar="SEC", type=int, default=3600*12, help="grace period where uploads can be deleted by the uploader, even without delete permissions; 0=disabled")
|
842
|
+
ap2.add_argument("--unpost", metavar="SEC", type=int, default=3600*12, help="grace period where uploads can be deleted by the uploader, even without delete permissions; 0=disabled, default=12h")
|
843
843
|
ap2.add_argument("--blank-wt", metavar="SEC", type=int, default=300, help="file write grace period (any client can write to a blank file last-modified more recently than \033[33mSEC\033[0m seconds ago)")
|
844
|
-
ap2.add_argument("--reg-cap", metavar="N", type=int, default=38400, help="max number of uploads to keep in memory when running without -e2d; roughly 1 MiB RAM per 600")
|
845
|
-
ap2.add_argument("--no-fpool", action="store_true", help="disable file-handle pooling -- instead, repeatedly close and reopen files during upload (
|
844
|
+
ap2.add_argument("--reg-cap", metavar="N", type=int, default=38400, help="max number of uploads to keep in memory when running without \033[33m-e2d\033[0m; roughly 1 MiB RAM per 600")
|
845
|
+
ap2.add_argument("--no-fpool", action="store_true", help="disable file-handle pooling -- instead, repeatedly close and reopen files during upload (bad idea to enable this on windows and/or cow filesystems)")
|
846
846
|
ap2.add_argument("--use-fpool", action="store_true", help="force file-handle pooling, even when it might be dangerous (multiprocessing, filesystems lacking sparse-files support, ...)")
|
847
847
|
ap2.add_argument("--hardlink", action="store_true", help="prefer hardlinks instead of symlinks when possible (within same filesystem) (volflag=hardlink)")
|
848
848
|
ap2.add_argument("--never-symlink", action="store_true", help="do not fallback to symlinks when a hardlink cannot be made (volflag=neversymlink)")
|
@@ -852,7 +852,7 @@ def add_upload(ap):
|
|
852
852
|
ap2.add_argument("--snap-wri", metavar="SEC", type=int, default=300, help="write upload state to ./hist/up2k.snap every \033[33mSEC\033[0m seconds; allows resuming incomplete uploads after a server crash")
|
853
853
|
ap2.add_argument("--snap-drop", metavar="MIN", type=float, default=1440, help="forget unfinished uploads after \033[33mMIN\033[0m minutes; impossible to resume them after that (360=6h, 1440=24h)")
|
854
854
|
ap2.add_argument("--u2ts", metavar="TXT", type=u, default="c", help="how to timestamp uploaded files; [\033[32mc\033[0m]=client-last-modified, [\033[32mu\033[0m]=upload-time, [\033[32mfc\033[0m]=force-c, [\033[32mfu\033[0m]=force-u (volflag=u2ts)")
|
855
|
-
ap2.add_argument("--rand", action="store_true", help="force randomized filenames, --nrand chars long (volflag=rand)")
|
855
|
+
ap2.add_argument("--rand", action="store_true", help="force randomized filenames, \033[33m--nrand\033[0m chars long (volflag=rand)")
|
856
856
|
ap2.add_argument("--nrand", metavar="NUM", type=int, default=9, help="randomized filenames length (volflag=nrand)")
|
857
857
|
ap2.add_argument("--magic", action="store_true", help="enable filetype detection on nameless uploads (volflag=magic)")
|
858
858
|
ap2.add_argument("--df", metavar="GiB", type=float, default=0, help="ensure \033[33mGiB\033[0m free disk space by rejecting upload requests")
|
@@ -866,12 +866,12 @@ def add_network(ap):
|
|
866
866
|
ap2 = ap.add_argument_group('network options')
|
867
867
|
ap2.add_argument("-i", metavar="IP", type=u, default="::", help="ip to bind (comma-sep.), default: all IPv4 and IPv6")
|
868
868
|
ap2.add_argument("-p", metavar="PORT", type=u, default="3923", help="ports to bind (comma/range)")
|
869
|
-
ap2.add_argument("--ll", action="store_true", help="include link-local IPv4/IPv6 even if the NIC has routable IPs (breaks some
|
870
|
-
ap2.add_argument("--rproxy", metavar="DEPTH", type=int, default=1, help="which ip to
|
869
|
+
ap2.add_argument("--ll", action="store_true", help="include link-local IPv4/IPv6 in mDNS replies, even if the NIC has routable IPs (breaks some mDNS clients)")
|
870
|
+
ap2.add_argument("--rproxy", metavar="DEPTH", type=int, default=1, help="which ip to associate clients with; [\033[32m0\033[0m]=tcp, [\033[32m1\033[0m]=origin (first x-fwd, unsafe), [\033[32m2\033[0m]=outermost-proxy, [\033[32m3\033[0m]=second-proxy, [\033[32m-1\033[0m]=closest-proxy")
|
871
871
|
ap2.add_argument("--xff-hdr", metavar="NAME", type=u, default="x-forwarded-for", help="if reverse-proxied, which http header to read the client's real ip from (argument must be lowercase, but not the actual header)")
|
872
|
-
ap2.add_argument("--xff-src", metavar="IP", type=u, default="127., ::1", help="comma-separated list of trusted reverse-proxy IPs; only accept the real-ip header (--xff-hdr) if the incoming connection is from an IP starting with either of these. Can be disabled with [\033[32many\033[0m] if you are behind cloudflare (or similar) and are using --xff-hdr=cf-connecting-ip (or similar)")
|
872
|
+
ap2.add_argument("--xff-src", metavar="IP", type=u, default="127., ::1", help="comma-separated list of trusted reverse-proxy IPs; only accept the real-ip header (\033[33m--xff-hdr\033[0m) if the incoming connection is from an IP starting with either of these. Can be disabled with [\033[32many\033[0m] if you are behind cloudflare (or similar) and are using \033[32m--xff-hdr=cf-connecting-ip\033[0m (or similar)")
|
873
873
|
ap2.add_argument("--ipa", metavar="PREFIX", type=u, default="", help="only accept connections from IP-addresses starting with \033[33mPREFIX\033[0m; example: [\033[32m127., 10.89., 192.168.\033[0m]")
|
874
|
-
ap2.add_argument("--rp-loc", metavar="PATH", type=u, default="", help="if reverse-proxying on a location instead of a dedicated domain/subdomain, provide the base location here
|
874
|
+
ap2.add_argument("--rp-loc", metavar="PATH", type=u, default="", help="if reverse-proxying on a location instead of a dedicated domain/subdomain, provide the base location here; example: [\033[32m/foo/bar\033[0m]")
|
875
875
|
if ANYWIN:
|
876
876
|
ap2.add_argument("--reuseaddr", action="store_true", help="set reuseaddr on listening sockets on windows; allows rapid restart of copyparty at the expense of being able to accidentally start multiple instances")
|
877
877
|
else:
|
@@ -900,7 +900,7 @@ def add_cert(ap, cert_path):
|
|
900
900
|
ap2 = ap.add_argument_group('TLS certificate generator options')
|
901
901
|
ap2.add_argument("--no-crt", action="store_true", help="disable automatic certificate creation")
|
902
902
|
ap2.add_argument("--crt-ns", metavar="N,N", type=u, default="", help="comma-separated list of FQDNs (domains) to add into the certificate")
|
903
|
-
ap2.add_argument("--crt-exact", action="store_true", help="do not add wildcard entries for each --crt-ns")
|
903
|
+
ap2.add_argument("--crt-exact", action="store_true", help="do not add wildcard entries for each \033[33m--crt-ns\033[0m")
|
904
904
|
ap2.add_argument("--crt-noip", action="store_true", help="do not add autodetected IP addresses into cert")
|
905
905
|
ap2.add_argument("--crt-nolo", action="store_true", help="do not add 127.0.0.1 / localhost into cert")
|
906
906
|
ap2.add_argument("--crt-nohn", action="store_true", help="do not add mDNS names / hostname into cert")
|
@@ -911,7 +911,7 @@ def add_cert(ap, cert_path):
|
|
911
911
|
ap2.add_argument("--crt-cnc", metavar="TXT", type=u, default="--crt-cn", help="override CA name")
|
912
912
|
ap2.add_argument("--crt-cns", metavar="TXT", type=u, default="--crt-cn cpp", help="override server-cert name")
|
913
913
|
ap2.add_argument("--crt-back", metavar="HRS", type=float, default=72, help="backdate in hours")
|
914
|
-
ap2.add_argument("--crt-alg", metavar="S-N", type=u, default="ecdsa-256", help="algorithm and keysize; one of these:
|
914
|
+
ap2.add_argument("--crt-alg", metavar="S-N", type=u, default="ecdsa-256", help="algorithm and keysize; one of these: \033[32mecdsa-256 rsa-4096 rsa-2048\033[0m")
|
915
915
|
|
916
916
|
|
917
917
|
def add_auth(ap):
|
@@ -926,19 +926,19 @@ def add_zeroconf(ap):
|
|
926
926
|
ap2.add_argument("--z-off", metavar="NETS", type=u, default="", help="disable zeroconf on the comma-separated list of subnets and/or interface names/indexes")
|
927
927
|
ap2.add_argument("--z-chk", metavar="SEC", type=int, default=10, help="check for network changes every \033[33mSEC\033[0m seconds (0=disable)")
|
928
928
|
ap2.add_argument("-zv", action="store_true", help="verbose all zeroconf backends")
|
929
|
-
ap2.add_argument("--mc-hop", metavar="SEC", type=int, default=0, help="rejoin multicast groups every \033[33mSEC\033[0m seconds (workaround for some switches/routers which cause mDNS to suddenly stop working after some time); try [\033[32m300\033[0m] or [\033[32m180\033[0m]")
|
929
|
+
ap2.add_argument("--mc-hop", metavar="SEC", type=int, default=0, help="rejoin multicast groups every \033[33mSEC\033[0m seconds (workaround for some switches/routers which cause mDNS to suddenly stop working after some time); try [\033[32m300\033[0m] or [\033[32m180\033[0m]\n └─note: can be due to firewalls; make sure UDP port 5353 is open in both directions (on clients too)")
|
930
930
|
|
931
931
|
|
932
932
|
def add_zc_mdns(ap):
|
933
933
|
ap2 = ap.add_argument_group("Zeroconf-mDNS options; also see --help-zm")
|
934
934
|
ap2.add_argument("--zm", action="store_true", help="announce the enabled protocols over mDNS (multicast DNS-SD) -- compatible with KDE, gnome, macOS, ...")
|
935
|
-
ap2.add_argument("--zm-on", metavar="NETS", type=u, default="", help="enable
|
936
|
-
ap2.add_argument("--zm-off", metavar="NETS", type=u, default="", help="disable
|
935
|
+
ap2.add_argument("--zm-on", metavar="NETS", type=u, default="", help="enable mDNS ONLY on the comma-separated list of subnets and/or interface names/indexes")
|
936
|
+
ap2.add_argument("--zm-off", metavar="NETS", type=u, default="", help="disable mDNS on the comma-separated list of subnets and/or interface names/indexes")
|
937
937
|
ap2.add_argument("--zm4", action="store_true", help="IPv4 only -- try this if some clients can't connect")
|
938
938
|
ap2.add_argument("--zm6", action="store_true", help="IPv6 only")
|
939
939
|
ap2.add_argument("--zmv", action="store_true", help="verbose mdns")
|
940
940
|
ap2.add_argument("--zmvv", action="store_true", help="verboser mdns")
|
941
|
-
ap2.add_argument("--zms", metavar="dhf", type=u, default="", help="list of services to announce -- d=webdav h=http f=ftp s=smb -- lowercase=plaintext uppercase=TLS -- default: all enabled services except http/https (\033[32mDdfs\033[0m if \033[33m--ftp\033[0m and \033[33m--smb\033[0m is set)")
|
941
|
+
ap2.add_argument("--zms", metavar="dhf", type=u, default="", help="list of services to announce -- d=webdav h=http f=ftp s=smb -- lowercase=plaintext uppercase=TLS -- default: all enabled services except http/https (\033[32mDdfs\033[0m if \033[33m--ftp\033[0m and \033[33m--smb\033[0m is set, \033[32mDd\033[0m otherwise)")
|
942
942
|
ap2.add_argument("--zm-ld", metavar="PATH", type=u, default="", help="link a specific folder for webdav shares")
|
943
943
|
ap2.add_argument("--zm-lh", metavar="PATH", type=u, default="", help="link a specific folder for http shares")
|
944
944
|
ap2.add_argument("--zm-lf", metavar="PATH", type=u, default="", help="link a specific folder for ftp shares")
|
@@ -946,14 +946,14 @@ def add_zc_mdns(ap):
|
|
946
946
|
ap2.add_argument("--zm-mnic", action="store_true", help="merge NICs which share subnets; assume that same subnet means same network")
|
947
947
|
ap2.add_argument("--zm-msub", action="store_true", help="merge subnets on each NIC -- always enabled for ipv6 -- reduces network load, but gnome-gvfs clients may stop working, and clients cannot be in subnets that the server is not")
|
948
948
|
ap2.add_argument("--zm-noneg", action="store_true", help="disable NSEC replies -- try this if some clients don't see copyparty")
|
949
|
-
ap2.add_argument("--zm-spam", metavar="SEC", type=float, default=0, help="send unsolicited announce every \033[33mSEC\033[0m; useful if clients have IPs in a subnet which doesn't overlap with the server")
|
949
|
+
ap2.add_argument("--zm-spam", metavar="SEC", type=float, default=0, help="send unsolicited announce every \033[33mSEC\033[0m; useful if clients have IPs in a subnet which doesn't overlap with the server, or to avoid some firewall issues")
|
950
950
|
|
951
951
|
|
952
952
|
def add_zc_ssdp(ap):
|
953
953
|
ap2 = ap.add_argument_group("Zeroconf-SSDP options")
|
954
954
|
ap2.add_argument("--zs", action="store_true", help="announce the enabled protocols over SSDP -- compatible with Windows")
|
955
|
-
ap2.add_argument("--zs-on", metavar="NETS", type=u, default="", help="enable
|
956
|
-
ap2.add_argument("--zs-off", metavar="NETS", type=u, default="", help="disable
|
955
|
+
ap2.add_argument("--zs-on", metavar="NETS", type=u, default="", help="enable SSDP ONLY on the comma-separated list of subnets and/or interface names/indexes")
|
956
|
+
ap2.add_argument("--zs-off", metavar="NETS", type=u, default="", help="disable SSDP on the comma-separated list of subnets and/or interface names/indexes")
|
957
957
|
ap2.add_argument("--zsv", action="store_true", help="verbose SSDP")
|
958
958
|
ap2.add_argument("--zsl", metavar="PATH", type=u, default="/?hc", help="location to include in the url (or a complete external URL), for example [\033[32mpriv/?pw=hunter2\033[0m] (goes directly to /priv/ with password hunter2) or [\033[32m?hc=priv&pw=hunter2\033[0m] (shows mounting options for /priv/ with password)")
|
959
959
|
ap2.add_argument("--zsid", metavar="UUID", type=u, default=zsid, help="USN (device identifier) to announce")
|
@@ -982,7 +982,7 @@ def add_webdav(ap):
|
|
982
982
|
|
983
983
|
def add_smb(ap):
|
984
984
|
ap2 = ap.add_argument_group('SMB/CIFS options')
|
985
|
-
ap2.add_argument("--smb", action="store_true", help="enable smb (read-only) -- this requires running copyparty as root on linux and macos unless --smb-port is set above 1024 and your OS does port-forwarding from 445 to that.\n\033[1;31mWARNING:\033[0m this protocol is
|
985
|
+
ap2.add_argument("--smb", action="store_true", help="enable smb (read-only) -- this requires running copyparty as root on linux and macos unless \033[33m--smb-port\033[0m is set above 1024 and your OS does port-forwarding from 445 to that.\n\033[1;31mWARNING:\033[0m this protocol is DANGEROUS and buggy! Never expose to the internet!")
|
986
986
|
ap2.add_argument("--smbw", action="store_true", help="enable write support (please dont)")
|
987
987
|
ap2.add_argument("--smb1", action="store_true", help="disable SMBv2, only enable SMBv1 (CIFS)")
|
988
988
|
ap2.add_argument("--smb-port", metavar="PORT", type=int, default=445, help="port to listen on -- if you change this value, you must NAT from TCP:445 to this port using iptables or similar")
|
@@ -996,9 +996,9 @@ def add_smb(ap):
|
|
996
996
|
|
997
997
|
def add_handlers(ap):
|
998
998
|
ap2 = ap.add_argument_group('handlers (see --help-handlers)')
|
999
|
-
ap2.add_argument("--on404", metavar="PY", type=u, action="append", help="handle 404s by executing
|
1000
|
-
ap2.add_argument("--on403", metavar="PY", type=u, action="append", help="handle 403s by executing
|
1001
|
-
ap2.add_argument("--hot-handlers", action="store_true", help="
|
999
|
+
ap2.add_argument("--on404", metavar="PY", type=u, action="append", help="handle 404s by executing \033[33mPY\033[0m file")
|
1000
|
+
ap2.add_argument("--on403", metavar="PY", type=u, action="append", help="handle 403s by executing \033[33mPY\033[0m file")
|
1001
|
+
ap2.add_argument("--hot-handlers", action="store_true", help="recompile handlers on each request -- expensive but convenient when hacking on stuff")
|
1002
1002
|
|
1003
1003
|
|
1004
1004
|
def add_hooks(ap):
|
@@ -1033,17 +1033,17 @@ def add_yolo(ap):
|
|
1033
1033
|
def add_optouts(ap):
|
1034
1034
|
ap2 = ap.add_argument_group('opt-outs')
|
1035
1035
|
ap2.add_argument("-nw", action="store_true", help="never write anything to disk (debug/benchmark)")
|
1036
|
-
ap2.add_argument("--keep-qem", action="store_true", help="do not disable quick-edit-mode on windows (it is disabled to avoid accidental text selection
|
1036
|
+
ap2.add_argument("--keep-qem", action="store_true", help="do not disable quick-edit-mode on windows (it is disabled to avoid accidental text selection in the terminal window, as this would pause execution)")
|
1037
1037
|
ap2.add_argument("--no-dav", action="store_true", help="disable webdav support")
|
1038
1038
|
ap2.add_argument("--no-del", action="store_true", help="disable delete operations")
|
1039
1039
|
ap2.add_argument("--no-mv", action="store_true", help="disable move/rename operations")
|
1040
|
-
ap2.add_argument("-nth", action="store_true", help="no title hostname; don't show --name in <title>")
|
1040
|
+
ap2.add_argument("-nth", action="store_true", help="no title hostname; don't show \033[33m--name\033[0m in <title>")
|
1041
1041
|
ap2.add_argument("-nih", action="store_true", help="no info hostname -- don't show in UI")
|
1042
1042
|
ap2.add_argument("-nid", action="store_true", help="no info disk-usage -- don't show in UI")
|
1043
1043
|
ap2.add_argument("-nb", action="store_true", help="no powered-by-copyparty branding in UI")
|
1044
1044
|
ap2.add_argument("--no-zip", action="store_true", help="disable download as zip/tar")
|
1045
1045
|
ap2.add_argument("--no-tarcmp", action="store_true", help="disable download as compressed tar (?tar=gz, ?tar=bz2, ?tar=xz, ?tar=gz:9, ...)")
|
1046
|
-
ap2.add_argument("--no-lifetime", action="store_true", help="
|
1046
|
+
ap2.add_argument("--no-lifetime", action="store_true", help="do not allow clients (or server config) to schedule an upload to be deleted after a given time")
|
1047
1047
|
|
1048
1048
|
|
1049
1049
|
def add_safety(ap):
|
@@ -1051,36 +1051,36 @@ def add_safety(ap):
|
|
1051
1051
|
ap2.add_argument("-s", action="count", default=0, help="increase safety: Disable thumbnails / potentially dangerous software (ffmpeg/pillow/vips), hide partial uploads, avoid crawlers.\n └─Alias of\033[32m --dotpart --no-thumb --no-mtag-ff --no-robots --force-js")
|
1052
1052
|
ap2.add_argument("-ss", action="store_true", help="further increase safety: Prevent js-injection, accidental move/delete, broken symlinks, webdav, 404 on 403, ban on excessive 404s.\n └─Alias of\033[32m -s --unpost=0 --no-del --no-mv --hardlink --vague-403 -nih")
|
1053
1053
|
ap2.add_argument("-sss", action="store_true", help="further increase safety: Enable logging to disk, scan for dangerous symlinks.\n └─Alias of\033[32m -ss --no-dav --no-logues --no-readme -lo=cpp-%%Y-%%m%%d-%%H%%M%%S.txt.xz --ls=**,*,ln,p,r")
|
1054
|
-
ap2.add_argument("--ls", metavar="U[,V[,F]]", type=u, help="do a sanity/safety check of all volumes on startup; arguments \033[33mUSER\033[0m,\033[33mVOL\033[0m,\033[33mFLAGS\033[0m; example [\033[32m**,*,ln,p,r\033[0m]")
|
1054
|
+
ap2.add_argument("--ls", metavar="U[,V[,F]]", type=u, help="do a sanity/safety check of all volumes on startup; arguments \033[33mUSER\033[0m,\033[33mVOL\033[0m,\033[33mFLAGS\033[0m (see \033[33m--help-ls\033[0m); example [\033[32m**,*,ln,p,r\033[0m]")
|
1055
1055
|
ap2.add_argument("--xvol", action="store_true", help="never follow symlinks leaving the volume root, unless the link is into another volume where the user has similar access (volflag=xvol)")
|
1056
1056
|
ap2.add_argument("--xdev", action="store_true", help="stay within the filesystem of the volume root; do not descend into other devices (symlink or bind-mount to another HDD, ...) (volflag=xdev)")
|
1057
1057
|
ap2.add_argument("--no-dot-mv", action="store_true", help="disallow moving dotfiles; makes it impossible to move folders containing dotfiles")
|
1058
|
-
ap2.add_argument("--no-dot-ren", action="store_true", help="disallow renaming dotfiles; makes it impossible to
|
1058
|
+
ap2.add_argument("--no-dot-ren", action="store_true", help="disallow renaming dotfiles; makes it impossible to turn something into a dotfile")
|
1059
1059
|
ap2.add_argument("--no-logues", action="store_true", help="disable rendering .prologue/.epilogue.html into directory listings")
|
1060
1060
|
ap2.add_argument("--no-readme", action="store_true", help="disable rendering readme.md into directory listings")
|
1061
1061
|
ap2.add_argument("--vague-403", action="store_true", help="send 404 instead of 403 (security through ambiguity, very enterprise)")
|
1062
|
-
ap2.add_argument("--force-js", action="store_true", help="don't send folder listings as HTML, force clients to use the embedded json instead -- slight protection against misbehaving search engines which ignore --no-robots")
|
1062
|
+
ap2.add_argument("--force-js", action="store_true", help="don't send folder listings as HTML, force clients to use the embedded json instead -- slight protection against misbehaving search engines which ignore \033[33m--no-robots\033[0m")
|
1063
1063
|
ap2.add_argument("--no-robots", action="store_true", help="adds http and html headers asking search engines to not index anything (volflag=norobots)")
|
1064
1064
|
ap2.add_argument("--logout", metavar="H", type=float, default="8086", help="logout clients after \033[33mH\033[0m hours of inactivity; [\033[32m0.0028\033[0m]=10sec, [\033[32m0.1\033[0m]=6min, [\033[32m24\033[0m]=day, [\033[32m168\033[0m]=week, [\033[32m720\033[0m]=month, [\033[32m8760\033[0m]=year)")
|
1065
1065
|
ap2.add_argument("--ban-pw", metavar="N,W,B", type=u, default="9,60,1440", help="more than \033[33mN\033[0m wrong passwords in \033[33mW\033[0m minutes = ban for \033[33mB\033[0m minutes; disable with [\033[32mno\033[0m]")
|
1066
1066
|
ap2.add_argument("--ban-404", metavar="N,W,B", type=u, default="50,60,1440", help="hitting more than \033[33mN\033[0m 404's in \033[33mW\033[0m minutes = ban for \033[33mB\033[0m minutes; only affects users who cannot see directory listings because their access is either g/G/h")
|
1067
1067
|
ap2.add_argument("--ban-403", metavar="N,W,B", type=u, default="9,2,1440", help="hitting more than \033[33mN\033[0m 403's in \033[33mW\033[0m minutes = ban for \033[33mB\033[0m minutes; [\033[32m1440\033[0m]=day, [\033[32m10080\033[0m]=week, [\033[32m43200\033[0m]=month")
|
1068
|
-
ap2.add_argument("--ban-422", metavar="N,W,B", type=u, default="9,2,1440", help="hitting more than \033[33mN\033[0m 422's in \033[33mW\033[0m minutes = ban for \033[33mB\033[0m minutes (
|
1069
|
-
ap2.add_argument("--ban-url", metavar="N,W,B", type=u, default="9,2,1440", help="hitting more than \033[33mN\033[0m sus URL's in \033[33mW\033[0m minutes = ban for \033[33mB\033[0m minutes; applies only to
|
1068
|
+
ap2.add_argument("--ban-422", metavar="N,W,B", type=u, default="9,2,1440", help="hitting more than \033[33mN\033[0m 422's in \033[33mW\033[0m minutes = ban for \033[33mB\033[0m minutes (invalid requests, attempted exploits ++)")
|
1069
|
+
ap2.add_argument("--ban-url", metavar="N,W,B", type=u, default="9,2,1440", help="hitting more than \033[33mN\033[0m sus URL's in \033[33mW\033[0m minutes = ban for \033[33mB\033[0m minutes; applies only to permissions g/G/h (decent replacement for \033[33m--ban-404\033[0m if that can't be used)")
|
1070
1070
|
ap2.add_argument("--sus-urls", metavar="R", type=u, default=r"\.php$|(^|/)wp-(admin|content|includes)/", help="URLs which are considered sus / eligible for banning; disable with blank or [\033[32mno\033[0m]")
|
1071
1071
|
ap2.add_argument("--nonsus-urls", metavar="R", type=u, default=r"^(favicon\.ico|robots\.txt)$|^apple-touch-icon|^\.well-known", help="harmless URLs ignored from 404-bans; disable with blank or [\033[32mno\033[0m]")
|
1072
1072
|
ap2.add_argument("--aclose", metavar="MIN", type=int, default=10, help="if a client maxes out the server connection limit, downgrade it from connection:keep-alive to connection:close for \033[33mMIN\033[0m minutes (and also kill its active connections) -- disable with 0")
|
1073
1073
|
ap2.add_argument("--loris", metavar="B", type=int, default=60, help="if a client maxes out the server connection limit without sending headers, ban it for \033[33mB\033[0m minutes; disable with [\033[32m0\033[0m]")
|
1074
1074
|
ap2.add_argument("--acao", metavar="V[,V]", type=u, default="*", help="Access-Control-Allow-Origin; list of origins (domains/IPs without port) to accept requests from; [\033[32mhttps://1.2.3.4\033[0m]. Default [\033[32m*\033[0m] allows requests from all sites but removes cookies and http-auth; only ?pw=hunter2 survives")
|
1075
|
-
ap2.add_argument("--acam", metavar="V[,V]", type=u, default="GET,HEAD", help="Access-Control-Allow-Methods; list of methods to accept from offsite ('*' behaves like
|
1075
|
+
ap2.add_argument("--acam", metavar="V[,V]", type=u, default="GET,HEAD", help="Access-Control-Allow-Methods; list of methods to accept from offsite ('*' behaves like \033[33m--acao\033[0m's description)")
|
1076
1076
|
|
1077
1077
|
|
1078
1078
|
def add_salt(ap, fk_salt, ah_salt):
|
1079
1079
|
ap2 = ap.add_argument_group('salting options')
|
1080
|
-
ap2.add_argument("--ah-alg", metavar="ALG", type=u, default="none", help="account-pw hashing algorithm; one of these, best to worst:
|
1081
|
-
ap2.add_argument("--ah-salt", metavar="SALT", type=u, default=ah_salt, help="account-pw salt; ignored if --ah-alg is none (default)")
|
1080
|
+
ap2.add_argument("--ah-alg", metavar="ALG", type=u, default="none", help="account-pw hashing algorithm; one of these, best to worst: \033[32margon2 scrypt sha2 none\033[0m (each optionally followed by alg-specific comma-sep. config)")
|
1081
|
+
ap2.add_argument("--ah-salt", metavar="SALT", type=u, default=ah_salt, help="account-pw salt; ignored if \033[33m--ah-alg\033[0m is none (default)")
|
1082
1082
|
ap2.add_argument("--ah-gen", metavar="PW", type=u, default="", help="generate hashed password for \033[33mPW\033[0m, or read passwords from STDIN if \033[33mPW\033[0m is [\033[32m-\033[0m]")
|
1083
|
-
ap2.add_argument("--ah-cli", action="store_true", help="interactive shell which hashes passwords without ever storing or displaying the original passwords")
|
1083
|
+
ap2.add_argument("--ah-cli", action="store_true", help="launch an interactive shell which hashes passwords without ever storing or displaying the original passwords")
|
1084
1084
|
ap2.add_argument("--fk-salt", metavar="SALT", type=u, default=fk_salt, help="per-file accesskey salt; used to generate unpredictable URLs for hidden files")
|
1085
1085
|
ap2.add_argument("--warksalt", metavar="SALT", type=u, default="hunter2", help="up2k file-hash salt; serves no purpose, no reason to change this (but delete all databases if you do)")
|
1086
1086
|
|
@@ -1094,8 +1094,8 @@ def add_shutdown(ap):
|
|
1094
1094
|
|
1095
1095
|
def add_logging(ap):
|
1096
1096
|
ap2 = ap.add_argument_group('logging options')
|
1097
|
-
ap2.add_argument("-q", action="store_true", help="quiet")
|
1098
|
-
ap2.add_argument("-lo", metavar="PATH", type=u, help="logfile, example: \033[32mcpp-%%Y-%%m%%d-%%H%%M%%S.txt.xz")
|
1097
|
+
ap2.add_argument("-q", action="store_true", help="quiet; disable most STDOUT messages")
|
1098
|
+
ap2.add_argument("-lo", metavar="PATH", type=u, help="logfile, example: \033[32mcpp-%%Y-%%m%%d-%%H%%M%%S.txt.xz\033[0m (NB: some errors may appear on STDOUT only)")
|
1099
1099
|
ap2.add_argument("--no-ansi", action="store_true", default=not VT100, help="disable colors; same as environment-variable NO_COLOR")
|
1100
1100
|
ap2.add_argument("--ansi", action="store_true", help="force colors; overrides environment-variable NO_COLOR")
|
1101
1101
|
ap2.add_argument("--no-logflush", action="store_true", help="don't flush the logfile after each write; tiny bit faster")
|
@@ -1104,7 +1104,7 @@ def add_logging(ap):
|
|
1104
1104
|
ap2.add_argument("--log-badpwd", metavar="N", type=int, default=1, help="log failed login attempt passwords: 0=terse, 1=plaintext, 2=hashed")
|
1105
1105
|
ap2.add_argument("--log-conn", action="store_true", help="debug: print tcp-server msgs")
|
1106
1106
|
ap2.add_argument("--log-htp", action="store_true", help="debug: print http-server threadpool scaling")
|
1107
|
-
ap2.add_argument("--ihead", metavar="HEADER", type=u, action='append', help="
|
1107
|
+
ap2.add_argument("--ihead", metavar="HEADER", type=u, action='append', help="print request \033[33mHEADER\033[0m; [\033[32m*\033[0m]=all")
|
1108
1108
|
ap2.add_argument("--lf-url", metavar="RE", type=u, default=r"^/\.cpr/|\?th=[wj]$|/\.(_|ql_|DS_Store$|localized$)", help="dont log URLs matching regex \033[33mRE\033[0m")
|
1109
1109
|
|
1110
1110
|
|
@@ -1123,16 +1123,16 @@ def add_thumbnail(ap):
|
|
1123
1123
|
ap2.add_argument("--th-size", metavar="WxH", default="320x256", help="thumbnail res (volflag=thsize)")
|
1124
1124
|
ap2.add_argument("--th-mt", metavar="CORES", type=int, default=CORES, help="num cpu cores to use for generating thumbnails")
|
1125
1125
|
ap2.add_argument("--th-convt", metavar="SEC", type=float, default=60, help="conversion timeout in seconds (volflag=convt)")
|
1126
|
-
ap2.add_argument("--th-no-crop", action="store_true", help="dynamic height; show full image by default (volflag=nocrop)")
|
1126
|
+
ap2.add_argument("--th-no-crop", action="store_true", help="dynamic height; show full image by default (client can override in UI) (volflag=nocrop)")
|
1127
1127
|
ap2.add_argument("--th-dec", metavar="LIBS", default="vips,pil,ff", help="image decoders, in order of preference")
|
1128
1128
|
ap2.add_argument("--th-no-jpg", action="store_true", help="disable jpg output")
|
1129
1129
|
ap2.add_argument("--th-no-webp", action="store_true", help="disable webp output")
|
1130
|
-
ap2.add_argument("--th-ff-jpg", action="store_true", help="force jpg output for video thumbs")
|
1131
|
-
ap2.add_argument("--th-ff-swr", action="store_true", help="use swresample instead of soxr for audio thumbs")
|
1130
|
+
ap2.add_argument("--th-ff-jpg", action="store_true", help="force jpg output for video thumbs (avoids issues on some FFmpeg builds)")
|
1131
|
+
ap2.add_argument("--th-ff-swr", action="store_true", help="use swresample instead of soxr for audio thumbs (faster, lower accuracy, avoids issues on some FFmpeg builds)")
|
1132
1132
|
ap2.add_argument("--th-poke", metavar="SEC", type=int, default=300, help="activity labeling cooldown -- avoids doing keepalive pokes (updating the mtime) on thumbnail folders more often than \033[33mSEC\033[0m seconds")
|
1133
1133
|
ap2.add_argument("--th-clean", metavar="SEC", type=int, default=43200, help="cleanup interval; 0=disabled")
|
1134
|
-
ap2.add_argument("--th-maxage", metavar="SEC", type=int, default=604800, help="max folder age -- folders which haven't been poked for longer than --th-poke seconds will get deleted every --th-clean seconds")
|
1135
|
-
ap2.add_argument("--th-covers", metavar="N,N", type=u, default="folder.png,folder.jpg,cover.png,cover.jpg", help="folder thumbnails to stat/look for; enabling -e2d will make these case-insensitive, and also automatically select thumbnails for all folders that contain pics, even if none match this pattern")
|
1134
|
+
ap2.add_argument("--th-maxage", metavar="SEC", type=int, default=604800, help="max folder age -- folders which haven't been poked for longer than \033[33m--th-poke\033[0m seconds will get deleted every \033[33m--th-clean\033[0m seconds")
|
1135
|
+
ap2.add_argument("--th-covers", metavar="N,N", type=u, default="folder.png,folder.jpg,cover.png,cover.jpg", help="folder thumbnails to stat/look for; enabling \033[33m-e2d\033[0m will make these case-insensitive, and also automatically select thumbnails for all folders that contain pics, even if none match this pattern")
|
1136
1136
|
# https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html
|
1137
1137
|
# https://github.com/libvips/libvips
|
1138
1138
|
# ffmpeg -hide_banner -demuxers | awk '/^ D /{print$2}' | while IFS= read -r x; do ffmpeg -hide_banner -h demuxer=$x; done | grep -E '^Demuxer |extensions:'
|
@@ -1153,8 +1153,8 @@ def add_transcoding(ap):
|
|
1153
1153
|
def add_db_general(ap, hcores):
|
1154
1154
|
ap2 = ap.add_argument_group('general db options')
|
1155
1155
|
ap2.add_argument("-e2d", action="store_true", help="enable up2k database, making files searchable + enables upload deduplication")
|
1156
|
-
ap2.add_argument("-e2ds", action="store_true", help="scan writable folders for new files on startup; sets -e2d")
|
1157
|
-
ap2.add_argument("-e2dsa", action="store_true", help="scans all folders on startup; sets -e2ds")
|
1156
|
+
ap2.add_argument("-e2ds", action="store_true", help="scan writable folders for new files on startup; sets \033[33m-e2d\033[0m")
|
1157
|
+
ap2.add_argument("-e2dsa", action="store_true", help="scans all folders on startup; sets \033[33m-e2ds\033[0m")
|
1158
1158
|
ap2.add_argument("-e2v", action="store_true", help="verify file integrity; rehash all files and compare with db")
|
1159
1159
|
ap2.add_argument("-e2vu", action="store_true", help="on hash mismatch: update the database with the new hash")
|
1160
1160
|
ap2.add_argument("-e2vp", action="store_true", help="on hash mismatch: panic and quit copyparty")
|
@@ -1163,11 +1163,11 @@ def add_db_general(ap, hcores):
|
|
1163
1163
|
ap2.add_argument("--no-idx", metavar="PTN", type=u, help="regex: disable indexing of matching absolute-filesystem-paths during e2ds folder scans (volflag=noidx)")
|
1164
1164
|
ap2.add_argument("--no-dhash", action="store_true", help="disable rescan acceleration; do full database integrity check -- makes the db ~5%% smaller and bootup/rescans 3~10x slower")
|
1165
1165
|
ap2.add_argument("--re-dhash", action="store_true", help="rebuild the cache if it gets out of sync (for example crash on startup during metadata scanning)")
|
1166
|
-
ap2.add_argument("--no-forget", action="store_true", help="never forget indexed files, even when deleted from disk -- makes it impossible to ever upload the same file twice (volflag=noforget)")
|
1167
|
-
ap2.add_argument("--dbd", metavar="PROFILE", default="wal", help="database durability profile; sets the tradeoff between robustness and speed, see --help-dbd (volflag=dbd)")
|
1166
|
+
ap2.add_argument("--no-forget", action="store_true", help="never forget indexed files, even when deleted from disk -- makes it impossible to ever upload the same file twice -- only useful for offloading uploads to a cloud service or something (volflag=noforget)")
|
1167
|
+
ap2.add_argument("--dbd", metavar="PROFILE", default="wal", help="database durability profile; sets the tradeoff between robustness and speed, see \033[33m--help-dbd\033[0m (volflag=dbd)")
|
1168
1168
|
ap2.add_argument("--xlink", action="store_true", help="on upload: check all volumes for dupes, not just the target volume (volflag=xlink)")
|
1169
1169
|
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")
|
1170
|
-
ap2.add_argument("--re-maxage", metavar="SEC", type=int, default=0, help="
|
1170
|
+
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)")
|
1171
1171
|
ap2.add_argument("--db-act", metavar="SEC", type=float, default=10, help="defer any scheduled volume reindexing until \033[33mSEC\033[0m seconds after last db write (uploads, renames, ...)")
|
1172
1172
|
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")
|
1173
1173
|
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")
|
@@ -1177,25 +1177,25 @@ def add_db_general(ap, hcores):
|
|
1177
1177
|
def add_db_metadata(ap):
|
1178
1178
|
ap2 = ap.add_argument_group('metadata db options')
|
1179
1179
|
ap2.add_argument("-e2t", action="store_true", help="enable metadata indexing; makes it possible to search for artist/title/codec/resolution/...")
|
1180
|
-
ap2.add_argument("-e2ts", action="store_true", help="scan
|
1181
|
-
ap2.add_argument("-e2tsr", action="store_true", help="delete all metadata from DB and do a full rescan; sets -e2ts")
|
1182
|
-
ap2.add_argument("--no-mutagen", action="store_true", help="use FFprobe for tags instead; will
|
1180
|
+
ap2.add_argument("-e2ts", action="store_true", help="scan newly discovered files for metadata on startup; sets \033[33m-e2t\033[0m")
|
1181
|
+
ap2.add_argument("-e2tsr", action="store_true", help="delete all metadata from DB and do a full rescan; sets \033[33m-e2ts\033[0m")
|
1182
|
+
ap2.add_argument("--no-mutagen", action="store_true", help="use FFprobe for tags instead; will detect more tags")
|
1183
1183
|
ap2.add_argument("--no-mtag-ff", action="store_true", help="never use FFprobe as tag reader; is probably safer")
|
1184
|
-
ap2.add_argument("--mtag-to", metavar="SEC", type=int, default=60, help="timeout for
|
1184
|
+
ap2.add_argument("--mtag-to", metavar="SEC", type=int, default=60, help="timeout for FFprobe tag-scan")
|
1185
1185
|
ap2.add_argument("--mtag-mt", metavar="CORES", type=int, default=CORES, help="num cpu cores to use for tag scanning")
|
1186
1186
|
ap2.add_argument("--mtag-v", action="store_true", help="verbose tag scanning; print errors from mtp subprocesses and such")
|
1187
|
-
ap2.add_argument("--mtag-vv", action="store_true", help="debug mtp settings and mutagen/
|
1187
|
+
ap2.add_argument("--mtag-vv", action="store_true", help="debug mtp settings and mutagen/FFprobe parsers")
|
1188
1188
|
ap2.add_argument("-mtm", metavar="M=t,t,t", type=u, action="append", help="add/replace metadata mapping")
|
1189
1189
|
ap2.add_argument("-mte", metavar="M,M,M", type=u, help="tags to index/display (comma-sep.); either an entire replacement list, or add/remove stuff on the default-list with +foo or /bar", default=DEF_MTE)
|
1190
|
-
ap2.add_argument("-mth", metavar="M,M,M", type=u, help="tags to hide by default (comma-sep.); assign/add/remove same as -mte", default=DEF_MTH)
|
1190
|
+
ap2.add_argument("-mth", metavar="M,M,M", type=u, help="tags to hide by default (comma-sep.); assign/add/remove same as \033[33m-mte\033[0m", default=DEF_MTH)
|
1191
1191
|
ap2.add_argument("-mtp", metavar="M=[f,]BIN", type=u, action="append", help="read tag \033[33mM\033[0m using program \033[33mBIN\033[0m to parse the file")
|
1192
1192
|
|
1193
1193
|
|
1194
1194
|
def add_txt(ap):
|
1195
1195
|
ap2 = ap.add_argument_group('textfile options')
|
1196
|
-
ap2.add_argument("-mcr", metavar="SEC", type=int, default=60, help="textfile editor
|
1196
|
+
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")
|
1197
1197
|
ap2.add_argument("-emp", action="store_true", help="enable markdown plugins -- neat but dangerous, big XSS risk")
|
1198
|
-
ap2.add_argument("--exp", action="store_true", help="enable textfile expansion -- replace {{self.ip}} and such; see --help-exp (volflag=exp)")
|
1198
|
+
ap2.add_argument("--exp", action="store_true", help="enable textfile expansion -- replace {{self.ip}} and such; see \033[33m--help-exp\033[0m (volflag=exp)")
|
1199
1199
|
ap2.add_argument("--exp-md", metavar="V,V,V", type=u, default=DEF_EXP, help="comma/space-separated list of placeholders to expand in markdown files; add/remove stuff on the default list with +hdr_foo or /vf.scan (volflag=exp_md)")
|
1200
1200
|
ap2.add_argument("--exp-lg", metavar="V,V,V", type=u, default=DEF_EXP, help="comma/space-separated list of placeholders to expand in prologue/epilogue files (volflag=exp_lg)")
|
1201
1201
|
|
@@ -1203,8 +1203,8 @@ def add_txt(ap):
|
|
1203
1203
|
def add_ui(ap, retry):
|
1204
1204
|
ap2 = ap.add_argument_group('ui options')
|
1205
1205
|
ap2.add_argument("--grid", action="store_true", help="show grid/thumbnails by default (volflag=grid)")
|
1206
|
-
ap2.add_argument("--lang", metavar="LANG", type=u, default="eng", help="language; one of the following:
|
1207
|
-
ap2.add_argument("--theme", metavar="NUM", type=int, default=0, help="default theme to use")
|
1206
|
+
ap2.add_argument("--lang", metavar="LANG", type=u, default="eng", help="language; one of the following: \033[32meng nor\033[0m")
|
1207
|
+
ap2.add_argument("--theme", metavar="NUM", type=int, default=0, help="default theme to use (0..7)")
|
1208
1208
|
ap2.add_argument("--themes", metavar="NUM", type=int, default=8, help="number of themes installed")
|
1209
1209
|
ap2.add_argument("--sort", metavar="C,C,C", type=u, default="href", help="default sort order, comma-separated column IDs (see header tooltips), prefix with '-' for descending. Examples: \033[32mhref -href ext sz ts tags/Album tags/.tn\033[0m (volflag=sort)")
|
1210
1210
|
ap2.add_argument("--unlist", metavar="REGEX", type=u, default="", help="don't show files matching \033[33mREGEX\033[0m in file list. Purely cosmetic! Does not affect API calls, just the browser. Example: [\033[32m\\.(js|css)$\033[0m] (volflag=unlist)")
|
@@ -1218,8 +1218,8 @@ def add_ui(ap, retry):
|
|
1218
1218
|
ap2.add_argument("--txt-max", metavar="KiB", type=int, default=64, help="max size of embedded textfiles on ?doc= (anything bigger will be lazy-loaded by JS)")
|
1219
1219
|
ap2.add_argument("--doctitle", metavar="TXT", type=u, default="copyparty @ --name", help="title / service-name to show in html documents")
|
1220
1220
|
ap2.add_argument("--bname", metavar="TXT", type=u, default="--name", help="server name (displayed in filebrowser document title)")
|
1221
|
-
ap2.add_argument("--pb-url", metavar="URL", type=u, default="https://github.com/9001/copyparty", help="powered-by link; disable with -np")
|
1222
|
-
ap2.add_argument("--ver", action="store_true", help="show version on the control panel (incompatible with -nb)")
|
1221
|
+
ap2.add_argument("--pb-url", metavar="URL", type=u, default="https://github.com/9001/copyparty", help="powered-by link; disable with \033[33m-np\033[0m")
|
1222
|
+
ap2.add_argument("--ver", action="store_true", help="show version on the control panel (incompatible with \033[33m-nb\033[0m)")
|
1223
1223
|
ap2.add_argument("--md-sbf", metavar="FLAGS", type=u, default="downloads forms popups scripts top-navigation-by-user-activation", help="list of capabilities to ALLOW for README.md docs (volflag=md_sbf); see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-sandbox")
|
1224
1224
|
ap2.add_argument("--lg-sbf", metavar="FLAGS", type=u, default="downloads forms popups scripts top-navigation-by-user-activation", help="list of capabilities to ALLOW for prologue/epilogue docs (volflag=lg_sbf)")
|
1225
1225
|
ap2.add_argument("--no-sb-md", action="store_true", help="don't sandbox README.md documents (volflags: no_sb_md | sb_md)")
|
@@ -1230,17 +1230,17 @@ def add_debug(ap):
|
|
1230
1230
|
ap2 = ap.add_argument_group('debug options')
|
1231
1231
|
ap2.add_argument("--vc", action="store_true", help="verbose config file parser (explain config)")
|
1232
1232
|
ap2.add_argument("--cgen", action="store_true", help="generate config file from current config (best-effort; probably buggy)")
|
1233
|
-
ap2.add_argument("--no-sendfile", action="store_true", help="disable sendfile;
|
1234
|
-
ap2.add_argument("--no-scandir", action="store_true", help="disable scandir;
|
1235
|
-
ap2.add_argument("--no-fastboot", action="store_true", help="wait for
|
1233
|
+
ap2.add_argument("--no-sendfile", action="store_true", help="kernel-bug workaround: disable sendfile; do a safe and slow read-send-loop instead")
|
1234
|
+
ap2.add_argument("--no-scandir", action="store_true", help="kernel-bug workaround: disable scandir; do a listdir + stat on each file instead")
|
1235
|
+
ap2.add_argument("--no-fastboot", action="store_true", help="wait for initial filesystem indexing before accepting client requests")
|
1236
1236
|
ap2.add_argument("--no-htp", action="store_true", help="disable httpserver threadpool, create threads as-needed instead")
|
1237
1237
|
ap2.add_argument("--srch-dbg", action="store_true", help="explain search processing, and do some extra expensive sanity checks")
|
1238
1238
|
ap2.add_argument("--rclone-mdns", action="store_true", help="use mdns-domain instead of server-ip on /?hc")
|
1239
1239
|
ap2.add_argument("--stackmon", metavar="P,S", type=u, help="write stacktrace to \033[33mP\033[0math every \033[33mS\033[0m second, for example --stackmon=\033[32m./st/%%Y-%%m/%%d/%%H%%M.xz,60")
|
1240
1240
|
ap2.add_argument("--log-thrs", metavar="SEC", type=float, help="list active threads every \033[33mSEC\033[0m")
|
1241
1241
|
ap2.add_argument("--log-fk", metavar="REGEX", type=u, default="", help="log filekey params for files where path matches \033[33mREGEX\033[0m; [\033[32m.\033[0m] (a single dot) = all files")
|
1242
|
-
ap2.add_argument("--bak-flips", action="store_true", help="[up2k] if a client uploads a bitflipped/corrupted chunk, store a copy according to --bf-nc and --bf-dir")
|
1243
|
-
ap2.add_argument("--bf-nc", metavar="NUM", type=int, default=200, help="bak-flips: stop if there's more than \033[33mNUM\033[0m files at --kf-dir already; default: 6.3 GiB max (200*32M)")
|
1242
|
+
ap2.add_argument("--bak-flips", action="store_true", help="[up2k] if a client uploads a bitflipped/corrupted chunk, store a copy according to \033[33m--bf-nc\033[0m and \033[33m--bf-dir\033[0m")
|
1243
|
+
ap2.add_argument("--bf-nc", metavar="NUM", type=int, default=200, help="bak-flips: stop if there's more than \033[33mNUM\033[0m files at \033[33m--kf-dir\033[0m already; default: 6.3 GiB max (200*32M)")
|
1244
1244
|
ap2.add_argument("--bf-dir", metavar="PATH", type=u, default="bf", help="bak-flips: store corrupted chunks at \033[33mPATH\033[0m; default: folder named 'bf' wherever copyparty was started")
|
1245
1245
|
|
1246
1246
|
|
copyparty/__version__.py
CHANGED
copyparty/bos/bos.py
CHANGED
copyparty/up2k.py
CHANGED
@@ -2928,7 +2928,6 @@ class Up2k(object):
|
|
2928
2928
|
|
2929
2929
|
self._symlink(dst, d2, self.flags[ptop], lmod=lmod)
|
2930
2930
|
if cur:
|
2931
|
-
self.db_rm(cur, rd, fn, job["size"])
|
2932
2931
|
self.db_add(cur, vflags, rd, fn, lmod, *z2[3:])
|
2933
2932
|
|
2934
2933
|
if cur:
|
@@ -2971,7 +2970,6 @@ class Up2k(object):
|
|
2971
2970
|
|
2972
2971
|
self.db_act = self.vol_act[ptop] = time.time()
|
2973
2972
|
try:
|
2974
|
-
self.db_rm(cur, rd, fn, sz)
|
2975
2973
|
self.db_add(
|
2976
2974
|
cur,
|
2977
2975
|
vflags,
|
@@ -3030,6 +3028,8 @@ class Up2k(object):
|
|
3030
3028
|
at ,
|
3031
3029
|
skip_xau = False,
|
3032
3030
|
) :
|
3031
|
+
self.db_rm(db, rd, fn, sz)
|
3032
|
+
|
3033
3033
|
sql = "insert into up values (?,?,?,?,?,?,?)"
|
3034
3034
|
v = (wark, int(ts), sz, rd, fn, ip or "", int(at or 0))
|
3035
3035
|
try:
|
@@ -3191,7 +3191,13 @@ class Up2k(object):
|
|
3191
3191
|
break
|
3192
3192
|
|
3193
3193
|
abspath = djoin(adir, fn)
|
3194
|
-
st = bos.
|
3194
|
+
st = stl = bos.lstat(abspath)
|
3195
|
+
if stat.S_ISLNK(st.st_mode):
|
3196
|
+
try:
|
3197
|
+
st = bos.stat(abspath)
|
3198
|
+
except:
|
3199
|
+
pass
|
3200
|
+
|
3195
3201
|
volpath = "{}/{}".format(vrem, fn).strip("/")
|
3196
3202
|
vpath = "{}/{}".format(dbv.vpath, volpath).strip("/")
|
3197
3203
|
self.log("rm {}\n {}".format(vpath, abspath))
|
@@ -3204,7 +3210,7 @@ class Up2k(object):
|
|
3204
3210
|
vpath,
|
3205
3211
|
"",
|
3206
3212
|
uname,
|
3207
|
-
|
3213
|
+
stl.st_mtime,
|
3208
3214
|
st.st_size,
|
3209
3215
|
ip,
|
3210
3216
|
0,
|
@@ -3234,7 +3240,7 @@ class Up2k(object):
|
|
3234
3240
|
vpath,
|
3235
3241
|
"",
|
3236
3242
|
uname,
|
3237
|
-
|
3243
|
+
stl.st_mtime,
|
3238
3244
|
st.st_size,
|
3239
3245
|
ip,
|
3240
3246
|
0,
|
@@ -3351,28 +3357,27 @@ class Up2k(object):
|
|
3351
3357
|
if bos.path.exists(dabs):
|
3352
3358
|
raise Pebkac(400, "mv2: target file exists")
|
3353
3359
|
|
3354
|
-
|
3355
|
-
|
3356
|
-
|
3357
|
-
|
3358
|
-
|
3360
|
+
is_link = is_dirlink = False
|
3361
|
+
st = stl = bos.lstat(sabs)
|
3362
|
+
if stat.S_ISLNK(stl.st_mode):
|
3363
|
+
is_link = True
|
3364
|
+
try:
|
3365
|
+
st = bos.stat(sabs)
|
3366
|
+
is_dirlink = stat.S_ISDIR(st.st_mode)
|
3367
|
+
except:
|
3368
|
+
pass # broken symlink; keep as-is
|
3359
3369
|
|
3360
3370
|
xbr = svn.flags.get("xbr")
|
3361
3371
|
xar = dvn.flags.get("xar")
|
3362
3372
|
if xbr:
|
3363
3373
|
if not runhook(
|
3364
|
-
self.log, xbr, sabs, svp, "", uname,
|
3374
|
+
self.log, xbr, sabs, svp, "", uname, stl.st_mtime, st.st_size, "", 0, ""
|
3365
3375
|
):
|
3366
3376
|
t = "move blocked by xbr server config: {}".format(svp)
|
3367
3377
|
self.log(t, 1)
|
3368
3378
|
raise Pebkac(405, t)
|
3369
3379
|
|
3370
3380
|
is_xvol = svn.realpath != dvn.realpath
|
3371
|
-
if stat.S_ISLNK(stl.st_mode):
|
3372
|
-
is_dirlink = stat.S_ISDIR(st.st_mode)
|
3373
|
-
is_link = True
|
3374
|
-
else:
|
3375
|
-
is_link = is_dirlink = False
|
3376
3381
|
|
3377
3382
|
bos.makedirs(os.path.dirname(dabs))
|
3378
3383
|
|
@@ -3399,7 +3404,7 @@ class Up2k(object):
|
|
3399
3404
|
c2 = self.cur.get(dvn.realpath)
|
3400
3405
|
|
3401
3406
|
if ftime_ is None:
|
3402
|
-
ftime =
|
3407
|
+
ftime = stl.st_mtime
|
3403
3408
|
fsize = st.st_size
|
3404
3409
|
else:
|
3405
3410
|
ftime = ftime_
|
@@ -3441,7 +3446,16 @@ class Up2k(object):
|
|
3441
3446
|
if is_xvol and has_dupes:
|
3442
3447
|
raise OSError(errno.EXDEV, "src is symlink")
|
3443
3448
|
|
3444
|
-
|
3449
|
+
if is_link and st != stl:
|
3450
|
+
# relink non-broken symlinks to still work after the move,
|
3451
|
+
# but only resolve 1st level to maintain relativity
|
3452
|
+
dlink = bos.readlink(sabs)
|
3453
|
+
dlink = os.path.join(os.path.dirname(sabs), dlink)
|
3454
|
+
dlink = bos.path.abspath(dlink)
|
3455
|
+
self._symlink(dlink, dabs, dvn.flags, lmod=ftime)
|
3456
|
+
bos.unlink(sabs)
|
3457
|
+
else:
|
3458
|
+
atomic_move(sabs, dabs)
|
3445
3459
|
|
3446
3460
|
except OSError as ex:
|
3447
3461
|
if ex.errno != errno.EXDEV:
|
@@ -3608,6 +3622,8 @@ class Up2k(object):
|
|
3608
3622
|
except:
|
3609
3623
|
self.log("relink: not found: [{}]".format(ap))
|
3610
3624
|
|
3625
|
+
# self.log("full:\n" + "\n".join(" {:90}: {}".format(*x) for x in full.items()))
|
3626
|
+
# self.log("links:\n" + "\n".join(" {:90}: {}".format(*x) for x in links.items()))
|
3611
3627
|
if not dabs and not full and links:
|
3612
3628
|
# deleting final remaining full copy; swap it with a symlink
|
3613
3629
|
slabs = list(sorted(links.keys()))[0]
|
@@ -3625,12 +3641,45 @@ class Up2k(object):
|
|
3625
3641
|
dabs = list(sorted(full.keys()))[0]
|
3626
3642
|
|
3627
3643
|
for alink, parts in links.items():
|
3628
|
-
lmod =
|
3644
|
+
lmod = 0.0
|
3629
3645
|
try:
|
3630
|
-
|
3631
|
-
|
3646
|
+
faulty = False
|
3647
|
+
ldst = alink
|
3648
|
+
try:
|
3649
|
+
for n in range(40): # MAXSYMLINKS
|
3650
|
+
zs = bos.readlink(ldst)
|
3651
|
+
ldst = os.path.join(os.path.dirname(ldst), zs)
|
3652
|
+
ldst = bos.path.abspath(ldst)
|
3653
|
+
if not bos.path.islink(ldst):
|
3654
|
+
break
|
3655
|
+
|
3656
|
+
if ldst == sabs:
|
3657
|
+
t = "relink because level %d would break:"
|
3658
|
+
self.log(t % (n,), 6)
|
3659
|
+
faulty = True
|
3660
|
+
except Exception as ex:
|
3661
|
+
self.log("relink because walk failed: %s; %r" % (ex, ex), 3)
|
3662
|
+
faulty = True
|
3632
3663
|
|
3633
|
-
|
3664
|
+
zs = absreal(alink)
|
3665
|
+
if ldst != zs:
|
3666
|
+
t = "relink because computed != actual destination:\n %s\n %s"
|
3667
|
+
self.log(t % (ldst, zs), 3)
|
3668
|
+
ldst = zs
|
3669
|
+
faulty = True
|
3670
|
+
|
3671
|
+
if bos.path.islink(ldst):
|
3672
|
+
raise Exception("broken symlink: %s" % (alink,))
|
3673
|
+
|
3674
|
+
if alink != sabs and ldst != sabs and not faulty:
|
3675
|
+
continue # original symlink OK; leave it be
|
3676
|
+
|
3677
|
+
except Exception as ex:
|
3678
|
+
t = "relink because symlink verification failed: %s; %r"
|
3679
|
+
self.log(t % (ex, ex), 3)
|
3680
|
+
|
3681
|
+
self.log("relinking [%s] to [%s]" % (alink, dabs))
|
3682
|
+
try:
|
3634
3683
|
lmod = bos.path.getmtime(alink, False)
|
3635
3684
|
bos.unlink(alink)
|
3636
3685
|
except:
|
copyparty/web/a/u2c.py
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
#!/usr/bin/env python3
|
2
2
|
from __future__ import print_function, unicode_literals
|
3
3
|
|
4
|
-
S_VERSION = "1.
|
5
|
-
S_BUILD_DT = "2023-
|
4
|
+
S_VERSION = "1.12"
|
5
|
+
S_BUILD_DT = "2023-12-08"
|
6
6
|
|
7
7
|
"""
|
8
8
|
u2c.py: upload to copyparty
|
@@ -907,12 +907,23 @@ class Ctl(object):
|
|
907
907
|
dp = os.path.join(top, rd)
|
908
908
|
lnodes = set(os.listdir(dp))
|
909
909
|
bnames = [x for x in ls if x not in lnodes]
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
910
|
+
vpath = self.ar.url.split("://")[-1].split("/", 1)[-1]
|
911
|
+
names = [x.decode("utf-8", "replace") for x in bnames]
|
912
|
+
locs = [vpath + srd + "/" + x for x in names]
|
913
|
+
while locs:
|
914
|
+
req = locs
|
915
|
+
while req:
|
916
|
+
print("DELETING ~%s/#%s" % (srd, len(req)))
|
917
|
+
r = req_ses.post(self.ar.url + "?delete", json=req)
|
918
|
+
if r.status_code == 413 and "json 2big" in r.text:
|
919
|
+
print(" (delete request too big; slicing...)")
|
920
|
+
req = req[: len(req) // 2]
|
921
|
+
continue
|
922
|
+
elif not r:
|
923
|
+
t = "delete request failed: %r %s"
|
924
|
+
raise Exception(t % (r, r.text))
|
925
|
+
break
|
926
|
+
locs = locs[len(req) :]
|
916
927
|
|
917
928
|
if isdir:
|
918
929
|
continue
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: copyparty
|
3
|
-
Version: 1.9.
|
3
|
+
Version: 1.9.27
|
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
|
@@ -199,9 +199,10 @@ you may also want these, especially on servers:
|
|
199
199
|
|
200
200
|
* [contrib/systemd/copyparty.service](contrib/systemd/copyparty.service) to run copyparty as a systemd service (see guide inside)
|
201
201
|
* [contrib/systemd/prisonparty.service](contrib/systemd/prisonparty.service) to run it in a chroot (for extra security)
|
202
|
+
* [contrib/openrc/copyparty](contrib/openrc/copyparty) to run copyparty on Alpine / Gentoo
|
202
203
|
* [contrib/rc/copyparty](contrib/rc/copyparty) to run copyparty on FreeBSD
|
203
|
-
* [contrib/nginx/copyparty.conf](contrib/nginx/copyparty.conf) to [reverse-proxy](#reverse-proxy) behind nginx (for better https)
|
204
204
|
* [nixos module](#nixos-module) to run copyparty on NixOS hosts
|
205
|
+
* [contrib/nginx/copyparty.conf](contrib/nginx/copyparty.conf) to [reverse-proxy](#reverse-proxy) behind nginx (for better https)
|
205
206
|
|
206
207
|
and remember to open the ports you want; here's a complete example including every feature copyparty has to offer:
|
207
208
|
```
|
@@ -392,7 +393,7 @@ upgrade notes
|
|
392
393
|
* yes, using [hooks](https://github.com/9001/copyparty/blob/hovudstraum/bin/hooks/wget.py)
|
393
394
|
|
394
395
|
* i want to learn python and/or programming and am considering looking at the copyparty source code in that occasion
|
395
|
-
|
396
|
+
* ```bash
|
396
397
|
_| _ __ _ _|_
|
397
398
|
(_| (_) | | (_) |_
|
398
399
|
```
|
@@ -874,6 +875,9 @@ using arguments or config files, or a mix of both:
|
|
874
875
|
* or click the `[reload cfg]` button in the control-panel if the user has `a`/admin in any volume
|
875
876
|
* changes to the `[global]` config section requires a restart to take effect
|
876
877
|
|
878
|
+
**NB:** as humongous as this readme is, there is also a lot of undocumented features. Run copyparty with `--help` to see all available global options; all of those can be used in the `[global]` section of config files, and everything listed in `--help-flags` can be used in volumes as volflags.
|
879
|
+
* if running in docker/podman, try this: `docker run --rm -it copyparty/ac --help`
|
880
|
+
|
877
881
|
|
878
882
|
## zeroconf
|
879
883
|
|
@@ -1416,15 +1420,19 @@ note: the following metrics are counted incorrectly if multiprocessing is enable
|
|
1416
1420
|
|
1417
1421
|
the party might be closer than you think
|
1418
1422
|
|
1423
|
+
if your distro/OS is not mentioned below, there might be some hints in the [«on servers»](#on-servers) section
|
1424
|
+
|
1419
1425
|
|
1420
1426
|
## arch package
|
1421
1427
|
|
1422
1428
|
now [available on aur](https://aur.archlinux.org/packages/copyparty) maintained by [@icxes](https://github.com/icxes)
|
1423
1429
|
|
1430
|
+
it comes with a [systemd service](./contrib/package/arch/copyparty.service) and expects to find one or more [config files](./docs/example.conf) in `/etc/copyparty.d/`
|
1431
|
+
|
1424
1432
|
|
1425
1433
|
## fedora package
|
1426
1434
|
|
1427
|
-
now [available on copr-pypi](https://copr.fedorainfracloud.org/coprs/g/copr/PyPI/) ,
|
1435
|
+
now [available on copr-pypi](https://copr.fedorainfracloud.org/coprs/g/copr/PyPI/) , autogenerated from pypi by fedora -- [track record](https://copr.fedorainfracloud.org/coprs/g/copr/PyPI/package/python-copyparty/) seems OK
|
1428
1436
|
|
1429
1437
|
```bash
|
1430
1438
|
dnf copr enable @copr/PyPI
|
@@ -1,6 +1,6 @@
|
|
1
1
|
copyparty/__init__.py,sha256=34xcU8AoRRQscgVSx2gC6DeUyu7ZLmEVlXjttdQgXnI,1752
|
2
|
-
copyparty/__main__.py,sha256=
|
3
|
-
copyparty/__version__.py,sha256=
|
2
|
+
copyparty/__main__.py,sha256=hBzc1ISxFcZH3BpmdOsduCKBdmbPQAhvUUyuqmUvyOU,89329
|
3
|
+
copyparty/__version__.py,sha256=o3Ox4FVfBf649e-YKX-zqh1ZF5NFlIWL2G164kcrwp0,254
|
4
4
|
copyparty/authsrv.py,sha256=PrMej_hmFWkV8t4Txr2tc8GY7JD_vb7L3alWTuGe8hU,71292
|
5
5
|
copyparty/broker_mp.py,sha256=4mEZC5tiHUazJMgYuwInNo2dxS7jrbzrGb1qs2UBt9k,3948
|
6
6
|
copyparty/broker_mpw.py,sha256=GlSn4PRd_OqqeG39FiXgNvPzXVQW6UCiAcqmBSr2q6g,3200
|
@@ -30,10 +30,10 @@ copyparty/tcpsrv.py,sha256=vz94zy-eUg5-U1lskN3VAQiTXVr80PPnwJfwzybVcW4,17169
|
|
30
30
|
copyparty/th_cli.py,sha256=MSp2kpoAPiX1bndMthv6JK2gt3K6CjrloWuJsI_CL94,3869
|
31
31
|
copyparty/th_srv.py,sha256=ClG82DOri2Z8iJeMn1q886uMfxF8ZdJenDWIsiL5gYM,23288
|
32
32
|
copyparty/u2idx.py,sha256=HMEnpmbH-TXDrci4wsKNFvtEW4TxPtVl9hO5MS_EFVs,12799
|
33
|
-
copyparty/up2k.py,sha256=
|
33
|
+
copyparty/up2k.py,sha256=c9R_fb18xwtLKpP9swicATKp-DmJGCuRYR07aoUAKto,132716
|
34
34
|
copyparty/util.py,sha256=vfCbQv8QUIEQbu65BIuCkuGkqSoUhnCI6xPOFQevKxQ,75998
|
35
35
|
copyparty/bos/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
36
|
-
copyparty/bos/bos.py,sha256=
|
36
|
+
copyparty/bos/bos.py,sha256=Wb7eWsXJgR5AFlBR9ZOyKrLTwy-Kct9RrGiOu4Jo37Y,1622
|
37
37
|
copyparty/bos/path.py,sha256=yEjCq2ki9CvxA5sCT8pS0keEXwugs0ZeUyUhdBziOCI,777
|
38
38
|
copyparty/res/COPYING.txt,sha256=087-rNDMk0NijtO0F7QZ_y1qiy7Za-rsLbImihEgQ-M,10465
|
39
39
|
copyparty/res/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -81,7 +81,7 @@ copyparty/web/util.js.gz,sha256=hGmBv9Ibt4PcRKea3HkIG2G0NIFsn_UJf7bKasymR90,1386
|
|
81
81
|
copyparty/web/w.hash.js.gz,sha256=P9469QknH8-1aKwI_1n1_S4yKvIGOu7bGoty9N3zYMI,1060
|
82
82
|
copyparty/web/a/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
83
83
|
copyparty/web/a/partyfuse.py,sha256=MuRkaSuYsdfWfBFMOkbPwDXqSvNTw3sd7QhhlKCDZ8I,32311
|
84
|
-
copyparty/web/a/u2c.py,sha256=
|
84
|
+
copyparty/web/a/u2c.py,sha256=3dRtYfNh_kDTHQvHACZ5VotJsEY9SPclYyfMC6hDsdo,37819
|
85
85
|
copyparty/web/a/webdav-cfg.bat,sha256=Y4NoGZlksAIg4cBMb7KdJrpKC6Nx97onaTl6yMjaimk,1449
|
86
86
|
copyparty/web/dd/2.png,sha256=gJ14XFPzaw95L6z92fSq9eMPikSQyu-03P1lgiGe0_I,258
|
87
87
|
copyparty/web/dd/3.png,sha256=4lho8Koz5tV7jJ4ODo6GMTScZfkqsT05yp48EDFIlyg,252
|
@@ -98,9 +98,9 @@ copyparty/web/deps/prismd.css.gz,sha256=ObUlksQVr-OuYlTz-I4B23TeBg2QDVVGRnWBz8cV
|
|
98
98
|
copyparty/web/deps/scp.woff2,sha256=w99BDU5i8MukkMEL-iW0YO9H4vFFZSPWxbkH70ytaAg,8612
|
99
99
|
copyparty/web/deps/sha512.ac.js.gz,sha256=lFZaCLumgWxrvEuDr4bqdKHsqjX82AbVAb7_F45Yk88,7033
|
100
100
|
copyparty/web/deps/sha512.hw.js.gz,sha256=km3_b5IoaVwg02Ex6PxnhDLZxKiOMP2cHW35j9CSWFA,8107
|
101
|
-
copyparty-1.9.
|
102
|
-
copyparty-1.9.
|
103
|
-
copyparty-1.9.
|
104
|
-
copyparty-1.9.
|
105
|
-
copyparty-1.9.
|
106
|
-
copyparty-1.9.
|
101
|
+
copyparty-1.9.27.dist-info/LICENSE,sha256=yyzj1id78vWoLs8zbMRJY7xkkLz0lv-9dfyeIauqdfM,1059
|
102
|
+
copyparty-1.9.27.dist-info/METADATA,sha256=v7eaPBfBOdji7cRJms62zqEQyPuZsk-AhRAbyGdNz-Y,108940
|
103
|
+
copyparty-1.9.27.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
104
|
+
copyparty-1.9.27.dist-info/entry_points.txt,sha256=4zw6a3rqASywQomiYLObjjlxybaI65LYYOTJwgKz7b0,128
|
105
|
+
copyparty-1.9.27.dist-info/top_level.txt,sha256=LnYUPsDyk-8kFgM6YJLG4h820DQekn81cObKSu9g-sI,10
|
106
|
+
copyparty-1.9.27.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|