Skip to content

enh(relay): send the relay API a path relative to the camera dir - #3379

Open
JamBalaya56562 wants to merge 1 commit into
motioneye-project:devfrom
JamBalaya56562:enh/relay-relative-path
Open

enh(relay): send the relay API a path relative to the camera dir#3379
JamBalaya56562 wants to merge 1 commit into
motioneye-project:devfrom
JamBalaya56562:enh/relay-relative-path

Conversation

@JamBalaya56562

Copy link
Copy Markdown
Contributor

What

Make the relay-event API receive a path relative to the camera dir instead of the absolute %f path motion passes. relayevent.sh strips the camera dir before posting, so the validation-oriented path slicing in relay_event.py and mediafiles.make_movie_preview is no longer needed.

Implements the idea @MichaIng raised in #3374 ("I would actually prefer if the API itself would take a relative path ... split off the camera dir in relayevent.sh").

How

  • scripts/relayevent.sh — takes an optional camera_dir arg and strips it from the filename (${filename#"$camera_dir"/}). Guarded against an empty/non-matching value, so a stale absolute path is left untouched and still validated server-side.
  • config.py — the generated on_movie_end / on_picture_save commands now pass the camera's target_dir (single-quoted) as that argument. target_dir is already known where the command is built; motion has no conversion specifier for it.
  • handlers/relay_event.py — the incoming filename is now relative. remove_prefix still tolerates a legacy absolute path (un-regenerated motion config), then it's validated directly. The absolute path is reconstructed only for the upload call, so the upload subsystem is unchanged.
  • mediafiles.make_movie_preview — now takes a relative path, validates it, and reconstructs the absolute path internally; get_media_preview passes the relative path it already had (dropping a redundant os.path.join).

Scope / not included

The upload services (UploadService.upload_file, incl. the S3 override) still receive an absolute path and keep deriving the cloud-relative name themselves — that derivation is cloud-path naming tied to @upload_subfolders, a separate concern from the validation slicing this PR removes. Relativizing it (and the broader "every API endpoint takes relative paths") would be a follow-up. Builds on the now-merged #3374 (utils.remove_prefix).

Testing

  • Full suite green in a Linux container: 128 passed.
  • tests/test_mediafiles.py: the make_movie_preview traversal/escape validation tests now pass relative malicious paths (the form the API actually receives); added a test asserting the absolute path is reconstructed (os.path.join(target_dir, rel_path)) for ffmpeg.
  • shellcheck -o all passes on relayevent.sh; verified the prefix-strip with a shell harness (matching prefix → relative, non-matching → unchanged, spaces handled, empty camera_dir → no bare-slash strip).
  • ruff check / ruff format --check pass.
  • Note: an end-to-end run (real motion + camera) wasn't possible in my environment.

@JamBalaya56562
JamBalaya56562 force-pushed the enh/relay-relative-path branch 2 times, most recently from 8b9953d to 9f3e441 Compare June 30, 2026 22:53
motion calls relayevent.sh with its %f specifier (an absolute path), so
the relay-event API received an absolute filename that every consumer had
to strip the camera dir back off for validation. Following @MichaIng's
suggestion in motioneye-project#3374, relayevent.sh now strips the camera dir (passed as a
new argument from the generated motion config), so the API receives a
path relative to the camera dir.

- relayevent.sh: new optional camera_dir arg; POSIX prefix strip (a no-op
  when empty or non-matching, so a stale absolute path still validates).
- config.py: append the camera target_dir to the on_movie_end /
  on_picture_save commands.
- relay_event.py: the filename is now relative (remove_prefix still
  tolerates a legacy absolute path); validate it directly and reconstruct
  the absolute path only for the upload subsystem, which is unchanged.
- mediafiles.make_movie_preview: take a relative path, validate it and
  reconstruct the absolute path internally; the other caller
  (get_media_preview) now passes the relative path it already has.
- tests: the make_movie_preview validation tests use relative paths; add a
  test that the absolute path is reconstructed.

The upload services (incl. S3) still receive an absolute path and keep
deriving the cloud-relative name themselves; relativizing that is a
separate upload-subsystem change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@JamBalaya56562
JamBalaya56562 force-pushed the enh/relay-relative-path branch from 9f3e441 to 0e11ca7 Compare July 15, 2026 20:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant