From b69b5b30056c5b4fb213b20ee0970f22de5c0503 Mon Sep 17 00:00:00 2001 From: Twentysix Date: Wed, 8 Feb 2017 19:03:05 +0100 Subject: [PATCH] [Streams] Added embeds and toggleable mass mentions --- cogs/streams.py | 188 +++++++++++++++++++++++++++--------------------- 1 file changed, 108 insertions(+), 80 deletions(-) diff --git a/cogs/streams.py b/cogs/streams.py index 3d5979697..8568cfa4b 100644 --- a/cogs/streams.py +++ b/cogs/streams.py @@ -4,12 +4,11 @@ from .utils.dataIO import dataIO from .utils.chat_formatting import * from .utils import checks from __main__ import send_cmd_help +from collections import defaultdict import os import re -import time import aiohttp import asyncio -from copy import deepcopy import logging @@ -23,7 +22,8 @@ class Streams: self.twitch_streams = dataIO.load_json("data/streams/twitch.json") self.hitbox_streams = dataIO.load_json("data/streams/hitbox.json") self.beam_streams = dataIO.load_json("data/streams/beam.json") - self.settings = dataIO.load_json("data/streams/settings.json") + settings = dataIO.load_json("data/streams/settings.json") + self.settings = defaultdict(dict, settings) @commands.command() async def hitbox(self, stream: str): @@ -32,9 +32,8 @@ class Streams: regex = r'^(https?\:\/\/)?(www\.)?(hitbox\.tv\/)' stream = re.sub(regex, '', stream) online = await self.hitbox_online(stream) - if online is True: - await self.bot.say("http://www.hitbox.tv/{}/" - " is online!".format(stream)) + if isinstance(online, discord.Embed): + await self.bot.say(embed=online) elif online is False: await self.bot.say(stream + " is offline.") elif online is None: @@ -49,9 +48,8 @@ class Streams: regex = r'^(https?\:\/\/)?(www\.)?(twitch\.tv\/)' stream = re.sub(regex, '', stream) online = await self.twitch_online(stream) - if online is True: - await self.bot.say("http://www.twitch.tv/{} " - "is online!".format(stream)) + if isinstance(online, discord.Embed): + await self.bot.say(embed=online) elif online is False: await self.bot.say(stream + " is offline.") elif online == 404: @@ -70,8 +68,8 @@ class Streams: regex = r'^(https?\:\/\/)?(www\.)?(beam\.pro\/)' stream = re.sub(regex, '', stream) online = await self.beam_online(stream) - if online is True: - await self.bot.say("https://beam.pro/{} is online!".format(stream)) + if isinstance(online, discord.Embed): + await self.bot.say(embed=online) elif online is False: await self.bot.say(stream + " is offline.") elif online is None: @@ -278,13 +276,13 @@ class Streams: "channel.") @commands.group(pass_context=True) - @checks.is_owner() async def streamset(self, ctx): """Stream settings""" if ctx.invoked_subcommand is None: await send_cmd_help(ctx) @streamset.command() + @checks.is_owner() async def twitchtoken(self, token : str): """Sets the Client-ID for Twitch @@ -293,17 +291,40 @@ class Streams: dataIO.save_json("data/streams/settings.json", self.settings) await self.bot.say('Twitch Client-ID set.') + @streamset.command(pass_context=True) + @checks.admin() + async def mention(self, ctx, *, mention_type : str): + """Sets mentions for stream alerts + + Types: everyone, here, none""" + server = ctx.message.server + mention_type = mention_type.lower() + + if mention_type in ("everyone", "here"): + self.settings[server.id]["MENTION"] = "@" + mention_type + await self.bot.say("When a stream is online @\u200b{} will be " + "mentioned.".format(mention_type)) + elif mention_type == "none": + self.settings[server.id]["MENTION"] = "" + await self.bot.say("Mentions disabled.") + else: + await self.bot.send_cmd_help(ctx) + + dataIO.save_json("data/streams/settings.json", self.settings) + async def hitbox_online(self, stream): - url = "https://api.hitbox.tv/user/" + stream + url = "https://api.hitbox.tv/media/live/" + stream try: async with aiohttp.get(url) as r: data = await r.json() - if data["is_live"] == "0": - return False - elif data["is_live"] == "1": - return True - elif data["is_live"] is None: + if "livestream" not in data: return None + if data["livestream"][0]["media_is_live"] == "0": + return False + elif data["livestream"][0]["media_is_live"] == "1": + data = self.hitbox_embed(data) + return data + return "error" except: return "error" @@ -322,7 +343,8 @@ class Streams: elif data["stream"] is None: return False elif data["stream"]: - return True + embed = self.twitch_embed(data) + return embed except: return "error" return "error" @@ -334,7 +356,8 @@ class Streams: data = await r.json() if "online" in data: if data["online"] is True: - return True + data = self.beam_embed(data) + return data else: return False elif "error" in data: @@ -343,73 +366,78 @@ class Streams: return "error" return "error" + def twitch_embed(self, data): + channel = data["stream"]["channel"] + url = channel["url"] + embed = discord.Embed(title=channel["status"], url=url) + embed.set_author(name=channel["display_name"]) + embed.add_field(name="Followers", value=channel["followers"]) + embed.add_field(name="Total views", value=channel["views"]) + embed.set_thumbnail(url=channel["logo"]) + embed.set_image(url=data["stream"]["preview"]["medium"]) + embed.set_footer(text="Playing: " + channel["game"]) + return embed + + def hitbox_embed(self, data): + base_url = "https://edge.sf.hitbox.tv" + livestream = data["livestream"][0] + channel = livestream["channel"] + url = channel["channel_link"] + embed = discord.Embed(title=livestream["media_status"], url=url) + embed.set_author(name=livestream["media_name"]) + embed.add_field(name="Followers", value=channel["followers"]) + #embed.add_field(name="Views", value=channel["views"]) + embed.set_thumbnail(url=base_url + channel["user_logo"]) + embed.set_image(url=base_url + livestream["media_thumbnail"]) + embed.set_footer(text="Playing: " + livestream["category_name"]) + return embed + + def beam_embed(self, data): + user = data["user"] + url = "https://beam.pro/" + data["token"] + embed = discord.Embed(title=data["name"], url=url) + embed.set_author(name=user["username"]) + embed.add_field(name="Followers", value=data["numFollowers"]) + embed.add_field(name="Total views", value=data["viewersTotal"]) + embed.set_thumbnail(url=user["avatarUrl"]) + embed.set_image(url=data["thumbnail"]["url"]) + if data["type"] is not None: + embed.set_footer(text="Playing: " + data["type"]["name"]) + return embed + async def stream_checker(self): CHECK_DELAY = 60 while self == self.bot.get_cog("Streams"): + save = False - old = (deepcopy(self.twitch_streams), deepcopy( - self.hitbox_streams), deepcopy(self.beam_streams)) + streams = ((self.twitch_streams, self.twitch_online), + (self.hitbox_streams, self.hitbox_online), + (self.beam_streams, self.beam_online)) - for stream in self.twitch_streams: - online = await self.twitch_online(stream["NAME"]) - if online is True and not stream["ALREADY_ONLINE"]: - stream["ALREADY_ONLINE"] = True - for channel in stream["CHANNELS"]: - channel_obj = self.bot.get_channel(channel) - if channel_obj is None: - continue - can_speak = channel_obj.permissions_for(channel_obj.server.me).send_messages - if channel_obj and can_speak: - await self.bot.send_message( - self.bot.get_channel(channel), - "http://www.twitch.tv/" - "{} is online!".format(stream["NAME"])) - else: - if stream["ALREADY_ONLINE"] and not online: - stream["ALREADY_ONLINE"] = False - await asyncio.sleep(0.5) + for stream_type in streams: + streams = stream_type[0] + parser = stream_type[1] + for stream in streams: + online = await parser(stream["NAME"]) + if isinstance(online, discord.Embed) and not stream["ALREADY_ONLINE"]: + save = True + stream["ALREADY_ONLINE"] = True + for channel in stream["CHANNELS"]: + channel_obj = self.bot.get_channel(channel) + if channel_obj is None: + continue + mention = self.settings.get(channel_obj.server.id, {}).get("MENTION", "") + can_speak = channel_obj.permissions_for(channel_obj.server.me).send_messages + if channel_obj and can_speak: + await self.bot.send_message(channel_obj, mention, embed=online) + else: + if stream["ALREADY_ONLINE"] and not online: + save = True + stream["ALREADY_ONLINE"] = False + await asyncio.sleep(0.5) - for stream in self.hitbox_streams: - online = await self.hitbox_online(stream["NAME"]) - if online is True and not stream["ALREADY_ONLINE"]: - stream["ALREADY_ONLINE"] = True - for channel in stream["CHANNELS"]: - channel_obj = self.bot.get_channel(channel) - if channel_obj is None: - continue - can_speak = channel_obj.permissions_for(channel_obj.server.me).send_messages - if channel_obj and can_speak: - await self.bot.send_message( - self.bot.get_channel(channel), - "http://www.hitbox.tv/" - "{} is online!".format(stream["NAME"])) - else: - if stream["ALREADY_ONLINE"] and not online: - stream["ALREADY_ONLINE"] = False - await asyncio.sleep(0.5) - - for stream in self.beam_streams: - online = await self.beam_online(stream["NAME"]) - if online is True and not stream["ALREADY_ONLINE"]: - stream["ALREADY_ONLINE"] = True - for channel in stream["CHANNELS"]: - channel_obj = self.bot.get_channel(channel) - if channel_obj is None: - continue - can_speak = channel_obj.permissions_for(channel_obj.server.me).send_messages - if channel_obj and can_speak: - await self.bot.send_message( - self.bot.get_channel(channel), - "https://beam.pro/" - "{} is online!".format(stream["NAME"])) - else: - if stream["ALREADY_ONLINE"] and not online: - stream["ALREADY_ONLINE"] = False - await asyncio.sleep(0.5) - - if old != (self.twitch_streams, self.hitbox_streams, - self.beam_streams): + if save: dataIO.save_json("data/streams/twitch.json", self.twitch_streams) dataIO.save_json("data/streams/hitbox.json", self.hitbox_streams) dataIO.save_json("data/streams/beam.json", self.beam_streams)