Comparison

plugins/vcard_update.lua @ 196:eb9d69d3f0b5

plugins.vcard_update: Support for XEP-153 avatar hash in presence broadcasts
author Kim Alvefur <zash@zash.se>
date Thu, 17 Mar 2011 01:30:44 +0100
child 229:279c0e89c3b3
comparison
equal deleted inserted replaced
195:dc61684e8dbf 196:eb9d69d3f0b5
1 local xmlns_vcard, xmlns_vcard_update = "vcard-temp", "vcard-temp:x:update";
2
3 -- MMMmmmm.. hacky
4 local ok, fun = pcall(function() return require("util.hashes").sha1; end);
5 if not ok then
6 ok, fun = pcall(function() return require("util.sha1").sha1; end);
7 if not ok then
8 error("Could not find a sha1()")
9 end
10 end
11 local sha1 = fun;
12
13 local ok, fun = pcall(function()
14 local unb64 = require("util.encodings").base64.decode;
15 assert(unb64("SGVsbG8=") == "Hello")
16 return unb64;
17 end);
18 if not ok then
19 ok, fun = pcall(function() return require("mime").unb64; end);
20 if not ok then
21 error("Could not find a base64 decoder")
22 end
23 end
24 local unb64 = fun;
25
26 function verse.plugins.vcard_update(stream)
27 stream:add_plugin("vcard");
28 stream:add_plugin("presence");
29
30
31 local x_vcard_update;
32
33 function update_vcard_photo(vCard)
34 local photo = vCard and vCard:get_child("PHOTO");
35 local binval = photo and photo:get_child("BINVAL");
36 local data = binval and binval:get_text();
37 if data then
38 local hash = sha1(unb64(data), true);
39 x_vcard_update = verse.stanza("x", { xmlns = xmlns_vcard_update })
40 :tag("photo"):text(hash);
41
42 stream:resend_presence()
43 else
44 x_vcard_update = nil;
45 end
46 end
47
48 local _set_vcard = stream.set_vcard;
49
50 --[[ TODO Complete this, it's probably broken.
51 -- Maybe better to hook outgoing stanza?
52 function stream:set_vcard(vCard, callback)
53 _set_vcard(vCard, function(event, ...)
54 if event.attr.type == "result" then
55 local vCard_ = response:get_child("vCard", xmlns_vcard);
56 if vCard_ then
57 update_vcard_photo(vCard_);
58 end -- Or fetch it again? Seems wasteful, but if the server overrides stuff? :/
59 end
60 if callback then
61 return callback(event, ...);
62 end
63 end);
64 end
65 --]]
66
67 local initial_vcard_fetch_started;
68 stream:hook("ready", function(event)
69 if initial_vcard_fetch_started then return; end
70 initial_vcard_fetch_started = true;
71 -- if stream:jid_supports(nil, xmlns_vcard) then TODO this, correctly
72 stream:get_vcard(nil, function(response)
73 -- FIXME Picking out the vCard element should be done in get_vcard()
74 if response.attr.type == "result" then
75 local vCard = response:get_child("vCard", xmlns_vcard);
76 if vCard then
77 update_vcard_photo(vCard);
78 end
79 end
80 stream:event("ready");
81 end);
82 return true;
83 end, 3);
84
85 stream:hook("presence-out", function(presence)
86 if x_vcard_update and not presence:get_child("x", xmlns_vcard_update) then
87 presence:add_child(x_vcard_update);
88 end
89 end, 10);
90
91 --[[
92 stream:hook("presence", function(presence)
93 local x_vcard_update = presence:get_child("x", xmlns_vcard_update);
94 local photo_hash = x_vcard_update and x_vcard_update:get_child("photo");
95 :get_child("photo"):get_text(hash);
96 if x_vcard_update then
97 -- TODO Cache peoples avatars here
98 end
99 end);
100 --]]
101 end