feat: release parser, media type detection, ffprobe integration

Replace the old domain/media release parser with a full rewrite under
domain/release/:
- ParsedRelease with media_type ("movie" | "tv_show" | "tv_complete" |
  "documentary" | "concert" | "other" | "unknown"), site_tag, parse_path,
  languages, audio_codec, audio_channels, bit_depth, hdr_format, edition
- Well-formedness check + sanitize pipeline (_is_well_formed, _sanitize,
  _strip_site_tag) before token-level parsing
- Multi-token sequence matching for audio (DTS-HD.MA, TrueHD.Atmos…),
  HDR (DV.HDR10…) and editions (DIRECTORS.CUT…)
- Knowledge YAML: file_extensions, release_format, languages, audio,
  video, editions, sites/c411

New infrastructure:
- ffprobe.py — single-pass probe returning MediaInfo (video, audio
  tracks, subtitle tracks)
- find_video.py — locate first video file in a release folder

New application helpers:
- detect_media_type — filesystem-based type refinement
- enrich_from_probe — fill missing ParsedRelease fields from MediaInfo

New agent tools:
- analyze_release — parse + detect type + ffprobe in one call
- probe_media — standalone ffprobe for a specific file

New domain value object:
- MediaInfo + AudioTrack + SubtitleTrack (domain/shared/media_info.py)

Testing CLIs:
- recognize_folders_in_downloads.py — full pipeline with colored output
- probe_video.py — display MediaInfo for a video file
This commit is contained in:
2026-05-12 16:14:20 +02:00
parent 249c5de76a
commit 1723b9fa53
32 changed files with 2323 additions and 562 deletions
+4 -8
View File
@@ -1,5 +1,5 @@
"""
Tests for alfred.domain.media.release_parser
Tests for alfred.domain.release.release_parser
Real-data cases sourced from /mnt/testipool/downloads/.
Covers: parsing, normalisation, naming methods, edge cases.
@@ -7,13 +7,9 @@ Covers: parsing, normalisation, naming methods, edge cases.
import pytest
from alfred.domain.media.release_parser import (
ParsedRelease,
_normalise,
_sanitise_for_fs,
_strip_episode_from_normalised,
parse_release,
)
from alfred.domain.release import ParsedRelease, parse_release
from alfred.domain.release.services import _normalise
from alfred.domain.release.value_objects import _sanitise_for_fs, _strip_episode_from_normalised
# ---------------------------------------------------------------------------