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.")