Support extras and stay slim on initial install
See https://git.vvvvvvaria.org/decentral1se/xbotlib/issues/7.
This commit is contained in:
parent
745a561409
commit
998667c839
|
@ -7,6 +7,7 @@
|
||||||
- Document `return` statement semantics ([#6](https://git.vvvvvvaria.org/decentral1se/xbotlib/issues/6))
|
- Document `return` statement semantics ([#6](https://git.vvvvvvaria.org/decentral1se/xbotlib/issues/6))
|
||||||
- Make file system the first-class storage option ([#3](https://git.vvvvvvaria.org/decentral1se/xbotlib/issues/3))
|
- Make file system the first-class storage option ([#3](https://git.vvvvvvaria.org/decentral1se/xbotlib/issues/3))
|
||||||
- Note support for open formats when serving the web ([#5](https://git.vvvvvvaria.org/decentral1se/xbotlib/issues/5))
|
- Note support for open formats when serving the web ([#5](https://git.vvvvvvaria.org/decentral1se/xbotlib/issues/5))
|
||||||
|
- Support extras for optional dependencies ([#7](https://git.vvvvvvaria.org/decentral1se/xbotlib/issues/7))
|
||||||
|
|
||||||
# xbotlib 0.14.1 (2021-01-21)
|
# xbotlib 0.14.1 (2021-01-21)
|
||||||
|
|
||||||
|
|
|
@ -278,7 +278,8 @@ $ cat mybot.json
|
||||||
For more advanced use cases, `xbotlib` also supports [Redis](https://redis.io/)
|
For more advanced use cases, `xbotlib` also supports [Redis](https://redis.io/)
|
||||||
as a storage back-end. You'll need to configure this (e.g. `--storage redis`)
|
as a storage back-end. You'll need to configure this (e.g. `--storage redis`)
|
||||||
as the default uses the filesystem approach mentioned above. The same `self.db`
|
as the default uses the filesystem approach mentioned above. The same `self.db`
|
||||||
will then be passed as a Redis connection object.
|
will then be passed as a Redis connection object. You will also need to install
|
||||||
|
additional dependencies using `pip install xbotlib[redis]`.
|
||||||
|
|
||||||
### Loading Plugins
|
### Loading Plugins
|
||||||
|
|
||||||
|
@ -294,6 +295,12 @@ See [here](https://slixmpp.readthedocs.io/xeps.html) for the list of supported p
|
||||||
|
|
||||||
### Serving HTTP
|
### Serving HTTP
|
||||||
|
|
||||||
|
Firstly, you'll need to install additional dependencies.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ pip install xbotlib[web]
|
||||||
|
```
|
||||||
|
|
||||||
Your bot will run a web server if you configure it to do so. Use the `--serve`
|
Your bot will run a web server if you configure it to do so. Use the `--serve`
|
||||||
option on the command-line, the `serve = True` configuration option or the
|
option on the command-line, the `serve = True` configuration option or the
|
||||||
`XBOT_SERVE=True` environment variable.
|
`XBOT_SERVE=True` environment variable.
|
||||||
|
|
|
@ -15,7 +15,7 @@ name = "aiohttp"
|
||||||
version = "3.7.3"
|
version = "3.7.3"
|
||||||
description = "Async http client/server framework (asyncio)"
|
description = "Async http client/server framework (asyncio)"
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = true
|
||||||
python-versions = ">=3.6"
|
python-versions = ">=3.6"
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -43,7 +43,7 @@ name = "async-timeout"
|
||||||
version = "3.0.1"
|
version = "3.0.1"
|
||||||
description = "Timeout context manager for asyncio programs"
|
description = "Timeout context manager for asyncio programs"
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = true
|
||||||
python-versions = ">=3.5.3"
|
python-versions = ">=3.5.3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -96,7 +96,7 @@ name = "chardet"
|
||||||
version = "3.0.4"
|
version = "3.0.4"
|
||||||
description = "Universal encoding detector for Python 2 and 3"
|
description = "Universal encoding detector for Python 2 and 3"
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = true
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -137,7 +137,7 @@ name = "idna"
|
||||||
version = "3.1"
|
version = "3.1"
|
||||||
description = "Internationalized Domain Names in Applications (IDNA)"
|
description = "Internationalized Domain Names in Applications (IDNA)"
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = true
|
||||||
python-versions = ">=3.4"
|
python-versions = ">=3.4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -145,7 +145,7 @@ name = "idna-ssl"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
description = "Patch ssl.match_hostname for Unicode(idna) domains support"
|
description = "Patch ssl.match_hostname for Unicode(idna) domains support"
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = true
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -185,7 +185,7 @@ name = "jinja2"
|
||||||
version = "2.11.2"
|
version = "2.11.2"
|
||||||
description = "A very fast and expressive template engine."
|
description = "A very fast and expressive template engine."
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = true
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -199,7 +199,7 @@ name = "markupsafe"
|
||||||
version = "1.1.1"
|
version = "1.1.1"
|
||||||
description = "Safely add untrusted strings to HTML/XML markup."
|
description = "Safely add untrusted strings to HTML/XML markup."
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = true
|
||||||
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*"
|
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -215,7 +215,7 @@ name = "multidict"
|
||||||
version = "5.1.0"
|
version = "5.1.0"
|
||||||
description = "multidict implementation"
|
description = "multidict implementation"
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = true
|
||||||
python-versions = ">=3.6"
|
python-versions = ">=3.6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -288,7 +288,7 @@ name = "redis"
|
||||||
version = "3.5.3"
|
version = "3.5.3"
|
||||||
description = "Python client for Redis key-value store"
|
description = "Python client for Redis key-value store"
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = true
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
|
@ -356,7 +356,7 @@ name = "yarl"
|
||||||
version = "1.6.3"
|
version = "1.6.3"
|
||||||
description = "Yet another URL library"
|
description = "Yet another URL library"
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = true
|
||||||
python-versions = ">=3.6"
|
python-versions = ">=3.6"
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -376,10 +376,14 @@ python-versions = ">=3.6"
|
||||||
docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"]
|
docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"]
|
||||||
testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"]
|
testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"]
|
||||||
|
|
||||||
|
[extras]
|
||||||
|
redis = ["redis"]
|
||||||
|
web = ["aiohttp", "Jinja2"]
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "1.1"
|
lock-version = "1.1"
|
||||||
python-versions = "^3.6"
|
python-versions = "^3.6"
|
||||||
content-hash = "0578ed3f31fcb6ea0b170b1afe2950a047bcd3eae5c0200982f2fd61abcb9307"
|
content-hash = "4d10b4f1e9f193be431e27f13f861f033a4c59e89258be4b40399b54f574c691"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
aiodns = [
|
aiodns = [
|
||||||
|
|
|
@ -17,15 +17,19 @@ keywords = []
|
||||||
python = "^3.6"
|
python = "^3.6"
|
||||||
slixmpp = "^1.6.0"
|
slixmpp = "^1.6.0"
|
||||||
humanize = "^3.2.0"
|
humanize = "^3.2.0"
|
||||||
redis = "^3.5.3"
|
redis = {version = "^3.5.3", optional = true}
|
||||||
Jinja2 = "^2.11.2"
|
aiohttp = {version = "^3.7.3", optional = true}
|
||||||
aiohttp = "^3.7.3"
|
Jinja2 = {version = "^2.11.2", optional = true}
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
black = "^19.10b0"
|
black = "^19.10b0"
|
||||||
flake8 = "^3.8.3"
|
flake8 = "^3.8.3"
|
||||||
isort = "^5.0.2"
|
isort = "^5.0.2"
|
||||||
|
|
||||||
|
[tool.poetry.extras]
|
||||||
|
redis = ["redis"]
|
||||||
|
web = ["aiohttp", "jinja2"]
|
||||||
|
|
||||||
[tool.black]
|
[tool.black]
|
||||||
line-length = 80
|
line-length = 80
|
||||||
target-version = ["py38"]
|
target-version = ["py38"]
|
||||||
|
|
32
xbotlib.py
32
xbotlib.py
|
@ -14,10 +14,7 @@ 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 humanize import naturaldelta
|
from humanize import naturaldelta
|
||||||
from jinja2 import Environment, FileSystemLoader
|
|
||||||
from redis import Redis
|
|
||||||
from slixmpp import ClientXMPP
|
from slixmpp import ClientXMPP
|
||||||
|
|
||||||
|
|
||||||
|
@ -434,8 +431,8 @@ 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)
|
|
||||||
self.serve = serve
|
self.serve = serve
|
||||||
|
self.template = self.load_template(template) if self.serve else None
|
||||||
self.storage = storage
|
self.storage = storage
|
||||||
self.storage_file = Path(storage_file).absolute()
|
self.storage_file = Path(storage_file).absolute()
|
||||||
|
|
||||||
|
@ -444,6 +441,13 @@ class Bot(ClientXMPP):
|
||||||
if not exists(Path(template).absolute()):
|
if not exists(Path(template).absolute()):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
try:
|
||||||
|
from jinja2 import Environment, FileSystemLoader
|
||||||
|
except ModuleNotFoundError:
|
||||||
|
print("Missing required dependency: jinja2")
|
||||||
|
print("Have you tried `pip install xbotlib[web]`")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
loader = FileSystemLoader(searchpath="./")
|
loader = FileSystemLoader(searchpath="./")
|
||||||
env = Environment(loader=loader)
|
env = Environment(loader=loader)
|
||||||
|
@ -578,12 +582,18 @@ class Bot(ClientXMPP):
|
||||||
exit(1)
|
exit(1)
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
|
from redis import Redis
|
||||||
|
|
||||||
self.db = Redis.from_url(self.redis_url, decode_responses=True)
|
self.db = Redis.from_url(self.redis_url, decode_responses=True)
|
||||||
return self.log.info("Successfully connected to Redis storage")
|
return self.log.info("Successfully connected to Redis storage")
|
||||||
except ValueError as exception:
|
except ValueError as exception:
|
||||||
message = f"Failed to connect to Redis storage: {exception}"
|
message = f"Failed to connect to Redis storage: {exception}"
|
||||||
self.log.info(message)
|
self.log.info(message)
|
||||||
exit(1)
|
exit(1)
|
||||||
|
except ModuleNotFoundError:
|
||||||
|
print("missing required dependency using Redis")
|
||||||
|
print("Have you tried `pip install xbotlib[redis]`")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
"""Run the bot."""
|
"""Run the bot."""
|
||||||
|
@ -628,6 +638,13 @@ class Bot(ClientXMPP):
|
||||||
|
|
||||||
async def default_serve(self, request):
|
async def default_serve(self, request):
|
||||||
"""Default placeholder text for HTML serving."""
|
"""Default placeholder text for HTML serving."""
|
||||||
|
try:
|
||||||
|
from aiohttp.web import Response
|
||||||
|
except ModuleNotFoundError:
|
||||||
|
print("Missing required dependency: aiohttp")
|
||||||
|
print("Have you tried `pip install xbotlib[web]`")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
return Response(text=f"{self.nick} is alive and well")
|
return Response(text=f"{self.nick} is alive and well")
|
||||||
|
|
||||||
def reply(self, text, to=None, room=None):
|
def reply(self, text, to=None, room=None):
|
||||||
|
@ -673,4 +690,11 @@ class Bot(ClientXMPP):
|
||||||
|
|
||||||
def respond(self, response, content_type="text/html"):
|
def respond(self, response, content_type="text/html"):
|
||||||
"""Send this response back with the web server."""
|
"""Send this response back with the web server."""
|
||||||
|
try:
|
||||||
|
from aiohttp.web import Response
|
||||||
|
except ModuleNotFoundError:
|
||||||
|
print("Missing required dependency: aiohttp")
|
||||||
|
print("Have you tried `pip install xbotlib[web]`")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
return Response(text=response, content_type=content_type)
|
return Response(text=response, content_type=content_type)
|
||||||
|
|
Loading…
Reference in New Issue