comparison src/plugins/plugin_xep_0054.py @ 2069:528e5fafc11b

plugin XEP-0054(XEP-0153): ignore image formats other than gif, jpeg and png, and empty BINVAL
author Goffi <goffi@goffi.org>
date Sat, 10 Sep 2016 18:03:24 +0200
parents ee9621d92cb9
children 11fb5f5e2f89
comparison
equal deleted inserted replaced
2068:741db5abf077 2069:528e5fafc11b
202 file_.write(data) 202 file_.write(data)
203 log.debug(_(u"file saved to %s") % hash_) 203 log.debug(_(u"file saved to %s") % hash_)
204 else: 204 else:
205 log.debug(_(u"file [%s] already in cache") % hash_) 205 log.debug(_(u"file [%s] already in cache") % hash_)
206 206
207 def savePhoto(self, photo_xml): 207 def savePhoto(self, photo_elt, target):
208 """Parse a <PHOTO> elem and save the picture""" 208 """Parse a <PHOTO> photo_elt and save the picture"""
209 for elem in photo_xml.elements(): 209 try:
210 if elem.name == 'TYPE': 210 type_ = unicode(photo_elt.elements(NS_VCARD, 'TYPE').next())
211 log.debug(_(u'Photo of type [%s] found') % str(elem)) 211 except StopIteration:
212 if elem.name == 'BINVAL': 212 type_ = None
213 log.debug(_('Decoding binary')) 213 else:
214 decoded = b64decode(str(elem)) 214 if type_ and type_ not in ("image/gif", "image/jpeg", "image/png"):
215 image_hash = sha1(decoded).hexdigest() 215 # TODO: handle other image formats (svg?)
216 self.saveAvatarFile(decoded, image_hash) 216 log.warning(u"following avatar image format is not handled: {type} [{jid}]".format(
217 return image_hash 217 type=type_, jid=target.full()))
218 return
219 log.debug(u'Photo of type {type} found [{jid}]'.format(
220 type=type_, jid=target.full()))
221 try:
222 bin_elt = photo_elt.elements(NS_VCARD, 'BINVAL').next()
223 except StopIteration:
224 return
225 buf = str(bin_elt)
226 if not buf:
227 log.warning(u"empty avatar for {jid}".format(jid=target.full()))
228 return
229 log.debug(_(u'Decoding binary'))
230 decoded = b64decode(buf)
231 image_hash = sha1(decoded).hexdigest()
232 self.saveAvatarFile(decoded, image_hash)
233 return image_hash
218 234
219 @defer.inlineCallbacks 235 @defer.inlineCallbacks
220 def vCard2Dict(self, client, vcard, target): 236 def vCard2Dict(self, client, vcard, target):
221 """Convert a VCard to a dict, and save binaries""" 237 """Convert a VCard to a dict, and save binaries"""
222 log.debug(_("parsing vcard")) 238 log.debug(_("parsing vcard"))
233 elif elem.name == 'EMAIL': 249 elif elem.name == 'EMAIL':
234 dictionary['email'] = unicode(elem) 250 dictionary['email'] = unicode(elem)
235 elif elem.name == 'BDAY': 251 elif elem.name == 'BDAY':
236 dictionary['birthday'] = unicode(elem) 252 dictionary['birthday'] = unicode(elem)
237 elif elem.name == 'PHOTO': 253 elif elem.name == 'PHOTO':
238 dictionary["avatar"] = yield threads.deferToThread(self.savePhoto, elem) 254 # TODO: handle EXTVAL
239 if not dictionary["avatar"]: # can happen in case of e.g. empty photo elem 255 avatar_hash = yield threads.deferToThread(self.savePhoto, elem, target)
240 del dictionary['avatar'] 256 if avatar_hash is None: # can happen e.g. in case of empty photo elem
241 else: 257 continue
242 self.updateCache(client, target, 'avatar', dictionary['avatar']) 258 dictionary['avatar'] = avatar_hash
259 self.updateCache(client, target, 'avatar', dictionary['avatar'])
243 else: 260 else:
244 log.info(_('FIXME: [%s] VCard tag is not managed yet') % elem.name) 261 log.debug(_('FIXME: [%s] VCard tag is not managed yet') % elem.name)
245 262
246 # if a data in cache doesn't exist anymore, we need to reset it 263 # if a data in cache doesn't exist anymore, we need to reset it
247 # so we check CACHED_DATA no gotten (i.e. not in dictionary keys) 264 # so we check CACHED_DATA no gotten (i.e. not in dictionary keys)
248 # and we reset them 265 # and we reset them
249 for datum in CACHED_DATA.difference(dictionary.keys()): 266 for datum in CACHED_DATA.difference(dictionary.keys()):