plugin identity, XEP-0054: move avatar resizing and caching method to identity plugin:

resizing and caching is now done in identity plugin, to prepare for the implementation of
other XEP to handle avatars.

rel 368
This commit is contained in:
Goffi 2022-06-29 11:47:48 +02:00
commit 35be6b741f

View file

@ -53,6 +53,7 @@ PLUGIN_INFO = {
C.PI_NAME: "XEP 0054 Plugin",
C.PI_IMPORT_NAME: IMPORT_NAME,
C.PI_TYPE: "XEP",
C.PI_MODES: C.PLUG_MODE_BOTH,
C.PI_PROTOCOLS: ["XEP-0054", "XEP-0153"],
C.PI_DEPENDENCIES: ["IDENTITY"],
C.PI_RECOMMENDATIONS: [],
@ -61,9 +62,6 @@ PLUGIN_INFO = {
C.PI_DESCRIPTION: _("""Implementation of vcard-temp"""),
}
AVATAR_PATH = "avatars"
AVATAR_DIM = (128, 128)
IQ_GET = '/iq[@type="get"]'
NS_VCARD = "vcard-temp"
VCARD_REQUEST = IQ_GET + '/vCard[@xmlns="' + NS_VCARD + '"]' # TODO: manage requests
@ -318,54 +316,6 @@ class XEP_0054(object):
return self._i.avatarBuildMetadata(
avatar_cache['path'], avatar_cache['mime_type'], avatar_hash)
def _buildSetAvatar(self, client, vcard_elt, avatar_data):
# XXX: this method is executed in a separate thread
if avatar_data["media_type"] == "image/svg+xml":
# for vector image, we save directly
img_buf = open(avatar_data["path"], "rb")
else:
# for bitmap image, we check size and resize if necessary
try:
img = Image.open(avatar_data["path"])
except IOError as e:
raise exceptions.DataError(f"Can't open image: {e}")
if img.size != AVATAR_DIM:
img.thumbnail(AVATAR_DIM)
if img.size[0] != img.size[1]: # we need to crop first
left, upper = (0, 0)
right, lower = img.size
offset = abs(right - lower) / 2
if right == min(img.size):
upper += offset
lower -= offset
else:
left += offset
right -= offset
img = img.crop((left, upper, right, lower))
img_buf = io.BytesIO()
# PNG is well supported among clients, so we convert to this format
img.save(img_buf, "PNG")
img_buf.seek(0)
avatar_data["media_type"] = "image/png"
media_type = avatar_data["media_type"]
photo_elt = vcard_elt.addElement("PHOTO")
photo_elt.addElement("TYPE", content=media_type)
image_b64 = b64encode(img_buf.read()).decode()
img_buf.seek(0)
photo_elt.addElement("BINVAL", content=image_b64)
image_hash = sha1(img_buf.read()).hexdigest()
img_buf.seek(0)
with self.host.common_cache.cacheData(
PLUGIN_INFO["import_name"], image_hash, media_type
) as f:
f.write(img_buf.read())
avatar_data['path'] = Path(f.name)
avatar_data['filename'] = avatar_data['path'].name
avatar_data['cache_uid'] = image_hash
return image_hash
async def setAvatar(self, client, avatar_data, entity):
"""Set avatar of the profile
@ -377,10 +327,10 @@ class XEP_0054(object):
iq_elt = client.IQ()
iq_elt.addChild(vcard_elt)
await threads.deferToThread(
self._buildSetAvatar, client, vcard_elt, avatar_data
)
# image is now at the right size/format
# metadata with encoded image are now filled at the right size/format
photo_elt = vcard_elt.addElement("PHOTO")
photo_elt.addElement("TYPE", content=avatar_data["media_type"])
photo_elt.addElement("BINVAL", content=avatar_data["base64"])
await iq_elt.send()