diff --git a/viu_media/assets/scripts/fzf/airing_schedule_info.py b/viu_media/assets/scripts/fzf/airing_schedule_info.py index e69de29..e11ff94 100644 --- a/viu_media/assets/scripts/fzf/airing_schedule_info.py +++ b/viu_media/assets/scripts/fzf/airing_schedule_info.py @@ -0,0 +1,41 @@ +import sys +from rich.console import Console +from rich.table import Table +from rich.rule import Rule +from rich.markdown import Markdown + +console = Console(force_terminal=True, color_system="truecolor") + +HEADER_COLOR = sys.argv[1] +SEPARATOR_COLOR = sys.argv[2] + + +def rule(title: str | None = None): + console.print(Rule(style=f"rgb({SEPARATOR_COLOR})")) + + +console.print("{ANIME_TITLE}", justify="center") + +left = [ + ("Total Episodes",), + ("Upcoming Episodes",), +] +right = [ + ("{TOTAL_EPISODES}",), + ("{UPCOMING_EPISODES}",), +] + + +for L_grp, R_grp in zip(left, right): + table = Table.grid(expand=True) + table.add_column(justify="left", no_wrap=True) + table.add_column(justify="right", overflow="fold") + for L, R in zip(L_grp, R_grp): + table.add_row(f"[bold rgb({HEADER_COLOR})]{L} [/]", f"{R}") + + rule() + console.print(table) + + +rule() +console.print(Markdown("""{SCHEDULE_TABLE}""")) diff --git a/viu_media/cli/utils/preview.py b/viu_media/cli/utils/preview.py index 42acd00..871717d 100644 --- a/viu_media/cli/utils/preview.py +++ b/viu_media/cli/utils/preview.py @@ -124,11 +124,9 @@ logger = logging.getLogger(__name__) PREVIEWS_CACHE_DIR = APP_CACHE_DIR / "previews" IMAGES_CACHE_DIR = PREVIEWS_CACHE_DIR / "images" INFO_CACHE_DIR = PREVIEWS_CACHE_DIR / "info" -AIRING_SCHEDULE_CACHE_DIR = PREVIEWS_CACHE_DIR / "airing_schedule" FZF_SCRIPTS_DIR = SCRIPTS_DIR / "fzf" TEMPLATE_PREVIEW_SCRIPT = (FZF_SCRIPTS_DIR / "preview.py").read_text(encoding="utf-8") -TEMPLATE_AIRING_SCHEDULE_PREVIEW_SCRIPT = "" DYNAMIC_PREVIEW_SCRIPT = "" EPISODE_PATTERN = re.compile(r"^Episode\s+(\d+)\s-\s.*") @@ -457,6 +455,50 @@ def get_review_preview(choice_map: Dict[str, MediaReview], config: AppConfig) -> return preview_script +def get_airing_schedule_preview( + schedule_result: AiringScheduleResult, config: AppConfig, anime_title: str = "Anime" +) -> str: + """ + Generate the generic loader script for airing schedule previews and start background caching. + """ + + IMAGES_CACHE_DIR.mkdir(parents=True, exist_ok=True) + INFO_CACHE_DIR.mkdir(parents=True, exist_ok=True) + + HEADER_COLOR = config.fzf.preview_header_color.split(",") + SEPARATOR_COLOR = config.fzf.preview_separator_color.split(",") + + # Start managed background caching for episodes + try: + preview_manager = _get_preview_manager() + worker = preview_manager.get_airing_schedule_worker() + worker.cache_airing_schedule_preview(anime_title, schedule_result, config) + logger.debug("Started background caching for airing schedule previews") + except Exception as e: + logger.error(f"Failed to start episode background caching: {e}") + + # Use the generic loader script + preview_script = TEMPLATE_PREVIEW_SCRIPT + + replacements = { + "PREVIEW_MODE": config.general.preview, + "IMAGE_CACHE_DIR": str(IMAGES_CACHE_DIR), + "INFO_CACHE_DIR": str(INFO_CACHE_DIR), + "IMAGE_RENDERER": config.general.image_renderer, + # Color codes + "HEADER_COLOR": ",".join(HEADER_COLOR), + "SEPARATOR_COLOR": ",".join(SEPARATOR_COLOR), + "PREFIX": "airing-schedule", + "KEY": "", + "SCALE_UP": str(config.general.preview_scale_up), + } + + for key, value in replacements.items(): + preview_script = preview_script.replace(f"{{{key}}}", value) + + return preview_script + + def get_dynamic_anime_preview(config: AppConfig) -> str: """ Generate dynamic anime preview script for search functionality. @@ -539,40 +581,3 @@ def get_preview_worker_status() -> dict: if _preview_manager: return _preview_manager.get_status() return {"preview_worker": None, "episode_worker": None} - - -def get_airing_schedule_preview( - schedule_result: AiringScheduleResult, config: AppConfig, anime_title: str = "Anime" -) -> str: - """ - Generate the generic loader script for airing schedule previews and start background caching. - """ - - INFO_CACHE_DIR.mkdir(parents=True, exist_ok=True) - preview_manager = _get_preview_manager() - worker = preview_manager.get_airing_schedule_worker() - worker.cache_airing_schedule_preview(anime_title, schedule_result, config) - logger.debug("Started background caching for airing schedule previews") - - # Use the generic loader script - preview_script = TEMPLATE_AIRING_SCHEDULE_PREVIEW_SCRIPT - path_sep = "\\" if PLATFORM == "win32" else "/" - - # Inject the correct cache path and color codes - replacements = { - "PREVIEW_MODE": config.general.preview, - "INFO_CACHE_DIR": str(INFO_CACHE_DIR), - "PATH_SEP": path_sep, - "C_TITLE": ansi.get_true_fg(config.fzf.header_color.split(","), bold=True), - "C_KEY": ansi.get_true_fg(config.fzf.header_color.split(","), bold=True), - "C_VALUE": ansi.get_true_fg(config.fzf.header_color.split(","), bold=True), - "C_RULE": ansi.get_true_fg( - config.fzf.preview_separator_color.split(","), bold=True - ), - "RESET": ansi.RESET, - } - - for key, value in replacements.items(): - preview_script = preview_script.replace(f"{{{key}}}", value) - - return preview_script diff --git a/viu_media/cli/utils/preview_workers.py b/viu_media/cli/utils/preview_workers.py index 42ff368..d2ad5c4 100644 --- a/viu_media/cli/utils/preview_workers.py +++ b/viu_media/cli/utils/preview_workers.py @@ -745,7 +745,7 @@ class AiringScheduleCacheWorker(ManagedBackgroundWorker): def _get_cache_hash(self, text: str) -> str: from hashlib import sha256 - return sha256(text.encode("utf-8")).hexdigest() + return "airing-schedule-" + sha256(text.encode("utf-8")).hexdigest() + ".py" def _on_task_completed(self, task: WorkerTask, future) -> None: super()._on_task_completed(task, future)