Files
FastAnime/fastanime/cli/interactive/session.py
2025-07-06 23:59:18 +03:00

101 lines
3.4 KiB
Python

from __future__ import annotations
import logging
from typing import TYPE_CHECKING, Optional
from pydantic import BaseModel, Field
if TYPE_CHECKING:
from ...core.config import AppConfig
from ...libs.api.base import BaseApiClient
from ...libs.api.types import Anime, SearchResult, Server, UserProfile
from ...libs.players.base import BasePlayer
from ...libs.selector.base import BaseSelector
logger = logging.getLogger(__name__)
# --- Nested State Models (Unchanged) ---
class AnilistState(BaseModel):
results_data: Optional[dict] = None
selected_anime: Optional[dict] = (
None # Using dict for AnilistBaseMediaDataSchema for now
)
class ProviderState(BaseModel):
selected_search_result: Optional[SearchResult] = None
anime_details: Optional[Anime] = None
current_episode: Optional[str] = None
current_server: Optional[Server] = None
class Config:
arbitrary_types_allowed = True
class NavigationState(BaseModel):
current_page: int = 1
history_stack_class_names: list[str] = Field(default_factory=list)
class TrackingState(BaseModel):
progress_mode: str = "prompt"
class SessionState(BaseModel):
anilist: AnilistState = Field(default_factory=AnilistState)
provider: ProviderState = Field(default_factory=ProviderState)
navigation: NavigationState = Field(default_factory=NavigationState)
tracking: TrackingState = Field(default_factory=TrackingState)
class Config:
arbitrary_types_allowed = True
class Session:
def __init__(self, config: AppConfig) -> None:
self.config: AppConfig = config
self.state: SessionState = SessionState()
self.is_running: bool = True
self.user_profile: Optional[UserProfile] = None
self._initialize_components()
def _initialize_components(self) -> None:
from ...cli.auth.manager import CredentialsManager
from ...libs.api.factory import create_api_client
from ...libs.players import create_player
from ...libs.selector import create_selector
logger.debug("Initializing session components...")
self.selector: BaseSelector = create_selector(self.config)
self.provider: AnimeProvider = create_provider(self.config.general.provider)
self.player: BasePlayer = create_player(self.config.stream.player, self.config)
# Instantiate and use the API factory
self.api_client: BaseApiClient = create_api_client("anilist", self.config)
# Load credentials and authenticate the API client
manager = CredentialsManager()
user_data = manager.load_user_profile()
if user_data and (token := user_data.get("token")):
self.user_profile = self.api_client.authenticate(token)
if not self.user_profile:
logger.warning(
"Loaded token is invalid or expired. User is not logged in."
)
def change_provider(self, provider_name: str) -> None:
from ...libs.anime.provider import create_provider
self.config.general.provider = provider_name
self.provider = create_provider(provider_name)
def change_player(self, player_name: str) -> None:
from ...libs.players import create_player
self.config.stream.player = player_name
self.player = create_player(player_name, self.config)
def stop(self) -> None:
self.is_running = False