From 2d4dfdd274248a2ca252cd5cde4450e2b2926aa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Deuchnord?= Date: Sun, 27 Jun 2021 19:36:21 +0200 Subject: [PATCH] Add Timers, fix some issues --- _twitchbot/__init__.py | 0 _twitchbot/config.py | 104 ++++++++++++++++++++++++++++++++++++++++ _twitchbot/twitchbot.py | 74 ++++++++++++++++++++++++++++ bot.py | 90 +++------------------------------- 4 files changed, 184 insertions(+), 84 deletions(-) create mode 100644 _twitchbot/__init__.py create mode 100644 _twitchbot/config.py create mode 100644 _twitchbot/twitchbot.py diff --git a/_twitchbot/__init__.py b/_twitchbot/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/_twitchbot/config.py b/_twitchbot/config.py new file mode 100644 index 0000000..1691e35 --- /dev/null +++ b/_twitchbot/config.py @@ -0,0 +1,104 @@ +import json + +from os import environ +from enum import Enum + + +class Command: + name: str + message: str + + def __init__(self, name: str, message: str): + self.name = name + self.message = message + + @classmethod + def from_dict(cls, params: dict): + return Command(params['name'], params['message']) + + +class TimerStrategy(Enum): + ROUND_ROBIN = "round-robin" + SHUFFLE = "shuffle" + + +class Timer: + time_between: int + msgs_between: int + strategy: TimerStrategy + messages: [str] + + def __init__( + self, + time_between: int = 10, + msgs_between: int = 10, + strategy: TimerStrategy = TimerStrategy.ROUND_ROBIN, + messages: [str] = [] + ): + self.time_between = time_between + self.msgs_between = msgs_between + self.strategy = strategy + self.messages = messages + + @classmethod + def from_dict(cls, param: dict): + return Timer( + time_between=param.get('between', {}).get('time', 10), + msgs_between=param.get('between', {}).get('messages', 10), + strategy=TimerStrategy(param.get('strategy', 'round-robin')), + messages=param.get('messages', []) + ) + + +class Config: + channel: str + nickname: str + token: str + command_prefix: str + commands: [Command] + timer: Timer + + def __init__( + self, + channel: str, + nickname: str, + token: str, + command_prefix: str, + commands: [Command], + timer: Timer + ): + self.nickname = nickname + self.channel = channel + self.token = token + self.command_prefix = command_prefix + self.commands = commands + self.timer = timer + + @classmethod + def from_dict(cls, params: dict, token: str): + commands_prefix = params.get('command_prefix', '!') + commands = [] + + help_command = Command("help", "Voici les commandes disponibles : ") + + for command in params.get('commands', []): + commands.append(Command.from_dict(command)) + help_command.message = "%s %s%s" % (help_command.message, commands_prefix, command['name']) + + if params.get('help', True): + commands.append(help_command) + + return Config( + params.get('channel'), + params.get('nickname'), + token, + commands_prefix, + commands, + Timer.from_dict(params.get('timer', {})) + ) + + +def get_config(): + with open('config.json', 'r') as config_file: + token = environ['TWITCH_TOKEN'] + return Config.from_dict(json.loads(config_file.read()), token) \ No newline at end of file diff --git a/_twitchbot/twitchbot.py b/_twitchbot/twitchbot.py new file mode 100644 index 0000000..ea97749 --- /dev/null +++ b/_twitchbot/twitchbot.py @@ -0,0 +1,74 @@ +import irc3 + +from .config import get_config, TimerStrategy +from random import shuffle +from datetime import datetime, timedelta + + +@irc3.plugin +class TwitchBot: + def __init__(self, bot): + self.config = get_config() + self.messages_stack = [] + self.bot = bot + self.log = self.bot.log + self.last_timer_date = datetime.now() + self.nb_messages_since_timer = 0 + + def connection_made(self): + print('connected') + + def server_ready(self): + print('ready') + + def connection_lost(self): + print('connection lost') + + @staticmethod + def _parse_variables(in_str: str, mask: str = None): + variables = { + 'author': mask.split('!')[0] + } + + for key in variables: + value = variables[key] + in_str = in_str.replace('{%s}' % key, value) + + return in_str + + @irc3.event(irc3.rfc.PRIVMSG) + def on_msg(self, target, mask, data, **_): + print(target) + for command in self.config.commands: + if ('%s ' % data.lower()).startswith('%s%s ' % (self.config.command_prefix, command.name.lower())): + print('%s: %s%s' % (mask, self.config.command_prefix, command.name)) + self.bot.privmsg(target, self._parse_variables(command.message, mask)) + break + + self.nb_messages_since_timer += 1 + self.play_timer() + + def play_timer(self): + print(self.messages_stack) + if not self.messages_stack: + print('Filling the timer messages stack in') + self.messages_stack = self.config.timer.messages.copy() + if self.config.timer.strategy == TimerStrategy.SHUFFLE: + print('Shuffle!') + shuffle(self.messages_stack) + + if self.nb_messages_since_timer < self.config.timer.msgs_between or \ + datetime.now() < self.last_timer_date + timedelta(minutes=self.config.timer.time_between): + return + + message = self.messages_stack.pop(0) + + print("Timer: %s" % message) + self.bot.privmsg('#%s' % self.config.channel, message) + + self.nb_messages_since_timer = 0 + self.last_timer_date = datetime.now() + + @irc3.event(irc3.rfc.JOIN) + def on_join(self, mask, channel, **_): + print('JOINED %s as %s' % (channel, mask)) diff --git a/bot.py b/bot.py index be58af5..ebf574b 100644 --- a/bot.py +++ b/bot.py @@ -1,104 +1,26 @@ #!/usr/bin/env python3 import irc3 -import json -from os import environ + +from _twitchbot.config import get_config +from _twitchbot import twitchbot TWITCH_IRC_SERVER = "irc.chat.twitch.tv" TWITCH_IRC_PORT = 6697 -class Command: - name: str - message: str - - def __init__(self, name: str, message: str): - self.name = name - self.message = message - - @classmethod - def from_dict(cls, params: dict): - return Command(params['name'], params['message']) - - -class Config: - channel: str - nickname: str - token: str - commands: [Command] - - def __init__(self, channel: str, nickname: str, token: str, commands: [Command] = None): - self.nickname = nickname - self.channel = channel - self.token = token - self.commands = commands if commands is not None else [] - - @classmethod - def from_dict(cls, params: dict, token: str): - commands = [] - - for command in params['commands']: - commands.append(Command.from_dict(command)) - - return Config( - params['channel'], - params['nickname'], - token, - commands - ) - - -@irc3.plugin -class TwitchBot: - def __init__(self, bot): - self.config = get_config() - self.bot = bot - self.log = self.bot.log - - def connection_made(self): - print('connected') - - def server_ready(self): - print('ready') - - def connection_lost(self): - print('connection lost') - - @irc3.event(irc3.rfc.PRIVMSG) - def on_msg(self, target, mask, data, event): - author_name = mask.split('!')[0] - - for command in self.config.commands: - print(command.name) - print('%s ' % data) - if ('%s ' % data).startswith('!%s ' % command.name): - self.bot.privmsg(target, command.message) - - @irc3.event(irc3.rfc.JOIN) - def on_join(self, mask, channel, **kw): - print('JOINED') - print(mask) - print(channel) - print(kw) - - -def get_config(): - with open('config.json', 'r') as config_file: - token = environ['TWITCH_TOKEN'] - return Config.from_dict(json.loads(config_file.read()), token) - - def main() -> int: config = get_config() + print(config.timer.messages) bot = irc3.IrcBot.from_config({ 'nick': config.nickname, 'password': config.token, - 'autojoins': ['%s' % config.channel], + 'autojoins': [config.channel], 'host': TWITCH_IRC_SERVER, 'port': TWITCH_IRC_PORT, 'ssl': True, - 'includes': [__name__] + 'includes': [twitchbot.__name__] }) bot.run(forever=True)