1 package Thrasher
::Plugin
::Vcard
;
2 # The Perl module standard and the capitalization of vCard are in
3 # conflict. I like Perl better. Perl wins!
12 Thrasher::Plugin::Vcard - implements vCard support for transport
13 users, including avatar support.
17 This module replies when a user's vcard is requested, filling in their
18 avatar, and possibly other things. This module is intended to be
19 filled out, as more things that can be stuck in vCards are
22 In the meantime, you get conventional avatars this way, including
23 full XEP-0153 support for avatar hash advertising.
27 use Thrasher
::Log
qw(log);
28 use Thrasher
::Plugin
qw(:all);
29 use Thrasher
::XML
qw(strip_resource);
30 use Thrasher
::Constants
qw(:all);
32 use Digest
::SHA1
qw(sha1_hex);
34 use Thrasher
::Component
qw(strip_resource);
36 # $user_jid -> $legacy_jid -> avatar sha1_hex
39 register_plugin
({client_iq_handlers
=>
40 {$NS_VCARD => { get
=> \
&return_vcard
}},
41 component_iq_handlers
=>
42 {$NS_VCARD => { get
=> \
&return_component_vcard
}},
43 features
=> [$NS_VCARD, $NS_VCARD_UPDATE],
45 presence_out
=> { vcard
=> \
&presence_hook
},
46 avatar_changed
=> { vcard
=> \
&avatar_update
}
52 my $component = shift;
54 my $legacy_jid = shift;
55 my $raw_binary_data = shift;
56 my $base64_data = shift;
59 my $hash = sha1_hex
($raw_binary_data);
60 my $old_hash = $AVATARS{$user_jid}->{$legacy_jid};
61 $AVATARS{$user_jid}->{$legacy_jid} = $hash;
63 if (!$old_hash || $hash ne $old_hash) {
64 my $session = $component->session_for($user_jid);
66 $session->{component
}->{presence
}->{strip_resource
($user_jid)}->{strip_resource
($legacy_jid)};
67 if (ref($presence_info) eq 'ARRAY') {
68 my ($type, $show, $status) = @
$presence_info;
69 $component->send_presence_xml
70 ($user_jid, $type, $legacy_jid,
77 my $component = shift;
78 my $presence_tag = shift;
80 my $component_name = $component->{component_name
};
82 my $user_jid = $presence_tag->[1]->{to
};
83 my $legacy_jid = $presence_tag->[1]->{from
};
85 if ($legacy_jid && $user_jid &&
86 $legacy_jid =~ /$component_name$/) {
89 my $avatar_hash = $AVATARS{$user_jid}->{$legacy_jid};
91 push(@children, [[$NS_VCARD_UPDATE, 'photo'], {}, $avatar_hash]);
94 push(@
{$presence_tag->[2]},
95 [[$NS_VCARD_UPDATE, 'x'], {}, \
@children]);
101 sub return_component_vcard
{
102 my $component = shift;
103 my $iq_params = shift;
106 my $vcard = [[$NS_VCARD, 'vCard'], {},
108 [[$NS_VCARD, 'EMAIL'], {},
109 [[[$NS_VCARD, 'USERID'], {},
110 [$component->{component_name
}]]]]]];
111 $component->iq_reply($iq_params, $vcard);
115 my $component = shift;
116 my $iq_params = shift;
119 my $vcard_target = strip_resource
($iq_params->{to
});
120 my $request_from = strip_resource
($iq_params->{from
});
123 $component->{protocol
}->{backend
}->get_avatar($request_from,
128 $vcard = [[$NS_VCARD, 'vCard'], {},
130 [[$NS_VCARD, 'PHOTO'], {},
132 [[$NS_VCARD, 'TYPE'], {}, ['image/png']],
133 [[$NS_VCARD, 'BINVAL'], {}, [$avatar]]
137 $vcard = [[$NS_VCARD, 'vCard'], {}, []];
140 $component->iq_reply($iq_params, $vcard);