From 3b2328423bbde2c1fc1c9de07adbc07ad319f026 Mon Sep 17 00:00:00 2001 From: Pengu Date: Wed, 10 Sep 2025 11:08:08 -0500 Subject: [PATCH] 1.0.5 (Added Stream Viewing) --- CHANGELOG.md | 1 + README.md | 1 + app.py | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++- version.json | 2 +- version.txt | 2 +- 5 files changed, 70 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7114d4..b5a8d56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ - Added Timezone support in .env - Added the `what2watch` command. Lists 5 random movie suggestions from the Jellyfin Library +- Added `activestreams` command. Lists all active Jellyfin Streams # 1.0.4 diff --git a/README.md b/README.md index 8d51834..2804f2f 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ Fill out values in the .env and you're good to go! - `!searchaccount` - Find linked Discord user - `!searchdiscord` @user - Find linked Jellyfin account - `!scanlibraries` - Scan all Jellyfin libraries +- `!activestreams` - View all Active Jellyfin streams - `!link` @user - Manually link accounts - `!unlink` @user - Manually unlink accounts diff --git a/app.py b/app.py index 0c2d376..46d830a 100644 --- a/app.py +++ b/app.py @@ -44,7 +44,7 @@ DB_NAME = get_env_var("DB_NAME") LOCAL_TZ = pytz.timezone(get_env_var("LOCAL_TZ", str, required=False) or "America/Chicago") -BOT_VERSION = "1.0.4" +BOT_VERSION = "1.0.5" VERSION_URL = "https://raw.githubusercontent.com/PenguCCN/Jellycord/main/version.txt" RELEASES_URL = "https://github.com/PenguCCN/Jellycord/releases" @@ -828,6 +828,70 @@ async def scanlibraries(ctx): await ctx.send(f"❌ Failed to start library scan. Status code: {response.status_code}") +@bot.command() +async def activestreams(ctx): + """Admin-only: Show currently active Jellyfin user streams (movies/episodes only) with progress.""" + if not has_admin_role(ctx.author): + await ctx.send("❌ You don’t have permission to use this command.") + return + + headers = {"X-Emby-Token": JELLYFIN_API_KEY} + try: + r = requests.get(f"{JELLYFIN_URL}/Sessions", headers=headers, timeout=10) + if r.status_code != 200: + await ctx.send(f"❌ Failed to fetch active streams. Status code: {r.status_code}") + return + + sessions = r.json() + # Only keep sessions that are actively playing a Movie or Episode + active_streams = [ + s for s in sessions + if s.get("NowPlayingItem") and s["NowPlayingItem"].get("Type") in ("Movie", "Episode") + ] + + if not active_streams: + await ctx.send("ℹ️ No active movie or episode streams at the moment.") + return + + embed = discord.Embed( + title="📺 Active Jellyfin Streams", + description=f"Currently {len(active_streams)} active stream(s):", + color=discord.Color.green() + ) + + for session in active_streams: + user_name = session.get("UserName", "Unknown User") + device = session.get("DeviceName", "Unknown Device") + media = session.get("NowPlayingItem", {}) + media_type = media.get("Type", "Unknown") + media_name = media.get("Name", "Unknown Title") + + # Get progress + try: + position_ticks = session.get("PlayState", {}).get("PositionTicks", 0) + runtime_ticks = media.get("RunTimeTicks", 1) # fallback to avoid division by zero + # Convert ticks to seconds (1 tick = 100 ns) + position_seconds = position_ticks / 10_000_000 + runtime_seconds = runtime_ticks / 10_000_000 + position_str = str(datetime.timedelta(seconds=int(position_seconds))) + runtime_str = str(datetime.timedelta(seconds=int(runtime_seconds))) + progress_str = f"[{position_str} / {runtime_str}]" + except Exception: + progress_str = "Unknown" + + embed.add_field( + name=f"{media_name} ({media_type})", + value=f"👤 {user_name}\n📱 {device}\n⏱ Progress: {progress_str}", + inline=False + ) + + await ctx.send(embed=embed) + + except Exception as e: + await ctx.send(f"❌ Error fetching active streams: {e}") + print(f"[activestreams] Error: {e}") + + @bot.command() async def link(ctx, jellyfin_username: str = None, user: discord.User = None, js_id: str = None): log_event(f"link invoked by {ctx.author}") @@ -991,6 +1055,7 @@ async def help_command(ctx): f"`{PREFIX}searchaccount ` - Find linked Discord user\n" f"`{PREFIX}searchdiscord @user` - Find linked Jellyfin account\n" f"`{PREFIX}scanlibraries` - Scan all Jellyfin libraries\n" + f"`{PREFIX}activestreams` - View all Active Jellyfin streams\n" f"{link_command}\n" f"`{PREFIX}unlink @user` - Manually unlink accounts\n" ), inline=False) diff --git a/version.json b/version.json index 580af15..49a645b 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{ "version": "1.0.4" } \ No newline at end of file +{ "version": "1.0.5" } \ No newline at end of file diff --git a/version.txt b/version.txt index a6a3a43..1464c52 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.0.4 \ No newline at end of file +1.0.5 \ No newline at end of file