AnyEvent-XMPP
view release on metacpan or search on metacpan
lib/AnyEvent/XMPP/IM/Roster.pm view on Meta::CPAN
package AnyEvent::XMPP::IM::Roster;
use AnyEvent::XMPP::IM::Contact;
use AnyEvent::XMPP::IM::Presence;
use AnyEvent::XMPP::Util qw/prep_bare_jid bare_jid cmp_bare_jid/;
use AnyEvent::XMPP::Namespaces qw/xmpp_ns/;
use strict;
no warnings;
=head1 NAME
AnyEvent::XMPP::IM::Roster - Instant messaging roster for XMPP
=head1 SYNOPSIS
my $con = AnyEvent::XMPP::IM::Connection->new (...);
...
my $ro = $con->roster;
if (my $c = $ro->get_contact ('test@example.com')) {
$c->make_message ()->add_body ("Hello there!")->send;
}
=head1 DESCRIPTION
This module represents a class for roster objects which contain
contact information.
It manages the roster of a JID connected by an L<AnyEvent::XMPP::IM::Connection>.
It manages also the presence information that is received.
You get the roster by calling the C<roster> method on an L<AnyEvent::XMPP::IM::Connection>
object. There is no other way.
=cut
sub new {
my $this = shift;
my $class = ref($this) || $this;
bless { @_ }, $class;
}
sub update {
my ($self, $node) = @_;
my ($query) = $node->find_all ([qw/roster query/]);
return unless $query;
my @upd;
for my $item ($query->find_all ([qw/roster item/])) {
my $jid = $item->attr ('jid');
my $sub = $item->attr ('subscription'),
$self->touch_jid ($jid);
if ($sub eq 'remove') {
my $c = $self->remove_contact ($jid);
$c->update ($item);
} else {
push @upd, $self->get_contact ($jid)->update ($item);
}
}
@upd
}
sub update_presence {
my ($self, $node) = @_;
my $jid = $node->attr ('from');
# XXX: should check whether C<$jid> is nice JID.
my $type = $node->attr ('type');
my $contact = $self->touch_jid ($jid);
my %stati;
$stati{$_->attr ('lang') || ''} = $_->text
for $node->find_all ([qw/client status/]);
if ($type eq 'subscribe') {
$self->{connection}->event (
contact_request_subscribe => $self, $contact, $stati{''});
} elsif ($type eq 'subscribed') {
$self->{connection}->event (
contact_subscribed => $self, $contact, $stati{''});
} elsif ($type eq 'unsubscribe') {
$self->{connection}->event (
contact_did_unsubscribe => $self, $contact, $stati{''});
} elsif ($type eq 'unsubscribed') {
$self->{connection}->event (
contact_unsubscribed => $self, $contact, $stati{''});
} else {
return $contact->update_presence ($node)
}
return ($contact)
}
sub touch_jid {
my ($self, $jid, $contact) = @_;
my $bjid = prep_bare_jid ($jid);
if (cmp_bare_jid ($jid, $self->{connection}->jid)) {
$self->{myself} =
$contact
|| AnyEvent::XMPP::IM::Contact->new (
connection => $self->{connection},
jid => AnyEvent::XMPP::Util::bare_jid ($jid),
is_me => 1,
);
return $self->{myself}
}
unless ($self->{contacts}->{$bjid}) {
$self->{contacts}->{$bjid} =
$contact
|| AnyEvent::XMPP::IM::Contact->new (
connection => $self->{connection},
jid => AnyEvent::XMPP::Util::bare_jid ($jid),
)
}
$self->{contacts}->{$bjid}
}
( run in 0.565 second using v1.01-cache-2.11-cpan-39bf76dae61 )