2 # -*- coding: utf-8 -*-
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.
16 from optparse
import OptionParser
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
26 if sys
.version_info
< (3, 0):
27 from slixmpp
.util
.misc_ops
import setdefaultencoding
28 setdefaultencoding('utf8')
40 class AvatarDownloader(slixmpp
.ClientXMPP
):
43 A basic script for downloading the avatars for a user's contacts.
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
)
55 self
.presences_received
= threading
.Event()
57 def start(self
, event
):
59 Process the session_start event.
61 Typical actions for the session_start event are
62 requesting the roster and broadcasting an initial
66 event -- An empty dictionary. The session_start
67 event does not provide any additional
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
)
80 result
= self
['xep_0054'].get_vcard(pres
['from'], cached
=True)
82 print("Error retrieving avatar for %s" % pres
['from'])
84 avatar
= result
['vcard_temp']['PHOTO']
86 filetype
= FILE_TYPES
.get(avatar
['TYPE'], 'png')
87 filename
= 'vcard_avatar_%s_%s.%s' % (
89 pres
['vcard_temp_update']['photo'],
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']:
100 result
= self
['xep_0084'].retrieve_avatar(msg
['from'], info
['id'])
102 print("Error retrieving avatar for %s" % msg
['from'])
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'])
112 # We could retrieve the avatar via HTTP, etc here instead.
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()
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',
133 default
=logging
.ERROR
)
134 optp
.add_option('-d','--debug', help='set logging to DEBUG',
135 action
='store_const',
138 default
=logging
.ERROR
)
139 optp
.add_option('-v','--verbose', help='set logging to COMM',
140 action
='store_const',
143 default
=logging
.ERROR
)
145 # JID and password options.
146 optp
.add_option("-j", "--jid", dest
="jid",
148 optp
.add_option("-p", "--password", dest
="password",
149 help="password to use")
150 opts
,args
= optp
.parse_args()
153 logging
.basicConfig(level
=opts
.loglevel
,
154 format
='%(levelname)-8s %(message)s')
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.
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
180 # if xmpp.connect(('talk.google.com', 5222)):
182 xmpp
.process(block
=True)
184 print("Unable to connect.")