Maki is a Discord bot that does things. Written in Python 3 and relies on Discord.py API implementation.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

97 lines
2.4KB

  1. # Maki
  2. # ----
  3. # Discord bot by MrDetonia
  4. #
  5. # Copyright 2018 Zac Herd
  6. # Licensed under BSD 3-clause License, see LICENSE.md for more info
  7. # IMPORTS
  8. import asyncio
  9. import discord
  10. import logging
  11. import datetime
  12. import re
  13. # LOCAL IMPORTS
  14. from common import *
  15. # clamps an integer
  16. def clamp(n, small, large):
  17. return max(small, min(n, large))
  18. # converts a datetime to a string
  19. def strfromdt(dt):
  20. return dt.strftime('%Y-%m-%d %H:%M:%S')
  21. # converts a timestamp to a datetime
  22. def dtfromts(ts):
  23. return datetime.datetime.fromtimestamp(ts)
  24. # logging setup
  25. def logger():
  26. logger = logging.getLogger('discord')
  27. logger.setLevel(logging.DEBUG)
  28. handler = logging.FileHandler(
  29. filename='discord.log', encoding='utf-8', mode='w')
  30. handler.setFormatter(
  31. logging.Formatter('%(asctime)s:%(levelname)s:%(name)s: %(message)s'))
  32. logger.addHandler(handler)
  33. # fuzzy search over dictionary
  34. def search(dict, term):
  35. s = term.lower()
  36. for item in dict.items():
  37. if s in item[0].lower():
  38. yield item
  39. # send_message wrapper (deals with Discord's shit API)
  40. @asyncio.coroutine
  41. def discord_send(client, message, response):
  42. if response is not '' and message.server.id not in quiet:
  43. for attempt in range(5):
  44. try:
  45. yield from client.send_message(message.channel, response)
  46. except discord.errors.HTTPException:
  47. continue
  48. else:
  49. break
  50. else:
  51. print('ERROR: Failed to send message to discord after 5 attempts')
  52. # send typing signal to Discord
  53. @asyncio.coroutine
  54. def discord_typing(client, message):
  55. for attempt in range(5):
  56. try:
  57. yield from client.send_typing(message.channel)
  58. except discord.errors.HTTPException:
  59. continue
  60. else:
  61. break
  62. else:
  63. print(
  64. 'ERROR: Failed to send typing signal to discord after 5 attempts')
  65. # Maki Reacts to...
  66. @asyncio.coroutine
  67. def makireacts(client, msg):
  68. # TODO: track down the person(s) responsible for naming emoji
  69. reactions = {
  70. r"\bmaki\b": "\N{BLACK HEART SUIT}",
  71. r"\bbutter\b": "\N{PERSON WITH FOLDED HANDS}",
  72. r"\begg[s]?\b": "\N{AUBERGINE}",
  73. r"\bproblematic\b": "\N{EYEGLASSES}",
  74. }
  75. for i in reactions:
  76. if bool(re.search(i, msg.content, re.IGNORECASE)):
  77. yield from client.add_reaction(msg, reactions[i])