mirror of
https://github.com/Benexl/FastAnime.git
synced 2025-12-05 20:40:09 -08:00
Compare commits
5 Commits
29ce664e4c
...
08ae8786c3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08ae8786c3 | ||
|
|
64093204ad | ||
|
|
8440ffb5e5 | ||
|
|
6e287d320d | ||
|
|
a7b0f21deb |
@@ -0,0 +1,44 @@
|
||||
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("{TITLE}", justify="center")
|
||||
|
||||
left = [
|
||||
("Duration", "Status"),
|
||||
("Total Episodes", "Next Episode"),
|
||||
("Progress", "List Status"),
|
||||
("Start Date", "End Date"),
|
||||
]
|
||||
right = [
|
||||
("{DURATION}", "{STATUS}"),
|
||||
("{EPISODES}", "{NEXT_EPISODE}"),
|
||||
("{USER_PROGRESS}", "{USER_STATUS}"),
|
||||
("{START_DATE}", "{END_DATE}"),
|
||||
]
|
||||
|
||||
|
||||
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()
|
||||
|
||||
@@ -26,8 +26,10 @@ SCALE_UP = "{SCALE_UP}" == "True"
|
||||
|
||||
# fzf passes the title with quotes, so we need to trim them
|
||||
TITLE = sys.argv[1]
|
||||
KEY = """{KEY}"""
|
||||
KEY = KEY + "-" if KEY else KEY
|
||||
|
||||
hash = f"{PREFIX}-{sha256(TITLE.encode('utf-8')).hexdigest()}"
|
||||
hash = f"{PREFIX}-{sha256((KEY + TITLE).encode('utf-8')).hexdigest()}"
|
||||
|
||||
|
||||
def fzf_image_preview(file_path: str):
|
||||
|
||||
@@ -6,6 +6,8 @@ from typing import Dict, List, Optional
|
||||
|
||||
import httpx
|
||||
|
||||
from viu_media.core.utils import formatter
|
||||
|
||||
from ...core.config import AppConfig
|
||||
from ...core.constants import APP_CACHE_DIR, PLATFORM, SCRIPTS_DIR
|
||||
from ...core.utils.file import AtomicWriter
|
||||
@@ -299,18 +301,19 @@ def get_anime_preview(
|
||||
# Color codes
|
||||
"HEADER_COLOR": ",".join(HEADER_COLOR),
|
||||
"SEPARATOR_COLOR": ",".join(SEPARATOR_COLOR),
|
||||
"PREFIX": "search-results",
|
||||
"PREFIX": "search-result",
|
||||
"KEY": "",
|
||||
"SCALE_UP": str(config.general.preview_scale_up),
|
||||
}
|
||||
|
||||
for key, value in replacements.items():
|
||||
preview_script = preview_script.replace(f"{{{key}}}", value)
|
||||
|
||||
(PREVIEWS_CACHE_DIR / "search-results-preview-script.py").write_text(
|
||||
(PREVIEWS_CACHE_DIR / "search-result-preview-script.py").write_text(
|
||||
preview_script, encoding="utf-8"
|
||||
)
|
||||
|
||||
preview_script_final = f"{sys.executable} {PREVIEWS_CACHE_DIR / 'search-results-preview-script.py'} {{}}"
|
||||
preview_script_final = f"{sys.executable} {PREVIEWS_CACHE_DIR / 'search-result-preview-script.py'} {{}}"
|
||||
return preview_script_final
|
||||
|
||||
|
||||
@@ -348,30 +351,30 @@ def get_episode_preview(
|
||||
logger.error(f"Failed to start episode background caching: {e}")
|
||||
# Continue with script generation even if caching fails
|
||||
|
||||
# Prepare values to inject into the template
|
||||
path_sep = "\\" if PLATFORM == "win32" else "/"
|
||||
|
||||
# Format the template with the dynamic values
|
||||
replacements = {
|
||||
"PREVIEW_MODE": config.general.preview,
|
||||
"IMAGE_CACHE_PATH": str(IMAGES_CACHE_DIR),
|
||||
"INFO_CACHE_PATH": str(INFO_CACHE_DIR),
|
||||
"PATH_SEP": path_sep,
|
||||
"IMAGE_CACHE_DIR": str(IMAGES_CACHE_DIR),
|
||||
"INFO_CACHE_DIR": str(INFO_CACHE_DIR),
|
||||
"IMAGE_RENDERER": config.general.image_renderer,
|
||||
# Color codes
|
||||
"C_TITLE": ansi.get_true_fg(HEADER_COLOR, bold=True),
|
||||
"C_KEY": ansi.get_true_fg(HEADER_COLOR, bold=True),
|
||||
"C_VALUE": ansi.get_true_fg(HEADER_COLOR, bold=True),
|
||||
"C_RULE": ansi.get_true_fg(SEPARATOR_COLOR, bold=True),
|
||||
"RESET": ansi.RESET,
|
||||
"PREFIX": f"{media_item.title.english}_Episode_",
|
||||
"SCALE_UP": " --scale-up" if config.general.preview_scale_up else "",
|
||||
"HEADER_COLOR": ",".join(HEADER_COLOR),
|
||||
"SEPARATOR_COLOR": ",".join(SEPARATOR_COLOR),
|
||||
"PREFIX": "episode",
|
||||
"KEY": f"{media_item.title.english.replace(formatter.DOUBLE_QUOTE, formatter.SINGLE_QUOTE)}",
|
||||
"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
|
||||
(PREVIEWS_CACHE_DIR / "episode-preview-script.py").write_text(
|
||||
preview_script, encoding="utf-8"
|
||||
)
|
||||
preview_script_final = (
|
||||
f"{sys.executable} {PREVIEWS_CACHE_DIR / 'episode-preview-script.py'} {{}}"
|
||||
)
|
||||
return preview_script_final
|
||||
|
||||
|
||||
def get_dynamic_anime_preview(config: AppConfig) -> str:
|
||||
|
||||
@@ -31,7 +31,9 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
FZF_SCRIPTS_DIR = SCRIPTS_DIR / "fzf"
|
||||
TEMPLATE_INFO_SCRIPT = (FZF_SCRIPTS_DIR / "info.py").read_text(encoding="utf-8")
|
||||
TEMPLATE_MEDIA_INFO_SCRIPT = (FZF_SCRIPTS_DIR / "media_info.py").read_text(
|
||||
encoding="utf-8"
|
||||
)
|
||||
TEMPLATE_EPISODE_INFO_SCRIPT = (FZF_SCRIPTS_DIR / "episode_info.py").read_text(
|
||||
encoding="utf-8"
|
||||
)
|
||||
@@ -142,7 +144,7 @@ class PreviewCacheWorker(ManagedBackgroundWorker):
|
||||
def _generate_info_text(self, media_item: MediaItem, config: AppConfig) -> str:
|
||||
"""Generate formatted info text for a media item."""
|
||||
# Import here to avoid circular imports
|
||||
info_script = TEMPLATE_INFO_SCRIPT
|
||||
info_script = TEMPLATE_MEDIA_INFO_SCRIPT
|
||||
description = formatter.clean_html(
|
||||
media_item.description or "No description available."
|
||||
)
|
||||
@@ -236,7 +238,7 @@ class PreviewCacheWorker(ManagedBackgroundWorker):
|
||||
"""Generate a cache hash for the given text."""
|
||||
from hashlib import sha256
|
||||
|
||||
return f"search-results-{sha256(text.encode('utf-8')).hexdigest()}"
|
||||
return f"search-result-{sha256(text.encode('utf-8')).hexdigest()}"
|
||||
|
||||
def _on_task_completed(self, task: WorkerTask, future) -> None:
|
||||
"""Handle task completion with enhanced logging."""
|
||||
@@ -306,7 +308,7 @@ class EpisodeCacheWorker(ManagedBackgroundWorker):
|
||||
|
||||
for episode_str in episodes:
|
||||
hash_id = self._get_cache_hash(
|
||||
f"{media_item.title.english}_Episode_{episode_str}"
|
||||
f"{media_item.title.english.replace(formatter.DOUBLE_QUOTE, formatter.SINGLE_QUOTE)}-{episode_str}"
|
||||
)
|
||||
|
||||
# Find episode data
|
||||
@@ -402,7 +404,7 @@ class EpisodeCacheWorker(ManagedBackgroundWorker):
|
||||
"""Generate a cache hash for the given text."""
|
||||
from hashlib import sha256
|
||||
|
||||
return sha256(text.encode("utf-8")).hexdigest()
|
||||
return "episode-" + sha256(text.encode("utf-8")).hexdigest()
|
||||
|
||||
def _on_task_completed(self, task: WorkerTask, future) -> None:
|
||||
"""Handle task completion with enhanced logging."""
|
||||
|
||||
@@ -5,6 +5,8 @@ from typing import Dict, List, Optional, Union
|
||||
from ...libs.media_api.types import AiringSchedule
|
||||
|
||||
COMMA_REGEX = re.compile(r"([0-9]{3})(?=\d)")
|
||||
SINGLE_QUOTE = "'"
|
||||
DOUBLE_QUOTE = '"'
|
||||
|
||||
|
||||
def format_media_duration(total_minutes: Optional[int]) -> str:
|
||||
|
||||
Reference in New Issue
Block a user