mirror of
https://github.com/Benexl/FastAnime.git
synced 2026-01-03 16:27:38 -08:00
- Added WatchHistoryManager for managing local watch history storage, including methods for adding, updating, removing, and retrieving entries. - Introduced WatchHistoryTracker to automatically track episode viewing and progress updates. - Created data models for watch history entries and overall history management, including serialization to and from JSON. - Implemented comprehensive error handling and logging throughout the system. - Developed a test script to validate the functionality of the watch history management system, covering basic operations and statistics.
108 lines
4.3 KiB
Python
108 lines
4.3 KiB
Python
from typing import TYPE_CHECKING
|
|
|
|
import click
|
|
from rich.console import Console
|
|
|
|
from ..session import Context, session
|
|
from ..state import ControlFlow, ProviderState, State
|
|
|
|
|
|
@session.menu
|
|
def episodes(ctx: Context, state: State) -> State | ControlFlow:
|
|
"""
|
|
Displays available episodes for a selected provider anime and handles
|
|
the logic for continuing from watch history or manual selection.
|
|
"""
|
|
provider_anime = state.provider.anime
|
|
anilist_anime = state.media_api.anime
|
|
config = ctx.config
|
|
console = Console()
|
|
console.clear()
|
|
|
|
if not provider_anime or not anilist_anime:
|
|
console.print("[bold red]Error: Anime details are missing.[/bold red]")
|
|
return ControlFlow.BACK
|
|
|
|
# Get the list of episode strings based on the configured translation type
|
|
available_episodes = getattr(
|
|
provider_anime.episodes, config.stream.translation_type, []
|
|
)
|
|
if not available_episodes:
|
|
console.print(
|
|
f"[bold yellow]No '{config.stream.translation_type}' episodes found for this anime.[/bold yellow]"
|
|
)
|
|
return ControlFlow.BACK
|
|
|
|
chosen_episode: str | None = None
|
|
|
|
if config.stream.continue_from_watch_history:
|
|
# Use our new watch history system
|
|
from ...utils.watch_history_tracker import get_continue_episode, track_episode_viewing
|
|
|
|
# Try to get continue episode from watch history
|
|
if config.stream.preferred_watch_history == "local":
|
|
chosen_episode = get_continue_episode(anilist_anime, available_episodes, prefer_history=True)
|
|
if chosen_episode:
|
|
click.echo(
|
|
f"[cyan]Continuing from local watch history. Auto-selecting episode {chosen_episode}.[/cyan]"
|
|
)
|
|
|
|
# Fallback to AniList progress if local history doesn't have info or preference is remote
|
|
if not chosen_episode and config.stream.preferred_watch_history == "remote":
|
|
progress = (
|
|
anilist_anime.user_status.progress
|
|
if anilist_anime.user_status and anilist_anime.user_status.progress
|
|
else 0
|
|
)
|
|
|
|
# Calculate the next episode based on progress
|
|
next_episode_num = str(progress + 1)
|
|
|
|
if next_episode_num in available_episodes:
|
|
click.echo(
|
|
f"[cyan]Continuing from AniList history. Auto-selecting episode {next_episode_num}.[/cyan]"
|
|
)
|
|
chosen_episode = next_episode_num
|
|
else:
|
|
# If the next episode isn't available, fall back to the last watched one
|
|
last_watched_num = str(progress)
|
|
if last_watched_num in available_episodes:
|
|
click.echo(
|
|
f"[cyan]Next episode ({next_episode_num}) not found. Falling back to last watched episode {last_watched_num}.[/cyan]"
|
|
)
|
|
chosen_episode = last_watched_num
|
|
else:
|
|
click.echo(
|
|
f"[yellow]Could not find episode based on your watch history. Please select manually.[/yellow]"
|
|
)
|
|
|
|
if not chosen_episode:
|
|
choices = [*sorted(available_episodes, key=float), "Back"]
|
|
|
|
# TODO: Implement FZF/Rofi preview for episode thumbnails if available
|
|
# preview_command = get_episode_preview(...)
|
|
|
|
chosen_episode_str = ctx.selector.choose(
|
|
prompt="Select Episode", choices=choices
|
|
)
|
|
|
|
if not chosen_episode_str or chosen_episode_str == "Back":
|
|
return ControlFlow.BACK
|
|
|
|
chosen_episode = chosen_episode_str
|
|
|
|
# Track episode selection in watch history (if enabled in config)
|
|
if config.stream.continue_from_watch_history and config.stream.preferred_watch_history == "local":
|
|
from ...utils.watch_history_tracker import track_episode_viewing
|
|
try:
|
|
episode_num = int(chosen_episode)
|
|
track_episode_viewing(anilist_anime, episode_num, start_tracking=True)
|
|
except (ValueError, AttributeError):
|
|
pass # Skip tracking if episode number is invalid
|
|
|
|
return State(
|
|
menu_name="SERVERS",
|
|
media_api=state.media_api,
|
|
provider=state.provider.model_copy(update={"episode_number": chosen_episode}),
|
|
)
|