copyparty 1.16.0__py3-none-any.whl → 1.16.1__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 CHANGED
@@ -870,8 +870,9 @@ def get_sects():
870
870
  use argon2id with timecost 3, 256 MiB, 4 threads, version 19 (0x13/v1.3)
871
871
 
872
872
  \033[36m--ah-alg scrypt\033[0m # which is the same as:
873
- \033[36m--ah-alg scrypt,13,2,8,4\033[0m
874
- use scrypt with cost 2**13, 2 iterations, blocksize 8, 4 threads
873
+ \033[36m--ah-alg scrypt,13,2,8,4,32\033[0m
874
+ use scrypt with cost 2**13, 2 iterations, blocksize 8, 4 threads,
875
+ and allow using up to 32 MiB RAM (ram=cost*blksz roughly)
875
876
 
876
877
  \033[36m--ah-alg sha2\033[0m # which is the same as:
877
878
  \033[36m--ah-alg sha2,424242\033[0m
@@ -1343,12 +1344,12 @@ def add_thumbnail(ap):
1343
1344
  # https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html
1344
1345
  # https://github.com/libvips/libvips
1345
1346
  # 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:'
1346
- ap2.add_argument("--th-r-pil", metavar="T,T", type=u, default="avif,avifs,blp,bmp,dcx,dds,dib,emf,eps,fits,flc,fli,fpx,gif,heic,heics,heif,heifs,icns,ico,im,j2p,j2k,jp2,jpeg,jpg,jpx,pbm,pcx,pgm,png,pnm,ppm,psd,qoi,sgi,spi,tga,tif,tiff,webp,wmf,xbm,xpm", help="image formats to decode using pillow")
1347
+ ap2.add_argument("--th-r-pil", metavar="T,T", type=u, default="avif,avifs,blp,bmp,cbz,dcx,dds,dib,emf,eps,fits,flc,fli,fpx,gif,heic,heics,heif,heifs,icns,ico,im,j2p,j2k,jp2,jpeg,jpg,jpx,pbm,pcx,pgm,png,pnm,ppm,psd,qoi,sgi,spi,tga,tif,tiff,webp,wmf,xbm,xpm", help="image formats to decode using pillow")
1347
1348
  ap2.add_argument("--th-r-vips", metavar="T,T", type=u, default="avif,exr,fit,fits,fts,gif,hdr,heic,jp2,jpeg,jpg,jpx,jxl,nii,pfm,pgm,png,ppm,svg,tif,tiff,webp", help="image formats to decode using pyvips")
1348
- ap2.add_argument("--th-r-ffi", metavar="T,T", type=u, default="apng,avif,avifs,bmp,dds,dib,fit,fits,fts,gif,hdr,heic,heics,heif,heifs,icns,ico,jp2,jpeg,jpg,jpx,jxl,pbm,pcx,pfm,pgm,png,pnm,ppm,psd,qoi,sgi,tga,tif,tiff,webp,xbm,xpm", help="image formats to decode using ffmpeg")
1349
+ ap2.add_argument("--th-r-ffi", metavar="T,T", type=u, default="apng,avif,avifs,bmp,cbz,dds,dib,fit,fits,fts,gif,hdr,heic,heics,heif,heifs,icns,ico,jp2,jpeg,jpg,jpx,jxl,pbm,pcx,pfm,pgm,png,pnm,ppm,psd,qoi,sgi,tga,tif,tiff,webp,xbm,xpm", help="image formats to decode using ffmpeg")
1349
1350
  ap2.add_argument("--th-r-ffv", metavar="T,T", type=u, default="3gp,asf,av1,avc,avi,flv,h264,h265,hevc,m4v,mjpeg,mjpg,mkv,mov,mp4,mpeg,mpeg2,mpegts,mpg,mpg2,mts,nut,ogm,ogv,rm,ts,vob,webm,wmv", help="video formats to decode using ffmpeg")
1350
1351
  ap2.add_argument("--th-r-ffa", metavar="T,T", type=u, default="aac,ac3,aif,aiff,alac,alaw,amr,apac,ape,au,bonk,dfpwm,dts,flac,gsm,ilbc,it,itgz,itxz,itz,m4a,mdgz,mdxz,mdz,mo3,mod,mp2,mp3,mpc,mptm,mt2,mulaw,ogg,okt,opus,ra,s3m,s3gz,s3xz,s3z,tak,tta,ulaw,wav,wma,wv,xm,xmgz,xmxz,xmz,xpk", help="audio formats to decode using ffmpeg")
1351
- ap2.add_argument("--au-unpk", metavar="E=F.C", type=u, default="mdz=mod.zip, mdgz=mod.gz, mdxz=mod.xz, s3z=s3m.zip, s3gz=s3m.gz, s3xz=s3m.xz, xmz=xm.zip, xmgz=xm.gz, xmxz=xm.xz, itz=it.zip, itgz=it.gz, itxz=it.xz", help="audio formats to decompress before passing to ffmpeg")
1352
+ ap2.add_argument("--au-unpk", metavar="E=F.C", type=u, default="mdz=mod.zip, mdgz=mod.gz, mdxz=mod.xz, s3z=s3m.zip, s3gz=s3m.gz, s3xz=s3m.xz, xmz=xm.zip, xmgz=xm.gz, xmxz=xm.xz, itz=it.zip, itgz=it.gz, itxz=it.xz, cbz=jpg.cbz", help="audio/image formats to decompress before passing to ffmpeg")
1352
1353
 
1353
1354
 
1354
1355
  def add_transcoding(ap):
copyparty/__version__.py CHANGED
@@ -1,8 +1,8 @@
1
1
  # coding: utf-8
2
2
 
3
- VERSION = (1, 16, 0)
3
+ VERSION = (1, 16, 1)
4
4
  CODENAME = "COPYparty"
5
- BUILD_DT = (2024, 11, 10)
5
+ BUILD_DT = (2024, 11, 15)
6
6
 
7
7
  S_VERSION = ".".join(map(str, VERSION))
8
8
  S_BUILD_DT = "{0:04d}-{1:02d}-{2:02d}".format(*BUILD_DT)
copyparty/authsrv.py CHANGED
@@ -360,18 +360,19 @@ class VFS(object):
360
360
  self.ahtml = {}
361
361
  self.aadmin = {}
362
362
  self.adot = {}
363
- self.all_vols = {}
364
363
 
365
364
  if realpath:
366
365
  rp = realpath + ("" if realpath.endswith(os.sep) else os.sep)
367
366
  vp = vpath + ("/" if vpath else "")
368
367
  self.histpath = os.path.join(realpath, ".hist") # db / thumbcache
369
368
  self.all_vols = {vpath: self} # flattened recursive
369
+ self.all_nodes = {vpath: self} # also jumpvols
370
370
  self.all_aps = [(rp, self)]
371
371
  self.all_vps = [(vp, self)]
372
372
  else:
373
373
  self.histpath = ""
374
374
  self.all_vols = {}
375
+ self.all_nodes = {}
375
376
  self.all_aps = []
376
377
  self.all_vps = []
377
378
 
@@ -389,9 +390,11 @@ class VFS(object):
389
390
  def get_all_vols(
390
391
  self,
391
392
  vols ,
393
+ nodes ,
392
394
  aps ,
393
395
  vps ,
394
396
  ) :
397
+ nodes[self.vpath] = self
395
398
  if self.realpath:
396
399
  vols[self.vpath] = self
397
400
  rp = self.realpath
@@ -401,7 +404,7 @@ class VFS(object):
401
404
  vps.append((vp, self))
402
405
 
403
406
  for v in self.nodes.values():
404
- v.get_all_vols(vols, aps, vps)
407
+ v.get_all_vols(vols, nodes, aps, vps)
405
408
 
406
409
  def add(self, src , dst ) :
407
410
  """get existing, or add new path to the vfs"""
@@ -1528,10 +1531,11 @@ class AuthSrv(object):
1528
1531
 
1529
1532
  assert vfs # type: ignore
1530
1533
  vfs.all_vols = {}
1534
+ vfs.all_nodes = {}
1531
1535
  vfs.all_aps = []
1532
1536
  vfs.all_vps = []
1533
- vfs.get_all_vols(vfs.all_vols, vfs.all_aps, vfs.all_vps)
1534
- for vol in vfs.all_vols.values():
1537
+ vfs.get_all_vols(vfs.all_vols, vfs.all_nodes, vfs.all_aps, vfs.all_vps)
1538
+ for vol in vfs.all_nodes.values():
1535
1539
  vol.all_aps.sort(key=lambda x: len(x[0]), reverse=True)
1536
1540
  vol.all_vps.sort(key=lambda x: len(x[0]), reverse=True)
1537
1541
  vol.root = vfs
@@ -1582,7 +1586,7 @@ class AuthSrv(object):
1582
1586
 
1583
1587
  vfs.nodes[shr] = vfs.all_vols[shr] = shv
1584
1588
  for vol in shv.nodes.values():
1585
- vfs.all_vols[vol.vpath] = vol
1589
+ vfs.all_vols[vol.vpath] = vfs.all_nodes[vol.vpath] = vol
1586
1590
  vol.get_dbv = vol._get_share_src
1587
1591
  vol.ls = vol._ls_nope
1588
1592
 
@@ -1725,7 +1729,19 @@ class AuthSrv(object):
1725
1729
 
1726
1730
  self.log("\n\n".join(ta) + "\n", c=3)
1727
1731
 
1728
- vfs.histtab = {zv.realpath: zv.histpath for zv in vfs.all_vols.values()}
1732
+ rhisttab = {}
1733
+ vfs.histtab = {}
1734
+ for zv in vfs.all_vols.values():
1735
+ histp = zv.histpath
1736
+ is_shr = shr and zv.vpath.split("/")[0] == shr
1737
+ if histp and not is_shr and histp in rhisttab:
1738
+ zv2 = rhisttab[histp]
1739
+ t = "invalid config; multiple volumes share the same histpath (database location):\n histpath: %s\n volume 1: /%s [%s]\n volume 2: %s [%s]"
1740
+ t = t % (histp, zv2.vpath, zv2.realpath, zv.vpath, zv.realpath)
1741
+ self.log(t, 1)
1742
+ raise Exception(t)
1743
+ rhisttab[histp] = zv
1744
+ vfs.histtab[zv.realpath] = histp
1729
1745
 
1730
1746
  for vol in vfs.all_vols.values():
1731
1747
  lim = Lim(self.log_func)
@@ -1784,12 +1800,12 @@ class AuthSrv(object):
1784
1800
  vol.lim = lim
1785
1801
 
1786
1802
  if self.args.no_robots:
1787
- for vol in vfs.all_vols.values():
1803
+ for vol in vfs.all_nodes.values():
1788
1804
  # volflag "robots" overrides global "norobots", allowing indexing by search engines for this vol
1789
1805
  if not vol.flags.get("robots"):
1790
1806
  vol.flags["norobots"] = True
1791
1807
 
1792
- for vol in vfs.all_vols.values():
1808
+ for vol in vfs.all_nodes.values():
1793
1809
  if self.args.no_vthumb:
1794
1810
  vol.flags["dvthumb"] = True
1795
1811
  if self.args.no_athumb:
@@ -1801,7 +1817,7 @@ class AuthSrv(object):
1801
1817
  vol.flags["dithumb"] = True
1802
1818
 
1803
1819
  have_fk = False
1804
- for vol in vfs.all_vols.values():
1820
+ for vol in vfs.all_nodes.values():
1805
1821
  fk = vol.flags.get("fk")
1806
1822
  fka = vol.flags.get("fka")
1807
1823
  if fka and not fk:
@@ -1833,7 +1849,7 @@ class AuthSrv(object):
1833
1849
  zs = os.path.join(E.cfg, "fk-salt.txt")
1834
1850
  self.log(t % (fk_len, 16, zs), 3)
1835
1851
 
1836
- for vol in vfs.all_vols.values():
1852
+ for vol in vfs.all_nodes.values():
1837
1853
  if "pk" in vol.flags and "gz" not in vol.flags and "xz" not in vol.flags:
1838
1854
  vol.flags["gz"] = False # def.pk
1839
1855
 
@@ -1844,7 +1860,7 @@ class AuthSrv(object):
1844
1860
 
1845
1861
  all_mte = {}
1846
1862
  errors = False
1847
- for vol in vfs.all_vols.values():
1863
+ for vol in vfs.all_nodes.values():
1848
1864
  if (self.args.e2ds and vol.axs.uwrite) or self.args.e2dsa:
1849
1865
  vol.flags["e2ds"] = True
1850
1866
 
@@ -2062,7 +2078,7 @@ class AuthSrv(object):
2062
2078
  errors = True
2063
2079
 
2064
2080
  have_daw = False
2065
- for vol in vfs.all_vols.values():
2081
+ for vol in vfs.all_nodes.values():
2066
2082
  daw = vol.flags.get("daw") or self.args.daw
2067
2083
  if daw:
2068
2084
  vol.flags["daw"] = True
@@ -2077,13 +2093,12 @@ class AuthSrv(object):
2077
2093
  self.log("--smb can only be used when --ah-alg is none", 1)
2078
2094
  errors = True
2079
2095
 
2080
- for vol in vfs.all_vols.values():
2096
+ for vol in vfs.all_nodes.values():
2081
2097
  for k in list(vol.flags.keys()):
2082
2098
  if re.match("^-[^-]+$", k):
2083
2099
  vol.flags.pop(k[1:], None)
2084
2100
  vol.flags.pop(k)
2085
2101
 
2086
- for vol in vfs.all_vols.values():
2087
2102
  if vol.flags.get("dots"):
2088
2103
  for name in vol.axs.uread:
2089
2104
  vol.axs.udot.add(name)
@@ -2225,6 +2240,11 @@ class AuthSrv(object):
2225
2240
  for x, y in vfs.all_vols.items()
2226
2241
  if x != shr and not x.startswith(shrs)
2227
2242
  }
2243
+ vfs.all_nodes = {
2244
+ x: y
2245
+ for x, y in vfs.all_nodes.items()
2246
+ if x != shr and not x.startswith(shrs)
2247
+ }
2228
2248
 
2229
2249
  assert db and cur and cur2 and shv # type: ignore
2230
2250
  for row in cur.execute("select * from sh"):
copyparty/httpsrv.py CHANGED
@@ -607,7 +607,7 @@ class HttpSrv(object):
607
607
  """
608
608
  dli = {}
609
609
  for k, (a, b, c, d, e) in sdli.items():
610
- vn = self.asrv.vfs.all_vols[c]
610
+ vn = self.asrv.vfs.all_nodes[c]
611
611
  dli[k] = (a, b, vn, d, e)
612
612
 
613
613
  self.tdli = dli
copyparty/mtag.py CHANGED
@@ -4,6 +4,7 @@ from __future__ import print_function, unicode_literals
4
4
  import argparse
5
5
  import json
6
6
  import os
7
+ import re
7
8
  import shutil
8
9
  import subprocess as sp
9
10
  import sys
@@ -56,6 +57,9 @@ def have_ff(scmd ) :
56
57
  HAVE_FFMPEG = not os.environ.get("PRTY_NO_FFMPEG") and have_ff("ffmpeg")
57
58
  HAVE_FFPROBE = not os.environ.get("PRTY_NO_FFPROBE") and have_ff("ffprobe")
58
59
 
60
+ CBZ_PICS = set("png jpg jpeg gif bmp tga tif tiff webp avif".split())
61
+ CBZ_01 = re.compile(r"(^|[^0-9v])0+[01]\b")
62
+
59
63
 
60
64
  class MParser(object):
61
65
  def __init__(self, cmdline ) :
@@ -120,6 +124,7 @@ def au_unpk(
120
124
  log , fmt_map , abspath , vn = None
121
125
  ) :
122
126
  ret = ""
127
+ maxsz = 1024 * 1024 * 64
123
128
  try:
124
129
  ext = abspath.split(".")[-1].lower()
125
130
  au, pk = fmt_map[ext].split(".")
@@ -142,17 +147,41 @@ def au_unpk(
142
147
  zf = zipfile.ZipFile(abspath, "r")
143
148
  zil = zf.infolist()
144
149
  zil = [x for x in zil if x.filename.lower().split(".")[-1] == au]
150
+ if not zil:
151
+ raise Exception("no audio inside zip")
145
152
  fi = zf.open(zil[0])
146
153
 
154
+ elif pk == "cbz":
155
+ import zipfile
156
+
157
+ zf = zipfile.ZipFile(abspath, "r")
158
+ znil = [(x.filename.lower(), x) for x in zf.infolist()]
159
+ nf = len(znil)
160
+ znil = [x for x in znil if x[0].split(".")[-1] in CBZ_PICS]
161
+ znil = [x for x in znil if "cover" in x[0]] or znil
162
+ znil = [x for x in znil if CBZ_01.search(x[0])] or znil
163
+ t = "cbz: %d files, %d hits" % (nf, len(znil))
164
+ if znil:
165
+ t += ", using " + znil[0][1].filename
166
+ log(t)
167
+ if not znil:
168
+ raise Exception("no images inside cbz")
169
+ fi = zf.open(znil[0][1])
170
+
147
171
  else:
148
172
  raise Exception("unknown compression %s" % (pk,))
149
173
 
174
+ fsz = 0
150
175
  with os.fdopen(fd, "wb") as fo:
151
176
  while True:
152
177
  buf = fi.read(32768)
153
178
  if not buf:
154
179
  break
155
180
 
181
+ fsz += len(buf)
182
+ if fsz > maxsz:
183
+ raise Exception("zipbomb defused")
184
+
156
185
  fo.write(buf)
157
186
 
158
187
  return ret
copyparty/pwhash.py CHANGED
@@ -24,17 +24,13 @@ class PWHash(object):
24
24
  def __init__(self, args ):
25
25
  self.args = args
26
26
 
27
- try:
28
- alg, ac = args.ah_alg.split(",")
29
- except:
30
- alg = args.ah_alg
31
- ac = {}
32
-
27
+ zsl = args.ah_alg.split(",")
28
+ alg = zsl[0]
33
29
  if alg == "none":
34
30
  alg = ""
35
31
 
36
32
  self.alg = alg
37
- self.ac = ac
33
+ self.ac = zsl[1:]
38
34
  if not alg:
39
35
  self.on = False
40
36
  self.hash = unicode
@@ -90,17 +86,23 @@ class PWHash(object):
90
86
  its = 2
91
87
  blksz = 8
92
88
  para = 4
89
+ ramcap = 0 # openssl 1.1 = 32 MiB
93
90
  try:
94
91
  cost = 2 << int(self.ac[0])
95
92
  its = int(self.ac[1])
96
93
  blksz = int(self.ac[2])
97
94
  para = int(self.ac[3])
95
+ ramcap = int(self.ac[4]) * 1024 * 1024
98
96
  except:
99
97
  pass
100
98
 
99
+ cfg = {"salt": self.salt, "n": cost, "r": blksz, "p": para, "dklen": 24}
100
+ if ramcap:
101
+ cfg["maxmem"] = ramcap
102
+
101
103
  ret = plain.encode("utf-8")
102
104
  for _ in range(its):
103
- ret = hashlib.scrypt(ret, salt=self.salt, n=cost, r=blksz, p=para, dklen=24)
105
+ ret = hashlib.scrypt(ret, **cfg)
104
106
 
105
107
  return "+" + base64.urlsafe_b64encode(ret).decode("utf-8")
106
108
 
Binary file
Binary file
Binary file
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: copyparty
3
- Version: 1.16.0
3
+ Version: 1.16.1
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
@@ -1,7 +1,7 @@
1
1
  copyparty/__init__.py,sha256=iRCNvMPg6k9WG_O2uCtlkD4vWogH8EgP9elp9XwSIJs,2610
2
- copyparty/__main__.py,sha256=NpKXKPp6rAuWYw-fMWs-iS0dAjyOMl9WBtwBTYsH9zY,112286
3
- copyparty/__version__.py,sha256=snuFV6IoeKYLPgiZHLcMTRengBZI8NN2la43bff1e3E,252
4
- copyparty/authsrv.py,sha256=7ypOOehMN-NiC10y46lO-sDU8uGGnXrJz2rt9njKEZg,99237
2
+ copyparty/__main__.py,sha256=zicmxWWy2Zxe6PDS4k9MHw6PLGI7lK14xuZCa5isPXc,112389
3
+ copyparty/__version__.py,sha256=9fYJx042QMcZp8vBaQP-XWPso5S8OpOlNVSkqDg9W50,252
4
+ copyparty/authsrv.py,sha256=RB0ww38uo1XvSLZiAiwbI8x9OZh0vfPtXexPfzC8UiE,100142
5
5
  copyparty/broker_mp.py,sha256=QdOXXvV2Xn6J0CysEqyY3GZbqxQMyWnTpnba-a5lMc0,4987
6
6
  copyparty/broker_mpw.py,sha256=PpSS4SK3pItlpfD8OwVr3QmJEPKlUgaf2nuMOozixgU,3347
7
7
  copyparty/broker_thr.py,sha256=fjoYtpSscUA7-nMl4r1n2R7UK3J9lrvLS3rUZ-iJzKQ,1721
@@ -13,13 +13,13 @@ copyparty/fsutil.py,sha256=5CshJWO7CflfaRRNOb3JxghUH7W5rmS_HWNmKfx42MM,4538
13
13
  copyparty/ftpd.py,sha256=T97SFS7JFtvRLbJX8C4fJSYwe13vhN3-E6emtlVmqLA,17608
14
14
  copyparty/httpcli.py,sha256=tu5abG7JpDZYTDlPNv9p5SYGd0ZgAdoWf8HNYAr45V4,206103
15
15
  copyparty/httpconn.py,sha256=mQSgljh0Q-jyWjF4tQLrHbRKRe9WKl19kGqsGMsJpWo,6880
16
- copyparty/httpsrv.py,sha256=WMQ-0sk6wk4Gbg7FB1ZYvnb74EsZQ5b7WJT0zAwZXjA,18226
16
+ copyparty/httpsrv.py,sha256=XRgM37y3wH-iRRhmMB-pcFbu-X6HdB3Dcxbp8rItbto,18227
17
17
  copyparty/ico.py,sha256=eWSxEae4wOCfheHl-m-wchYvFRAR_97kJDb4NGaB-Z8,3561
18
18
  copyparty/mdns.py,sha256=vC078llnL1v0pvL3mnwacuStFHPJUQuxo9Opj-IbHL4,18155
19
19
  copyparty/metrics.py,sha256=EOIiPOItEQmdK9YgNb75l0kCzanWb6RtJGwMI7ufifY,8966
20
- copyparty/mtag.py,sha256=8WGjEn0T0Ri9ww1yBpLUnFHZiTQMye1BMXL6SkK3MRo,18893
20
+ copyparty/mtag.py,sha256=o-rxu4LajWF4H3HFmfCbXnKfs0GCQh1FQ0XywuW6wOc,19934
21
21
  copyparty/multicast.py,sha256=Ha27l2oATEa-Qo2WOzkeRgjAm6G_YDCfbVJWR-ao2UE,12319
22
- copyparty/pwhash.py,sha256=AdLMLyIi2IDhGtbKIQOswKUxWvO7ARYYRF_ThsryOoc,4124
22
+ copyparty/pwhash.py,sha256=X87RWeay8IhzGVZLDKE5LctF9YVUcYxPAJ1BX6r_9CU,4248
23
23
  copyparty/smbd.py,sha256=Or7RF13cl1r3ncnpVh8BqyAGqH2Oa04O9iPZWCoB0Bo,14609
24
24
  copyparty/ssdp.py,sha256=R1Z61GZOxBMF2Sk4RTxKWMOemogmcjEWG-CvLihd45k,7023
25
25
  copyparty/star.py,sha256=tV5BbX6AiQ7N4UU8DYtSTckNYeoeey4DBqq4LjfymbY,3818
@@ -54,10 +54,10 @@ copyparty/stolen/ifaddr/__init__.py,sha256=vpREjAyPubr5s1NJi91icXV3q1o4DrKAvHABw
54
54
  copyparty/stolen/ifaddr/_posix.py,sha256=-67NdfGrCktfQPakT2fLbjl2U00QMvyBGkSvrUuTOrU,2626
55
55
  copyparty/stolen/ifaddr/_shared.py,sha256=uNC4SdEIgdSLKvuUzsf1aM-H1Xrc_9mpLoOT43YukGs,6206
56
56
  copyparty/stolen/ifaddr/_win32.py,sha256=EE-QyoBgeB7lYQ6z62VjXNaRozaYfCkaJBHGNA8QtZM,4026
57
- copyparty/web/baguettebox.js.gz,sha256=YIaxFDsubJfGIdzzxA-cL6GwJVmpWZyaPhW9hHcOIIw,7964
58
- copyparty/web/browser.css.gz,sha256=N5T5U-iWzls21E2SYkQvDUaaZf11gjj3KwUP0lm1mMA,11672
57
+ copyparty/web/baguettebox.js.gz,sha256=6_iq9JfcltSEgj-cMdNXM-mDbui06iY2TtrSq-eJXc0,7964
58
+ copyparty/web/browser.css.gz,sha256=6_ZpGwfi0OQlH6Zs9sL2uw5vSvqDtHbPmTBy6UyRwFY,11644
59
59
  copyparty/web/browser.html,sha256=ISpfvWEawufJCYZIqvuXiyUgiXgjmOTtScz4zrEaypI,4870
60
- copyparty/web/browser.js.gz,sha256=uGALYaMsyyXuCSKbvdMZpB-YrIvCIV3JWo611xRlHd8,88488
60
+ copyparty/web/browser.js.gz,sha256=vJUAUYgTOybM4PkM1U0Y0pZuL_S-HEHHuZ_kK51BbeE,88513
61
61
  copyparty/web/browser2.html,sha256=NRUZ08GH-e2YcGXcoz0UjYg6JIVF42u4IMX4HHwWTmg,1587
62
62
  copyparty/web/cf.html,sha256=lJThtNFNAQT1ClCHHlivAkDGE0LutedwopXD62Z8Nys,589
63
63
  copyparty/web/dbg-audio.js.gz,sha256=Ma-KZtK8LnmiwNvNKFKXMPYl_Nn_3U7GsJ6-DRWC2HE,688
@@ -106,9 +106,9 @@ copyparty/web/deps/prismd.css.gz,sha256=ObUlksQVr-OuYlTz-I4B23TeBg2QDVVGRnWBz8cV
106
106
  copyparty/web/deps/scp.woff2,sha256=w99BDU5i8MukkMEL-iW0YO9H4vFFZSPWxbkH70ytaAg,8612
107
107
  copyparty/web/deps/sha512.ac.js.gz,sha256=lFZaCLumgWxrvEuDr4bqdKHsqjX82AbVAb7_F45Yk88,7033
108
108
  copyparty/web/deps/sha512.hw.js.gz,sha256=vqoXeracj-99Z5MfY3jK2N4WiSzYQdfjy0RnUlQDhSU,8110
109
- copyparty-1.16.0.dist-info/LICENSE,sha256=gOr4h33pCsBEg9uIy9AYmb7qlocL4V9t2uPJS5wllr0,1072
110
- copyparty-1.16.0.dist-info/METADATA,sha256=tLqMYoMnPCLqhLEvCe8twQHQoRnXfIGwu8neJ1MucdQ,140282
111
- copyparty-1.16.0.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
112
- copyparty-1.16.0.dist-info/entry_points.txt,sha256=4zw6a3rqASywQomiYLObjjlxybaI65LYYOTJwgKz7b0,128
113
- copyparty-1.16.0.dist-info/top_level.txt,sha256=LnYUPsDyk-8kFgM6YJLG4h820DQekn81cObKSu9g-sI,10
114
- copyparty-1.16.0.dist-info/RECORD,,
109
+ copyparty-1.16.1.dist-info/LICENSE,sha256=gOr4h33pCsBEg9uIy9AYmb7qlocL4V9t2uPJS5wllr0,1072
110
+ copyparty-1.16.1.dist-info/METADATA,sha256=zfXe8Vl2Ru14OYRGYTHhj5VLEZum4cEiBqe08_AuczU,140282
111
+ copyparty-1.16.1.dist-info/WHEEL,sha256=R06PA3UVYHThwHvxuRWMqaGcr-PuniXahwjmQRFMEkY,91
112
+ copyparty-1.16.1.dist-info/entry_points.txt,sha256=4zw6a3rqASywQomiYLObjjlxybaI65LYYOTJwgKz7b0,128
113
+ copyparty-1.16.1.dist-info/top_level.txt,sha256=LnYUPsDyk-8kFgM6YJLG4h820DQekn81cObKSu9g-sI,10
114
+ copyparty-1.16.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.3.0)
2
+ Generator: setuptools (75.5.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5