From c9dec93a4b2415e1f4a7d9cf81654169167e603c Mon Sep 17 00:00:00 2001 From: Luke Murphy Date: Sat, 16 Jan 2021 20:21:22 +0100 Subject: [PATCH] Expose Redis URL via conf and environ Closes https://git.autonomic.zone/decentral1se/xbotlib/issues/23. --- CHANGELOG.md | 3 ++- README.md | 14 ++++++++------ xbotlib.py | 29 +++++++++++++++++++++-------- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ee8366..6257e77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,13 +3,14 @@ # xbotlib 0.11.0 (2021-01-16) - Allow to configure avatar from configuration file and environment +- Load Redis details fron conf and CLI also ([#23](https://git.autonomic.zone/decentral1se/xbotlib/issues/23)) +- Migrate Redis environment naming: `REDIS_URL` -> `XBOT_REDIS_URL` ([#23](https://git.autonomic.zone/decentral1se/xbotlib/issues/23)) # xbotlib 0.10.0 (2021-01-16) - Implement Redis based storage ([#21](https://git.autonomic.zone/decentral1se/xbotlib/issues/21)) - Add `GlossBot` ([#10](https://git.autonomic.zone/decentral1se/xbotlib/issues/10)) - Revise command syntax and use unified `@` approach -- `REDIS_URL` -> `XBOT_REDIS_URL` - `SimpleMessage.body` -> `SimpleMessage.text` - Add `SimpleMessage.content` which simplifies parsing logic diff --git a/README.md b/README.md index a2453a9..e342cc3 100644 --- a/README.md +++ b/README.md @@ -157,6 +157,7 @@ deployments. - **XBOT_PASSWORD**: The bot password - **XBOT_NICK**: The bot nickname - **XBOT_AVATAR**: The bot avatar icon +- **XBOT_REDIS_URL**: Redis key store connection URL ## Deploy your bots @@ -164,23 +165,24 @@ See [bots.varia.zone](https://bots.varia.zone/). ## Persistent storage -## Redis key/value +## Redis key/value storage `xbotlib` supports using [Redis](https://redis.io/) as a storage back-end. It -is simple to work with because the interface is exactly like a dictionary. Here -is how to quickly run Redis locally (using -[Docker](https://docs.docker.com/engine/install/debian/)). +is simple to work with because the interface is exactly like a dictionary. You +can quickly run Redis locally using +[Docker](https://docs.docker.com/engine/install/debian/) or if you're on a +Debian system you can also `sudo apt install -y redis`. ```bash $ docker run --network=host --name redis -d redis -$ export REDIS_URL=redis://localhost:6379/0 +$ export XBOT_REDIS_URL=redis://localhost:6379/0 ``` And you access the interface via the `self.db` attribute. ```python def direct(self, message): - self.db["my-message"] = message.body + self.db["mykey"] = message.text ``` You should see `INFO Successfully connected to storage` when your bot diff --git a/xbotlib.py b/xbotlib.py index d636fa6..903e60b 100644 --- a/xbotlib.py +++ b/xbotlib.py @@ -170,6 +170,13 @@ class Bot(ClientXMPP): help="Avatar for the bot account", default="avatar.png", ) + self.parser.add_argument( + "-r", + "--redis-url", + dest="redis_url", + help="Redis storage connection URL", + default="redis://localhost:6379/0", + ) self.args = self.parser.parse_args() @@ -201,15 +208,17 @@ class Bot(ClientXMPP): password = getpass("Password: ") nick = input("Nickname: ") avatar = input("Avatar: ") + redis_url = input("Redis URL: ") config = ConfigParser() config[self.name] = {"account": account, "password": password} if nick: config[self.name]["nick"] = nick - if avatar: config[self.name]["avatar"] = avatar + if redis_url: + config[self.name]["redis_url"] = redis_url with open(self.CONFIG_FILE, "w") as file_handle: config.write(file_handle) @@ -234,6 +243,11 @@ class Bot(ClientXMPP): or self.config.avatar or environ.get("XBOT_AVATAR", None) ) + redis_url = ( + self.args.redis_url + or self.config.redis_url + or environ.get("XBOT_REDIS_URL", None) + ) if not account: self.log.error("Unable to discover account") @@ -251,6 +265,7 @@ class Bot(ClientXMPP): self.password = password self.nick = nick self.avatar = avatar + self.redis_url = redis_url def register_xmpp_event_handlers(self): """Register functions against specific XMPP event handlers.""" @@ -340,14 +355,12 @@ class Bot(ClientXMPP): def init_db(self): """Initialise the Redis key/value store.""" - url = environ.get("REDIS_URL", None) - - if not url: + if not self.redis_url: self.db = None - self.log.info("No storage discovered") - else: - self.db = Redis.from_url(url, decode_responses=True) - self.log.info("Successfully connected to storage") + return self.log.info("No storage discovered") + + self.db = Redis.from_url(self.redis_url, decode_responses=True) + self.log.info("Successfully connected to storage") def run(self): """Run the bot."""