Clean a new bunch of stuf
[slixmpp.git] / examples / disco_browser.py
blob9df22bbc66d8d966fe1679637149e615e7fb7460
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
4 """
5 Slixmpp: The Slick XMPP Library
6 Copyright (C) 2010 Nathanael C. Fritz
7 This file is part of Slixmpp.
9 See the file LICENSE for copying permission.
10 """
12 import sys
13 import logging
14 import getpass
15 from optparse import OptionParser
17 import slixmpp
18 from slixmpp.exceptions import IqError, IqTimeout
21 # Python versions before 3.0 do not use UTF-8 encoding
22 # by default. To ensure that Unicode is handled properly
23 # throughout Slixmpp, we will set the default encoding
24 # ourselves to UTF-8.
25 if sys.version_info < (3, 0):
26 from slixmpp.util.misc_ops import setdefaultencoding
27 setdefaultencoding('utf8')
28 else:
29 raw_input = input
32 class Disco(slixmpp.ClientXMPP):
34 """
35 A demonstration for using basic service discovery.
37 Send a disco#info and disco#items request to a JID/node combination,
38 and print out the results.
40 May also request only particular info categories such as just features,
41 or just items.
42 """
44 def __init__(self, jid, password, target_jid, target_node='', get=''):
45 slixmpp.ClientXMPP.__init__(self, jid, password)
47 # Using service discovery requires the XEP-0030 plugin.
48 self.register_plugin('xep_0030')
50 self.get = get
51 self.target_jid = target_jid
52 self.target_node = target_node
54 # Values to control which disco entities are reported
55 self.info_types = ['', 'all', 'info', 'identities', 'features']
56 self.identity_types = ['', 'all', 'info', 'identities']
57 self.feature_types = ['', 'all', 'info', 'features']
58 self.items_types = ['', 'all', 'items']
61 # The session_start event will be triggered when
62 # the bot establishes its connection with the server
63 # and the XML streams are ready for use. We want to
64 # listen for this event so that we we can initialize
65 # our roster.
66 self.add_event_handler("session_start", self.start, threaded=True)
68 def start(self, event):
69 """
70 Process the session_start event.
72 Typical actions for the session_start event are
73 requesting the roster and broadcasting an initial
74 presence stanza.
76 In this case, we send disco#info and disco#items
77 stanzas to the requested JID and print the results.
79 Arguments:
80 event -- An empty dictionary. The session_start
81 event does not provide any additional
82 data.
83 """
84 self.get_roster()
85 self.send_presence()
87 try:
88 if self.get in self.info_types:
89 # By using block=True, the result stanza will be
90 # returned. Execution will block until the reply is
91 # received. Non-blocking options would be to listen
92 # for the disco_info event, or passing a handler
93 # function using the callback parameter.
94 info = self['xep_0030'].get_info(jid=self.target_jid,
95 node=self.target_node,
96 block=True)
97 elif self.get in self.items_types:
98 # The same applies from above. Listen for the
99 # disco_items event or pass a callback function
100 # if you need to process a non-blocking request.
101 items = self['xep_0030'].get_items(jid=self.target_jid,
102 node=self.target_node,
103 block=True)
104 else:
105 logging.error("Invalid disco request type.")
106 return
107 except IqError as e:
108 logging.error("Entity returned an error: %s" % e.iq['error']['condition'])
109 except IqTimeout:
110 logging.error("No response received.")
111 else:
112 header = 'XMPP Service Discovery: %s' % self.target_jid
113 print(header)
114 print('-' * len(header))
115 if self.target_node != '':
116 print('Node: %s' % self.target_node)
117 print('-' * len(header))
119 if self.get in self.identity_types:
120 print('Identities:')
121 for identity in info['disco_info']['identities']:
122 print(' - %s' % str(identity))
124 if self.get in self.feature_types:
125 print('Features:')
126 for feature in info['disco_info']['features']:
127 print(' - %s' % feature)
129 if self.get in self.items_types:
130 print('Items:')
131 for item in items['disco_items']['items']:
132 print(' - %s' % str(item))
133 finally:
134 self.disconnect()
137 if __name__ == '__main__':
138 # Setup the command line arguments.
139 optp = OptionParser()
140 optp.version = '%%prog 0.1'
141 optp.usage = "Usage: %%prog [options] %s <jid> [<node>]" % \
142 'all|info|items|identities|features'
144 optp.add_option('-q','--quiet', help='set logging to ERROR',
145 action='store_const',
146 dest='loglevel',
147 const=logging.ERROR,
148 default=logging.ERROR)
149 optp.add_option('-d','--debug', help='set logging to DEBUG',
150 action='store_const',
151 dest='loglevel',
152 const=logging.DEBUG,
153 default=logging.ERROR)
154 optp.add_option('-v','--verbose', help='set logging to COMM',
155 action='store_const',
156 dest='loglevel',
157 const=5,
158 default=logging.ERROR)
160 # JID and password options.
161 optp.add_option("-j", "--jid", dest="jid",
162 help="JID to use")
163 optp.add_option("-p", "--password", dest="password",
164 help="password to use")
165 opts,args = optp.parse_args()
167 # Setup logging.
168 logging.basicConfig(level=opts.loglevel,
169 format='%(levelname)-8s %(message)s')
171 if len(args) < 2:
172 optp.print_help()
173 exit()
175 if len(args) == 2:
176 args = (args[0], args[1], '')
178 if opts.jid is None:
179 opts.jid = raw_input("Username: ")
180 if opts.password is None:
181 opts.password = getpass.getpass("Password: ")
183 # Setup the Disco browser.
184 xmpp = Disco(opts.jid, opts.password, args[1], args[2], args[0])
186 # If you are working with an OpenFire server, you may need
187 # to adjust the SSL version used:
188 # xmpp.ssl_version = ssl.PROTOCOL_SSLv3
190 # If you want to verify the SSL certificates offered by a server:
191 # xmpp.ca_certs = "path/to/ca/cert"
193 # Connect to the XMPP server and start processing XMPP stanzas.
194 if xmpp.connect():
195 # If you do not have the dnspython library installed, you will need
196 # to manually specify the name of the server if it does not match
197 # the one in the JID. For example, to use Google Talk you would
198 # need to use:
200 # if xmpp.connect(('talk.google.com', 5222)):
201 # ...
202 xmpp.process(block=True)
203 else:
204 print("Unable to connect.")