File

plugins/vcard_update.lua @ 263:598e9f93de78

plugins.pubsub: Fix missing <item/> when publishing.
author Kim Alvefur <zash@zash.se>
date Sat, 10 Dec 2011 15:21:09 +0100
parent 250:a5ac643a7fd6
child 380:0891b4e27766
line wrap: on
line source

local verse = require "verse";

local xmlns_vcard, xmlns_vcard_update = "vcard-temp", "vcard-temp:x:update";

-- MMMmmmm.. hacky
local ok, fun = pcall(function() return require("util.hashes").sha1; end);
if not ok then
	ok, fun = pcall(function() return require("util.sha1").sha1; end);
	if not ok then
		error("Could not find a sha1()")
	end
end
local sha1 = fun;

local ok, fun = pcall(function()
	local unb64 = require("util.encodings").base64.decode;
	assert(unb64("SGVsbG8=") == "Hello")
	return unb64;
end);
if not ok then
	ok, fun = pcall(function() return require("mime").unb64; end);
	if not ok then
		error("Could not find a base64 decoder")
	end
end
local unb64 = fun;

function verse.plugins.vcard_update(stream)
	stream:add_plugin("vcard");
	stream:add_plugin("presence");


	local x_vcard_update;

	function update_vcard_photo(vCard) 
		local data;
		for i=1,#vCard do
			if vCard[i].name == "PHOTO" then
				data = vCard[i][1];
				break
			end
		end
		if data then
			local hash = sha1(unb64(data), true);
			x_vcard_update = verse.stanza("x", { xmlns = xmlns_vcard_update })
			:tag("photo"):text(hash);

			stream:resend_presence()
		else
			x_vcard_update = nil;
		end
	end

	local _set_vcard = stream.set_vcard;

	--[[ TODO Complete this, it's probably broken.
	-- Maybe better to hook outgoing stanza?
	function stream:set_vcard(vCard, callback)
		_set_vcard(vCard, function(event, ...)
			if event.attr.type == "result" then
				local vCard_ = response:get_child("vCard", xmlns_vcard);
				if vCard_ then
					update_vcard_photo(vCard_);
				end -- Or fetch it again? Seems wasteful, but if the server overrides stuff? :/
			end
			if callback then
				return callback(event, ...);
			end
		end);
	end
	--]]

	local initial_vcard_fetch_started;
	stream:hook("ready", function(event)
		if initial_vcard_fetch_started then return; end
		initial_vcard_fetch_started = true;
		-- if stream:jid_supports(nil, xmlns_vcard) then TODO this, correctly
		stream:get_vcard(nil, function(response)
			if response then
				update_vcard_photo(response)
			end
			stream:event("ready");
		end);
		return true;
	end, 3);

	stream:hook("presence-out", function(presence)
		if x_vcard_update and not presence:get_child("x", xmlns_vcard_update) then
			presence:add_child(x_vcard_update);
		end
	end, 10);

	--[[
	stream:hook("presence", function(presence)
			local x_vcard_update = presence:get_child("x", xmlns_vcard_update);
			local photo_hash = x_vcard_update and x_vcard_update:get_child("photo");
				:get_child_text("photo");
			if x_vcard_update then
				-- TODO Cache peoples avatars here
			end
	end);
	--]]
end