From 4518daba36678f52330513ec1fec82a44340fa81 Mon Sep 17 00:00:00 2001 From: jason Date: Thu, 18 Aug 2016 19:30:35 -0600 Subject: Remove the hard-coded config file path - added a dynamic config file path --- README.org | 17 +++++++++++------ bin/dbolla | 14 ++++++++++---- warmachine/addons/base.py | 1 + warmachine/addons/standup.py | 15 +++++++++++++-- warmachine/connections/base.py | 3 +++ warmachine/connections/irc.py | 1 + 6 files changed, 39 insertions(+), 12 deletions(-) diff --git a/README.org b/README.org index 4d8bf43..b317e13 100644 --- a/README.org +++ b/README.org @@ -30,6 +30,8 @@ you must call ~super()~. ** ~self._loop~ This is given to you access to the asyncio loop. This is useful for scheduling tasks to be run later. +** ~self.config_dir~ +The directory to store any configuration files and other junk in. ** ~self.log~ This is a logger that you should use when logging messages. ** ~recv_msg(channel, message)~ @@ -76,18 +78,21 @@ you may want to do such as create configuration files that don't exist yet. * Writing a Connection To write a new connection protocol you must inherit from ~warmachine.connections.base.Connection~. This class defines an interface you -must implement to support the plugins. +must implement to support the plugins. If you override ~__init__~ you must call +~super()~. ** ~__config_prefix__~ This global is used to decide which connection to use when it is found in the config file. E.g. IRC uses ~'irc'~ and Slack uses ~'slack'~. It should be defined somewhere near the top of your file. -** ~connect()~ +** ~self.config_dir~ +The directory to store any configuration files and other junk in. +** ~self.connect()~ D'bolla uses python 3's asyncio to manage multiple connections concurrently thus you should use ~asyncio.open_connection~ to create your connection. Once you have successfully connected you must set ~self.status~ to ~warmachine.connections.base.CONNECTED~. This indicates the connection is ready to use. -** ~read()~ +** ~self.read()~ This method is constantly checked in a loop by the ~Bot~ class. When a message is returned it is passed into the ~recv_msg~ method in all loaded plugins. This return value should be formatted in the following format: @@ -99,9 +104,9 @@ return value should be formatted in the following format: 'message': 'The message that was received', } #+END_SRC -** ~say(message, destination)~ +** ~self.say(message, destination)~ This method is used by plugins to send a message to a channel or user. -** ~id~ +** ~self.id~ This should return a unique id used to identify this particular connection. This is used by plugins when saving state. As an example, the IRC connection uses something like this: @@ -115,6 +120,6 @@ def id(self): value = '{}-{}'.format(self.host, self.nick) return md5(value.encode()).hexdigest() #+END_SRC -** ~get_users_by_channel(channel)~ +** ~self.get_users_by_channel(channel)~ This method should return a list of all users (including the bot) for the connection. diff --git a/bin/dbolla b/bin/dbolla index e00143b..5bef051 100755 --- a/bin/dbolla +++ b/bin/dbolla @@ -43,6 +43,13 @@ log_config = { class Bot(object): def __init__(self, settings): self.log = logging.getLogger(self.__class__.__name__) + + self.config_dir = os.path.expanduser('~/.warmachine') + if not os.path.exists(self.config_dir): + self.log.info('Creating config directory: {}'.format( + self.config_dir)) + os.makedirs(self.config_dir) + self._loop = asyncio.get_event_loop() self.settings = settings @@ -55,8 +62,6 @@ class Bot(object): self.load_plugin('warmachine.addons.giphy.GiphySearch') self.load_plugin('warmachine.addons.standup.StandUpPlugin') - # TODO: Ensure the config directory has been created - def start(self): for connection in self.connections: t = asyncio.ensure_future(connection.connect()) @@ -65,6 +70,7 @@ class Bot(object): self._loop.run_forever() def add_connection(self, connection): + connection.config_dir = self.config_dir self.connections[connection] = {} def on_connect(self, connection, task): @@ -104,9 +110,9 @@ class Bot(object): mod = import_module(mod_path) if hasattr(mod, cls_name): - cls = getattr(mod, cls_name)() + obj = getattr(mod, cls_name)(config_dir=self.config_dir) - self.loaded_plugins.append(cls) + self.loaded_plugins.append(obj) def reload_plugin(self, path): """ diff --git a/warmachine/addons/base.py b/warmachine/addons/base.py index 0a02df7..d67500f 100644 --- a/warmachine/addons/base.py +++ b/warmachine/addons/base.py @@ -6,6 +6,7 @@ class WarMachinePlugin(object): def __init__(self, *args, **kwargs): self._loop = asyncio.get_event_loop() self.log = logging.getLogger(self.__class__.__name__) + self.config_dir = kwargs.pop('config_dir', None) def recv_msg(self, *args, **kwargs): """ diff --git a/warmachine/addons/standup.py b/warmachine/addons/standup.py index 6ee6378..aa7fda6 100644 --- a/warmachine/addons/standup.py +++ b/warmachine/addons/standup.py @@ -2,6 +2,7 @@ import asyncio from datetime import datetime, timedelta import functools import json +import os from pprint import pformat from .base import WarMachinePlugin @@ -20,6 +21,7 @@ class StandUpPlugin(WarMachinePlugin): !standup-schedules !standup-waiting_replies """ + SETTINGS_FILENAME = 'standup_schedules.json' def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -38,6 +40,15 @@ class StandUpPlugin(WarMachinePlugin): self.users_awaiting_reply = {} self.log.info('Loaded standup plugin') + self.settings_file = os.path.join( + self.config_dir, self.SETTINGS_FILENAME) + + if not os.path.exists(self.settings_file): + self.log.info('Creating standup config file: {}'.format( + self.settings_file)) + with open(self.settings_file, 'w') as f: + f.write('{}') + def on_connect(self, connection): self.load_schedule(connection) @@ -416,7 +427,7 @@ class StandUpPlugin(WarMachinePlugin): data[channel][key] = self.standup_schedules[channel][key] data = {connection.id: data} - with open('/home/jason/.warmachine/standup_schedules.json', 'w') as f: + with open(self.settings_file, 'w') as f: f.write(json.dumps(data)) self.log.info('Schedules saved to disk') @@ -425,7 +436,7 @@ class StandUpPlugin(WarMachinePlugin): """ Load the channel schedules from a file. """ - with open('/home/jason/.warmachine/standup_schedules.json', 'r') as f: + with open(self.settings_file, 'r') as f: try: data = json.loads(f.read()) except Exception as e: diff --git a/warmachine/connections/base.py b/warmachine/connections/base.py index e787e35..56ce108 100644 --- a/warmachine/connections/base.py +++ b/warmachine/connections/base.py @@ -3,6 +3,9 @@ CONNECTED = 'Connected' class Connection(object): + def __init__(self): + self.config_dir = None + def connect(self, *args, **kwargs): """ This is called by the main start method. It should prepare your diff --git a/warmachine/connections/irc.py b/warmachine/connections/irc.py index 86068d7..542ba62 100644 --- a/warmachine/connections/irc.py +++ b/warmachine/connections/irc.py @@ -7,6 +7,7 @@ from ..utils.decorators import memoize class AioIRC(Connection): def __init__(self, host, port): + super().__init__() self._loop = asyncio.get_event_loop() self.log = logging.getLogger(self.__class__.__name__) -- cgit v1.2.1