|
|
|
@ -76,9 +76,8 @@ class DiscordClient(discord.Client):
|
|
|
|
|
self.logger.info('Logged in as {0}'.format(self.user.name))
|
|
|
|
|
|
|
|
|
|
async def on_message(self, message):
|
|
|
|
|
await self._process_new_member(message)
|
|
|
|
|
await self._process_announcement(message)
|
|
|
|
|
server = message.server.id if message.server else None
|
|
|
|
|
server = message.guild.id if message.guild else None
|
|
|
|
|
for pattern, action in self.supported_commands:
|
|
|
|
|
m = pattern.match(message.content)
|
|
|
|
|
if m:
|
|
|
|
@ -86,12 +85,35 @@ class DiscordClient(discord.Client):
|
|
|
|
|
for cmd, resp in self.extra_commands.items():
|
|
|
|
|
if cmd == message.content:
|
|
|
|
|
def repl(m):
|
|
|
|
|
emoji = discord.utils.get(message.server.emojis, name=m.group(0))
|
|
|
|
|
emoji = discord.utils.get(message.guild.emojis, name=m.group(0))
|
|
|
|
|
if not emoji:
|
|
|
|
|
emoji = discord.utils.get(self.get_all_emojis(), name=m.group(0))
|
|
|
|
|
return str(emoji) if emoji else m.string
|
|
|
|
|
resp = EMOJI_PATTERN.sub(repl, resp)
|
|
|
|
|
await self.send_message(message.channel, resp.format(user=message.author.mention))
|
|
|
|
|
await message.channel.send(resp.format(user=message.author.mention))
|
|
|
|
|
|
|
|
|
|
async def on_member_join(self, member):
|
|
|
|
|
new_members_channel = self.config['Discord'].getint('new_members_channel')
|
|
|
|
|
info_channel = self.config['Discord'].getint('info_channel')
|
|
|
|
|
welcome_channel = self.config['Discord'].getint('welcome_channel')
|
|
|
|
|
welcome_pattern = self.config['Discord'].get('welcome_pattern')
|
|
|
|
|
info_channel = self.get_channel(info_channel)
|
|
|
|
|
if member.guild.system_channel.id != new_members_channel:
|
|
|
|
|
return
|
|
|
|
|
if not info_channel:
|
|
|
|
|
return
|
|
|
|
|
welcome_channel = self.get_channel(welcome_channel)
|
|
|
|
|
if not welcome_channel:
|
|
|
|
|
return
|
|
|
|
|
try:
|
|
|
|
|
await welcome_channel.send(welcome_pattern.format(user=member.mention, info_channel=info_channel.mention))
|
|
|
|
|
except discord.errors.Forbidden:
|
|
|
|
|
pass
|
|
|
|
|
threshold = self.config['Discord'].getint('gifted_sub_threshold')
|
|
|
|
|
self.logger.info('Looking for gifted subs matching {0}'.format(member.display_name))
|
|
|
|
|
gifted_subs = self._guess_gifted_subs(member.display_name, datetime.datetime.utcnow(), threshold)
|
|
|
|
|
if gifted_subs:
|
|
|
|
|
await self._process_gifted_subs(member, gifted_subs)
|
|
|
|
|
|
|
|
|
|
def _guess_gifted_subs(self, nick, time, threshold):
|
|
|
|
|
subs = self.commands.plausible_gifted_subs(time)
|
|
|
|
@ -110,52 +132,27 @@ class DiscordClient(discord.Client):
|
|
|
|
|
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')
|
|
|
|
|
channel = self.config['Discord'].getint('gifted_sub_notice_channel')
|
|
|
|
|
try:
|
|
|
|
|
await self.send_message(discord.Object(channel), message)
|
|
|
|
|
await self.get_channel(channel).send(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')
|
|
|
|
|
welcome_channel = self.config['Discord'].get('welcome_channel')
|
|
|
|
|
welcome_pattern = self.config['Discord'].get('welcome_pattern')
|
|
|
|
|
if not message.channel or not message.server:
|
|
|
|
|
return
|
|
|
|
|
if message.channel.id != new_members_channel:
|
|
|
|
|
return
|
|
|
|
|
info_channel = [c for c in message.server.channels if c.id == info_channel]
|
|
|
|
|
if info_channel:
|
|
|
|
|
info_channel = info_channel[0]
|
|
|
|
|
else:
|
|
|
|
|
return
|
|
|
|
|
welcome_channel = discord.Object(welcome_channel)
|
|
|
|
|
try:
|
|
|
|
|
await self.send_message(welcome_channel, welcome_pattern.format(
|
|
|
|
|
user=message.author.mention, info_channel=info_channel.mention))
|
|
|
|
|
except discord.errors.Forbidden:
|
|
|
|
|
pass
|
|
|
|
|
threshold = self.config['Discord'].getint('gifted_sub_threshold')
|
|
|
|
|
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(), threshold)
|
|
|
|
|
if gifted_subs:
|
|
|
|
|
await self._process_gifted_subs(message.author, gifted_subs)
|
|
|
|
|
|
|
|
|
|
async def _process_announcement(self, message):
|
|
|
|
|
announcer = self.config['Discord'].get('announcer')
|
|
|
|
|
announcer = self.config['Discord'].getint('announcer')
|
|
|
|
|
channels = self.config['Discord'].get('announcement_channels').split(',')
|
|
|
|
|
channels = [int(c) for c in channels]
|
|
|
|
|
if not message.author or not message.channel:
|
|
|
|
|
return
|
|
|
|
|
if message.author.id != announcer or message.channel.id not in channels:
|
|
|
|
|
return
|
|
|
|
|
after = datetime.datetime.utcnow() - datetime.timedelta(minutes=5)
|
|
|
|
|
for channel in [discord.Object(c) for c in channels if c != message.channel.id]:
|
|
|
|
|
async for msg in self.logs_from(channel, after=after):
|
|
|
|
|
for channel in [self.get_channel(c) for c in channels if c != message.channel.id]:
|
|
|
|
|
async for msg in channel.history(after=after):
|
|
|
|
|
if msg.content == message.content:
|
|
|
|
|
return
|
|
|
|
|
try:
|
|
|
|
|
await self.send_message(channel, message.content)
|
|
|
|
|
await channel.send(message.content)
|
|
|
|
|
except discord.errors.Forbidden:
|
|
|
|
|
pass
|
|
|
|
|
announcement = self.config['Twitter'].get('announcement_pattern')
|
|
|
|
@ -164,8 +161,7 @@ class DiscordClient(discord.Client):
|
|
|
|
|
self.twitter_api.PostUpdate(announcement.format(**m.groupdict()))
|
|
|
|
|
|
|
|
|
|
async def _cooldown_failure(self, server, user, message, **kwargs):
|
|
|
|
|
await self.send_message(message.channel,
|
|
|
|
|
'Sorry {0}, you have to wait a while before running '
|
|
|
|
|
await message.channel.send('Sorry {0}, you have to wait a while before running '
|
|
|
|
|
'the same command again'.format(message.author.mention))
|
|
|
|
|
|
|
|
|
|
def _format_quote(self, quote):
|
|
|
|
@ -177,37 +173,37 @@ class DiscordClient(discord.Client):
|
|
|
|
|
try:
|
|
|
|
|
result = self.commands.last_quote()
|
|
|
|
|
except CommandError as e:
|
|
|
|
|
await self.send_message(message.channel, 'Sorry {0}, {1}'.format(message.author.mention, e))
|
|
|
|
|
await message.channel.send('Sorry {0}, {1}'.format(message.author.mention, e))
|
|
|
|
|
else:
|
|
|
|
|
await self.send_message(message.channel, self._format_quote(result))
|
|
|
|
|
await message.channel.send(self._format_quote(result))
|
|
|
|
|
|
|
|
|
|
async def _do_findquote(self, server, user, message, filter, **kwargs):
|
|
|
|
|
try:
|
|
|
|
|
result = self.commands.find_quote(filter)
|
|
|
|
|
except CommandError as e:
|
|
|
|
|
await self.send_message(message.channel, 'Sorry {0}, {1}'.format(message.author.mention, e))
|
|
|
|
|
await message.channel.send('Sorry {0}, {1}'.format(message.author.mention, e))
|
|
|
|
|
else:
|
|
|
|
|
await self.send_message(message.channel, self._format_quote(result))
|
|
|
|
|
await message.channel.send(self._format_quote(result))
|
|
|
|
|
|
|
|
|
|
@cooldown(retries=2, timeout=5*60, failure=_cooldown_failure)
|
|
|
|
|
async def _do_bellagram(self, server, user, message, **kwargs):
|
|
|
|
|
try:
|
|
|
|
|
bellagram = self.commands.bellagram()
|
|
|
|
|
except CommandError as e:
|
|
|
|
|
await self.send_message(message.channel, 'Sorry {0}, {1}'.format(message.author.mention, e))
|
|
|
|
|
await message.channel.send('Sorry {0}, {1}'.format(message.author.mention, e))
|
|
|
|
|
else:
|
|
|
|
|
embed = discord.Embed(title=bellagram['caption'], url=bellagram['url'], color=0xd2a517)
|
|
|
|
|
embed.set_image(url=bellagram['display_url'])
|
|
|
|
|
embed.set_author(name=bellagram['owner_username'], url=bellagram['owner_url'],
|
|
|
|
|
icon_url=bellagram['owner_profile_pic_url'])
|
|
|
|
|
await self.send_message(message.channel, embed=embed)
|
|
|
|
|
await message.channel.send(embed=embed)
|
|
|
|
|
|
|
|
|
|
@cooldown(retries=3, timeout=5*60, failure=_cooldown_failure)
|
|
|
|
|
async def _do_yt(self, server, user, message, query, **kwargs):
|
|
|
|
|
try:
|
|
|
|
|
result = self.commands.query_youtube(query)
|
|
|
|
|
except CommandError as e:
|
|
|
|
|
await self.send_message(message.channel, 'Sorry {0}, {1}'.format(message.author.mention, e))
|
|
|
|
|
await message.channel.send('Sorry {0}, {1}'.format(message.author.mention, e))
|
|
|
|
|
else:
|
|
|
|
|
if result['kind'] == 'playlist':
|
|
|
|
|
embed = discord.Embed(title=result['title'], url=result['url'],
|
|
|
|
@ -215,25 +211,25 @@ class DiscordClient(discord.Client):
|
|
|
|
|
embed.set_thumbnail(url=result['thumbnail_url'])
|
|
|
|
|
embed.set_author(name=result['channel_title'], url=result['channel_url'],
|
|
|
|
|
icon_url=result['channel_thumbnail_url'])
|
|
|
|
|
await self.send_message(message.channel, embed=embed)
|
|
|
|
|
await message.channel.send(embed=embed)
|
|
|
|
|
else:
|
|
|
|
|
await self.send_message(message.channel, '{title}\n{url}'.format(**result))
|
|
|
|
|
await message.channel.send('{title}\n{url}'.format(**result))
|
|
|
|
|
|
|
|
|
|
@cooldown(retries=3, timeout=5*60, failure=_cooldown_failure)
|
|
|
|
|
async def _do_clip(self, server, user, message, filter, **kwargs):
|
|
|
|
|
try:
|
|
|
|
|
result = self.commands.find_clip(filter)
|
|
|
|
|
except CommandError as e:
|
|
|
|
|
await self.send_message(message.channel, 'Sorry {0}, {1}'.format(message.author.mention, e))
|
|
|
|
|
await message.channel.send('Sorry {0}, {1}'.format(message.author.mention, e))
|
|
|
|
|
else:
|
|
|
|
|
await self.send_message(message.channel, '{title}\n{url}'.format(**result))
|
|
|
|
|
await message.channel.send('{title}\n{url}'.format(**result))
|
|
|
|
|
|
|
|
|
|
@cooldown(retries=3, timeout=5*60, failure=_cooldown_failure)
|
|
|
|
|
async def _do_cheese(self, server, user, message, query, **kwargs):
|
|
|
|
|
try:
|
|
|
|
|
result = self.commands.query_cheese_com(query)
|
|
|
|
|
except CommandError as e:
|
|
|
|
|
await self.send_message(message.channel, 'Sorry {0}, {1}'.format(message.author.mention, e))
|
|
|
|
|
await message.channel.send('Sorry {0}, {1}'.format(message.author.mention, e))
|
|
|
|
|
else:
|
|
|
|
|
embed = discord.Embed(title=result['name'], url=result['url'],
|
|
|
|
|
description=result['description'], color=0xffd700)
|
|
|
|
@ -246,16 +242,16 @@ class DiscordClient(discord.Client):
|
|
|
|
|
except ValueError:
|
|
|
|
|
name, value = 'Base', point
|
|
|
|
|
embed.add_field(name=name.strip(), value=value.strip(), inline=True)
|
|
|
|
|
await self.send_message(message.channel, embed=embed)
|
|
|
|
|
await message.channel.send(embed=embed)
|
|
|
|
|
|
|
|
|
|
async def _do_roll(self, server, user, message, formula, **kwargs):
|
|
|
|
|
try:
|
|
|
|
|
result = self.commands.roll(formula)
|
|
|
|
|
except CommandError as e:
|
|
|
|
|
await self.send_message(message.channel, 'Sorry {0}, {1}'.format(message.author.mention, e))
|
|
|
|
|
await message.channel.send('Sorry {0}, {1}'.format(message.author.mention, e))
|
|
|
|
|
else:
|
|
|
|
|
embed = discord.Embed(description=result, color=0xaaaccc)
|
|
|
|
|
await self.send_message(message.channel, embed=embed)
|
|
|
|
|
await message.channel.send(embed=embed)
|
|
|
|
|
|
|
|
|
|
async def _do_nextstream(self, server, user, message, **kwargs):
|
|
|
|
|
def format_delta(d):
|
|
|
|
@ -278,7 +274,7 @@ class DiscordClient(discord.Client):
|
|
|
|
|
try:
|
|
|
|
|
result = self.commands.next_stream()
|
|
|
|
|
except CommandError as e:
|
|
|
|
|
await self.send_message(message.channel, 'Sorry {0}, {1}'.format(message.author.mention, e))
|
|
|
|
|
await message.channel.send('Sorry {0}, {1}'.format(message.author.mention, e))
|
|
|
|
|
else:
|
|
|
|
|
embed = discord.Embed(title=result['title'],
|
|
|
|
|
url='https://www.twitch.tv/events/{0}'.format(result['id']),
|
|
|
|
@ -290,4 +286,4 @@ class DiscordClient(discord.Client):
|
|
|
|
|
time = dateutil.parser.parse(result['start'])
|
|
|
|
|
embed.add_field(name=format_delta(time - datetime.datetime.utcnow()),
|
|
|
|
|
value=time.strftime('%Y-%m-%d %I:%M %p GMT'), inline=False)
|
|
|
|
|
await self.send_message(message.channel, embed=embed)
|
|
|
|
|
await message.channel.send(embed=embed)
|
|
|
|
|