Add modular TMDb-first movie pipeline and Discord bot
This commit is contained in:
110
embed_builder.py
Normal file
110
embed_builder.py
Normal file
@@ -0,0 +1,110 @@
|
||||
#!/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
|
||||
Reference in New Issue
Block a user