copyparty 1.15.9__py3-none-any.whl → 1.16.0__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/__init__.py +1 -0
- copyparty/__main__.py +16 -1
- copyparty/__version__.py +3 -3
- copyparty/authsrv.py +15 -10
- copyparty/broker_mp.py +40 -5
- copyparty/broker_mpw.py +20 -19
- copyparty/broker_thr.py +2 -2
- copyparty/cfg.py +4 -0
- copyparty/ftpd.py +1 -0
- copyparty/httpcli.py +285 -79
- copyparty/httpsrv.py +39 -0
- copyparty/metrics.py +3 -0
- copyparty/svchub.py +47 -33
- copyparty/szip.py +1 -1
- copyparty/tcpsrv.py +2 -2
- copyparty/tftpd.py +1 -0
- copyparty/th_srv.py +10 -3
- copyparty/up2k.py +339 -69
- copyparty/util.py +79 -11
- copyparty/web/a/partyfuse.py +3 -2
- copyparty/web/a/u2c.py +20 -5
- copyparty/web/browser.css.gz +0 -0
- copyparty/web/browser.js.gz +0 -0
- copyparty/web/shares.js.gz +0 -0
- copyparty/web/splash.css.gz +0 -0
- copyparty/web/splash.html +24 -3
- copyparty/web/splash.js.gz +0 -0
- copyparty/web/ui.css.gz +0 -0
- copyparty/web/util.js.gz +0 -0
- {copyparty-1.15.9.dist-info → copyparty-1.16.0.dist-info}/METADATA +12 -4
- {copyparty-1.15.9.dist-info → copyparty-1.16.0.dist-info}/RECORD +35 -35
- {copyparty-1.15.9.dist-info → copyparty-1.16.0.dist-info}/WHEEL +1 -1
- {copyparty-1.15.9.dist-info → copyparty-1.16.0.dist-info}/LICENSE +0 -0
- {copyparty-1.15.9.dist-info → copyparty-1.16.0.dist-info}/entry_points.txt +0 -0
- {copyparty-1.15.9.dist-info → copyparty-1.16.0.dist-info}/top_level.txt +0 -0
copyparty/httpsrv.py
CHANGED
@@ -81,6 +81,7 @@ from .util import (
|
|
81
81
|
)
|
82
82
|
|
83
83
|
if TYPE_CHECKING:
|
84
|
+
from .authsrv import VFS
|
84
85
|
from .broker_util import BrokerCli
|
85
86
|
from .ssdp import SSDPr
|
86
87
|
|
@@ -127,6 +128,12 @@ class HttpSrv(object):
|
|
127
128
|
self.bans = {}
|
128
129
|
self.aclose = {}
|
129
130
|
|
131
|
+
dli = {} # info
|
132
|
+
dls = {} # state
|
133
|
+
self.dli = self.tdli = dli
|
134
|
+
self.dls = self.tdls = dls
|
135
|
+
self.iiam = '<img src="%s.cpr/iiam.gif" />' % (self.args.SRS,)
|
136
|
+
|
130
137
|
self.bound = set()
|
131
138
|
self.name = "hsrv" + nsuf
|
132
139
|
self.mutex = threading.Lock()
|
@@ -201,6 +208,9 @@ class HttpSrv(object):
|
|
201
208
|
self.start_threads(4)
|
202
209
|
|
203
210
|
if nid:
|
211
|
+
self.tdli = {}
|
212
|
+
self.tdls = {}
|
213
|
+
|
204
214
|
if self.args.stackmon:
|
205
215
|
start_stackmon(self.args.stackmon, nid)
|
206
216
|
|
@@ -573,3 +583,32 @@ class HttpSrv(object):
|
|
573
583
|
ident += "a"
|
574
584
|
|
575
585
|
self.u2idx_free[ident] = u2idx
|
586
|
+
|
587
|
+
def read_dls(
|
588
|
+
self,
|
589
|
+
):
|
590
|
+
|
591
|
+
|
592
|
+
"""
|
593
|
+
mp-broker asking for local dl-info + dl-state;
|
594
|
+
reduce overhead by sending just the vfs vpath
|
595
|
+
"""
|
596
|
+
dli = {k: (a, b, c.vpath, d, e) for k, (a, b, c, d, e) in self.dli.items()}
|
597
|
+
return (dli, self.dls)
|
598
|
+
|
599
|
+
def write_dls(
|
600
|
+
self,
|
601
|
+
sdli ,
|
602
|
+
dls ,
|
603
|
+
) :
|
604
|
+
"""
|
605
|
+
mp-broker pushing total dl-info + dl-state;
|
606
|
+
swap out the vfs vpath with the vfs node
|
607
|
+
"""
|
608
|
+
dli = {}
|
609
|
+
for k, (a, b, c, d, e) in sdli.items():
|
610
|
+
vn = self.asrv.vfs.all_vols[c]
|
611
|
+
dli[k] = (a, b, vn, d, e)
|
612
|
+
|
613
|
+
self.tdli = dli
|
614
|
+
self.tdls = dls
|
copyparty/metrics.py
CHANGED
@@ -72,6 +72,9 @@ class Metrics(object):
|
|
72
72
|
v = "{:.3f}".format(self.hsrv.t0)
|
73
73
|
addug("cpp_boot_unixtime", "seconds", v, t)
|
74
74
|
|
75
|
+
t = "number of active downloads"
|
76
|
+
addg("cpp_active_dl", str(len(self.hsrv.tdls)), t)
|
77
|
+
|
75
78
|
t = "number of open http(s) client connections"
|
76
79
|
addg("cpp_http_conns", str(self.hsrv.ncli), t)
|
77
80
|
|
copyparty/svchub.py
CHANGED
@@ -106,7 +106,7 @@ class SvcHub(object):
|
|
106
106
|
self.stopping = False
|
107
107
|
self.stopped = False
|
108
108
|
self.reload_req = False
|
109
|
-
self.
|
109
|
+
self.reload_mutex = threading.Lock()
|
110
110
|
self.stop_cond = threading.Condition()
|
111
111
|
self.nsigs = 3
|
112
112
|
self.retcode = 0
|
@@ -205,6 +205,15 @@ class SvcHub(object):
|
|
205
205
|
t = "WARNING: --s-rd-sz (%d) is larger than --iobuf (%d); this may lead to reduced performance"
|
206
206
|
self.log("root", t % (args.s_rd_sz, args.iobuf), 3)
|
207
207
|
|
208
|
+
zs = ""
|
209
|
+
if args.th_ram_max < 0.22:
|
210
|
+
zs = "generate thumbnails"
|
211
|
+
elif args.th_ram_max < 1:
|
212
|
+
zs = "generate audio waveforms or spectrograms"
|
213
|
+
if zs:
|
214
|
+
t = "WARNING: --th-ram-max is very small (%.2f GiB); will not be able to %s"
|
215
|
+
self.log("root", t % (args.th_ram_max, zs), 3)
|
216
|
+
|
208
217
|
if args.chpw and args.idp_h_usr:
|
209
218
|
t = "ERROR: user-changeable passwords is incompatible with IdP/identity-providers; you must disable either --chpw or --idp-h-usr"
|
210
219
|
self.log("root", t, 1)
|
@@ -217,13 +226,14 @@ class SvcHub(object):
|
|
217
226
|
args.chpw_no = noch
|
218
227
|
|
219
228
|
if args.ipu:
|
220
|
-
iu, nm = load_ipu(self.log, args.ipu)
|
229
|
+
iu, nm = load_ipu(self.log, args.ipu, True)
|
221
230
|
setattr(args, "ipu_iu", iu)
|
222
231
|
setattr(args, "ipu_nm", nm)
|
223
232
|
|
224
233
|
if not self.args.no_ses:
|
225
234
|
self.setup_session_db()
|
226
235
|
|
236
|
+
args.shr1 = ""
|
227
237
|
if args.shr:
|
228
238
|
self.setup_share_db()
|
229
239
|
|
@@ -372,6 +382,14 @@ class SvcHub(object):
|
|
372
382
|
|
373
383
|
self.broker = Broker(self)
|
374
384
|
|
385
|
+
# create netmaps early to avoid firewall gaps,
|
386
|
+
# but the mutex blocks multiprocessing startup
|
387
|
+
for zs in "ipu_iu ftp_ipa_nm tftp_ipa_nm".split():
|
388
|
+
try:
|
389
|
+
getattr(args, zs).mutex = threading.Lock()
|
390
|
+
except:
|
391
|
+
pass
|
392
|
+
|
375
393
|
def setup_session_db(self) :
|
376
394
|
if not HAVE_SQLITE3:
|
377
395
|
self.args.no_ses = True
|
@@ -444,6 +462,7 @@ class SvcHub(object):
|
|
444
462
|
raise Exception(t)
|
445
463
|
|
446
464
|
al.shr = "/%s/" % (al.shr,)
|
465
|
+
al.shr1 = al.shr[1:]
|
447
466
|
|
448
467
|
create = True
|
449
468
|
modified = False
|
@@ -751,8 +770,8 @@ class SvcHub(object):
|
|
751
770
|
al.idp_h_grp = al.idp_h_grp.lower()
|
752
771
|
al.idp_h_key = al.idp_h_key.lower()
|
753
772
|
|
754
|
-
al.ftp_ipa_nm = build_netmap(al.ftp_ipa or al.ipa)
|
755
|
-
al.tftp_ipa_nm = build_netmap(al.tftp_ipa or al.ipa)
|
773
|
+
al.ftp_ipa_nm = build_netmap(al.ftp_ipa or al.ipa, True)
|
774
|
+
al.tftp_ipa_nm = build_netmap(al.tftp_ipa or al.ipa, True)
|
756
775
|
|
757
776
|
mte = ODict.fromkeys(DEF_MTE.split(","), True)
|
758
777
|
al.mte = odfusion(mte, al.mte)
|
@@ -799,6 +818,24 @@ class SvcHub(object):
|
|
799
818
|
if len(al.tcolor) == 3: # fc5 => ffcc55
|
800
819
|
al.tcolor = "".join([x * 2 for x in al.tcolor])
|
801
820
|
|
821
|
+
zs = al.u2sz
|
822
|
+
zsl = zs.split(",")
|
823
|
+
if len(zsl) not in (1, 3):
|
824
|
+
t = "invalid --u2sz; must be either one number, or a comma-separated list of three numbers (min,default,max)"
|
825
|
+
raise Exception(t)
|
826
|
+
if len(zsl) < 3:
|
827
|
+
zsl = ["1", zs, zs]
|
828
|
+
zi2 = 1
|
829
|
+
for zs in zsl:
|
830
|
+
zi = int(zs)
|
831
|
+
# arbitrary constraint (anything above 2 GiB is probably unintended)
|
832
|
+
if zi < 1 or zi > 2047:
|
833
|
+
raise Exception("invalid --u2sz; minimum is 1, max is 2047")
|
834
|
+
if zi < zi2:
|
835
|
+
raise Exception("invalid --u2sz; values must be equal or ascending")
|
836
|
+
zi2 = zi
|
837
|
+
al.u2sz = ",".join(zsl)
|
838
|
+
|
802
839
|
return True
|
803
840
|
|
804
841
|
def _ipa2re(self, txt) :
|
@@ -966,41 +1003,18 @@ class SvcHub(object):
|
|
966
1003
|
except:
|
967
1004
|
self.log("root", "ssdp startup failed;\n" + min_ex(), 3)
|
968
1005
|
|
969
|
-
def reload(self) :
|
970
|
-
|
971
|
-
|
972
|
-
return "cannot reload; already in progress"
|
973
|
-
self.reloading = 1
|
974
|
-
|
975
|
-
Daemon(self._reload, "reloading")
|
976
|
-
return "reload initiated"
|
977
|
-
|
978
|
-
def _reload(self, rescan_all_vols = True, up2k = True) :
|
979
|
-
with self.up2k.mutex:
|
980
|
-
if self.reloading != 1:
|
981
|
-
return
|
982
|
-
self.reloading = 2
|
1006
|
+
def reload(self, rescan_all_vols , up2k ) :
|
1007
|
+
t = "config has been reloaded"
|
1008
|
+
with self.reload_mutex:
|
983
1009
|
self.log("root", "reloading config")
|
984
1010
|
self.asrv.reload(9 if up2k else 4)
|
985
1011
|
if up2k:
|
986
1012
|
self.up2k.reload(rescan_all_vols)
|
1013
|
+
t += "; volumes are now reinitializing"
|
987
1014
|
else:
|
988
1015
|
self.log("root", "reload done")
|
989
1016
|
self.broker.reload()
|
990
|
-
|
991
|
-
|
992
|
-
def _reload_blocking(self, rescan_all_vols = True, up2k = True) :
|
993
|
-
while True:
|
994
|
-
with self.up2k.mutex:
|
995
|
-
if self.reloading < 2:
|
996
|
-
self.reloading = 1
|
997
|
-
break
|
998
|
-
time.sleep(0.05)
|
999
|
-
|
1000
|
-
# try to handle multiple pending IdP reloads at once:
|
1001
|
-
time.sleep(0.2)
|
1002
|
-
|
1003
|
-
self._reload(rescan_all_vols=rescan_all_vols, up2k=up2k)
|
1017
|
+
return t
|
1004
1018
|
|
1005
1019
|
def _reload_sessions(self) :
|
1006
1020
|
with self.asrv.mutex:
|
@@ -1014,7 +1028,7 @@ class SvcHub(object):
|
|
1014
1028
|
|
1015
1029
|
if self.reload_req:
|
1016
1030
|
self.reload_req = False
|
1017
|
-
self.reload()
|
1031
|
+
self.reload(True, True)
|
1018
1032
|
|
1019
1033
|
self.shutdown()
|
1020
1034
|
|
copyparty/szip.py
CHANGED
@@ -94,7 +94,7 @@ def gen_hdr(
|
|
94
94
|
|
95
95
|
# spec says to put zeros when !crc if bit3 (streaming)
|
96
96
|
# however infozip does actual sz and it even works on winxp
|
97
|
-
# (same
|
97
|
+
# (same reasoning for z64 extradata later)
|
98
98
|
vsz = 0xFFFFFFFF if z64 else sz
|
99
99
|
ret += spack(b"<LL", vsz, vsz)
|
100
100
|
|
copyparty/tcpsrv.py
CHANGED
@@ -368,7 +368,7 @@ class TcpSrv(object):
|
|
368
368
|
if self.args.q:
|
369
369
|
print(msg)
|
370
370
|
|
371
|
-
self.hub.broker.say("listen", srv)
|
371
|
+
self.hub.broker.say("httpsrv.listen", srv)
|
372
372
|
|
373
373
|
self.srv = srvs
|
374
374
|
self.bound = bound
|
@@ -376,7 +376,7 @@ class TcpSrv(object):
|
|
376
376
|
self._distribute_netdevs()
|
377
377
|
|
378
378
|
def _distribute_netdevs(self):
|
379
|
-
self.hub.broker.say("set_netdevs", self.netdevs)
|
379
|
+
self.hub.broker.say("httpsrv.set_netdevs", self.netdevs)
|
380
380
|
self.hub.start_zeroconf()
|
381
381
|
gencert(self.log, self.args, self.netdevs)
|
382
382
|
self.hub.restart_ftpd()
|
copyparty/tftpd.py
CHANGED
@@ -266,6 +266,7 @@ class Tftpd(object):
|
|
266
266
|
"*",
|
267
267
|
not self.args.no_scandir,
|
268
268
|
[[True, False]],
|
269
|
+
throw=True,
|
269
270
|
)
|
270
271
|
dnames = set([x[0] for x in vfs_ls if stat.S_ISDIR(x[1].st_mode)])
|
271
272
|
dirs1 = [(v.st_mtime, v.st_size, k + "/") for k, v in vfs_ls if k in dnames]
|
copyparty/th_srv.py
CHANGED
@@ -20,7 +20,6 @@ from .util import (
|
|
20
20
|
FFMPEG_URL,
|
21
21
|
Cooldown,
|
22
22
|
Daemon,
|
23
|
-
Pebkac,
|
24
23
|
afsenc,
|
25
24
|
fsenc,
|
26
25
|
min_ex,
|
@@ -161,6 +160,7 @@ class ThumbSrv(object):
|
|
161
160
|
self.ram = {}
|
162
161
|
self.memcond = threading.Condition(self.mutex)
|
163
162
|
self.stopping = False
|
163
|
+
self.rm_nullthumbs = True # forget failed conversions on startup
|
164
164
|
self.nthr = max(1, self.args.th_mt)
|
165
165
|
|
166
166
|
self.q = Queue(self.nthr * 4)
|
@@ -858,7 +858,6 @@ class ThumbSrv(object):
|
|
858
858
|
def cleaner(self) :
|
859
859
|
interval = self.args.th_clean
|
860
860
|
while True:
|
861
|
-
time.sleep(interval)
|
862
861
|
ndirs = 0
|
863
862
|
for vol, histpath in self.asrv.vfs.histtab.items():
|
864
863
|
if histpath.startswith(vol):
|
@@ -872,6 +871,8 @@ class ThumbSrv(object):
|
|
872
871
|
self.log("\033[Jcln err in %s: %r" % (histpath, ex), 3)
|
873
872
|
|
874
873
|
self.log("\033[Jcln ok; rm {} dirs".format(ndirs))
|
874
|
+
self.rm_nullthumbs = False
|
875
|
+
time.sleep(interval)
|
875
876
|
|
876
877
|
def clean(self, histpath ) :
|
877
878
|
ret = 0
|
@@ -892,7 +893,9 @@ class ThumbSrv(object):
|
|
892
893
|
prev_b64 = None
|
893
894
|
prev_fp = ""
|
894
895
|
try:
|
895
|
-
t1 = statdir(
|
896
|
+
t1 = statdir(
|
897
|
+
self.log_func, not self.args.no_scandir, False, thumbpath, False
|
898
|
+
)
|
896
899
|
ents = sorted(list(t1))
|
897
900
|
except:
|
898
901
|
return 0
|
@@ -933,6 +936,10 @@ class ThumbSrv(object):
|
|
933
936
|
|
934
937
|
continue
|
935
938
|
|
939
|
+
if self.rm_nullthumbs and not inf.st_size:
|
940
|
+
bos.unlink(fp)
|
941
|
+
continue
|
942
|
+
|
936
943
|
if b64 == prev_b64:
|
937
944
|
self.log("rm replaced [{}]".format(fp))
|
938
945
|
bos.unlink(prev_fp)
|