ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/Net-XMPP2/lib/Net/XMPP2/Ext/Disco.pm
Revision: 1.8
Committed: Thu Jul 12 07:28:24 2007 UTC (19 years, 2 months ago) by elmex
Branch: MAIN
Changes since 1.7: +3 -5 lines
Log Message:
minor doc fixes and i should put some stuff in the synopsises sometime

File Contents

# User Rev Content
1 elmex 1.3 package Net::XMPP2::Ext::Disco;
2 elmex 1.1 use Net::XMPP2::Namespaces qw/xmpp_ns/;
3 elmex 1.3 use Net::XMPP2::Ext::Disco::Items;
4     use Net::XMPP2::Ext::Disco::Info;
5 elmex 1.6 use Net::XMPP2::Ext;
6    
7     our @ISA = qw/Net::XMPP2::Ext/;
8 elmex 1.1
9     =head1 NAME
10    
11 elmex 1.5 Net::XMPP2::Ext::Disco - Service discovery manager class for XEP-0030
12 elmex 1.1
13     =head1 SYNOPSIS
14    
15 elmex 1.3 use Net::XMPP2::Ext::Disco;
16 elmex 1.1
17     my $con = Net::XMPP2::IM::Connection->new (...);
18 elmex 1.7 $con->add_extension (my $disco = Net::XMPP2::Ext::Disco->new);
19 elmex 1.1 $disco->request_items ('romeo@montague.net',
20 elmex 1.8 sub {
21     my ($disco, $items, $error) = @_;
22 elmex 1.1 if ($error) { print "ERROR".$error->string."\n" }
23     else {
24 elmex 1.8 ... do something with the $items ...
25 elmex 1.1 }
26     }
27     );
28    
29     =head1 DESCRIPTION
30    
31     This module represents a service discovery manager class.
32     You make instances of this class and get a handle to send
33     discovery requests like described in XEP-0030.
34    
35     It also allows you to setup a disco-info/items tree
36     that others can walk and also lets you publish disco information.
37    
38 elmex 1.6 This class is derived from L<Net::XMPP2::Ext> and can be added as extension to
39     objects that implement the L<Net::XMPP2::Extendable> interface or derive from
40     it.
41    
42 elmex 1.1 =head1 METHODS
43    
44 elmex 1.4 =over 4
45    
46     =item B<new (%args)>
47 elmex 1.1
48 elmex 1.6 Creates a new disco handle.
49 elmex 1.1
50     =cut
51    
52     sub new {
53     my $this = shift;
54     my $class = ref($this) || $this;
55     my $self = bless { @_ }, $class;
56     $self->init;
57     $self
58     }
59    
60     sub init {
61     my ($self) = @_;
62    
63     $self->set_identity (client => console => 'Net::XMPP2');
64    
65 elmex 1.6 $self->reg_cb (
66     iq_get_request_xml => sub {
67     my ($self, $con, $node, $handled_ref) = @_;
68     return 1 if $$handled_ref;
69 elmex 1.1
70 elmex 1.6 if ($self->handle_disco_query ($con, $node)) {
71     $$handled_ref = 1;
72     }
73 elmex 1.1
74 elmex 1.6 1
75     }
76     );
77 elmex 1.1 }
78    
79 elmex 1.4 =item B<set_identity ($category, $type, $name)>
80 elmex 1.1
81     This sets the identity of the top info node.
82     The default is: C<$category = "client">, C<$type = "console">
83     and C<$name = "Net::XMPP2">.
84    
85     C<$name> is optional and can be undef.
86    
87     For a list of valid identites look at:
88    
89     http://www.xmpp.org/registrar/disco-categories.html
90    
91     Valid identity types for C<$category = "client"> may be:
92    
93     bot
94     console
95     handheld
96     pc
97     phone
98     web
99    
100     =cut
101    
102     sub set_identity {
103     my ($self, $category, $type, $name) = @_;
104     $self->{iden}->{cat} = $category;
105     $self->{iden}->{type} = $type;
106     $self->{iden}->{name} = $name;
107     }
108    
109    
110 elmex 1.4 =item B<enable_feature ($uri)>
111 elmex 1.1
112     This method enables the feature C<$uri>, where C<$uri>
113     should be one of the values from the B<Name> column on:
114    
115     http://www.xmpp.org/registrar/disco-features.html
116    
117     These features are enabled by default:
118    
119     http://jabber.org/protocol/disco#info
120     http://jabber.org/protocol/disco#items
121    
122     =cut
123    
124     sub enable_feature {
125     my ($self, $feature) = @_;
126     $self->{feat}->{$feature} = 1
127     }
128    
129 elmex 1.4 =item B<disable_feature ($uri)>
130 elmex 1.1
131     This method enables the feature C<$uri>, where C<$uri>
132     should be one of the values from the B<Name> column on:
133    
134     http://www.xmpp.org/registrar/disco-features.html
135    
136     These features are enabled by default:
137    
138     http://jabber.org/protocol/disco#info
139     http://jabber.org/protocol/disco#items
140    
141     =cut
142    
143     sub disable_feature {
144     my ($self, $feature) = @_;
145     delete $self->{feat}->{$feature}
146     }
147    
148     sub write_feature {
149     my ($self, $w, $var) = @_;
150    
151     $w->emptyTag ([xmpp_ns ('disco_info'), 'feature'], var => $var);
152     }
153    
154     sub write_identity {
155     my ($self, $w, $cat, $type, $name) = @_;
156    
157     $w->emptyTag ([xmpp_ns ('disco_info'), 'identity'],
158     category => $cat,
159     type => $type,
160     (defined $name ? (name => $name) : ())
161     );
162     }
163    
164     sub handle_disco_query {
165 elmex 1.6 my ($self, $con, $node) = @_;
166 elmex 1.1
167     if ($node->find_all ([qw/disco_info query/])) {
168 elmex 1.6 $con->reply_iq_result (
169 elmex 1.1 $node, sub {
170     my ($w) = @_;
171    
172     if ($node->attr ('node')) {
173     $w->addPrefix (xmpp_ns ('disco_info'), '');
174     $w->emptyTag ([xmpp_ns ('disco_info'), 'query']);
175    
176     } else {
177     $w->addPrefix (xmpp_ns ('disco_info'), '');
178     $w->startTag ([xmpp_ns ('disco_info'), 'query']);
179     $self->write_identity ($w,
180     $self->{iden}->{cat},
181     $self->{iden}->{type},
182     $self->{iden}->{name},
183     );
184     $self->write_feature ($w, 'http://jabber.org/protocol/disco#info');
185     $self->write_feature ($w, 'http://jabber.org/protocol/disco#items');
186     $w->endTag;
187     }
188 elmex 1.6 },
189     to => $node->attr ('from')
190 elmex 1.1 );
191    
192     return 1
193    
194     } elsif ($node->find_all ([qw/disco_items query/])) {
195 elmex 1.6 $con->reply_iq_result (
196 elmex 1.1 $node, sub {
197     my ($w) = @_;
198    
199     if ($node->attr ('node')) {
200     $w->addPrefix (xmpp_ns ('disco_items'), '');
201     $w->emptyTag ([xmpp_ns ('disco_items'), 'query']);
202    
203     } else {
204     $w->addPrefix (xmpp_ns ('disco_items'), '');
205     $w->emptyTag ([xmpp_ns ('disco_items'), 'query']);
206     }
207 elmex 1.6 },
208     to => $node->attr ('from')
209 elmex 1.1 );
210    
211     return 1
212     }
213    
214     0
215     }
216    
217     sub DESTROY {
218     my ($self) = @_;
219     $self->{connection}->unreg_cb ($self->{cb_id})
220     }
221    
222 elmex 1.2
223 elmex 1.6 =item B<request_items ($con, $dest, $node, $cb)>
224 elmex 1.2
225     This method does send a items request to the JID entity C<$from>.
226     C<$node> is the optional node to send the request to, which can be
227     undef.
228 elmex 1.6 C<$con> must be an instance of L<Net::XMPP2::Connection> or a subclass of it.
229 elmex 1.2 The callback C<$cb> will be called when the request returns with 3 arguments:
230 elmex 1.3 the disco handle, an L<Net::XMPP2::Ext::Disco::Items> object (or undef)
231 elmex 1.2 and an L<Net::XMPP2::Error::IQ> object when an error occured and no items
232     were received.
233    
234 elmex 1.6 $disco->request_items ($con, 'a@b.com', undef, sub {
235 elmex 1.2 my ($disco, $items, $error) = @_;
236     die $error->string if $error;
237    
238     # do something with the items here ;_)
239     });
240    
241     =cut
242    
243     sub request_items {
244 elmex 1.6 my ($self, $con, $dest, $node, $cb) = @_;
245 elmex 1.2
246 elmex 1.6 $con->send_iq (
247 elmex 1.2 get => sub {
248     my ($w) = @_;
249     $w->addPrefix (xmpp_ns ('disco_items'), '');
250     $w->emptyTag ([xmpp_ns ('disco_items'), 'query'],
251     (defined $node ? (node => $node) : ())
252     );
253     },
254     sub {
255     my ($xmlnode, $error) = @_;
256     my $items;
257    
258     if ($xmlnode) {
259     my (@query) = $xmlnode->find_all ([qw/disco_items query/]);
260 elmex 1.3 $items = Net::XMPP2::Ext::Disco::Items->new (
261 elmex 1.2 jid => $dest,
262     node => $node,
263     xmlnode => $query[0]
264     )
265     }
266    
267     $cb->($self, $items, $error)
268     },
269     to => $dest
270     );
271     }
272    
273 elmex 1.6 =item B<request_info ($con, $dest, $node, $cb)>
274 elmex 1.2
275     This method does send a info request to the JID entity C<$from>.
276     C<$node> is the optional node to send the request to, which can be
277     undef.
278 elmex 1.6 C<$con> must be an instance of L<Net::XMPP2::Connection> or a subclass of it.
279 elmex 1.2 The callback C<$cb> will be called when the request returns with 3 arguments:
280 elmex 1.3 the disco handle, an L<Net::XMPP2::Ext::Disco::Info> object (or undef)
281 elmex 1.2 and an L<Net::XMPP2::Error::IQ> object when an error occured and no items
282     were received.
283    
284     $disco->request_info ('a@b.com', undef, sub {
285     my ($disco, $info, $error) = @_;
286     die $error->string if $error;
287    
288     # do something with info here ;_)
289     });
290    
291     =cut
292    
293     sub request_info {
294 elmex 1.6 my ($self, $con, $dest, $node, $cb) = @_;
295 elmex 1.2
296 elmex 1.6 $con->send_iq (
297 elmex 1.2 get => sub {
298     my ($w) = @_;
299     $w->addPrefix (xmpp_ns ('disco_info'), '');
300     $w->emptyTag ([xmpp_ns ('disco_info'), 'query'],
301     (defined $node ? (node => $node) : ())
302     );
303     },
304     sub {
305     my ($xmlnode, $error) = @_;
306     my $info;
307    
308     if ($xmlnode) {
309     my (@query) = $xmlnode->find_all ([qw/disco_info query/]);
310 elmex 1.3 $info = Net::XMPP2::Ext::Disco::Info->new (
311 elmex 1.2 jid => $dest,
312     node => $node,
313     xmlnode => $query[0]
314     )
315     }
316    
317     $cb->($self, $info, $error)
318     },
319     to => $dest
320     );
321     }
322    
323 elmex 1.4 =back
324    
325 elmex 1.1 =head1 AUTHOR
326    
327 elmex 1.4 Robin Redeker, C<< <elmex at ta-sa.org> >>, JID: C<< <elmex at jabber.org> >>
328 elmex 1.1
329     =head1 COPYRIGHT & LICENSE
330    
331     Copyright 2007 Robin Redeker, all rights reserved.
332    
333     This program is free software; you can redistribute it and/or modify it
334     under the same terms as Perl itself.
335    
336     =cut
337    
338     1;