The KISS Twitch bot
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

167 行
4.4 KiB

  1. # Twason - The KISS Twitch bot
  2. # Copyright (C) 2021 Jérôme Deuchnord
  3. #
  4. # This program is free software: you can redistribute it and/or modify
  5. # it under the terms of the GNU Affero General Public License as
  6. # published by the Free Software Foundation, either version 3 of the
  7. # License, or (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU Affero General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU Affero General Public License
  15. # along with this program. If not, see <https://www.gnu.org/licenses/>.
  16. import json
  17. from os import environ
  18. from enum import Enum
  19. from typing import Union
  20. class Command:
  21. name: str
  22. message: str
  23. aliases: [str]
  24. disabled: bool
  25. def __init__(self, name: str, message: str, aliases: [str] = None, disabled: bool = False):
  26. self.name = name
  27. self.message = message
  28. self.aliases = aliases if aliases is not None else []
  29. self.disabled = disabled
  30. @classmethod
  31. def from_dict(cls, params: dict):
  32. return Command(
  33. params.get('name'),
  34. params['message'],
  35. params.get('aliases', []),
  36. params.get('disabled', False)
  37. )
  38. class TimerStrategy(Enum):
  39. ROUND_ROBIN = "round-robin"
  40. SHUFFLE = "shuffle"
  41. class Timer:
  42. time_between: int
  43. msgs_between: int
  44. strategy: TimerStrategy
  45. pool: [Command]
  46. def __init__(
  47. self,
  48. time_between: int = 10,
  49. msgs_between: int = 10,
  50. strategy: TimerStrategy = TimerStrategy.ROUND_ROBIN,
  51. pool: [Command] = None
  52. ):
  53. self.time_between = time_between
  54. self.msgs_between = msgs_between
  55. self.strategy = strategy
  56. self.pool = pool if pool else []
  57. @classmethod
  58. def from_dict(cls, param: dict):
  59. pool = []
  60. for c in param.get('pool', []):
  61. command = Command.from_dict(c)
  62. if not command.disabled:
  63. pool.append(command)
  64. return Timer(
  65. time_between=param.get('between', {}).get('time', 10),
  66. msgs_between=param.get('between', {}).get('messages', 10),
  67. strategy=TimerStrategy(param.get('strategy', 'round-robin')),
  68. pool=pool
  69. )
  70. class Config:
  71. channel: str
  72. nickname: str
  73. token: str
  74. command_prefix: str
  75. commands: [Command]
  76. timer: Timer
  77. def __init__(
  78. self,
  79. channel: str,
  80. nickname: str,
  81. token: str,
  82. command_prefix: str,
  83. commands: [Command],
  84. timer: Timer
  85. ):
  86. self.nickname = nickname
  87. self.channel = channel
  88. self.token = token
  89. self.command_prefix = command_prefix
  90. self.commands = commands
  91. self.timer = timer
  92. @classmethod
  93. def from_dict(cls, params: dict, token: str):
  94. timer = Timer.from_dict(params.get('timer', {}))
  95. commands_prefix = params.get('command_prefix', '!')
  96. commands = []
  97. help_command = Command("help", "Voici les commandes disponibles : ")
  98. for command in params.get('commands', []):
  99. command = Command.from_dict(command)
  100. if command.disabled:
  101. continue
  102. commands.append(command)
  103. for command in timer.pool:
  104. if command.name is None:
  105. continue
  106. commands.append(command)
  107. # Generate help command
  108. if params.get('help', True):
  109. for command in commands:
  110. help_command.message = "%s %s%s" % (help_command.message, commands_prefix, command.name)
  111. commands.append(help_command)
  112. return Config(
  113. params.get('channel'),
  114. params.get('nickname'),
  115. token,
  116. commands_prefix,
  117. commands,
  118. timer
  119. )
  120. def find_command(self, command: str) -> Union[None, Command]:
  121. if not command.startswith(self.command_prefix):
  122. return None
  123. command = command[1:]
  124. for c in self.commands:
  125. if c.name == command or command in c.aliases:
  126. return c
  127. return None
  128. def get_config(file_path: str):
  129. with open(file_path, 'r') as config_file:
  130. token = environ['TWITCH_TOKEN']
  131. return Config.from_dict(json.loads(config_file.read()), token)