diff --git a/playitstatus/playitstatus.py b/playitstatus/playitstatus.py index 40c6c63..1b178b3 100644 --- a/playitstatus/playitstatus.py +++ b/playitstatus/playitstatus.py @@ -1,7 +1,6 @@ import discord from redbot.core import commands, Config import aiohttp -import asyncio from datetime import datetime @@ -11,23 +10,13 @@ class PlayitStatus(commands.Cog): def __init__(self, bot): self.bot = bot self.config = Config.get_conf(self, identifier=1234567890) - self.config.register_guild( - channel_id=None, - monitor_enabled=False, - last_status={}, - ) + self.config.register_global(channel_id=None, last_status={}) self.session = None - self.task = None self.api_url = "https://status.playit.gg/api/getMonitorList/AxwIw5PSiW" - self.feed_url = "https://status.playit.gg/api/getEventFeed/AxwIw5PSiW" async def red_delete_data_for_user(self, **kwargs): return - def cog_unload(self): - if self.task: - self.task.cancel() - async def init_session(self): if self.session is None or self.session.closed: self.session = aiohttp.ClientSession() @@ -43,149 +32,75 @@ class PlayitStatus(commands.Cog): pass return [] - async def fetch_events(self): - await self.init_session() - try: - async with self.session.get(self.feed_url) as resp: - if resp.status == 200: - data = await resp.json() - return data.get("results", []) - except Exception: - pass - return [] - - async def monitor_loop(self): - while True: - try: - await asyncio.sleep(10) - guilds = await self.config.all_guilds() - for guild_id, guild_data in guilds.items(): - if not guild_data.get("monitor_enabled"): - continue - channel_id = guild_data.get("channel_id") - if not channel_id: - continue - channel = self.bot.get_channel(channel_id) - if not channel: - continue - monitors = await self.fetch_status() - last_status = guild_data.get("last_status", {}) - for monitor in monitors: - name = monitor.get("name", "Unknown") - status_class = monitor.get("statusClass", "unknown") - is_up = status_class == "success" - was_up = last_status.get(name, True) - if not is_up and was_up: - embed = discord.Embed( - title="Playit.gg Status Alert", - description=f"**{name}** is now **DOWN**", - color=discord.Color.red(), - timestamp=datetime.utcnow(), - ) - embed.add_field( - name="Status", - value=status_class, - inline=True, - ) - embed.set_footer(text="Playit.gg Status Monitor") - await channel.send(embed=embed) - elif is_up and not was_up: - embed = discord.Embed( - title="Playit.gg Status Update", - description=f"**{name}** is now **UP**", - color=discord.Color.green(), - timestamp=datetime.utcnow(), - ) - embed.set_footer(text="Playit.gg Status Monitor") - await channel.send(embed=embed) - last_status[name] = is_up - await self.config.guild( - self.bot.get_guild(guild_id) - ).last_status.set(last_status) - except asyncio.CancelledError: - break - except Exception: - await asyncio.sleep(5) - - @commands.group() - @commands.admin_or_permissions(manage_guild=True) - async def playitstatus(self, ctx): - """Playit.gg status monitor commands.""" - pass - - @playitstatus.command() - async def channel(self, ctx, channel: discord.TextChannel): - """Set the channel for status alerts.""" - await self.config.guild(ctx.guild).channel_id.set(channel.id) - await ctx.send(f"Status alerts will be sent to {channel.mention}") - - @playitstatus.command() - async def start(self, ctx): - """Start monitoring playit.gg status.""" - await self.config.guild(ctx.guild).monitor_enabled.set(True) - await self.config.guild(ctx.guild).last_status.set({}) - if not self.task or self.task.done(): - self.task = self.bot.loop.create_task(self.monitor_loop()) - await ctx.send("Started monitoring playit.gg status (checks every 10 seconds)") - - @playitstatus.command() - async def stop(self, ctx): - """Stop monitoring playit.gg status.""" - await self.config.guild(ctx.guild).monitor_enabled.set(False) - await ctx.send("Stopped monitoring playit.gg status") - - @playitstatus.command() - async def status(self, ctx): - """Check current playit.gg status.""" - monitors = await self.fetch_status() - if not monitors: - await ctx.send("Failed to fetch status") - return - embed = discord.Embed( - title="Playit.gg Current Status", - color=discord.Color.blue(), - timestamp=datetime.utcnow(), - ) + async def send_status(self, channel, monitors, changed_only=False): + last_status = await self.config.last_status() + changed = False for monitor in monitors: name = monitor.get("name", "Unknown") status_class = monitor.get("statusClass", "unknown") - emoji = "🟢" if status_class == "success" else "🔴" - embed.add_field( - name=f"{emoji} {name}", - value=status_class.upper(), - inline=True, - ) - await ctx.send(embed=embed) + is_up = status_class == "success" + was_up = last_status.get(name, True) + if changed_only and is_up == was_up: + continue + changed = True + if not is_up and was_up: + embed = discord.Embed( + title="playit.gg DOWN", + description=f"**{name}** is now **DOWN**", + color=discord.Color.red(), + timestamp=datetime.utcnow(), + ) + elif is_up and not was_up: + embed = discord.Embed( + title="playit.gg UP", + description=f"**{name}** is back **UP**", + color=discord.Color.green(), + timestamp=datetime.utcnow(), + ) + else: + continue + embed.set_footer(text="playit.gg Status Monitor") + await channel.send(embed=embed) + last_status[name] = is_up + await self.config.last_status.set(last_status) + return changed - @playitstatus.command() - async def events(self, ctx): - """Check recent status events.""" - events = await self.fetch_events() - if not events: - await ctx.send("No recent events") + @commands.group() + @commands.admin_or_permissions(manage_guild=True) + async def playit(self, ctx): + """playit.gg status monitor.""" + pass + + @playit.command() + async def channel(self, ctx, channel_id: int): + """Set the channel ID for status updates.""" + channel = self.bot.get_channel(channel_id) + if not channel: + await ctx.send("Channel not found.") return - embed = discord.Embed( - title="Playit.gg Recent Events", - color=discord.Color.orange(), - timestamp=datetime.utcnow(), - ) - for event in events[:5]: - monitor = event.get("monitor", "Unknown") - date = event.get("timeGMT", "Unknown") - duration = event.get("duration", "Unknown") - label = event.get("label", "Unknown") - embed.add_field( - name=monitor, - value=f"{label.upper()} - {date}\nDuration: {duration}", - inline=False, - ) - await ctx.send(embed=embed) - - @playitstatus.command() - async def test(self, ctx): - """Test if the API is reachable.""" + await self.config.channel_id.set(channel_id) monitors = await self.fetch_status() if monitors: - await ctx.send(f"API reachable. Found {len(monitors)} monitors.") + await self.send_status(channel, monitors) + await ctx.send(f"Monitoring set to {channel.mention}. Status posted.") else: - await ctx.send("Failed to reach API") + await ctx.send("Channel set but failed to fetch status.") + + @playit.command() + async def status(self, ctx): + """Check playit.gg status now.""" + channel_id = await self.config.channel_id() + if not channel_id: + await ctx.send("No channel set. Use `[p]playit channel ` first.") + return + channel = self.bot.get_channel(channel_id) + if not channel: + await ctx.send("Channel not found.") + return + monitors = await self.fetch_status() + if not monitors: + await ctx.send("Failed to fetch status.") + return + changed = await self.send_status(channel, monitors, changed_only=True) + if not changed: + await ctx.send("No changes. All services stable.")