File Coverage

blib/lib/Net/Laconica.pm
Criterion Covered Total %
statement 45 91 49.4
branch 10 50 20.0
condition 9 21 42.8
subroutine 9 16 56.2
pod 3 3 100.0
total 76 181 41.9


line stmt bran cond sub pod time code
1             package Net::Laconica;
2              
3 1     1   34762 use warnings;
  1         2  
  1         27  
4 1     1   5 use strict;
  1         3  
  1         27  
5 1     1   1924 use HTML::Parser;
  1         7590  
  1         39  
6 1     1   1125 use LWP::UserAgent;
  1         87842  
  1         45  
7 1     1   1132 use Data::Validate qw(is_alphanumeric);
  1         115466  
  1         95  
8 1     1   1704 use Data::Validate::URI qw(is_http_uri);
  1         107862  
  1         346  
9 1     1   13 use Carp;
  1         2  
  1         1181  
10              
11             our $VERSION = '0.08';
12              
13             my $ua = LWP::UserAgent->new;
14             $ua->agent('Mozilla');
15             $ua->cookie_jar({ file => 'cookies.txt' });
16              
17              
18             sub new {
19 20     20 1 11809 my $class = shift;
20 20         63 my $self = { login => 1, @_ };
21              
22 20 100 100     194 unless( exists $self->{uri} && exists $self->{username} && exists $self->{password}
      66        
      100        
      33        
23             or exists $self->{uri} && exists $self->{username} ) {
24 13         110 croak 'Invalid arguments';
25             }
26              
27             # Sanitise arguments and check for validity
28 7 100       184 is_http_uri($self->{uri}) || croak 'Invalid URI';
29 5 100       3466 is_alphanumeric($self->{username}) || croak 'Invalid username';
30              
31             # Append a slash at the end of uri if it does not end with one
32 3 50       1028 if( substr($self->{uri}, (length $self->{uri}) - 1, 1) ne '/' ) {
33 3         7 $self->{uri} .= '/';
34             }
35              
36             # Convert the username to lowercase and return the blessed reference
37 3         10 $self->{username} = lc $self->{username};
38 3         19 bless $self, $class;
39             }
40              
41              
42             sub fetch {
43 1     1 1 9 my $self = shift;
44 1         2 undef $self->{contents};
45 1         2 my $number;
46              
47             # Get/set the number of messages to be fetched
48 1 50       7 if( @_ == 1 ) {
    50          
49 0         0 $number = shift;
50 0 0       0 if($number > 20) {
51 0         0 $number = 20;
52             }
53             } elsif( @_ == 0 ) {
54 1         2 $number = 10;
55             } else {
56 0         0 croak 'Invalid arguments';
57             }
58              
59             # Start fetching messages
60 1         24 my $p = HTML::Parser->new(api_version => 3);
61 1     0   49 $p->handler(start => sub { $self->_start_handler(@_) }, 'self,tagname,attr');
  0         0  
62             $p->handler(end => sub {
63 0 0   0   0 return unless defined $self->{value};
64 0 0 0     0 return if $self->{value} eq 'content' && shift eq 'a';
65 0         0 $self->{value} = undef;
66 1         7 }, 'tagname');
67 1         5 $p->utf8_mode(1);
68              
69 1         16 my $response = $ua->get($self->{uri} . $self->{username} . '/all');
70 1         472527 $p->parse($response->content);
71              
72 1 50       25 unless( $self->{login} ) {
73 0         0 croak 'Incorrect username';
74             }
75              
76             # Ignore the first array element which is undef, and return the rest of the elements
77 1         3 splice @{$self->{contents}}, 1, $number;
  1         113  
78             }
79              
80              
81             sub send {
82 0     0 1   my $self = shift;
83 0           my $message;
84              
85 0 0         unless( exists $self->{password} ) {
86 0           return $self->{login} = 0;
87             }
88              
89 0 0         if( @_ == 1 ) {
90             # Strip the message to 140 characters if the message is longer
91 0           $message = shift;
92 0 0         if(length $message > 140) {
93 0           $message = substr $message, 0, 140;
94             }
95             } else {
96 0           croak 'Invalid arguments';
97             }
98              
99             # Start sending messages
100 0           my $p = HTML::Parser->new(api_version => 3);
101 0     0     $p->handler(start => sub { $self->_start_handler(@_) }, 'self,tagname,attr');
  0            
102             $p->handler(end => sub {
103 0 0   0     return unless defined $self->{value};
104 0 0 0       return if $self->{value} eq 'content' && shift eq 'a';
105 0           $self->{value} = undef;
106 0           }, 'tagname');
107 0           $p->utf8_mode(1);
108              
109 0           my $response = $ua->post($self->{uri} . 'main/login', [nickname => $self->{username}, password => $self->{password}]);
110 0           $p->parse($response->content);
111              
112             # Return 0 if not logged in
113 0 0         return 0 unless $self->{login};
114 0           $response = $ua->post($self->{uri} . 'notice/new', [status_textarea => $message, returnto => 'all']);
115             }
116              
117              
118             sub _start_handler {
119 0     0     my $class = shift;
120 0           my $self = shift;
121              
122 0 0         return unless exists $_[1]->{class};
123              
124 0 0         if( $_[1]->{class} eq 'nickname' ) {
    0          
    0          
125 0           $class->{value} = 'nickname';
126 0           $class->{counter}++;
127             } elsif( $_[1]->{class} eq 'content' ) {
128 0           $class->{value} = 'content';
129             } elsif( $_[1]->{class} eq 'error' ) {
130 0           $class->{value} = 'error';
131             }
132              
133             $self->handler(text => sub {
134 0 0   0     return unless defined $class->{value};
135 0 0         if( $class->{value} eq 'content' ) {
    0          
    0          
136 0           $class->{contents}[$class->{counter}] .= shift;
137             } elsif( $class->{value} eq 'nickname' ) {
138 0           $class->{contents}[$class->{counter}] .= shift(@_) . ': ';
139             } elsif( $class->{value} eq 'error' ) {
140 0           my $error = shift;
141 0 0 0       if( $error eq 'Incorrect username or password.' || $error eq 'No such user.' ) {
142 0           $class->{login} = 0;
143             }
144             }
145 0           }, 'dtext');
146             }
147              
148             1;
149              
150             __END__