changeset 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 741db5abf077
children 58f0c96d60e5
files src/plugins/plugin_xep_0054.py
diffstat 1 files changed, 34 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/src/plugins/plugin_xep_0054.py	Sat Sep 10 11:43:32 2016 +0200
+++ b/src/plugins/plugin_xep_0054.py	Sat Sep 10 18:03:24 2016 +0200
@@ -204,17 +204,33 @@
         else:
             log.debug(_(u"file [%s] already in cache") % hash_)
 
-    def savePhoto(self, photo_xml):
-        """Parse a <PHOTO> elem and save the picture"""
-        for elem in photo_xml.elements():
-            if elem.name == 'TYPE':
-                log.debug(_(u'Photo of type [%s] found') % str(elem))
-            if elem.name == 'BINVAL':
-                log.debug(_('Decoding binary'))
-                decoded = b64decode(str(elem))
-                image_hash = sha1(decoded).hexdigest()
-                self.saveAvatarFile(decoded, image_hash)
-                return image_hash
+    def savePhoto(self, photo_elt, target):
+        """Parse a <PHOTO> photo_elt and save the picture"""
+        try:
+            type_ = unicode(photo_elt.elements(NS_VCARD, 'TYPE').next())
+        except StopIteration:
+            type_ = None
+        else:
+            if type_ and type_ not in ("image/gif", "image/jpeg", "image/png"):
+                # TODO: handle other image formats (svg?)
+                log.warning(u"following avatar image format is not handled: {type} [{jid}]".format(
+                    type=type_, jid=target.full()))
+                return
+            log.debug(u'Photo of type {type} found [{jid}]'.format(
+                    type=type_, jid=target.full()))
+        try:
+            bin_elt = photo_elt.elements(NS_VCARD, 'BINVAL').next()
+        except StopIteration:
+            return
+        buf = str(bin_elt)
+        if not buf:
+            log.warning(u"empty avatar for {jid}".format(jid=target.full()))
+            return
+        log.debug(_(u'Decoding binary'))
+        decoded = b64decode(buf)
+        image_hash = sha1(decoded).hexdigest()
+        self.saveAvatarFile(decoded, image_hash)
+        return image_hash
 
     @defer.inlineCallbacks
     def vCard2Dict(self, client, vcard, target):
@@ -235,13 +251,14 @@
             elif elem.name == 'BDAY':
                 dictionary['birthday'] = unicode(elem)
             elif elem.name == 'PHOTO':
-                dictionary["avatar"] = yield threads.deferToThread(self.savePhoto, elem)
-                if not dictionary["avatar"]:  # can happen in case of e.g. empty photo elem
-                    del dictionary['avatar']
-                else:
-                    self.updateCache(client, target, 'avatar', dictionary['avatar'])
+                # TODO: handle EXTVAL
+                avatar_hash = yield threads.deferToThread(self.savePhoto, elem, target)
+                if avatar_hash is None: # can happen e.g. in case of empty photo elem
+                    continue
+                dictionary['avatar'] = avatar_hash
+                self.updateCache(client, target, 'avatar', dictionary['avatar'])
             else:
-                log.info(_('FIXME: [%s] VCard tag is not managed yet') % elem.name)
+                log.debug(_('FIXME: [%s] VCard tag is not managed yet') % elem.name)
 
         # if a data in cache doesn't exist anymore, we need to reset it
         # so we check CACHED_DATA no gotten (i.e. not in dictionary keys)