diff --git a/src/Config.py b/src/Config.py index 71e01871..bf597b78 100644 --- a/src/Config.py +++ b/src/Config.py @@ -1,16 +1,12 @@ import configparser, os class Config(object): - def __init__(self, bot, directory, filename="bot.conf"): - self.bot = bot - self.filename = filename - self.full_location = os.path.join(directory, filename) - self.bot.config = {} - self.load_config() + def __init__(self, location): + self.location = location def load_config(self): - if os.path.isfile(self.full_location): - with open(self.full_location) as config_file: + if os.path.isfile(self.location): + with open(self.location) as config_file: parser = configparser.ConfigParser() parser.read_string(config_file.read()) return dict(parser["bot"].items()) diff --git a/src/Database.py b/src/Database.py index 3bf3fe90..6abf0362 100644 --- a/src/Database.py +++ b/src/Database.py @@ -239,11 +239,10 @@ class UserChannelSettings(Table): [user_id, channel_id, setting.lower()]) class Database(object): - def __init__(self, bot, directory, filename): - self.bot = bot - self.filename = filename - self.full_location = os.path.join(directory, filename) - self.database = sqlite3.connect(self.full_location, + def __init__(self, log, location): + self.log = log + self.location = location + self.database = sqlite3.connect(self.location, check_same_thread=False, isolation_level=None) self.database.execute("PRAGMA foreign_keys = ON") self._cursor = None @@ -273,7 +272,7 @@ class Database(object): def _execute_fetch(self, query, fetch_func, params=[]): printable_query = " ".join(query.split()) - self.bot.log.debug("executing query: \"%s\" (params: %s)", + self.log.debug("executing query: \"%s\" (params: %s)", [printable_query, params]) start = time.monotonic() @@ -283,7 +282,7 @@ class Database(object): end = time.monotonic() total_milliseconds = (end - start) * 1000 - self.bot.log.debug("executed in %fms", [total_milliseconds]) + self.log.debug("executed in %fms", [total_milliseconds]) return value def execute_fetchall(self, query, params=[]): diff --git a/src/EventManager.py b/src/EventManager.py index f2c0aced..292f5bf0 100644 --- a/src/EventManager.py +++ b/src/EventManager.py @@ -11,8 +11,7 @@ DEFAULT_EVENT_DELIMITER = "." DEFAULT_MULTI_DELIMITER = "|" class Event(object): - def __init__(self, bot, name, **kwargs): - self.bot = bot + def __init__(self, name, **kwargs): self.name = name self.kwargs = kwargs self.eaten = False @@ -26,9 +25,8 @@ class Event(object): self.eaten = True class EventCallback(object): - def __init__(self, function, bot, priority, kwargs): + def __init__(self, function, priority, kwargs): self.function = function - self.bot = bot self.priority = priority self.kwargs = kwargs def call(self, event): @@ -81,8 +79,8 @@ class EventHookContext(object): return self._parent.get_children() class EventHook(object): - def __init__(self, bot, name=None, parent=None): - self.bot = bot + def __init__(self, log, name=None, parent=None): + self.log = log self.name = name self.parent = parent self._children = {} @@ -91,7 +89,7 @@ class EventHook(object): self._context_hooks = {} def _make_event(self, kwargs): - return Event(self.bot, self.name, **kwargs) + return Event(self.name, **kwargs) def _get_path(self): path = [] @@ -110,7 +108,7 @@ class EventHook(object): def _context_hook(self, context, function, priority, replay, kwargs): self._hook(function, context, priority, replay, kwargs) def _hook(self, function, context, priority, replay, kwargs): - callback = EventCallback(function, self.bot, priority, kwargs) + callback = EventCallback(function, priority, kwargs) if context == None: self._hooks.append(callback) @@ -176,7 +174,7 @@ class EventHook(object): return self._call(kwargs, maximum=maximum) def _call(self, kwargs, maximum=None): event_path = self._get_path() - self.bot.log.debug("calling event: \"%s\" (params: %s)", + self.log.debug("calling event: \"%s\" (params: %s)", [event_path, kwargs]) start = time.monotonic() @@ -189,11 +187,11 @@ class EventHook(object): returns.append(hook.call(event)) except Exception as e: traceback.print_exc() - self.bot.log.error("failed to call event \"%s\"", [ + self.log.error("failed to call event \"%s\"", [ event_path], exc_info=True) total_milliseconds = (time.monotonic() - start) * 1000 - self.bot.log.debug("event \"%s\" called in %fms", [ + self.log.debug("event \"%s\" called in %fms", [ event_path, total_milliseconds]) self.check_purge() @@ -203,8 +201,8 @@ class EventHook(object): def get_child(self, child_name): child_name_lower = child_name.lower() if not child_name_lower in self._children: - self._children[child_name_lower] = EventHook(self.bot, - child_name_lower, self) + self._children[child_name_lower] = EventHook(self.log, + child_name_lower) return self._children[child_name_lower] def remove_child(self, child_name): child_name_lower = child_name.lower() diff --git a/src/Logging.py b/src/Logging.py index 3f5815d6..e08160f4 100644 --- a/src/Logging.py +++ b/src/Logging.py @@ -14,7 +14,7 @@ class BitBotFormatter(logging.Formatter): return s class Log(object): - def __init__(self, bot, directory, filename): + def __init__(self, location): self.logger = logging.getLogger(__name__) self.logger.setLevel(logging.DEBUG) @@ -29,7 +29,7 @@ class Log(object): self.logger.addHandler(stdout_handler) file_handler = logging.handlers.TimedRotatingFileHandler( - os.path.join(directory, filename), when="midnight", backupCount=5) + location, when="midnight", backupCount=5) file_handler.setLevel(logging.DEBUG) file_handler.setFormatter(formatter) self.logger.addHandler(file_handler) diff --git a/start.py b/start.py index b105b49c..d8bc1600 100755 --- a/start.py +++ b/start.py @@ -8,30 +8,44 @@ def bool_input(s): result = input("%s (Y/n): " % s) return not result or result[0].lower() in ["", "y"] +directory = os.path.dirname(os.path.realpath(__file__)) + arg_parser = argparse.ArgumentParser( - description="Python3 event-driven asynchronous modular IRC bot") -arg_parser.add_argument("--config", "-c", default="bot.conf", - help="Location of the JSON config file") -arg_parser.add_argument("--database", "-d", default="databases/bot.db", - help="Location of the sqlite3 database file") -arg_parser.add_argument("--log", "-l", default="logs/bot.log", - help="Location of the main log file") + description="Python3 event-driven modular IRC bot") + +arg_parser.add_argument("--config", "-c", + help="Location of the JSON config file", + default=os.path.join(directory, "bot.conf")) + +arg_parser.add_argument("--database", "-d", + help="Location of the sqlite3 database file", + default=os.path.join(directory, "databases", "bot.db")) + +arg_parser.add_argument("--log", "-l", + help="Location of the main log file", + default=os.path.join(directory, "logs", "bot.log")) + arg_parser.add_argument("--verbose", "-v", action="store_true") args = arg_parser.parse_args() -directory = os.path.dirname(os.path.realpath(__file__)) +log = Logging.Log(args.log) +config = Config.Config(args.config).load_config() +database = Database.Database(log, args.database) +events = events = EventManager.EventHook(log) +exports = exports = Exports.Exports() bot = IRCBot.Bot() -bot._events = events = EventManager.EventHook(bot) -bot._exports = exports = Exports.Exports() bot.modules = modules = ModuleManager.ModuleManager(bot, events, exports, os.path.join(directory, "modules")) -bot.line_handler = IRCLineHandler.LineHandler(bot, bot._events) -bot.log = Logging.Log(bot, directory, args.log) -bot.database = Database.Database(bot, directory, args.database) -bot.config = Config.Config(bot, directory, args.config).load_config() +bot.line_handler = IRCLineHandler.LineHandler(bot, events) + +bot.log = log +bot.config = config +bot.database = database +bot._events = events +bot._exports = exports bot.args = args bot._events.on("timer.reconnect").hook(bot.reconnect)