From aa1ea03bedd8c8641268af1a8892862ae6fd4614 Mon Sep 17 00:00:00 2001 From: Leo Vasanko Date: Wed, 13 Aug 2025 10:15:22 -0700 Subject: [PATCH] Fix running with today's Python tooling and av module. --- cista/preview.py | 34 ++++++++++++++++++++++++++++------ pyproject.toml | 15 +++++++++------ 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/cista/preview.py b/cista/preview.py index a595057..c37a4a4 100644 --- a/cista/preview.py +++ b/cista/preview.py @@ -18,8 +18,6 @@ from sanic.log import logger from cista import config from cista.util.filename import sanitize -DISPLAYMATRIX = av.stream.SideData.DISPLAYMATRIX - bp = Blueprint("preview", url_prefix="/preview") @@ -100,15 +98,39 @@ def process_video(path, *, maxsize, quality): with av.open(str(path)) as container: stream = container.streams.video[0] stream.codec_context.skip_frame = "NONKEY" - rot = stream.side_data and stream.side_data.get(DISPLAYMATRIX) or 0 + + # Updated side data access for newer av versions + rot = 0 + try: + # Try newer API first + if hasattr(stream, "side_data") and stream.side_data: + display_matrix = stream.side_data.get("DISPLAYMATRIX") + if display_matrix: + rot = ( + display_matrix.rotation + if hasattr(display_matrix, "rotation") + else 0 + ) + except (AttributeError, KeyError): + # Fallback for older API or missing side data + rot = 0 + container.seek(container.duration // 8) - img = next(container.decode(stream)).to_image() + try: + frame = next(container.decode(stream)) + img = frame.to_image() + except StopIteration: + # If no frame found, try from beginning + container.seek(0) + frame = next(container.decode(stream)) + img = frame.to_image() + del stream img.thumbnail((maxsize, maxsize)) imgdata = io.BytesIO() - if rot: - img = img.rotate(rot, expand=True) + if rot and rot != 0: + img = img.rotate(-rot, expand=True) # Negative rotation for correct orientation img.save(imgdata, format="webp", quality=quality, method=4) del img ret = imgdata.getvalue() diff --git a/pyproject.toml b/pyproject.toml index 64fb3eb..401c9f1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,6 +15,7 @@ classifiers = [ requires-python = ">=3.11" dependencies = [ "argon2-cffi", + "av", "blake3", "brotli", "docopt", @@ -23,7 +24,6 @@ dependencies = [ "natsort", "pathvalidate", "pillow", - "pyav", "pyjwt", "pymupdf", "sanic", @@ -50,15 +50,15 @@ source = "vcs" [tool.hatch.build] artifacts = ["cista/wwwroot"] targets.sdist.hooks.custom.path = "scripts/build-frontend.py" +targets.sdist.include = [ + "/cista", +] hooks.vcs.version-file = "cista/_version.py" hooks.vcs.template = """ # This file is automatically generated by hatch build. __version__ = {version!r} """ only-packages = true -targets.sdist.include = [ - "/cista", -] [tool.pytest.ini_options] addopts = [ @@ -95,11 +95,14 @@ ignore = [ "TD0", "TRY", ] -show-source = true -show-fixes = true [tool.ruff.isort] known-first-party = ["cista"] [tool.ruff.per-file-ignores] "tests/*" = ["S", "ANN", "D", "INP"] + +[dependency-groups] +dev = [ + "pytest>=8.4.1", +]