infra: reorganized repo
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
"""Subtitle domain services - Business logic."""
|
||||
|
||||
import logging
|
||||
|
||||
from ..shared.value_objects import FilePath, ImdbId
|
||||
from .entities import Subtitle
|
||||
from .exceptions import SubtitleNotFound
|
||||
from .repositories import SubtitleRepository
|
||||
from .value_objects import Language, SubtitleFormat
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SubtitleService:
|
||||
"""
|
||||
Domain service for subtitle-related business logic.
|
||||
|
||||
This service is SHARED between movies and TV shows domains.
|
||||
Both can use this service to manage subtitles.
|
||||
"""
|
||||
|
||||
def __init__(self, repository: SubtitleRepository):
|
||||
"""
|
||||
Initialize subtitle service.
|
||||
|
||||
Args:
|
||||
repository: Subtitle repository for persistence
|
||||
"""
|
||||
self.repository = repository
|
||||
|
||||
def add_subtitle(self, subtitle: Subtitle) -> None:
|
||||
"""
|
||||
Add a subtitle to the library.
|
||||
|
||||
Args:
|
||||
subtitle: Subtitle entity to add
|
||||
"""
|
||||
self.repository.save(subtitle)
|
||||
logger.info(
|
||||
f"Added subtitle: {subtitle.language.value} for {subtitle.media_imdb_id}"
|
||||
)
|
||||
|
||||
def find_subtitles_for_movie(
|
||||
self, imdb_id: ImdbId, languages: list[Language] | None = None
|
||||
) -> list[Subtitle]:
|
||||
"""
|
||||
Find subtitles for a movie.
|
||||
|
||||
Args:
|
||||
imdb_id: IMDb ID of the movie
|
||||
languages: Optional list of languages to filter by
|
||||
|
||||
Returns:
|
||||
List of matching subtitles
|
||||
"""
|
||||
if languages:
|
||||
all_subtitles = []
|
||||
for lang in languages:
|
||||
subs = self.repository.find_by_media(imdb_id, language=lang)
|
||||
all_subtitles.extend(subs)
|
||||
return all_subtitles
|
||||
else:
|
||||
return self.repository.find_by_media(imdb_id)
|
||||
|
||||
def find_subtitles_for_episode(
|
||||
self,
|
||||
imdb_id: ImdbId,
|
||||
season: int,
|
||||
episode: int,
|
||||
languages: list[Language] | None = None,
|
||||
) -> list[Subtitle]:
|
||||
"""
|
||||
Find subtitles for a TV show episode.
|
||||
|
||||
Args:
|
||||
imdb_id: IMDb ID of the TV show
|
||||
season: Season number
|
||||
episode: Episode number
|
||||
languages: Optional list of languages to filter by
|
||||
|
||||
Returns:
|
||||
List of matching subtitles
|
||||
"""
|
||||
if languages:
|
||||
all_subtitles = []
|
||||
for lang in languages:
|
||||
subs = self.repository.find_by_media(
|
||||
imdb_id, language=lang, season=season, episode=episode
|
||||
)
|
||||
all_subtitles.extend(subs)
|
||||
return all_subtitles
|
||||
else:
|
||||
return self.repository.find_by_media(
|
||||
imdb_id, season=season, episode=episode
|
||||
)
|
||||
|
||||
def remove_subtitle(self, subtitle: Subtitle) -> None:
|
||||
"""
|
||||
Remove a subtitle from the library.
|
||||
|
||||
Args:
|
||||
subtitle: Subtitle to remove
|
||||
|
||||
Raises:
|
||||
SubtitleNotFound: If subtitle not found
|
||||
"""
|
||||
if not self.repository.delete(subtitle):
|
||||
raise SubtitleNotFound(f"Subtitle not found: {subtitle}")
|
||||
|
||||
logger.info(f"Removed subtitle: {subtitle}")
|
||||
|
||||
def detect_format_from_file(self, file_path: FilePath) -> SubtitleFormat:
|
||||
"""
|
||||
Detect subtitle format from file extension.
|
||||
|
||||
Args:
|
||||
file_path: Path to subtitle file
|
||||
|
||||
Returns:
|
||||
Detected subtitle format
|
||||
"""
|
||||
extension = file_path.value.suffix
|
||||
return SubtitleFormat.from_extension(extension)
|
||||
|
||||
def validate_subtitle_file(self, file_path: FilePath) -> bool:
|
||||
"""
|
||||
Validate that a file is a valid subtitle file.
|
||||
|
||||
Args:
|
||||
file_path: Path to the file
|
||||
|
||||
Returns:
|
||||
True if valid subtitle file, False otherwise
|
||||
"""
|
||||
if not file_path.exists():
|
||||
logger.warning(f"File does not exist: {file_path}")
|
||||
return False
|
||||
|
||||
if not file_path.is_file():
|
||||
logger.warning(f"Path is not a file: {file_path}")
|
||||
return False
|
||||
|
||||
# Check file extension
|
||||
try:
|
||||
self.detect_format_from_file(file_path)
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.warning(f"Invalid subtitle format: {e}")
|
||||
return False
|
||||
Reference in New Issue
Block a user