File Coverage

blib/lib/yesssSMS.pm
Criterion Covered Total %
statement 17 190 8.9
branch 0 78 0.0
condition 0 27 0.0
subroutine 6 21 28.5
pod 9 14 64.2
total 32 330 9.7


line stmt bran cond sub pod time code
1             package yesssSMS;
2              
3 1     1   67634 use 5.014002;
  1         4  
4 1     1   5 use strict;
  1         3  
  1         20  
5 1     1   13 use warnings;
  1         3  
  1         37  
6 1     1   602 use HTML::Parser;
  1         5883  
  1         39  
7 1     1   725 use LWP::UserAgent;
  1         48769  
  1         38  
8 1     1   620 use HTTP::Cookies;
  1         6745  
  1         2144  
9              
10              
11             require Exporter;
12              
13             our @ISA = qw(Exporter);
14              
15             # Items to export into callers namespace by default. Note: do not export
16             # names by default without a very good reason. Use EXPORT_OK instead.
17             # Do not simply export all your public functions/methods/constants.
18              
19             # This allows declaration use yesssSMS ':all';
20             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
21             # will save memory.
22             our %EXPORT_TAGS = ( 'all' => [ qw(
23            
24             ) ] );
25              
26             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
27              
28             our @EXPORT = qw(
29            
30             );
31              
32             our $VERSION = '2.12';
33              
34             sub new
35             {
36 0     0 1   my $self = {};
37 0           $self->{LOGINSTATE} = 0;
38 0           $self->{URL}="https://www.yesss.at/kontomanager.at/";
39              
40 0           bless ($self);
41 0           return $self;
42             }
43              
44             sub login
45             {
46 0     0 1   my $self = shift;
47 0           my $phoneParser;
48              
49             ($self->{TELNR},
50 0           $self->{PASS})=@_;
51              
52             # don't login if logged in...
53 0 0         if ($self->{LOGINSTATE} == 1)
54             {
55 0           $self->{LASTERROR}='Cannot login when already logged in';
56 0           $self->{RETURNCODE}=1;
57 0           return 1;
58             }
59              
60             # Cookies are needed
61 0           $self->{UA} = LWP::UserAgent->new;
62 0           $self->{UA}->cookie_jar(HTTP::Cookies->new);
63              
64             # go to start page
65 0           $self->{CONTENT}=$self->{UA}->get($self->{URL});
66              
67             # if there was an error on the start page, stop
68 0 0         if (!($self->{CONTENT}->is_success))
69             {
70 0           $self->{LASTERROR}='Error loading startpage of YESSS!';
71 0           $self->{RETURNCODE}=2;
72 0           return 2;
73             }
74              
75             # do the login post
76 0           $self->{CONTENT}=$self->{UA}->post($self->{URL}."index.php",{'login_rufnummer' => $self->{TELNR},'login_passwort' => $self->{PASS}});
77              
78             # successful login results in redirect
79 0 0         if (!($self->{CONTENT}->is_redirect))
80             {
81 0           $self->{LASTERROR}='Error sending credentials!';
82 0           $self->{RETURNCODE}=3;
83 0           return 3;
84             }
85              
86             # usually, a redirect is replied
87 0           while ($self->{CONTENT}->is_redirect)
88             {
89             # follow redirect
90 0           $self->{CONTENT}=$self->{UA}->post($self->{CONTENT}->header("Location"),{'login_rufnummer' => $self->{TELNR},'login_passwort' => $self->{PASS}});
91              
92             # if there was an error during redirect, stop
93 0 0         if (!($self->{CONTENT}->is_success))
94             {
95 0           $self->{LASTERROR}='Error during post-login redirect';
96 0           $self->{RETURNCODE}=4;
97 0           print $self->{CONTENT}->status_line;
98 0           return 4;
99             }
100             }
101              
102             # parse interesting values
103 0           $phoneParser=HTML::Parser->new(api_version=>3,
104             start_h => [\&loginStartTagParse, "self,tagname,attr"],
105             text_h => [\&loginTextParse, "self, text"],
106             end_h => [\&loginEndTagParse, "self, tagname"]
107             );
108             # bring my "self" into the handlers without global vars
109             # delete possible existing subscriptions
110             # initialize some variables needed for the parser
111 0           undef($self->{SUBSCRIPTIONS});
112 0           $phoneParser->{'yesssSMSself'}=$self;
113 0           $phoneParser->{'inSubscriber'}=0;
114 0           $phoneParser->{'inProgresslist'}=0;
115 0           $phoneParser->{'inProgressheading'}=0;
116 0           $phoneParser->{'amountSubscriptions'}=0;
117 0           $phoneParser->{'amountItems'}=0;
118 0           $phoneParser->parse($self->{CONTENT}->decoded_content);
119              
120             # print found phone numbers and their values
121              
122 0           $self->{LOGINSTATE}=1;
123 0           $self->{LASTERROR}='Login successful';
124 0           $self->{RETURNCODE}=0;
125 0           return 0;
126             }
127              
128             sub selectPhonenumber
129             {
130 0     0 0   my $self = shift;
131 0           my ($telnr)=@_;
132 0           my $phoneParser;
133              
134             # switching is only possible after login
135 0 0         if ($self->{LOGINSTATE} == 0)
136             {
137 0           $self->{LASTERROR}='Not logged in while trying to select phonenumber';
138 0           $self->{RETURNCODE}=1;
139 0           return 1;
140             }
141              
142             # check, if the requested phonenumber is valid
143 0 0         if (! defined($self->{SUBSCRIBERS}->{$telnr}))
144             {
145 0           $self->{LASTERROR}='Requested phonenumber not available in account';
146 0           $self->{RETURNCODE}=6;
147 0           return 6;
148             }
149              
150             $self->{CONTENT}=$self->{UA}->post($self->{URL}."kundendaten.php",
151             {
152 0           'subscriber' => $self->{SUBSCRIBERS}->{$telnr},
153             'groupaction' => 'change_subscriber'
154             }
155             );
156              
157             # stop on error
158 0 0         if (!($self->{CONTENT}->is_success))
159             {
160 0           $self->{LASTERROR}='Error while selecting phonenumber';
161 0           $self->{RETURNCODE}=7;
162 0           return 7;
163             }
164              
165             # parse interesting values
166 0           $phoneParser=HTML::Parser->new(api_version=>3,
167             start_h => [\&loginStartTagParse, "self,tagname,attr"],
168             text_h => [\&loginTextParse, "self, text"],
169             end_h => [\&loginEndTagParse, "self, tagname"]
170             );
171             # bring my "self" into the handlers without global vars
172 0           undef($self->{SUBSCRIPTIONS});
173 0           $phoneParser->{'yesssSMSself'}=$self;
174 0           $phoneParser->{'inSubscriber'}=0;
175 0           $phoneParser->{'inProgresslist'}=0;
176 0           $phoneParser->{'inProgressheading'}=0;
177 0           $phoneParser->{'amountSubscriptions'}=0;
178 0           $phoneParser->{'amountItems'}=0;
179 0           $phoneParser->parse($self->{CONTENT}->decoded_content);
180              
181            
182             }
183              
184             sub sendmessage
185             {
186 0     0 1   my $self = shift;
187 0           my ($telnr,$message)=@_;
188              
189             # only send message when login was successful
190 0 0         if ($self->{LOGINSTATE} == 0)
191             {
192 0           $self->{LASTERROR}='Not logged in while trying to send a message';
193 0           $self->{RETURNCODE}=1;
194 0           return 1;
195             }
196              
197             #if (length($message)>160)
198             #{
199             # $self->{LASTERROR}='Shortmessage too long';
200             # $self->{RETURNCODE}=2;
201             # return 2;
202             #}
203 0 0 0       if (!($telnr=~/^00/) || (length($telnr)<14))
204             {
205 0           $self->{LASTERROR}='Invalid destination (not Austria or too short)';
206 0           $self->{RETURNCODE}=3;
207 0           return 3;
208             }
209              
210             # go to correct menu item
211 0           $self->{CONTENT}=$self->{UA}->post($self->{URL}."websms.php");
212              
213             # stop on error
214 0 0         if (!($self->{CONTENT}->is_success))
215             {
216 0           $self->{LASTERROR}='Error while selecting SMS menu';
217 0           $self->{RETURNCODE}=4;
218 0           return 4;
219             }
220              
221             # try to send message
222 0           $self->{CONTENT}=$self->{UA}->post($self->{URL}."websms_send.php",{'to_netz' => 'a','to_nummer' => $telnr,'nachricht' => $message});
223              
224             # stop on error
225 0 0         if (!($self->{CONTENT}->is_success))
226             {
227 0           $self->{LASTERROR}='Error while sending message';
228 0           $self->{RETURNCODE}=5;
229 0           return 5;
230             }
231              
232 0           $self->{LASTERROR}='Message sent successfully';
233 0           $self->{RETURNCODE}=0;
234 0           return 0;
235             }
236              
237             sub getLoginstate
238             {
239 0     0 1   my $self = shift;
240            
241 0           return $self->{LOGINSTATE};
242             }
243              
244             sub logout
245             {
246 0     0 1   my $self = shift;
247              
248             # don't logout if not logged in...
249 0 0         if ($self->{LOGINSTATE} == 0)
250             {
251 0           $self->{LASTERROR}='Cannot logout when not logged in.';
252 0           $self->{RETURNCODE}=1;
253 0           return 1;
254             }
255              
256             # post the logout url
257 0           $self->{CONTENT}=$self->{UA}->post($self->{URL}."index.php?dologout=1");
258              
259             # if there was an error during logout, stop
260 0 0         if (!($self->{CONTENT}->is_success))
261             {
262 0           $self->{LASTERROR}='Error during logout.';
263 0           $self->{RETURNCODE}=2;
264 0           return 2;
265             }
266              
267             # reset LOGINSTATE
268 0           $self->{LOGINSTATE}=0;
269 0           $self->{LASTERROR}='Logout successful';
270 0           $self->{RETURNCODE}=0;
271 0           return 0;
272             }
273              
274             sub getLastResult
275             {
276 0     0 1   my $self = shift;
277              
278 0           return $self->{RETURNCODE};
279             }
280              
281             sub getLastError
282             {
283 0     0 1   my $self = shift;
284              
285 0           return $self->{LASTERROR};
286             }
287              
288             sub getContent
289             {
290 0     0 1   my $self = shift;
291              
292 0           return $self->{CONTENT};
293             }
294              
295             sub getSubscriptions
296             {
297 0     0 1   my $self = shift;
298              
299 0           return $self->{SUBSCRIPTIONS};
300             }
301              
302             sub DESTROY
303             {
304 0     0     my $self = shift;
305 0 0         if ($self->{LOGINSTATE}==1)
306             {
307 0           $self->logout();
308             }
309             }
310              
311              
312             ####### methods for parser
313             # login/switch phone number
314             sub loginStartTagParse
315             {
316 0     0 0   my ($self, $tagname, $attr) = @_;
317              
318 0 0 0       if (($self->{'inSubscriber'} != 1) &&
    0          
    0          
319             ($self->{'inProgresslist'} < 1))
320             {
321 0 0 0       if (($tagname eq 'select') &&
    0 0        
      0        
322             ($attr->{'id'} eq 'subscriber'))
323             {
324 0           $self->{'inSubscriber'}=1;
325             }
326             elsif (($tagname eq 'div') &&
327             (defined ($attr->{'class'})) &&
328             ($attr->{'class'} eq 'progress-list'))
329             {
330 0           $self->{'inProgresslist'}++;
331             }
332             }
333             elsif ($self->{'inSubscriber'} == 1)
334             {
335 0 0         if ($tagname eq 'option')
336             {
337 0           $self->{'lastValue'}=$attr->{'value'};
338             }
339             }
340             elsif ($self->{'inProgresslist'} >= 1)
341             {
342 0 0         if ($tagname eq 'div')
343             {
344 0 0         if ($attr->{'class'} eq 'info-list-item')
    0          
345             {
346 0           $self->{'inProgresslist'}=0;
347 0           $self->{'amountItems'}=0;
348             }
349             elsif ($attr->{'class'} eq 'progress-item')
350             {
351 0           $self->{'amountItems'}++;
352 0           $self->{'inProgresslist'}++;
353             }
354             else
355             {
356 0           $self->{'inProgresslist'}++;
357             }
358             }
359 0 0         if ($tagname eq 'h3')
360             {
361 0 0 0       if ((defined($attr->{'id'})) &&
362             ($attr->{'id'} eq 'kostenkontrolle'))
363             {
364             # we ignore 'Kostenkontrolle'
365 0           $self->{'inProgresslist'}=0;
366 0           $self->{'amountItems'}=0;
367             }
368             else
369             {
370 0           $self->{'inProgressheading'}=1;
371             }
372             }
373             }
374             }
375              
376             sub loginTextParse
377             {
378 0     0 0   my ($self, $text) = @_;
379 0           my $phonenumber;
380             my $progressname;
381 0           my $progresstype;
382 0           my $value;
383              
384 0           &trim(\$text);
385 0 0 0       if (($self->{'inSubscriber'} == 1) &&
    0 0        
    0 0        
386             (length($text)>1))
387             {
388 0           ($phonenumber)=$text=~/^([0-9]+)[^0-9]/;
389 0           $self->{'yesssSMSself'}->{SUBSCRIBERS}->{$phonenumber}=$self->{'lastValue'};
390             }
391             elsif (($self->{'inProgressheading'} == 1) &&
392             (length($text)>1))
393             {
394 0           ($progressname,$progresstype)=$text=~/Ihr (.*) ([^\s]*):$/;
395 0           $self->{'amountSubscriptions'}++;
396 0           $self->{'yesssSMSself'}->{SUBSCRIPTIONS}->[$self->{'amountSubscriptions'}-1]->{'name'}=$progressname;
397 0 0         if ($progresstype eq 'Guthaben')
398             {
399 0           $progresstype='Paket';
400             }
401 0           $self->{'yesssSMSself'}->{SUBSCRIPTIONS}->[$self->{'amountSubscriptions'}-1]->{'type'}=$progresstype;
402             }
403             elsif (($self->{'inProgresslist'} >= 1) &&
404             (length($text)>1))
405             {
406 0 0         if ($text=~/^[0-9]+\s/)
    0          
    0          
407             {
408 0           ($value)=$text=~/^[0-9]+\s(.+)$/;
409             $self->{'yesssSMSself'}->{SUBSCRIPTIONS}->
410 0           [$self->{'amountSubscriptions'}-1]->{'items'}->[$self->{'amountItems'}-1]->{'unit'}=$value;
411             }
412             elsif ($text=~/^Verbraucht/)
413             {
414 0           ($value)=$text=~/^Verbraucht: ([0-9]+)$/;
415             $self->{'yesssSMSself'}->{SUBSCRIPTIONS}->
416 0           [$self->{'amountSubscriptions'}-1]->{'items'}->[$self->{'amountItems'}-1]->{'used'}=$value;
417             }
418             elsif ($text=~/^Verbleibend/)
419             {
420 0           ($value)=$text=~/^Verbleibend: ([0-9]+)$/;
421             $self->{'yesssSMSself'}->{SUBSCRIPTIONS}->
422 0           [$self->{'amountSubscriptions'}-1]->{'items'}->[$self->{'amountItems'}-1]->{'remaining'}=$value;
423             }
424             }
425             }
426              
427             sub loginEndTagParse
428             {
429 0     0 0   my ($self, $tagname) = @_;
430              
431 0 0         if ($self->{'inSubscriber'} == 1)
    0          
432             {
433 0 0         if ($tagname eq 'select')
434             {
435 0           $self->{'inSubscriber'}=0;
436             }
437             }
438             elsif ($self->{'inProgresslist'} >= 1)
439             {
440 0 0         if ($tagname eq 'div')
441             {
442 0           $self->{'inProgresslist'}--;
443 0 0         if ($self->{'inProgresslist'} == 0)
444             {
445 0           $self->{'amountItems'}=0;
446             }
447             }
448 0 0         if ($self->{'inProgressheading'} == 1)
449             {
450 0 0         if ($tagname eq 'h3')
451             {
452 0           $self->{'inProgressheading'}=0;
453             }
454             }
455             }
456             }
457              
458             sub trim
459             {
460 0     0 0   my $string=$_[0];
461              
462 0           $$string =~ s/^\s+//;
463 0           $$string =~ s/\s+$//;
464             }
465              
466             1;
467             __END__