copyparty 1.15.3__tar.gz → 1.15.4__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 (127) hide show
  1. {copyparty-1.15.3 → copyparty-1.15.4}/PKG-INFO +9 -8
  2. {copyparty-1.15.3 → copyparty-1.15.4}/README.md +8 -7
  3. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/__init__.py +55 -0
  4. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/__main__.py +15 -12
  5. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/__version__.py +2 -2
  6. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/cert.py +20 -8
  7. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/cfg.py +1 -1
  8. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/ftpd.py +1 -1
  9. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/httpcli.py +226 -67
  10. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/httpconn.py +0 -3
  11. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/httpsrv.py +10 -15
  12. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/metrics.py +1 -1
  13. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/smbd.py +6 -3
  14. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/stolen/qrcodegen.py +17 -0
  15. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/szip.py +1 -1
  16. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/u2idx.py +1 -0
  17. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/up2k.py +30 -12
  18. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/util.py +145 -64
  19. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/a/partyfuse.py +233 -357
  20. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/a/u2c.py +249 -153
  21. copyparty-1.15.4/copyparty/web/browser.css.gz +0 -0
  22. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/browser.html +3 -6
  23. copyparty-1.15.4/copyparty/web/browser.js.gz +0 -0
  24. copyparty-1.15.4/copyparty/web/deps/fuse.py +1064 -0
  25. copyparty-1.15.4/copyparty/web/deps/marked.js.gz +0 -0
  26. copyparty-1.15.4/copyparty/web/shares.css.gz +0 -0
  27. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/shares.html +7 -4
  28. copyparty-1.15.4/copyparty/web/shares.js.gz +0 -0
  29. copyparty-1.15.4/copyparty/web/splash.js.gz +0 -0
  30. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/svcs.html +1 -1
  31. copyparty-1.15.4/copyparty/web/ui.css.gz +0 -0
  32. copyparty-1.15.4/copyparty/web/util.js.gz +0 -0
  33. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty.egg-info/PKG-INFO +9 -8
  34. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty.egg-info/SOURCES.txt +1 -0
  35. copyparty-1.15.3/copyparty/web/browser.css.gz +0 -0
  36. copyparty-1.15.3/copyparty/web/browser.js.gz +0 -0
  37. copyparty-1.15.3/copyparty/web/deps/marked.js.gz +0 -0
  38. copyparty-1.15.3/copyparty/web/shares.css.gz +0 -0
  39. copyparty-1.15.3/copyparty/web/shares.js.gz +0 -0
  40. copyparty-1.15.3/copyparty/web/splash.js.gz +0 -0
  41. copyparty-1.15.3/copyparty/web/ui.css.gz +0 -0
  42. copyparty-1.15.3/copyparty/web/util.js.gz +0 -0
  43. {copyparty-1.15.3 → copyparty-1.15.4}/LICENSE +0 -0
  44. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/authsrv.py +0 -0
  45. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/bos/__init__.py +0 -0
  46. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/bos/bos.py +0 -0
  47. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/bos/path.py +0 -0
  48. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/broker_mp.py +0 -0
  49. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/broker_mpw.py +0 -0
  50. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/broker_thr.py +0 -0
  51. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/broker_util.py +0 -0
  52. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/dxml.py +0 -0
  53. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/fsutil.py +0 -0
  54. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/ico.py +0 -0
  55. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/mdns.py +0 -0
  56. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/mtag.py +0 -0
  57. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/multicast.py +0 -0
  58. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/pwhash.py +0 -0
  59. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/res/COPYING.txt +0 -0
  60. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/res/__init__.py +0 -0
  61. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/res/insecure.pem +0 -0
  62. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/ssdp.py +0 -0
  63. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/star.py +0 -0
  64. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/stolen/__init__.py +0 -0
  65. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/stolen/dnslib/__init__.py +0 -0
  66. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/stolen/dnslib/bimap.py +0 -0
  67. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/stolen/dnslib/bit.py +0 -0
  68. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/stolen/dnslib/buffer.py +0 -0
  69. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/stolen/dnslib/dns.py +0 -0
  70. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/stolen/dnslib/label.py +0 -0
  71. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/stolen/dnslib/lex.py +0 -0
  72. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/stolen/dnslib/ranges.py +0 -0
  73. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/stolen/ifaddr/__init__.py +0 -0
  74. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/stolen/ifaddr/_posix.py +0 -0
  75. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/stolen/ifaddr/_shared.py +0 -0
  76. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/stolen/ifaddr/_win32.py +0 -0
  77. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/stolen/surrogateescape.py +0 -0
  78. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/sutil.py +0 -0
  79. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/svchub.py +0 -0
  80. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/tcpsrv.py +0 -0
  81. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/tftpd.py +0 -0
  82. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/th_cli.py +0 -0
  83. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/th_srv.py +0 -0
  84. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/a/__init__.py +0 -0
  85. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/a/webdav-cfg.bat +0 -0
  86. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/baguettebox.js.gz +0 -0
  87. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/browser2.html +0 -0
  88. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/cf.html +0 -0
  89. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/dbg-audio.js.gz +0 -0
  90. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/dd/2.png +0 -0
  91. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/dd/3.png +0 -0
  92. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/dd/4.png +0 -0
  93. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/dd/5.png +0 -0
  94. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/dd/__init__.py +0 -0
  95. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/deps/__init__.py +0 -0
  96. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/deps/busy.mp3.gz +0 -0
  97. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/deps/easymde.css.gz +0 -0
  98. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/deps/easymde.js.gz +0 -0
  99. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/deps/mini-fa.css.gz +0 -0
  100. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/deps/mini-fa.woff +0 -0
  101. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/deps/prism.css.gz +0 -0
  102. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/deps/prism.js.gz +0 -0
  103. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/deps/prismd.css.gz +0 -0
  104. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/deps/scp.woff2 +0 -0
  105. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/deps/sha512.ac.js.gz +0 -0
  106. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/deps/sha512.hw.js.gz +0 -0
  107. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/md.css.gz +0 -0
  108. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/md.html +0 -0
  109. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/md.js.gz +0 -0
  110. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/md2.css.gz +0 -0
  111. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/md2.js.gz +0 -0
  112. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/mde.css.gz +0 -0
  113. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/mde.html +0 -0
  114. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/mde.js.gz +0 -0
  115. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/msg.css.gz +0 -0
  116. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/msg.html +0 -0
  117. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/splash.css.gz +0 -0
  118. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/splash.html +12 -12
  119. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/svcs.js.gz +0 -0
  120. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/up2k.js.gz +0 -0
  121. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty/web/w.hash.js.gz +0 -0
  122. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty.egg-info/dependency_links.txt +0 -0
  123. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty.egg-info/entry_points.txt +0 -0
  124. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty.egg-info/requires.txt +0 -0
  125. {copyparty-1.15.3 → copyparty-1.15.4}/copyparty.egg-info/top_level.txt +0 -0
  126. {copyparty-1.15.3 → copyparty-1.15.4}/pyproject.toml +0 -0
  127. {copyparty-1.15.3 → copyparty-1.15.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: copyparty
3
- Version: 1.15.3
3
+ Version: 1.15.4
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
@@ -1169,12 +1169,12 @@ some **BIG WARNINGS** specific to SMB/CIFS, in decreasing importance:
1169
1169
  * [shadowing](#shadowing) probably works as expected but no guarantees
1170
1170
 
1171
1171
  and some minor issues,
1172
- * clients only see the first ~400 files in big folders; [impacket#1433](https://github.com/SecureAuthCorp/impacket/issues/1433)
1172
+ * clients only see the first ~400 files in big folders;
1173
+ * this was originally due to [impacket#1433](https://github.com/SecureAuthCorp/impacket/issues/1433) which was fixed in impacket-0.12, so you can disable the workaround with `--smb-nwa-1` but then you get unacceptably poor performance instead
1173
1174
  * hot-reload of server config (`/?reload=cfg`) does not include the `[global]` section (commandline args)
1174
1175
  * listens on the first IPv4 `-i` interface only (default = :: = 0.0.0.0 = all)
1175
1176
  * login doesn't work on winxp, but anonymous access is ok -- remove all accounts from copyparty config for that to work
1176
1177
  * win10 onwards does not allow connecting anonymously / without accounts
1177
- * on windows, creating a new file through rightclick --> new --> textfile throws an error due to impacket limitations -- hit OK and F5 to get your file
1178
1178
  * python3 only
1179
1179
  * slow (the builtin webdav support in windows is 5x faster, and rclone-webdav is 30x faster)
1180
1180
 
@@ -1213,8 +1213,6 @@ note that this disables hotlinking because the opengraph spec demands it; to sne
1213
1213
 
1214
1214
  you can also hotlink files regardless by appending `?raw` to the url
1215
1215
 
1216
- NOTE: because discord (and maybe others) strip query args such as `?raw` in opengraph tags, any links which require a filekey or dirkey will not work
1217
-
1218
1216
  if you want to entirely replace the copyparty response with your own jinja2 template, give the template filepath to `--og-tpl` or volflag `og_tpl` (all members of `HttpCli` are available through the `this` object)
1219
1217
 
1220
1218
 
@@ -1939,6 +1937,7 @@ interact with copyparty using non-browser clients
1939
1937
 
1940
1938
  * FUSE: mount a copyparty server as a local filesystem
1941
1939
  * cross-platform python client available in [./bin/](bin/)
1940
+ * able to mount nginx and iis directory listings too, not just copyparty
1942
1941
  * can be downloaded from copyparty: controlpanel -> connect -> [partyfuse.py](http://127.0.0.1:3923/.cpr/a/partyfuse.py)
1943
1942
  * [rclone](https://rclone.org/) as client can give ~5x performance, see [./docs/rclone.md](docs/rclone.md)
1944
1943
 
@@ -1978,7 +1977,7 @@ alternatively, some alternatives roughly sorted by speed (unreproducible benchma
1978
1977
 
1979
1978
  * [rclone-webdav](./docs/rclone.md) (25s), read/WRITE (rclone v1.63 or later)
1980
1979
  * [rclone-http](./docs/rclone.md) (26s), read-only
1981
- * [partyfuse.py](./bin/#partyfusepy) (35s), read-only
1980
+ * [partyfuse.py](./bin/#partyfusepy) (26s), read-only
1982
1981
  * [rclone-ftp](./docs/rclone.md) (47s), read/WRITE
1983
1982
  * davfs2 (103s), read/WRITE
1984
1983
  * [win10-webdav](#webdav-server) (138s), read/WRITE
@@ -2140,6 +2139,8 @@ volflag `dky` disables the actual key-check, meaning anyone can see the contents
2140
2139
 
2141
2140
  volflag `dks` lets people enter subfolders as well, and also enables download-as-zip/tar
2142
2141
 
2142
+ if you enable dirkeys, it is probably a good idea to enable filekeys too, otherwise it will be impossible to hotlink files from a folder which was accessed using a dirkey
2143
+
2143
2144
  dirkeys are generated based on another salt (`--dk-salt`) + filesystem-path and have a few limitations:
2144
2145
  * the key does not change if the contents of the folder is modified
2145
2146
  * if you need a new dirkey, either change the salt or rename the folder
@@ -2222,7 +2223,7 @@ enable [thumbnails](#thumbnails) of...
2222
2223
  * **JPEG XL pictures:** `pyvips` or `ffmpeg`
2223
2224
 
2224
2225
  enable [smb](#smb-server) support (**not** recommended):
2225
- * `impacket==0.11.0`
2226
+ * `impacket==0.12.0`
2226
2227
 
2227
2228
  `pyvips` gives higher quality thumbnails than `Pillow` and is 320% faster, using 270% more ram: `sudo apt install libvips42 && python3 -m pip install --user -U pyvips`
2228
2229
 
@@ -2296,7 +2297,7 @@ then again, if you are already into downloading shady binaries from the internet
2296
2297
 
2297
2298
  ## zipapp
2298
2299
 
2299
- another emergency alternative, [copyparty.pyz](https://github.com/9001/copyparty/releases/latest/download/copyparty.pyz) has less features, requires python 3.7 or newer, worse compression, and more importantly is unable to benefit from more recent versions of jinja2 and such (which makes it less secure)... lots of drawbacks with this one really -- but it *may* just work if the regular sfx fails to start because the computer is messed up in certain funky ways, so it's worth a shot if all else fails
2300
+ another emergency alternative, [copyparty.pyz](https://github.com/9001/copyparty/releases/latest/download/copyparty.pyz) has less features, is slow, requires python 3.7 or newer, worse compression, and more importantly is unable to benefit from more recent versions of jinja2 and such (which makes it less secure)... lots of drawbacks with this one really -- but it does not unpack any temporay files to disk, so it *may* just work if the regular sfx fails to start because the computer is messed up in certain funky ways, so it's worth a shot if all else fails
2300
2301
 
2301
2302
  run it by doubleclicking it, or try typing `python copyparty.pyz` in your terminal/console/commandline/telex if that fails
2302
2303
 
@@ -1115,12 +1115,12 @@ some **BIG WARNINGS** specific to SMB/CIFS, in decreasing importance:
1115
1115
  * [shadowing](#shadowing) probably works as expected but no guarantees
1116
1116
 
1117
1117
  and some minor issues,
1118
- * clients only see the first ~400 files in big folders; [impacket#1433](https://github.com/SecureAuthCorp/impacket/issues/1433)
1118
+ * clients only see the first ~400 files in big folders;
1119
+ * this was originally due to [impacket#1433](https://github.com/SecureAuthCorp/impacket/issues/1433) which was fixed in impacket-0.12, so you can disable the workaround with `--smb-nwa-1` but then you get unacceptably poor performance instead
1119
1120
  * hot-reload of server config (`/?reload=cfg`) does not include the `[global]` section (commandline args)
1120
1121
  * listens on the first IPv4 `-i` interface only (default = :: = 0.0.0.0 = all)
1121
1122
  * login doesn't work on winxp, but anonymous access is ok -- remove all accounts from copyparty config for that to work
1122
1123
  * win10 onwards does not allow connecting anonymously / without accounts
1123
- * on windows, creating a new file through rightclick --> new --> textfile throws an error due to impacket limitations -- hit OK and F5 to get your file
1124
1124
  * python3 only
1125
1125
  * slow (the builtin webdav support in windows is 5x faster, and rclone-webdav is 30x faster)
1126
1126
 
@@ -1159,8 +1159,6 @@ note that this disables hotlinking because the opengraph spec demands it; to sne
1159
1159
 
1160
1160
  you can also hotlink files regardless by appending `?raw` to the url
1161
1161
 
1162
- NOTE: because discord (and maybe others) strip query args such as `?raw` in opengraph tags, any links which require a filekey or dirkey will not work
1163
-
1164
1162
  if you want to entirely replace the copyparty response with your own jinja2 template, give the template filepath to `--og-tpl` or volflag `og_tpl` (all members of `HttpCli` are available through the `this` object)
1165
1163
 
1166
1164
 
@@ -1885,6 +1883,7 @@ interact with copyparty using non-browser clients
1885
1883
 
1886
1884
  * FUSE: mount a copyparty server as a local filesystem
1887
1885
  * cross-platform python client available in [./bin/](bin/)
1886
+ * able to mount nginx and iis directory listings too, not just copyparty
1888
1887
  * can be downloaded from copyparty: controlpanel -> connect -> [partyfuse.py](http://127.0.0.1:3923/.cpr/a/partyfuse.py)
1889
1888
  * [rclone](https://rclone.org/) as client can give ~5x performance, see [./docs/rclone.md](docs/rclone.md)
1890
1889
 
@@ -1924,7 +1923,7 @@ alternatively, some alternatives roughly sorted by speed (unreproducible benchma
1924
1923
 
1925
1924
  * [rclone-webdav](./docs/rclone.md) (25s), read/WRITE (rclone v1.63 or later)
1926
1925
  * [rclone-http](./docs/rclone.md) (26s), read-only
1927
- * [partyfuse.py](./bin/#partyfusepy) (35s), read-only
1926
+ * [partyfuse.py](./bin/#partyfusepy) (26s), read-only
1928
1927
  * [rclone-ftp](./docs/rclone.md) (47s), read/WRITE
1929
1928
  * davfs2 (103s), read/WRITE
1930
1929
  * [win10-webdav](#webdav-server) (138s), read/WRITE
@@ -2086,6 +2085,8 @@ volflag `dky` disables the actual key-check, meaning anyone can see the contents
2086
2085
 
2087
2086
  volflag `dks` lets people enter subfolders as well, and also enables download-as-zip/tar
2088
2087
 
2088
+ if you enable dirkeys, it is probably a good idea to enable filekeys too, otherwise it will be impossible to hotlink files from a folder which was accessed using a dirkey
2089
+
2089
2090
  dirkeys are generated based on another salt (`--dk-salt`) + filesystem-path and have a few limitations:
2090
2091
  * the key does not change if the contents of the folder is modified
2091
2092
  * if you need a new dirkey, either change the salt or rename the folder
@@ -2168,7 +2169,7 @@ enable [thumbnails](#thumbnails) of...
2168
2169
  * **JPEG XL pictures:** `pyvips` or `ffmpeg`
2169
2170
 
2170
2171
  enable [smb](#smb-server) support (**not** recommended):
2171
- * `impacket==0.11.0`
2172
+ * `impacket==0.12.0`
2172
2173
 
2173
2174
  `pyvips` gives higher quality thumbnails than `Pillow` and is 320% faster, using 270% more ram: `sudo apt install libvips42 && python3 -m pip install --user -U pyvips`
2174
2175
 
@@ -2242,7 +2243,7 @@ then again, if you are already into downloading shady binaries from the internet
2242
2243
 
2243
2244
  ## zipapp
2244
2245
 
2245
- another emergency alternative, [copyparty.pyz](https://github.com/9001/copyparty/releases/latest/download/copyparty.pyz) has less features, requires python 3.7 or newer, worse compression, and more importantly is unable to benefit from more recent versions of jinja2 and such (which makes it less secure)... lots of drawbacks with this one really -- but it *may* just work if the regular sfx fails to start because the computer is messed up in certain funky ways, so it's worth a shot if all else fails
2246
+ another emergency alternative, [copyparty.pyz](https://github.com/9001/copyparty/releases/latest/download/copyparty.pyz) has less features, is slow, requires python 3.7 or newer, worse compression, and more importantly is unable to benefit from more recent versions of jinja2 and such (which makes it less secure)... lots of drawbacks with this one really -- but it does not unpack any temporay files to disk, so it *may* just work if the regular sfx fails to start because the computer is messed up in certain funky ways, so it's worth a shot if all else fails
2246
2247
 
2247
2248
  run it by doubleclicking it, or try typing `python copyparty.pyz` in your terminal/console/commandline/telex if that fails
2248
2249
 
@@ -48,9 +48,64 @@ try:
48
48
  except:
49
49
  CORES = (os.cpu_count() if hasattr(os, "cpu_count") else 0) or 2
50
50
 
51
+ # all embedded resources to be retrievable over http
52
+ zs = """
53
+ web/a/partyfuse.py
54
+ web/a/u2c.py
55
+ web/a/webdav-cfg.bat
56
+ web/baguettebox.js
57
+ web/browser.css
58
+ web/browser.html
59
+ web/browser.js
60
+ web/browser2.html
61
+ web/cf.html
62
+ web/copyparty.gif
63
+ web/dd/2.png
64
+ web/dd/3.png
65
+ web/dd/4.png
66
+ web/dd/5.png
67
+ web/deps/busy.mp3
68
+ web/deps/easymde.css
69
+ web/deps/easymde.js
70
+ web/deps/marked.js
71
+ web/deps/fuse.py
72
+ web/deps/mini-fa.css
73
+ web/deps/mini-fa.woff
74
+ web/deps/prism.css
75
+ web/deps/prism.js
76
+ web/deps/prismd.css
77
+ web/deps/scp.woff2
78
+ web/deps/sha512.ac.js
79
+ web/deps/sha512.hw.js
80
+ web/md.css
81
+ web/md.html
82
+ web/md.js
83
+ web/md2.css
84
+ web/md2.js
85
+ web/mde.css
86
+ web/mde.html
87
+ web/mde.js
88
+ web/msg.css
89
+ web/msg.html
90
+ web/shares.css
91
+ web/shares.html
92
+ web/shares.js
93
+ web/splash.css
94
+ web/splash.html
95
+ web/splash.js
96
+ web/svcs.html
97
+ web/svcs.js
98
+ web/ui.css
99
+ web/up2k.js
100
+ web/util.js
101
+ web/w.hash.js
102
+ """
103
+ RES = set(zs.strip().split("\n"))
104
+
51
105
 
52
106
  class EnvParams(object):
53
107
  def __init__(self) :
108
+ self.pkg = None
54
109
  self.t0 = time.time()
55
110
  self.mod = ""
56
111
  self.cfg = ""
@@ -57,6 +57,8 @@ from .util import (
57
57
  ansi_re,
58
58
  b64enc,
59
59
  dedent,
60
+ has_resource,
61
+ load_resource,
60
62
  min_ex,
61
63
  pybin,
62
64
  termsize,
@@ -210,6 +212,7 @@ def init_E(EE ) :
210
212
 
211
213
  raise Exception("could not find a writable path for config")
212
214
 
215
+ E.pkg = sys.modules[__package__]
213
216
  E.mod = os.path.dirname(os.path.realpath(__file__))
214
217
  if E.mod.endswith("__init__"):
215
218
  E.mod = os.path.dirname(E.mod)
@@ -319,8 +322,7 @@ def ensure_locale() :
319
322
 
320
323
 
321
324
  def ensure_webdeps() :
322
- ap = os.path.join(E.mod, "web/deps/mini-fa.woff")
323
- if os.path.exists(ap):
325
+ if has_resource(E, "web/deps/mini-fa.woff"):
324
326
  return
325
327
 
326
328
  warn(
@@ -511,14 +513,18 @@ def sfx_tpoke(top ):
511
513
 
512
514
 
513
515
  def showlic() :
514
- p = os.path.join(E.mod, "res", "COPYING.txt")
515
- if not os.path.exists(p):
516
+ try:
517
+ with load_resource(E, "res/COPYING.txt") as f:
518
+ buf = f.read()
519
+ except:
520
+ buf = b""
521
+
522
+ if buf:
523
+ print(buf.decode("utf-8", "replace"))
524
+ else:
516
525
  print("no relevant license info to display")
517
526
  return
518
527
 
519
- with open(p, "rb") as f:
520
- print(f.read().decode("utf-8", "replace"))
521
-
522
528
 
523
529
  def get_sects():
524
530
  return [
@@ -1166,7 +1172,7 @@ def add_smb(ap):
1166
1172
  ap2.add_argument("--smbw", action="store_true", help="enable write support (please dont)")
1167
1173
  ap2.add_argument("--smb1", action="store_true", help="disable SMBv2, only enable SMBv1 (CIFS)")
1168
1174
  ap2.add_argument("--smb-port", metavar="PORT", type=int, default=445, help="port to listen on -- if you change this value, you must NAT from TCP:445 to this port using iptables or similar")
1169
- ap2.add_argument("--smb-nwa-1", action="store_true", help="disable impacket#1433 workaround (truncate directory listings to 64kB)")
1175
+ ap2.add_argument("--smb-nwa-1", action="store_true", help="truncate directory listings to 64kB (~400 files); avoids impacket-0.11 bug, fixes impacket-0.12 performance")
1170
1176
  ap2.add_argument("--smb-nwa-2", action="store_true", help="disable impacket workaround for filecopy globs")
1171
1177
  ap2.add_argument("--smba", action="store_true", help="small performance boost: disable per-account permissions, enables account coalescing instead (if one user has write/delete-access, then everyone does)")
1172
1178
  ap2.add_argument("--smbv", action="store_true", help="verbose")
@@ -1558,16 +1564,13 @@ def run_argparse(
1558
1564
  return ret
1559
1565
 
1560
1566
 
1561
- def main(argv = None, rsrc = None) :
1567
+ def main(argv = None) :
1562
1568
  time.strptime("19970815", "%Y%m%d") # python#7980
1563
1569
  if WINDOWS:
1564
1570
  os.system("rem") # enables colors
1565
1571
 
1566
1572
  init_E(E)
1567
1573
 
1568
- if rsrc: # pyz
1569
- E.mod = rsrc
1570
-
1571
1574
  if argv is None:
1572
1575
  argv = sys.argv
1573
1576
 
@@ -1,8 +1,8 @@
1
1
  # coding: utf-8
2
2
 
3
- VERSION = (1, 15, 3)
3
+ VERSION = (1, 15, 4)
4
4
  CODENAME = "fill the drives"
5
- BUILD_DT = (2024, 9, 16)
5
+ BUILD_DT = (2024, 10, 4)
6
6
 
7
7
  S_VERSION = ".".join(map(str, VERSION))
8
8
  S_BUILD_DT = "{0:04d}-{1:02d}-{2:02d}".format(*BUILD_DT)
@@ -7,7 +7,7 @@ import shutil
7
7
  import time
8
8
 
9
9
  from .__init__ import ANYWIN
10
- from .util import Netdev, runcmd, wrename, wunlink
10
+ from .util import Netdev, load_resource, runcmd, wrename, wunlink
11
11
 
12
12
  HAVE_CFSSL = not os.environ.get("PRTY_NO_CFSSL")
13
13
 
@@ -25,13 +25,15 @@ def ensure_cert(log , args) :
25
25
 
26
26
  i feel awful about this and so should they
27
27
  """
28
- cert_insec = os.path.join(args.E.mod, "res/insecure.pem")
28
+ with load_resource(args.E, "res/insecure.pem") as f:
29
+ cert_insec = f.read()
29
30
  cert_appdata = os.path.join(args.E.cfg, "cert.pem")
30
31
  if not os.path.isfile(args.cert):
31
32
  if cert_appdata != args.cert:
32
33
  raise Exception("certificate file does not exist: " + args.cert)
33
34
 
34
- shutil.copy(cert_insec, args.cert)
35
+ with open(args.cert, "wb") as f:
36
+ f.write(cert_insec)
35
37
 
36
38
  with open(args.cert, "rb") as f:
37
39
  buf = f.read()
@@ -46,7 +48,9 @@ def ensure_cert(log , args) :
46
48
  raise Exception(m + "private key must appear before server certificate")
47
49
 
48
50
  try:
49
- if filecmp.cmp(args.cert, cert_insec):
51
+ with open(args.cert, "rb") as f:
52
+ active_cert = f.read()
53
+ if active_cert == cert_insec:
50
54
  t = "using default TLS certificate; https will be insecure:\033[36m {}"
51
55
  log("cert", t.format(args.cert), 3)
52
56
  except:
@@ -147,14 +151,22 @@ def _gen_srv(log , args, netdevs ):
147
151
  raise Exception("no useable cert found")
148
152
 
149
153
  expired = time.time() + args.crt_sdays * 60 * 60 * 24 * 0.5 > expiry
150
- cert_insec = os.path.join(args.E.mod, "res/insecure.pem")
154
+ if expired:
155
+ raise Exception("old server-cert has expired")
156
+
151
157
  for n in names:
152
158
  if n not in inf["sans"]:
153
159
  raise Exception("does not have {}".format(n))
154
- if expired:
155
- raise Exception("old server-cert has expired")
156
- if not filecmp.cmp(args.cert, cert_insec):
160
+
161
+ with load_resource(args.E, "res/insecure.pem") as f:
162
+ cert_insec = f.read()
163
+
164
+ with open(args.cert, "rb") as f:
165
+ active_cert = f.read()
166
+
167
+ if active_cert and active_cert != cert_insec:
157
168
  return
169
+
158
170
  except Exception as ex:
159
171
  log("cert", "will create new server-cert; {}".format(ex))
160
172
 
@@ -2,7 +2,7 @@
2
2
  from __future__ import print_function, unicode_literals
3
3
 
4
4
  # awk -F\" '/add_argument\("-[^-]/{print(substr($2,2))}' copyparty/__main__.py | sort | tr '\n' ' '
5
- zs = "a c e2d e2ds e2dsa e2t e2ts e2tsr e2v e2vp e2vu ed emp i j lo mcr mte mth mtm mtp nb nc nid nih nw p q s ss sss v z zv"
5
+ zs = "a c e2d e2ds e2dsa e2t e2ts e2tsr e2v e2vp e2vu ed emp i j lo mcr mte mth mtm mtp nb nc nid nih nth nw p q s ss sss v z zv"
6
6
  onedash = set(zs.split())
7
7
 
8
8
 
@@ -159,7 +159,7 @@ class FtpFs(AbstractedFS):
159
159
  t = "Unsupported characters in [{}]"
160
160
  raise FSE(t.format(vpath), 1)
161
161
 
162
- fn = sanitize_fn(fn or "", "", [".prologue.html", ".epilogue.html"])
162
+ fn = sanitize_fn(fn or "", "")
163
163
  vpath = vjoin(rd, fn)
164
164
  vfs, rem = self.hub.asrv.vfs.get(vpath, self.uname, r, w, m, d)
165
165
  if not vfs.realpath: