diff --git a/flake.nix b/flake.nix index 648b3cc..6fed0c9 100644 --- a/flake.nix +++ b/flake.nix @@ -13,7 +13,7 @@ default = matebot; matebot = pkgs.python3Packages.buildPythonApplication { pname = "matebot"; - version = "0.3.0"; + version = "0.3.1"; pyproject = true; src = self; build-system = [ pkgs.python3Packages.hatchling ]; diff --git a/pyproject.toml b/pyproject.toml index 8423e84..a66f977 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "matebot" -version = "0.3.0" +version = "0.3.1" description = "The proactive companion for GaggiMate espresso machines: post-shot logging bot, .slog decoder, shot-journal site generator" readme = "README.md" license = "MIT" diff --git a/src/matebot/__init__.py b/src/matebot/__init__.py index 40bb6aa..3ed8784 100644 --- a/src/matebot/__init__.py +++ b/src/matebot/__init__.py @@ -1,3 +1,3 @@ """matebot — the proactive companion for GaggiMate espresso machines.""" -__version__ = "0.3.0" +__version__ = "0.3.1" diff --git a/src/matebot/commands.py b/src/matebot/commands.py index 71a880b..3cdff78 100644 --- a/src/matebot/commands.py +++ b/src/matebot/commands.py @@ -268,6 +268,18 @@ async def _cmd_vsync(self) -> None: f"🎬 Shot #{shot} video offset: {current:+.2f}s → {current + delta:+.2f}s. " "Journal updates on the next sync." ) + try: + from .render import RenderError, render_reel + + reel = await render_reel(self.config.data_repo, shot, title=f"Shot #{shot}") + try: + await self.messenger.send_video( + reel.read_bytes(), f"🎬 Shot #{shot} @ {current + delta:+.2f}s" + ) + finally: + reel.unlink(missing_ok=True) + except RenderError as exc: + log.info("no reel re-render for shot %06d: %s", shot, exc) async def _cmd_digest(self) -> None: text = await build_digest(self.client, self.config) diff --git a/src/matebot/render.py b/src/matebot/render.py index 61fb565..4bbfe5a 100644 --- a/src/matebot/render.py +++ b/src/matebot/render.py @@ -26,7 +26,6 @@ WIDTH = 720 CHART_H = 406 PLAYHEAD = "0xF0561D" # GaggiMate orange -TAIL_S = 2.0 class RenderError(Exception): @@ -61,7 +60,7 @@ async def render_reel(repo: str | Path, shot_id: int, *, title: str | None = Non delay = max(0.0, -offset) # video starts this long after chart t=0 trim = max(0.0, offset) # positive offset: drop the clip's head instead dur = geom["t_end"] # animate across the actual data range - total = dur + TAIL_S + total = dur # end exactly when the playhead reaches the end of the x axis # scale axis geometry from the rendered PNG to the reel's chart panel sx, sy = WIDTH / geom["img_w"], CHART_H / geom["img_h"] diff --git a/tests/test_render.py b/tests/test_render.py index 94bebb4..f889ef1 100644 --- a/tests/test_render.py +++ b/tests/test_render.py @@ -46,6 +46,7 @@ def test_positive_offset_trims_clip(repo, monkeypatch): out = asyncio.run(render.render_reel(repo, 4)) args = calls[0] assert args[args.index("-ss") + 1] == "0.60" + assert args[args.index("-t") + 1] == f"{GEOM['t_end']:.2f}" # ends at the x-axis end assert "adelay=0|0" in args[args.index("-filter_complex") + 1] assert out.read_bytes() == b"reel" out.unlink()