Added parse_mention().
authorCMDR furrycat <elite@furrycat.net>
Mon, 5 Dec 2016 18:02:39 +0000 (18:02 +0000)
committerCMDR furrycat <elite@furrycat.net>
Mon, 5 Dec 2016 18:02:39 +0000 (18:02 +0000)
bot.py

diff --git a/bot.py b/bot.py
index e3b8d79..749e3bc 100644 (file)
--- a/bot.py
+++ b/bot.py
@@ -153,6 +153,105 @@ def parse_channel(text, *, text_ok = True, voice_ok = True):
   log.warning("Can't find {} channel {}!".format(channel_type, text))
   return None
 
+def parse_mention(text, author):
+  log.debug("Parsing mention {}".format(text))
+
+  # Message author.
+  if text == 'me':
+    return author.id
+
+  # @everyone or @here.
+  m = re.match(r'^@?(everyone|here)$', text)
+  if m is not None:
+    return m.group(1)
+
+  # <@&role>, @&role or &role.
+  m = re.match(r'<@&(\d+)>', text)
+  if m is None:
+    m = re.match(r'@?&(\d+)', text)
+  if m is not None:
+    role_id = m.group(1)
+    log.debug('Role ID {}.'.format(role_id))
+    for server in client.servers:
+      member = server.get_member(author.id)
+      if member is None:
+        log.debug('Role {} is not known to {} on {}.'.format(role_id, author, server.name))
+        continue
+      for role in server.roles:
+        if role.id == role_id:
+          log.info('Parsed role {} as {} on {}.'.format(role_id, role.name, server.name))
+          return '&{}'.format(role_id)
+    log.warning("Can't find role with ID {}!".format(role_id))
+    return None
+
+  # @mention.
+  m = re.match(r'<@(\d+)>', text)
+  if m is None:
+    m = re.match(r'@?(\d+)', text)
+  if m is not None:
+    member_id = m.group(1)
+    log.debug('Member {}.'.format(member_id))
+    log.info('Member {}'.format(member_id))
+    return member_id
+
+  # @&role, @role or @name.
+  m = re.match(r'@(&)?(.+)', text)
+  if m is not None:
+    name = m.group(2).lower()
+    log.debug('Role {}.'.format(name))
+    for server in client.servers:
+      member = server.get_member(author.id)
+      if member is None:
+        log.debug('Role {} is not known to {} on {}.'.format(name, author, server.name))
+        continue
+      for role in server.roles:
+        if role.name.lower() == name:
+          log.info('Parsed {} as {} on {}.'.format(name, role.name, server.name))
+          return '&{}'.format(role.id)
+    if m.group(1) != '&':
+      log.debug('Member {}.'.format(name))
+      parts = name.split('#')
+      member_name = parts[0]
+      if len(parts) > 1:
+        discriminator = parts[1]
+      else:
+        discriminator = None
+      for member in client.get_all_members():
+        if member.name != member_name:
+          continue
+        if discriminator is not None and member.discriminator != discriminator:
+          continue
+        log.info('Parsed {} as {}#{} on {}'.format(name, member.name, member.discriminator, server.name))
+        return member.id
+    log.warning("Can't find role or member with name {}!".format(name))
+    return None
+
+
+  # <#channel> or #channel.
+  m = re.match(r'<#(.+)>', text)
+  if m is None:
+    m = re.match(r'#(.+)', text)
+  if m is not None:
+    name = m.group(1).lower()
+    log.debug('Channel name {}.'.format(name))
+    for channel in client.get_all_channels():
+      if channel.name.lower() != name:
+        continue
+      member = channel.server.get_member(author.id)
+      if member is None:
+        log.warning('Channel {} is not known to {} on {}.'.format(name, author, channel.server.name))
+        continue
+      if channel.type == discord.ChannelType.voice:
+        log.warning('Channel {} is a voice channel!'.format(channel.name))
+        continue
+      log.info('Parsed channel {} as {} on {}.'.format(name, channel.name, channel.server.name))
+      return '#{}'.format(channel.id)
+    log.warning("Can't find channel with name {}!".format(name))
+    return None
+
+  log.warning("Can't parse {}!".format(text))
+  return None
+
 def open_url(url):
   # Specify our own user agent as Cloudflare doesn't seem to like the urllib one
   try: