104 lines
3.9 KiB
Python
104 lines
3.9 KiB
Python
import asyncio
|
|
import discord
|
|
import traceback
|
|
import utils
|
|
|
|
from discord.ext import commands, tasks
|
|
|
|
BASE_URL = "https://api.picarto.tv/v1"
|
|
|
|
|
|
def produce_embed(*channels):
|
|
description = ""
|
|
# Loop through each channel and produce the information that will go in the description
|
|
for channel in channels:
|
|
url = f"https://picarto.tv/{channel.get('name')}"
|
|
description = f"""{description}\n\n**Title:** [{channel.get("title")}]({url})
|
|
**Channel:** [{channel.get("name")}]({url})
|
|
**Adult:** {"Yes" if channel.get("adult") else "No"}
|
|
**Gaming:** {"Yes" if channel.get("gaming") else "No"}
|
|
**Commissions:** {"Yes" if channel.get("commissions") else "No"}"""
|
|
|
|
return discord.Embed(
|
|
title="Channels that have gone online!", description=description.strip()
|
|
)
|
|
|
|
|
|
class Picarto(commands.Cog):
|
|
"""Pretty self-explanatory"""
|
|
|
|
def __init__(self, bot):
|
|
self.bot = bot
|
|
self.channel_info = {}
|
|
|
|
# noinspection PyAttributeOutsideInit
|
|
async def get_online_users(self):
|
|
# This method is in place to just return all online users so we can compare against it
|
|
url = BASE_URL + "/online"
|
|
payload = {"adult": "true", "gaming": "true"}
|
|
channel_info = {}
|
|
channels = await utils.request(url, payload=payload)
|
|
if channels and isinstance(channels, (list, set, tuple)) and len(channels) > 0:
|
|
for channel in channels:
|
|
name = channel["name"]
|
|
previous = self.channel_info.get(name)
|
|
# There are three statuses, on, remained, and off
|
|
# On means they were off previously, but are now online
|
|
# Remained means they were on previous, and are still on
|
|
# Off means they were on preivous, but are now offline
|
|
# If they weren't included in the online channels...well they're off
|
|
if previous is None:
|
|
channel_info[name] = channel
|
|
channel_info[name]["status"] = "on"
|
|
elif previous["status"] in ["on", "remaining"]:
|
|
channel_info[name] = channel
|
|
channel_info[name]["status"] = "remaining"
|
|
# After loop has finished successfully, we want to override the statuses of the channels
|
|
self.channel_info = channel_info
|
|
|
|
@tasks.loop(seconds=30)
|
|
async def check_channels(self):
|
|
query = """
|
|
SELECT
|
|
id, followed_picarto_channels, COALESCE(picarto_alerts, default_alerts) AS channel
|
|
FROM
|
|
guilds
|
|
WHERE
|
|
COALESCE(picarto_alerts, default_alerts) IS NOT NULL
|
|
"""
|
|
# Recheck who is currently online
|
|
await self.get_online_users()
|
|
# Now get all guilds and their picarto channels they follow and loop through them
|
|
results = await self.bot.db.fetch(query) or []
|
|
for result in results:
|
|
# Get all the channels that have gone online
|
|
gone_online = [
|
|
self.channel_info.get(name)
|
|
for name in result["followed_picarto_channels"]
|
|
if self.channel_info.get(name, {}).get("status", "off") == "on"
|
|
]
|
|
# If they've gone online, produce the embed for them and send it
|
|
if gone_online:
|
|
embed = produce_embed(*gone_online)
|
|
g = self.bot.get_guild(result["id"])
|
|
channel = g.get_channel(result["channel"])
|
|
if channel is not None:
|
|
try:
|
|
await channel.send(embed=embed)
|
|
except (discord.Forbidden, discord.HTTPException, AttributeError):
|
|
pass
|
|
|
|
@check_channels.before_loop
|
|
async def before_check_channels(self):
|
|
await self.get_online_users()
|
|
await asyncio.sleep(30)
|
|
|
|
@check_channels.error
|
|
async def picarto_error(self, error):
|
|
await utils.log_error(error, self.bot)
|
|
await self.check_channels.restart()
|
|
|
|
|
|
def setup(bot):
|
|
bot.add_cog(Picarto(bot))
|