Remove google modules from setup.py file
[slixmpp.git] / examples / download_avatars.py
blobbd505432f3ff7c64323fe0209b1fd0f549fb68b0
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
4 """
5 Slixmpp: The Slick XMPP Library
6 Copyright (C) 2012 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 import threading
16 from optparse import OptionParser
18 import slixmpp
19 from slixmpp.exceptions import XMPPError
22 # Python versions before 3.0 do not use UTF-8 encoding
23 # by default. To ensure that Unicode is handled properly
24 # throughout Slixmpp, we will set the default encoding
25 # ourselves to UTF-8.
26 if sys.version_info < (3, 0):
27 from slixmpp.util.misc_ops import setdefaultencoding
28 setdefaultencoding('utf8')
29 else:
30 raw_input = input
33 FILE_TYPES = {
34 'image/png': 'png',
35 'image/gif': 'gif',
36 'image/jpeg': 'jpg'
40 class AvatarDownloader(slixmpp.ClientXMPP):
42 """
43 A basic script for downloading the avatars for a user's contacts.
44 """
46 def __init__(self, jid, password):
47 slixmpp.ClientXMPP.__init__(self, jid, password)
48 self.add_event_handler("session_start", self.start, threaded=True)
49 self.add_event_handler("changed_status", self.wait_for_presences)
51 self.add_event_handler('vcard_avatar_update', self.on_vcard_avatar)
52 self.add_event_handler('avatar_metadata_publish', self.on_avatar)
54 self.received = set()
55 self.presences_received = threading.Event()
57 def start(self, event):
58 """
59 Process the session_start event.
61 Typical actions for the session_start event are
62 requesting the roster and broadcasting an initial
63 presence stanza.
65 Arguments:
66 event -- An empty dictionary. The session_start
67 event does not provide any additional
68 data.
69 """
70 self.send_presence()
71 self.get_roster()
73 print('Waiting for presence updates...\n')
74 self.presences_received.wait(15)
75 self.disconnect(wait=True)
77 def on_vcard_avatar(self, pres):
78 print("Received vCard avatar update from %s" % pres['from'].bare)
79 try:
80 result = self['xep_0054'].get_vcard(pres['from'], cached=True)
81 except XMPPError:
82 print("Error retrieving avatar for %s" % pres['from'])
83 return
84 avatar = result['vcard_temp']['PHOTO']
86 filetype = FILE_TYPES.get(avatar['TYPE'], 'png')
87 filename = 'vcard_avatar_%s_%s.%s' % (
88 pres['from'].bare,
89 pres['vcard_temp_update']['photo'],
90 filetype)
91 with open(filename, 'w+') as img:
92 img.write(avatar['BINVAL'])
94 def on_avatar(self, msg):
95 print("Received avatar update from %s" % msg['from'])
96 metadata = msg['pubsub_event']['items']['item']['avatar_metadata']
97 for info in metadata['items']:
98 if not info['url']:
99 try:
100 result = self['xep_0084'].retrieve_avatar(msg['from'], info['id'])
101 except XMPPError:
102 print("Error retrieving avatar for %s" % msg['from'])
103 return
105 avatar = result['pubsub']['items']['item']['avatar_data']
107 filetype = FILE_TYPES.get(metadata['type'], 'png')
108 filename = 'avatar_%s_%s.%s' % (msg['from'].bare, info['id'], filetype)
109 with open(filename, 'w+') as img:
110 img.write(avatar['value'])
111 else:
112 # We could retrieve the avatar via HTTP, etc here instead.
113 pass
115 def wait_for_presences(self, pres):
117 Wait to receive updates from all roster contacts.
119 self.received.add(pres['from'].bare)
120 if len(self.received) >= len(self.client_roster.keys()):
121 self.presences_received.set()
122 else:
123 self.presences_received.clear()
126 if __name__ == '__main__':
127 # Setup the command line arguments.
128 optp = OptionParser()
129 optp.add_option('-q','--quiet', help='set logging to ERROR',
130 action='store_const',
131 dest='loglevel',
132 const=logging.ERROR,
133 default=logging.ERROR)
134 optp.add_option('-d','--debug', help='set logging to DEBUG',
135 action='store_const',
136 dest='loglevel',
137 const=logging.DEBUG,
138 default=logging.ERROR)
139 optp.add_option('-v','--verbose', help='set logging to COMM',
140 action='store_const',
141 dest='loglevel',
142 const=5,
143 default=logging.ERROR)
145 # JID and password options.
146 optp.add_option("-j", "--jid", dest="jid",
147 help="JID to use")
148 optp.add_option("-p", "--password", dest="password",
149 help="password to use")
150 opts,args = optp.parse_args()
152 # Setup logging.
153 logging.basicConfig(level=opts.loglevel,
154 format='%(levelname)-8s %(message)s')
156 if opts.jid is None:
157 opts.jid = raw_input("Username: ")
158 if opts.password is None:
159 opts.password = getpass.getpass("Password: ")
161 xmpp = AvatarDownloader(opts.jid, opts.password)
162 xmpp.register_plugin('xep_0054')
163 xmpp.register_plugin('xep_0153')
164 xmpp.register_plugin('xep_0084')
166 # If you are working with an OpenFire server, you may need
167 # to adjust the SSL version used:
168 # xmpp.ssl_version = ssl.PROTOCOL_SSLv3
170 # If you want to verify the SSL certificates offered by a server:
171 # xmpp.ca_certs = "path/to/ca/cert"
173 # Connect to the XMPP server and start processing XMPP stanzas.
174 if xmpp.connect():
175 # If you do not have the dnspython library installed, you will need
176 # to manually specify the name of the server if it does not match
177 # the one in the JID. For example, to use Google Talk you would
178 # need to use:
180 # if xmpp.connect(('talk.google.com', 5222)):
181 # ...
182 xmpp.process(block=True)
183 else:
184 print("Unable to connect.")