Support avatars
Closes https://git.autonomic.zone/decentral1se/xbotlib/issues/17.
This commit is contained in:
parent
d9e48a5567
commit
78581dcf2f
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
|
*.conf
|
||||||
*.egg-info/
|
*.egg-info/
|
||||||
*.pyc
|
*.pyc
|
||||||
.coverage
|
.coverage
|
||||||
@ -6,8 +7,8 @@
|
|||||||
.mypy_cache/
|
.mypy_cache/
|
||||||
.tox/
|
.tox/
|
||||||
__pycache__
|
__pycache__
|
||||||
*.conf
|
avatar.png
|
||||||
echobot.py
|
|
||||||
build/
|
build/
|
||||||
dist/
|
dist/
|
||||||
|
echobot.py
|
||||||
pip-wheel-metadata/
|
pip-wheel-metadata/
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
# xbotlib x.x.x (UNRELEASED)
|
# xbotlib x.x.x (UNRELEASED)
|
||||||
|
|
||||||
|
# xbotlib 0.8.1 (2021-01-15)
|
||||||
|
|
||||||
|
- Support avatars ([#17](https://git.autonomic.zone/decentral1se/xbotlib/issues/17))
|
||||||
|
|
||||||
# xbotlib 0.8.0 (2021-01-14)
|
# xbotlib 0.8.0 (2021-01-14)
|
||||||
|
|
||||||
- Support not providing response implementation ([#18](https://git.autonomic.zone/decentral1se/xbotlib/issues/18))
|
- Support not providing response implementation ([#18](https://git.autonomic.zone/decentral1se/xbotlib/issues/18))
|
||||||
|
@ -109,6 +109,13 @@ The bot will then respond to:
|
|||||||
- `!uptime` commands in direct messages
|
- `!uptime` commands in direct messages
|
||||||
- `<nick>:!uptime` commands in group chats (use your own nick)
|
- `<nick>:!uptime` commands in group chats (use your own nick)
|
||||||
|
|
||||||
|
## Avatars
|
||||||
|
|
||||||
|
By default, `xbotlib` will look for an `avatar.png` file alongside your Python
|
||||||
|
script which contains your bot implementation. You can also specify another
|
||||||
|
path using the `--avatar` option on the command-line interface. The images
|
||||||
|
should ideally have a height of `64` and a width of `64` pixels each.
|
||||||
|
|
||||||
## Configure your bot
|
## Configure your bot
|
||||||
|
|
||||||
All the ways you can pass configuration details to your bot.
|
All the ways you can pass configuration details to your bot.
|
||||||
|
34
xbotlib.py
34
xbotlib.py
@ -4,6 +4,7 @@ from argparse import ArgumentParser
|
|||||||
from configparser import ConfigParser
|
from configparser import ConfigParser
|
||||||
from datetime import datetime as dt
|
from datetime import datetime as dt
|
||||||
from getpass import getpass
|
from getpass import getpass
|
||||||
|
from imghdr import what
|
||||||
from logging import DEBUG, INFO, basicConfig, getLogger
|
from logging import DEBUG, INFO, basicConfig, getLogger
|
||||||
from os import environ
|
from os import environ
|
||||||
from os.path import exists
|
from os.path import exists
|
||||||
@ -12,6 +13,7 @@ from sys import exit, stdout
|
|||||||
|
|
||||||
from humanize import naturaldelta
|
from humanize import naturaldelta
|
||||||
from slixmpp import ClientXMPP
|
from slixmpp import ClientXMPP
|
||||||
|
from slixmpp.exceptions import XMPPError
|
||||||
|
|
||||||
|
|
||||||
class SimpleMessage:
|
class SimpleMessage:
|
||||||
@ -114,6 +116,13 @@ class Bot(ClientXMPP):
|
|||||||
dest="nick",
|
dest="nick",
|
||||||
help="Nickname for the bot account",
|
help="Nickname for the bot account",
|
||||||
)
|
)
|
||||||
|
self.parser.add_argument(
|
||||||
|
"-av",
|
||||||
|
"--avatar",
|
||||||
|
dest="avatar",
|
||||||
|
help="Avatar for the bot account",
|
||||||
|
default="avatar.png",
|
||||||
|
)
|
||||||
|
|
||||||
self.args = self.parser.parse_args()
|
self.args = self.parser.parse_args()
|
||||||
|
|
||||||
@ -185,6 +194,8 @@ class Bot(ClientXMPP):
|
|||||||
self.password = password
|
self.password = password
|
||||||
self.nick = nick
|
self.nick = nick
|
||||||
|
|
||||||
|
self.avatar = self.args.avatar
|
||||||
|
|
||||||
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."""
|
||||||
self.add_event_handler("session_start", self.session_start)
|
self.add_event_handler("session_start", self.session_start)
|
||||||
@ -210,6 +221,27 @@ class Bot(ClientXMPP):
|
|||||||
"""Handle session_start event."""
|
"""Handle session_start event."""
|
||||||
self.send_presence()
|
self.send_presence()
|
||||||
self.get_roster()
|
self.get_roster()
|
||||||
|
self.publish_avatar()
|
||||||
|
|
||||||
|
def publish_avatar(self):
|
||||||
|
"""Publish bot avatar."""
|
||||||
|
try:
|
||||||
|
abspath = Path(self.avatar).absolute()
|
||||||
|
with open(abspath, "rb") as handle:
|
||||||
|
contents = handle.read()
|
||||||
|
except IOError:
|
||||||
|
self.log.info(f"No avatar discovered (tried '{abspath}')")
|
||||||
|
return
|
||||||
|
|
||||||
|
id = self.plugin["xep_0084"].generate_id(contents)
|
||||||
|
info = {
|
||||||
|
"id": id,
|
||||||
|
"type": f"image/{what('', contents)}",
|
||||||
|
"bytes": len(contents),
|
||||||
|
}
|
||||||
|
|
||||||
|
self.plugin["xep_0084"].publish_avatar(contents)
|
||||||
|
self.plugin["xep_0084"].publish_avatar_metadata(items=[info])
|
||||||
|
|
||||||
def group_invite(self, message):
|
def group_invite(self, message):
|
||||||
"""Accept invites to group chats."""
|
"""Accept invites to group chats."""
|
||||||
@ -236,6 +268,8 @@ class Bot(ClientXMPP):
|
|||||||
self.register_plugin("xep_0045") # Multi-User Chat
|
self.register_plugin("xep_0045") # Multi-User Chat
|
||||||
self.register_plugin("xep_0199") # XMPP Ping
|
self.register_plugin("xep_0199") # XMPP Ping
|
||||||
|
|
||||||
|
self.register_plugin("xep_0084") # User Avatar
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
"""Run the bot."""
|
"""Run the bot."""
|
||||||
self.connect()
|
self.connect()
|
||||||
|
Reference in New Issue
Block a user