copyparty 1.15.8__tar.gz → 1.15.10__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 (122) hide show
  1. {copyparty-1.15.8 → copyparty-1.15.10}/PKG-INFO +30 -1
  2. {copyparty-1.15.8 → copyparty-1.15.10}/README.md +28 -0
  3. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/__main__.py +15 -1
  4. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/__version__.py +2 -2
  5. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/authsrv.py +17 -7
  6. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/cfg.py +1 -0
  7. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/httpcli.py +274 -75
  8. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/metrics.py +1 -1
  9. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/svchub.py +31 -3
  10. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/u2idx.py +5 -3
  11. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/up2k.py +7 -5
  12. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/util.py +49 -13
  13. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/a/partyfuse.py +1 -1
  14. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/a/u2c.py +13 -9
  15. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/browser.js.gz +0 -0
  16. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/splash.html +12 -3
  17. copyparty-1.15.10/copyparty/web/splash.js.gz +0 -0
  18. copyparty-1.15.10/copyparty/web/up2k.js.gz +0 -0
  19. copyparty-1.15.10/copyparty/web/w.hash.js.gz +0 -0
  20. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty.egg-info/PKG-INFO +30 -1
  21. {copyparty-1.15.8 → copyparty-1.15.10}/pyproject.toml +1 -0
  22. copyparty-1.15.8/copyparty/web/splash.js.gz +0 -0
  23. copyparty-1.15.8/copyparty/web/up2k.js.gz +0 -0
  24. copyparty-1.15.8/copyparty/web/w.hash.js.gz +0 -0
  25. {copyparty-1.15.8 → copyparty-1.15.10}/LICENSE +0 -0
  26. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/__init__.py +0 -0
  27. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/bos/__init__.py +0 -0
  28. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/bos/bos.py +0 -0
  29. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/bos/path.py +0 -0
  30. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/broker_mp.py +0 -0
  31. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/broker_mpw.py +0 -0
  32. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/broker_thr.py +0 -0
  33. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/broker_util.py +0 -0
  34. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/cert.py +0 -0
  35. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/dxml.py +0 -0
  36. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/fsutil.py +0 -0
  37. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/ftpd.py +0 -0
  38. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/httpconn.py +0 -0
  39. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/httpsrv.py +0 -0
  40. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/ico.py +0 -0
  41. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/mdns.py +0 -0
  42. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/mtag.py +0 -0
  43. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/multicast.py +0 -0
  44. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/pwhash.py +0 -0
  45. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/res/COPYING.txt +0 -0
  46. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/res/__init__.py +0 -0
  47. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/res/insecure.pem +0 -0
  48. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/smbd.py +0 -0
  49. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/ssdp.py +0 -0
  50. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/star.py +0 -0
  51. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/stolen/__init__.py +0 -0
  52. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/stolen/dnslib/__init__.py +0 -0
  53. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/stolen/dnslib/bimap.py +0 -0
  54. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/stolen/dnslib/bit.py +0 -0
  55. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/stolen/dnslib/buffer.py +0 -0
  56. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/stolen/dnslib/dns.py +0 -0
  57. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/stolen/dnslib/label.py +0 -0
  58. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/stolen/dnslib/lex.py +0 -0
  59. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/stolen/dnslib/ranges.py +0 -0
  60. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/stolen/ifaddr/__init__.py +0 -0
  61. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/stolen/ifaddr/_posix.py +0 -0
  62. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/stolen/ifaddr/_shared.py +0 -0
  63. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/stolen/ifaddr/_win32.py +0 -0
  64. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/stolen/qrcodegen.py +0 -0
  65. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/stolen/surrogateescape.py +0 -0
  66. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/sutil.py +0 -0
  67. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/szip.py +0 -0
  68. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/tcpsrv.py +0 -0
  69. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/tftpd.py +0 -0
  70. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/th_cli.py +0 -0
  71. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/th_srv.py +0 -0
  72. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/a/__init__.py +0 -0
  73. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/a/webdav-cfg.bat +0 -0
  74. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/baguettebox.js.gz +0 -0
  75. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/browser.css.gz +0 -0
  76. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/browser.html +0 -0
  77. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/browser2.html +0 -0
  78. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/cf.html +0 -0
  79. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/dbg-audio.js.gz +0 -0
  80. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/dd/2.png +0 -0
  81. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/dd/3.png +0 -0
  82. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/dd/4.png +0 -0
  83. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/dd/5.png +0 -0
  84. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/dd/__init__.py +0 -0
  85. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/deps/__init__.py +0 -0
  86. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/deps/busy.mp3.gz +0 -0
  87. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/deps/easymde.css.gz +0 -0
  88. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/deps/easymde.js.gz +0 -0
  89. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/deps/fuse.py +0 -0
  90. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/deps/marked.js.gz +0 -0
  91. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/deps/mini-fa.css.gz +0 -0
  92. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/deps/mini-fa.woff +0 -0
  93. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/deps/prism.css.gz +0 -0
  94. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/deps/prism.js.gz +0 -0
  95. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/deps/prismd.css.gz +0 -0
  96. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/deps/scp.woff2 +0 -0
  97. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/deps/sha512.ac.js.gz +0 -0
  98. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/deps/sha512.hw.js.gz +0 -0
  99. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/md.css.gz +0 -0
  100. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/md.html +0 -0
  101. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/md.js.gz +0 -0
  102. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/md2.css.gz +0 -0
  103. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/md2.js.gz +0 -0
  104. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/mde.css.gz +0 -0
  105. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/mde.html +0 -0
  106. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/mde.js.gz +0 -0
  107. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/msg.css.gz +0 -0
  108. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/msg.html +0 -0
  109. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/shares.css.gz +0 -0
  110. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/shares.html +0 -0
  111. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/shares.js.gz +0 -0
  112. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/splash.css.gz +0 -0
  113. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/svcs.html +0 -0
  114. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/svcs.js.gz +0 -0
  115. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/ui.css.gz +0 -0
  116. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty/web/util.js.gz +0 -0
  117. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty.egg-info/SOURCES.txt +0 -0
  118. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty.egg-info/dependency_links.txt +0 -0
  119. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty.egg-info/entry_points.txt +0 -0
  120. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty.egg-info/requires.txt +0 -0
  121. {copyparty-1.15.8 → copyparty-1.15.10}/copyparty.egg-info/top_level.txt +0 -0
  122. {copyparty-1.15.8 → copyparty-1.15.10}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: copyparty
3
- Version: 1.15.8
3
+ Version: 1.15.10
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
@@ -101,6 +102,7 @@ turn almost any device into a file server with resumable uploads/downloads using
101
102
  * [file manager](#file-manager) - cut/paste, rename, and delete files/folders (if you have permission)
102
103
  * [shares](#shares) - share a file or folder by creating a temporary link
103
104
  * [batch rename](#batch-rename) - select some files and press `F2` to bring up the rename UI
105
+ * [rss feeds](#rss-feeds) - monitor a folder with your RSS reader
104
106
  * [media player](#media-player) - plays almost every audio format there is
105
107
  * [audio equalizer](#audio-equalizer) - and [dynamic range compressor](https://en.wikipedia.org/wiki/Dynamic_range_compression)
106
108
  * [fix unreliable playback on android](#fix-unreliable-playback-on-android) - due to phone / app settings
@@ -899,6 +901,30 @@ or a mix of both:
899
901
  the metadata keys you can use in the format field are the ones in the file-browser table header (whatever is collected with `-mte` and `-mtp`)
900
902
 
901
903
 
904
+ ## rss feeds
905
+
906
+ monitor a folder with your RSS reader , optionally recursive
907
+
908
+ must be enabled per-volume with volflag `rss` or globally with `--rss`
909
+
910
+ the feed includes itunes metadata for use with podcast readers such as [AntennaPod](https://antennapod.org/)
911
+
912
+ a feed example: https://cd.ocv.me/a/d2/d22/?rss&fext=mp3
913
+
914
+ url parameters:
915
+
916
+ * `pw=hunter2` for password auth
917
+ * `recursive` to also include subfolders
918
+ * `title=foo` changes the feed title (default: folder name)
919
+ * `fext=mp3,opus` only include mp3 and opus files (default: all)
920
+ * `nf=30` only show the first 30 results (default: 250)
921
+ * `sort=m` sort by mtime (file last-modified), newest first (default)
922
+ * `u` = upload-time; NOTE: non-uploaded files have upload-time `0`
923
+ * `n` = filename
924
+ * `a` = filesize
925
+ * uppercase = reverse-sort; `M` = oldest file first
926
+
927
+
902
928
  ## media player
903
929
 
904
930
  plays almost every audio format there is (if the server has FFmpeg installed for on-demand transcoding)
@@ -1962,6 +1988,9 @@ quick summary of more eccentric web-browsers trying to view a directory index:
1962
1988
  | **ie4** and **netscape** 4.0 | can browse, upload with `?b=u`, auth with `&pw=wark` |
1963
1989
  | **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) |
1964
1990
  | **SerenityOS** (7e98457) | hits a page fault, works with `?b=u`, file upload not-impl |
1991
+ | **nintendo 3ds** | can browse, upload, view thumbnails (thx bnjmn) |
1992
+
1993
+ <p align="center"><img src="https://github.com/user-attachments/assets/88deab3d-6cad-4017-8841-2f041472b853" /></p>
1965
1994
 
1966
1995
 
1967
1996
  # client examples
@@ -47,6 +47,7 @@ turn almost any device into a file server with resumable uploads/downloads using
47
47
  * [file manager](#file-manager) - cut/paste, rename, and delete files/folders (if you have permission)
48
48
  * [shares](#shares) - share a file or folder by creating a temporary link
49
49
  * [batch rename](#batch-rename) - select some files and press `F2` to bring up the rename UI
50
+ * [rss feeds](#rss-feeds) - monitor a folder with your RSS reader
50
51
  * [media player](#media-player) - plays almost every audio format there is
51
52
  * [audio equalizer](#audio-equalizer) - and [dynamic range compressor](https://en.wikipedia.org/wiki/Dynamic_range_compression)
52
53
  * [fix unreliable playback on android](#fix-unreliable-playback-on-android) - due to phone / app settings
@@ -845,6 +846,30 @@ or a mix of both:
845
846
  the metadata keys you can use in the format field are the ones in the file-browser table header (whatever is collected with `-mte` and `-mtp`)
846
847
 
847
848
 
849
+ ## rss feeds
850
+
851
+ monitor a folder with your RSS reader , optionally recursive
852
+
853
+ must be enabled per-volume with volflag `rss` or globally with `--rss`
854
+
855
+ the feed includes itunes metadata for use with podcast readers such as [AntennaPod](https://antennapod.org/)
856
+
857
+ a feed example: https://cd.ocv.me/a/d2/d22/?rss&fext=mp3
858
+
859
+ url parameters:
860
+
861
+ * `pw=hunter2` for password auth
862
+ * `recursive` to also include subfolders
863
+ * `title=foo` changes the feed title (default: folder name)
864
+ * `fext=mp3,opus` only include mp3 and opus files (default: all)
865
+ * `nf=30` only show the first 30 results (default: 250)
866
+ * `sort=m` sort by mtime (file last-modified), newest first (default)
867
+ * `u` = upload-time; NOTE: non-uploaded files have upload-time `0`
868
+ * `n` = filename
869
+ * `a` = filesize
870
+ * uppercase = reverse-sort; `M` = oldest file first
871
+
872
+
848
873
  ## media player
849
874
 
850
875
  plays almost every audio format there is (if the server has FFmpeg installed for on-demand transcoding)
@@ -1908,6 +1933,9 @@ quick summary of more eccentric web-browsers trying to view a directory index:
1908
1933
  | **ie4** and **netscape** 4.0 | can browse, upload with `?b=u`, auth with `&pw=wark` |
1909
1934
  | **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) |
1910
1935
  | **SerenityOS** (7e98457) | hits a page fault, works with `?b=u`, file upload not-impl |
1936
+ | **nintendo 3ds** | can browse, upload, view thumbnails (thx bnjmn) |
1937
+
1938
+ <p align="center"><img src="https://github.com/user-attachments/assets/88deab3d-6cad-4017-8841-2f041472b853" /></p>
1911
1939
 
1912
1940
 
1913
1941
  # client examples
@@ -1029,7 +1029,7 @@ def add_network(ap):
1029
1029
  else:
1030
1030
  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)")
1031
1031
  ap2.add_argument("--s-thead", metavar="SEC", type=int, default=120, help="socket timeout (read request header)")
1032
- ap2.add_argument("--s-tbody", metavar="SEC", type=float, default=186.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")
1032
+ 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")
1033
1033
  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)")
1034
1034
  ap2.add_argument("--s-wr-sz", metavar="B", type=int, default=256*1024, help="socket write size in bytes")
1035
1035
  ap2.add_argument("--s-wr-slp", metavar="SEC", type=float, default=0.0, help="debug: socket write delay in seconds")
@@ -1299,6 +1299,7 @@ def add_logging(ap):
1299
1299
  ap2.add_argument("--log-conn", action="store_true", help="debug: print tcp-server msgs")
1300
1300
  ap2.add_argument("--log-htp", action="store_true", help="debug: print http-server threadpool scaling")
1301
1301
  ap2.add_argument("--ihead", metavar="HEADER", type=u, action='append', help="print request \033[33mHEADER\033[0m; [\033[32m*\033[0m]=all")
1302
+ ap2.add_argument("--ohead", metavar="HEADER", type=u, action='append', help="print response \033[33mHEADER\033[0m; [\033[32m*\033[0m]=all")
1302
1303
  ap2.add_argument("--lf-url", metavar="RE", type=u, default=r"^/\.cpr/|\?th=[wj]$|/\.(_|ql_|DS_Store$|localized$)", help="dont log URLs matching regex \033[33mRE\033[0m")
1303
1304
 
1304
1305
 
@@ -1349,6 +1350,14 @@ def add_transcoding(ap):
1349
1350
  ap2.add_argument("--ac-maxage", metavar="SEC", type=int, default=86400, help="delete cached transcode output after \033[33mSEC\033[0m seconds")
1350
1351
 
1351
1352
 
1353
+ def add_rss(ap):
1354
+ ap2 = ap.add_argument_group('RSS options')
1355
+ ap2.add_argument("--rss", action="store_true", help="enable RSS output (experimental)")
1356
+ ap2.add_argument("--rss-nf", metavar="HITS", type=int, default=250, help="default number of files to return (url-param 'nf')")
1357
+ ap2.add_argument("--rss-fext", metavar="E,E", type=u, default="", help="default list of file extensions to include (url-param 'fext'); blank=all")
1358
+ ap2.add_argument("--rss-sort", metavar="ORD", type=u, default="m", help="default sort order (url-param 'sort'); [\033[32mm\033[0m]=last-modified [\033[32mu\033[0m]=upload-time [\033[32mn\033[0m]=filename [\033[32ms\033[0m]=filesize; Uppercase=oldest-first. Note that upload-time is 0 for non-uploaded files")
1359
+
1360
+
1352
1361
  def add_db_general(ap, hcores):
1353
1362
  noidx = APPLESAN_TXT if MACOS else ""
1354
1363
  ap2 = ap.add_argument_group('general db options')
@@ -1444,6 +1453,7 @@ def add_ui(ap, retry):
1444
1453
  ap2.add_argument("--pb-url", metavar="URL", type=u, default="https://github.com/9001/copyparty", help="powered-by link; disable with \033[33m-np\033[0m")
1445
1454
  ap2.add_argument("--ver", action="store_true", help="show version on the control panel (incompatible with \033[33m-nb\033[0m)")
1446
1455
  ap2.add_argument("--k304", metavar="NUM", type=int, default=0, help="configure the option to enable/disable k304 on the controlpanel (workaround for buggy reverse-proxies); [\033[32m0\033[0m] = hidden and default-off, [\033[32m1\033[0m] = visible and default-off, [\033[32m2\033[0m] = visible and default-on")
1456
+ ap2.add_argument("--no304", metavar="NUM", type=int, default=0, help="configure the option to enable/disable no304 on the controlpanel (workaround for buggy caching in browsers); [\033[32m0\033[0m] = hidden and default-off, [\033[32m1\033[0m] = visible and default-off, [\033[32m2\033[0m] = visible and default-on")
1447
1457
  ap2.add_argument("--md-sbf", metavar="FLAGS", type=u, default="downloads forms popups scripts top-navigation-by-user-activation", help="list of capabilities to ALLOW for README.md docs (volflag=md_sbf); see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-sandbox")
1448
1458
  ap2.add_argument("--lg-sbf", metavar="FLAGS", type=u, default="downloads forms popups scripts top-navigation-by-user-activation", help="list of capabilities to ALLOW for prologue/epilogue docs (volflag=lg_sbf)")
1449
1459
  ap2.add_argument("--no-sb-md", action="store_true", help="don't sandbox README/PREADME.md documents (volflags: no_sb_md | sb_md)")
@@ -1518,6 +1528,7 @@ def run_argparse(
1518
1528
  add_db_metadata(ap)
1519
1529
  add_thumbnail(ap)
1520
1530
  add_transcoding(ap)
1531
+ add_rss(ap)
1521
1532
  add_ftp(ap)
1522
1533
  add_webdav(ap)
1523
1534
  add_tftp(ap)
@@ -1740,6 +1751,9 @@ def main(argv = None) :
1740
1751
  if al.ihead:
1741
1752
  al.ihead = [x.lower() for x in al.ihead]
1742
1753
 
1754
+ if al.ohead:
1755
+ al.ohead = [x.lower() for x in al.ohead]
1756
+
1743
1757
  if HAVE_SSL:
1744
1758
  if al.ssl_ver:
1745
1759
  configure_ssl_ver(al)
@@ -1,8 +1,8 @@
1
1
  # coding: utf-8
2
2
 
3
- VERSION = (1, 15, 8)
3
+ VERSION = (1, 15, 10)
4
4
  CODENAME = "fill the drives"
5
- BUILD_DT = (2024, 10, 16)
5
+ BUILD_DT = (2024, 10, 26)
6
6
 
7
7
  S_VERSION = ".".join(map(str, VERSION))
8
8
  S_BUILD_DT = "{0:04d}-{1:02d}-{2:02d}".format(*BUILD_DT)
@@ -158,8 +158,11 @@ class Lim(object):
158
158
  self.chk_rem(rem)
159
159
  if sz != -1:
160
160
  self.chk_sz(sz)
161
- self.chk_vsz(broker, ptop, sz, volgetter)
162
- self.chk_df(abspath, sz) # side effects; keep last-ish
161
+ else:
162
+ sz = 0
163
+
164
+ self.chk_vsz(broker, ptop, sz, volgetter)
165
+ self.chk_df(abspath, sz) # side effects; keep last-ish
163
166
 
164
167
  ap2, vp2 = self.rot(abspath)
165
168
  if abspath == ap2:
@@ -199,7 +202,15 @@ class Lim(object):
199
202
 
200
203
  if self.dft < time.time():
201
204
  self.dft = int(time.time()) + 300
202
- self.dfv = get_df(abspath)[0] or 0
205
+
206
+ df, du, err = get_df(abspath, True)
207
+ if err:
208
+ t = "failed to read disk space usage for [%s]: %s"
209
+ self.log(t % (abspath, err), 3)
210
+ self.dfv = 0xAAAAAAAAA # 42.6 GiB
211
+ else:
212
+ self.dfv = df or 0
213
+
203
214
  for j in list(self.reg.values()) if self.reg else []:
204
215
  self.dfv -= int(j["size"] / (len(j["hash"]) or 999) * len(j["need"]))
205
216
 
@@ -534,15 +545,14 @@ class VFS(object):
534
545
  return self._get_dbv(vrem)
535
546
 
536
547
  shv, srem = src
537
- return shv, vjoin(srem, vrem)
548
+ return shv._get_dbv(vjoin(srem, vrem))
538
549
 
539
550
  def _get_dbv(self, vrem ) :
540
551
  dbv = self.dbv
541
552
  if not dbv:
542
553
  return self, vrem
543
554
 
544
- tv = [self.vpath[len(dbv.vpath) :].lstrip("/"), vrem]
545
- vrem = "/".join([x for x in tv if x])
555
+ vrem = vjoin(self.vpath[len(dbv.vpath) :].lstrip("/"), vrem)
546
556
  return dbv, vrem
547
557
 
548
558
  def canonical(self, rem , resolve = True) :
@@ -2622,7 +2632,7 @@ class AuthSrv(object):
2622
2632
  ]
2623
2633
 
2624
2634
  csv = set("i p th_covers zm_on zm_off zs_on zs_off".split())
2625
- zs = "c ihead mtm mtp on403 on404 xad xar xau xiu xban xbd xbr xbu xm"
2635
+ zs = "c ihead ohead mtm mtp on403 on404 xad xar xau xiu xban xbd xbr xbu xm"
2626
2636
  lst = set(zs.split())
2627
2637
  askip = set("a v c vc cgen exp_lg exp_md theme".split())
2628
2638
  fskip = set("exp_lg exp_md mv_re_r mv_re_t rm_re_r rm_re_t".split())
@@ -46,6 +46,7 @@ def vf_bmap() :
46
46
  "og_no_head",
47
47
  "og_s_title",
48
48
  "rand",
49
+ "rss",
49
50
  "xdev",
50
51
  "xlink",
51
52
  "xvol",