import re import random import importlib import datetime class Bot: def __init__(self, nickname): """Initialize a bot object Args: nickname: nickname of the bot on irc """ self.nickname = nickname self.channel = None self.port = None self.server = None self.reactions = {} self.pings = [] self.on_join = None self.tg_user_match = re.compile("^<\x03..\x02\x02(?P.+)\x03>") self.ping_match = re.compile("(<.+> )?\@?{name}".format(name=nickname)) self.min_time = 0 self.last_time = datetime.datetime(1, 1, 1) def add_reaction(self, match, reaction): """Add a reaction to the bot. Args: match: The string which, if matched will trigger the answer. reaction: The string which will be sent. """ context = { "server": self.server, "channel": self.channel, "name": self.nickname, } self.reactions[re.compile(match.format(**context))] = reaction def add_python_reaction(self, match, reaction): """ Add a Python callback to the reactions. Args: match: The string which, if matched will trigger the answer. reaction: The path to the callback """ self.add_reaction(match, self.fetch_callback(reaction)) def add_ping(self, reaction): """Add a reaction to a ping""" self.pings.append(reaction) def add_python_ping(self, reaction): """Fetch a Python callable and add it to the pings""" self.add_ping(self.fetch_callback(reaction)) def fetch_callback(self, path): """Fetch a Python callable""" s = path.split(".") module, callback = ".".join(s[:-1]), s[-1] module = importlib.import_module(module) return getattr(module, callback) def get_reaction(self, user, channel, message): """Get a reaction to a message. Args: user: The user who sent the message. channel: The channel on which the bot speak. message: The message to which the bot has to react. Returns: Every matched reactions. """ if (datetime.datetime.now() - self.last_time).total_seconds() < self.min_time: return [] username = user.split("!")[0] tg_user_match = self.tg_user_match.match(message) if "bot" in username.lower() and tg_user_match: username = "@" + tg_user_match.groupdict()["username"] context = { "server": self.server, "channel": channel, "name": self.nickname, "user": username, "message": message, } result = [] for m in self.reactions.keys(): search = m.search(message) if search: r = self.reactions[m] if callable(r): r = r(self, username, channel, message) else: r = r.format(**context) result.append(r) if not result and self.ping_match.search(message): r = random.choice(self.pings) if callable(r): r = r(self, username, channel, message) else: r = r.format(**context) result.append(" : ".join([username, r])) if len(result) > 0: self.last_time = datetime.datetime.now() return result