From 1bc48a1f66b48544b90b70e082293643b6642091 Mon Sep 17 00:00:00 2001 From: Ben Date: Fri, 30 Apr 2010 17:18:35 +0000 Subject: [PATCH] Push public IM aliases as XMPP roster names and vCard full names. --- perl/lib/Thrasher/Component.pm | 11 ++++++- perl/lib/Thrasher/Plugin/Vcard.pm | 43 +++++++++++++++++--------- perl/lib/Thrasher/Protocol.pm | 58 ++++++++++++++++++++++++++++++++++++ perl/lib/Thrasher/Protocol/Purple.pm | 4 +++ perl/lib/Thrasher/Session.pm | 16 ++++++++++ 5 files changed, 117 insertions(+), 15 deletions(-) diff --git a/perl/lib/Thrasher/Component.pm b/perl/lib/Thrasher/Component.pm index d37c754..f7d423b 100644 --- a/perl/lib/Thrasher/Component.pm +++ b/perl/lib/Thrasher/Component.pm @@ -106,6 +106,9 @@ my $states = { connected => \&xml_in_connected }; +# Out-of-band hook: +our $UNREGISTER_CALLBACK = undef; + sub new { my $class = shift; my $self = {}; @@ -1545,8 +1548,14 @@ sub set_roster_name { $session->do_if_feature($NS_ROSTER_EXCHANGE, $send_iq); } + + callbacks('set_roster_name', + $session->{'full_jid'}, + undef, + $legacy_jid, + $name); } - + =pod =back diff --git a/perl/lib/Thrasher/Plugin/Vcard.pm b/perl/lib/Thrasher/Plugin/Vcard.pm index d8fb1c9..3570aff 100644 --- a/perl/lib/Thrasher/Plugin/Vcard.pm +++ b/perl/lib/Thrasher/Plugin/Vcard.pm @@ -91,6 +91,19 @@ sub presence_hook { push(@children, [[$NS_VCARD_UPDATE, 'photo'], {}, $avatar_hash]); } + if ($legacy_jid =~ /\@/) { + my $legacy_name + = $component->xmpp_name_to_legacy($user_jid, $legacy_jid); + my $displayname + = $component->{protocol}->get_displayname($user_jid, + $legacy_name); + if ($displayname) { + push(@children, [[$NS_VCARD_UPDATE, 'fn'], + {}, + [ $displayname ]]); + } + } + push(@{$presence_tag->[2]}, [[$NS_VCARD_UPDATE, 'x'], {}, \@children]); } @@ -118,26 +131,28 @@ sub return_vcard { my $vcard_target = strip_resource($iq_params->{to}); my $request_from = strip_resource($iq_params->{from}); + my @vcard_elts; - my $avatar = + my $avatar = $component->{protocol}->{backend}->get_avatar($request_from, $vcard_target); - - my $vcard; if ($avatar) { - $vcard = [[$NS_VCARD, 'vCard'], {}, - [ - [[$NS_VCARD, 'PHOTO'], {}, - [ - [[$NS_VCARD, 'TYPE'], {}, ['image/png']], - [[$NS_VCARD, 'BINVAL'], {}, [$avatar]] - ]], - ]]; - } else { - $vcard = [[$NS_VCARD, 'vCard'], {}, []]; + push(@vcard_elts, [[$NS_VCARD, 'PHOTO'], {}, [ + [[$NS_VCARD, 'TYPE'], {}, ['image/png']], + [[$NS_VCARD, 'BINVAL'], {}, [$avatar]], + ]]); } - $component->iq_reply($iq_params, $vcard); + my $legacy_name = $component->xmpp_name_to_legacy($request_from, + $vcard_target); + my $displayname = $component->{protocol}->get_displayname($request_from, + $legacy_name); + if ($displayname) { + push(@vcard_elts, [[$NS_VCARD, 'FN'], {}, [ $displayname ]]); + } + + my $vcard_xml = [[$NS_VCARD, 'vCard'], {}, \@vcard_elts]; + $component->iq_reply($iq_params, $vcard_xml); } 1; diff --git a/perl/lib/Thrasher/Protocol.pm b/perl/lib/Thrasher/Protocol.pm index 3f5f934..6195448 100644 --- a/perl/lib/Thrasher/Protocol.pm +++ b/perl/lib/Thrasher/Protocol.pm @@ -449,6 +449,8 @@ sub logout { my $session = shift; my $continuation = shift; + # TODO: displaynames are allowed to persist while the protocol object does. + my $legacy_login = $session->{'legacy_login'}; delete($self->{'username_to_session'}->{$legacy_login}); } @@ -584,6 +586,7 @@ sub subscribed { log("Using stored presence information for $legacy_username"); $component->send_presence($session->{jid}, $legacy_username, @$presence_info); + $session->resend_displayname($legacy_username); } } @@ -633,6 +636,23 @@ sub ft_local_ready { =pod +=item * + +C($jid, $legacy_username): +Returns the displayname of the legacy user as it should be presented to $jid. + +The default implementation should be sufficient. + +=cut + +sub get_displayname { + my ($self, $jid, $legacy_username) = @_; + + return $self->{'displayname'}->{$jid}->{$legacy_username}; +} + +=pod + =back =head2 Protocol Interface @@ -1073,6 +1093,44 @@ sub set_current_legacy_roster { =pod +=item * + +C($jid, $legacy_username, $displayname_value): +Stores the displayname of the legacy user as it should be presented to $jid. + +If this is overridden, get_displayname() should be, too. + +=cut + +sub set_displayname { + my ($self, $jid, $legacy_username, $displayname) = @_; + + debug("set_displayname($jid, $legacy_username, $displayname) called\n"); + + if (not $displayname) { + # Forget it! + delete($self->{'displayname'}->{$jid}->{$legacy_username}); + return $displayname; + } + + my $displayname_was = $self->get_displayname($jid, $legacy_username); + if ($displayname_was && $displayname_was eq $displayname) { + # Don't send update if unchanged. + return $displayname; + } + + $self->{'displayname'}->{$jid}->{$legacy_username} = $displayname; + + # Push change into $jid's roster. + my $component = $self->{'component'}; + my $legacy_jid = $component->legacy_name_to_xmpp($jid, $legacy_username); + $component->set_roster_name($jid, $legacy_jid, $displayname); + + return $displayname; +} + +=pod + =back =head2 PRE-CANNED ERRORS diff --git a/perl/lib/Thrasher/Protocol/Purple.pm b/perl/lib/Thrasher/Protocol/Purple.pm index 4a942be..cb2728c 100644 --- a/perl/lib/Thrasher/Protocol/Purple.pm +++ b/perl/lib/Thrasher/Protocol/Purple.pm @@ -212,6 +212,10 @@ sub _presence_in { $message =~ s/([\x80-\xff])/'&#' . ord($1) . ';'/ge; } + if ($alias) { + $self->set_displayname($jid, $sender, $alias); + } + # Nothing is done with protocol? my $xmpp_presence = $purple_presence_to_xmpp{$status}; if ($xmpp_presence) { diff --git a/perl/lib/Thrasher/Session.pm b/perl/lib/Thrasher/Session.pm index 917d03f..8745fe4 100644 --- a/perl/lib/Thrasher/Session.pm +++ b/perl/lib/Thrasher/Session.pm @@ -208,6 +208,7 @@ sub subscribe { log("Using stored presence information for $legacy_username"); $comp->send_presence($self->{jid}, $legacy_username, @$stored_presence); + $self->resend_displayname($legacy_username); } else { log("no stored presence information for $legacy_username found."); } @@ -241,6 +242,21 @@ sub subscribe { $self->{protocol}->subscribe($self, $legacy_id, $handle_subscription); } +sub resend_displayname { + my ($self, $legacy_username) = @_; + + my $displayname = $self->{'protocol'}->get_displayname($self->{'jid'}, + $legacy_username); + if ($displayname) { + $self->{'protocol'}->set_displayname($self->{'jid'}, + $legacy_username, + ''); + $self->{'protocol'}->set_displayname($self->{'jid'}, + $legacy_username, + $displayname); + } +} + # Implementing section 4.7 sub unsubscribe { my $self = shift; -- 2.11.4.GIT