#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import logging
from getpass import getpass
from argparse import ArgumentParser
import slixmpp
from slixmpp.xmlstream import ET, tostring
from slixmpp.xmlstream.asyncio import asyncio
def make_callback():
future = asyncio.Future()
def callback(result):
future.set_result(result)
return future, callback
class PubsubClient(slixmpp.ClientXMPP):
def __init__(self, jid, password, server,
node=None, action='list', data=''):
super(PubsubClient, self).__init__(jid, password)
self.register_plugin('xep_0030')
self.register_plugin('xep_0059')
self.register_plugin('xep_0060')
self.actions = ['nodes', 'create', 'delete',
'publish', 'get', 'retract',
'purge', 'subscribe', 'unsubscribe']
self.action = action
self.node = node
self.data = data
self.pubsub_server = server
self.add_event_handler('session_start', self.start)
def start(self, event):
self.get_roster()
self.send_presence()
try:
getattr(self, self.action)()
except:
logging.error('Could not execute: %s' % self.action)
self.disconnect()
def nodes(self):
future, callback = make_callback()
try:
self['xep_0060'].get_nodes(self.pubsub_server, self.node, callback=callback)
result = yield from future
for item in result['disco_items']['items']:
print(' - %s' % str(item))
except:
logging.error('Could not retrieve node list.')
def create(self):
try:
self['xep_0060'].create_node(self.pubsub_server, self.node)
except:
logging.error('Could not create node: %s' % self.node)
def delete(self):
try:
self['xep_0060'].delete_node(self.pubsub_server, self.node)
print('Deleted node: %s' % self.node)
except:
logging.error('Could not delete node: %s' % self.node)
def publish(self):
payload = ET.fromstring("%s" % self.data)
future, callback = make_callback()
try:
self['xep_0060'].publish(self.pubsub_server, self.node, payload=payload, callback=callback)
result = yield from future
id = result['pubsub']['publish']['item']['id']
print('Published at item id: %s' % id)
except:
logging.error('Could not publish to: %s' % self.node)
def get(self):
future, callback = make_callback()
try:
self['xep_0060'].get_item(self.pubsub_server, self.node, self.data, callback=callback)
result = yield from future
for item in result['pubsub']['items']['substanzas']:
print('Retrieved item %s: %s' % (item['id'], tostring(item['payload'])))
except:
logging.error('Could not retrieve item %s from node %s' % (self.data, self.node))
def retract(self):
try:
self['xep_0060'].retract(self.pubsub_server, self.node, self.data)
print('Retracted item %s from node %s' % (self.data, self.node))
except:
logging.error('Could not retract item %s from node %s' % (self.data, self.node))
def purge(self):
try:
self['xep_0060'].purge(self.pubsub_server, self.node)
print('Purged all items from node %s' % self.node)
except:
logging.error('Could not purge items from node %s' % self.node)
def subscribe(self):
try:
self['xep_0060'].subscribe(self.pubsub_server, self.node)
print('Subscribed %s to node %s' % (self.boundjid.bare, self.node))
except:
logging.error('Could not subscribe %s to node %s' % (self.boundjid.bare, self.node))
def unsubscribe(self):
try:
self['xep_0060'].unsubscribe(self.pubsub_server, self.node)
print('Unsubscribed %s from node %s' % (self.boundjid.bare, self.node))
except:
logging.error('Could not unsubscribe %s from node %s' % (self.boundjid.bare, self.node))
if __name__ == '__main__':
# Setup the command line arguments.
parser = ArgumentParser()
parser.version = '%%prog 0.1'
parser.usage = "Usage: %%prog [options] " + \
'nodes|create|delete|purge|subscribe|unsubscribe|publish|retract|get' + \
' [ ]'
parser.add_argument("-q","--quiet", help="set logging to ERROR",
action="store_const",
dest="loglevel",
const=logging.ERROR,
default=logging.ERROR)
parser.add_argument("-d","--debug", help="set logging to DEBUG",
action="store_const",
dest="loglevel",
const=logging.DEBUG,
default=logging.ERROR)
# JID and password options.
parser.add_argument("-j", "--jid", dest="jid",
help="JID to use")
parser.add_argument("-p", "--password", dest="password",
help="password to use")
parser.add_argument("server")
parser.add_argument("action", choice=["nodes", "create", "delete", "purge", "subscribe", "unsubscribe", "publish", "retract", "get"])
parser.add_argument("node", nargs='?')
parser.add_argument("data", nargs='?')
args = parser.parse_args()
# Setup logging.
logging.basicConfig(level=args.loglevel,
format='%(levelname)-8s %(message)s')
if args.jid is None:
args.jid = input("Username: ")
if args.password is None:
args.password = getpass("Password: ")
# Setup the Pubsub client
xmpp = PubsubClient(args.jid, args.password,
server=args.server,
node=args.node,
action=args.action,
data=args.data)
# Connect to the XMPP server and start processing XMPP stanzas.
xmpp.connect()
xmpp.process(forever=False)