111 lines
3.5 KiB
Python
111 lines
3.5 KiB
Python
#!/usr/bin/env python3
|
|
from __future__ import annotations
|
|
|
|
import html
|
|
import re
|
|
|
|
import discord
|
|
|
|
|
|
def is_missing(value: str | None) -> bool:
|
|
text = (value or "").strip().lower()
|
|
return text in {"", "n/a", "none", "null"}
|
|
|
|
|
|
def fit_embed_value(text: str, max_len: int = 1000) -> str:
|
|
value = (text or "").strip()
|
|
if is_missing(value):
|
|
value = "Unbekannt"
|
|
if len(value) <= max_len:
|
|
return value
|
|
return value[: max_len - 3] + "..."
|
|
|
|
|
|
def fit_embed_description(text: str, max_len: int = 3800) -> str:
|
|
value = (text or "").strip()
|
|
if len(value) <= max_len:
|
|
return value
|
|
return value[: max_len - 3] + "..."
|
|
|
|
|
|
def format_tag_badges(tags_text: str) -> str:
|
|
if is_missing(tags_text):
|
|
return "Unbekannt"
|
|
parts = [part.strip() for part in tags_text.split(",") if part.strip()]
|
|
if not parts:
|
|
return "Unbekannt"
|
|
return " ".join(f"`{part}`" for part in parts)
|
|
|
|
|
|
def format_single_badge(text: str) -> str:
|
|
if is_missing(text):
|
|
return "Unbekannt"
|
|
return f"`{fit_embed_value(text, max_len=200)}`"
|
|
|
|
|
|
def compact_text(text: str) -> str:
|
|
raw = text or ""
|
|
raw = re.sub(r"<\s*br\s*/?\s*>", " ", raw, flags=re.IGNORECASE)
|
|
raw = re.sub(r"</\s*p\s*>", " ", raw, flags=re.IGNORECASE)
|
|
raw = re.sub(r"<[^>]+>", "", raw)
|
|
raw = html.unescape(raw)
|
|
return " ".join(raw.replace("\n", " ").split())
|
|
|
|
|
|
def add_line(lines: list[str], label: str, value: str) -> None:
|
|
if is_missing(value):
|
|
return
|
|
lines.append(f"**{label}:** {fit_embed_value(value)}")
|
|
|
|
|
|
def make_links_view(anilist_url: str) -> discord.ui.View | None:
|
|
if is_missing(anilist_url):
|
|
return None
|
|
|
|
view = discord.ui.View(timeout=None)
|
|
view.add_item(discord.ui.Button(label="Zum Anime", style=discord.ButtonStyle.link, url=anilist_url))
|
|
return view
|
|
|
|
|
|
def build_movie_embed(item: dict, index: int) -> discord.Embed:
|
|
title = fit_embed_value(
|
|
str(item.get("title_schedule_english") or item.get("title_english_anilist") or item.get("title", "")),
|
|
max_len=200,
|
|
)
|
|
anilist_url = str(item.get("anilist_url", "")).strip()
|
|
embed = discord.Embed(
|
|
title=title,
|
|
url=anilist_url if not is_missing(anilist_url) else None,
|
|
color=discord.Color.from_rgb(30, 144, 255),
|
|
)
|
|
|
|
tags_badges = format_tag_badges(str(item.get("tags", "")))
|
|
genres_badges = format_tag_badges(str(item.get("genres", "")))
|
|
romaji_badge = format_single_badge(str(item.get("title_romaji", "")))
|
|
native_badge = format_single_badge(str(item.get("title_native", "")))
|
|
description_text = compact_text(str(item.get("description", "")))
|
|
|
|
lines: list[str] = []
|
|
add_line(lines, "Anime Typ", str(item.get("format", "")))
|
|
add_line(lines, "Genres", genres_badges)
|
|
add_line(lines, "Tags", tags_badges)
|
|
add_line(lines, "Release", str(item.get("release", "")))
|
|
add_line(lines, "Studios", str(item.get("studio", "")))
|
|
add_line(lines, "Romaji", romaji_badge)
|
|
add_line(lines, "Nativ", native_badge)
|
|
add_line(lines, "Beschreibung", description_text)
|
|
embed.description = fit_embed_description("\n".join(lines) if lines else "Keine Details verfuegbar")
|
|
|
|
cover = (item.get("cover_image") or "").strip()
|
|
if cover:
|
|
embed.set_image(url=cover)
|
|
|
|
embed.set_footer(
|
|
text=(
|
|
"Daten: AniList, AnimeSchedule, TMDB | "
|
|
"This product uses the TMDB API but is not endorsed or certified by TMDB. "
|
|
f"| Eintrag #{index}"
|
|
)
|
|
)
|
|
return embed
|