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 |