#!/usr/bin/env python3 # Slixmpp: The Slick XMPP Library # Copyright (C) 2011 Nathanael C. Fritz # This file is part of Slixmpp. # See the file LICENSE for copying permission. import logging from getpass import getpass from argparse import ArgumentParser import slixmpp from slixmpp.exceptions import IqError, IqTimeout from slixmpp.xmlstream.asyncio import asyncio class RosterBrowser(slixmpp.ClientXMPP): """ A basic script for dumping a client's roster to the command line. """ def __init__(self, jid, password): slixmpp.ClientXMPP.__init__(self, jid, password) # The session_start event will be triggered when # the bot establishes its connection with the server # and the XML streams are ready for use. We want to # listen for this event so that we we can initialize # our roster. self.add_event_handler("session_start", self.start) self.add_event_handler("changed_status", self.wait_for_presences) self.received = set() self.presences_received = asyncio.Event() async def start(self, event): """ Process the session_start event. Typical actions for the session_start event are requesting the roster and broadcasting an initial presence stanza. Arguments: event -- An empty dictionary. The session_start event does not provide any additional data. """ try: await self.get_roster() except IqError as err: print('Error: %s' % err.iq['error']['condition']) except IqTimeout: print('Error: Request timed out') self.send_presence() print('Waiting for presence updates...\n') await asyncio.sleep(10) print('Roster for %s' % self.boundjid.bare) groups = self.client_roster.groups() for group in groups: print('\n%s' % group) print('-' * 72) for jid in groups[group]: sub = self.client_roster[jid]['subscription'] name = self.client_roster[jid]['name'] if self.client_roster[jid]['name']: print(' %s (%s) [%s]' % (name, jid, sub)) else: print(' %s [%s]' % (jid, sub)) connections = self.client_roster.presence(jid) for res, pres in connections.items(): show = 'available' if pres['show']: show = pres['show'] print(' - %s (%s)' % (res, show)) if pres['status']: print(' %s' % pres['status']) self.disconnect() def wait_for_presences(self, pres): """ Track how many roster entries have received presence updates. """ self.received.add(pres['from'].bare) if len(self.received) >= len(self.client_roster.keys()): self.presences_received.set() else: self.presences_received.clear() if __name__ == '__main__': # Setup the command line arguments. parser = ArgumentParser() 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") 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: ") xmpp = RosterBrowser(args.jid, args.password) # Connect to the XMPP server and start processing XMPP stanzas. xmpp.connect() xmpp.process(forever=False)