mirror of
https://github.com/Benexl/FastAnime.git
synced 2025-12-05 20:40:09 -08:00
feat: rewrite FZF preview scripts to use ANSI utilities for improved formatting
This commit is contained in:
152
viu_media/assets/scripts/fzf/_ansi_utils.py
Normal file
152
viu_media/assets/scripts/fzf/_ansi_utils.py
Normal file
@@ -0,0 +1,152 @@
|
||||
"""
|
||||
ANSI utilities for FZF preview scripts.
|
||||
|
||||
Lightweight stdlib-only utilities to replace Rich dependency in preview scripts.
|
||||
Provides RGB color formatting, table rendering, and markdown stripping.
|
||||
"""
|
||||
|
||||
import re
|
||||
import shutil
|
||||
import textwrap
|
||||
|
||||
|
||||
def rgb_color(r: int, g: int, b: int, text: str, bold: bool = False) -> str:
|
||||
"""
|
||||
Format text with RGB color using ANSI escape codes.
|
||||
|
||||
Args:
|
||||
r: Red component (0-255)
|
||||
g: Green component (0-255)
|
||||
b: Blue component (0-255)
|
||||
text: Text to colorize
|
||||
bold: Whether to make text bold
|
||||
|
||||
Returns:
|
||||
ANSI-escaped colored text
|
||||
"""
|
||||
color_code = f"\x1b[38;2;{r};{g};{b}m"
|
||||
bold_code = "\x1b[1m" if bold else ""
|
||||
reset = "\x1b[0m"
|
||||
return f"{color_code}{bold_code}{text}{reset}"
|
||||
|
||||
|
||||
def parse_color(color_csv: str) -> tuple[int, int, int]:
|
||||
"""
|
||||
Parse RGB color from comma-separated string.
|
||||
|
||||
Args:
|
||||
color_csv: Color as 'R,G,B' string
|
||||
|
||||
Returns:
|
||||
Tuple of (r, g, b) integers
|
||||
"""
|
||||
parts = color_csv.split(",")
|
||||
return int(parts[0]), int(parts[1]), int(parts[2])
|
||||
|
||||
|
||||
def print_rule(sep_color: str) -> None:
|
||||
"""
|
||||
Print a horizontal rule line.
|
||||
|
||||
Args:
|
||||
sep_color: Color as 'R,G,B' string
|
||||
"""
|
||||
width = shutil.get_terminal_size((80, 24)).columns
|
||||
r, g, b = parse_color(sep_color)
|
||||
print(rgb_color(r, g, b, "─" * width))
|
||||
|
||||
|
||||
def print_table_row(
|
||||
key: str, value: str, header_color: str, key_width: int, value_width: int
|
||||
) -> None:
|
||||
"""
|
||||
Print a two-column table row with left-aligned key and right-aligned value.
|
||||
|
||||
Args:
|
||||
key: Left column text (header/key)
|
||||
value: Right column text (value)
|
||||
header_color: Color for key as 'R,G,B' string
|
||||
key_width: Width for key column
|
||||
value_width: Width for value column
|
||||
"""
|
||||
r, g, b = parse_color(header_color)
|
||||
key_styled = rgb_color(r, g, b, key, bold=True)
|
||||
|
||||
# Ensure minimum width to avoid textwrap errors
|
||||
safe_value_width = max(20, value_width)
|
||||
|
||||
# Wrap value if it's too long
|
||||
value_lines = textwrap.wrap(str(value), width=safe_value_width) if value else [""]
|
||||
|
||||
if not value_lines:
|
||||
value_lines = [""]
|
||||
|
||||
# Print first line with right-aligned value
|
||||
first_line = value_lines[0]
|
||||
print(f"{key_styled:<{key_width + 20}} {first_line:>{safe_value_width}}")
|
||||
|
||||
# Print remaining wrapped lines (left-aligned, indented)
|
||||
for line in value_lines[1:]:
|
||||
print(f"{' ' * (key_width + 2)}{line}")
|
||||
def strip_markdown(text: str) -> str:
|
||||
"""
|
||||
Strip markdown formatting from text.
|
||||
|
||||
Removes:
|
||||
- Headers (# ## ###)
|
||||
- Bold (**text** or __text__)
|
||||
- Italic (*text* or _text_)
|
||||
- Links ([text](url))
|
||||
- Code blocks (```code```)
|
||||
- Inline code (`code`)
|
||||
|
||||
Args:
|
||||
text: Markdown-formatted text
|
||||
|
||||
Returns:
|
||||
Plain text with markdown removed
|
||||
"""
|
||||
if not text:
|
||||
return ""
|
||||
|
||||
# Remove code blocks first
|
||||
text = re.sub(r"```[\s\S]*?```", "", text)
|
||||
|
||||
# Remove inline code
|
||||
text = re.sub(r"`([^`]+)`", r"\1", text)
|
||||
|
||||
# Remove headers
|
||||
text = re.sub(r"^#{1,6}\s+", "", text, flags=re.MULTILINE)
|
||||
|
||||
# Remove bold (** or __)
|
||||
text = re.sub(r"\*\*(.+?)\*\*", r"\1", text)
|
||||
text = re.sub(r"__(.+?)__", r"\1", text)
|
||||
|
||||
# Remove italic (* or _)
|
||||
text = re.sub(r"\*(.+?)\*", r"\1", text)
|
||||
text = re.sub(r"_(.+?)_", r"\1", text)
|
||||
|
||||
# Remove links, keep text
|
||||
text = re.sub(r"\[(.+?)\]\(.+?\)", r"\1", text)
|
||||
|
||||
# Remove images
|
||||
text = re.sub(r"!\[.*?\]\(.+?\)", "", text)
|
||||
|
||||
return text.strip()
|
||||
|
||||
|
||||
def wrap_text(text: str, width: int | None = None) -> str:
|
||||
"""
|
||||
Wrap text to terminal width.
|
||||
|
||||
Args:
|
||||
text: Text to wrap
|
||||
width: Width to wrap to (defaults to terminal width)
|
||||
|
||||
Returns:
|
||||
Wrapped text
|
||||
"""
|
||||
if width is None:
|
||||
width = shutil.get_terminal_size((80, 24)).columns
|
||||
|
||||
return textwrap.fill(text, width=width)
|
||||
@@ -1,41 +1,31 @@
|
||||
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")
|
||||
import shutil
|
||||
from _ansi_utils import print_rule, print_table_row, strip_markdown, wrap_text
|
||||
|
||||
HEADER_COLOR = sys.argv[1]
|
||||
SEPARATOR_COLOR = sys.argv[2]
|
||||
|
||||
# Get terminal dimensions
|
||||
term_width = shutil.get_terminal_size((80, 24)).columns
|
||||
|
||||
def rule(title: str | None = None):
|
||||
console.print(Rule(style=f"rgb({SEPARATOR_COLOR})"))
|
||||
# Print title centered
|
||||
print("{ANIME_TITLE}".center(term_width))
|
||||
|
||||
|
||||
console.print("{ANIME_TITLE}", justify="center")
|
||||
|
||||
left = [
|
||||
("Total Episodes",),
|
||||
("Upcoming Episodes",),
|
||||
]
|
||||
right = [
|
||||
("{TOTAL_EPISODES}",),
|
||||
("{UPCOMING_EPISODES}",),
|
||||
rows = [
|
||||
("Total Episodes", "{TOTAL_EPISODES}"),
|
||||
]
|
||||
|
||||
print_rule(SEPARATOR_COLOR)
|
||||
for key, value in rows:
|
||||
print_table_row(key, value, HEADER_COLOR, 15, term_width - 20)
|
||||
|
||||
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}")
|
||||
rows = [
|
||||
("Upcoming Episodes", "{UPCOMING_EPISODES}"),
|
||||
]
|
||||
|
||||
rule()
|
||||
console.print(table)
|
||||
print_rule(SEPARATOR_COLOR)
|
||||
for key, value in rows:
|
||||
print_table_row(key, value, HEADER_COLOR, 15, term_width - 20)
|
||||
|
||||
|
||||
rule()
|
||||
console.print(Markdown("""{SCHEDULE_TABLE}"""))
|
||||
print_rule(SEPARATOR_COLOR)
|
||||
print(wrap_text(strip_markdown("""{SCHEDULE_TABLE}"""), term_width))
|
||||
|
||||
@@ -1,43 +1,42 @@
|
||||
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")
|
||||
import shutil
|
||||
from _ansi_utils import print_rule, print_table_row, strip_markdown, wrap_text
|
||||
|
||||
HEADER_COLOR = sys.argv[1]
|
||||
SEPARATOR_COLOR = sys.argv[2]
|
||||
|
||||
# Get terminal dimensions
|
||||
term_width = shutil.get_terminal_size((80, 24)).columns
|
||||
|
||||
def rule(title: str | None = None):
|
||||
console.print(Rule(style=f"rgb({SEPARATOR_COLOR})"))
|
||||
# Print title centered
|
||||
print("{CHARACTER_NAME}".center(term_width))
|
||||
|
||||
|
||||
console.print("{CHARACTER_NAME}", justify="center")
|
||||
|
||||
left = [
|
||||
("Native Name", "Gender"),
|
||||
("Age", "Blood Type"),
|
||||
("Birthday", "Favourites"),
|
||||
]
|
||||
right = [
|
||||
("{CHARACTER_NATIVE_NAME}", "{CHARACTER_GENDER}"),
|
||||
("{CHARACTER_AGE}", "{CHARACTER_BLOOD_TYPE}"),
|
||||
("{CHARACTER_BIRTHDAY}", "{CHARACTER_FAVOURITES}"),
|
||||
rows = [
|
||||
("Native Name", "{CHARACTER_NATIVE_NAME}"),
|
||||
("Gender", "{CHARACTER_GENDER}"),
|
||||
]
|
||||
|
||||
print_rule(SEPARATOR_COLOR)
|
||||
for key, value in rows:
|
||||
print_table_row(key, value, HEADER_COLOR, 15, term_width - 20)
|
||||
|
||||
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}")
|
||||
rows = [
|
||||
("Age", "{CHARACTER_AGE}"),
|
||||
("Blood Type", "{CHARACTER_BLOOD_TYPE}"),
|
||||
]
|
||||
|
||||
rule()
|
||||
console.print(table)
|
||||
print_rule(SEPARATOR_COLOR)
|
||||
for key, value in rows:
|
||||
print_table_row(key, value, HEADER_COLOR, 15, term_width - 20)
|
||||
|
||||
rows = [
|
||||
("Birthday", "{CHARACTER_BIRTHDAY}"),
|
||||
("Favourites", "{CHARACTER_FAVOURITES}"),
|
||||
]
|
||||
|
||||
rule()
|
||||
console.print(Markdown("""{CHARACTER_DESCRIPTION}"""))
|
||||
print_rule(SEPARATOR_COLOR)
|
||||
for key, value in rows:
|
||||
print_table_row(key, value, HEADER_COLOR, 15, term_width - 20)
|
||||
|
||||
print_rule(SEPARATOR_COLOR)
|
||||
print(wrap_text(strip_markdown("""{CHARACTER_DESCRIPTION}"""), term_width))
|
||||
|
||||
@@ -1,44 +1,50 @@
|
||||
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")
|
||||
import shutil
|
||||
from _ansi_utils import print_rule, print_table_row
|
||||
|
||||
HEADER_COLOR = sys.argv[1]
|
||||
SEPARATOR_COLOR = sys.argv[2]
|
||||
|
||||
# Get terminal dimensions
|
||||
term_width = shutil.get_terminal_size((80, 24)).columns
|
||||
|
||||
def rule(title: str | None = None):
|
||||
console.print(Rule(style=f"rgb({SEPARATOR_COLOR})"))
|
||||
# Print title centered
|
||||
print("{TITLE}".center(term_width))
|
||||
|
||||
|
||||
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}"),
|
||||
rows = [
|
||||
("Duration", "{DURATION}"),
|
||||
("Status", "{STATUS}"),
|
||||
]
|
||||
|
||||
print_rule(SEPARATOR_COLOR)
|
||||
for key, value in rows:
|
||||
print_table_row(key, value, HEADER_COLOR, 15, term_width - 20)
|
||||
|
||||
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}")
|
||||
rows = [
|
||||
("Total Episodes", "{EPISODES}"),
|
||||
("Next Episode", "{NEXT_EPISODE}"),
|
||||
]
|
||||
|
||||
rule()
|
||||
console.print(table)
|
||||
print_rule(SEPARATOR_COLOR)
|
||||
for key, value in rows:
|
||||
print_table_row(key, value, HEADER_COLOR, 15, term_width - 20)
|
||||
|
||||
rows = [
|
||||
("Progress", "{USER_PROGRESS}"),
|
||||
("List Status", "{USER_STATUS}"),
|
||||
]
|
||||
|
||||
rule()
|
||||
print_rule(SEPARATOR_COLOR)
|
||||
for key, value in rows:
|
||||
print_table_row(key, value, HEADER_COLOR, 15, term_width - 20)
|
||||
|
||||
rows = [
|
||||
("Start Date", "{START_DATE}"),
|
||||
("End Date", "{END_DATE}"),
|
||||
]
|
||||
|
||||
print_rule(SEPARATOR_COLOR)
|
||||
for key, value in rows:
|
||||
print_table_row(key, value, HEADER_COLOR, 15, term_width - 20)
|
||||
|
||||
print_rule(SEPARATOR_COLOR)
|
||||
|
||||
@@ -1,89 +1,88 @@
|
||||
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")
|
||||
import shutil
|
||||
from _ansi_utils import print_rule, print_table_row, strip_markdown, wrap_text
|
||||
|
||||
HEADER_COLOR = sys.argv[1]
|
||||
SEPARATOR_COLOR = sys.argv[2]
|
||||
|
||||
# Get terminal dimensions
|
||||
term_width = shutil.get_terminal_size((80, 24)).columns
|
||||
|
||||
def rule(title: str | None = None):
|
||||
console.print(Rule(style=f"rgb({SEPARATOR_COLOR})"))
|
||||
# Print title centered
|
||||
print("{TITLE}".center(term_width))
|
||||
|
||||
|
||||
console.print("{TITLE}", justify="center")
|
||||
|
||||
left = [
|
||||
(
|
||||
"Score",
|
||||
"Favorites",
|
||||
"Popularity",
|
||||
"Status",
|
||||
),
|
||||
(
|
||||
"Episodes",
|
||||
"Duration",
|
||||
"Next Episode",
|
||||
),
|
||||
(
|
||||
"Genres",
|
||||
"Format",
|
||||
),
|
||||
(
|
||||
"List Status",
|
||||
"Progress",
|
||||
),
|
||||
(
|
||||
"Start Date",
|
||||
"End Date",
|
||||
),
|
||||
("Studios",),
|
||||
("Synonymns",),
|
||||
("Tags",),
|
||||
]
|
||||
right = [
|
||||
(
|
||||
"{SCORE}",
|
||||
"{FAVOURITES}",
|
||||
"{POPULARITY}",
|
||||
"{STATUS}",
|
||||
),
|
||||
(
|
||||
"{EPISODES}",
|
||||
"{DURATION}",
|
||||
"{NEXT_EPISODE}",
|
||||
),
|
||||
(
|
||||
"{GENRES}",
|
||||
"{FORMAT}",
|
||||
),
|
||||
(
|
||||
"{USER_STATUS}",
|
||||
"{USER_PROGRESS}",
|
||||
),
|
||||
(
|
||||
"{START_DATE}",
|
||||
"{END_DATE}",
|
||||
),
|
||||
("{STUDIOS}",),
|
||||
("{SYNONYMNS}",),
|
||||
("{TAGS}",),
|
||||
# Define table data
|
||||
rows = [
|
||||
("Score", "{SCORE}"),
|
||||
("Favorites", "{FAVOURITES}"),
|
||||
("Popularity", "{POPULARITY}"),
|
||||
("Status", "{STATUS}"),
|
||||
]
|
||||
|
||||
print_rule(SEPARATOR_COLOR)
|
||||
for key, value in rows:
|
||||
print_table_row(key, value, HEADER_COLOR, 15, term_width - 20)
|
||||
|
||||
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}")
|
||||
rows = [
|
||||
("Episodes", "{EPISODES}"),
|
||||
("Duration", "{DURATION}"),
|
||||
("Next Episode", "{NEXT_EPISODE}"),
|
||||
]
|
||||
|
||||
rule()
|
||||
console.print(table)
|
||||
print_rule(SEPARATOR_COLOR)
|
||||
for key, value in rows:
|
||||
print_table_row(key, value, HEADER_COLOR, 15, term_width - 20)
|
||||
|
||||
rows = [
|
||||
("Genres", "{GENRES}"),
|
||||
("Format", "{FORMAT}"),
|
||||
]
|
||||
|
||||
rule()
|
||||
console.print(Markdown("""{SYNOPSIS}"""))
|
||||
print_rule(SEPARATOR_COLOR)
|
||||
for key, value in rows:
|
||||
print_table_row(key, value, HEADER_COLOR, 15, term_width - 20)
|
||||
|
||||
rows = [
|
||||
("List Status", "{USER_STATUS}"),
|
||||
("Progress", "{USER_PROGRESS}"),
|
||||
]
|
||||
|
||||
print_rule(SEPARATOR_COLOR)
|
||||
for key, value in rows:
|
||||
print_table_row(key, value, HEADER_COLOR, 15, term_width - 20)
|
||||
|
||||
rows = [
|
||||
("Start Date", "{START_DATE}"),
|
||||
("End Date", "{END_DATE}"),
|
||||
]
|
||||
|
||||
print_rule(SEPARATOR_COLOR)
|
||||
for key, value in rows:
|
||||
print_table_row(key, value, HEADER_COLOR, 15, term_width - 20)
|
||||
|
||||
rows = [
|
||||
("Studios", "{STUDIOS}"),
|
||||
]
|
||||
|
||||
print_rule(SEPARATOR_COLOR)
|
||||
for key, value in rows:
|
||||
print_table_row(key, value, HEADER_COLOR, 15, term_width - 20)
|
||||
|
||||
rows = [
|
||||
("Synonymns", "{SYNONYMNS}"),
|
||||
]
|
||||
|
||||
print_rule(SEPARATOR_COLOR)
|
||||
for key, value in rows:
|
||||
print_table_row(key, value, HEADER_COLOR, 15, term_width - 20)
|
||||
|
||||
rows = [
|
||||
("Tags", "{TAGS}"),
|
||||
]
|
||||
|
||||
print_rule(SEPARATOR_COLOR)
|
||||
for key, value in rows:
|
||||
print_table_row(key, value, HEADER_COLOR, 15, term_width - 20)
|
||||
|
||||
print_rule(SEPARATOR_COLOR)
|
||||
print(wrap_text(strip_markdown("""{SYNOPSIS}"""), term_width))
|
||||
|
||||
@@ -244,11 +244,12 @@ def fzf_image_preview(file_path: str):
|
||||
|
||||
def fzf_text_info_render():
|
||||
"""Renders the text-based info via the cached python script."""
|
||||
from rich.console import Console
|
||||
from rich.rule import Rule
|
||||
import shutil
|
||||
|
||||
console = Console(force_terminal=True, color_system="truecolor")
|
||||
console.print(Rule(style=f"rgb({SEPARATOR_COLOR})"))
|
||||
# Print simple separator line
|
||||
width = shutil.get_terminal_size((80, 24)).columns
|
||||
r, g, b = map(int, SEPARATOR_COLOR.split(","))
|
||||
print(f"\x1b[38;2;{r};{g};{b}m" + "─" * width + "\x1b[0m")
|
||||
|
||||
if PREVIEW_MODE == "text" or PREVIEW_MODE == "full":
|
||||
preview_info_path = INFO_CACHE_DIR / f"{hash_id}.py"
|
||||
@@ -257,7 +258,8 @@ def fzf_text_info_render():
|
||||
[sys.executable, str(preview_info_path), HEADER_COLOR, SEPARATOR_COLOR]
|
||||
)
|
||||
else:
|
||||
console.print("📝 Loading details...", style="dim")
|
||||
# Print dim text
|
||||
print("\x1b[2m📝 Loading details...\x1b[0m")
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
@@ -1,39 +1,23 @@
|
||||
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")
|
||||
import shutil
|
||||
from _ansi_utils import print_rule, print_table_row, strip_markdown, wrap_text
|
||||
|
||||
HEADER_COLOR = sys.argv[1]
|
||||
SEPARATOR_COLOR = sys.argv[2]
|
||||
|
||||
# Get terminal dimensions
|
||||
term_width = shutil.get_terminal_size((80, 24)).columns
|
||||
|
||||
def rule(title: str | None = None):
|
||||
console.print(Rule(style=f"rgb({SEPARATOR_COLOR})"))
|
||||
# Print title centered
|
||||
print("{REVIEWER_NAME}".center(term_width))
|
||||
|
||||
|
||||
console.print("{REVIEWER_NAME}", justify="center")
|
||||
|
||||
left = [
|
||||
("Summary",),
|
||||
]
|
||||
right = [
|
||||
("{REVIEW_SUMMARY}",),
|
||||
rows = [
|
||||
("Summary", "{REVIEW_SUMMARY}"),
|
||||
]
|
||||
|
||||
print_rule(SEPARATOR_COLOR)
|
||||
for key, value in rows:
|
||||
print_table_row(key, value, HEADER_COLOR, 15, term_width - 20)
|
||||
|
||||
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("""{REVIEW_BODY}"""))
|
||||
print_rule(SEPARATOR_COLOR)
|
||||
print(wrap_text(strip_markdown("""{REVIEW_BODY}"""), term_width))
|
||||
|
||||
@@ -135,6 +135,20 @@ EPISODE_PATTERN = re.compile(r"^Episode\s+(\d+)\s-\s.*")
|
||||
_preview_manager: Optional[PreviewWorkerManager] = None
|
||||
|
||||
|
||||
def _ensure_ansi_utils_in_cache():
|
||||
"""Copy _ansi_utils.py to the info cache directory so cached scripts can import it."""
|
||||
source = FZF_SCRIPTS_DIR / "_ansi_utils.py"
|
||||
dest = INFO_CACHE_DIR / "_ansi_utils.py"
|
||||
|
||||
if source.exists() and (not dest.exists() or source.stat().st_mtime > dest.stat().st_mtime):
|
||||
try:
|
||||
import shutil
|
||||
shutil.copy2(source, dest)
|
||||
logger.debug(f"Copied _ansi_utils.py to {INFO_CACHE_DIR}")
|
||||
except Exception as e:
|
||||
logger.warning(f"Failed to copy _ansi_utils.py to cache: {e}")
|
||||
|
||||
|
||||
def create_preview_context():
|
||||
"""
|
||||
Create a context manager for preview operations.
|
||||
@@ -270,6 +284,7 @@ def get_anime_preview(
|
||||
# Ensure cache directories exist on startup
|
||||
IMAGES_CACHE_DIR.mkdir(parents=True, exist_ok=True)
|
||||
INFO_CACHE_DIR.mkdir(parents=True, exist_ok=True)
|
||||
_ensure_ansi_utils_in_cache()
|
||||
|
||||
HEADER_COLOR = config.fzf.preview_header_color.split(",")
|
||||
SEPARATOR_COLOR = config.fzf.preview_separator_color.split(",")
|
||||
@@ -527,6 +542,7 @@ def get_dynamic_anime_preview(config: AppConfig) -> str:
|
||||
# Ensure cache directories exist
|
||||
IMAGES_CACHE_DIR.mkdir(parents=True, exist_ok=True)
|
||||
INFO_CACHE_DIR.mkdir(parents=True, exist_ok=True)
|
||||
_ensure_ansi_utils_in_cache()
|
||||
|
||||
HEADER_COLOR = config.fzf.preview_header_color.split(",")
|
||||
SEPARATOR_COLOR = config.fzf.preview_separator_color.split(",")
|
||||
|
||||
Reference in New Issue
Block a user