diff --git a/redbot/cogs/streams/streams.py b/redbot/cogs/streams/streams.py index bf55657e6..c51a280a1 100644 --- a/redbot/cogs/streams/streams.py +++ b/redbot/cogs/streams/streams.py @@ -467,7 +467,7 @@ class Streams: except OfflineStream: for message in stream._messages_cache: try: - autodelete = self.db.guild(message.guild).autodelete() + autodelete = await self.db.guild(message.guild).autodelete() if autodelete: await message.delete() except: @@ -508,30 +508,51 @@ class Streams: async def check_communities(self): for community in self.communities: try: - streams = community.get_community_streams() + stream_list = await community.get_community_streams() except CommunityNotFound: print(_("Community {} not found!").format(community.name)) continue except OfflineCommunity: - pass - else: - token = self.db.tokens().get(TwitchStream.__name__) - for channel in community.channels: - chn = self.bot.get_channel(channel) - await chn.send(_("Online streams for {}").format(community.name)) - for stream in streams: - stream_obj = TwitchStream( - token=token, name=stream["channel"]["name"], - id=stream["_id"] - ) + for message in community._messages_cache: try: - emb = await stream_obj.is_online() + autodelete = await self.db.guild(message.guild).autodelete() + if autodelete: + await message.delete() except: pass + community._messages_cache.clear() + except: + pass + else: + for channel in community.channels: + chn = self.bot.get_channel(channel) + streams = await self.filter_streams(stream_list, chn) + emb = await community.make_embed(streams) + chn_msg = [m for m in community._messages_cache if m.channel == chn] + if not chn_msg: + mentions = await self._get_mention_str(chn.guild) + if mentions: + msg = await chn.send(mentions, embed=emb) + else: + msg = await chn.send(embed=emb) + community._messages_cache.append(msg) else: - for channel in community.channels: - chn = self.bot.get_channel(channel) - await chn.send(embed=emb) + chn_msg = sorted(chn_msg, key=lambda x: x.created_at, reverse=True)[0] + community._messages_cache.remove(chn_msg) + await chn_msg.edit(embed=emb) + community._messages_cache.append(chn_msg) + + async def filter_streams(self, streams: list, channel: discord.TextChannel) -> list: + filtered = [] + for stream in streams: + tw_id = str(stream["channel"]["_id"]) + for alert in self.streams: + if isinstance(alert, TwitchStream) and alert.id == tw_id: + if channel.id in alert.channels: + break + else: + filtered.append(stream) + return filtered async def load_streams(self): streams = [] diff --git a/redbot/cogs/streams/streamtypes.py b/redbot/cogs/streams/streamtypes.py index e28b740dd..6e3c05a05 100644 --- a/redbot/cogs/streams/streamtypes.py +++ b/redbot/cogs/streams/streamtypes.py @@ -1,6 +1,6 @@ from .errors import StreamNotFound, APIError, OfflineStream, CommunityNotFound, OfflineCommunity, \ InvalidYoutubeCredentials, InvalidTwitchCredentials -from random import choice +from random import choice, sample from string import ascii_letters import discord import aiohttp @@ -27,6 +27,7 @@ class TwitchCommunity: self.name = kwargs.pop("name") self.id = kwargs.pop("id", None) self.channels = kwargs.pop("channels", []) + self._messages_cache = [] self._token = kwargs.pop("token", None) self.type = self.__class__.__name__ @@ -61,7 +62,8 @@ class TwitchCommunity: "Client-ID": str(self._token) } params = { - "community_id": self.id + "community_id": self.id, + "limit": 100 } url = TWITCH_BASE_URL + "/kraken/streams" async with aiohttp.ClientSession() as session: @@ -79,6 +81,35 @@ class TwitchCommunity: else: raise APIError() + async def make_embed(self, streams: list) -> discord.Embed: + headers = { + "Accept": "application/vnd.twitchtv.v5+json", + "Client-ID": str(self._token) + } + async with aiohttp.ClientSession() as session: + async with session.get( + "{}/{}".format(TWITCH_COMMUNITIES_ENDPOINT, self.id), + headers=headers) as r: + data = await r.json() + + avatar = data["avatar_image_url"] + title = "Channels currently streaming to {}".format(data["display_name"]) + url = "https://www.twitch.tv/communities/{}".format(self.name) + embed = discord.Embed(title=title, url=url) + embed.set_image(url=avatar) + if len(streams) >= 10: + stream_list = sample(streams, 10) + else: + stream_list = streams + for stream in stream_list: + name = "[{}]({})".format( + stream["channel"]["display_name"], stream["channel"]["url"] + ) + embed.add_field(name=stream["channel"]["status"], value=name, inline=False) + embed.color = 0x6441A4 + + return embed + def export(self): data = {} for k, v in self.__dict__.items():