From 2063477c583aeb337bf239e067f8ab2e0ed6ad09 Mon Sep 17 00:00:00 2001 From: Joscha Date: Tue, 24 May 2016 22:47:18 +0200 Subject: [PATCH] Save and restore bots --- yaboli/bot.py | 9 +++++ yaboli/botmanager.py | 93 +++++++++++++++++++++++++++++++++++++------- 2 files changed, 87 insertions(+), 15 deletions(-) diff --git a/yaboli/bot.py b/yaboli/bot.py index 8d23367..ef47706 100644 --- a/yaboli/bot.py +++ b/yaboli/bot.py @@ -187,6 +187,15 @@ class Bot(): return self.room.room + def password(self): + """ + password() -> password + + The current room's password. + """ + + return self.room.password + def nick(self): """ nick() -> nick diff --git a/yaboli/botmanager.py b/yaboli/botmanager.py index 7eeba82..7b1bb88 100644 --- a/yaboli/botmanager.py +++ b/yaboli/botmanager.py @@ -1,3 +1,5 @@ +import json + from . import bot from . import exceptions @@ -6,20 +8,31 @@ class BotManager(): Keep track of multiple bots in different rooms. """ - def __init__(self, bot_class, default_nick="yaboli", max_bots=100): + def __init__(self, bot_class, default_nick="yaboli", max_bots=100, + bots_file="bots.json", data_file="data.json"): """ bot_class - class to create instances of default_nick - default nick for all bots to assume when no nick is specified max_bots - maximum number of bots allowed to exist simultaneously None or 0 - no limit + bots_file - file the bot backups are saved to + None - no bot backups + data_file - file the bot data is saved to + - None - bot data isn't saved """ self.bot_class = bot_class self.max_bots = max_bots self.default_nick = default_nick - self.bots = {} - self.bot_id = 0 + self.bots_file = bots_file + self.data_file = data_file + + self._bots = {} + self._bot_id = 0 + self._bot_data = {} + + self._load_bots() def create(self, room, password=None, nick=None): """ @@ -31,12 +44,14 @@ class BotManager(): if nick is None: nick = self.default_nick - if self.max_bots and len(self.bots) >= self.max_bots: + if self.max_bots and len(self._bots) >= self.max_bots: raise exceptions.CreateBotException("max_bots limit hit") else: bot = self.bot_class(room, nick=nick, password=password, manager=self) - self.bots[self.bot_id] = bot - self.bot_id += 1 + self._bots[self._bot_id] = bot + self._bot_id += 1 + + self._save_bots() return bot @@ -47,11 +62,11 @@ class BotManager(): Kill a bot and remove it from the list of bots. """ - if not bot_id in self.bots: - raise exceptions.BotNotFoundException("Bot not in bots list") - - self.bots[bot_id].stop() - del self.bots[bot_id] + if bot_id in self._bots: + self._bots[bot_id].stop() + self._bots.pop(bot_id) + + self._save_bots() def get(self, bot_id): """ @@ -60,8 +75,8 @@ class BotManager(): Return bot with that id, if found. """ - if bot_id in self.bots: - return self.bots[bot_id] + if bot_id in self._bots: + return self._bots[bot_id] def get_id(self, bot): """ @@ -70,7 +85,7 @@ class BotManager(): Return the bot id, if the bot is known. """ - for bot_id, own_bot in self.bots.items(): + for bot_id, own_bot in self._bots.items(): if bot == own_bot: return bot_id @@ -81,5 +96,53 @@ class BotManager(): Collect all bots that are connected to the room and have that nick. """ - return {bot_id: bot for bot_id, bot in self.bots.items() + return {bot_id: bot for bot_id, bot in self._bots.items() if bot.roomname() == room and bot.mentionable().lower() == nick.lower()} + + def _load_bots(self): + """ + _load_bots() -> None + + Load and create bots from self.bots_file. + """ + + if not self.bots_file: + return + + try: + with open(self.bots_file) as f: + bots = json.load(f) + except FileNotFoundError: + pass + else: + for bot_info in bots: + bot = self.create(bot_info["room"], password=bot_info["password"], + nick=bot_info["nick"]) + bot.created_in = bot_info["created_in"] + bot.created_by = bot_info["created_by"] + + def _save_bots(self): + """ + _save_bots() -> None + + Save all current bots to self.bots_file. + """ + + if not self.bots_file: + return + + bots = [] + + for bot_id, bot in self._bots.items(): + bot_info = {} + + bot_info["room"] = bot.roomname() + bot_info["password"] = bot.password() + bot_info["nick"] = bot.nick() + bot_info["created_in"] = bot.created_in + bot_info["created_by"] = bot.created_by + + bots.append(bot_info) + + with open(self.bots_file, "w") as f: + json.dump(bots, f)