bots/streambot/streambot.sleekxmpp.py

133 lines
4.5 KiB
Python

import logging
import argparse
from sleekxmpp import ClientXMPP
from sleekxmpp.exceptions import IqError, IqTimeout
import os, subprocess
import urllib.request
import datetime
import ssl
from PIL import Image
from pprint import pprint
# python3 streambot.py -j streambot@vvvvvvaria.org -p ******* -m test@muc.vvvvvvaria.org -o ./stream/
# rewrite script to work with slixmpp >>> https://slixmpp.readthedocs.io/getting_started/muc.html
parser = argparse.ArgumentParser()
parser.add_argument("-j", "--jid", help="jabber identifier", type=str, required=True)
parser.add_argument("-p", "--password", help="password", type=str, required=True)
parser.add_argument("-m", "--muc", help="destination muc", type=str, required=True)
parser.add_argument("-n", "--nick", help="nickname of the bot", default="streambot", type=str)
parser.add_argument("-o", "--output", help="output folder", default="./stream/", type=str)
args = parser.parse_args()
# This was a useful tutorial: http://sleekxmpp.com/getting_started/echobot.html#echobot
class ArchivistBot(ClientXMPP):
def __init__(self, jid, password, room, nick, output):
ClientXMPP.__init__(self, jid, password)
self.datadir = output
self.room = room
self.nick = nick
self.add_event_handler("session_start", self.session_start)
self.add_event_handler("message", self.archive_msg) # by using 'message' instead of 'groupchat_message' every message received can be archived (also personal msgs)
# self.add_event_handler("groupchat_message", self.archive_msg2)
self.register_plugin('xep_0045')
self.register_plugin('xep_0030')
self.register_plugin('xep_0084')
self.register_plugin('xep_0096') # Transfer files..
self.register_plugin('xep_0066') # Transfer files..
def session_start(self, event):
roster = self.get_roster()
print('\nRoster:', roster)
self.send_presence()
self.plugin['xep_0045'].joinMUC(self.room, self.nick) # MUC plugin
with open('avatar.png', 'rb') as avatar_file:
avatar = avatar_file.read()
avatar_id = self['xep_0084'].generate_id(avatar)
info = {
'id': avatar_id,
'type': 'image/png',
'bytes': len(avatar)
}
self['xep_0084'].publish_avatar(avatar)
self['xep_0084'].publish_avatar_metadata(items=[info])
# XEP-0153: vCard-Based Avatars
# Not working ATM
self['xep_0153'].set_avatar(avatar=avatar, mtype='image/png')
def archive_msg(self, msg):
print('\nMessage:{}'.format(msg))
print('\nMessage TYPE:{}'.format(msg['type']))
print('\nMessage OOB:{}'.format(msg['oob']))
print('\nMessage OOB URL:{}'.format(msg['oob']['url']))
print('\nMessage MUCK NICK:{}'.format(msg['mucnick']))
# Always check that a message is not the bot itself, otherwise you will create an infinite loop responding to your own messages.
if msg['mucnick'] != self.nick:
if msg['type'] in ('groupchat', 'normal'):
# only works if messages are not encrypted
if len(msg['oob']['url']) > 0:
# logging.getLogger().debug("received OOB from %s with %s" % (self.nick, msg['oob']['url']))
filename = os.path.basename(msg['oob']['url'])
targetDir = self.datadir
if not os.path.exists(targetDir):
os.mkdir(targetDir, '0755')
targetFile = os.path.join(targetDir, filename)
print('\n targetFile', targetFile)
#needed to disable certificate validation:
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
# save image to file
# urllib.request.urlretrieve(msg['oob']['url'], targetFile, context=ctx)
# with urllib.request.urlopen(msg['oob']['url'], context=ctx) as u, \
# open(targetFile, 'w+') as f:
# f.write(u.read())
# f.close()
# Download the file from `url` and save it locally under `file_name`:
with urllib.request.urlopen(msg['oob']['url']) as response:
data = response.read() # a `bytes` object
f = open(targetFile, 'wb')
f.write(data)
logging.getLogger().debug("saved to %s" % targetFile)
# subprocess.call(["make","publish"], cwd="/srv/gitea/clones/varia.website/")
msg.reply("Thanks for sending! I will store that for you." % msg).send() # works! also for omemo messages, but it cannot decrypt them.
if __name__ == '__main__':
# Ideally use optparse or argparse to get JID,
# password, and log level.
logging.basicConfig(level=logging.DEBUG, format='%(levelname)-8s %(message)s')
client = ArchivistBot(args.jid, args.password, args.muc, args.nick, args.output)
if client.connect():
client.process(block=True)
else:
logging.getLogger().error("Can't connect.")