Support loading jinja templates

Closes https://git.autonomic.zone/decentral1se/xbotlib/issues/30.
This commit is contained in:
Luke Murphy 2021-01-17 20:18:04 +01:00
parent c5127a92cf
commit 15e06852de
No known key found for this signature in database
GPG Key ID: 5E2EF5A63E3718CC
5 changed files with 55 additions and 12 deletions

1
.gitignore vendored
View File

@ -11,5 +11,6 @@ __pycache__
avatar.png
build/
dist/
index.html.j2
pip-wheel-metadata/
testbot.py

View File

@ -1,5 +1,9 @@
# xbotlib x.x.x (UNRELEASED)
# xbotlib 0.12.2 (2021-01-17)
- Support loading Jinja2 template ([#30](https://git.autonomic.zone/decentral1se/xbotlib/issues/30))
# xbotlib 0.12.1 (2021-01-17)
- Allow to configure port

View File

@ -105,13 +105,6 @@ Arguments:
- **request**: the web request
```python
from xbotlib import Response
def serve(self, request):
return Response(text="Hello, World!")
```
### SimpleMessage
A simple message interface.
@ -213,7 +206,8 @@ optional arguments:
--no-auto-join Disable automatically joining rooms when invited
-pt PORT, --port PORT
The port to serve from
-t TEMPLATE, --template TEMPLATE
The template to render
```
#### Using the environment
@ -276,13 +270,18 @@ Your bot will automatically be running a web server at port `8080` when it is
run. If you're running your bot locally, just visit
[0.0.0.0:8080](http://0.0.0.0:8080) to see. The default response is just some
placeholder text. You can write your own responses using the
[Bot.serve](#botserve) function.
[Bot.serve](#bot-serve-request) function.
`xbotlib` provides a small wrapper API for
[Jinja2](https://jinja.palletsprojects.com/en/2.11.x/) which allows you to
easily template and generate HTML. The web server is provided by
[aiohttp](https://docs.aiohttp.org/).
The default template search path is `index.html.j2` in the current working
directory. This can be configured through the usual configuration entrypoints.
Here's a small example.
```python
from xbotlib import Response

View File

@ -4,7 +4,7 @@ build-backend = "poetry.masonry.api"
[tool.poetry]
name = "xbotlib"
version = "0.12.1"
version = "0.12.2"
description = "XMPP bots for humans"
authors = ["decentral1se <lukewm@riseup.net>"]
maintainers = ["decentral1se <lukewm@riseup.net>"]

View File

@ -8,13 +8,14 @@ from getpass import getpass
from imghdr import what
from inspect import cleandoc
from logging import DEBUG, INFO, basicConfig, getLogger
from os import environ
from os import environ, getcwd
from os.path import exists
from pathlib import Path
from sys import exit, stdout
from aiohttp.web import Application, Response, get, run_app
from humanize import naturaldelta
from jinja2 import Environment, FileSystemLoader
from redis import Redis
from slixmpp import ClientXMPP
@ -139,6 +140,11 @@ class Config:
"""The port to serve from."""
return self.section.get("port", None)
@property
def template(self):
"""The Jinja template to render."""
return self.section.get("template", None)
class Bot(ClientXMPP):
"""XMPP bots for humans."""
@ -150,7 +156,6 @@ class Bot(ClientXMPP):
"""Initialise the object."""
self.name = type(self).__name__.lower()
self.start = dt.now()
self.CONFIG_FILE = f"{self.name}.conf"
self.parse_arguments()
@ -222,6 +227,12 @@ class Bot(ClientXMPP):
dest="port",
help="The port to serve from",
)
self.parser.add_argument(
"-t",
"--template",
dest="template",
help="The template to render",
)
self.args = self.parser.parse_args()
@ -303,6 +314,13 @@ class Bot(ClientXMPP):
)
port = input("Port: ")
print(
"Please choose Jinja template file path",
"(leave empty to choose default value of index.html.j2)",
sep="\n",
)
template = input("Jinja HTML template: ")
print("*" * 79)
config = ConfigParser()
@ -322,6 +340,8 @@ class Bot(ClientXMPP):
)
if port:
config[self.name]["port"] = port
if template:
config[self.name]["template"] = template
with open(self.CONFIG_FILE, "w") as file_handle:
config.write(file_handle)
@ -369,6 +389,12 @@ class Bot(ClientXMPP):
or environ.get("XBOT_PORT", None)
or "8080"
)
template = (
self.args.template
or self.config.template
or environ.get("XBOT_TEMPLATE", None)
or "index.html.j2"
)
if not account:
self.log.error("Unable to discover account")
@ -390,6 +416,19 @@ class Bot(ClientXMPP):
self.rooms = rooms
self.no_auto_join = no_auto_join
self.port = port
self.template = self.load_template(template)
def load_template(self, template):
"""Load template via Jinja."""
if not exists(Path(template).absolute()):
return None
try:
loader = FileSystemLoader(searchpath="./")
env = Environment(loader=loader)
return env.get_template(template)
except Exception:
self.log.info(f"Unable to load {template}")
def register_xmpp_event_handlers(self):
"""Register functions against specific XMPP event handlers."""