PreviewError subclasses carry a concise short label for UI, a full log
message, backend name, and metadata fields (OnlyOffice code/status/url,
backend stage, timeout seconds, cancel reason). Exceptions travel across
the worker pool wire pickled in the binary response payload (ok=False)
and are re-raised with their original type on the caller side. Combined
pipelines such as pdf+pyvips tag the failing stage.
Add fixtures and tests covering image EXIF orientations, HDR AVIF, SDR video, 90/270 rotated video, HDR video with and without rotation, PDF, dispatch, and OnlyOffice (skipped unless configured).
Regenerate rotated/HDR video fixtures and sample.pdf with tests/files/generate_fixtures.py.
- Accept a keyframe with pts as well as dts, so all-intra or short HDR clips are not rejected as No frames found.
- Round resized video dimensions to multiples of 2 (width) and 4 (height) so planar 4:2:0 YUV rotation always works.
- Use abs(frame.rotation) when swapping display dimensions, so both +90 and -90 rotation matrices report the correct orientation.
- __main__ is now a self-contained docopt CLI going straight to
backends.dispatch (no blake3/tracerite needed); 'oosetup' builds and
starts the bundled OnlyOffice container and prints
ONLYOFFICE_JWT_SECRET=<token> as its only stdout line
- dispatch: log a plain one-line error for missing-extra ImportErrors
instead of a traceback
- worker/pool: friendly install hints when the 'worker' extra is missing
- office: fix import on Python 3.11-3.13 without the 'office' extra
(lazy annotations); setup_docker returns the JWT secret used and
redacts it from the logged docker command
- add 'mediapreview' console script and docopt-ng dependency