copyparty 1.16.16__tar.gz → 1.16.18__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 (124) hide show
  1. {copyparty-1.16.16 → copyparty-1.16.18}/PKG-INFO +14 -3
  2. {copyparty-1.16.16 → copyparty-1.16.18}/README.md +11 -1
  3. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/__main__.py +21 -40
  4. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/__version__.py +2 -2
  5. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/authsrv.py +137 -56
  6. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/cfg.py +10 -0
  7. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/fsutil.py +7 -5
  8. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/ftpd.py +11 -0
  9. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/httpcli.py +87 -33
  10. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/mtag.py +1 -2
  11. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/svchub.py +5 -4
  12. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/szip.py +1 -2
  13. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/tcpsrv.py +18 -0
  14. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/tftpd.py +29 -8
  15. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/up2k.py +13 -8
  16. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/util.py +62 -3
  17. copyparty-1.16.18/copyparty/web/browser.js.gz +0 -0
  18. copyparty-1.16.18/copyparty/web/up2k.js.gz +0 -0
  19. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/util.js.gz +0 -0
  20. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty.egg-info/PKG-INFO +14 -3
  21. copyparty-1.16.16/copyparty/web/browser.js.gz +0 -0
  22. copyparty-1.16.16/copyparty/web/up2k.js.gz +0 -0
  23. {copyparty-1.16.16 → copyparty-1.16.18}/LICENSE +0 -0
  24. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/__init__.py +0 -0
  25. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/bos/__init__.py +0 -0
  26. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/bos/bos.py +0 -0
  27. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/bos/path.py +0 -0
  28. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/broker_mp.py +0 -0
  29. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/broker_mpw.py +0 -0
  30. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/broker_thr.py +0 -0
  31. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/broker_util.py +0 -0
  32. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/cert.py +0 -0
  33. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/dxml.py +0 -0
  34. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/httpconn.py +0 -0
  35. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/httpsrv.py +0 -0
  36. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/ico.py +0 -0
  37. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/mdns.py +0 -0
  38. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/metrics.py +0 -0
  39. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/multicast.py +0 -0
  40. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/pwhash.py +0 -0
  41. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/res/COPYING.txt +0 -0
  42. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/res/__init__.py +0 -0
  43. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/res/insecure.pem +0 -0
  44. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/smbd.py +0 -0
  45. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/ssdp.py +0 -0
  46. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/star.py +0 -0
  47. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/stolen/__init__.py +0 -0
  48. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/stolen/dnslib/__init__.py +0 -0
  49. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/stolen/dnslib/bimap.py +0 -0
  50. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/stolen/dnslib/bit.py +0 -0
  51. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/stolen/dnslib/buffer.py +0 -0
  52. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/stolen/dnslib/dns.py +0 -0
  53. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/stolen/dnslib/label.py +0 -0
  54. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/stolen/dnslib/lex.py +0 -0
  55. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/stolen/dnslib/ranges.py +0 -0
  56. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/stolen/ifaddr/__init__.py +0 -0
  57. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/stolen/ifaddr/_posix.py +0 -0
  58. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/stolen/ifaddr/_shared.py +0 -0
  59. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/stolen/ifaddr/_win32.py +0 -0
  60. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/stolen/qrcodegen.py +0 -0
  61. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/stolen/surrogateescape.py +0 -0
  62. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/sutil.py +0 -0
  63. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/th_cli.py +0 -0
  64. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/th_srv.py +0 -0
  65. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/u2idx.py +0 -0
  66. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/a/__init__.py +0 -0
  67. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/a/partyfuse.py +0 -0
  68. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/a/u2c.py +0 -0
  69. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/a/webdav-cfg.bat +0 -0
  70. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/baguettebox.js.gz +0 -0
  71. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/browser.css.gz +0 -0
  72. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/browser.html +0 -0
  73. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/browser2.html +0 -0
  74. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/cf.html +0 -0
  75. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/dbg-audio.js.gz +0 -0
  76. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/dd/2.png +0 -0
  77. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/dd/3.png +0 -0
  78. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/dd/4.png +0 -0
  79. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/dd/5.png +0 -0
  80. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/dd/__init__.py +0 -0
  81. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/deps/__init__.py +0 -0
  82. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/deps/busy.mp3.gz +0 -0
  83. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/deps/easymde.css.gz +0 -0
  84. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/deps/easymde.js.gz +0 -0
  85. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/deps/fuse.py +0 -0
  86. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/deps/marked.js.gz +0 -0
  87. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/deps/mini-fa.css.gz +0 -0
  88. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/deps/mini-fa.woff +0 -0
  89. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/deps/prism.css.gz +0 -0
  90. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/deps/prism.js.gz +0 -0
  91. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/deps/prismd.css.gz +0 -0
  92. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/deps/scp.woff2 +0 -0
  93. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/deps/sha512.ac.js.gz +0 -0
  94. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/deps/sha512.hw.js.gz +0 -0
  95. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/md.css.gz +0 -0
  96. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/md.html +0 -0
  97. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/md.js.gz +0 -0
  98. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/md2.css.gz +0 -0
  99. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/md2.js.gz +0 -0
  100. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/mde.css.gz +0 -0
  101. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/mde.html +0 -0
  102. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/mde.js.gz +0 -0
  103. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/msg.css.gz +0 -0
  104. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/msg.html +0 -0
  105. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/rups.css.gz +0 -0
  106. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/rups.html +0 -0
  107. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/rups.js.gz +0 -0
  108. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/shares.css.gz +0 -0
  109. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/shares.html +0 -0
  110. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/shares.js.gz +0 -0
  111. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/splash.css.gz +0 -0
  112. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/splash.html +0 -0
  113. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/splash.js.gz +0 -0
  114. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/svcs.html +0 -0
  115. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/svcs.js.gz +0 -0
  116. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/ui.css.gz +0 -0
  117. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty/web/w.hash.js.gz +0 -0
  118. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty.egg-info/SOURCES.txt +0 -0
  119. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty.egg-info/dependency_links.txt +0 -0
  120. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty.egg-info/entry_points.txt +0 -0
  121. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty.egg-info/requires.txt +0 -0
  122. {copyparty-1.16.16 → copyparty-1.16.18}/copyparty.egg-info/top_level.txt +0 -0
  123. {copyparty-1.16.16 → copyparty-1.16.18}/pyproject.toml +0 -0
  124. {copyparty-1.16.16 → copyparty-1.16.18}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: copyparty
3
- Version: 1.16.16
3
+ Version: 1.16.18
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
@@ -54,6 +54,7 @@ Provides-Extra: pwhash
54
54
  Requires-Dist: argon2-cffi; extra == "pwhash"
55
55
  Provides-Extra: zeromq
56
56
  Requires-Dist: pyzmq; extra == "zeromq"
57
+ Dynamic: license-file
57
58
 
58
59
  <img src="https://github.com/9001/copyparty/raw/hovudstraum/docs/logo.svg" width="250" align="right"/>
59
60
 
@@ -157,6 +158,7 @@ turn almost any device into a file server with resumable uploads/downloads using
157
158
  * [custom mimetypes](#custom-mimetypes) - change the association of a file extension
158
159
  * [GDPR compliance](#GDPR-compliance) - imagine using copyparty professionally...
159
160
  * [feature chickenbits](#feature-chickenbits) - buggy feature? rip it out
161
+ * [feature beefybits](#feature-beefybits) - force-enable features with known issues on your OS/env
160
162
  * [packages](#packages) - the party might be closer than you think
161
163
  * [arch package](#arch-package) - now [available on aur](https://aur.archlinux.org/packages/copyparty) maintained by [@icxes](https://github.com/icxes)
162
164
  * [fedora package](#fedora-package) - does not exist yet
@@ -1893,7 +1895,7 @@ tell search engines you don't wanna be indexed, either using the good old [robo
1893
1895
  * volflag `[...]:c,norobots` does the same thing for that single volume
1894
1896
  * volflag `[...]:c,robots` ALLOWS search-engine crawling for that volume, even if `--no-robots` is set globally
1895
1897
 
1896
- also, `--force-js` disables the plain HTML folder listing, making things harder to parse for search engines
1898
+ also, `--force-js` disables the plain HTML folder listing, making things harder to parse for *some* search engines -- note that crawlers which understand javascript (such as google) will not be affected
1897
1899
 
1898
1900
 
1899
1901
  ## themes
@@ -2194,6 +2196,15 @@ buggy feature? rip it out by setting any of the following environment variables
2194
2196
  example: `PRTY_NO_IFADDR=1 python3 copyparty-sfx.py`
2195
2197
 
2196
2198
 
2199
+ ### feature beefybits
2200
+
2201
+ force-enable features with known issues on your OS/env by setting any of the following environment variables, also affectionately known as `fuckitbits` or `hail-mary-bits`
2202
+
2203
+ | env-var | what it does |
2204
+ | ------------------------ | ------------ |
2205
+ | `PRTY_FORCE_MP` | force-enable multiprocessing (real multithreading) on MacOS and other broken platforms |
2206
+
2207
+
2197
2208
  # packages
2198
2209
 
2199
2210
  the party might be closer than you think
@@ -100,6 +100,7 @@ turn almost any device into a file server with resumable uploads/downloads using
100
100
  * [custom mimetypes](#custom-mimetypes) - change the association of a file extension
101
101
  * [GDPR compliance](#GDPR-compliance) - imagine using copyparty professionally...
102
102
  * [feature chickenbits](#feature-chickenbits) - buggy feature? rip it out
103
+ * [feature beefybits](#feature-beefybits) - force-enable features with known issues on your OS/env
103
104
  * [packages](#packages) - the party might be closer than you think
104
105
  * [arch package](#arch-package) - now [available on aur](https://aur.archlinux.org/packages/copyparty) maintained by [@icxes](https://github.com/icxes)
105
106
  * [fedora package](#fedora-package) - does not exist yet
@@ -1836,7 +1837,7 @@ tell search engines you don't wanna be indexed, either using the good old [robo
1836
1837
  * volflag `[...]:c,norobots` does the same thing for that single volume
1837
1838
  * volflag `[...]:c,robots` ALLOWS search-engine crawling for that volume, even if `--no-robots` is set globally
1838
1839
 
1839
- also, `--force-js` disables the plain HTML folder listing, making things harder to parse for search engines
1840
+ also, `--force-js` disables the plain HTML folder listing, making things harder to parse for *some* search engines -- note that crawlers which understand javascript (such as google) will not be affected
1840
1841
 
1841
1842
 
1842
1843
  ## themes
@@ -2137,6 +2138,15 @@ buggy feature? rip it out by setting any of the following environment variables
2137
2138
  example: `PRTY_NO_IFADDR=1 python3 copyparty-sfx.py`
2138
2139
 
2139
2140
 
2141
+ ### feature beefybits
2142
+
2143
+ force-enable features with known issues on your OS/env by setting any of the following environment variables, also affectionately known as `fuckitbits` or `hail-mary-bits`
2144
+
2145
+ | env-var | what it does |
2146
+ | ------------------------ | ------------ |
2147
+ | `PRTY_FORCE_MP` | force-enable multiprocessing (real multithreading) on MacOS and other broken platforms |
2148
+
2149
+
2140
2150
  # packages
2141
2151
 
2142
2152
  the party might be closer than you think
@@ -40,6 +40,7 @@ from .cfg import flagcats, onedash
40
40
  from .svchub import SvcHub
41
41
  from .util import (
42
42
  APPLESAN_TXT,
43
+ BAD_BOTS,
43
44
  DEF_EXP,
44
45
  DEF_MTE,
45
46
  DEF_MTH,
@@ -65,6 +66,7 @@ from .util import (
65
66
  load_resource,
66
67
  min_ex,
67
68
  pybin,
69
+ read_utf8,
68
70
  termsize,
69
71
  wrap,
70
72
  )
@@ -249,8 +251,7 @@ def get_srvname(verbose) :
249
251
  if verbose:
250
252
  lprint("using hostname from {}\n".format(fp))
251
253
  try:
252
- with open(fp, "rb") as f:
253
- ret = f.read().decode("utf-8", "replace").strip()
254
+ return read_utf8(None, fp, True).strip()
254
255
  except:
255
256
  ret = ""
256
257
  namelen = 5
@@ -259,47 +260,18 @@ def get_srvname(verbose) :
259
260
  ret = re.sub("[234567=]", "", ret)[:namelen]
260
261
  with open(fp, "wb") as f:
261
262
  f.write(ret.encode("utf-8") + b"\n")
262
-
263
- return ret
264
-
265
-
266
- def get_fk_salt() :
267
- fp = os.path.join(E.cfg, "fk-salt.txt")
268
- try:
269
- with open(fp, "rb") as f:
270
- ret = f.read().strip()
271
- except:
272
- ret = b64enc(os.urandom(18))
273
- with open(fp, "wb") as f:
274
- f.write(ret + b"\n")
275
-
276
- return ret.decode("utf-8")
277
-
278
-
279
- def get_dk_salt() :
280
- fp = os.path.join(E.cfg, "dk-salt.txt")
281
- try:
282
- with open(fp, "rb") as f:
283
- ret = f.read().strip()
284
- except:
285
- ret = b64enc(os.urandom(30))
286
- with open(fp, "wb") as f:
287
- f.write(ret + b"\n")
288
-
289
- return ret.decode("utf-8")
263
+ return ret
290
264
 
291
265
 
292
- def get_ah_salt() :
293
- fp = os.path.join(E.cfg, "ah-salt.txt")
266
+ def get_salt(name , nbytes ) :
267
+ fp = os.path.join(E.cfg, "%s-salt.txt" % (name,))
294
268
  try:
295
- with open(fp, "rb") as f:
296
- ret = f.read().strip()
269
+ return read_utf8(None, fp, True).strip()
297
270
  except:
298
- ret = b64enc(os.urandom(18))
271
+ ret = b64enc(os.urandom(nbytes))
299
272
  with open(fp, "wb") as f:
300
273
  f.write(ret + b"\n")
301
-
302
- return ret.decode("utf-8")
274
+ return ret.decode("utf-8")
303
275
 
304
276
 
305
277
  def ensure_locale() :
@@ -1050,6 +1022,8 @@ def add_network(ap):
1050
1022
  ap2.add_argument("--reuseaddr", action="store_true", help="set reuseaddr on listening sockets on windows; allows rapid restart of copyparty at the expense of being able to accidentally start multiple instances")
1051
1023
  else:
1052
1024
  ap2.add_argument("--freebind", action="store_true", help="allow listening on IPs which do not yet exist, for example if the network interfaces haven't finished going up. Only makes sense for IPs other than '0.0.0.0', '127.0.0.1', '::', and '::1'. May require running as root (unless net.ipv6.ip_nonlocal_bind)")
1025
+ ap2.add_argument("--wr-h-eps", metavar="PATH", type=u, default="", help="write list of listening-on ip:port to textfile at \033[33mPATH\033[0m when http-servers have started")
1026
+ ap2.add_argument("--wr-h-aon", metavar="PATH", type=u, default="", help="write list of accessible-on ip:port to textfile at \033[33mPATH\033[0m when http-servers have started")
1053
1027
  ap2.add_argument("--s-thead", metavar="SEC", type=int, default=120, help="socket timeout (read request header)")
1054
1028
  ap2.add_argument("--s-tbody", metavar="SEC", type=float, default=128.0, help="socket timeout (read/write request/response bodies). Use 60 on fast servers (default is extremely safe). Disable with 0 if reverse-proxied for a 2%% speed boost")
1055
1029
  ap2.add_argument("--s-rd-sz", metavar="B", type=int, default=256*1024, help="socket read size in bytes (indirectly affects filesystem writes; recommendation: keep equal-to or lower-than \033[33m--iobuf\033[0m)")
@@ -1243,6 +1217,7 @@ def add_yolo(ap):
1243
1217
  ap2 = ap.add_argument_group('yolo options')
1244
1218
  ap2.add_argument("--allow-csrf", action="store_true", help="disable csrf protections; let other domains/sites impersonate you through cross-site requests")
1245
1219
  ap2.add_argument("--getmod", action="store_true", help="permit ?move=[...] and ?delete as GET")
1220
+ ap2.add_argument("--wo-up-readme", action="store_true", help="allow users with write-only access to upload logues and readmes without adding the _wo_ filename prefix (volflag=wo_up_readme)")
1246
1221
 
1247
1222
 
1248
1223
  def add_optouts(ap):
@@ -1257,7 +1232,12 @@ def add_optouts(ap):
1257
1232
  ap2.add_argument("-nih", action="store_true", help="no info hostname -- don't show in UI")
1258
1233
  ap2.add_argument("-nid", action="store_true", help="no info disk-usage -- don't show in UI")
1259
1234
  ap2.add_argument("-nb", action="store_true", help="no powered-by-copyparty branding in UI")
1235
+ ap2.add_argument("--zipmaxn", metavar="N", type=u, default="0", help="reject download-as-zip if more than \033[33mN\033[0m files in total; optionally takes a unit suffix: [\033[32m256\033[0m], [\033[32m9K\033[0m], [\033[32m4G\033[0m] (volflag=zipmaxn)")
1236
+ ap2.add_argument("--zipmaxs", metavar="SZ", type=u, default="0", help="reject download-as-zip if total download size exceeds \033[33mSZ\033[0m bytes; optionally takes a unit suffix: [\033[32m256M\033[0m], [\033[32m4G\033[0m], [\033[32m2T\033[0m] (volflag=zipmaxs)")
1237
+ ap2.add_argument("--zipmaxt", metavar="TXT", type=u, default="", help="custom errormessage when download size exceeds max (volflag=zipmaxt)")
1238
+ ap2.add_argument("--zipmaxu", action="store_true", help="authenticated users bypass the zip size limit (volflag=zipmaxu)")
1260
1239
  ap2.add_argument("--zip-who", metavar="LVL", type=int, default=3, help="who can download as zip/tar? [\033[32m0\033[0m]=nobody, [\033[32m1\033[0m]=admins, [\033[32m2\033[0m]=authenticated-with-read-access, [\033[32m3\033[0m]=everyone-with-read-access (volflag=zip_who)\n\033[1;31mWARNING:\033[0m if a nested volume has a more restrictive value than a parent volume, then this will be \033[33mignored\033[0m if the download is initiated from the parent, more lenient volume")
1240
+ ap2.add_argument("--ua-nozip", metavar="PTN", type=u, default=BAD_BOTS, help="regex of user-agents to reject from download-as-zip/tar; disable with [\033[32mno\033[0m] or blank")
1261
1241
  ap2.add_argument("--no-zip", action="store_true", help="disable download as zip/tar; same as \033[33m--zip-who=0\033[0m")
1262
1242
  ap2.add_argument("--no-tarcmp", action="store_true", help="disable download as compressed tar (?tar=gz, ?tar=bz2, ?tar=xz, ?tar=gz:9, ...)")
1263
1243
  ap2.add_argument("--no-lifetime", action="store_true", help="do not allow clients (or server config) to schedule an upload to be deleted after a given time")
@@ -1448,6 +1428,7 @@ def add_txt(ap):
1448
1428
  ap2.add_argument("--exp", action="store_true", help="enable textfile expansion -- replace {{self.ip}} and such; see \033[33m--help-exp\033[0m (volflag=exp)")
1449
1429
  ap2.add_argument("--exp-md", metavar="V,V,V", type=u, default=DEF_EXP, help="comma/space-separated list of placeholders to expand in markdown files; add/remove stuff on the default list with +hdr_foo or /vf.scan (volflag=exp_md)")
1450
1430
  ap2.add_argument("--exp-lg", metavar="V,V,V", type=u, default=DEF_EXP, help="comma/space-separated list of placeholders to expand in prologue/epilogue files (volflag=exp_lg)")
1431
+ ap2.add_argument("--ua-nodoc", metavar="PTN", type=u, default=BAD_BOTS, help="regex of user-agents to reject from viewing documents through ?doc=[...]; disable with [\033[32mno\033[0m] or blank")
1451
1432
 
1452
1433
 
1453
1434
  def add_og(ap):
@@ -1544,9 +1525,9 @@ def run_argparse(
1544
1525
 
1545
1526
  cert_path = os.path.join(E.cfg, "cert.pem")
1546
1527
 
1547
- fk_salt = get_fk_salt()
1548
- dk_salt = get_dk_salt()
1549
- ah_salt = get_ah_salt()
1528
+ fk_salt = get_salt("fk", 18)
1529
+ dk_salt = get_salt("dk", 30)
1530
+ ah_salt = get_salt("ah", 18)
1550
1531
 
1551
1532
  # alpine peaks at 5 threads for some reason,
1552
1533
  # all others scale past that (but try to avoid SMT),
@@ -1,8 +1,8 @@
1
1
  # coding: utf-8
2
2
 
3
- VERSION = (1, 16, 16)
3
+ VERSION = (1, 16, 18)
4
4
  CODENAME = "COPYparty"
5
- BUILD_DT = (2025, 2, 28)
5
+ BUILD_DT = (2025, 3, 23)
6
6
 
7
7
  S_VERSION = ".".join(map(str, VERSION))
8
8
  S_BUILD_DT = "{0:04d}-{1:02d}-{2:02d}".format(*BUILD_DT)