ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Net-XMPP2/samples/room_lister
Revision: 1.5
Committed: Thu Jul 26 19:45:23 2007 UTC (16 years, 10 months ago) by elmex
Branch: MAIN
CVS Tags: HEAD
Changes since 1.4: +3 -2 lines
Log Message:
fixed some other bugs....

File Contents

# Content
1 #!/opt/perl/bin/perl
2 use strict;
3 use utf8;
4 use Event;
5 use AnyEvent;
6 use Net::XMPP2::Client;
7 use Net::XMPP2::Ext::Disco;
8 use Net::XMPP2::Ext::DataForm;
9 use Storable;
10 use XML::DOM::XPath;
11 use EVQ;
12
13 our $datafile = "room_data.stor";
14 our $data = {};
15
16 eval { $data = retrieve $datafile };
17 sub sync_data { store $data, $datafile }
18
19 # MAIN START
20 my $conferences = retrieve 'conferences.stor';
21 if ($ARGV[0] eq 'stat') {
22 my @srv = keys %$conferences;
23 my %conf;
24 for (map { my $s = pop @$_; my $a = $_; map { $s . ":" . $_ } @$a } map { [$_, keys %{$conferences->{$_}}] } keys %$conferences) {
25 $conf{$_} = 1;
26 }
27 print "servers with conferences: " . scalar (@srv) . "\n";
28 print "conferences : " . scalar (join ",\n", keys %conf) . "\n";
29 exit;
30 }
31 my $cl = Net::XMPP2::Client->new ();
32 my $d = Net::XMPP2::Ext::Disco->new;
33 $cl->add_extension ($d);
34 $cl->add_account ('net_xmpp2@jabber.org/test2', 'test');
35
36 sub disco_info {
37 my ($con, $jid, $cb) = @_;
38
39 EVQ::push_request ("di_$jid", sub {
40 my $ID = shift;
41 $d->request_info ($con, $jid, undef, sub {
42 my ($d, $i, $e) = @_;
43 if ($e) {
44 print "error on disco info on $jid: " . $e->string . "\n";
45 } else {
46 $cb->($i);
47 }
48 EVQ::finreq ($ID)
49 });
50 });
51 }
52
53 sub disco_items {
54 my ($con, $jid, $cb) = @_;
55
56 EVQ::push_request ("dit_$jid", sub {
57 my $ID = shift;
58 $d->request_items ($con, $jid, undef, sub {
59 my ($d, $i, $e) = @_;
60 if ($e) {
61 print "error on disco items on $jid: " . $e->string . "\n";
62 } else {
63 $cb->($i);
64 }
65 EVQ::finreq ($ID)
66 });
67 });
68 }
69
70 sub fetch_room_occupants {
71 my ($con, $jid, $cb) = @_;
72
73 EVQ::push_request ("fro_$jid", sub {
74 my $ID = shift;
75 $d->request_info ($con, $jid, undef, sub {
76 my ($d, $i, $e) = @_;
77 if ($e) {
78 print "error on disco info to $jid for room occupants: " . $e->string . "\n";
79 } else {
80 my (@q) = $i->xml_node ()->find_all ([qw/data_form x/]);
81 if (@q) {
82 my $df = Net::XMPP2::Ext::DataForm->new;
83 $df->from_node (@q);
84 if (my $f = $df->get_field ('muc#roominfo_occupants')) {
85 $cb->($jid, $f->{values}->[0]);
86 EVQ::finreq ($ID);
87 return;
88 }
89 }
90 $cb->($jid);
91 }
92 EVQ::finreq ($ID);
93 });
94 });
95 }
96
97 sub disco_conference {
98 my ($con, $jid, $cb) = @_;
99
100 EVQ::push_request ("dc_$jid", sub {
101 my $ID = shift;
102 disco_items ($con, $jid, sub {
103 my ($items) = @_;
104 for my $i ($items->items) {
105 my $room_name = $i->{name};
106 fetch_room_occupants ($con, $i->{jid}, sub {
107 my ($room_jid, $cnt) = @_;
108 unless (defined $cnt) {
109 if ($room_name =~ /\((\d+)\)\s*$/) {
110 $cnt = $1;
111 }
112 }
113 $cb->($jid, $room_jid, $room_name, $cnt);
114 });
115 }
116 EVQ::finreq ($ID);
117 });
118 });
119 }
120
121 my $con;
122 my $A = AnyEvent->condvar;
123
124 $cl->reg_cb (
125 error => sub {
126 my ($cl, $acc, $err) = @_;
127 print "ERROR: " . $err->string . "\n";
128 1
129 },
130 iq_result_cb_exception => sub {
131 my ($cl, $acc, $ex) = @_;
132 print "EXCEPTION: $ex\n";
133 1
134 },
135 session_ready => sub {
136 my ($cl, $acc) = @_;
137 print "session ready, requesting items for $ARGV[0]\n";
138 my $c = $acc->connection ();
139 $c->set_default_iq_timeout (30);
140 $con = $c;
141 $A->broadcast;
142 0
143 },
144 message => sub {
145 my ($cl, $acc, $msg) = @_;
146 print "message from: " . $msg->from . ": " . $msg->any_body . "\n";
147 1
148 }
149 );
150
151 $cl->start;
152
153 $A->wait;
154
155 print "EVQ start\n";
156 EVQ::start ();
157
158 my $t;
159 sub mkti { $t = AnyEvent->timer (after => 10, cb => sub { sync_data (); mkti (); }) }
160 mkti;
161
162 for my $SERVER (keys %{$conferences}) {
163 my $conf = $conferences->{$SERVER};
164 for my $cj (keys %$conf) {
165 disco_conference ($con, $cj, sub {
166 my ($cjid, $rjid, $rname, $rocc) = @_;
167 my $prev = $data->{$cjid}->{$rjid};
168 if ($prev) {
169 if ($prev->[3] < $rocc) {
170 $data->{$cjid}->{$rjid} = [$cjid, $rjid, $rname, $rocc];
171 }
172 } else {
173 $data->{$cjid}->{$rjid} = [$cjid, $rjid, $rname, $rocc];
174 }
175 printf "\t*** %-30s: %-50s: %3d\n",
176 $cjid, $rjid, $rocc;
177 });
178 }
179 }
180
181
182 EVQ::wait ();