diff --git a/copyparty/__main__.py b/copyparty/__main__.py
index 2e988d66..ec051f6d 100644
--- a/copyparty/__main__.py
+++ b/copyparty/__main__.py
@@ -675,7 +675,7 @@ def main(argv: Optional[list[str]] = None) -> None:
if argv is None:
argv = sys.argv
- f = '\033[36mcopyparty v{} "\033[35m{}\033[36m" ({})\n{}\033[0;36m\n sqlite v{} | jinja2 v{} | pyftpd v{}\n\033[0m\n'
+ f = '\033[36mcopyparty v{} "\033[35m{}\033[36m" ({})\n{}\033[0;36m\n sqlite v{} | jinja2 v{} | pyftpd v{}\n\033[0m'
f = f.format(
S_VERSION,
CODENAME,
diff --git a/copyparty/__version__.py b/copyparty/__version__.py
index ceafd9aa..7e8cd9d4 100644
--- a/copyparty/__version__.py
+++ b/copyparty/__version__.py
@@ -1,8 +1,8 @@
# coding: utf-8
-VERSION = (1, 3, 8)
+VERSION = (1, 3, 9)
CODENAME = "god dag"
-BUILD_DT = (2022, 7, 27)
+BUILD_DT = (2022, 8, 4)
S_VERSION = ".".join(map(str, VERSION))
S_BUILD_DT = "{0:04d}-{1:02d}-{2:02d}".format(*BUILD_DT)
diff --git a/copyparty/authsrv.py b/copyparty/authsrv.py
index d3740a41..6c4ff433 100644
--- a/copyparty/authsrv.py
+++ b/copyparty/authsrv.py
@@ -1036,7 +1036,7 @@ class AuthSrv(object):
vol.flags["fk"] = int(fk) if fk is not True else 8
have_fk = True
- if have_fk and re.match("^[0-9\.]+$", self.args.fk_salt):
+ if have_fk and re.match(r"^[0-9\.]+$", self.args.fk_salt):
self.log("filekey salt: {}".format(self.args.fk_salt))
for vol in vfs.all_vols.values():
diff --git a/copyparty/fsutil.py b/copyparty/fsutil.py
index 883b9879..e115d76f 100644
--- a/copyparty/fsutil.py
+++ b/copyparty/fsutil.py
@@ -6,12 +6,12 @@ import re
import time
from .__init__ import ANYWIN, MACOS
-from .bos import bos
from .authsrv import AXS, VFS
+from .bos import bos
from .util import chkcmd, min_ex
try:
- from typing import Any, Optional, Union
+ from typing import Optional, Union
from .util import RootLogger
except:
diff --git a/copyparty/svchub.py b/copyparty/svchub.py
index 24ab34fe..88e56df5 100644
--- a/copyparty/svchub.py
+++ b/copyparty/svchub.py
@@ -20,7 +20,7 @@ try:
from types import FrameType
import typing
- from typing import Optional, Union
+ from typing import Any, Optional, Union
except:
pass
@@ -467,7 +467,7 @@ class SvcHub(object):
if self.logf:
self.logf.write(msg)
- def pr(self, *a, **ka):
+ def pr(self, *a: Any, **ka: Any) -> None:
with self.log_mutex:
print(*a, **ka)
diff --git a/copyparty/up2k.py b/copyparty/up2k.py
index e92b1d7f..467f4314 100644
--- a/copyparty/up2k.py
+++ b/copyparty/up2k.py
@@ -32,8 +32,8 @@ from .util import (
ProgressPrinter,
absreal,
atomic_move,
- djoin,
db_ex_chk,
+ djoin,
fsenc,
min_ex,
quotep,
@@ -143,7 +143,8 @@ class Up2k(object):
if self.sqlite_ver < (3, 9):
self.no_expr_idx = True
else:
- self.log("could not initialize sqlite3, will use in-memory registry only")
+ t = "could not initialize sqlite3, will use in-memory registry only"
+ self.log(t, 3)
if ANYWIN:
# usually fails to set lastmod too quickly
diff --git a/copyparty/util.py b/copyparty/util.py
index 4c026686..24c20639 100644
--- a/copyparty/util.py
+++ b/copyparty/util.py
@@ -84,8 +84,6 @@ else:
from urllib import quote # pylint: disable=no-name-in-module
from urllib import unquote # pylint: disable=no-name-in-module
-_: Any = (mp, BytesIO, quote, unquote)
-__all__ = ["mp", "BytesIO", "quote", "unquote"]
try:
struct.unpack(b">i", b"idgi")
@@ -258,6 +256,10 @@ VERSIONS = "copyparty v{} ({})\n{}\n sqlite v{} | jinja v{} | pyftpd v{}".form
)
+_: Any = (mp, BytesIO, quote, unquote, SQLITE_VER, JINJA_VER, PYFTPD_VER)
+__all__ = ["mp", "BytesIO", "quote", "unquote", "SQLITE_VER", "JINJA_VER", "PYFTPD_VER"]
+
+
class Cooldown(object):
def __init__(self, maxage: float) -> None:
self.maxage = maxage
diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js
index 3da62527..c337bb2b 100644
--- a/copyparty/web/browser.js
+++ b/copyparty/web/browser.js
@@ -824,7 +824,7 @@ ebi('op_cfg').innerHTML = (
' 田 the grid\n' +
' 🖼️ thumbs\n' +
' dotfiles\n' +
- ' ↑ dirs\n' +
+ ' 📁 first\n' +
' 📜 readme\n' +
' \n' +
'\n' +
diff --git a/docs/changelog.md b/docs/changelog.md
index 434acd16..8eb88707 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -1,3 +1,133 @@
+▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
+# 2022-0727-1407 `v1.3.8` more async
+
+* read-only demo server at https://a.ocv.me/pub/demo/
+* latest gzip edition of the sfx: [v1.0.14](https://github.com/9001/copyparty/releases/tag/v1.0.14#:~:text=release-specific%20notes)
+
+## new features
+* new arg `--df 4` and volflag `:c,df=4g` to guarantee 4 GiB free disk space by rejecting uploads
+* some features no longer block new uploads while they're processing
+ * `-e2v` file integrity checker
+ * `-e2ts` initial tag scanner
+ * hopefully fixes a [deadlock](https://www.youtube.com/watch?v=DkKoMveT_jo&t=3s) someone ran into (but probably doesn't)
+ * (the "deadlock" link is an addictive demoscene banger -- the actual issue is #10)
+* reduced the impact of some features which still do
+ * defer `--re-maxage` reindexing if there was a write (upload/rename/...) recently
+ * `--db-act` sets minimum idle period before reindex can start (default 10sec)
+* bbox / image-viewer: add video hotkeys 0..9 to seek 0%..90%
+* audio-player: add audio crossfeed (left-right channel mixer / vocal isolation)
+* splashpage (`/?h`) shows time since the most recent write
+
+## bugfixes
+* a11y:
+ * enter-key should always trigger onclick
+ * only focus password box if in-bounds
+ * improve skip-to-files
+* prisonparty: volume labeling in root folders
+* other minor stuff
+ * forget deleted shadowed files from the db
+ * be less noisy if a client disconnects mid-reply
+ * up2k.js less eager to thrash slow server HDDs
+
+## other changes
+* show client's upload ETA in server log
+* dump stacks and issue `lsof` on the db if a transaction is stuck
+ * will hopefully help if there's any more deadlocks
+* [up2k-hook-ytid](https://github.com/9001/copyparty/blob/hovudstraum/contrib/plugins/up2k-hook-ytid.js) (the overengineered up2k.js plugin example) now has an mp4/webm/mkv metadata parser
+
+
+
+▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
+# 2022-0716-1848 `v1.3.7` faster
+
+* read-only demo server at https://a.ocv.me/pub/demo/
+* latest gzip edition of the sfx: [v1.0.14](https://github.com/9001/copyparty/releases/tag/v1.0.14#:~:text=release-specific%20notes)
+
+## new features
+* `up2k.js`: **improved upload speeds!**
+ * **...when there's many small files** (or the browser is slow)
+ * add [potato mode](https://user-images.githubusercontent.com/241032/179336639-8ecc01ea-2662-4cb6-8048-5be3ad599f33.png) -- lightweight UI for faster uploads from slow boxes
+ * enables automatically if it detects a cpu bottleneck (not very accurate)
+ * **...on really fast connections (LAN / fiber)**
+ * batch progress updates to reduce repaints
+ * **...when there is a mix of big and small files**
+ * sort the uploads by size, smallest first, for optimal cpu/network usage
+ * can be overridden to alphabetical order in the settings tab
+ * new arg `--u2sort` changes the default + overrides the override button
+ * improve upload pacing when alphabetical order is enabled
+ * mainly affecting single files that are 300 GiB +
+* `up2k.js`: add [up2k hooks](https://github.com/9001/copyparty/blob/hovudstraum/contrib/plugins/up2k-hooks.js)
+ * specify *client-side* rules to reject files as they are dropped into the browser
+ * not a hard-reject since people can use [up2k.py](https://github.com/9001/copyparty/blob/hovudstraum/bin/up2k.py) and whatnot, more like a hint
+* `up2k.py`: add file integrity checker
+ * new arg `-e2v` to scan volumes and verify file checksums on startup
+ * `-e2vu` updates the db on mismatch, `-e2vp` panics
+ * uploads are blocked while the scan is running -- might get fixed at some point
+ * for now it prints a warning
+* bbox / image-viewer: doubletap a picture to enter fullscreen mode
+* md-editor: `ctrl-c/x` affects current line if no selection, and `ctrl-e` is fullscreen
+* tag-parser plugins:
+ * add support for passing metadata from one mtp to another (parser dependencies)
+ * the `p` flag in [vidchk](https://github.com/9001/copyparty/blob/hovudstraum/bin/mtag/vidchk.py) usage makes it run after the base parser, eating its output
+ * add [rclone uploader](https://github.com/9001/copyparty/blob/hovudstraum/bin/mtag/rclone-upload.py) which optionally and by default depends on vidchk
+
+## bugfixes
+* sfx would crash if it got the same PID as recently (for example across two reboots)
+* audio equalizer on recent chromes
+ * still can't figure out why chrome sometimes drops the mediasession
+* bbox: don't attach click events to videos
+* up2k.py:
+ * more sensible behavior w/ blank files
+ * avoid some extra directory scans when deleting files
+ * faster shutdown on `ctrl-c` during volume indexing
+* warning from the thumbnail cleaner if the volume has no thumbnails
+* `>fixing py2 support` `>2022`
+
+## other changes
+* up2k.js:
+ * sends a summary of the upload queue to [the server log](https://github.com/9001/copyparty#up2k)
+ * shows a toast while loading huge filedrops to indicate it's still alive
+* sfx: disable guru meditation unless running on windows
+ * avoids hanging systemd on certain crashes
+* logs the state of all threads if sqlite hits a timeout
+
+
+
+▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
+# 2022-0706-0029 `v1.3.5` sup cloudflare
+
+* read-only demo server at https://a.ocv.me/pub/demo/
+* latest gzip edition of the sfx: [v1.0.14](https://github.com/9001/copyparty/releases/tag/v1.0.14#:~:text=release-specific%20notes)
+
+## new features
+* detect + recover from cloudflare ddos-protection memes during upload
+ * while carefully avoiding any mention of "DDoS" in the JS because enterprise firewalls do not enjoy that
+* new option `--favico` to specify a default favicon
+ * set to `🎉` by default, which also enables the fancy upload progress donut 👌
+* baguettebox (image/video viewer):
+ * toolbar button `⛶` to enter fullscreen mode (same as hotkey `F`)
+ * tap middle of screen to show/hide toolbar
+ * tap left/right-side of pics to navigate prev/next
+ * hotkeys `[` and `]` to set A-B loop in videos
+ * and [URL parameters](https://a.ocv.me/pub/demo/pics-vids/#gf-e2e482ae&t=4.2-6) for that + [initial seekpoint](https://a.ocv.me/pub/demo/pics-vids/#gf-c04bb0f6&t=26s) (same as the audio player)
+
+## bugfixes
+* when a tag-parser hits the timeout, `pkill` all its descendants too
+ * and a [new mtp flag](https://github.com/9001/copyparty/#file-parser-plugins) to override that; `kt` (kill tree, default), `km` (kill main, old default), `kn` (kill none)
+* cpu-wasting spin while waiting for the final handful of files to finish tag-scraping
+* detection of sparse-files support inside [prisonparty](https://github.com/9001/copyparty/tree/hovudstraum/bin#prisonpartysh) and other strict jails
+* baguettebox (image/video viewer):
+ * crash on swipe during close
+* didn't reset terminal color at the end of `?ls=v`
+* don't try to thumbnail empty files (harmless but dumb)
+
+## other changes
+* ux improvements
+ * hide the uploads table until something happens
+* bump codemirror to 5.65.6
+
+
+
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
# 2022-0627-2057 `v1.3.3` sdcardfs
diff --git a/tests/util.py b/tests/util.py
index 33654a2e..000244db 100644
--- a/tests/util.py
+++ b/tests/util.py
@@ -94,7 +94,7 @@ class Cfg(Namespace):
def __init__(self, a=None, v=None, c=None):
ka = {}
- ex = "e2d e2ds e2dsa e2t e2ts e2tsr e2v e2vu e2vp ed emp force_js ihead no_acode no_athumb no_del no_logues no_mv no_readme no_robots no_scandir no_thumb no_vthumb no_zip nid nih nw"
+ ex = "e2d e2ds e2dsa e2t e2ts e2tsr e2v e2vu e2vp xdev xvol ed emp force_js ihead no_acode no_athumb no_del no_logues no_mv no_readme no_robots no_scandir no_thumb no_vthumb no_zip nid nih nw"
ka.update(**{k: False for k in ex.split()})
ex = "no_rescan no_sendfile no_voldump"