copyparty 1.19.9__py3-none-any.whl → 1.19.11__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
@@ -1212,6 +1212,7 @@ def add_upload(ap):
1212
1212
  ap2.add_argument("--chmod-d", metavar="UGO", type=u, default="755", help="unix file permissions to use when creating directories; see --help-chmod. Examples: [\033[32m755\033[0m] = owner-RW + all-R, [\033[32m777\033[0m] = full-yolo (volflag=chmod_d)")
1213
1213
  ap2.add_argument("--uid", metavar="N", type=int, default=-1, help="unix user-id to chown new files/folders to; default = -1 = do-not-change (volflag=uid)")
1214
1214
  ap2.add_argument("--gid", metavar="N", type=int, default=-1, help="unix group-id to chown new files/folders to; default = -1 = do-not-change (volflag=gid)")
1215
+ ap2.add_argument("--wram", action="store_true", help="allow uploading even if a volume is inside a ramdisk, meaning that all data will be lost on the next server reboot (volflag=wram)")
1215
1216
  ap2.add_argument("--dedup", action="store_true", help="enable symlink-based upload deduplication (volflag=dedup)")
1216
1217
  ap2.add_argument("--safe-dedup", metavar="N", type=int, default=50, help="how careful to be when deduplicating files; [\033[32m1\033[0m] = just verify the filesize, [\033[32m50\033[0m] = verify file contents have not been altered (volflag=safededup)")
1217
1218
  ap2.add_argument("--hardlink", action="store_true", help="enable hardlink-based dedup; will fallback on symlinks when that is impossible (across filesystems) (volflag=hardlink)")
@@ -1569,6 +1570,9 @@ def add_logging(ap):
1569
1570
  ap2.add_argument("--ihead", metavar="HEADER", type=u, action='append', help="print request \033[33mHEADER\033[0m; [\033[32m*\033[0m]=all")
1570
1571
  ap2.add_argument("--ohead", metavar="HEADER", type=u, action='append', help="print response \033[33mHEADER\033[0m; [\033[32m*\033[0m]=all")
1571
1572
  ap2.add_argument("--lf-url", metavar="RE", type=u, default=r"^/\.cpr/|[?&]th=[wjp]|/\.(_|ql_|DS_Store$|localized$)", help="dont log URLs matching regex \033[33mRE\033[0m")
1573
+ ap2.add_argument("--scan-st-r", metavar="SEC", type=float, default=0.1, help="fs-indexing: wait \033[33mSEC\033[0m between each status-message")
1574
+ ap2.add_argument("--scan-pr-r", metavar="SEC", type=float, default=10, help="fs-indexing: wait \033[33mSEC\033[0m between each 'progress:' message")
1575
+ ap2.add_argument("--scan-pr-s", metavar="MiB", type=float, default=1, help="fs-indexing: say 'file: <name>' when a file larger than \033[33mMiB\033[0m is about to be hashed")
1572
1576
 
1573
1577
 
1574
1578
  def add_admin(ap):
copyparty/__version__.py CHANGED
@@ -1,8 +1,8 @@
1
1
  # coding: utf-8
2
2
 
3
- VERSION = (1, 19, 9)
3
+ VERSION = (1, 19, 11)
4
4
  CODENAME = "usernames"
5
- BUILD_DT = (2025, 9, 15)
5
+ BUILD_DT = (2025, 9, 20)
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/broker_mpw.py CHANGED
@@ -12,6 +12,7 @@ import queue
12
12
  from .__init__ import ANYWIN
13
13
  from .authsrv import AuthSrv
14
14
  from .broker_util import BrokerCli, ExceptionalQueue, NotExQueue
15
+ from .fsutil import ramdisk_chk
15
16
  from .httpsrv import HttpSrv
16
17
  from .util import FAKE_MP, Daemon, HMaccas
17
18
 
@@ -50,6 +51,7 @@ class MpWorker(BrokerCli):
50
51
 
51
52
  # starting to look like a good idea
52
53
  self.asrv = AuthSrv(args, None, False)
54
+ ramdisk_chk(self.asrv)
53
55
 
54
56
  # instantiate all services here (TODO: inheritance?)
55
57
  self.iphash = HMaccas(os.path.join(self.args.E.cfg, "iphash"), 8)
@@ -93,6 +95,7 @@ class MpWorker(BrokerCli):
93
95
  if dest == "reload":
94
96
  self.logw("mpw.asrv reloading")
95
97
  self.asrv.reload()
98
+ ramdisk_chk(self.asrv)
96
99
  self.logw("mpw.asrv reloaded")
97
100
  continue
98
101
 
copyparty/cfg.py CHANGED
@@ -57,6 +57,7 @@ def vf_bmap() :
57
57
  "rmagic",
58
58
  "rss",
59
59
  "wo_up_readme",
60
+ "wram",
60
61
  "xdev",
61
62
  "xlink",
62
63
  "xvol",
@@ -187,6 +188,7 @@ flagcats = {
187
188
  "chmod_f=644": "unix-permission for new files",
188
189
  "uid=573": "change owner of new files/folders to unix-user 573",
189
190
  "gid=999": "change owner of new files/folders to unix-group 999",
191
+ "wram": "allow uploading into ramdisks",
190
192
  "sparse": "force use of sparse files, mainly for s3-backed storage",
191
193
  "nosparse": "deny use of sparse files, mainly for slow storage",
192
194
  "daw": "enable full WebDAV write support (dangerous);\nPUT-operations will now \033[1;31mOVERWRITE\033[0;35m existing files",
copyparty/fsutil.py CHANGED
@@ -7,27 +7,30 @@ import re
7
7
  import time
8
8
 
9
9
  from .__init__ import ANYWIN, MACOS
10
- from .authsrv import AXS, VFS
10
+ from .authsrv import AXS, VFS, AuthSrv
11
11
  from .bos import bos
12
12
  from .util import chkcmd, min_ex, undot
13
13
 
14
14
  class Fstab(object):
15
- def __init__(self, log , args ):
15
+ def __init__(self, log , args , verbose ):
16
16
  self.log_func = log
17
+ self.verbose = verbose
17
18
 
18
19
  self.warned = False
19
20
  self.trusted = False
20
21
  self.tab = None
21
22
  self.oldtab = None
22
23
  self.srctab = "a"
23
- self.cache = {}
24
+ self.cache = {}
24
25
  self.age = 0.0
25
26
  self.maxage = args.mtab_age
26
27
 
27
28
  def log(self, msg , c = 0) :
29
+ if not c or self.verbose:
30
+ return
28
31
  self.log_func("fstab", msg, c)
29
32
 
30
- def get(self, path ) :
33
+ def get(self, path ) :
31
34
  now = time.time()
32
35
  if now - self.age > self.maxage or len(self.cache) > 9000:
33
36
  self.age = now
@@ -35,6 +38,7 @@ class Fstab(object):
35
38
  self.tab = None
36
39
  self.cache = {}
37
40
 
41
+ mp = ""
38
42
  fs = "ext4"
39
43
  msg = "failed to determine filesystem at %r; assuming %s\n%s"
40
44
 
@@ -44,7 +48,7 @@ class Fstab(object):
44
48
  path = self._winpath(path)
45
49
  except:
46
50
  self.log(msg % (path, fs, min_ex()), 3)
47
- return fs
51
+ return fs, ""
48
52
 
49
53
  path = undot(path)
50
54
  try:
@@ -53,14 +57,14 @@ class Fstab(object):
53
57
  pass
54
58
 
55
59
  try:
56
- fs = self.get_w32(path) if ANYWIN else self.get_unix(path)
60
+ fs, mp = self.get_w32(path) if ANYWIN else self.get_unix(path)
57
61
  except:
58
62
  self.log(msg % (path, fs, min_ex()), 3)
59
63
 
60
64
  fs = fs.lower()
61
- self.cache[path] = fs
62
- self.log("found %s at %r" % (fs, path))
63
- return fs
65
+ self.cache[path] = (fs, mp)
66
+ self.log("found %s at %r, %r" % (fs, mp, path))
67
+ return fs, mp
64
68
 
65
69
  def _winpath(self, path ) :
66
70
  # try to combine volume-label + st_dev (vsn)
@@ -75,34 +79,49 @@ class Fstab(object):
75
79
  self.tab = VFS(self.log_func, "idk", "/", "/", AXS(), {})
76
80
  self.trusted = False
77
81
 
78
- def build_tab(self) :
79
- self.log("inspecting mtab for changes")
80
-
82
+ def _from_sp_mount(self) :
81
83
  sptn = r"^.*? on (.*) type ([^ ]+) \(.*"
82
84
  if MACOS:
83
85
  sptn = r"^.*? on (.*) \(([^ ]+), .*"
84
86
 
85
87
  ptn = re.compile(sptn)
86
88
  so, _ = chkcmd(["mount"])
87
- tab1 = []
88
- atab = []
89
+ dtab = {}
89
90
  for ln in so.split("\n"):
90
91
  m = ptn.match(ln)
91
92
  if not m:
92
93
  continue
93
94
 
94
95
  zs1, zs2 = m.groups()
95
- tab1.append((str(zs1), str(zs2)))
96
- atab.append(ln)
96
+ dtab[str(zs1)] = str(zs2)
97
+
98
+ return dtab
99
+
100
+ def _from_proc(self) :
101
+ ret = {}
102
+ with open("/proc/self/mounts", "rb", 262144) as f:
103
+ src = f.read(262144).decode("utf-8", "replace").split("\n")
104
+ for zsl in [x.split(" ") for x in src]:
105
+ if len(zsl) < 3:
106
+ continue
107
+ zs = zsl[1]
108
+ zs = zs.replace("\\011", "\t").replace("\\040", " ").replace("\\134", "\\")
109
+ ret[zs] = zsl[2]
110
+ return ret
111
+
112
+ def build_tab(self) :
113
+ self.log("inspecting mtab for changes")
114
+ dtab = self._from_sp_mount() if MACOS else self._from_proc()
97
115
 
98
116
  # keep empirically-correct values if mounttab unchanged
99
- srctab = "\n".join(sorted(atab))
117
+ srctab = str(sorted(dtab.items()))
100
118
  if srctab == self.srctab:
101
119
  self.tab = self.oldtab
102
120
  return
103
121
 
104
122
  self.log("mtab has changed; reevaluating support for sparse files")
105
123
 
124
+ tab1 = list(dtab.items())
106
125
  tab1.sort(key=lambda x: (len(x[0]), x[0]))
107
126
  path1, fs1 = tab1[0]
108
127
  tab = VFS(self.log_func, fs1, path1, path1, AXS(), {})
@@ -139,7 +158,7 @@ class Fstab(object):
139
158
  vn.realpath = ptn.sub(nval, vn.realpath)
140
159
  visit.extend(list(vn.nodes.values()))
141
160
 
142
- def get_unix(self, path ) :
161
+ def get_unix(self, path ) :
143
162
  if not self.tab:
144
163
  try:
145
164
  self.build_tab()
@@ -148,18 +167,42 @@ class Fstab(object):
148
167
  # prisonparty or other restrictive environment
149
168
  if not self.warned:
150
169
  self.warned = True
151
- self.log("failed to build tab:\n{}".format(min_ex()), 3)
170
+ t = "failed to associate fs-mounts with the VFS (this is fine):\n%s"
171
+ self.log(t % (min_ex(),), 6)
152
172
  self.build_fallback()
153
173
 
154
174
  ret = self.tab._find(path)[0]
155
175
  if self.trusted or path == ret.vpath:
156
- return ret.realpath.split("/")[0]
176
+ return ret.realpath.split("/")[0], ret.vpath
157
177
  else:
158
- return "idk"
178
+ return "idk", ""
159
179
 
160
- def get_w32(self, path ) :
180
+ def get_w32(self, path ) :
161
181
  if not self.tab:
162
182
  self.build_fallback()
163
183
 
164
184
  ret = self.tab._find(path)[0]
165
- return ret.realpath
185
+ return ret.realpath, ""
186
+
187
+
188
+ def ramdisk_chk(asrv ) :
189
+ # should have been in authsrv but that's a circular import
190
+ mods = []
191
+ ramfs = ("tmpfs", "overlay")
192
+ log = asrv.log_func or print
193
+ fstab = Fstab(log, asrv.args, False)
194
+ for vn in asrv.vfs.all_nodes.values():
195
+ if not vn.axs.uwrite or "wram" in vn.flags:
196
+ continue
197
+ ap = vn.realpath
198
+ if not ap or os.path.isfile(ap):
199
+ continue
200
+ fs, mp = fstab.get(ap)
201
+ mp = "/" + mp.strip("/")
202
+ if fs == "tmpfs" or (mp == "/" and fs in ramfs):
203
+ mods.append((vn.vpath, ap, fs, mp))
204
+ vn.axs.uwrite.clear()
205
+ if mods:
206
+ t = "WARNING: write-access was removed from the following volumes because they are not mapped to an actual HDD for storage! All uploaded data would live in RAM only, and all uploaded files would be LOST on next reboot. To allow uploading and ignore this hazard, enable the 'wram' option (global/volflag). List of affected volumes:"
207
+ t2 = ["\n volume=[/%s], abspath=%r, type=%s, root=%r" % x for x in mods]
208
+ log("vfs", t + "".join(t2) + "\n", 1)
copyparty/ftpd.py CHANGED
@@ -275,6 +275,10 @@ class FtpFs(AbstractedFS):
275
275
  def chdir(self, path ) :
276
276
  nwd = join(self.cwd, path)
277
277
  vfs, rem = self.hub.asrv.vfs.get(nwd, self.uname, False, False)
278
+ if not vfs.realpath:
279
+ self.cwd = nwd
280
+ return
281
+
278
282
  ap = vfs.canonical(rem)
279
283
  try:
280
284
  st = bos.stat(ap)
@@ -284,12 +288,9 @@ class FtpFs(AbstractedFS):
284
288
  # returning 550 is library-default and suitable
285
289
  raise FSE("No such file or directory")
286
290
 
287
- if vfs.realpath:
288
- avfs = vfs.chk_ap(ap, st)
289
- if not avfs:
290
- raise FSE("Permission denied", 1)
291
- else:
292
- avfs = vfs
291
+ avfs = vfs.chk_ap(ap, st)
292
+ if not avfs:
293
+ raise FSE("Permission denied", 1)
293
294
 
294
295
  self.cwd = nwd
295
296
 
copyparty/mtag.py CHANGED
@@ -426,9 +426,8 @@ def _get_cover_from_epub2(
426
426
  ) :
427
427
  # <meta name="cover" content="id-to-cover-image"> in <metadata>, then
428
428
  # <item> in <manifest>
429
- cover_id = package_root.find("./metadata/meta[@name='cover']", package_ns).get(
430
- "content"
431
- )
429
+ xn = package_root.find("./metadata/meta[@name='cover']", package_ns)
430
+ cover_id = xn.get("content") if xn is not None else None
432
431
 
433
432
  if not cover_id:
434
433
  return None
copyparty/svchub.py CHANGED
@@ -24,6 +24,7 @@ from .__init__ import ANYWIN, EXE, MACOS, PY2, TYPE_CHECKING, E, EnvParams, unic
24
24
  from .authsrv import BAD_CFG, AuthSrv, n_du_who, n_ver_who
25
25
  from .bos import bos
26
26
  from .cert import ensure_cert
27
+ from .fsutil import ramdisk_chk
27
28
  from .mtag import HAVE_FFMPEG, HAVE_FFPROBE, HAVE_MUTAGEN
28
29
  from .pwhash import HAVE_ARGON2
29
30
  from .tcpsrv import TcpSrv
@@ -304,6 +305,7 @@ class SvcHub(object):
304
305
 
305
306
  # initiate all services to manage
306
307
  self.asrv = AuthSrv(self.args, self.log, dargs=self.dargs)
308
+ ramdisk_chk(self.asrv)
307
309
 
308
310
  if args.cgen:
309
311
  self.asrv.cgen()
@@ -1349,6 +1351,7 @@ class SvcHub(object):
1349
1351
  with self.reload_mutex:
1350
1352
  self.log("root", "reloading config")
1351
1353
  self.asrv.reload(9 if up2k else 4)
1354
+ ramdisk_chk(self.asrv)
1352
1355
  if up2k:
1353
1356
  self.up2k.reload(rescan_all_vols)
1354
1357
  t += "; volumes are now reinitializing"
copyparty/up2k.py CHANGED
@@ -209,7 +209,7 @@ class Up2k(object):
209
209
  t = "could not initialize sqlite3, will use in-memory registry only"
210
210
  self.log(t, 3)
211
211
 
212
- self.fstab = Fstab(self.log_func, self.args)
212
+ self.fstab = Fstab(self.log_func, self.args, True)
213
213
  self.gen_fk = self._gen_fk if self.args.log_fk else gen_filekey
214
214
 
215
215
  if self.args.hash_mt < 2:
@@ -1491,6 +1491,7 @@ class Up2k(object):
1491
1491
 
1492
1492
  th_cvd = self.args.th_coversd
1493
1493
  th_cvds = self.args.th_coversd_set
1494
+ scan_pr_s = self.args.scan_pr_s
1494
1495
 
1495
1496
  self.pp.msg = "a%d %s" % (self.pp.n, cdir)
1496
1497
 
@@ -1702,7 +1703,7 @@ class Up2k(object):
1702
1703
  if nohash or not sz:
1703
1704
  wark = up2k_wark_from_metadata(self.salt, sz, lmod, rd, fn)
1704
1705
  else:
1705
- if sz > 1024 * 1024:
1706
+ if sz > 1024 * 1024 * scan_pr_s:
1706
1707
  self.log("file: %r" % (abspath,))
1707
1708
 
1708
1709
  try:
@@ -2991,7 +2992,7 @@ class Up2k(object):
2991
2992
 
2992
2993
  # check if filesystem supports sparse files;
2993
2994
  # refuse out-of-order / multithreaded uploading if sprs False
2994
- sprs = self.fstab.get(pdir) != "ng"
2995
+ sprs = self.fstab.get(pdir)[0] != "ng"
2995
2996
 
2996
2997
  if True:
2997
2998
  jcur = self.cur.get(ptop)
@@ -5155,7 +5156,7 @@ class Up2k(object):
5155
5156
  sprs = False
5156
5157
 
5157
5158
  if not ANYWIN and sprs and sz > 1024 * 1024:
5158
- fs = self.fstab.get(pdir)
5159
+ fs, mnt = self.fstab.get(pdir)
5159
5160
  if fs == "ok":
5160
5161
  pass
5161
5162
  elif "nosparse" in vf:
copyparty/util.py CHANGED
@@ -525,6 +525,8 @@ def py_desc() :
525
525
  ofs = py_ver.find(".final.")
526
526
  if ofs > 0:
527
527
  py_ver = py_ver[:ofs]
528
+ if "free-threading" in sys.version:
529
+ py_ver += "t"
528
530
 
529
531
  host_os = platform.system()
530
532
  compiler = platform.python_compiler().split("http")[0]
@@ -1040,16 +1042,18 @@ class ProgressPrinter(threading.Thread):
1040
1042
  sigblock()
1041
1043
  tp = 0
1042
1044
  msg = None
1043
- no_stdout = self.args.q
1045
+ slp_pr = self.args.scan_pr_r
1046
+ slp_ps = min(slp_pr, self.args.scan_st_r)
1047
+ no_stdout = self.args.q or slp_pr == slp_ps
1044
1048
  fmt = " {}\033[K\r" if VT100 else " {} $\r"
1045
1049
  while not self.end:
1046
- time.sleep(0.1)
1050
+ time.sleep(slp_ps)
1047
1051
  if msg == self.msg or self.end:
1048
1052
  continue
1049
1053
 
1050
1054
  msg = self.msg
1051
1055
  now = time.time()
1052
- if msg and now - tp > 10:
1056
+ if msg and now - tp >= slp_pr:
1053
1057
  tp = now
1054
1058
  self.log("progress: %r" % (msg,), 6)
1055
1059
 
Binary file
copyparty/web/up2k.js.gz CHANGED
Binary file
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: copyparty
3
- Version: 1.19.9
3
+ Version: 1.19.11
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
@@ -1418,7 +1418,7 @@ general usage:
1418
1418
  on macos, connect from finder:
1419
1419
  * [Go] -> [Connect to Server...] -> http://192.168.123.1:3923/
1420
1420
 
1421
- in order to grant full write-access to webdav clients, the volflag `daw` must be set and the account must also have delete-access (otherwise the client won't be allowed to replace the contents of existing files, which is how webdav works)
1421
+ to upload or edit files with WebDAV clients, enable the `daw` volflag (because most WebDAV clients expect this) and give your account the delete-permission. This avoids getting several copies of the same file on the server. HOWEVER: This will also make all PUT-uploads overwrite existing files if the user has delete-access, so use with caution.
1422
1422
 
1423
1423
  > note: if you have enabled [IdP authentication](#identity-providers) then that may cause issues for some/most webdav clients; see [the webdav section in the IdP docs](https://github.com/9001/copyparty/blob/hovudstraum/docs/idp.md#connecting-webdav-clients)
1424
1424
 
@@ -2771,7 +2771,7 @@ below are some tweaks roughly ordered by usefulness:
2771
2771
  * and pypy can sometimes crash on startup with `-j0` (TODO make issue)
2772
2772
 
2773
2773
  * if you are running the copyparty server **on Windows or Macos:**
2774
- * `--casechk=y` makes it much faster, but also awakens [the usual surprises](https://github.com/9001/copyparty/issues/781) you expect from a case-insensitive filesystem
2774
+ * `--casechk=n` makes it much faster, but also awakens [the usual surprises](https://github.com/9001/copyparty/issues/781) you expect from a case-insensitive filesystem
2775
2775
  * this is the same as `casechk: n` in a config-file
2776
2776
 
2777
2777
 
@@ -3088,7 +3088,7 @@ first install one of the following:
3088
3088
  and then copypaste the following command into `a-Shell`:
3089
3089
 
3090
3090
  ```sh
3091
- curl https://github.com/9001/copyparty/raw/refs/heads/hovudstraum/contrib/setup-ashell.sh | sh
3091
+ curl -L https://github.com/9001/copyparty/raw/refs/heads/hovudstraum/contrib/setup-ashell.sh | sh
3092
3092
  ```
3093
3093
 
3094
3094
  what this does:
@@ -1,38 +1,38 @@
1
1
  copyparty/__init__.py,sha256=8nHuSqcIwZvExA-66pV6slJnDEunE8LwlmGzYnGnDBU,2647
2
- copyparty/__main__.py,sha256=b0eURrybXQRskCWSK4Y0wR2Su6tRHgFd2CAbNWLqvK4,144217
3
- copyparty/__version__.py,sha256=x0kGBgJD-lVB_8ZPEnHxRPxds_whwQbXlPRKJh2kCKk,251
2
+ copyparty/__main__.py,sha256=TUuw1j99qRRm4uEfYloMn3pFxSqTcnvnYsLHGb_GZfY,144888
3
+ copyparty/__version__.py,sha256=JyTM3wlUjXrxseoG5BebPP8uOQLOid9Yws-jSDNvVBw,252
4
4
  copyparty/authsrv.py,sha256=ccWyDpc4Pk07iRd7Zjs7GA8FDU1BXTsNQ6yj4DvXIV0,132201
5
5
  copyparty/broker_mp.py,sha256=QdOXXvV2Xn6J0CysEqyY3GZbqxQMyWnTpnba-a5lMc0,4987
6
- copyparty/broker_mpw.py,sha256=PpSS4SK3pItlpfD8OwVr3QmJEPKlUgaf2nuMOozixgU,3347
6
+ copyparty/broker_mpw.py,sha256=LXQlmxzOvdpqP1aZoiIvWHAYUV_PoewLORLD1BGRs0g,3449
7
7
  copyparty/broker_thr.py,sha256=fjoYtpSscUA7-nMl4r1n2R7UK3J9lrvLS3rUZ-iJzKQ,1721
8
8
  copyparty/broker_util.py,sha256=oZ3dGdJXLYvmdV4KSFdUv_PGErkgU-7kgr1SIglkjCU,1663
9
9
  copyparty/cert.py,sha256=OGTUBxhqPbseG0Bd4cHD6e5T5T8JdGqp3q0KAYqX0Cc,8031
10
- copyparty/cfg.py,sha256=xIZH90TbOb9AnTOfx_v-cx6ONQce_TL9tKp9srNxx2g,16455
10
+ copyparty/cfg.py,sha256=2SpjFYkgnMrwJ_V8SlrcHtwccSwIptFBbj1ybmDJiP0,16520
11
11
  copyparty/dxml.py,sha256=VZADJS9z18LalENSvVfjk29ddnpaDQ-v8AVm_THwS1c,2607
12
- copyparty/fsutil.py,sha256=NC_CJC4TDag399vVDH9_uQfdfpTMwRFLNxERSWhlVvs,4594
13
- copyparty/ftpd.py,sha256=XtHvgtZPSMm0YMTCeKrElb8ZeIceHWskM16B3HyRXjQ,18264
12
+ copyparty/fsutil.py,sha256=kGvNM9G9YLeqcQjhDGfmT8gV7fn2WU0xye9BulL4h04,6469
13
+ copyparty/ftpd.py,sha256=aTnDmpaSbzsG6wAg8r3xf8ZLWHkdTJTgSYew2Oc4GoU,18266
14
14
  copyparty/httpcli.py,sha256=K-qyKwk9QChYTwqHcGFqugbCRni4YfswWT4yopk0Yf4,240218
15
15
  copyparty/httpconn.py,sha256=IA9fdCjigawZ4kWhgvVN3nSiy5pb3W2qaE6rFqUYdq0,6943
16
16
  copyparty/httpsrv.py,sha256=tza1m3Ob8A_iPjJBRoh9O_8ruAM7l3bJ905GsHsVf2A,19039
17
17
  copyparty/ico.py,sha256=-7QjF_jIxnPo4Vr0oUPksQ_U_Ef0HRsSPm3s71idOz8,3879
18
18
  copyparty/mdns.py,sha256=u0G1ho1Pqks5dtgsyn3qctgRhGHk3ufQ3Y8HJ2l4Nhk,18422
19
19
  copyparty/metrics.py,sha256=1dim0ShnsD5cfspRbeN9Mt14wOIxPRtxCZY2IScikKw,8974
20
- copyparty/mtag.py,sha256=fz0QXGc4F63iormFLkFCDtpSNmo6aDX5DmtkHBbovow,22803
20
+ copyparty/mtag.py,sha256=HGZDY7YF1Uqq73Pd76eCxMicpVnR-imFtjXze6Z7FsA,22829
21
21
  copyparty/multicast.py,sha256=xjCBHbbFI7XEohXxgBCAeExkzXJede6TLc5oR7ov5vM,12322
22
22
  copyparty/pwhash.py,sha256=58txP8GXIHOtWd__Tni8qkilHEGpOFsKIPuzjdFLc6M,4426
23
23
  copyparty/smbd.py,sha256=1iLbJMwG84EswYOe2irTc-CSJkzkM3Tq4cuqRFJDHII,14671
24
24
  copyparty/ssdp.py,sha256=R1Z61GZOxBMF2Sk4RTxKWMOemogmcjEWG-CvLihd45k,7023
25
25
  copyparty/star.py,sha256=tV5BbX6AiQ7N4UU8DYtSTckNYeoeey4DBqq4LjfymbY,3818
26
26
  copyparty/sutil.py,sha256=E65jAaOzHlJYnqsOKDMPVT8kALPUVexpkSStWBdItkY,3231
27
- copyparty/svchub.py,sha256=PTExaPzyztOHsMamPp-HNH8JKLdd4QSORNEov5KuPrA,54171
27
+ copyparty/svchub.py,sha256=aVSm2twX8XFj9sWdWbSEzHHwO6AvThFdENC332s3eqg,54269
28
28
  copyparty/szip.py,sha256=9srQzjsTBrBadf6QMh4YRAL70rkZLevAOHqXWK5jvr8,8846
29
29
  copyparty/tcpsrv.py,sha256=v3L4vpNwLC-gZjXEdeyS2QyCujYjnGz8FnGfnRKIZzI,22099
30
30
  copyparty/tftpd.py,sha256=fXW0w2_fSbzKVQGTLgr4DbtxaIEfwB591bl0pYhwy6k,14272
31
31
  copyparty/th_cli.py,sha256=n3MMbnN7HTVSBHkTI2qLIjgwVvHkGsfTW7-aPJ-2o4s,5545
32
32
  copyparty/th_srv.py,sha256=iAWBHgtAaYAshXdCFrUx7IWq4y3NXrH79yzHChsy2dc,38335
33
33
  copyparty/u2idx.py,sha256=YiacETpyncxHcyzhu3ltujovdLV7PPC7pZ3Tkwtwoj8,14437
34
- copyparty/up2k.py,sha256=__FwjSxXh1r8IywPqHU4118FCqZ_BQMuHGtuaZ_UnlQ,182779
35
- copyparty/util.py,sha256=g4eCa23uoz7rVPEOj6dAyuYZ3xwVIHv7AUUmYvtqvW4,109002
34
+ copyparty/up2k.py,sha256=bxE--k3nLUqI6SyGOvoBvX4EwRB7UYnMQmWnaBt0kjs,182845
35
+ copyparty/util.py,sha256=0pWH8zhfhQQ3tzHfX1TMUTaebCi5YdkPIhCygQw4h_I,109179
36
36
  copyparty/bos/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
37
  copyparty/bos/bos.py,sha256=aGnph4sLIXe7-SFLo5qo1V67Ab1ZtgiUNbAN8EnHvkA,3371
38
38
  copyparty/bos/path.py,sha256=yEjCq2ki9CvxA5sCT8pS0keEXwugs0ZeUyUhdBziOCI,777
@@ -57,7 +57,7 @@ copyparty/stolen/ifaddr/_win32.py,sha256=EE-QyoBgeB7lYQ6z62VjXNaRozaYfCkaJBHGNA8
57
57
  copyparty/web/baguettebox.js.gz,sha256=IXzu3LvbDUX1XXxtN88YHPaxIoJQEN6fo3Mx9T1mgdI,8365
58
58
  copyparty/web/browser.css.gz,sha256=NQJZWuyE2umXFakMrqE0Q0sVq55rORGdw_wA5PRz67o,15703
59
59
  copyparty/web/browser.html,sha256=DrhMtj-FUjDM0jYhQnsOkVMc8U0bFY_6uGMIY1HB9po,4791
60
- copyparty/web/browser.js.gz,sha256=tmGsp1xEJwM6o9ajSeIaZjQxc9FaLZUikAzM-HFe_Jk,315342
60
+ copyparty/web/browser.js.gz,sha256=0J_xaTlfi6uHyj9wtYhsCpjAetD9HTJDrgzCwDFuuwE,315342
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=fNf4wGVGdz5fDtn-97ks3XPIglTKnTKiYo4Dk2m-NoA,688
@@ -84,7 +84,7 @@ copyparty/web/splash.js.gz,sha256=35fsbq9PAN4p67BcXzJhkupDnM6W7qn48AUGYeaFPKI,15
84
84
  copyparty/web/svcs.html,sha256=jILgJ2WZ9gWHFqOla1tXTPPrR7XI5vENctz4UWTx0Go,17577
85
85
  copyparty/web/svcs.js.gz,sha256=DapO-UcJYln4VPyZ6Pwi0Lzhlyx0Hul7y7E2ephu34c,971
86
86
  copyparty/web/ui.css.gz,sha256=Txx36dDbFI7_9I2LPUO40nCFnxLFKVpdkBsHFwI7JoE,2848
87
- copyparty/web/up2k.js.gz,sha256=PzZR6mqB796ETr_EZVob0XZOrNZLo8GN3E8TYW3q7TY,25033
87
+ copyparty/web/up2k.js.gz,sha256=wD1KyDTIyv16e8OY1YLxE4yCuuB6LyRLV8lHptGWIck,25035
88
88
  copyparty/web/util.js.gz,sha256=CWy_7OGcsMo4RvQE21A4UF3BIP9hRJFXPAYTGjZOX2k,15571
89
89
  copyparty/web/w.hash.js.gz,sha256=rI-78PyXCdVjOpULbD9raBRyxxaPls5OjR7wonzXZPE,1193
90
90
  copyparty/web/a/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -105,9 +105,9 @@ copyparty/web/deps/prismd.css.gz,sha256=VPKuZhPmVyhTKHo2xN6IBX-C2A8Eo313vIPxQ2Hx
105
105
  copyparty/web/deps/scp.woff2,sha256=mmjmsoLDBPKa5VHcEdxZiJcDR1S1TOvCjIg5Cf1iL0s,8684
106
106
  copyparty/web/deps/sha512.ac.js.gz,sha256=OLk7EjA5e-DtJGlV0IQbvokpmoyE5v7djezx9kZBabE,7046
107
107
  copyparty/web/deps/sha512.hw.js.gz,sha256=UAed2_ocklZCnIzcSYz2h4P1ycztlCLj-ewsRTud2lU,7939
108
- copyparty-1.19.9.dist-info/licenses/LICENSE,sha256=gOr4h33pCsBEg9uIy9AYmb7qlocL4V9t2uPJS5wllr0,1072
109
- copyparty-1.19.9.dist-info/METADATA,sha256=35gSIe2RmfYMrNXpmjA2wt-Irvbi01lJZhpg_vpJAlo,177645
110
- copyparty-1.19.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
111
- copyparty-1.19.9.dist-info/entry_points.txt,sha256=4zw6a3rqASywQomiYLObjjlxybaI65LYYOTJwgKz7b0,128
112
- copyparty-1.19.9.dist-info/top_level.txt,sha256=LnYUPsDyk-8kFgM6YJLG4h820DQekn81cObKSu9g-sI,10
113
- copyparty-1.19.9.dist-info/RECORD,,
108
+ copyparty-1.19.11.dist-info/licenses/LICENSE,sha256=gOr4h33pCsBEg9uIy9AYmb7qlocL4V9t2uPJS5wllr0,1072
109
+ copyparty-1.19.11.dist-info/METADATA,sha256=xPs6zs__O4pfHzKTwwx81jlkuU1JcgEHQTkTr9uzsuo,177756
110
+ copyparty-1.19.11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
111
+ copyparty-1.19.11.dist-info/entry_points.txt,sha256=4zw6a3rqASywQomiYLObjjlxybaI65LYYOTJwgKz7b0,128
112
+ copyparty-1.19.11.dist-info/top_level.txt,sha256=LnYUPsDyk-8kFgM6YJLG4h820DQekn81cObKSu9g-sI,10
113
+ copyparty-1.19.11.dist-info/RECORD,,