File Coverage

blib/lib/E2/Message.pm
Criterion Covered Total %
statement 18 175 10.2
branch 0 114 0.0
condition 0 15 0.0
subroutine 6 32 18.7
pod 15 15 100.0
total 39 351 11.1


line stmt bran cond sub pod time code
1             # E2::Message
2             # Jose M. Weeks
3             # 18 June 2003
4             #
5             # See bottom for pod documentation.
6              
7             package E2::Message;
8              
9 1     1   863 use 5.006;
  1         3  
  1         40  
10 1     1   7 use strict;
  1         3  
  1         35  
11 1     1   5 use warnings;
  1         2  
  1         32  
12 1     1   5 use Carp;
  1         3  
  1         71  
13              
14 1     1   5 use E2::Ticker;
  1         3  
  1         25  
15 1     1   5 use E2::Node; # for set_room
  1         3  
  1         3275  
16              
17             our @ISA = "E2::Ticker";
18             our $VERSION = "0.32";
19             our $DEBUG; *DEBUG = *E2::Interface::DEBUG;
20              
21             our %room_name_to_id = (
22             "outside" => undef, # 1102338,
23             "political asylum" => 553129,
24             "noder's nursery" => 553146
25             );
26              
27             # Methods
28              
29             sub new;
30              
31             sub list_public;
32             sub list_private;
33              
34             sub reset_public;
35             sub reset_private;
36              
37             sub room;
38             sub room_id;
39             sub topic;
40              
41             sub set_room;
42             sub send;
43             sub blab;
44             sub delete;
45              
46             # Private
47              
48             sub list_messages;
49              
50             # Methods
51              
52             sub new {
53 0     0 1   my $arg = shift;
54 0   0       my $class = ref( $arg ) || $arg;
55 0           my $self = $class->SUPER::new();
56 0           return bless ($self, $class);
57             }
58              
59             sub topic {
60 0 0   0 1   my $self = shift or croak "Usage: topic E2MESSAGE";
61 0           return $self->{topic};
62             }
63              
64             sub room {
65 0 0   0 1   my $self = shift or croak "Usage: room E2MESSAGE";
66 0           return $self->{room};
67             }
68              
69             sub room_id {
70 0 0   0 1   my $self = shift or croak "Usage: room_id E2MESSAGE";
71 0           return $self->{room_id};
72             }
73              
74             sub reset_public {
75 0 0   0 1   my $self = shift or croak "Usage: reset_public E2MESSAGE";
76 0           $self->{msglimit} = undef;
77             }
78              
79             sub reset_private {
80 0 0   0 1   my $self = shift or croak "Usage: reset_private E2MESSAGE";
81 0           $self->{p_msglimit} = undef;
82             }
83              
84             sub list_public {
85 0 0   0 1   my $self = shift or croak "Usage: list_public E2MESSAGE";
86            
87 0           my %opt;
88             my @list;
89            
90 0 0         warn "E2::Message::list_public\n" if $DEBUG > 1;
91              
92             # We need to lock list_public, because there is a re-entrance issue
93             # with msglimit (if we call this method a second time before the
94             # first has completed, we'll have two list_publics with the same
95             # msglimit, which means any messages retrieved will be retrieved
96             # twice).
97              
98 0 0         return () if $self->{__lock_list_public};
99 0           $self->{__lock_list_public} = 1;
100            
101 0           $opt{nosort} = 1;
102 0           $opt{backtime} = 10;
103 0 0         $opt{msglimit} = $self->{msglimit} if $self->{msglimit};
104 0 0         $opt{for_node} = $self->{room_id} if $self->{room_id};
105            
106             # This code is repeated in list_private (to some extent).
107              
108             my $handlers = {
109             'messages/topic' => sub {
110 0     0     (my $a, my $b) = @_;
111 0           $self->{topic} = $b->text;
112             },
113             'messages/room' => sub {
114 0     0     (my $a, my $b) = @_;
115              
116             # If we're in the process of changing rooms, don't
117             # store any room values.
118              
119 0 0         return if $self->{room_lock};
120              
121 0           $self->{room} = $b->text;
122 0           $self->{room_id} = $b->{att}->{room_id}
123             },
124             'messages/msglist/msg' => sub {
125 0     0     (my $a, my $b) = @_;
126 0           my $m = {};
127              
128 0           $m->{id} = $b->{att}->{msg_id};
129 0           $m->{time} = $b->{att}->{msg_time};
130              
131             # Set 'author' and 'author_id' if they exist
132              
133 0 0         if( my $f = $b->first_child('from') ) {
134 0           $m->{author} = $f->first_child('e2link')->text;
135 0           $m->{author_id} = $f->first_child('e2link')->
136             {att}->{node_id};
137             }
138              
139 0           $m->{archive} = $b->{att}->{archive};
140            
141 0           $m->{text} = $b->first_child('txt')->text;
142              
143 0 0 0       if( !$self->{msglimit} ||
144             $m->{id} > $self->{msglimit} ) {
145 0           $self->{msglimit} = $m->{id};
146             }
147              
148 0           push @list, $m;
149             }
150 0           };
151              
152             # We need to do some post-processing (sorting), so we'll have to use
153             # thread_then
154            
155             return $self->thread_then(
156             [
157             \&E2::Ticker::parse,
158             $self,
159             'messages',
160             $handlers,
161             [], # It'll be more efficient to not pass
162             %opt # @list back and forth, so just pass a
163             ], # dummy value.
164 0     0     sub { return sort { $a->{id} <=> $b->{id} } @list }, # POST
  0            
165 0     0     sub { delete $self->{__lock_list_public} } # FINISH
166 0           );
167             }
168              
169             sub list_private {
170 0 0   0 1   my $self = shift or croak "Usage: list_private E2MESSAGE [, DROP_ARCHIVED ]";
171 0           my $drop_archived = shift;
172 0           my @list;
173             my %opt;
174            
175 0 0         warn "E2::Message::list_private\n" if $DEBUG > 1;
176              
177 0 0         return () if $self->{__lock_list_private};
178 0           $self->{__lock_list_private} = 1;
179              
180 0 0         $opt{msglimit} = $self->{p_msglimit} if $self->{p_msglimit};
181 0           $opt{for_node} = "me";
182              
183             my $handlers = {
184             'messages/msglist/msg' => sub {
185 0     0     (my $a, my $b) = @_;
186 0           my $m = {};
187              
188 0           $m->{id} = $b->{att}->{msg_id};
189 0           $m->{time} = $b->{att}->{msg_time};
190              
191             # Set 'author' and 'author_id' if they exist
192              
193 0 0         if( my $f = $b->first_child('from') ) {
194 0           $m->{author} = $f->first_child('e2link')->text;
195 0           $m->{author_id} = $f->first_child('e2link')->
196             {att}->{node_id};
197             }
198              
199 0           $m->{archive} = $b->{att}->{archive};
200            
201 0           $m->{text} = $b->first_child('txt')->text;
202              
203             # Do group stuff if this is a group message
204              
205 0 0         if( my $g = $b->first_child( 'grp' ) ) {
206 0           $m->{group} = $g->first_child('e2link')->text;
207 0           $m->{group_id} = $g->first_child('e2link')->
208             {att}->{node_id};
209 0           $m->{grouptype} = $g->{att}->{type};
210             }
211              
212 0 0 0       if( !$self->{p_msglimit} ||
213             $m->{id} > $self->{p_msglimit} ) {
214 0           $self->{p_msglimit} = $m->{id};
215             }
216              
217             # Don't store if we're dropping archived AND
218             # this message is archived.
219              
220 0 0 0       if( $drop_archived && $m->{archive} ) {
221 0           return;
222             }
223              
224 0           push @list, $m;
225             }
226 0           };
227              
228             # We need to do some post-processing (sorting), so we'll have to use
229             # thread_then
230            
231             return $self->thread_then(
232             [
233             \&E2::Ticker::parse,
234             $self,
235             'messages',
236             $handlers,
237             [], # It'll be more efficient to not pass
238             %opt # @list back and forth, so just pass a
239             ], # dummy value.
240 0     0     sub { return sort { $a->{id} <=> $b->{id} } @list }, # POST
  0            
241 0     0     sub { delete $self->{__lock_list_private} } # FINISH
242 0           );
243             }
244              
245             sub send {
246 0 0   0 1   my $self = shift or croak "Usage: send E2MESSAGE, MESSAGE_TEXT";
247 0 0         my $message = shift or croak "Usage: send E2MESSAGE, MESSAGE_TEXT";
248            
249 0 0         warn "E2::Message::send\n" if $DEBUG > 1;
250            
251 0 0         if( ! $self->logged_in ) {
252 0 0         warn "Unable to send message: not logged in" if $DEBUG;
253 0           return undef;
254             }
255            
256             return $self->thread_then(
257             [
258             \&E2::Interface::process_request,
259             $self,
260             op => "message",
261             message => $message
262             ],
263             sub {
264 0     0     return 1; # FIXME
265 0           });
266             }
267            
268             sub set_room {
269 0 0   0 1   our $self = shift or croak "Usage: set_room E2MESSAGE, ROOM_NAME";
270 0 0         my $room = shift or croak "Usage: set_room E2MESSAGE, ROOM_NAME";
271              
272 0 0         warn "E2::Message::set_room\n" if $DEBUG > 1;
273              
274 0 0         return undef if $self->{__lock_set_room};
275 0           $self->{__lock_set_room} = 1;
276              
277 0 0         if( ! $self->logged_in ) {
278 0 0         warn "Unable to set room message: not logged in" if $DEBUG;
279 0           return undef;
280             }
281              
282 0           $room = lc( $room );
283            
284             # Return 0 if we're already in the specified room
285            
286 0 0         if( lc($self->{room}) eq $room ) {
287 0           return 0;
288             }
289              
290             # Change rooms
291              
292 0           our $n = new E2::Node;
293 0           $n->clone( $self );
294            
295             return $self->thread_then(
296             [
297             \&E2::Node::load,
298             $n,
299             $room,
300             'room'
301             ],
302             sub {
303 0 0 0 0     if( (!$n->type) || $n->type ne 'room' ) {
304 0           return undef;
305             }
306            
307 0           $self->{room} = $n->title;
308 0           $self->{room_id} = $n->node_id;
309 0           $self->{topic} = $n->description;
310 0           $self->{msglimit} = undef;
311              
312 0           delete $self->{__lock_set_room};
313            
314 0           return 1;
315 0           });
316             }
317              
318             sub blab {
319 0 0   0 1   my $self = shift or croak "Usage: blab E2MESSAGE, USER_ID, TEXT [ , CC_BOOL ]";
320 0 0         my $user_id = shift or croak "Usage: blab E2MESSAGE, USER_ID, TEXT [ , CC_BOOL ]";
321 0 0         my $text = shift or croak "Usage: blab E2MESSAGE, USER_ID, TEXT [ , CC_BOOL ]";
322 0           my $cc = shift;
323              
324 0           my %request;
325              
326 0 0         warn "E2::Message::blab\n" if $DEBUG > 1;
327              
328 0 0         if( ! $self->logged_in ) {
329 0 0         warn "Unable to blab: not logged in" if $DEBUG;
330 0           return undef;
331             }
332              
333 0           $request{node_id} = $user_id;
334 0           $request{"msguser_$user_id"} = $text;
335              
336 0 0         if( $cc ) {
337 0 0         if( !$self->this_user_id ) {
338              
339             return $self->thread_then(
340             [
341             \&E2::Interface::verify_login,
342             $self
343             ],
344             sub {
345 0 0   0     return undef if !$self->this_user_id;
346              
347 0           $request{"ccmsguser_$self->{user_id}"} = 1;
348              
349 0           return process_request( %request );
350 0           });
351            
352             } else {
353 0           $request{"ccmsguser_$self->{user_id}"} = 1
354             }
355             }
356              
357 0           return $self->process_request( %request );
358             }
359              
360             sub archive {
361 0 0   0 1   my $self = shift or croak "Usage: archive E2MESSAGE, MSG_ID ...";
362 0 0         my @msgs = @_ or croak "Usage: archive E2MESSAGE, MSG_ID ...";
363              
364 0 0         warn "E2::Message::archive\n" if $DEBUG > 1;
365            
366 0           my %req = ( op => 'message' );
367            
368 0           foreach( @msgs ) { $req{"archive_$_"} = 'yup' }
  0            
369              
370 0           return $self->process_request( %req );
371             }
372              
373             sub unarchive {
374 0 0   0 1   my $self = shift or croak "Usage: unarchive E2MESSAGE, MSG_ID ...";
375 0 0         my @msgs = @_ or croak "Usage: unarchive E2MESSAGE, MSG_ID ...";
376              
377 0 0         warn "E2::Message::unarchive\n" if $DEBUG > 1;
378            
379 0           my %req = ( op => 'message' );
380            
381 0           foreach( @msgs ) { $req{"unarchive_$_"} = 'yup' }
  0            
382              
383 0           return $self->process_request( %req );
384             }
385              
386             sub delete {
387 0 0   0 1   my $self = shift or croak "Usage: delete E2MESSAGE, MSG_ID ...";
388 0 0         my @msgs = @_ or croak "Usage: delete E2MESSAGE, MSG_ID ...";
389              
390 0 0         warn "E2::Message::delete\n" if $DEBUG > 1;
391            
392 0           my %req = ( op => 'message' );
393            
394 0           foreach( @msgs ) { $req{"deletemsg_$_"} = 'yup' }
  0            
395              
396 0           return $self->process_request( %req );
397             }
398              
399             sub perform {
400 0 0   0 1   my $self = shift or croak "Usage: perform E2MESSAGE, HASH";
401 0 0         my %ops = @_ or croak "Usage: perform E2MESSAGE, HASH";
402              
403 0           my %req = ( op => 'message' );
404              
405 0           foreach( keys %ops ) {
406 0 0         if( lc($ops{$_}) eq 'delete' ) {
    0          
    0          
407 0           $req{"deletemsg_$_"} = 'yup';
408             } elsif( lc($ops{$_}) eq 'archive' ) {
409 0           $req{"archive_$_"} = 'yup';
410             } elsif( lc($ops{$_}) eq 'unarchive' ) {
411 0           $req{"unarchive_$_"} = 'yup';
412             } else {
413 0           croak "Invalid operation: $_";
414             }
415             }
416              
417 0           return $self->process_request( %req );
418             }
419              
420             1;
421             __END__