copyparty 1.16.14__tar.gz → 1.16.16__tar.gz

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.
Files changed (125) hide show
  1. {copyparty-1.16.14 → copyparty-1.16.16}/PKG-INFO +3 -1
  2. {copyparty-1.16.14 → copyparty-1.16.16}/README.md +2 -0
  3. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/__version__.py +2 -2
  4. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/authsrv.py +8 -7
  5. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/cfg.py +3 -0
  6. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/httpcli.py +9 -4
  7. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/up2k.py +6 -1
  8. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/browser.js.gz +0 -0
  9. copyparty-1.16.16/copyparty/web/md2.js.gz +0 -0
  10. copyparty-1.16.16/copyparty/web/up2k.js.gz +0 -0
  11. copyparty-1.16.16/copyparty/web/w.hash.js.gz +0 -0
  12. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty.egg-info/PKG-INFO +3 -1
  13. copyparty-1.16.14/copyparty/web/md2.js.gz +0 -0
  14. copyparty-1.16.14/copyparty/web/up2k.js.gz +0 -0
  15. copyparty-1.16.14/copyparty/web/w.hash.js.gz +0 -0
  16. {copyparty-1.16.14 → copyparty-1.16.16}/LICENSE +0 -0
  17. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/__init__.py +0 -0
  18. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/__main__.py +0 -0
  19. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/bos/__init__.py +0 -0
  20. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/bos/bos.py +0 -0
  21. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/bos/path.py +0 -0
  22. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/broker_mp.py +0 -0
  23. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/broker_mpw.py +0 -0
  24. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/broker_thr.py +0 -0
  25. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/broker_util.py +0 -0
  26. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/cert.py +0 -0
  27. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/dxml.py +0 -0
  28. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/fsutil.py +0 -0
  29. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/ftpd.py +0 -0
  30. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/httpconn.py +0 -0
  31. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/httpsrv.py +0 -0
  32. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/ico.py +0 -0
  33. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/mdns.py +0 -0
  34. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/metrics.py +0 -0
  35. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/mtag.py +0 -0
  36. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/multicast.py +0 -0
  37. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/pwhash.py +0 -0
  38. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/res/COPYING.txt +0 -0
  39. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/res/__init__.py +0 -0
  40. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/res/insecure.pem +0 -0
  41. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/smbd.py +0 -0
  42. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/ssdp.py +0 -0
  43. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/star.py +0 -0
  44. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/stolen/__init__.py +0 -0
  45. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/stolen/dnslib/__init__.py +0 -0
  46. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/stolen/dnslib/bimap.py +0 -0
  47. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/stolen/dnslib/bit.py +0 -0
  48. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/stolen/dnslib/buffer.py +0 -0
  49. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/stolen/dnslib/dns.py +0 -0
  50. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/stolen/dnslib/label.py +0 -0
  51. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/stolen/dnslib/lex.py +0 -0
  52. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/stolen/dnslib/ranges.py +0 -0
  53. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/stolen/ifaddr/__init__.py +0 -0
  54. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/stolen/ifaddr/_posix.py +0 -0
  55. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/stolen/ifaddr/_shared.py +0 -0
  56. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/stolen/ifaddr/_win32.py +0 -0
  57. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/stolen/qrcodegen.py +0 -0
  58. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/stolen/surrogateescape.py +0 -0
  59. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/sutil.py +0 -0
  60. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/svchub.py +0 -0
  61. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/szip.py +0 -0
  62. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/tcpsrv.py +0 -0
  63. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/tftpd.py +0 -0
  64. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/th_cli.py +0 -0
  65. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/th_srv.py +0 -0
  66. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/u2idx.py +0 -0
  67. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/util.py +0 -0
  68. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/a/__init__.py +0 -0
  69. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/a/partyfuse.py +0 -0
  70. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/a/u2c.py +0 -0
  71. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/a/webdav-cfg.bat +0 -0
  72. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/baguettebox.js.gz +0 -0
  73. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/browser.css.gz +0 -0
  74. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/browser.html +0 -0
  75. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/browser2.html +0 -0
  76. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/cf.html +0 -0
  77. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/dbg-audio.js.gz +0 -0
  78. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/dd/2.png +0 -0
  79. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/dd/3.png +0 -0
  80. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/dd/4.png +0 -0
  81. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/dd/5.png +0 -0
  82. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/dd/__init__.py +0 -0
  83. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/deps/__init__.py +0 -0
  84. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/deps/busy.mp3.gz +0 -0
  85. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/deps/easymde.css.gz +0 -0
  86. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/deps/easymde.js.gz +0 -0
  87. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/deps/fuse.py +0 -0
  88. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/deps/marked.js.gz +0 -0
  89. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/deps/mini-fa.css.gz +0 -0
  90. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/deps/mini-fa.woff +0 -0
  91. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/deps/prism.css.gz +0 -0
  92. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/deps/prism.js.gz +0 -0
  93. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/deps/prismd.css.gz +0 -0
  94. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/deps/scp.woff2 +0 -0
  95. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/deps/sha512.ac.js.gz +0 -0
  96. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/deps/sha512.hw.js.gz +0 -0
  97. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/md.css.gz +0 -0
  98. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/md.html +0 -0
  99. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/md.js.gz +0 -0
  100. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/md2.css.gz +0 -0
  101. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/mde.css.gz +0 -0
  102. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/mde.html +0 -0
  103. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/mde.js.gz +0 -0
  104. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/msg.css.gz +0 -0
  105. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/msg.html +0 -0
  106. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/rups.css.gz +0 -0
  107. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/rups.html +0 -0
  108. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/rups.js.gz +0 -0
  109. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/shares.css.gz +0 -0
  110. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/shares.html +0 -0
  111. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/shares.js.gz +0 -0
  112. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/splash.css.gz +0 -0
  113. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/splash.html +0 -0
  114. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/splash.js.gz +0 -0
  115. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/svcs.html +0 -0
  116. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/svcs.js.gz +0 -0
  117. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/ui.css.gz +0 -0
  118. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty/web/util.js.gz +0 -0
  119. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty.egg-info/SOURCES.txt +0 -0
  120. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty.egg-info/dependency_links.txt +0 -0
  121. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty.egg-info/entry_points.txt +0 -0
  122. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty.egg-info/requires.txt +0 -0
  123. {copyparty-1.16.14 → copyparty-1.16.16}/copyparty.egg-info/top_level.txt +0 -0
  124. {copyparty-1.16.14 → copyparty-1.16.16}/pyproject.toml +0 -0
  125. {copyparty-1.16.14 → copyparty-1.16.16}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: copyparty
3
- Version: 1.16.14
3
+ Version: 1.16.16
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
@@ -285,6 +285,7 @@ also see [comparison to similar software](./docs/versus.md)
285
285
  * ☑ [upnp / zeroconf / mdns / ssdp](#zeroconf)
286
286
  * ☑ [event hooks](#event-hooks) / script runner
287
287
  * ☑ [reverse-proxy support](https://github.com/9001/copyparty#reverse-proxy)
288
+ * ☑ cross-platform (Windows, Linux, Macos, Android, FreeBSD, arm32/arm64, ppc64le, s390x, risc-v/riscv64)
288
289
  * upload
289
290
  * ☑ basic: plain multipart, ie6 support
290
291
  * ☑ [up2k](#uploading): js, resumable, multithreaded
@@ -2363,6 +2364,7 @@ quick summary of more eccentric web-browsers trying to view a directory index:
2363
2364
  | **ie4** and **netscape** 4.0 | can browse, upload with `?b=u`, auth with `&pw=wark` |
2364
2365
  | **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) |
2365
2366
  | **SerenityOS** (7e98457) | hits a page fault, works with `?b=u`, file upload not-impl |
2367
+ | **sony psp** 5.50 | can browse, upload/mkdir/msg (thx dwarf) [screenshot](https://github.com/user-attachments/assets/9d21f020-1110-4652-abeb-6fc09c533d4f) |
2366
2368
  | **nintendo 3ds** | can browse, upload, view thumbnails (thx bnjmn) |
2367
2369
 
2368
2370
  <p align="center"><img src="https://github.com/user-attachments/assets/88deab3d-6cad-4017-8841-2f041472b853" /></p>
@@ -228,6 +228,7 @@ also see [comparison to similar software](./docs/versus.md)
228
228
  * ☑ [upnp / zeroconf / mdns / ssdp](#zeroconf)
229
229
  * ☑ [event hooks](#event-hooks) / script runner
230
230
  * ☑ [reverse-proxy support](https://github.com/9001/copyparty#reverse-proxy)
231
+ * ☑ cross-platform (Windows, Linux, Macos, Android, FreeBSD, arm32/arm64, ppc64le, s390x, risc-v/riscv64)
231
232
  * upload
232
233
  * ☑ basic: plain multipart, ie6 support
233
234
  * ☑ [up2k](#uploading): js, resumable, multithreaded
@@ -2306,6 +2307,7 @@ quick summary of more eccentric web-browsers trying to view a directory index:
2306
2307
  | **ie4** and **netscape** 4.0 | can browse, upload with `?b=u`, auth with `&pw=wark` |
2307
2308
  | **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) |
2308
2309
  | **SerenityOS** (7e98457) | hits a page fault, works with `?b=u`, file upload not-impl |
2310
+ | **sony psp** 5.50 | can browse, upload/mkdir/msg (thx dwarf) [screenshot](https://github.com/user-attachments/assets/9d21f020-1110-4652-abeb-6fc09c533d4f) |
2309
2311
  | **nintendo 3ds** | can browse, upload, view thumbnails (thx bnjmn) |
2310
2312
 
2311
2313
  <p align="center"><img src="https://github.com/user-attachments/assets/88deab3d-6cad-4017-8841-2f041472b853" /></p>
@@ -1,8 +1,8 @@
1
1
  # coding: utf-8
2
2
 
3
- VERSION = (1, 16, 14)
3
+ VERSION = (1, 16, 16)
4
4
  CODENAME = "COPYparty"
5
- BUILD_DT = (2025, 2, 19)
5
+ BUILD_DT = (2025, 2, 28)
6
6
 
7
7
  S_VERSION = ".".join(map(str, VERSION))
8
8
  S_BUILD_DT = "{0:04d}-{1:02d}-{2:02d}".format(*BUILD_DT)
@@ -1577,12 +1577,8 @@ class AuthSrv(object):
1577
1577
  for vol in vfs.all_vols.values():
1578
1578
  unknown_flags = set()
1579
1579
  for k, v in vol.flags.items():
1580
- stripped = k.lstrip("-")
1581
- if k != stripped and stripped not in vol.flags:
1582
- t = "WARNING: the config for volume [/%s] tried to remove volflag [%s] by specifying [%s] but that volflag was not already set"
1583
- self.log(t % (vol.vpath, stripped, k), 3)
1584
- k = stripped
1585
- if k not in flagdescs and k not in k_ign:
1580
+ ks = k.lstrip("-")
1581
+ if ks not in flagdescs and ks not in k_ign:
1586
1582
  unknown_flags.add(k)
1587
1583
  if unknown_flags:
1588
1584
  t = "WARNING: the config for volume [/%s] has unrecognized volflags; will ignore: '%s'"
@@ -2174,8 +2170,13 @@ class AuthSrv(object):
2174
2170
  for vol in vfs.all_nodes.values():
2175
2171
  for k in list(vol.flags.keys()):
2176
2172
  if re.match("^-[^-]+$", k):
2177
- vol.flags.pop(k[1:], None)
2178
2173
  vol.flags.pop(k)
2174
+ zs = k[1:]
2175
+ if zs in vol.flags:
2176
+ vol.flags.pop(k[1:])
2177
+ else:
2178
+ t = "WARNING: the config for volume [/%s] tried to remove volflag [%s] by specifying [%s] but that volflag was not already set"
2179
+ self.log(t % (vol.vpath, zs, k), 3)
2179
2180
 
2180
2181
  if vol.flags.get("dots"):
2181
2182
  for name in vol.axs.uread:
@@ -293,6 +293,9 @@ flagcats = {
293
293
  "dots": "allow all users with read-access to\nenable the option to show dotfiles in listings",
294
294
  "fk=8": 'generates per-file accesskeys,\nwhich are then required at the "g" permission;\nkeys are invalidated if filesize or inode changes',
295
295
  "fka=8": 'generates slightly weaker per-file accesskeys,\nwhich are then required at the "g" permission;\nnot affected by filesize or inode numbers',
296
+ "dk=8": 'generates per-directory accesskeys,\nwhich are then required at the "g" permission;\nkeys are invalidated if filesize or inode changes',
297
+ "dks": "per-directory accesskeys allow browsing into subdirs",
298
+ "dky": 'allow seeing files (not folders) inside a specific folder\nwith "g" perm, and does not require a valid dirkey to do so',
296
299
  "rss": "allow '?rss' URL suffix (experimental)",
297
300
  "ups_who=2": "restrict viewing the list of recent uploads",
298
301
  "zip_who=2": "restrict access to download-as-zip/tar",
@@ -148,6 +148,8 @@ RE_HSAFE = re.compile(r"[\x00-\x1f<>\"'&]") # search always much faster
148
148
  RE_HOST = re.compile(r"[^][0-9a-zA-Z.:_-]") # search faster <=17ch
149
149
  RE_MHOST = re.compile(r"^[][0-9a-zA-Z.:_-]+$") # match faster >=18ch
150
150
  RE_K = re.compile(r"[^0-9a-zA-Z_-]") # search faster <=17ch
151
+ RE_HR = re.compile(r"[<>\"'&]")
152
+ RE_MDV = re.compile(r"(.*)\.([0-9]+\.[0-9]{3})(\.[Mm][Dd])$")
151
153
 
152
154
  UPARAM_CC_OK = set("doc move tree".split())
153
155
 
@@ -5947,7 +5949,7 @@ class HttpCli(object):
5947
5949
  # [num-backups, most-recent, hist-path]
5948
5950
  hist = {}
5949
5951
  histdir = os.path.join(fsroot, ".hist")
5950
- ptn = re.compile(r"(.*)\.([0-9]+\.[0-9]{3})(\.[^\.]+)$")
5952
+ ptn = RE_MDV
5951
5953
  try:
5952
5954
  for hfn in bos.listdir(histdir):
5953
5955
  m = ptn.match(hfn)
@@ -5980,6 +5982,7 @@ class HttpCli(object):
5980
5982
 
5981
5983
  dirs = []
5982
5984
  files = []
5985
+ ptn_hr = RE_HR
5983
5986
  for fn in ls_names:
5984
5987
  base = ""
5985
5988
  href = fn
@@ -6034,11 +6037,13 @@ class HttpCli(object):
6034
6037
  zd.second,
6035
6038
  )
6036
6039
 
6037
- try:
6038
- ext = "---" if is_dir else fn.rsplit(".", 1)[1]
6040
+ if is_dir:
6041
+ ext = "---"
6042
+ elif "." in fn:
6043
+ ext = ptn_hr.sub("@", fn.rsplit(".", 1)[1])
6039
6044
  if len(ext) > 16:
6040
6045
  ext = ext[:16]
6041
- except:
6046
+ else:
6042
6047
  ext = "%"
6043
6048
 
6044
6049
  if add_fk and not is_dir:
@@ -2939,9 +2939,14 @@ class Up2k(object):
2939
2939
  self.salt, cj["size"], cj["lmod"], cj["prel"], cj["name"]
2940
2940
  )
2941
2941
 
2942
- if vfs.flags.get("up_ts", "") == "fu" or not cj["lmod"]:
2942
+ zi = cj["lmod"]
2943
+ bad_mt = zi <= 0 or zi > 0xAAAAAAAA
2944
+ if bad_mt or vfs.flags.get("up_ts", "") == "fu":
2943
2945
  # force upload time rather than last-modified
2944
2946
  cj["lmod"] = int(time.time())
2947
+ if zi and bad_mt:
2948
+ t = "ignoring impossible last-modified time from client: %s"
2949
+ self.log(t % (zi,), 6)
2945
2950
 
2946
2951
  alts = []
2947
2952
  for ptop, cur in vols:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: copyparty
3
- Version: 1.16.14
3
+ Version: 1.16.16
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
@@ -285,6 +285,7 @@ also see [comparison to similar software](./docs/versus.md)
285
285
  * ☑ [upnp / zeroconf / mdns / ssdp](#zeroconf)
286
286
  * ☑ [event hooks](#event-hooks) / script runner
287
287
  * ☑ [reverse-proxy support](https://github.com/9001/copyparty#reverse-proxy)
288
+ * ☑ cross-platform (Windows, Linux, Macos, Android, FreeBSD, arm32/arm64, ppc64le, s390x, risc-v/riscv64)
288
289
  * upload
289
290
  * ☑ basic: plain multipart, ie6 support
290
291
  * ☑ [up2k](#uploading): js, resumable, multithreaded
@@ -2363,6 +2364,7 @@ quick summary of more eccentric web-browsers trying to view a directory index:
2363
2364
  | **ie4** and **netscape** 4.0 | can browse, upload with `?b=u`, auth with `&pw=wark` |
2364
2365
  | **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) |
2365
2366
  | **SerenityOS** (7e98457) | hits a page fault, works with `?b=u`, file upload not-impl |
2367
+ | **sony psp** 5.50 | can browse, upload/mkdir/msg (thx dwarf) [screenshot](https://github.com/user-attachments/assets/9d21f020-1110-4652-abeb-6fc09c533d4f) |
2366
2368
  | **nintendo 3ds** | can browse, upload, view thumbnails (thx bnjmn) |
2367
2369
 
2368
2370
  <p align="center"><img src="https://github.com/user-attachments/assets/88deab3d-6cad-4017-8841-2f041472b853" /></p>
Binary file
Binary file
File without changes
File without changes
File without changes