messaging.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. from dataclasses import dataclass
  2. from enum import Enum, auto
  3. BANGS = ('!',)
  4. def pop_arg(text):
  5. if text is None:
  6. return None, None
  7. parts = text.split(maxsplit=1)
  8. if len(parts) == 1:
  9. return parts[0], None
  10. return parts[0], parts[1].strip()
  11. @dataclass
  12. class RollbotMessage:
  13. src: str
  14. name: str
  15. sender_id: str
  16. group_id: str
  17. message_id: str
  18. message_txt: str
  19. from_admin: bool
  20. def __post_init__(self):
  21. self.is_command = False
  22. if len(self.message_txt) > 0 and self.message_txt[0] in BANGS:
  23. cmd, raw = pop_arg(self.message_txt[1:].strip())
  24. if cmd is not None:
  25. self.is_command = True
  26. self.command = cmd.lower()
  27. self.raw_args = raw
  28. @staticmethod
  29. def from_groupme(msg, global_admins=(), group_admins={}):
  30. sender_id = msg["sender_id"]
  31. group_id = msg["group_id"]
  32. return RollbotMessage(
  33. "GROUPME",
  34. msg["name"],
  35. sender_id,
  36. group_id,
  37. msg["id"],
  38. msg["text"].strip(),
  39. sender_id in global_admins or (
  40. group_id in group_admins and
  41. sender_id in group_admins[group_id])
  42. )
  43. @staticmethod
  44. def from_discord(msg, global_admins=(), group_admins={}):
  45. sender_id = str(msg.author.id)
  46. group_id = str(msg.channel.id)
  47. return RollbotMessage(
  48. "DISCORD",
  49. msg.author.name,
  50. sender_id,
  51. group_id,
  52. msg.id,
  53. msg.content.strip(),
  54. sender_id in global_admins or (
  55. group_id in group_admins and
  56. sender_id in group_admins[group_id])
  57. )
  58. def args(self, normalize=True):
  59. arg, rest = pop_arg(self.raw_args)
  60. while arg is not None:
  61. yield arg.lower() if normalize else arg
  62. arg, rest = pop_arg(rest)
  63. class RollbotFailure(Enum):
  64. INVALID_COMMAND = auto()
  65. MISSING_SUBCOMMAND = auto()
  66. INVALID_SUBCOMMAND = auto()
  67. INVALID_ARGUMENTS = auto()
  68. SERVICE_DOWN = auto()
  69. PERMISSIONS = auto()
  70. INTERNAL_ERROR = auto()
  71. _RESPONSE_TEMPLATE = """Response{
  72. Original Message: %s,
  73. Text Response: %s,
  74. Image Response: %s,
  75. Respond: %s,
  76. Failure Reason: %s,
  77. Failure Notes: %s
  78. }"""
  79. @dataclass
  80. class RollbotResponse:
  81. msg: RollbotMessage
  82. txt: str = None
  83. img: str = None
  84. respond: bool = True
  85. failure: RollbotFailure = None
  86. debugging: dict = None
  87. def __post_init__(self):
  88. self.info = _RESPONSE_TEMPLATE % (self.msg, self.txt, self.img, self.respond, self.failure, self.debugging)
  89. self.is_success = self.failure is None
  90. if self.failure is None:
  91. self.failure_msg = None
  92. elif self.failure == RollbotFailure.INVALID_COMMAND:
  93. self.failure_msg = "Sorry - I don't think I understand the command '!%s'... " % self.msg.command \
  94. + "I'll try to figure it out and get back to you!"
  95. elif self.failure == RollbotFailure.MISSING_SUBCOMMAND:
  96. self.failure_msg = "Sorry - !%s requires a sub-command." % self.msg.command
  97. elif self.failure == RollbotFailure.INVALID_SUBCOMMAND:
  98. self.failure_msg = "Sorry - the sub-command you used for %s was not valid." % self.msg.command
  99. elif self.failure == RollbotFailure.INVALID_ARGUMENTS:
  100. self.failure_msg = "Sorry - %s cannot use those arguments!" % self.msg.command
  101. elif self.failure == RollbotFailure.SERVICE_DOWN:
  102. self.failure_msg = "Sorry - %s relies on a service I couldn't reach!" % self.msg.command
  103. elif self.failure == RollbotFailure.PERMISSIONS:
  104. self.failure_msg = "Sorry - you don't have permission to use that command or sub-command in this chat!"
  105. elif self.failure == RollbotFailure.INTERNAL_ERROR:
  106. self.failure_msg = "Sorry - I encountered an unrecoverable error, please review internal logs."
  107. if self.debugging is not None and "explain" in self.debugging:
  108. self.failure_msg += " " + self.debugging["explain"]