114 lines
4.0 KiB
Python
114 lines
4.0 KiB
Python
#!/usr/bin/env python3
|
|
import asyncio
|
|
|
|
import discord
|
|
from discord import app_commands
|
|
from discord.ext import commands
|
|
|
|
from app_config import get_settings
|
|
from movie_pipeline import get_upcoming_movie_records
|
|
from embed_builder import build_movie_embed, make_links_view
|
|
|
|
|
|
async def fetch_records(locale: str, tmdb_token: str, schedule_token: str) -> list[dict]:
|
|
return await asyncio.to_thread(
|
|
get_upcoming_movie_records,
|
|
locale,
|
|
None,
|
|
schedule_token,
|
|
tmdb_token,
|
|
)
|
|
|
|
|
|
def create_bot() -> commands.Bot:
|
|
settings = get_settings()
|
|
intents = discord.Intents.default()
|
|
bot = commands.Bot(command_prefix="!", intents=intents)
|
|
guild_obj = discord.Object(id=int(settings.discord_guild_id)) if settings.discord_guild_id.isdigit() else None
|
|
|
|
async def sync_commands() -> None:
|
|
if guild_obj:
|
|
try:
|
|
# Remove stale global commands to avoid duplicate /anime entries.
|
|
cleared_global = await bot.tree.sync()
|
|
cleared_names = ", ".join(cmd.name for cmd in cleared_global) if cleared_global else "keine"
|
|
print(f"Globale Slash Commands aktualisiert: {len(cleared_global)} ({cleared_names})")
|
|
|
|
synced = await bot.tree.sync(guild=guild_obj)
|
|
names = ", ".join(cmd.name for cmd in synced) if synced else "keine"
|
|
print(f"Slash Commands fuer Guild synchronisiert: {len(synced)} ({names})")
|
|
return
|
|
except Exception as exc:
|
|
print(f"Guild-Sync fehlgeschlagen, nutze globalen Sync: {exc}")
|
|
|
|
synced = await bot.tree.sync()
|
|
names = ", ".join(cmd.name for cmd in synced) if synced else "keine"
|
|
print(f"Globale Slash Commands synchronisiert: {len(synced)} ({names})")
|
|
print("Hinweis: Globale Slash Commands koennen bis zu 60 Minuten brauchen.")
|
|
print("Setze DISCORD_GUILD_ID fuer sofortige Verfuegbarkeit in deinem Server.")
|
|
|
|
@bot.event
|
|
async def setup_hook() -> None:
|
|
await sync_commands()
|
|
|
|
@bot.event
|
|
async def on_ready() -> None:
|
|
print(f"Bot online als {bot.user}")
|
|
|
|
async def anime_handler(interaction: discord.Interaction, limit: app_commands.Range[int, 1, 25] = 10) -> None:
|
|
locale = settings.locale
|
|
safe_limit = int(limit)
|
|
|
|
await interaction.response.defer(thinking=True)
|
|
try:
|
|
records = await fetch_records(locale, settings.tmdb_read_access_token, settings.animeschedule_api_token)
|
|
except Exception as exc:
|
|
await interaction.followup.send(f"Fehler beim Abruf: {exc}")
|
|
return
|
|
|
|
if not records:
|
|
await interaction.followup.send("Keine Anime Filme fuer diesen und naechsten Monat gefunden.")
|
|
return
|
|
|
|
selected = records[:safe_limit]
|
|
await interaction.followup.send(f"Gefunden: {len(selected)} Anime-Filme")
|
|
|
|
for idx, item in enumerate(selected, start=1):
|
|
embed = build_movie_embed(item, idx)
|
|
view = make_links_view(str(item.get("anilist_url", "")))
|
|
if view is None:
|
|
await interaction.followup.send(embed=embed)
|
|
else:
|
|
await interaction.followup.send(embed=embed, view=view)
|
|
|
|
anime_handler = app_commands.describe(limit="Anzahl Ergebnisse (1-25)")(anime_handler)
|
|
if guild_obj:
|
|
bot.tree.command(
|
|
name="anime",
|
|
description="Zeigt kommende Anime-Filme",
|
|
guild=guild_obj,
|
|
)(anime_handler)
|
|
else:
|
|
bot.tree.command(
|
|
name="anime",
|
|
description="Zeigt kommende Anime-Filme",
|
|
)(anime_handler)
|
|
|
|
return bot
|
|
|
|
|
|
def main() -> int:
|
|
settings = get_settings()
|
|
token = settings.discord_bot_token
|
|
if not token:
|
|
print("Fehler: DISCORD_BOT_TOKEN ist nicht gesetzt.")
|
|
return 1
|
|
|
|
bot = create_bot()
|
|
bot.run(token)
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|