copyparty 1.13.2__py3-none-any.whl → 1.13.4__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 +94 -43
- copyparty/__version__.py +2 -2
- copyparty/authsrv.py +75 -13
- copyparty/cert.py +10 -6
- copyparty/cfg.py +3 -0
- copyparty/ftpd.py +44 -7
- copyparty/httpcli.py +188 -64
- copyparty/httpsrv.py +3 -3
- copyparty/mdns.py +24 -3
- copyparty/mtag.py +6 -1
- copyparty/smbd.py +1 -1
- copyparty/ssdp.py +23 -3
- copyparty/star.py +4 -4
- copyparty/sutil.py +12 -6
- copyparty/svchub.py +4 -2
- copyparty/szip.py +4 -4
- copyparty/tcpsrv.py +4 -1
- copyparty/tftpd.py +5 -10
- copyparty/th_cli.py +1 -1
- copyparty/th_srv.py +22 -11
- copyparty/up2k.py +84 -16
- copyparty/util.py +69 -22
- copyparty/web/a/u2c.py +14 -6
- copyparty/web/baguettebox.js.gz +0 -0
- copyparty/web/browser.css.gz +0 -0
- copyparty/web/browser.js.gz +0 -0
- copyparty/web/deps/marked.js.gz +0 -0
- copyparty/web/md2.js.gz +0 -0
- copyparty/web/ui.css.gz +0 -0
- copyparty/web/util.js.gz +0 -0
- {copyparty-1.13.2.dist-info → copyparty-1.13.4.dist-info}/METADATA +39 -7
- {copyparty-1.13.2.dist-info → copyparty-1.13.4.dist-info}/RECORD +36 -36
- {copyparty-1.13.2.dist-info → copyparty-1.13.4.dist-info}/WHEEL +1 -1
- {copyparty-1.13.2.dist-info → copyparty-1.13.4.dist-info}/LICENSE +0 -0
- {copyparty-1.13.2.dist-info → copyparty-1.13.4.dist-info}/entry_points.txt +0 -0
- {copyparty-1.13.2.dist-info → copyparty-1.13.4.dist-info}/top_level.txt +0 -0
copyparty/__main__.py
CHANGED
@@ -13,6 +13,7 @@ import base64
|
|
13
13
|
import locale
|
14
14
|
import os
|
15
15
|
import re
|
16
|
+
import select
|
16
17
|
import socket
|
17
18
|
import sys
|
18
19
|
import threading
|
@@ -41,6 +42,7 @@ from .util import (
|
|
41
42
|
DEF_EXP,
|
42
43
|
DEF_MTE,
|
43
44
|
DEF_MTH,
|
45
|
+
HAVE_IPV6,
|
44
46
|
IMPLICATIONS,
|
45
47
|
JINJA_VER,
|
46
48
|
MIMES,
|
@@ -167,8 +169,10 @@ def init_E(EE ) :
|
|
167
169
|
(os.environ.get, "TMP"),
|
168
170
|
(unicode, "/tmp"),
|
169
171
|
]
|
172
|
+
errs = []
|
170
173
|
for chk in [os.listdir, os.mkdir]:
|
171
|
-
for pf, pa in paths:
|
174
|
+
for npath, (pf, pa) in enumerate(paths):
|
175
|
+
p = ""
|
172
176
|
try:
|
173
177
|
p = pf(pa)
|
174
178
|
# print(chk.__name__, p, pa)
|
@@ -181,9 +185,20 @@ def init_E(EE ) :
|
|
181
185
|
if not os.path.isdir(p):
|
182
186
|
os.mkdir(p)
|
183
187
|
|
188
|
+
if npath > 1:
|
189
|
+
t = "Using [%s] for config; filekeys/dirkeys will change on every restart. Consider setting XDG_CONFIG_HOME or giving the unix-user a ~/.config/"
|
190
|
+
errs.append(t % (p,))
|
191
|
+
elif errs:
|
192
|
+
errs.append("Using [%s] instead" % (p,))
|
193
|
+
|
194
|
+
if errs:
|
195
|
+
print("WARNING: " + ". ".join(errs))
|
196
|
+
|
184
197
|
return p # type: ignore
|
185
|
-
except:
|
186
|
-
|
198
|
+
except Exception as ex:
|
199
|
+
if p and npath < 2:
|
200
|
+
t = "Unable to store config in [%s] due to %r"
|
201
|
+
errs.append(t % (p, ex))
|
187
202
|
|
188
203
|
raise Exception("could not find a writable path for config")
|
189
204
|
|
@@ -273,6 +288,9 @@ def get_ah_salt() :
|
|
273
288
|
|
274
289
|
|
275
290
|
def ensure_locale() :
|
291
|
+
if ANYWIN and PY2:
|
292
|
+
return # maybe XP, so busted 65001
|
293
|
+
|
276
294
|
safe = "en_US.UTF-8"
|
277
295
|
for x in [
|
278
296
|
safe,
|
@@ -610,12 +628,12 @@ def get_sects():
|
|
610
628
|
\033[36mxban\033[35m executes CMD if someone gets banned
|
611
629
|
\033[0m
|
612
630
|
can be defined as --args or volflags; for example \033[36m
|
613
|
-
--xau
|
614
|
-
-v .::r:c,xau=
|
631
|
+
--xau foo.py
|
632
|
+
-v .::r:c,xau=bar.py
|
615
633
|
\033[0m
|
616
|
-
|
617
|
-
each --arg and volflag can be specified multiple times,
|
618
|
-
each
|
634
|
+
hooks specified as commandline --args are appended to volflags;
|
635
|
+
each commandline --arg and volflag can be specified multiple times,
|
636
|
+
each hook will execute in order unless one returns non-zero
|
619
637
|
|
620
638
|
optionally prefix the command with comma-sep. flags similar to -mtp:
|
621
639
|
|
@@ -626,6 +644,10 @@ def get_sects():
|
|
626
644
|
\033[36mtN\033[35m sets an N sec timeout before the command is abandoned
|
627
645
|
\033[36miN\033[35m xiu only: volume must be idle for N sec (default = 5)
|
628
646
|
|
647
|
+
\033[36mar\033[35m only run hook if user has read-access
|
648
|
+
\033[36marw\033[35m only run hook if user has read-write-access
|
649
|
+
\033[36marwmd\033[35m ...and so on... (doesn't work for xiu or xban)
|
650
|
+
|
629
651
|
\033[36mkt\033[35m kills the entire process tree on timeout (default),
|
630
652
|
\033[36mkm\033[35m kills just the main process
|
631
653
|
\033[36mkn\033[35m lets it continue running until copyparty is terminated
|
@@ -635,6 +657,21 @@ def get_sects():
|
|
635
657
|
\033[36mc2\033[35m show only stdout
|
636
658
|
\033[36mc3\033[35m mute all process otput
|
637
659
|
\033[0m
|
660
|
+
examples:
|
661
|
+
|
662
|
+
\033[36m--xm some.py\033[35m runs \033[33msome.py msgtxt\033[35m on each 📟 message;
|
663
|
+
\033[33mmsgtxt\033[35m is the message that was written into the web-ui
|
664
|
+
|
665
|
+
\033[36m--xm j,some.py\033[35m runs \033[33msome.py jsontext\033[35m on each 📟 message;
|
666
|
+
\033[33mjsontext\033[35m is the message info (ip, user, ..., msg-text)
|
667
|
+
|
668
|
+
\033[36m--xm aw,j,some.py\033[35m requires user to have write-access
|
669
|
+
|
670
|
+
\033[36m--xm aw,,notify-send,hey,--\033[35m shows an OS alert on linux;
|
671
|
+
the \033[33m,,\033[35m stops copyparty from reading the rest as flags and
|
672
|
+
the \033[33m--\033[35m stops notify-send from reading the message as args
|
673
|
+
and the alert will be "hey" followed by the messagetext
|
674
|
+
\033[0m
|
638
675
|
each hook is executed once for each event, except for \033[36mxiu\033[0m
|
639
676
|
which builds up a backlog of uploads, running the hook just once
|
640
677
|
as soon as the volume has been idle for iN seconds (5 by default)
|
@@ -661,7 +698,10 @@ def get_sects():
|
|
661
698
|
\033[36mstash\033[35m dumps the data to file and returns length + checksum
|
662
699
|
\033[36msave,get\033[35m dumps to file and returns the page like a GET
|
663
700
|
\033[36mprint,get\033[35m prints the data in the log and returns GET
|
664
|
-
(leave out the ",get" to return an error instead)
|
701
|
+
(leave out the ",get" to return an error instead)\033[0m
|
702
|
+
|
703
|
+
note that the \033[35m--xm\033[0m hook will only run if \033[35m--urlform\033[0m
|
704
|
+
is either \033[36mprint\033[0m or the default \033[36mprint,get\033[0m
|
665
705
|
"""
|
666
706
|
),
|
667
707
|
],
|
@@ -887,12 +927,12 @@ def add_upload(ap):
|
|
887
927
|
ap2.add_argument("--no-dupe", action="store_true", help="reject duplicate files during upload; only matches within the same volume (volflag=nodupe)")
|
888
928
|
ap2.add_argument("--no-snap", action="store_true", help="disable snapshots -- forget unfinished uploads on shutdown; don't create .hist/up2k.snap files -- abandoned/interrupted uploads must be cleaned up manually")
|
889
929
|
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")
|
890
|
-
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)")
|
930
|
+
ap2.add_argument("--snap-drop", metavar="MIN", type=float, default=1440.0, help="forget unfinished uploads after \033[33mMIN\033[0m minutes; impossible to resume them after that (360=6h, 1440=24h)")
|
891
931
|
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)")
|
892
932
|
ap2.add_argument("--rand", action="store_true", help="force randomized filenames, \033[33m--nrand\033[0m chars long (volflag=rand)")
|
893
933
|
ap2.add_argument("--nrand", metavar="NUM", type=int, default=9, help="randomized filenames length (volflag=nrand)")
|
894
934
|
ap2.add_argument("--magic", action="store_true", help="enable filetype detection on nameless uploads (volflag=magic)")
|
895
|
-
ap2.add_argument("--df", metavar="GiB", type=
|
935
|
+
ap2.add_argument("--df", metavar="GiB", type=u, default="0", help="ensure \033[33mGiB\033[0m free disk space by rejecting upload requests; assumes gigabytes unless a unit suffix is given: [\033[32m256m\033[0m], [\033[32m4\033[0m], [\033[32m2T\033[0m] (volflag=df)")
|
896
936
|
ap2.add_argument("--sparse", metavar="MiB", type=int, default=4, help="windows-only: minimum size of incoming uploads through up2k before they are made into sparse files")
|
897
937
|
ap2.add_argument("--turbo", metavar="LVL", type=int, default=0, help="configure turbo-mode in up2k client; [\033[32m-1\033[0m] = forbidden/always-off, [\033[32m0\033[0m] = default-off and warn if enabled, [\033[32m1\033[0m] = default-off, [\033[32m2\033[0m] = on, [\033[32m3\033[0m] = on and disable datecheck")
|
898
938
|
ap2.add_argument("--u2j", metavar="JOBS", type=int, default=2, help="web-client: number of file chunks to upload in parallel; 1 or 2 is good for low-latency (same-country) connections, 4-8 for android clients, 16 for cross-atlantic (max=64)")
|
@@ -915,12 +955,12 @@ def add_network(ap):
|
|
915
955
|
else:
|
916
956
|
ap2.add_argument("--freebind", action="store_true", help="allow listening on IPs which do not yet exist, for example if the network interfaces haven't finished going up. Only makes sense for IPs other than '0.0.0.0', '127.0.0.1', '::', and '::1'. May require running as root (unless net.ipv6.ip_nonlocal_bind)")
|
917
957
|
ap2.add_argument("--s-thead", metavar="SEC", type=int, default=120, help="socket timeout (read request header)")
|
918
|
-
ap2.add_argument("--s-tbody", metavar="SEC", type=float, default=186, help="socket timeout (read/write request/response bodies). Use 60 on fast servers (default is extremely safe). Disable with 0 if reverse-proxied for a 2%% speed boost")
|
958
|
+
ap2.add_argument("--s-tbody", metavar="SEC", type=float, default=186.0, help="socket timeout (read/write request/response bodies). Use 60 on fast servers (default is extremely safe). Disable with 0 if reverse-proxied for a 2%% speed boost")
|
919
959
|
ap2.add_argument("--s-rd-sz", metavar="B", type=int, default=256*1024, help="socket read size in bytes (indirectly affects filesystem writes; recommendation: keep equal-to or lower-than \033[33m--iobuf\033[0m)")
|
920
960
|
ap2.add_argument("--s-wr-sz", metavar="B", type=int, default=256*1024, help="socket write size in bytes")
|
921
|
-
ap2.add_argument("--s-wr-slp", metavar="SEC", type=float, default=0, help="debug: socket write delay in seconds")
|
922
|
-
ap2.add_argument("--rsp-slp", metavar="SEC", type=float, default=0, help="debug: response delay in seconds")
|
923
|
-
ap2.add_argument("--rsp-jtr", metavar="SEC", type=float, default=0, help="debug: response delay, random duration 0..\033[33mSEC\033[0m")
|
961
|
+
ap2.add_argument("--s-wr-slp", metavar="SEC", type=float, default=0.0, help="debug: socket write delay in seconds")
|
962
|
+
ap2.add_argument("--rsp-slp", metavar="SEC", type=float, default=0.0, help="debug: response delay in seconds")
|
963
|
+
ap2.add_argument("--rsp-jtr", metavar="SEC", type=float, default=0.0, help="debug: response delay, random duration 0..\033[33mSEC\033[0m")
|
924
964
|
|
925
965
|
|
926
966
|
def add_tls(ap, cert_path):
|
@@ -928,10 +968,10 @@ def add_tls(ap, cert_path):
|
|
928
968
|
ap2.add_argument("--http-only", action="store_true", help="disable ssl/tls -- force plaintext")
|
929
969
|
ap2.add_argument("--https-only", action="store_true", help="disable plaintext -- force tls")
|
930
970
|
ap2.add_argument("--cert", metavar="PATH", type=u, default=cert_path, help="path to TLS certificate")
|
931
|
-
ap2.add_argument("--ssl-ver", metavar="LIST", type=u, help="set allowed ssl/tls versions; [\033[32mhelp\033[0m] shows available versions; default is what your python version considers safe")
|
932
|
-
ap2.add_argument("--ciphers", metavar="LIST", type=u, help="set allowed ssl/tls ciphers; [\033[32mhelp\033[0m] shows available ciphers")
|
971
|
+
ap2.add_argument("--ssl-ver", metavar="LIST", type=u, default="", help="set allowed ssl/tls versions; [\033[32mhelp\033[0m] shows available versions; default is what your python version considers safe")
|
972
|
+
ap2.add_argument("--ciphers", metavar="LIST", type=u, default="", help="set allowed ssl/tls ciphers; [\033[32mhelp\033[0m] shows available ciphers")
|
933
973
|
ap2.add_argument("--ssl-dbg", action="store_true", help="dump some tls info")
|
934
|
-
ap2.add_argument("--ssl-log", metavar="PATH", type=u, help="log master secrets for later decryption in wireshark")
|
974
|
+
ap2.add_argument("--ssl-log", metavar="PATH", type=u, default="", help="log master secrets for later decryption in wireshark")
|
935
975
|
|
936
976
|
|
937
977
|
def add_cert(ap, cert_path):
|
@@ -944,12 +984,12 @@ def add_cert(ap, cert_path):
|
|
944
984
|
ap2.add_argument("--crt-nolo", action="store_true", help="do not add 127.0.0.1 / localhost into cert")
|
945
985
|
ap2.add_argument("--crt-nohn", action="store_true", help="do not add mDNS names / hostname into cert")
|
946
986
|
ap2.add_argument("--crt-dir", metavar="PATH", default=cert_dir, help="where to save the CA cert")
|
947
|
-
ap2.add_argument("--crt-cdays", metavar="D", type=float, default=3650, help="ca-certificate expiration time in days")
|
948
|
-
ap2.add_argument("--crt-sdays", metavar="D", type=float, default=365, help="server-cert expiration time in days")
|
987
|
+
ap2.add_argument("--crt-cdays", metavar="D", type=float, default=3650.0, help="ca-certificate expiration time in days")
|
988
|
+
ap2.add_argument("--crt-sdays", metavar="D", type=float, default=365.0, help="server-cert expiration time in days")
|
949
989
|
ap2.add_argument("--crt-cn", metavar="TXT", type=u, default="partyco", help="CA/server-cert common-name")
|
950
990
|
ap2.add_argument("--crt-cnc", metavar="TXT", type=u, default="--crt-cn", help="override CA name")
|
951
991
|
ap2.add_argument("--crt-cns", metavar="TXT", type=u, default="--crt-cn cpp", help="override server-cert name")
|
952
|
-
ap2.add_argument("--crt-back", metavar="HRS", type=float, default=72, help="backdate in hours")
|
992
|
+
ap2.add_argument("--crt-back", metavar="HRS", type=float, default=72.0, help="backdate in hours")
|
953
993
|
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")
|
954
994
|
|
955
995
|
|
@@ -990,7 +1030,7 @@ def add_zc_mdns(ap):
|
|
990
1030
|
ap2.add_argument("--zm-mnic", action="store_true", help="merge NICs which share subnets; assume that same subnet means same network")
|
991
1031
|
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")
|
992
1032
|
ap2.add_argument("--zm-noneg", action="store_true", help="disable NSEC replies -- try this if some clients don't see copyparty")
|
993
|
-
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")
|
1033
|
+
ap2.add_argument("--zm-spam", metavar="SEC", type=float, default=0.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")
|
994
1034
|
|
995
1035
|
|
996
1036
|
def add_zc_ssdp(ap):
|
@@ -1005,14 +1045,15 @@ def add_zc_ssdp(ap):
|
|
1005
1045
|
|
1006
1046
|
def add_ftp(ap):
|
1007
1047
|
ap2 = ap.add_argument_group('FTP options (TCP only)')
|
1008
|
-
ap2.add_argument("--ftp", metavar="PORT", type=int, help="enable FTP server on \033[33mPORT\033[0m, for example \033[32m3921")
|
1009
|
-
ap2.add_argument("--ftps", metavar="PORT", type=int, help="enable FTPS server on \033[33mPORT\033[0m, for example \033[32m3990")
|
1048
|
+
ap2.add_argument("--ftp", metavar="PORT", type=int, default=0, help="enable FTP server on \033[33mPORT\033[0m, for example \033[32m3921")
|
1049
|
+
ap2.add_argument("--ftps", metavar="PORT", type=int, default=0, help="enable FTPS server on \033[33mPORT\033[0m, for example \033[32m3990")
|
1010
1050
|
ap2.add_argument("--ftpv", action="store_true", help="verbose")
|
1011
1051
|
ap2.add_argument("--ftp4", action="store_true", help="only listen on IPv4")
|
1012
1052
|
ap2.add_argument("--ftp-ipa", metavar="CIDR", type=u, default="", help="only accept connections from IP-addresses inside \033[33mCIDR\033[0m; specify [\033[32many\033[0m] to disable inheriting \033[33m--ipa\033[0m. Examples: [\033[32mlan\033[0m] or [\033[32m10.89.0.0/16, 192.168.33.0/24\033[0m]")
|
1053
|
+
ap2.add_argument("--ftp-no-ow", action="store_true", help="if target file exists, reject upload instead of overwrite")
|
1013
1054
|
ap2.add_argument("--ftp-wt", metavar="SEC", type=int, default=7, help="grace period for resuming interrupted uploads (any client can write to any file last-modified more recently than \033[33mSEC\033[0m seconds ago)")
|
1014
|
-
ap2.add_argument("--ftp-nat", metavar="ADDR", type=u, help="the NAT address to use for passive connections")
|
1015
|
-
ap2.add_argument("--ftp-pr", metavar="P-P", type=u, help="the range of TCP ports to use for passive connections, for example \033[32m12000-13000")
|
1055
|
+
ap2.add_argument("--ftp-nat", metavar="ADDR", type=u, default="", help="the NAT address to use for passive connections")
|
1056
|
+
ap2.add_argument("--ftp-pr", metavar="P-P", type=u, default="", help="the range of TCP ports to use for passive connections, for example \033[32m12000-13000")
|
1016
1057
|
|
1017
1058
|
|
1018
1059
|
def add_webdav(ap):
|
@@ -1026,14 +1067,15 @@ def add_webdav(ap):
|
|
1026
1067
|
|
1027
1068
|
def add_tftp(ap):
|
1028
1069
|
ap2 = ap.add_argument_group('TFTP options (UDP only)')
|
1029
|
-
ap2.add_argument("--tftp", metavar="PORT", type=int, help="enable TFTP server on \033[33mPORT\033[0m, for example \033[32m69 \033[0mor \033[32m3969")
|
1070
|
+
ap2.add_argument("--tftp", metavar="PORT", type=int, default=0, help="enable TFTP server on \033[33mPORT\033[0m, for example \033[32m69 \033[0mor \033[32m3969")
|
1071
|
+
ap2.add_argument("--tftp4", action="store_true", help="only listen on IPv4")
|
1030
1072
|
ap2.add_argument("--tftpv", action="store_true", help="verbose")
|
1031
1073
|
ap2.add_argument("--tftpvv", action="store_true", help="verboser")
|
1032
1074
|
ap2.add_argument("--tftp-no-fast", action="store_true", help="debug: disable optimizations")
|
1033
1075
|
ap2.add_argument("--tftp-lsf", metavar="PTN", type=u, default="\\.?(dir|ls)(\\.txt)?", help="return a directory listing if a file with this name is requested and it does not exist; defaults matches .ls, dir, .dir.txt, ls.txt, ...")
|
1034
1076
|
ap2.add_argument("--tftp-nols", action="store_true", help="if someone tries to download a directory, return an error instead of showing its directory listing")
|
1035
1077
|
ap2.add_argument("--tftp-ipa", metavar="CIDR", type=u, default="", help="only accept connections from IP-addresses inside \033[33mCIDR\033[0m; specify [\033[32many\033[0m] to disable inheriting \033[33m--ipa\033[0m. Examples: [\033[32mlan\033[0m] or [\033[32m10.89.0.0/16, 192.168.33.0/24\033[0m]")
|
1036
|
-
ap2.add_argument("--tftp-pr", metavar="P-P", type=u, help="the range of UDP ports to use for data transfer, for example \033[32m12000-13000")
|
1078
|
+
ap2.add_argument("--tftp-pr", metavar="P-P", type=u, default="", help="the range of UDP ports to use for data transfer, for example \033[32m12000-13000")
|
1037
1079
|
|
1038
1080
|
|
1039
1081
|
def add_smb(ap):
|
@@ -1109,7 +1151,7 @@ def add_safety(ap):
|
|
1109
1151
|
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")
|
1110
1152
|
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")
|
1111
1153
|
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")
|
1112
|
-
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]")
|
1154
|
+
ap2.add_argument("--ls", metavar="U[,V[,F]]", type=u, default="", help="do a sanity/safety check of all volumes on startup; arguments \033[33mUSER\033[0m,\033[33mVOL\033[0m,\033[33mFLAGS\033[0m (see \033[33m--help-ls\033[0m); example [\033[32m**,*,ln,p,r\033[0m]")
|
1113
1155
|
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)")
|
1114
1156
|
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)")
|
1115
1157
|
ap2.add_argument("--no-dot-mv", action="store_true", help="disallow moving dotfiles; makes it impossible to move folders containing dotfiles")
|
@@ -1119,7 +1161,7 @@ def add_safety(ap):
|
|
1119
1161
|
ap2.add_argument("--vague-403", action="store_true", help="send 404 instead of 403 (security through ambiguity, very enterprise)")
|
1120
1162
|
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")
|
1121
1163
|
ap2.add_argument("--no-robots", action="store_true", help="adds http and html headers asking search engines to not index anything (volflag=norobots)")
|
1122
|
-
ap2.add_argument("--logout", metavar="H", type=float, default=
|
1164
|
+
ap2.add_argument("--logout", metavar="H", type=float, default=8086.0, help="logout clients after \033[33mH\033[0m hours of inactivity; [\033[32m0.0028\033[0m]=10sec, [\033[32m0.1\033[0m]=6min, [\033[32m24\033[0m]=day, [\033[32m168\033[0m]=week, [\033[32m720\033[0m]=month, [\033[32m8760\033[0m]=year)")
|
1123
1165
|
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]")
|
1124
1166
|
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")
|
1125
1167
|
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")
|
@@ -1155,7 +1197,7 @@ def add_shutdown(ap):
|
|
1155
1197
|
def add_logging(ap):
|
1156
1198
|
ap2 = ap.add_argument_group('logging options')
|
1157
1199
|
ap2.add_argument("-q", action="store_true", help="quiet; disable most STDOUT messages")
|
1158
|
-
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)")
|
1200
|
+
ap2.add_argument("-lo", metavar="PATH", type=u, default="", help="logfile, example: \033[32mcpp-%%Y-%%m%%d-%%H%%M%%S.txt.xz\033[0m (NB: some errors may appear on STDOUT only)")
|
1159
1201
|
ap2.add_argument("--no-ansi", action="store_true", default=not VT100, help="disable colors; same as environment-variable NO_COLOR")
|
1160
1202
|
ap2.add_argument("--ansi", action="store_true", help="force colors; overrides environment-variable NO_COLOR")
|
1161
1203
|
ap2.add_argument("--no-logflush", action="store_true", help="don't flush the logfile after each write; tiny bit faster")
|
@@ -1182,10 +1224,10 @@ def add_thumbnail(ap):
|
|
1182
1224
|
ap2.add_argument("--no-athumb", action="store_true", help="disable audio thumbnails (spectrograms) (volflag=dathumb)")
|
1183
1225
|
ap2.add_argument("--th-size", metavar="WxH", default="320x256", help="thumbnail res (volflag=thsize)")
|
1184
1226
|
ap2.add_argument("--th-mt", metavar="CORES", type=int, default=CORES, help="num cpu cores to use for generating thumbnails")
|
1185
|
-
ap2.add_argument("--th-convt", metavar="SEC", type=float, default=60, help="conversion timeout in seconds (volflag=convt)")
|
1186
|
-
ap2.add_argument("--th-ram-max", metavar="GB", type=float, default=6, help="max memory usage (GiB) permitted by thumbnailer; not very accurate")
|
1187
|
-
ap2.add_argument("--th-crop", metavar="TXT", type=u, default="y", help="crop thumbnails to 4:3 or keep dynamic height; client can override in UI unless force. [\033[
|
1188
|
-
ap2.add_argument("--th-x3", metavar="TXT", type=u, default="n", help="show thumbs at 3x resolution; client can override in UI unless force. [\033[
|
1227
|
+
ap2.add_argument("--th-convt", metavar="SEC", type=float, default=60.0, help="conversion timeout in seconds (volflag=convt)")
|
1228
|
+
ap2.add_argument("--th-ram-max", metavar="GB", type=float, default=6.0, help="max memory usage (GiB) permitted by thumbnailer; not very accurate")
|
1229
|
+
ap2.add_argument("--th-crop", metavar="TXT", type=u, default="y", help="crop thumbnails to 4:3 or keep dynamic height; client can override in UI unless force. [\033[32my\033[0m]=crop, [\033[32mn\033[0m]=nocrop, [\033[32mfy\033[0m]=force-y, [\033[32mfn\033[0m]=force-n (volflag=crop)")
|
1230
|
+
ap2.add_argument("--th-x3", metavar="TXT", type=u, default="n", help="show thumbs at 3x resolution; client can override in UI unless force. [\033[32my\033[0m]=yes, [\033[32mn\033[0m]=no, [\033[32mfy\033[0m]=force-yes, [\033[32mfn\033[0m]=force-no (volflag=th3x)")
|
1189
1231
|
ap2.add_argument("--th-dec", metavar="LIBS", default="vips,pil,ff", help="image decoders, in order of preference")
|
1190
1232
|
ap2.add_argument("--th-no-jpg", action="store_true", help="disable jpg output")
|
1191
1233
|
ap2.add_argument("--th-no-webp", action="store_true", help="disable webp output")
|
@@ -1224,8 +1266,8 @@ def add_db_general(ap, hcores):
|
|
1224
1266
|
ap2.add_argument("-e2v", action="store_true", help="verify file integrity; rehash all files and compare with db")
|
1225
1267
|
ap2.add_argument("-e2vu", action="store_true", help="on hash mismatch: update the database with the new hash")
|
1226
1268
|
ap2.add_argument("-e2vp", action="store_true", help="on hash mismatch: panic and quit copyparty")
|
1227
|
-
ap2.add_argument("--hist", metavar="PATH", type=u, help="where to store volume data (db, thumbs) (volflag=hist)")
|
1228
|
-
ap2.add_argument("--no-hash", metavar="PTN", type=u, help="regex: disable hashing of matching absolute-filesystem-paths during e2ds folder scans (volflag=nohash)")
|
1269
|
+
ap2.add_argument("--hist", metavar="PATH", type=u, default="", help="where to store volume data (db, thumbs); default is a folder named \".hist\" inside each volume (volflag=hist)")
|
1270
|
+
ap2.add_argument("--no-hash", metavar="PTN", type=u, default="", help="regex: disable hashing of matching absolute-filesystem-paths during e2ds folder scans (volflag=nohash)")
|
1229
1271
|
ap2.add_argument("--no-idx", metavar="PTN", type=u, default=noidx, help="regex: disable indexing of matching absolute-filesystem-paths during e2ds folder scans (volflag=noidx)")
|
1230
1272
|
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")
|
1231
1273
|
ap2.add_argument("--re-dhash", action="store_true", help="force a cache rebuild on startup; enable this once if it gets out of sync (should never be necessary)")
|
@@ -1234,7 +1276,7 @@ def add_db_general(ap, hcores):
|
|
1234
1276
|
ap2.add_argument("--xlink", action="store_true", help="on upload: check all volumes for dupes, not just the target volume (volflag=xlink)")
|
1235
1277
|
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")
|
1236
1278
|
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)")
|
1237
|
-
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, ...)")
|
1279
|
+
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, ...)")
|
1238
1280
|
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")
|
1239
1281
|
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")
|
1240
1282
|
ap2.add_argument("--dotsrch", action="store_true", help="show dotfiles in search results (volflags: dotsrch | nodotsrch)")
|
@@ -1287,6 +1329,7 @@ def add_og(ap):
|
|
1287
1329
|
def add_ui(ap, retry):
|
1288
1330
|
ap2 = ap.add_argument_group('ui options')
|
1289
1331
|
ap2.add_argument("--grid", action="store_true", help="show grid/thumbnails by default (volflag=grid)")
|
1332
|
+
ap2.add_argument("--gsel", action="store_true", help="select files in grid by ctrl-click (volflag=gsel)")
|
1290
1333
|
ap2.add_argument("--lang", metavar="LANG", type=u, default="eng", help="language; one of the following: \033[32meng nor\033[0m")
|
1291
1334
|
ap2.add_argument("--theme", metavar="NUM", type=int, default=0, help="default theme to use (0..7)")
|
1292
1335
|
ap2.add_argument("--themes", metavar="NUM", type=int, default=8, help="number of themes installed")
|
@@ -1295,8 +1338,8 @@ def add_ui(ap, retry):
|
|
1295
1338
|
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)")
|
1296
1339
|
ap2.add_argument("--favico", metavar="TXT", type=u, default="c 000 none" if retry else "🎉 000 none", help="\033[33mfavicon-text\033[0m [ \033[33mforeground\033[0m [ \033[33mbackground\033[0m ] ], set blank to disable")
|
1297
1340
|
ap2.add_argument("--mpmc", metavar="URL", type=u, default="", help="change the mediaplayer-toggle mouse cursor; URL to a folder with {2..5}.png inside (or disable with [\033[32m.\033[0m])")
|
1298
|
-
ap2.add_argument("--js-browser", metavar="L", type=u, help="URL to additional JS to include")
|
1299
|
-
ap2.add_argument("--css-browser", metavar="L", type=u, help="URL to additional CSS to include")
|
1341
|
+
ap2.add_argument("--js-browser", metavar="L", type=u, default="", help="URL to additional JS to include")
|
1342
|
+
ap2.add_argument("--css-browser", metavar="L", type=u, default="", help="URL to additional CSS to include")
|
1300
1343
|
ap2.add_argument("--html-head", metavar="TXT", type=u, default="", help="text to append to the <head> of all HTML pages; can be @PATH to send the contents of a file at PATH, and/or begin with %% to render as jinja2 template (volflag=html_head)")
|
1301
1344
|
ap2.add_argument("--ih", action="store_true", help="if a folder contains index.html, show that instead of the directory listing by default (can be changed in the client settings UI, or add ?v to URL for override)")
|
1302
1345
|
ap2.add_argument("--textfiles", metavar="CSV", type=u, default="txt,nfo,diz,cue,readme", help="file extensions to present as plaintext")
|
@@ -1316,14 +1359,16 @@ def add_debug(ap):
|
|
1316
1359
|
ap2 = ap.add_argument_group('debug options')
|
1317
1360
|
ap2.add_argument("--vc", action="store_true", help="verbose config file parser (explain config)")
|
1318
1361
|
ap2.add_argument("--cgen", action="store_true", help="generate config file from current config (best-effort; probably buggy)")
|
1362
|
+
if hasattr(select, "poll"):
|
1363
|
+
ap2.add_argument("--no-poll", action="store_true", help="kernel-bug workaround: disable poll; use select instead (limits max num clients to ~700)")
|
1319
1364
|
ap2.add_argument("--no-sendfile", action="store_true", help="kernel-bug workaround: disable sendfile; do a safe and slow read-send-loop instead")
|
1320
1365
|
ap2.add_argument("--no-scandir", action="store_true", help="kernel-bug workaround: disable scandir; do a listdir + stat on each file instead")
|
1321
1366
|
ap2.add_argument("--no-fastboot", action="store_true", help="wait for initial filesystem indexing before accepting client requests")
|
1322
1367
|
ap2.add_argument("--no-htp", action="store_true", help="disable httpserver threadpool, create threads as-needed instead")
|
1323
1368
|
ap2.add_argument("--srch-dbg", action="store_true", help="explain search processing, and do some extra expensive sanity checks")
|
1324
1369
|
ap2.add_argument("--rclone-mdns", action="store_true", help="use mdns-domain instead of server-ip on /?hc")
|
1325
|
-
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")
|
1326
|
-
ap2.add_argument("--log-thrs", metavar="SEC", type=float, help="list active threads every \033[33mSEC\033[0m")
|
1370
|
+
ap2.add_argument("--stackmon", metavar="P,S", type=u, default="", 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")
|
1371
|
+
ap2.add_argument("--log-thrs", metavar="SEC", type=float, default=0.0, help="list active threads every \033[33mSEC\033[0m")
|
1327
1372
|
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")
|
1328
1373
|
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")
|
1329
1374
|
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)")
|
@@ -1526,7 +1571,7 @@ def main(argv = None, rsrc = None) :
|
|
1526
1571
|
if hard > 0: # -1 == infinite
|
1527
1572
|
nc = min(nc, int(hard / 4))
|
1528
1573
|
except:
|
1529
|
-
nc = 512
|
1574
|
+
nc = 486 # mdns/ssdp restart headroom; select() maxfd is 512 on windows
|
1530
1575
|
|
1531
1576
|
retry = False
|
1532
1577
|
for fmtr in [RiceFormatter, RiceFormatter, Dodge11874, BasicDodge11874]:
|
@@ -1571,6 +1616,9 @@ def main(argv = None, rsrc = None) :
|
|
1571
1616
|
if getattr(al, k1):
|
1572
1617
|
setattr(al, k2, False)
|
1573
1618
|
|
1619
|
+
if not HAVE_IPV6 and al.i == "::":
|
1620
|
+
al.i = "0.0.0.0"
|
1621
|
+
|
1574
1622
|
al.i = al.i.split(",")
|
1575
1623
|
try:
|
1576
1624
|
if "-" in al.p:
|
@@ -1619,6 +1667,9 @@ def main(argv = None, rsrc = None) :
|
|
1619
1667
|
if not hasattr(os, "sendfile"):
|
1620
1668
|
al.no_sendfile = True
|
1621
1669
|
|
1670
|
+
if not hasattr(select, "poll"):
|
1671
|
+
al.no_poll = True
|
1672
|
+
|
1622
1673
|
# signal.signal(signal.SIGINT, sighandler)
|
1623
1674
|
|
1624
1675
|
SvcHub(al, dal, argv, "".join(printed)).run()
|
copyparty/__version__.py
CHANGED
copyparty/authsrv.py
CHANGED
@@ -17,6 +17,8 @@ from .bos import bos
|
|
17
17
|
from .cfg import flagdescs, permdescs, vf_bmap, vf_cmap, vf_vmap
|
18
18
|
from .pwhash import PWHash
|
19
19
|
from .util import (
|
20
|
+
DEF_MTE,
|
21
|
+
DEF_MTH,
|
20
22
|
EXTS,
|
21
23
|
IMPLICATIONS,
|
22
24
|
MIMES,
|
@@ -468,6 +470,13 @@ class VFS(object):
|
|
468
470
|
)
|
469
471
|
# skip uhtml because it's rarely needed
|
470
472
|
|
473
|
+
def get_perms(self, vpath , uname ) :
|
474
|
+
zbl = self.can_access(vpath, uname)
|
475
|
+
ret = "".join(ch for ch, ok in zip("rwmdgGa.", zbl) if ok)
|
476
|
+
if "rwmd" in ret and "a." in ret:
|
477
|
+
ret += "A"
|
478
|
+
return ret
|
479
|
+
|
471
480
|
def get(
|
472
481
|
self,
|
473
482
|
vpath ,
|
@@ -1610,11 +1619,14 @@ class AuthSrv(object):
|
|
1610
1619
|
use = True
|
1611
1620
|
lim.nosub = True
|
1612
1621
|
|
1613
|
-
zs = vol.flags.get("df") or
|
1614
|
-
|
1615
|
-
)
|
1616
|
-
if zs:
|
1622
|
+
zs = vol.flags.get("df") or self.args.df or ""
|
1623
|
+
if zs not in ("", "0"):
|
1617
1624
|
use = True
|
1625
|
+
try:
|
1626
|
+
_ = float(zs)
|
1627
|
+
zs = "%sg" % (zs)
|
1628
|
+
except:
|
1629
|
+
pass
|
1618
1630
|
lim.dfl = unhumanize(zs)
|
1619
1631
|
|
1620
1632
|
zs = vol.flags.get("sz")
|
@@ -2257,10 +2269,11 @@ class AuthSrv(object):
|
|
2257
2269
|
"",
|
2258
2270
|
]
|
2259
2271
|
|
2260
|
-
csv = set("i p".split())
|
2272
|
+
csv = set("i p th_covers zm_on zm_off zs_on zs_off".split())
|
2261
2273
|
zs = "c ihead mtm mtp on403 on404 xad xar xau xiu xban xbd xbr xbu xm"
|
2262
2274
|
lst = set(zs.split())
|
2263
|
-
askip = set("a v c vc cgen theme".split())
|
2275
|
+
askip = set("a v c vc cgen exp_lg exp_md theme".split())
|
2276
|
+
fskip = set("exp_lg exp_md mv_re_r mv_re_t rm_re_r rm_re_t".split())
|
2264
2277
|
|
2265
2278
|
# keymap from argv to vflag
|
2266
2279
|
amap = vf_bmap()
|
@@ -2281,11 +2294,35 @@ class AuthSrv(object):
|
|
2281
2294
|
for k, v in args.items():
|
2282
2295
|
if k in askip:
|
2283
2296
|
continue
|
2297
|
+
|
2298
|
+
try:
|
2299
|
+
v = v.pattern
|
2300
|
+
if k in ("idp_gsep", "tftp_lsf"):
|
2301
|
+
v = v[1:-1] # close enough
|
2302
|
+
except:
|
2303
|
+
pass
|
2304
|
+
|
2305
|
+
skip = False
|
2306
|
+
for k2, defstr in (("mte", DEF_MTE), ("mth", DEF_MTH)):
|
2307
|
+
if k != k2:
|
2308
|
+
continue
|
2309
|
+
s1 = list(sorted(list(v)))
|
2310
|
+
s2 = list(sorted(defstr.split(",")))
|
2311
|
+
if s1 == s2:
|
2312
|
+
skip = True
|
2313
|
+
break
|
2314
|
+
v = ",".join(s1)
|
2315
|
+
|
2316
|
+
if skip:
|
2317
|
+
continue
|
2318
|
+
|
2284
2319
|
if k in csv:
|
2285
2320
|
v = ", ".join([str(za) for za in v])
|
2286
2321
|
try:
|
2287
2322
|
v2 = getattr(self.dargs, k)
|
2288
|
-
if
|
2323
|
+
if k == "tcolor" and len(v2) == 3:
|
2324
|
+
v2 = "".join([x * 2 for x in v2])
|
2325
|
+
if v == v2 or v.replace(", ", ",") == v2:
|
2289
2326
|
continue
|
2290
2327
|
except:
|
2291
2328
|
continue
|
@@ -2344,6 +2381,7 @@ class AuthSrv(object):
|
|
2344
2381
|
pstr += pchar
|
2345
2382
|
if "g" in pstr and "G" in pstr:
|
2346
2383
|
pstr = pstr.replace("g", "")
|
2384
|
+
pstr = pstr.replace("rwmd.a", "A")
|
2347
2385
|
try:
|
2348
2386
|
vperms[pstr].append(uname)
|
2349
2387
|
except:
|
@@ -2353,24 +2391,48 @@ class AuthSrv(object):
|
|
2353
2391
|
trues = []
|
2354
2392
|
vals = []
|
2355
2393
|
for k, v in sorted(vol.flags.items()):
|
2394
|
+
if k in fskip:
|
2395
|
+
continue
|
2396
|
+
|
2397
|
+
try:
|
2398
|
+
v = v.pattern
|
2399
|
+
except:
|
2400
|
+
pass
|
2401
|
+
|
2356
2402
|
try:
|
2357
2403
|
ak = vmap[k]
|
2358
|
-
|
2404
|
+
v2 = getattr(self.args, ak)
|
2405
|
+
|
2406
|
+
try:
|
2407
|
+
v2 = v2.pattern
|
2408
|
+
except:
|
2409
|
+
pass
|
2410
|
+
|
2411
|
+
if v2 is v:
|
2359
2412
|
continue
|
2360
2413
|
except:
|
2361
2414
|
pass
|
2362
2415
|
|
2416
|
+
skip = False
|
2417
|
+
for k2, defstr in (("mte", DEF_MTE), ("mth", DEF_MTH)):
|
2418
|
+
if k != k2:
|
2419
|
+
continue
|
2420
|
+
s1 = list(sorted(list(v)))
|
2421
|
+
s2 = list(sorted(defstr.split(",")))
|
2422
|
+
if s1 == s2:
|
2423
|
+
skip = True
|
2424
|
+
break
|
2425
|
+
v = ",".join(s1)
|
2426
|
+
|
2427
|
+
if skip:
|
2428
|
+
continue
|
2429
|
+
|
2363
2430
|
if k in lst:
|
2364
2431
|
for ve in v:
|
2365
2432
|
vals.append("{}: {}".format(k, ve))
|
2366
2433
|
elif v is True:
|
2367
2434
|
trues.append(k)
|
2368
2435
|
elif v is not False:
|
2369
|
-
try:
|
2370
|
-
v = v.pattern
|
2371
|
-
except:
|
2372
|
-
pass
|
2373
|
-
|
2374
2436
|
vals.append("{}: {}".format(k, v))
|
2375
2437
|
pops = []
|
2376
2438
|
for k1, k2 in IMPLICATIONS:
|
copyparty/cert.py
CHANGED
@@ -79,6 +79,8 @@ def _read_crt(args, fn):
|
|
79
79
|
|
80
80
|
|
81
81
|
def _gen_ca(log , args):
|
82
|
+
nlog = lambda msg, c=0: log("cert-gen-ca", msg, c)
|
83
|
+
|
82
84
|
expiry = _read_crt(args, "ca.pem")[0]
|
83
85
|
if time.time() + args.crt_cdays * 60 * 60 * 24 * 0.1 < expiry:
|
84
86
|
return
|
@@ -109,16 +111,18 @@ def _gen_ca(log , args):
|
|
109
111
|
|
110
112
|
bname = os.path.join(args.crt_dir, "ca")
|
111
113
|
try:
|
112
|
-
wunlink(
|
114
|
+
wunlink(nlog, bname + ".key", VF)
|
113
115
|
except:
|
114
116
|
pass
|
115
|
-
wrename(
|
116
|
-
wunlink(
|
117
|
+
wrename(nlog, bname + "-key.pem", bname + ".key", VF)
|
118
|
+
wunlink(nlog, bname + ".csr", VF)
|
117
119
|
|
118
120
|
log("cert", "new ca OK", 2)
|
119
121
|
|
120
122
|
|
121
123
|
def _gen_srv(log , args, netdevs ):
|
124
|
+
nlog = lambda msg, c=0: log("cert-gen-srv", msg, c)
|
125
|
+
|
122
126
|
names = args.crt_ns.split(",") if args.crt_ns else []
|
123
127
|
if not args.crt_exact:
|
124
128
|
for n in names[:]:
|
@@ -192,11 +196,11 @@ def _gen_srv(log , args, netdevs ):
|
|
192
196
|
|
193
197
|
bname = os.path.join(args.crt_dir, "srv")
|
194
198
|
try:
|
195
|
-
wunlink(
|
199
|
+
wunlink(nlog, bname + ".key", VF)
|
196
200
|
except:
|
197
201
|
pass
|
198
|
-
wrename(
|
199
|
-
wunlink(
|
202
|
+
wrename(nlog, bname + "-key.pem", bname + ".key", VF)
|
203
|
+
wunlink(nlog, bname + ".csr", VF)
|
200
204
|
|
201
205
|
with open(os.path.join(args.crt_dir, "ca.pem"), "rb") as f:
|
202
206
|
ca = f.read()
|
copyparty/cfg.py
CHANGED
@@ -35,6 +35,7 @@ def vf_bmap() :
|
|
35
35
|
"e2vp",
|
36
36
|
"exp",
|
37
37
|
"grid",
|
38
|
+
"gsel",
|
38
39
|
"hardlink",
|
39
40
|
"magic",
|
40
41
|
"no_sb_md",
|
@@ -144,6 +145,7 @@ flagcats = {
|
|
144
145
|
"maxb=1g,300": "max 1 GiB over 5min (suffixes: b, k, m, g, t)",
|
145
146
|
"vmaxb=1g": "total volume size max 1 GiB (suffixes: b, k, m, g, t)",
|
146
147
|
"vmaxn=4k": "max 4096 files in volume (suffixes: b, k, m, g, t)",
|
148
|
+
"medialinks": "return medialinks for non-up2k uploads (not hotlinks)",
|
147
149
|
"rand": "force randomized filenames, 9 chars long by default",
|
148
150
|
"nrand=N": "randomized filenames are N chars long",
|
149
151
|
"u2ts=fc": "[f]orce [c]lient-last-modified or [u]pload-time",
|
@@ -213,6 +215,7 @@ flagcats = {
|
|
213
215
|
},
|
214
216
|
"client and ux": {
|
215
217
|
"grid": "show grid/thumbnails by default",
|
218
|
+
"gsel": "select files in grid by ctrl-click",
|
216
219
|
"sort": "default sort order",
|
217
220
|
"unlist": "dont list files matching REGEX",
|
218
221
|
"html_head=TXT": "includes TXT in the <head>, or @PATH for file at PATH",
|