refactor: consolidate metadata normalization into domain layer

- Add expand_metadata_aliases() for concept fan-out (series→5, author→2,
  description→2, tags→3 keys)
- Replace _normalize_metadata_tags in webui/service.py with
  normalize_metadata_map from domain
- Replace _normalize_metadata in epub3/exporter.py with
  normalize_metadata_map from domain
- Replace manual fan-out in form.py with expand_metadata_aliases()
- Rewrite metadata_overrides.py to use expand_metadata_aliases()
- Remove unused normalize_metadata_casefold import from exporters.py
- 19 new tests for expand_metadata_aliases (1528 total)
This commit is contained in:
Artem Akymenko
2026-07-30 13:04:44 +00:00
parent 464bf8e17d
commit 2d18501839
7 changed files with 212 additions and 117 deletions
+2 -10
View File
@@ -12,6 +12,7 @@ from typing import Any, Dict, Iterable, List, Optional, Pattern, Sequence, Tuple
import zipfile
from abogen.text_extractor import ExtractedChapter, ExtractionResult
from abogen.domain.metadata_helpers import normalize_metadata_map
@dataclass(slots=True)
@@ -59,7 +60,7 @@ class EPUB3PackageBuilder:
self.output_path = output_path
self.book_id = book_id or str(uuid.uuid4())
self.extraction = extraction
self.metadata_tags = _normalize_metadata(metadata_tags)
self.metadata_tags = normalize_metadata_map(metadata_tags)
self.chapter_markers = list(chapter_markers or [])
self.chunk_markers = list(chunk_markers or [])
self.chunks = list(chunks or [])
@@ -550,15 +551,6 @@ class ChunkLookup:
by_chapter: Dict[int, List[Dict[str, Any]]]
def _normalize_metadata(metadata: Optional[Dict[str, Any]]) -> Dict[str, str]:
normalized: Dict[str, str] = {}
for key, value in (metadata or {}).items():
if value is None:
continue
normalized[str(key).lower()] = str(value)
return normalized
def _combine_metadata(*sources: Dict[str, Any]) -> Dict[str, str]:
combined: Dict[str, str] = {}
for source in sources: