Software /
code /
prosody-modules
File
mod_storage_ldap/ldap/vcard.lib.lua @ 3656:3e0f4d727825
mod_vcard_muc: Add an alternative method of signaling avatar change
When the avatar has been changed, a signal is sent that the room
configuration has changed. Clients then do a disco#info query to find
the SHA-1 of the new avatar. They can then fetch it as before, or not if
they have it cached already.
This is meant to be less disruptive than signaling via presence, which
caused problems for some clients.
If clients transition to the new method, the old one can eventually be removed.
The namespace is made up while waiting for standardization.
Otherwise it is very close to what's described in
https://xmpp.org/extensions/inbox/muc-avatars.html
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sun, 25 Aug 2019 20:46:43 +0200 |
parent | 830:f160166612c2 |
line wrap: on
line source
-- vim:sts=4 sw=4 -- Prosody IM -- Copyright (C) 2008-2010 Matthew Wild -- Copyright (C) 2008-2010 Waqas Hussain -- Copyright (C) 2012 Rob Hoelz -- -- This project is MIT/X11 licensed. Please see the -- COPYING file in the source package for more information. -- local st = require 'util.stanza'; local VCARD_NS = 'vcard-temp'; local builder_methods = {}; local base64_encode = require('util.encodings').base64.encode; function builder_methods:addvalue(key, value) self.vcard:tag(key):text(value):up(); end function builder_methods:addphotofield(tagname, format_section) local record = self.record; local format = self.format; local vcard = self.vcard; local config = format[format_section]; if not config then return; end if config.extval then if record[config.extval] then local tag = vcard:tag(tagname); tag:tag('EXTVAL'):text(record[config.extval]):up(); end elseif config.type and config.binval then if record[config.binval] then local tag = vcard:tag(tagname); tag:tag('TYPE'):text(config.type):up(); tag:tag('BINVAL'):text(base64_encode(record[config.binval])):up(); end else module:log('error', 'You have an invalid %s config section', tagname); return; end vcard:up(); end function builder_methods:addregularfield(tagname, format_section) local record = self.record; local format = self.format; local vcard = self.vcard; if not format[format_section] then return; end local tag = vcard:tag(tagname); for k, v in pairs(format[format_section]) do tag:tag(string.upper(k)):text(record[v]):up(); end vcard:up(); end function builder_methods:addmultisectionedfield(tagname, format_section) local record = self.record; local format = self.format; local vcard = self.vcard; if not format[format_section] then return; end for k, v in pairs(format[format_section]) do local tag = vcard:tag(tagname); if type(k) == 'string' then tag:tag(string.upper(k)):up(); end for k2, v2 in pairs(v) do if type(v2) == 'boolean' then tag:tag(string.upper(k2)):up(); else tag:tag(string.upper(k2)):text(record[v2]):up(); end end vcard:up(); end end function builder_methods:build() local record = self.record; local format = self.format; self:addvalue( 'VERSION', '2.0'); self:addvalue( 'FN', record[format.displayname]); self:addregularfield( 'N', 'name'); self:addvalue( 'NICKNAME', record[format.nickname]); self:addphotofield( 'PHOTO', 'photo'); self:addvalue( 'BDAY', record[format.birthday]); self:addmultisectionedfield('ADR', 'address'); self:addvalue( 'LABEL', nil); -- we don't support LABEL...yet. self:addmultisectionedfield('TEL', 'telephone'); self:addmultisectionedfield('EMAIL', 'email'); self:addvalue( 'JABBERID', record.jid); self:addvalue( 'MAILER', record[format.mailer]); self:addvalue( 'TZ', record[format.timezone]); self:addregularfield( 'GEO', 'geo'); self:addvalue( 'TITLE', record[format.title]); self:addvalue( 'ROLE', record[format.role]); self:addphotofield( 'LOGO', 'logo'); self:addvalue( 'AGENT', nil); -- we don't support AGENT...yet. self:addregularfield( 'ORG', 'org'); self:addvalue( 'CATEGORIES', nil); -- we don't support CATEGORIES...yet. self:addvalue( 'NOTE', record[format.note]); self:addvalue( 'PRODID', nil); -- we don't support PRODID...yet. self:addvalue( 'REV', record[format.rev]); self:addvalue( 'SORT-STRING', record[format.sortstring]); self:addregularfield( 'SOUND', 'sound'); self:addvalue( 'UID', record[format.uid]); self:addvalue( 'URL', record[format.url]); self:addvalue( 'CLASS', nil); -- we don't support CLASS...yet. self:addregularfield( 'KEY', 'key'); self:addvalue( 'DESC', record[format.description]); return self.vcard; end local function new_builder(params) local vcard_tag = st.stanza('vCard', { xmlns = VCARD_NS }); local object = { vcard = vcard_tag, __index = builder_methods, }; for k, v in pairs(params) do object[k] = v; end setmetatable(object, object); return object; end local _M = {}; function _M.create(params) local builder = new_builder(params); return builder:build(); end return _M;