Support loading jinja templates
Closes https://git.autonomic.zone/decentral1se/xbotlib/issues/30.
This commit is contained in:
parent
c5127a92cf
commit
15e06852de
1
.gitignore
vendored
1
.gitignore
vendored
@ -11,5 +11,6 @@ __pycache__
|
|||||||
avatar.png
|
avatar.png
|
||||||
build/
|
build/
|
||||||
dist/
|
dist/
|
||||||
|
index.html.j2
|
||||||
pip-wheel-metadata/
|
pip-wheel-metadata/
|
||||||
testbot.py
|
testbot.py
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
# xbotlib x.x.x (UNRELEASED)
|
# 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)
|
# xbotlib 0.12.1 (2021-01-17)
|
||||||
|
|
||||||
- Allow to configure port
|
- Allow to configure port
|
||||||
|
17
README.md
17
README.md
@ -105,13 +105,6 @@ Arguments:
|
|||||||
|
|
||||||
- **request**: the web request
|
- **request**: the web request
|
||||||
|
|
||||||
```python
|
|
||||||
from xbotlib import Response
|
|
||||||
|
|
||||||
def serve(self, request):
|
|
||||||
return Response(text="Hello, World!")
|
|
||||||
```
|
|
||||||
|
|
||||||
### SimpleMessage
|
### SimpleMessage
|
||||||
|
|
||||||
A simple message interface.
|
A simple message interface.
|
||||||
@ -213,7 +206,8 @@ optional arguments:
|
|||||||
--no-auto-join Disable automatically joining rooms when invited
|
--no-auto-join Disable automatically joining rooms when invited
|
||||||
-pt PORT, --port PORT
|
-pt PORT, --port PORT
|
||||||
The port to serve from
|
The port to serve from
|
||||||
|
-t TEMPLATE, --template TEMPLATE
|
||||||
|
The template to render
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Using the environment
|
#### 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
|
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
|
[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
|
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
|
`xbotlib` provides a small wrapper API for
|
||||||
[Jinja2](https://jinja.palletsprojects.com/en/2.11.x/) which allows you to
|
[Jinja2](https://jinja.palletsprojects.com/en/2.11.x/) which allows you to
|
||||||
easily template and generate HTML. The web server is provided by
|
easily template and generate HTML. The web server is provided by
|
||||||
[aiohttp](https://docs.aiohttp.org/).
|
[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
|
```python
|
||||||
from xbotlib import Response
|
from xbotlib import Response
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ build-backend = "poetry.masonry.api"
|
|||||||
|
|
||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "xbotlib"
|
name = "xbotlib"
|
||||||
version = "0.12.1"
|
version = "0.12.2"
|
||||||
description = "XMPP bots for humans"
|
description = "XMPP bots for humans"
|
||||||
authors = ["decentral1se <lukewm@riseup.net>"]
|
authors = ["decentral1se <lukewm@riseup.net>"]
|
||||||
maintainers = ["decentral1se <lukewm@riseup.net>"]
|
maintainers = ["decentral1se <lukewm@riseup.net>"]
|
||||||
|
43
xbotlib.py
43
xbotlib.py
@ -8,13 +8,14 @@ from getpass import getpass
|
|||||||
from imghdr import what
|
from imghdr import what
|
||||||
from inspect import cleandoc
|
from inspect import cleandoc
|
||||||
from logging import DEBUG, INFO, basicConfig, getLogger
|
from logging import DEBUG, INFO, basicConfig, getLogger
|
||||||
from os import environ
|
from os import environ, getcwd
|
||||||
from os.path import exists
|
from os.path import exists
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from sys import exit, stdout
|
from sys import exit, stdout
|
||||||
|
|
||||||
from aiohttp.web import Application, Response, get, run_app
|
from aiohttp.web import Application, Response, get, run_app
|
||||||
from humanize import naturaldelta
|
from humanize import naturaldelta
|
||||||
|
from jinja2 import Environment, FileSystemLoader
|
||||||
from redis import Redis
|
from redis import Redis
|
||||||
from slixmpp import ClientXMPP
|
from slixmpp import ClientXMPP
|
||||||
|
|
||||||
@ -139,6 +140,11 @@ class Config:
|
|||||||
"""The port to serve from."""
|
"""The port to serve from."""
|
||||||
return self.section.get("port", None)
|
return self.section.get("port", None)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def template(self):
|
||||||
|
"""The Jinja template to render."""
|
||||||
|
return self.section.get("template", None)
|
||||||
|
|
||||||
|
|
||||||
class Bot(ClientXMPP):
|
class Bot(ClientXMPP):
|
||||||
"""XMPP bots for humans."""
|
"""XMPP bots for humans."""
|
||||||
@ -150,7 +156,6 @@ class Bot(ClientXMPP):
|
|||||||
"""Initialise the object."""
|
"""Initialise the object."""
|
||||||
self.name = type(self).__name__.lower()
|
self.name = type(self).__name__.lower()
|
||||||
self.start = dt.now()
|
self.start = dt.now()
|
||||||
|
|
||||||
self.CONFIG_FILE = f"{self.name}.conf"
|
self.CONFIG_FILE = f"{self.name}.conf"
|
||||||
|
|
||||||
self.parse_arguments()
|
self.parse_arguments()
|
||||||
@ -222,6 +227,12 @@ class Bot(ClientXMPP):
|
|||||||
dest="port",
|
dest="port",
|
||||||
help="The port to serve from",
|
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()
|
self.args = self.parser.parse_args()
|
||||||
|
|
||||||
@ -303,6 +314,13 @@ class Bot(ClientXMPP):
|
|||||||
)
|
)
|
||||||
port = input("Port: ")
|
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)
|
print("*" * 79)
|
||||||
|
|
||||||
config = ConfigParser()
|
config = ConfigParser()
|
||||||
@ -322,6 +340,8 @@ class Bot(ClientXMPP):
|
|||||||
)
|
)
|
||||||
if port:
|
if port:
|
||||||
config[self.name]["port"] = port
|
config[self.name]["port"] = port
|
||||||
|
if template:
|
||||||
|
config[self.name]["template"] = template
|
||||||
|
|
||||||
with open(self.CONFIG_FILE, "w") as file_handle:
|
with open(self.CONFIG_FILE, "w") as file_handle:
|
||||||
config.write(file_handle)
|
config.write(file_handle)
|
||||||
@ -369,6 +389,12 @@ class Bot(ClientXMPP):
|
|||||||
or environ.get("XBOT_PORT", None)
|
or environ.get("XBOT_PORT", None)
|
||||||
or "8080"
|
or "8080"
|
||||||
)
|
)
|
||||||
|
template = (
|
||||||
|
self.args.template
|
||||||
|
or self.config.template
|
||||||
|
or environ.get("XBOT_TEMPLATE", None)
|
||||||
|
or "index.html.j2"
|
||||||
|
)
|
||||||
|
|
||||||
if not account:
|
if not account:
|
||||||
self.log.error("Unable to discover account")
|
self.log.error("Unable to discover account")
|
||||||
@ -390,6 +416,19 @@ class Bot(ClientXMPP):
|
|||||||
self.rooms = rooms
|
self.rooms = rooms
|
||||||
self.no_auto_join = no_auto_join
|
self.no_auto_join = no_auto_join
|
||||||
self.port = port
|
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):
|
def register_xmpp_event_handlers(self):
|
||||||
"""Register functions against specific XMPP event handlers."""
|
"""Register functions against specific XMPP event handlers."""
|
||||||
|
Reference in New Issue
Block a user