Compare commits

...

10 Commits

6 changed files with 78 additions and 44 deletions

View File

@ -1,12 +1,16 @@
# xbotlib x.x.x (UNRELEASED) # xbotlib x.x.x (UNRELEASED)
# xbotlib 0.16.0 (2021-01-??) # xbotlib 0.16.0 (2021-02-02)
- Fix logging of exceptions and increase info for stack traces ([#2](https://github.com/decentral1se/xbotlib/issues/2)) - Fix logging of exceptions and increase info for stack traces ([#2](https://github.com/decentral1se/xbotlib/issues/2))
- Format JSON to human readable when saving ([#8](https://git.vvvvvvaria.org/decentral1se/xbotlib/issues/8)) - Format JSON to human readable when saving ([#8](https://git.vvvvvvaria.org/decentral1se/xbotlib/issues/8))
- Fix room formatting when storing in configuration files ([#10](https://git.vvvvvvaria.org/decentral1se/xbotlib/issues/10)) - Fix room formatting when storing in configuration files ([#10](https://git.vvvvvvaria.org/decentral1se/xbotlib/issues/10))
- `--storage-file` goes away and is replaced by the `--output` option ([#9](https://git.vvvvvvaria.org/decentral1se/xbotlib/issues/9)) - `--storage-file` goes away and is replaced by the `--output` option ([#9](https://git.vvvvvvaria.org/decentral1se/xbotlib/issues/9))
- New internal runtime data store available in `.xbotlib/data.json` ([#11](https://git.vvvvvvaria.org/decentral1se/xbotlib/issues/11)) - New internal runtime data store available in `.xbotlib/data.json` ([#11](https://git.vvvvvvaria.org/decentral1se/xbotlib/issues/11))
- Add documentation for invitations management ([#11](https://git.vvvvvvaria.org/decentral1se/xbotlib/issues/11))
- Fix `del` usage for `SimpleStorage` ([#5](https://github.com/decentral1se/xbotlib/issues/5))
- Always log tracebacks for errors ([#6](https://github.com/decentral1se/xbotlib/issues/6))
- Use latest Slixmpp (1.7) version
# xbotlib 0.15.2 (2021-01-24) # xbotlib 0.15.2 (2021-01-24)

View File

@ -258,6 +258,7 @@ easily template and generate HTML. The web server is provided by
The default template search path is `index.html.j2` in the current working The default template search path is `index.html.j2` in the current working
directory. This can be configured through the usual configuration entrypoints. directory. This can be configured through the usual configuration entrypoints.
It is possible to use the template without the built-in server too!
Here's a small example that renders a random ASCII letter and uses a stylesheet. Here's a small example that renders a random ASCII letter and uses a stylesheet.
@ -412,11 +413,11 @@ you want to chat or just invite your bots for testing.
## More Examples ## More Examples
See more examples on [git.vvvvvvaria.org](https://git.vvvvvvaria.org/explore/repos?q=xbotlib&topic=1). See more examples on [git.vvvvvvaria.org](https://git.vvvvvvaria.org/varia/bots).
## Deploy your bots ## Deploy your bots
See [bots.varia.zone](https://bots.varia.zone/). > Documentation coming **soon**.
## Roadmap ## Roadmap

40
poetry.lock generated
View File

@ -153,7 +153,7 @@ idna = ">=2.0"
[[package]] [[package]]
name = "importlib-metadata" name = "importlib-metadata"
version = "3.3.0" version = "3.4.0"
description = "Read metadata from Python packages" description = "Read metadata from Python packages"
category = "dev" category = "dev"
optional = false optional = false
@ -164,8 +164,8 @@ typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""}
zipp = ">=0.5" zipp = ">=0.5"
[package.extras] [package.extras]
docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] docs = ["sphinx", "jaraco.packaging (>=8.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)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "pytest-enabler", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"]
[[package]] [[package]]
name = "isort" name = "isort"
@ -182,7 +182,7 @@ colors = ["colorama (>=0.4.3,<0.5.0)"]
[[package]] [[package]]
name = "jinja2" name = "jinja2"
version = "2.11.2" version = "2.11.3"
description = "A very fast and expressive template engine." description = "A very fast and expressive template engine."
category = "main" category = "main"
optional = true optional = true
@ -304,7 +304,7 @@ python-versions = "*"
[[package]] [[package]]
name = "slixmpp" name = "slixmpp"
version = "1.6.0" version = "1.7.0"
description = "Slixmpp is an elegant Python library for XMPP (aka Jabber)." description = "Slixmpp is an elegant Python library for XMPP (aka Jabber)."
category = "main" category = "main"
optional = false optional = false
@ -479,6 +479,7 @@ cffi = [
{file = "cffi-1.14.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:840793c68105fe031f34d6a086eaea153a0cd5c491cde82a74b420edd0a2b909"}, {file = "cffi-1.14.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:840793c68105fe031f34d6a086eaea153a0cd5c491cde82a74b420edd0a2b909"},
{file = "cffi-1.14.4-cp39-cp39-manylinux1_i686.whl", hash = "sha256:b18e0a9ef57d2b41f5c68beefa32317d286c3d6ac0484efd10d6e07491bb95dd"}, {file = "cffi-1.14.4-cp39-cp39-manylinux1_i686.whl", hash = "sha256:b18e0a9ef57d2b41f5c68beefa32317d286c3d6ac0484efd10d6e07491bb95dd"},
{file = "cffi-1.14.4-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:045d792900a75e8b1e1b0ab6787dd733a8190ffcf80e8c8ceb2fb10a29ff238a"}, {file = "cffi-1.14.4-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:045d792900a75e8b1e1b0ab6787dd733a8190ffcf80e8c8ceb2fb10a29ff238a"},
{file = "cffi-1.14.4-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:7ef7d4ced6b325e92eb4d3502946c78c5367bc416398d387b39591532536734e"},
{file = "cffi-1.14.4-cp39-cp39-win32.whl", hash = "sha256:ba4e9e0ae13fc41c6b23299545e5ef73055213e466bd107953e4a013a5ddd7e3"}, {file = "cffi-1.14.4-cp39-cp39-win32.whl", hash = "sha256:ba4e9e0ae13fc41c6b23299545e5ef73055213e466bd107953e4a013a5ddd7e3"},
{file = "cffi-1.14.4-cp39-cp39-win_amd64.whl", hash = "sha256:f032b34669220030f905152045dfa27741ce1a6db3324a5bc0b96b6c7420c87b"}, {file = "cffi-1.14.4-cp39-cp39-win_amd64.whl", hash = "sha256:f032b34669220030f905152045dfa27741ce1a6db3324a5bc0b96b6c7420c87b"},
{file = "cffi-1.14.4.tar.gz", hash = "sha256:1a465cbe98a7fd391d47dce4b8f7e5b921e6cd805ef421d04f5f66ba8f06086c"}, {file = "cffi-1.14.4.tar.gz", hash = "sha256:1a465cbe98a7fd391d47dce4b8f7e5b921e6cd805ef421d04f5f66ba8f06086c"},
@ -507,16 +508,16 @@ idna-ssl = [
{file = "idna-ssl-1.1.0.tar.gz", hash = "sha256:a933e3bb13da54383f9e8f35dc4f9cb9eb9b3b78c6b36f311254d6d0d92c6c7c"}, {file = "idna-ssl-1.1.0.tar.gz", hash = "sha256:a933e3bb13da54383f9e8f35dc4f9cb9eb9b3b78c6b36f311254d6d0d92c6c7c"},
] ]
importlib-metadata = [ importlib-metadata = [
{file = "importlib_metadata-3.3.0-py3-none-any.whl", hash = "sha256:bf792d480abbd5eda85794e4afb09dd538393f7d6e6ffef6e9f03d2014cf9450"}, {file = "importlib_metadata-3.4.0-py3-none-any.whl", hash = "sha256:ace61d5fc652dc280e7b6b4ff732a9c2d40db2c0f92bc6cb74e07b73d53a1771"},
{file = "importlib_metadata-3.3.0.tar.gz", hash = "sha256:5c5a2720817414a6c41f0a49993908068243ae02c1635a228126519b509c8aed"}, {file = "importlib_metadata-3.4.0.tar.gz", hash = "sha256:fa5daa4477a7414ae34e95942e4dd07f62adf589143c875c133c1e53c4eff38d"},
] ]
isort = [ isort = [
{file = "isort-5.7.0-py3-none-any.whl", hash = "sha256:fff4f0c04e1825522ce6949973e83110a6e907750cd92d128b0d14aaaadbffdc"}, {file = "isort-5.7.0-py3-none-any.whl", hash = "sha256:fff4f0c04e1825522ce6949973e83110a6e907750cd92d128b0d14aaaadbffdc"},
{file = "isort-5.7.0.tar.gz", hash = "sha256:c729845434366216d320e936b8ad6f9d681aab72dc7cbc2d51bedc3582f3ad1e"}, {file = "isort-5.7.0.tar.gz", hash = "sha256:c729845434366216d320e936b8ad6f9d681aab72dc7cbc2d51bedc3582f3ad1e"},
] ]
jinja2 = [ jinja2 = [
{file = "Jinja2-2.11.2-py2.py3-none-any.whl", hash = "sha256:f0a4641d3cf955324a89c04f3d94663aa4d638abe8f733ecd3582848e1c37035"}, {file = "Jinja2-2.11.3-py2.py3-none-any.whl", hash = "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419"},
{file = "Jinja2-2.11.2.tar.gz", hash = "sha256:89aab215427ef59c34ad58735269eb58b1a5808103067f7bb9d5836c651b3bb0"}, {file = "Jinja2-2.11.3.tar.gz", hash = "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6"},
] ]
markupsafe = [ markupsafe = [
{file = "MarkupSafe-1.1.1-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161"}, {file = "MarkupSafe-1.1.1-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161"},
@ -537,20 +538,39 @@ markupsafe = [
{file = "MarkupSafe-1.1.1-cp35-cp35m-win32.whl", hash = "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1"}, {file = "MarkupSafe-1.1.1-cp35-cp35m-win32.whl", hash = "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1"},
{file = "MarkupSafe-1.1.1-cp35-cp35m-win_amd64.whl", hash = "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d"}, {file = "MarkupSafe-1.1.1-cp35-cp35m-win_amd64.whl", hash = "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d"},
{file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff"}, {file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff"},
{file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d53bc011414228441014aa71dbec320c66468c1030aae3a6e29778a3382d96e5"},
{file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473"}, {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473"},
{file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e"}, {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e"},
{file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:3b8a6499709d29c2e2399569d96719a1b21dcd94410a586a18526b143ec8470f"},
{file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:84dee80c15f1b560d55bcfe6d47b27d070b4681c699c572af2e3c7cc90a3b8e0"},
{file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:b1dba4527182c95a0db8b6060cc98ac49b9e2f5e64320e2b56e47cb2831978c7"},
{file = "MarkupSafe-1.1.1-cp36-cp36m-win32.whl", hash = "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66"}, {file = "MarkupSafe-1.1.1-cp36-cp36m-win32.whl", hash = "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66"},
{file = "MarkupSafe-1.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5"}, {file = "MarkupSafe-1.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5"},
{file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d"}, {file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d"},
{file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:bf5aa3cbcfdf57fa2ee9cd1822c862ef23037f5c832ad09cfea57fa846dec193"},
{file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e"}, {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e"},
{file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6"}, {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6"},
{file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:6fffc775d90dcc9aed1b89219549b329a9250d918fd0b8fa8d93d154918422e1"},
{file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:a6a744282b7718a2a62d2ed9d993cad6f5f585605ad352c11de459f4108df0a1"},
{file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:195d7d2c4fbb0ee8139a6cf67194f3973a6b3042d742ebe0a9ed36d8b6f0c07f"},
{file = "MarkupSafe-1.1.1-cp37-cp37m-win32.whl", hash = "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2"}, {file = "MarkupSafe-1.1.1-cp37-cp37m-win32.whl", hash = "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2"},
{file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"}, {file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"},
{file = "MarkupSafe-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15"}, {file = "MarkupSafe-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15"},
{file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2"}, {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2"},
{file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42"}, {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42"},
{file = "MarkupSafe-1.1.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:acf08ac40292838b3cbbb06cfe9b2cb9ec78fce8baca31ddb87aaac2e2dc3bc2"},
{file = "MarkupSafe-1.1.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:d9be0ba6c527163cbed5e0857c451fcd092ce83947944d6c14bc95441203f032"},
{file = "MarkupSafe-1.1.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:caabedc8323f1e93231b52fc32bdcde6db817623d33e100708d9a68e1f53b26b"},
{file = "MarkupSafe-1.1.1-cp38-cp38-win32.whl", hash = "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b"}, {file = "MarkupSafe-1.1.1-cp38-cp38-win32.whl", hash = "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b"},
{file = "MarkupSafe-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be"}, {file = "MarkupSafe-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be"},
{file = "MarkupSafe-1.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d73a845f227b0bfe8a7455ee623525ee656a9e2e749e4742706d80a6065d5e2c"},
{file = "MarkupSafe-1.1.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:98bae9582248d6cf62321dcb52aaf5d9adf0bad3b40582925ef7c7f0ed85fceb"},
{file = "MarkupSafe-1.1.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:2beec1e0de6924ea551859edb9e7679da6e4870d32cb766240ce17e0a0ba2014"},
{file = "MarkupSafe-1.1.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:7fed13866cf14bba33e7176717346713881f56d9d2bcebab207f7a036f41b850"},
{file = "MarkupSafe-1.1.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:6f1e273a344928347c1290119b493a1f0303c52f5a5eae5f16d74f48c15d4a85"},
{file = "MarkupSafe-1.1.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:feb7b34d6325451ef96bc0e36e1a6c0c1c64bc1fbec4b854f4529e51887b1621"},
{file = "MarkupSafe-1.1.1-cp39-cp39-win32.whl", hash = "sha256:22c178a091fc6630d0d045bdb5992d2dfe14e3259760e713c490da5323866c39"},
{file = "MarkupSafe-1.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:b7d644ddb4dbd407d31ffb699f1d140bc35478da613b441c582aeb7c43838dd8"},
{file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"}, {file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"},
] ]
mccabe = [ mccabe = [
@ -721,7 +741,7 @@ regex = [
{file = "regex-2020.11.13.tar.gz", hash = "sha256:83d6b356e116ca119db8e7c6fc2983289d87b27b3fac238cfe5dca529d884562"}, {file = "regex-2020.11.13.tar.gz", hash = "sha256:83d6b356e116ca119db8e7c6fc2983289d87b27b3fac238cfe5dca529d884562"},
] ]
slixmpp = [ slixmpp = [
{file = "slixmpp-1.6.0.tar.gz", hash = "sha256:8a3799856068d67dccb233b91309e511911ab612c57ab4ef53398c2d83a75549"}, {file = "slixmpp-1.7.0.tar.gz", hash = "sha256:7f2eec44a4bb8a1e099a3396fe7a0bf2a275c5656940b6c16ce6c79ccc13dc17"},
] ]
toml = [ toml = [
{file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},

View File

@ -4,7 +4,7 @@ build-backend = "poetry.masonry.api"
[tool.poetry] [tool.poetry]
name = "xbotlib" name = "xbotlib"
version = "0.15.2" version = "0.16.0"
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>"]

View File

@ -1,7 +1,6 @@
"""Unit tests for xbotlib module.""" """Unit tests for xbotlib module."""
from logging import getLogger from logging import getLogger
from pathlib import Path
from pytest import fixture from pytest import fixture
@ -101,3 +100,10 @@ def test_config(config):
assert config.serve assert config.serve
assert config.storage == "file" assert config.storage == "file"
assert config.output == "." assert config.output == "."
def test_simple_message_delete(tmp_db_path):
db = SimpleDatabase(tmp_db_path, log)
db["foo"] = "bar"
del db["foo"]
assert "foo" not in db

View File

@ -13,7 +13,6 @@ from os import environ, mkdir
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 traceback import print_exc
from humanize import naturaldelta from humanize import naturaldelta
from slixmpp import ClientXMPP from slixmpp import ClientXMPP
@ -44,7 +43,7 @@ class SimpleDatabase(dict):
self.update(loads(handle.read())) self.update(loads(handle.read()))
except Exception as exception: except Exception as exception:
message = f"Loading file storage failed: {exception}" message = f"Loading file storage failed: {exception}"
self.log.error(message) self.log.error(message, exc_info=exception)
exit(1) exit(1)
def _dumps(self): def _dumps(self):
@ -54,17 +53,17 @@ class SimpleDatabase(dict):
handle.write(dumps(self, indent=2, sort_keys=True)) handle.write(dumps(self, indent=2, sort_keys=True))
except Exception as exception: except Exception as exception:
message = f"Saving file storage failed: {exception}" message = f"Saving file storage failed: {exception}"
self.log.error(message) self.log.error(message, exc_info=exception)
exit(1) exit(1)
def __setitem__(self, key, val): def __setitem__(self, key, val):
"""Write data to the database.""" """Write data to the database."""
dict.__setitem__(self, key, val) super().__setitem__(key, val)
self._dumps() self._dumps()
def __delitem__(self, key): def __delitem__(self, key):
"""Remove data from the database.""" """Remove data from the database."""
dict.__delitem__(key) super().__delitem__(key)
self._dumps() self._dumps()
def update(self, *args, **kwargs): def update(self, *args, **kwargs):
@ -112,7 +111,8 @@ class SimpleMessage:
filtered = list(filter(None, split)) filtered = list(filter(None, split))
return filtered[-1].strip() return filtered[-1].strip()
except Exception as exception: except Exception as exception:
self.log.error(f"Couldn't parse {body}: {exception}") message = f"Couldn't parse {body}: {exception}"
self.log.error(message, exc_info=exception)
return None return None
@property @property
@ -490,11 +490,7 @@ class Bot(ClientXMPP):
self.no_auto_join = no_auto_join self.no_auto_join = no_auto_join
self.port = port self.port = port
self.serve_web = serve_web self.serve_web = serve_web
self.template = self.load_template(template)
self.template = None
if self.serve_web:
self.template = self.load_template(template)
self.storage = storage self.storage = storage
self.output = Path(output).absolute() self.output = Path(output).absolute()
@ -505,10 +501,11 @@ class Bot(ClientXMPP):
try: try:
from jinja2 import Environment, FileSystemLoader from jinja2 import Environment, FileSystemLoader
except ModuleNotFoundError: except ModuleNotFoundError as exception:
self.log.error( self.log.error(
"Missing required dependency jinja2, ", "Missing required dependency jinja2, ",
"have you tried `pip install xbotlib[web]`", "have you tried `pip install xbotlib[web]`",
exc_info=exception,
) )
exit(1) exit(1)
@ -516,8 +513,9 @@ class Bot(ClientXMPP):
loader = FileSystemLoader(searchpath="./") loader = FileSystemLoader(searchpath="./")
env = Environment(loader=loader) env = Environment(loader=loader)
return env.get_template(template) return env.get_template(template)
except Exception: except Exception as exception:
self.log.error(f"Unable to load {template}") message = f"Unable to load {template}"
self.log.error(message, exc_info=exception)
exit(1) exit(1)
def register_xmpp_event_handlers(self): def register_xmpp_event_handlers(self):
@ -550,8 +548,8 @@ class Bot(ClientXMPP):
try: try:
self.direct(message) self.direct(message)
except Exception as exception: except Exception as exception:
self.log.error(f"Bot.direct threw exception: {exception}") message = f"Bot.direct threw exception: {exception}"
print_exc(file=stdout) self.log.error(message, exc_info=exception)
if self.storage == "file": if self.storage == "file":
self.db._dumps() self.db._dumps()
@ -575,7 +573,8 @@ class Bot(ClientXMPP):
with open(abspath, "rb") as handle: with open(abspath, "rb") as handle:
contents = handle.read() contents = handle.read()
except Exception as exception: except Exception as exception:
self.log.error(f"Failed to load avatar: {exception}") message = f"Failed to load avatar: {exception}"
self.log.error(message, exc_info=exception)
return return
id = self.plugin["xep_0084"].generate_id(contents) id = self.plugin["xep_0084"].generate_id(contents)
@ -641,8 +640,8 @@ class Bot(ClientXMPP):
try: try:
self.group(message) self.group(message)
except Exception as exception: except Exception as exception:
self.log.error(f"Bot.group threw exception: {exception}") message = f"Bot.group threw exception: {exception}"
print_exc(file=stdout) self.log.error(message, exc_info=exception)
if self.storage == "file": if self.storage == "file":
self.db._dumps() self.db._dumps()
@ -665,7 +664,7 @@ class Bot(ClientXMPP):
self.log.info(f"Loaded {plugin}") self.log.info(f"Loaded {plugin}")
except Exception as exception: except Exception as exception:
message = f"Loading additional plugins failed: {exception}" message = f"Loading additional plugins failed: {exception}"
self.log.error(message) self.log.error(message, exc_info=exception)
def init_storage(self): def init_storage(self):
"""Initialise the storage back-end.""" """Initialise the storage back-end."""
@ -677,7 +676,7 @@ class Bot(ClientXMPP):
self.log.info("Successfully loaded file storage") self.log.info("Successfully loaded file storage")
except Exception as exception: except Exception as exception:
message = f"Failed to load {file_storage_path}: {exception}" message = f"Failed to load {file_storage_path}: {exception}"
self.log.error(message) self.log.error(message, exc_info=exception)
exit(1) exit(1)
else: else:
try: try:
@ -687,12 +686,13 @@ class Bot(ClientXMPP):
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.error(message) self.log.error(message, exc_info=exception)
exit(1) exit(1)
except ModuleNotFoundError: except ModuleNotFoundError as exception:
self.log.error( self.log.error(
"Missing required dependency using Redis, ", "Missing required dependency using Redis, ",
"have you tried `pip install xbotlib[redis]`", "have you tried `pip install xbotlib[redis]`",
exc_info=exception,
) )
exit(1) exit(1)
@ -705,7 +705,7 @@ class Bot(ClientXMPP):
self.log.info("Successfully initialised internal directory") self.log.info("Successfully initialised internal directory")
except Exception as exception: except Exception as exception:
message = f"Failed to create {internal_dir}: {exception}" message = f"Failed to create {internal_dir}: {exception}"
self.log.error(message) self.log.error(message, exc_info=exception)
exit(1) exit(1)
try: try:
@ -714,7 +714,7 @@ class Bot(ClientXMPP):
self.log.info("Successfully loaded internal storage") self.log.info("Successfully loaded internal storage")
except Exception as exception: except Exception as exception:
message = f"Failed to load {internal_storage_path}: {exception}" message = f"Failed to load {internal_storage_path}: {exception}"
self.log.error(message) self.log.error(message, exc_info=exception)
exit(1) exit(1)
if "invited" not in self._data: if "invited" not in self._data:
@ -735,7 +735,7 @@ class Bot(ClientXMPP):
self.log.info("Finished running setup") self.log.info("Finished running setup")
except Exception as exception: except Exception as exception:
message = f"Bot.setup failed: {exception}" message = f"Bot.setup failed: {exception}"
self.log.error(message) self.log.error(message, exc_info=exception)
self.process(forever=False) self.process(forever=False)
except (KeyboardInterrupt, RuntimeError): except (KeyboardInterrupt, RuntimeError):
@ -745,10 +745,11 @@ class Bot(ClientXMPP):
"""Run the web server.""" """Run the web server."""
try: try:
from aiohttp.web import Application, get, run_app from aiohttp.web import Application, get, run_app
except ModuleNotFoundError: except ModuleNotFoundError as exception:
self.log.error( self.log.error(
"Missing required dependency aiohttp, ", "Missing required dependency aiohttp, ",
"have you tried `pip install xbotlib[web]`", "have you tried `pip install xbotlib[web]`",
exc_info=exception,
) )
exit(1) exit(1)
@ -772,10 +773,11 @@ class Bot(ClientXMPP):
"""Default placeholder text for HTML serving.""" """Default placeholder text for HTML serving."""
try: try:
from aiohttp.web import Response from aiohttp.web import Response
except ModuleNotFoundError: except ModuleNotFoundError as exception:
self.log.error( self.log.error(
"Missing required dependency aiohttp, ", "Missing required dependency aiohttp, ",
"have you tried `pip install xbotlib[web]`", "have you tried `pip install xbotlib[web]`",
exc_info=exception,
) )
exit(1) exit(1)
@ -826,10 +828,11 @@ class Bot(ClientXMPP):
"""Send this response back with the web server.""" """Send this response back with the web server."""
try: try:
from aiohttp.web import Response from aiohttp.web import Response
except ModuleNotFoundError: except ModuleNotFoundError as exception:
self.log.error( self.log.error(
"Missing required dependency aiohttp, ", "Missing required dependency aiohttp, ",
"have you tried `pip install xbotlib[web]`", "have you tried `pip install xbotlib[web]`",
exc_info=exception,
) )
exit(1) exit(1)