mirror of
https://github.com/Benexl/FastAnime.git
synced 2025-12-25 12:24:52 -08:00
88 lines
3.0 KiB
Python
88 lines
3.0 KiB
Python
# fastanime/cli/utils/image.py
|
|
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
import shutil
|
|
import subprocess
|
|
from typing import Optional
|
|
|
|
import click
|
|
import httpx
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def render(url: str, capture: bool = False, size: str = "30x30") -> Optional[str]:
|
|
"""
|
|
Renders an image from a URL in the terminal using icat or chafa.
|
|
|
|
This function automatically detects the best available tool.
|
|
|
|
Args:
|
|
url: The URL of the image to render.
|
|
capture: If True, returns the terminal-formatted image as a string
|
|
instead of printing it. Defaults to False.
|
|
size: The size parameter to pass to the rendering tool (e.g., "WxH").
|
|
|
|
Returns:
|
|
If capture is True, returns the image data as a string.
|
|
If capture is False, prints directly to the terminal and returns None.
|
|
Returns None on any failure.
|
|
"""
|
|
# --- Common subprocess arguments ---
|
|
subprocess_kwargs = {
|
|
"check": False, # We will handle errors manually
|
|
"capture_output": capture,
|
|
"text": capture, # Decode stdout/stderr as text if capturing
|
|
}
|
|
|
|
# --- Try icat (Kitty terminal) first ---
|
|
if icat_executable := shutil.which("icat"):
|
|
process = subprocess.run(
|
|
[icat_executable, "--align", "left", url], **subprocess_kwargs
|
|
)
|
|
if process.returncode == 0:
|
|
return process.stdout if capture else None
|
|
logger.warning(f"icat failed for URL {url} with code {process.returncode}")
|
|
|
|
# --- Fallback to chafa ---
|
|
if chafa_executable := shutil.which("chafa"):
|
|
try:
|
|
# Chafa requires downloading the image data first
|
|
with httpx.Client() as client:
|
|
response = client.get(url, follow_redirects=True, timeout=20)
|
|
response.raise_for_status()
|
|
img_bytes = response.content
|
|
|
|
# Add stdin input to the subprocess arguments
|
|
subprocess_kwargs["input"] = img_bytes
|
|
|
|
process = subprocess.run(
|
|
[chafa_executable, f"--size={size}", "-"], **subprocess_kwargs
|
|
)
|
|
if process.returncode == 0:
|
|
return process.stdout if capture else None
|
|
logger.warning(f"chafa failed for URL {url} with code {process.returncode}")
|
|
|
|
except httpx.HTTPStatusError as e:
|
|
logger.error(
|
|
f"HTTP error fetching image for chafa: {e.response.status_code}"
|
|
)
|
|
click.echo(
|
|
f"[dim]Error fetching image: {e.response.status_code}[/dim]", err=True
|
|
)
|
|
except Exception as e:
|
|
logger.error(f"An exception occurred while running chafa: {e}")
|
|
|
|
return None
|
|
|
|
# --- Final fallback if no tool is found ---
|
|
if not capture:
|
|
# Only show this message if the user expected to see something.
|
|
click.echo(
|
|
"[dim](Image preview skipped: icat or chafa not found)[/dim]", err=True
|
|
)
|
|
|
|
return None
|