Files
alfred/domain/movies/entities.py
Francwa 2c8cdd3ab1 New archi: domain driven development
Working but need to check out code
2025-12-01 07:10:03 +01:00

87 lines
2.9 KiB
Python

"""Movie domain entities."""
from dataclasses import dataclass, field
from typing import Optional
from datetime import datetime
from ..shared.value_objects import ImdbId, FilePath, FileSize
from .value_objects import MovieTitle, ReleaseYear, Quality
@dataclass
class Movie:
"""
Movie entity representing a movie in the media library.
This is the main aggregate root for the movies domain.
"""
imdb_id: ImdbId
title: MovieTitle
release_year: Optional[ReleaseYear] = None
quality: Quality = Quality.UNKNOWN
file_path: Optional[FilePath] = None
file_size: Optional[FileSize] = None
tmdb_id: Optional[int] = None
overview: Optional[str] = None
poster_path: Optional[str] = None
vote_average: Optional[float] = None
added_at: datetime = field(default_factory=datetime.now)
def __post_init__(self):
"""Validate movie entity."""
# Ensure ImdbId is actually an ImdbId instance
if not isinstance(self.imdb_id, ImdbId):
if isinstance(self.imdb_id, str):
object.__setattr__(self, 'imdb_id', ImdbId(self.imdb_id))
else:
raise ValueError(f"imdb_id must be ImdbId or str, got {type(self.imdb_id)}")
# Ensure MovieTitle is actually a MovieTitle instance
if not isinstance(self.title, MovieTitle):
if isinstance(self.title, str):
object.__setattr__(self, 'title', MovieTitle(self.title))
else:
raise ValueError(f"title must be MovieTitle or str, got {type(self.title)}")
def has_file(self) -> bool:
"""Check if the movie has an associated file."""
return self.file_path is not None and self.file_path.exists()
def is_downloaded(self) -> bool:
"""Check if the movie is downloaded (has a file)."""
return self.has_file()
def get_folder_name(self) -> str:
"""
Get the folder name for this movie.
Format: "Title (Year)"
Example: "Inception (2010)"
"""
if self.release_year:
return f"{self.title.value} ({self.release_year.value})"
return self.title.value
def get_filename(self) -> str:
"""
Get the suggested filename for this movie.
Format: "Title.Year.Quality.ext"
Example: "Inception.2010.1080p.mkv"
"""
parts = [self.title.normalized()]
if self.release_year:
parts.append(str(self.release_year.value))
if self.quality != Quality.UNKNOWN:
parts.append(self.quality.value)
# Extension will be added based on actual file
return ".".join(parts)
def __str__(self) -> str:
return f"{self.title.value} ({self.release_year.value if self.release_year else 'Unknown'})"
def __repr__(self) -> str:
return f"Movie(imdb_id={self.imdb_id}, title='{self.title.value}')"