From 77f1b539e6e6d1d5351e2a0dd9de8df0f723f406 Mon Sep 17 00:00:00 2001 From: Pengu Date: Wed, 10 Sep 2025 10:29:31 -0500 Subject: [PATCH] Added random movie suggestion command --- CHANGELOG.md | 1 + README.md | 1 + app.py | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d47765a..a7114d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # 1.0.5 - Added Timezone support in .env +- Added the `what2watch` command. Lists 5 random movie suggestions from the Jellyfin Library # 1.0.4 diff --git a/README.md b/README.md index e9fed60..8d51834 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ Fill out values in the .env and you're good to go! - `!recoveraccount` - Reset your password - `!deleteaccount` - Delete your Jellyfin account - `!trialaccount` - Create a 24-hour trial Jellyfin account. Only if ENABLE_TRIAL_ACCOUNTS=True +- `!what2watch` - Lists 5 random movie suggestions from the Jellyfin Library ***Admin Commands*** - `!cleanup` - Remove Jellyfin accounts from users without roles diff --git a/app.py b/app.py index d58a4c4..0c2d376 100644 --- a/app.py +++ b/app.py @@ -6,6 +6,7 @@ import asyncio import os from dotenv import load_dotenv import pytz +import random # ===================== # ENV + VALIDATION @@ -615,6 +616,59 @@ async def deleteaccount(ctx, username: str = None): else: await ctx.send(f"❌ Failed to delete Jellyfin account **{username}**.") +@bot.command() +async def what2watch(ctx): + """Pick 5 random movies from the Jellyfin library with embeds and posters.""" + member = ctx.guild.get_member(ctx.author.id) if ctx.guild else None + if not member or not has_required_role(member): + await ctx.send(f"❌ {ctx.author.mention}, you don’t have the required role to use this command.") + return + + headers = {"X-Emby-Token": JELLYFIN_API_KEY} + try: + # Fetch all movies + r = requests.get(f"{JELLYFIN_URL}/Items?IncludeItemTypes=Movie&Recursive=true", headers=headers, timeout=10) + if r.status_code != 200: + await ctx.send(f"❌ Failed to fetch movies. Status code: {r.status_code}") + return + + movies = r.json().get("Items", []) + if not movies: + await ctx.send("⚠️ No movies found in the library.") + return + + # Pick 5 random movies + selection = random.sample(movies, min(5, len(movies))) + + embed = discord.Embed( + title="🎬 What to Watch", + description="Here are 5 random movie suggestions from the library:", + color=discord.Color.blue() + ) + + for movie in selection: + name = movie.get("Name") + year = movie.get("ProductionYear", "N/A") + runtime = movie.get("RunTimeTicks", None) + runtime_min = int(runtime / 10_000_000 / 60) if runtime else "N/A" + + # Poster URL if available + poster_url = None + if "PrimaryImageTag" in movie and movie["PrimaryImageTag"]: + poster_url = f"{JELLYFIN_URL}/Items/{movie['Id']}/Images/Primary?tag={movie['PrimaryImageTag']}&quality=90" + + field_value = f"Year: {year}\nRuntime: {runtime_min} min" + embed.add_field(name=name, value=field_value, inline=False) + + if poster_url: + embed.set_image(url=poster_url) # Only last movie's poster will appear as main embed image + + await ctx.send(embed=embed) + + except Exception as e: + await ctx.send(f"❌ Error fetching movies: {e}") + print(f"[what2watch] Error: {e}") + @bot.command() async def cleanup(ctx): @@ -914,6 +968,7 @@ async def help_command(ctx): f"`{PREFIX}createaccount ` - Create your Jellyfin account", f"`{PREFIX}recoveraccount ` - Reset your password", f"`{PREFIX}deleteaccount ` - Delete your Jellyfin account" + f"`{PREFIX}what2watch` - Lists 5 random movie suggestions from the Jellyfin Library" ] # Only show trialaccount if enabled