refactor(knowledge): extract YAML loaders from domain to infrastructure

The domain layer no longer reads YAML files. All knowledge loaders move
from `alfred/domain/*/knowledge/` to `alfred/infrastructure/knowledge/`:

  domain/release/knowledge.py
    → infrastructure/knowledge/release.py
  domain/shared/knowledge/language_registry.py
    → infrastructure/knowledge/language_registry.py
  domain/subtitles/knowledge/{loader,base}.py
    → infrastructure/knowledge/subtitles/{loader,base}.py

Callers in domain/release/{services,value_objects}.py,
domain/subtitles/{aggregates,services/*}.py, and
application/filesystem/manage_subtitles.py updated to absolute imports.
Re-exports of KnowledgeLoader/SubtitleKnowledgeBase from
domain/subtitles/__init__.py dropped (no shim per project convention).
Tests follow the moved targets.
This commit is contained in:
2026-05-19 14:35:18 +02:00
parent f338b08706
commit ced72547f7
17 changed files with 25 additions and 24 deletions
@@ -5,8 +5,8 @@ from pathlib import Path
from alfred.domain.shared.value_objects import ImdbId from alfred.domain.shared.value_objects import ImdbId
from alfred.domain.subtitles.entities import SubtitleCandidate from alfred.domain.subtitles.entities import SubtitleCandidate
from alfred.domain.subtitles.knowledge.base import SubtitleKnowledgeBase from alfred.infrastructure.knowledge.subtitles.base import SubtitleKnowledgeBase
from alfred.domain.subtitles.knowledge.loader import KnowledgeLoader from alfred.infrastructure.knowledge.subtitles.loader import KnowledgeLoader
from alfred.domain.subtitles.services.identifier import SubtitleIdentifier from alfred.domain.subtitles.services.identifier import SubtitleIdentifier
from alfred.domain.subtitles.services.matcher import SubtitleMatcher from alfred.domain.subtitles.services.matcher import SubtitleMatcher
from alfred.domain.subtitles.services.pattern_detector import PatternDetector from alfred.domain.subtitles.services.pattern_detector import PatternDetector
+1 -1
View File
@@ -4,7 +4,7 @@ from __future__ import annotations
import re import re
from .knowledge import load_separators from alfred.infrastructure.knowledge.release import load_separators
from .value_objects import ( from .value_objects import (
_AUDIO, _AUDIO,
_CODECS, _CODECS,
+1 -1
View File
@@ -6,7 +6,7 @@ from dataclasses import dataclass, field
from enum import Enum from enum import Enum
from ..shared.exceptions import ValidationError from ..shared.exceptions import ValidationError
from .knowledge import ( from alfred.infrastructure.knowledge.release import (
load_audio, load_audio,
load_codecs, load_codecs,
load_editions, load_editions,
@@ -1,5 +0,0 @@
"""Shared knowledge loaders (cross-domain)."""
from .language_registry import LanguageRegistry
__all__ = ["LanguageRegistry"]
-3
View File
@@ -3,7 +3,6 @@
from .aggregates import SubtitleRuleSet from .aggregates import SubtitleRuleSet
from .entities import MediaSubtitleMetadata, SubtitleCandidate from .entities import MediaSubtitleMetadata, SubtitleCandidate
from .exceptions import SubtitleNotFound from .exceptions import SubtitleNotFound
from .knowledge import KnowledgeLoader, SubtitleKnowledgeBase
from .services import PatternDetector, SubtitleIdentifier, SubtitleMatcher from .services import PatternDetector, SubtitleIdentifier, SubtitleMatcher
from .value_objects import ( from .value_objects import (
RuleScope, RuleScope,
@@ -20,8 +19,6 @@ __all__ = [
"SubtitleCandidate", "SubtitleCandidate",
"MediaSubtitleMetadata", "MediaSubtitleMetadata",
"SubtitleRuleSet", "SubtitleRuleSet",
"SubtitleKnowledgeBase",
"KnowledgeLoader",
"SubtitleIdentifier", "SubtitleIdentifier",
"SubtitleMatcher", "SubtitleMatcher",
"PatternDetector", "PatternDetector",
+2 -1
View File
@@ -3,8 +3,9 @@
from dataclasses import dataclass, field from dataclasses import dataclass, field
from typing import Any from typing import Any
from alfred.infrastructure.knowledge.subtitles.base import SubtitleKnowledgeBase
from ..shared.value_objects import ImdbId from ..shared.value_objects import ImdbId
from .knowledge.base import SubtitleKnowledgeBase
from .value_objects import RuleScope, SubtitleMatchingRules from .value_objects import RuleScope, SubtitleMatchingRules
@@ -6,9 +6,10 @@ import re
import subprocess import subprocess
from pathlib import Path from pathlib import Path
from alfred.infrastructure.knowledge.subtitles.base import SubtitleKnowledgeBase
from ...shared.value_objects import ImdbId from ...shared.value_objects import ImdbId
from ..entities import MediaSubtitleMetadata, SubtitleCandidate from ..entities import MediaSubtitleMetadata, SubtitleCandidate
from ..knowledge.base import SubtitleKnowledgeBase
from ..value_objects import ScanStrategy, SubtitlePattern, SubtitleType from ..value_objects import ScanStrategy, SubtitlePattern, SubtitleType
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -5,7 +5,8 @@ import logging
import subprocess import subprocess
from pathlib import Path from pathlib import Path
from ..knowledge.base import SubtitleKnowledgeBase from alfred.infrastructure.knowledge.subtitles.base import SubtitleKnowledgeBase
from ..value_objects import ScanStrategy, SubtitlePattern from ..value_objects import ScanStrategy, SubtitlePattern
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -0,0 +1,6 @@
"""Knowledge loaders — YAML I/O kept out of the domain layer.
Each submodule reads its YAML files from ``alfred/knowledge/`` (builtin,
versioned) and ``data/knowledge/`` (learned, gitignored), and exposes plain
Python values (sets, dicts, classes) for domain code to consume.
"""
@@ -13,7 +13,7 @@ import yaml
import alfred as _alfred_pkg import alfred as _alfred_pkg
from ..value_objects import Language from alfred.domain.shared.value_objects import Language
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -2,8 +2,8 @@
import logging import logging
from ...shared.knowledge.language_registry import LanguageRegistry from alfred.infrastructure.knowledge.language_registry import LanguageRegistry
from ..value_objects import ( from alfred.domain.subtitles.value_objects import (
ScanStrategy, ScanStrategy,
SubtitleFormat, SubtitleFormat,
SubtitleLanguage, SubtitleLanguage,
+1 -1
View File
@@ -23,7 +23,7 @@ from unittest.mock import patch
import pytest import pytest
from alfred.domain.subtitles.entities import SubtitleCandidate from alfred.domain.subtitles.entities import SubtitleCandidate
from alfred.domain.subtitles.knowledge.base import SubtitleKnowledgeBase from alfred.infrastructure.knowledge.subtitles.base import SubtitleKnowledgeBase
from alfred.domain.subtitles.services.identifier import ( from alfred.domain.subtitles.services.identifier import (
SubtitleIdentifier, SubtitleIdentifier,
_count_entries, _count_entries,
+4 -4
View File
@@ -1,4 +1,4 @@
"""Tests for ``alfred.domain.subtitles.knowledge`` (loader + base). """Tests for ``alfred.infrastructure.knowledge.subtitles`` (loader + base).
Covers: Covers:
@@ -19,9 +19,9 @@ from pathlib import Path
import pytest import pytest
from alfred.domain.subtitles.knowledge import loader as loader_mod from alfred.infrastructure.knowledge.subtitles import loader as loader_mod
from alfred.domain.subtitles.knowledge.base import SubtitleKnowledgeBase from alfred.infrastructure.knowledge.subtitles.base import SubtitleKnowledgeBase
from alfred.domain.subtitles.knowledge.loader import KnowledgeLoader, _merge from alfred.infrastructure.knowledge.subtitles.loader import KnowledgeLoader, _merge
from alfred.domain.subtitles.value_objects import ( from alfred.domain.subtitles.value_objects import (
ScanStrategy, ScanStrategy,
SubtitleType, SubtitleType,
@@ -25,7 +25,7 @@ from unittest.mock import patch
import pytest import pytest
from alfred.domain.subtitles.knowledge.base import SubtitleKnowledgeBase from alfred.infrastructure.knowledge.subtitles.base import SubtitleKnowledgeBase
from alfred.domain.subtitles.services.pattern_detector import PatternDetector from alfred.domain.subtitles.services.pattern_detector import PatternDetector