Software /
code /
verse
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 |