diff --git a/clients/discord.py b/clients/discord.py index bda23e5..0050fca 100644 --- a/clients/discord.py +++ b/clients/discord.py @@ -2,7 +2,9 @@ import datetime import re import time +import dateutil.parser import discord +import fuzzywuzzy.process import twitter from commands import CommandError @@ -80,6 +82,29 @@ class DiscordClient(discord.Client): if cmd == message.content: await self.send_message(message.channel, resp.format(user=message.author.mention)) + def _guess_gifted_subs(self, nick, time): + subs = self.commands.plausible_gifted_subs(time) + choices = {i: s['receiver'] for i, s in enumerate(subs)} + guesses = fuzzywuzzy.process.extractWithoutOrder(nick, choices, score_cutoff=50) + result = [] + for _, score, i in guesses: + days = (time - dateutil.parser.parse(subs[i]['time'])).days + result.append((subs[i]['receiver'], score, days)) + return sorted(result, key=lambda x: (x[1], 32 - x[2], x[0]), reverse=True) + + async def _process_gifted_subs(self, user, gifted_subs): + header = '{0: <20} | {1: <5} | {2: <11}'.format('Twitch username', 'Match', 'When') + table = [header, '-' * len(header)] + for nick, score, days in gifted_subs: + table.append('{0: <20} | {1: >4}% | {2: >2} days ago'.format(nick, score, days)) + message = ('It seems that {0} could have been gifted a sub. ' + 'Here are the most probable candidates:\n```{1}```').format(user.mention, '\n'.join(table)) + channel = self.config['Discord'].get('gifted_sub_notice_channel') + try: + await self.send_message(discord.Object(channel), message) + except discord.errors.Forbidden: + pass + async def _process_new_member(self, message): new_members_channel = self.config['Discord'].get('new_members_channel') info_channel = self.config['Discord'].get('info_channel') @@ -100,6 +125,10 @@ class DiscordClient(discord.Client): user=message.author.mention, info_channel=info_channel.mention)) except discord.errors.Forbidden: pass + self.logger.info('Looking for gifted subs matching {0}'.format(message.author.display_name)) + gifted_subs = self._guess_gifted_subs(message.author.display_name, datetime.datetime.utcnow()) + if gifted_subs: + await self._process_gifted_subs(message.author, gifted_subs) async def _process_announcement(self, message): announcer = self.config['Discord'].get('announcer') diff --git a/commands.py b/commands.py index 30f344e..8174d8c 100644 --- a/commands.py +++ b/commands.py @@ -77,6 +77,18 @@ class Commands(object): else: return messages + def plausible_gifted_subs(self, time): + try: + gifted_subs = self._get_gifted_subs(dict( + older_than=time.isoformat(), + newer_than=(time - datetime.timedelta(days=31)).isoformat(), + sort_by='time', + sort_order='desc')).json() + except (requests.exceptions.HTTPError, IndexError): + raise CommandError('no gifted subs found') + else: + return gifted_subs + def last_quote(self): try: quotes = self._get_quotes(dict( @@ -157,6 +169,12 @@ class Commands(object): # FIXME: reindex subsequent quotes return r + def _get_gifted_subs(self, params): + api_url = self.config['GiftedSubs'].get('api_url') + r = requests.get('{0}/gifted-subs'.format(api_url), params=params) + r.raise_for_status() + return r + def _post_gifted_subs(self, data): api_url = self.config['GiftedSubs'].get('api_url') api_key = self.config['GiftedSubs'].get('api_key') diff --git a/settings.cfg.example b/settings.cfg.example index c4aa298..096e68d 100644 --- a/settings.cfg.example +++ b/settings.cfg.example @@ -17,6 +17,8 @@ welcome_pattern = Hi {user}! Welcome to the Cheese Horde! Please check out all o announcer = 369539730989252609 # #cheesenouncements announcement_channels = 383778221004554249,352145992256061440 +# #gifted_alerts +gifted_sub_notice_channel = 479792436080672789 [Twitter] consumer_key = __TWITTER_CONSUMER_KEY__