From 903e9e7117b5ea6bb33e4cef5f281e6d979fbfa4 Mon Sep 17 00:00:00 2001 From: Francwa Date: Tue, 19 May 2026 15:07:39 +0200 Subject: [PATCH] refactor(subtitles): move SubtitlePlacer to application layer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The placer performs filesystem I/O (os.link) — it belongs in the application layer, not the domain. Domain services should be pure. - Move alfred/domain/subtitles/services/placer.py to alfred/application/subtitles/placer.py - Move tests/domain/test_subtitle_placer.py to tests/application/test_subtitle_placer.py - Update all callers (manage_subtitles use case, metadata store, tests) - Drop placer re-exports from domain.subtitles.services.__init__ --- alfred/application/filesystem/manage_subtitles.py | 2 +- alfred/application/subtitles/__init__.py | 0 .../subtitles/services => application/subtitles}/placer.py | 4 ++-- alfred/domain/subtitles/services/__init__.py | 4 ---- alfred/infrastructure/subtitle/metadata_store.py | 2 +- tests/application/test_manage_subtitles.py | 2 +- tests/{domain => application}/test_subtitle_placer.py | 6 +++--- tests/infrastructure/test_subtitle_metadata_store.py | 2 +- 8 files changed, 9 insertions(+), 13 deletions(-) create mode 100644 alfred/application/subtitles/__init__.py rename alfred/{domain/subtitles/services => application/subtitles}/placer.py (96%) rename tests/{domain => application}/test_subtitle_placer.py (97%) diff --git a/alfred/application/filesystem/manage_subtitles.py b/alfred/application/filesystem/manage_subtitles.py index 66a68b9..4c199b4 100644 --- a/alfred/application/filesystem/manage_subtitles.py +++ b/alfred/application/filesystem/manage_subtitles.py @@ -8,7 +8,7 @@ from alfred.domain.subtitles.entities import SubtitleCandidate from alfred.domain.subtitles.services.identifier import SubtitleIdentifier from alfred.domain.subtitles.services.matcher import SubtitleMatcher from alfred.domain.subtitles.services.pattern_detector import PatternDetector -from alfred.domain.subtitles.services.placer import ( +from alfred.application.subtitles.placer import ( PlacedTrack, SubtitlePlacer, _build_dest_name, diff --git a/alfred/application/subtitles/__init__.py b/alfred/application/subtitles/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/alfred/domain/subtitles/services/placer.py b/alfred/application/subtitles/placer.py similarity index 96% rename from alfred/domain/subtitles/services/placer.py rename to alfred/application/subtitles/placer.py index 584fc59..1f90100 100644 --- a/alfred/domain/subtitles/services/placer.py +++ b/alfred/application/subtitles/placer.py @@ -5,8 +5,8 @@ import os from dataclasses import dataclass from pathlib import Path -from ..entities import SubtitleCandidate -from ..value_objects import SubtitleType +from alfred.domain.subtitles.entities import SubtitleCandidate +from alfred.domain.subtitles.value_objects import SubtitleType logger = logging.getLogger(__name__) diff --git a/alfred/domain/subtitles/services/__init__.py b/alfred/domain/subtitles/services/__init__.py index a429b25..f743df1 100644 --- a/alfred/domain/subtitles/services/__init__.py +++ b/alfred/domain/subtitles/services/__init__.py @@ -1,13 +1,9 @@ from .identifier import SubtitleIdentifier from .matcher import SubtitleMatcher from .pattern_detector import PatternDetector -from .placer import PlacedTrack, PlaceResult, SubtitlePlacer __all__ = [ "SubtitleIdentifier", "SubtitleMatcher", "PatternDetector", - "SubtitlePlacer", - "PlacedTrack", - "PlaceResult", ] diff --git a/alfred/infrastructure/subtitle/metadata_store.py b/alfred/infrastructure/subtitle/metadata_store.py index e18f0cd..f2f3773 100644 --- a/alfred/infrastructure/subtitle/metadata_store.py +++ b/alfred/infrastructure/subtitle/metadata_store.py @@ -14,7 +14,7 @@ from pathlib import Path from typing import Any from alfred.domain.subtitles.entities import SubtitleCandidate -from alfred.domain.subtitles.services.placer import PlacedTrack +from alfred.application.subtitles.placer import PlacedTrack from alfred.infrastructure.metadata.store import MetadataStore logger = logging.getLogger(__name__) diff --git a/tests/application/test_manage_subtitles.py b/tests/application/test_manage_subtitles.py index 29c6f76..c4aed58 100644 --- a/tests/application/test_manage_subtitles.py +++ b/tests/application/test_manage_subtitles.py @@ -41,7 +41,7 @@ from alfred.application.filesystem.manage_subtitles import ( _to_unresolved_dto, ) from alfred.domain.subtitles.entities import MediaSubtitleMetadata, SubtitleCandidate -from alfred.domain.subtitles.services.placer import PlacedTrack, PlaceResult +from alfred.application.subtitles.placer import PlacedTrack, PlaceResult from alfred.domain.subtitles.value_objects import ( ScanStrategy, SubtitleFormat, diff --git a/tests/domain/test_subtitle_placer.py b/tests/application/test_subtitle_placer.py similarity index 97% rename from tests/domain/test_subtitle_placer.py rename to tests/application/test_subtitle_placer.py index 0746435..aecb1f0 100644 --- a/tests/domain/test_subtitle_placer.py +++ b/tests/application/test_subtitle_placer.py @@ -1,4 +1,4 @@ -"""Tests for ``alfred.domain.subtitles.services.placer.SubtitlePlacer``. +"""Tests for ``alfred.application.subtitles.placer.SubtitlePlacer``. The placer hard-links subtitle files next to a destination video, naming them ``{video_stem}.{lang}[.sdh|.forced].{ext}``. @@ -22,7 +22,7 @@ from unittest.mock import patch import pytest from alfred.domain.subtitles.entities import SubtitleCandidate -from alfred.domain.subtitles.services.placer import ( +from alfred.application.subtitles.placer import ( PlacedTrack, PlaceResult, SubtitlePlacer, @@ -198,7 +198,7 @@ class TestOSError: video.write_bytes(b"") track = _track(src) with patch( - "alfred.domain.subtitles.services.placer.os.link", + "alfred.application.subtitles.placer.os.link", side_effect=OSError("cross-device link"), ): result = placer.place([track], video) diff --git a/tests/infrastructure/test_subtitle_metadata_store.py b/tests/infrastructure/test_subtitle_metadata_store.py index 716af12..83a6233 100644 --- a/tests/infrastructure/test_subtitle_metadata_store.py +++ b/tests/infrastructure/test_subtitle_metadata_store.py @@ -17,7 +17,7 @@ from __future__ import annotations from pathlib import Path from alfred.domain.subtitles.entities import SubtitleCandidate -from alfred.domain.subtitles.services.placer import PlacedTrack +from alfred.application.subtitles.placer import PlacedTrack from alfred.domain.subtitles.value_objects import ( SubtitleFormat, SubtitleLanguage,