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/util.py CHANGED
@@ -415,6 +415,27 @@ UNHUMANIZE_UNITS = {
415
415
  VF_CAREFUL = {"mv_re_t": 5, "rm_re_t": 5, "mv_re_r": 0.1, "rm_re_r": 0.1}
416
416
 
417
417
 
418
+ def read_ram() :
419
+ a = b = 0
420
+ try:
421
+ with open("/proc/meminfo", "rb", 0x10000) as f:
422
+ zsl = f.read(0x10000).decode("ascii", "replace").split("\n")
423
+
424
+ p = re.compile("^MemTotal:.* kB")
425
+ zs = next((x for x in zsl if p.match(x)))
426
+ a = int((int(zs.split()[1]) / 0x100000) * 100) / 100
427
+
428
+ p = re.compile("^MemAvailable:.* kB")
429
+ zs = next((x for x in zsl if p.match(x)))
430
+ b = int((int(zs.split()[1]) / 0x100000) * 100) / 100
431
+ except:
432
+ pass
433
+ return a, b
434
+
435
+
436
+ RAM_TOTAL, RAM_AVAIL = read_ram()
437
+
438
+
418
439
  pybin = sys.executable or ""
419
440
  if EXE:
420
441
  pybin = ""
@@ -647,13 +668,20 @@ class HLog(logging.Handler):
647
668
 
648
669
  class NetMap(object):
649
670
  def __init__(
650
- self, ips , cidrs , keep_lo=False, strict_cidr=False
671
+ self,
672
+ ips ,
673
+ cidrs ,
674
+ keep_lo=False,
675
+ strict_cidr=False,
676
+ defer_mutex=False,
651
677
  ) :
652
678
  """
653
679
  ips: list of plain ipv4/ipv6 IPs, not cidr
654
680
  cidrs: list of cidr-notation IPs (ip/prefix)
655
681
  """
656
- self.mutex = threading.Lock()
682
+
683
+ # fails multiprocessing; defer assignment
684
+ self.mutex = None if defer_mutex else threading.Lock()
657
685
 
658
686
  if "::" in ips:
659
687
  ips = [x for x in ips if x != "::"] + list(
@@ -692,6 +720,8 @@ class NetMap(object):
692
720
  try:
693
721
  return self.cache[ip]
694
722
  except:
723
+ # intentionally crash the calling thread if unset:
724
+
695
725
  with self.mutex:
696
726
  return self._map(ip)
697
727
 
@@ -940,6 +970,7 @@ class MTHash(object):
940
970
  self.sz = 0
941
971
  self.csz = 0
942
972
  self.stop = False
973
+ self.readsz = 1024 * 1024 * (2 if (RAM_AVAIL or 2) < 1 else 12)
943
974
  self.omutex = threading.Lock()
944
975
  self.imutex = threading.Lock()
945
976
  self.work_q = Queue()
@@ -1014,7 +1045,7 @@ class MTHash(object):
1014
1045
  while chunk_rem > 0:
1015
1046
  with self.imutex:
1016
1047
  f.seek(ofs)
1017
- buf = f.read(min(chunk_rem, 1024 * 1024 * 12))
1048
+ buf = f.read(min(chunk_rem, self.readsz))
1018
1049
 
1019
1050
  if not buf:
1020
1051
  raise Exception("EOF at " + str(ofs))
@@ -2109,6 +2140,23 @@ def unquotep(txt ) :
2109
2140
  return w8dec(unq2)
2110
2141
 
2111
2142
 
2143
+ def vroots(vp1 , vp2 ) :
2144
+ """
2145
+ input("q/w/e/r","a/s/d/e/r") output("/q/w/","/a/s/d/")
2146
+ """
2147
+ while vp1 and vp2:
2148
+ zt1 = vp1.rsplit("/", 1) if "/" in vp1 else ("", vp1)
2149
+ zt2 = vp2.rsplit("/", 1) if "/" in vp2 else ("", vp2)
2150
+ if zt1[1] != zt2[1]:
2151
+ break
2152
+ vp1 = zt1[0]
2153
+ vp2 = zt2[0]
2154
+ return (
2155
+ "/%s/" % (vp1,) if vp1 else "/",
2156
+ "/%s/" % (vp2,) if vp2 else "/",
2157
+ )
2158
+
2159
+
2112
2160
  def vsplit(vpath ) :
2113
2161
  if "/" not in vpath:
2114
2162
  return "", vpath
@@ -2568,7 +2616,7 @@ def list_ips() :
2568
2616
  return list(ret)
2569
2617
 
2570
2618
 
2571
- def build_netmap(csv ):
2619
+ def build_netmap(csv , defer_mutex = False):
2572
2620
  csv = csv.lower().strip()
2573
2621
 
2574
2622
  if csv in ("any", "all", "no", ",", ""):
@@ -2603,10 +2651,12 @@ def build_netmap(csv ):
2603
2651
  cidrs.append(zs)
2604
2652
 
2605
2653
  ips = [x.split("/")[0] for x in cidrs]
2606
- return NetMap(ips, cidrs, True)
2654
+ return NetMap(ips, cidrs, True, False, defer_mutex)
2607
2655
 
2608
2656
 
2609
- def load_ipu(log , ipus ) :
2657
+ def load_ipu(
2658
+ log , ipus , defer_mutex = False
2659
+ ) :
2610
2660
  ip_u = {"": "*"}
2611
2661
  cidr_u = {}
2612
2662
  for ipu in ipus:
@@ -2623,7 +2673,7 @@ def load_ipu(log , ipus ) :
2623
2673
  cidr_u[cidr] = uname
2624
2674
  ip_u[cip] = uname
2625
2675
  try:
2626
- nm = NetMap(["::"], list(cidr_u.keys()), True, True)
2676
+ nm = NetMap(["::"], list(cidr_u.keys()), True, True, defer_mutex)
2627
2677
  except Exception as ex:
2628
2678
  t = "failed to translate --ipu into netmap, probably due to invalid config: %r"
2629
2679
  log("root", t % (ex,), 1)
@@ -2676,7 +2726,10 @@ def sendfile_py(
2676
2726
  bufsz ,
2677
2727
  slp ,
2678
2728
  use_poll ,
2729
+ dls ,
2730
+ dl_id ,
2679
2731
  ) :
2732
+ sent = 0
2680
2733
  remains = upper - lower
2681
2734
  f.seek(lower)
2682
2735
  while remains > 0:
@@ -2693,6 +2746,10 @@ def sendfile_py(
2693
2746
  except:
2694
2747
  return remains
2695
2748
 
2749
+ if dl_id:
2750
+ sent += len(buf)
2751
+ dls[dl_id] = (time.time(), sent)
2752
+
2696
2753
  return 0
2697
2754
 
2698
2755
 
@@ -2705,6 +2762,8 @@ def sendfile_kern(
2705
2762
  bufsz ,
2706
2763
  slp ,
2707
2764
  use_poll ,
2765
+ dls ,
2766
+ dl_id ,
2708
2767
  ) :
2709
2768
  out_fd = s.fileno()
2710
2769
  in_fd = f.fileno()
@@ -2717,7 +2776,7 @@ def sendfile_kern(
2717
2776
  while ofs < upper:
2718
2777
  stuck = stuck or time.time()
2719
2778
  try:
2720
- req = min(2 ** 30, upper - ofs)
2779
+ req = min(0x2000000, upper - ofs) # 32 MiB
2721
2780
  if use_poll:
2722
2781
  poll.poll(10000)
2723
2782
  else:
@@ -2741,13 +2800,16 @@ def sendfile_kern(
2741
2800
  return upper - ofs
2742
2801
 
2743
2802
  ofs += n
2803
+ if dl_id:
2804
+ dls[dl_id] = (time.time(), ofs - lower)
2805
+
2744
2806
  # print("sendfile: ok, sent {} now, {} total, {} remains".format(n, ofs - lower, upper - ofs))
2745
2807
 
2746
2808
  return 0
2747
2809
 
2748
2810
 
2749
2811
  def statdir(
2750
- logger , scandir , lstat , top
2812
+ logger , scandir , lstat , top , throw
2751
2813
  ) :
2752
2814
  if lstat and ANYWIN:
2753
2815
  lstat = False
@@ -2783,6 +2845,12 @@ def statdir(
2783
2845
  logger(src, "[s] {} @ {}".format(repr(ex), fsdec(abspath)), 6)
2784
2846
 
2785
2847
  except Exception as ex:
2848
+ if throw:
2849
+ zi = getattr(ex, "errno", 0)
2850
+ if zi == errno.ENOENT:
2851
+ raise Pebkac(404, str(ex))
2852
+ raise
2853
+
2786
2854
  t = "{} @ {}".format(repr(ex), top)
2787
2855
  if logger:
2788
2856
  logger(src, t, 1)
@@ -2791,7 +2859,7 @@ def statdir(
2791
2859
 
2792
2860
 
2793
2861
  def dir_is_empty(logger , scandir , top ):
2794
- for _ in statdir(logger, scandir, False, top):
2862
+ for _ in statdir(logger, scandir, False, top, False):
2795
2863
  return False
2796
2864
  return True
2797
2865
 
@@ -2804,7 +2872,7 @@ def rmdirs(
2804
2872
  top = os.path.dirname(top)
2805
2873
  depth -= 1
2806
2874
 
2807
- stats = statdir(logger, scandir, lstat, top)
2875
+ stats = statdir(logger, scandir, lstat, top, False)
2808
2876
  dirs = [x[0] for x in stats if stat.S_ISDIR(x[1].st_mode)]
2809
2877
  dirs = [os.path.join(top, x) for x in dirs]
2810
2878
  ok = []
@@ -358,7 +358,8 @@ class Gateway(object):
358
358
  if r.status != 200:
359
359
  self.closeconn()
360
360
  info("http error %s reading dir %r", r.status, web_path)
361
- raise FuseOSError(errno.ENOENT)
361
+ err = errno.ENOENT if r.status == 404 else errno.EIO
362
+ raise FuseOSError(err)
362
363
 
363
364
  ctype = r.getheader("Content-Type", "")
364
365
  if ctype == "application/json":
@@ -844,7 +845,7 @@ def main():
844
845
 
845
846
  # dircache is always a boost,
846
847
  # only want to disable it for tests etc,
847
- cdn = 9 # max num dirs; 0=disable
848
+ cdn = 24 # max num dirs; keep larger than max dir depth; 0=disable
848
849
  cds = 1 # numsec until an entry goes stale
849
850
 
850
851
  where = "local directory"
copyparty/web/a/u2c.py CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env python3
2
2
  from __future__ import print_function, unicode_literals
3
3
 
4
- S_VERSION = "2.5"
5
- S_BUILD_DT = "2024-10-18"
4
+ S_VERSION = "2.6"
5
+ S_BUILD_DT = "2024-11-10"
6
6
 
7
7
  """
8
8
  u2c.py: upload to copyparty
@@ -189,6 +189,8 @@ class HCli(object):
189
189
  return C(self.addr, self.port, timeout=timeout, **args)
190
190
 
191
191
  def req(self, meth, vpath, hdrs, body=None, ctype=None):
192
+ now = time.time()
193
+
192
194
  hdrs.update(self.base_hdrs)
193
195
  if self.ar.a:
194
196
  hdrs["PW"] = self.ar.a
@@ -201,7 +203,9 @@ class HCli(object):
201
203
 
202
204
  # large timeout for handshakes (safededup)
203
205
  conns = self.hconns if ctype == MJ else self.conns
204
- c = conns.pop() if conns else self._connect(999 if ctype == MJ else 128)
206
+ while conns and self.ar.cxp < now - conns[0][0]:
207
+ conns.pop(0)[1].close()
208
+ c = conns.pop()[1] if conns else self._connect(999 if ctype == MJ else 128)
205
209
  try:
206
210
  c.request(meth, vpath, body, hdrs)
207
211
  if PY27:
@@ -210,8 +214,15 @@ class HCli(object):
210
214
  rsp = c.getresponse()
211
215
 
212
216
  data = rsp.read()
213
- conns.append(c)
217
+ conns.append((time.time(), c))
214
218
  return rsp.status, data.decode("utf-8")
219
+ except http_client.BadStatusLine:
220
+ if self.ar.cxp > 4:
221
+ t = "\nWARNING: --cxp probably too high; reducing from %d to 4"
222
+ print(t % (self.ar.cxp,))
223
+ self.ar.cxp = 4
224
+ c.close()
225
+ raise
215
226
  except:
216
227
  c.close()
217
228
  raise
@@ -1140,7 +1151,10 @@ class Ctl(object):
1140
1151
 
1141
1152
  if self.ar.drd:
1142
1153
  dp = os.path.join(top, rd)
1143
- lnodes = set(os.listdir(dp))
1154
+ try:
1155
+ lnodes = set(os.listdir(dp))
1156
+ except:
1157
+ lnodes = list(ls) # fs eio; don't delete
1144
1158
  if ptn:
1145
1159
  zs = dp.replace(sep, b"/").rstrip(b"/") + b"/"
1146
1160
  zls = [zs + x for x in lnodes]
@@ -1498,6 +1512,7 @@ source file/folder selection uses rsync syntax, meaning that:
1498
1512
  ap.add_argument("--szm", type=int, metavar="MiB", default=96, help="max size of each POST (default is cloudflare max)")
1499
1513
  ap.add_argument("-nh", action="store_true", help="disable hashing while uploading")
1500
1514
  ap.add_argument("-ns", action="store_true", help="no status panel (for slow consoles and macos)")
1515
+ ap.add_argument("--cxp", type=float, metavar="SEC", default=57, help="assume http connections expired after SEConds")
1501
1516
  ap.add_argument("--cd", type=float, metavar="SEC", default=5, help="delay before reattempting a failed handshake/upload")
1502
1517
  ap.add_argument("--safe", action="store_true", help="use simple fallback approach")
1503
1518
  ap.add_argument("-z", action="store_true", help="ZOOMIN' (skip uploading files if they exist at the destination with the ~same last-modified timestamp, so same as yolo / turbo with date-chk but even faster)")
Binary file
Binary file
Binary file
Binary file
copyparty/web/splash.html CHANGED
@@ -44,6 +44,18 @@
44
44
  </table>
45
45
  {%- endif %}
46
46
 
47
+ {%- if dls %}
48
+ <h1 id="ae">active downloads:</h1>
49
+ <table class="vols">
50
+ <thead><tr><th>%</th><th>sent</th><th>speed</th><th>eta</th><th>idle</th><th></th><th>dir</th><th>file</th></tr></thead>
51
+ <tbody>
52
+ {% for u in dls %}
53
+ <tr><td>{{ u[0] }}</td><td>{{ u[1] }}</td><td>{{ u[2] }}</td><td>{{ u[3] }}</td><td>{{ u[4] }}</td><td>{{ u[5] }}</td><td><a href="{{ u[6] }}">{{ u[7]|e }}</a></td><td>{{ u[8] }}</td></tr>
54
+ {% endfor %}
55
+ </tbody>
56
+ </table>
57
+ {%- endif %}
58
+
47
59
  {%- if avol %}
48
60
  <h1>admin panel:</h1>
49
61
  <table><tr><td> <!-- hehehe -->
@@ -129,11 +141,20 @@
129
141
 
130
142
  {% if k304 or k304vis %}
131
143
  {% if k304 %}
132
- <li><a id="h" href="{{ r }}/?k304=n">disable k304</a> (currently enabled)
144
+ <li><a id="h" href="{{ r }}/?cc&setck=k304=n">disable k304</a> (currently enabled)
145
+ {%- else %}
146
+ <li><a id="i" href="{{ r }}/?cc&setck=k304=y" class="r">enable k304</a> (currently disabled)
147
+ {% endif %}
148
+ <blockquote id="j">enabling k304 will disconnect your client on every HTTP 304, which can prevent some buggy proxies from getting stuck (suddenly not loading pages), <em>but</em> it will also make things slower in general</blockquote></li>
149
+ {% endif %}
150
+
151
+ {% if no304 or no304vis %}
152
+ {% if no304 %}
153
+ <li><a id="ab" href="{{ r }}/?cc&setck=no304=n">disable no304</a> (currently enabled)
133
154
  {%- else %}
134
- <li><a id="i" href="{{ r }}/?k304=y" class="r">enable k304</a> (currently disabled)
155
+ <li><a id="ac" href="{{ r }}/?cc&setck=no304=y" class="r">enable no304</a> (currently disabled)
135
156
  {% endif %}
136
- <blockquote id="j">enabling this will disconnect your client on every HTTP 304, which can prevent some buggy proxies from getting stuck (suddenly not loading pages), <em>but</em> it will also make things slower in general</blockquote></li>
157
+ <blockquote id="ad">enabling no304 will disable all caching; try this if k304 wasn't enough. This will waste a huge amount of network traffic!</blockquote></li>
137
158
  {% endif %}
138
159
 
139
160
  <li><a id="k" href="{{ r }}/?reset" class="r" onclick="localStorage.clear();return true">reset client settings</a></li>
Binary file
copyparty/web/ui.css.gz CHANGED
Binary file
copyparty/web/util.js.gz CHANGED
Binary file
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: copyparty
3
- Version: 1.15.9
3
+ Version: 1.16.0
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
@@ -21,6 +21,7 @@ Classifier: Programming Language :: Python :: 3.9
21
21
  Classifier: Programming Language :: Python :: 3.10
22
22
  Classifier: Programming Language :: Python :: 3.11
23
23
  Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Programming Language :: Python :: 3.13
24
25
  Classifier: Programming Language :: Python :: Implementation :: CPython
25
26
  Classifier: Programming Language :: Python :: Implementation :: Jython
26
27
  Classifier: Programming Language :: Python :: Implementation :: PyPy
@@ -482,7 +483,7 @@ configuring accounts/volumes with arguments:
482
483
 
483
484
  permissions:
484
485
  * `r` (read): browse folder contents, download files, download as zip/tar, see filekeys/dirkeys
485
- * `w` (write): upload files, move files *into* this folder
486
+ * `w` (write): upload files, move/copy files *into* this folder
486
487
  * `m` (move): move files/folders *from* this folder
487
488
  * `d` (delete): delete files/folders
488
489
  * `.` (dots): user can ask to show dotfiles in directory listings
@@ -562,7 +563,8 @@ the browser has the following hotkeys (always qwerty)
562
563
  * `ESC` close various things
563
564
  * `ctrl-K` delete selected files/folders
564
565
  * `ctrl-X` cut selected files/folders
565
- * `ctrl-V` paste
566
+ * `ctrl-C` copy selected files/folders to clipboard
567
+ * `ctrl-V` paste (move/copy)
566
568
  * `Y` download selected files
567
569
  * `F2` [rename](#batch-rename) selected file/folder
568
570
  * when a file/folder is selected (in not-grid-view):
@@ -631,6 +633,7 @@ click the `🌲` or pressing the `B` hotkey to toggle between breadcrumbs path (
631
633
 
632
634
  press `g` or `田` to toggle grid-view instead of the file listing and `t` toggles icons / thumbnails
633
635
  * can be made default globally with `--grid` or per-volume with volflag `grid`
636
+ * enable by adding `?imgs` to a link, or disable with `?imgs=0`
634
637
 
635
638
  ![copyparty-thumbs-fs8](https://user-images.githubusercontent.com/241032/129636211-abd20fa2-a953-4366-9423-1c88ebb96ba9.png)
636
639
 
@@ -810,10 +813,11 @@ file selection: click somewhere on the line (not the link itself), then:
810
813
  * shift-click another line for range-select
811
814
 
812
815
  * cut: select some files and `ctrl-x`
816
+ * copy: select some files and `ctrl-c`
813
817
  * paste: `ctrl-v` in another folder
814
818
  * rename: `F2`
815
819
 
816
- you can move files across browser tabs (cut in one tab, paste in another)
820
+ you can copy/move files across browser tabs (cut/copy in one tab, paste in another)
817
821
 
818
822
 
819
823
  ## shares
@@ -1738,6 +1742,7 @@ scrape_configs:
1738
1742
  currently the following metrics are available,
1739
1743
  * `cpp_uptime_seconds` time since last copyparty restart
1740
1744
  * `cpp_boot_unixtime_seconds` same but as an absolute timestamp
1745
+ * `cpp_active_dl` number of active downloads
1741
1746
  * `cpp_http_conns` number of open http(s) connections
1742
1747
  * `cpp_http_reqs` number of http(s) requests handled
1743
1748
  * `cpp_sus_reqs` number of 403/422/malicious requests
@@ -1987,6 +1992,9 @@ quick summary of more eccentric web-browsers trying to view a directory index:
1987
1992
  | **ie4** and **netscape** 4.0 | can browse, upload with `?b=u`, auth with `&pw=wark` |
1988
1993
  | **ncsa mosaic** 2.7 | does not get a pass, [pic1](https://user-images.githubusercontent.com/241032/174189227-ae816026-cf6f-4be5-a26e-1b3b072c1b2f.png) - [pic2](https://user-images.githubusercontent.com/241032/174189225-5651c059-5152-46e9-ac26-7e98e497901b.png) |
1989
1994
  | **SerenityOS** (7e98457) | hits a page fault, works with `?b=u`, file upload not-impl |
1995
+ | **nintendo 3ds** | can browse, upload, view thumbnails (thx bnjmn) |
1996
+
1997
+ <p align="center"><img src="https://github.com/user-attachments/assets/88deab3d-6cad-4017-8841-2f041472b853" /></p>
1990
1998
 
1991
1999
 
1992
2000
  # client examples
@@ -1,22 +1,22 @@
1
- copyparty/__init__.py,sha256=Chqw7uXX4r_-a2p6-xthrrqVHFI4aZdW45sWU7UvqeE,2597
2
- copyparty/__main__.py,sha256=rx8OlvcX3M-SQOvkrYT9C-HN7GmlPUx5p_2Vqv_LEo4,110949
3
- copyparty/__version__.py,sha256=PMcIJPKN9PvxPb2mIFEiFAsp9HLavA8qaM4ckTc7cNE,258
4
- copyparty/authsrv.py,sha256=Iw_4lJUhRU9q3qCQucGWRtJOFKYrYd5omL5nmwGvw-k,98979
5
- copyparty/broker_mp.py,sha256=jsHUM2BSfRVRyZT869iPCqYEHSqedk6VkwvygZwbEZE,4017
6
- copyparty/broker_mpw.py,sha256=PYFgQfssOCfdI6qayW1ZjO1j1-7oez094muhYMbPOz0,3339
7
- copyparty/broker_thr.py,sha256=MXrwjusP0z1LPURUhi5jx_TL3jrXhYcDrJPDSKu6EEU,1705
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
5
+ copyparty/broker_mp.py,sha256=QdOXXvV2Xn6J0CysEqyY3GZbqxQMyWnTpnba-a5lMc0,4987
6
+ copyparty/broker_mpw.py,sha256=PpSS4SK3pItlpfD8OwVr3QmJEPKlUgaf2nuMOozixgU,3347
7
+ copyparty/broker_thr.py,sha256=fjoYtpSscUA7-nMl4r1n2R7UK3J9lrvLS3rUZ-iJzKQ,1721
8
8
  copyparty/broker_util.py,sha256=76mfnFOpX1gUUvtjm8UQI7jpTIaVINX10QonM-B7ggc,1680
9
9
  copyparty/cert.py,sha256=0ZAPeXeMR164vWn9GQU3JDKooYXEq_NOQkDeg543ivg,8009
10
- copyparty/cfg.py,sha256=E9iBGNjIUrDAPLFRgKsVOmAknP9bDE27xh0gkmNdH1s,10127
10
+ copyparty/cfg.py,sha256=4-Tk1Yb3eGcA8pO3jNRzd9HfCci6vRu3BNWarry0ia8,10263
11
11
  copyparty/dxml.py,sha256=lZpg-kn-kQsXRtNY1n6fRaS-b7uXzMCyv8ovKnhZcZc,1548
12
12
  copyparty/fsutil.py,sha256=5CshJWO7CflfaRRNOb3JxghUH7W5rmS_HWNmKfx42MM,4538
13
- copyparty/ftpd.py,sha256=G_h1urfIikzfCWGXnW9p-rioWdNM_Je6vWYq0-QSbC8,17580
14
- copyparty/httpcli.py,sha256=irIxsAI0KpNvxoenK16zkezttl4sUSNUB59yBr8L6VA,199053
13
+ copyparty/ftpd.py,sha256=T97SFS7JFtvRLbJX8C4fJSYwe13vhN3-E6emtlVmqLA,17608
14
+ copyparty/httpcli.py,sha256=tu5abG7JpDZYTDlPNv9p5SYGd0ZgAdoWf8HNYAr45V4,206103
15
15
  copyparty/httpconn.py,sha256=mQSgljh0Q-jyWjF4tQLrHbRKRe9WKl19kGqsGMsJpWo,6880
16
- copyparty/httpsrv.py,sha256=d_UiGnQKniBoEV68lNFgnYm-byda7uj56mFf-YC7piI,17223
16
+ copyparty/httpsrv.py,sha256=WMQ-0sk6wk4Gbg7FB1ZYvnb74EsZQ5b7WJT0zAwZXjA,18226
17
17
  copyparty/ico.py,sha256=eWSxEae4wOCfheHl-m-wchYvFRAR_97kJDb4NGaB-Z8,3561
18
18
  copyparty/mdns.py,sha256=vC078llnL1v0pvL3mnwacuStFHPJUQuxo9Opj-IbHL4,18155
19
- copyparty/metrics.py,sha256=-1Rkk44gBh_1YJbdzGZHaqR4pEwkbno6fSdsRb5wDIk,8865
19
+ copyparty/metrics.py,sha256=EOIiPOItEQmdK9YgNb75l0kCzanWb6RtJGwMI7ufifY,8966
20
20
  copyparty/mtag.py,sha256=8WGjEn0T0Ri9ww1yBpLUnFHZiTQMye1BMXL6SkK3MRo,18893
21
21
  copyparty/multicast.py,sha256=Ha27l2oATEa-Qo2WOzkeRgjAm6G_YDCfbVJWR-ao2UE,12319
22
22
  copyparty/pwhash.py,sha256=AdLMLyIi2IDhGtbKIQOswKUxWvO7ARYYRF_ThsryOoc,4124
@@ -24,15 +24,15 @@ copyparty/smbd.py,sha256=Or7RF13cl1r3ncnpVh8BqyAGqH2Oa04O9iPZWCoB0Bo,14609
24
24
  copyparty/ssdp.py,sha256=R1Z61GZOxBMF2Sk4RTxKWMOemogmcjEWG-CvLihd45k,7023
25
25
  copyparty/star.py,sha256=tV5BbX6AiQ7N4UU8DYtSTckNYeoeey4DBqq4LjfymbY,3818
26
26
  copyparty/sutil.py,sha256=JTMrQwcWH85hXB_cKG206eDZ967WZDGaP00AWvl_gB0,3214
27
- copyparty/svchub.py,sha256=FuQGFBm-lJfe28M-SMBLieHy8jdWIQMkONK2GcWZU_E,40105
28
- copyparty/szip.py,sha256=sDypi1_yR6-62fIZ_3D0L9PfIzCUiK_3JqcaJCvTBCs,8601
29
- copyparty/tcpsrv.py,sha256=l_vb9FoF0AJur0IoqHNUSBDqMgBO_MRUZeDszi1UNfY,19881
30
- copyparty/tftpd.py,sha256=jZbf2JpeJmkuQWJErmAPG-dKhtYNvIUHbkAgodSXw9Y,13582
27
+ copyparty/svchub.py,sha256=op6BtcsSa0OLmnJ_dslPswaNTOZaqScM8tRZnQrMkDs,40864
28
+ copyparty/szip.py,sha256=HFtnwOiBgx0HMLUf-h_T84zSlRijPxmhRo5PM613kRA,8602
29
+ copyparty/tcpsrv.py,sha256=VuW_aVDcyXIhIMZ8I-wpIouX8MI9TGp7KKSRohrMTtk,19897
30
+ copyparty/tftpd.py,sha256=FRCALO3PigoBlwUrqxoKHM_xk7wT2O0GPG1TvNRtjOY,13606
31
31
  copyparty/th_cli.py,sha256=o6FMkerYvAXS455z3DUossVztu_nzFlYSQhs6qN6Jt8,4636
32
- copyparty/th_srv.py,sha256=hI9wY1E_9N9Cgqvtr8zADeVqqiLGTiTdAnYAA7WFvJw,29346
32
+ copyparty/th_srv.py,sha256=LBcB4LpsF-H7L52Z0Dhn9LogRjJVPp1GKa8MeIMIBnw,29596
33
33
  copyparty/u2idx.py,sha256=HLO49L1zmpJtBcJiXgD12a6pAlQdnf2pFelHMA7habw,13462
34
- copyparty/up2k.py,sha256=2K21-Scz4c3_Y9MzAPmvq3_LEOIkFnx7KLR6hqJkP18,165419
35
- copyparty/util.py,sha256=eJU7a5O-bZf_MEplCVmLoS3r5mjPC3-2khqZVTYGw-c,92653
34
+ copyparty/up2k.py,sha256=m7sWNWmRR1-VoFzlXlAOYxwhOlbeOyFBO5a8Rcl6mnE,173608
35
+ copyparty/util.py,sha256=jk4Z32KuIvqPQK8aveYhUfGZT9k0LR8viGGfcX4iab4,94422
36
36
  copyparty/bos/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
37
  copyparty/bos/bos.py,sha256=Wb7eWsXJgR5AFlBR9ZOyKrLTwy-Kct9RrGiOu4Jo37Y,1622
38
38
  copyparty/bos/path.py,sha256=yEjCq2ki9CvxA5sCT8pS0keEXwugs0ZeUyUhdBziOCI,777
@@ -55,9 +55,9 @@ copyparty/stolen/ifaddr/_posix.py,sha256=-67NdfGrCktfQPakT2fLbjl2U00QMvyBGkSvrUu
55
55
  copyparty/stolen/ifaddr/_shared.py,sha256=uNC4SdEIgdSLKvuUzsf1aM-H1Xrc_9mpLoOT43YukGs,6206
56
56
  copyparty/stolen/ifaddr/_win32.py,sha256=EE-QyoBgeB7lYQ6z62VjXNaRozaYfCkaJBHGNA8QtZM,4026
57
57
  copyparty/web/baguettebox.js.gz,sha256=YIaxFDsubJfGIdzzxA-cL6GwJVmpWZyaPhW9hHcOIIw,7964
58
- copyparty/web/browser.css.gz,sha256=4bAS9Xkl2fflhaxRSRSVoYQcpXsg1mCWxsYjId7phbU,11610
58
+ copyparty/web/browser.css.gz,sha256=N5T5U-iWzls21E2SYkQvDUaaZf11gjj3KwUP0lm1mMA,11672
59
59
  copyparty/web/browser.html,sha256=ISpfvWEawufJCYZIqvuXiyUgiXgjmOTtScz4zrEaypI,4870
60
- copyparty/web/browser.js.gz,sha256=7rubbEoqFlNn7FPF0mz3L2LQeWuPzw95MYpIaZmcczE,84985
60
+ copyparty/web/browser.js.gz,sha256=uGALYaMsyyXuCSKbvdMZpB-YrIvCIV3JWo611xRlHd8,88488
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
@@ -73,19 +73,19 @@ copyparty/web/msg.css.gz,sha256=u90fXYAVrMD-jqwf5XFVC1ptSpSHZUe8Mez6PX101P8,300
73
73
  copyparty/web/msg.html,sha256=w9CM3hkLLGJX9fWEaG4gSbTOPe2GcPqW8BpSCDiFzOI,977
74
74
  copyparty/web/shares.css.gz,sha256=T2fSezuluDVIiNIERAuUREByhHFlIwwNyx7EBOAVVyQ,499
75
75
  copyparty/web/shares.html,sha256=ZNHtLBM-Y4BX2qa9AGTrZzZp_IP5PLM3QvFMYKolFfM,2494
76
- copyparty/web/shares.js.gz,sha256=814O61mxLSWs0AO2fbGJ8d4BSPB7pE9NdkKiVf1gj6E,926
77
- copyparty/web/splash.css.gz,sha256=RjdNoIT5BSxXRFu0ldMUH4ghRNUMCTs2mGKzstrpI6o,1033
78
- copyparty/web/splash.html,sha256=pUbsso_W3Q7bso8fy8qxh-fHDrrLm39mBBTIlTeH63w,5235
79
- copyparty/web/splash.js.gz,sha256=Xoccku-2vE3tABo-88q3Cl4koHs_AE76T8QvMy4u6T8,2540
76
+ copyparty/web/shares.js.gz,sha256=_8_1MkmERDcrPeLFpNGzJA4vticRzNRehGKeDV24fNs,926
77
+ copyparty/web/splash.css.gz,sha256=zgF2kvrp7z8LlhkaXNvFkP3RLlA4dHFZCkwQpG5RcYI,1081
78
+ copyparty/web/splash.html,sha256=wc8El8_5BR3EMuVik8WYAkkEQ4S6-VepR1B1F8qAYgI,6190
79
+ copyparty/web/splash.js.gz,sha256=EEfsi9YGtPTYRB6MPX8Dfg4YyfqncI9ldJS7_MGVOhs,2710
80
80
  copyparty/web/svcs.html,sha256=P5YZimYLeQMT0uz6u3clQSNZRc5Zs0Ok-ffcbcGSYuc,11762
81
81
  copyparty/web/svcs.js.gz,sha256=k81ZvZ3I-f4fMHKrNGGOgOlvXnCBz0mVjD-8mieoWCA,520
82
- copyparty/web/ui.css.gz,sha256=wloSacrHgP722hy4XiOvVY2GI9-V4zvfvzu84LLWS_o,2779
82
+ copyparty/web/ui.css.gz,sha256=DCWgsJLb4exJ3_tUPHRcI0PuLLNlJJ1krF3WiSN9I7w,2785
83
83
  copyparty/web/up2k.js.gz,sha256=lGR1Xb0RkIZ1eHmncsSwWRuFc6FC2rZalvjo3oNTV1s,23291
84
- copyparty/web/util.js.gz,sha256=NvjPYhIa0-C_NhUyW-Ra-XinUCRjj8G3pYq1zJHYWEk,14805
84
+ copyparty/web/util.js.gz,sha256=AMr49EVNOJiJjgSJyYyXKf_tHFLk3ODkCPQu26zbMZI,14815
85
85
  copyparty/web/w.hash.js.gz,sha256=l3GpSJD6mcU-1CRWkIj7PybgbjlfSr8oeO3vortIrQk,1105
86
86
  copyparty/web/a/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
87
- copyparty/web/a/partyfuse.py,sha256=fa9bBYNJHvtWpNVjQyyFzx6JOK7MJL1u0zj80PBYQKs,27960
88
- copyparty/web/a/u2c.py,sha256=ZmLcGuOWB66ZkAMpJBiR1Xpa75PgpzdFRTt3GGVCorc,49533
87
+ copyparty/web/a/partyfuse.py,sha256=9p5Hpg_IBiSimv7j9kmPhCGpy-FLXSRUOYnLjJ5JifU,28049
88
+ copyparty/web/a/u2c.py,sha256=4_YvRoWEAYrUVQHRts-1rPdWLBd6axfzG0fF5mc2Uj8,50196
89
89
  copyparty/web/a/webdav-cfg.bat,sha256=Y4NoGZlksAIg4cBMb7KdJrpKC6Nx97onaTl6yMjaimk,1449
90
90
  copyparty/web/dd/2.png,sha256=gJ14XFPzaw95L6z92fSq9eMPikSQyu-03P1lgiGe0_I,258
91
91
  copyparty/web/dd/3.png,sha256=4lho8Koz5tV7jJ4ODo6GMTScZfkqsT05yp48EDFIlyg,252
@@ -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.15.9.dist-info/LICENSE,sha256=gOr4h33pCsBEg9uIy9AYmb7qlocL4V9t2uPJS5wllr0,1072
110
- copyparty-1.15.9.dist-info/METADATA,sha256=1GMM2x8ZO0z3TgiQgCB6xEiiahXsn3PdeiA7Uni_D_4,139807
111
- copyparty-1.15.9.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
112
- copyparty-1.15.9.dist-info/entry_points.txt,sha256=4zw6a3rqASywQomiYLObjjlxybaI65LYYOTJwgKz7b0,128
113
- copyparty-1.15.9.dist-info/top_level.txt,sha256=LnYUPsDyk-8kFgM6YJLG4h820DQekn81cObKSu9g-sI,10
114
- copyparty-1.15.9.dist-info/RECORD,,
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,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.2.0)
2
+ Generator: setuptools (75.3.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5