1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
namespace Xmpp.Xep.VCard {
private const string NS_URI = "vcard-temp";
private const string NS_URI_UPDATE = NS_URI + ":x:update";
public async Bytes? fetch_image(XmppStream stream, Jid jid, string hash) {
Iq.Stanza iq = new Iq.Stanza.get(new StanzaNode.build("vCard", NS_URI).add_self_xmlns()) { to=jid };
Iq.Stanza iq_res = yield stream.get_module(Iq.Module.IDENTITY).send_iq_async(stream, iq);
if (iq_res.is_error()) return null;
string? res = iq_res.stanza.get_deep_string_content(@"$NS_URI:vCard", "PHOTO", "BINVAL");
if (res == null) return null;
Bytes content = new Bytes.take(Base64.decode(res));
string sha1 = Checksum.compute_for_bytes(ChecksumType.SHA1, content);
if (sha1 != hash) return null;
return content;
}
public class Module : XmppStreamModule {
public static ModuleIdentity<Module> IDENTITY = new ModuleIdentity<Module>(NS_URI, "0153_vcard_based_avatars");
public signal void received_avatar_hash(XmppStream stream, Jid jid, string hash);
public override void attach(XmppStream stream) {
stream.get_module(Presence.Module.IDENTITY).received_presence.connect(on_received_presence);
}
public override void detach(XmppStream stream) {
stream.get_module(Presence.Module.IDENTITY).received_presence.disconnect(on_received_presence);
}
public override string get_ns() { return NS_URI; }
public override string get_id() { return IDENTITY.id; }
private void on_received_presence(XmppStream stream, Presence.Stanza presence) {
if (presence.type_ != Presence.Stanza.TYPE_AVAILABLE) {
return;
}
StanzaNode? update_node = presence.stanza.get_subnode("x", NS_URI_UPDATE);
if (update_node == null) return;
StanzaNode? photo_node = update_node.get_subnode("photo", NS_URI_UPDATE);
if (photo_node == null) return;
string? sha1 = photo_node.get_string_content();
if (sha1 == null) return;
received_avatar_hash(stream, presence.from, sha1);
}
}
}
|