comparison sat/plugins/plugin_xep_0054.py @ 3258:7aa01e262e05

plugin XEP-0054: SVG images can now be uploaded for avatars.
author Goffi <goffi@goffi.org>
date Sun, 19 Apr 2020 16:40:34 +0200
parents 6cf4bd6972c2
children cf07641b764d
comparison
equal deleted inserted replaced
3257:704dada41df0 3258:7aa01e262e05
329 return self._i.avatarBuildMetadata( 329 return self._i.avatarBuildMetadata(
330 avatar_cache['path'], avatar_cache['mime_type'], avatar_hash) 330 avatar_cache['path'], avatar_cache['mime_type'], avatar_hash)
331 331
332 def _buildSetAvatar(self, client, vcard_elt, avatar_data): 332 def _buildSetAvatar(self, client, vcard_elt, avatar_data):
333 # XXX: this method is executed in a separate thread 333 # XXX: this method is executed in a separate thread
334 try: 334 if avatar_data["media_type"] == "image/svg+xml":
335 img = Image.open(avatar_data['path']) 335 # for vector image, we save directly
336 except IOError as e: 336 img_buf = open(avatar_data["path"], "rb")
337 raise exceptions.DataError(f"Can't open image: {e}") 337 else:
338 338 # for bitmap image, we check size and resize if necessary
339 if img.size != AVATAR_DIM: 339 try:
340 img.thumbnail(AVATAR_DIM) 340 img = Image.open(avatar_data["path"])
341 if img.size[0] != img.size[1]: # we need to crop first 341 except IOError as e:
342 left, upper = (0, 0) 342 raise exceptions.DataError(f"Can't open image: {e}")
343 right, lower = img.size 343
344 offset = abs(right - lower) / 2 344 if img.size != AVATAR_DIM:
345 if right == min(img.size): 345 img.thumbnail(AVATAR_DIM)
346 upper += offset 346 if img.size[0] != img.size[1]: # we need to crop first
347 lower -= offset 347 left, upper = (0, 0)
348 else: 348 right, lower = img.size
349 left += offset 349 offset = abs(right - lower) / 2
350 right -= offset 350 if right == min(img.size):
351 img = img.crop((left, upper, right, lower)) 351 upper += offset
352 img_buf = io.BytesIO() 352 lower -= offset
353 img.save(img_buf, "PNG") 353 else:
354 354 left += offset
355 right -= offset
356 img = img.crop((left, upper, right, lower))
357 img_buf = io.BytesIO()
358 # PNG is well supported among clients, so we convert to this format
359 img.save(img_buf, "PNG")
360 img_buf.seek(0)
361 avatar_data["media_type"] = "image/png"
362
363 media_type = avatar_data["media_type"]
355 photo_elt = vcard_elt.addElement("PHOTO") 364 photo_elt = vcard_elt.addElement("PHOTO")
356 photo_elt.addElement("TYPE", content="image/png") 365 photo_elt.addElement("TYPE", content=media_type)
357 image_b64 = b64encode(img_buf.getvalue()).decode() 366 image_b64 = b64encode(img_buf.read()).decode()
367 img_buf.seek(0)
358 photo_elt.addElement("BINVAL", content=image_b64) 368 photo_elt.addElement("BINVAL", content=image_b64)
359 image_hash = sha1(img_buf.getvalue()).hexdigest() 369 image_hash = sha1(img_buf.read()).hexdigest()
370 img_buf.seek(0)
360 with self.host.common_cache.cacheData( 371 with self.host.common_cache.cacheData(
361 PLUGIN_INFO["import_name"], image_hash, "image/png" 372 PLUGIN_INFO["import_name"], image_hash, media_type
362 ) as f: 373 ) as f:
363 f.write(img_buf.getvalue()) 374 f.write(img_buf.read())
364 avatar_data['path'] = Path(f.name) 375 avatar_data['path'] = Path(f.name)
365 avatar_data['cache_uid'] = image_hash 376 avatar_data['cache_uid'] = image_hash
366 return image_hash 377 return image_hash
367 378
368 async def setAvatar(self, client, avatar_data, entity): 379 async def setAvatar(self, client, avatar_data, entity):