File Coverage

blib/lib/WWW/SMS.pm
Criterion Covered Total %
statement 12 74 16.2
branch 0 26 0.0
condition 0 9 0.0
subroutine 4 8 50.0
pod 3 4 75.0
total 19 121 15.7


line stmt bran cond sub pod time code
1             #
2             # Copyright (c) 2001-2003
3             # Giulio Motta, Ivo Marino All rights reserved.
4             #
5             # http://www-sms.sourceforge.net/
6             #
7             # This program is free software; you can redistribute it and/or
8             # modify it under the same terms as Perl itself.
9             #
10              
11             package WWW::SMS;
12              
13 1     1   27946 use strict;
  1         2  
  1         41  
14 1     1   5 no strict 'refs';
  1         2  
  1         25  
15 1     1   5 use vars qw($VERSION $Error);
  1         5  
  1         155  
16              
17             $VERSION = '0.09';
18              
19 1     1   485 use Telephone::Number;
  1         2  
  1         936  
20              
21             my %RELIABILITY = (
22             Omnitel => 95, # Italian Gateway
23             Libero => 90, # Italian Gateway
24             Everyday => 85, # Italian Gateway
25             Gomobile => 80, # Swiss Gateway
26             Enel => 70, # Italian Gateway
27             Vizzavi => 50,
28             SFR => 50, # French Gateway
29             Beeline => 50, # Russian Gateway
30             MTS => 50,
31             LoopDE => 50, # German Gateway
32             GsmboxIT => 20,
33             GsmboxUK => 20, # UK Gateway
34             GsmboxDE => -1,
35             Clarence => 0,
36             GoldenTelecom => 0, # World Gateway
37             );
38              
39             sub new {
40 0     0 1   my ($self, $tn, $key, $value);
41 0           my $class = shift;
42 0 0 0       if ( (@_ > 2 ) && $_[2] =~ /^\d+$/) { # this suppose no %hash key is all numeric
43 0           $tn = Telephone::Number->new(shift, shift, shift);
44             } else {
45 0           $tn = Telephone::Number->new(shift);
46             }
47 0           my ($smstext, %hash) = @_;
48 0 0         $self = bless {
49             'tn' => $tn,
50             'whole_number' => $tn->whole_number(),
51             'smstext' => $smstext,
52             'cookie_jar' => exists $hash{cookie_jar} ?
53             delete $hash{cookie_jar} :
54             "lwpcookies.txt",
55             }, $class;
56 0           @{$self}{keys %{$tn}} = @{$tn}{keys %{$tn}};
  0            
  0            
  0            
  0            
57 0           @{$self}{keys %hash} = @hash{keys %hash}; #dragonchild suggestion
  0            
58 0           $self;
59             }
60              
61             sub send {
62 0     0 1   my ($sms, $gate) = @_;
63 0           my @PREFIXES;
64 0           my $gateway = "WWW::SMS::$gate";
65 0           eval "use $gateway";
66 0 0         if ($@) {
67 0           $Error = "No such a gateway available: $gate ($@)";
68 0           return;
69             }
70 0           @PREFIXES = @{ $gateway . '::PREFIXES' };
  0            
71 0 0         if (@PREFIXES) {
72 0           for (@PREFIXES) {
73 0 0         return &{ $gateway . '::_send'} ($sms)
  0            
74             if $sms->{tn}->fits($_);
75             }
76             } else {
77 0           return &{ $gateway . '::_send' } ($sms);
  0            
78             }
79 0           $Error = "Telephone number $sms->{whole_number} not compatible with $gate gateway";
80 0           return;
81             }
82              
83             sub send_sms { #for backward compatibility only
84 0     0 0   my ($class, $sms, $gate) = @_;
85 0           $sms->send($gate);
86             }
87              
88             sub gateways {
89 0     0 1   $_ = shift;
90 0 0         my $sms = ref $_ ? $_ : undef;
91 0           my %hash = @_;
92 0           my (@gates, @realgates, @PREFIXES, %seen);
93 0           my ($gate, $gateway);
94 0           for (@INC) {
95 0 0         opendir(DIR, "$_/WWW/SMS") || next;
96 0 0 0       push @gates, grep {
97 0           /^(.+)\.pm$/i and
98             !$seen{$1}++ and
99             $_ = $1
100             } readdir(DIR);
101 0           closedir(DIR);
102             }
103 0 0         if ($sms) {
104 0           for $gate (@gates) {
105 0           $gateway = "WWW::SMS::$gate";
106 0           eval "use $gateway";
107 0 0         print "$@" if ($@);
108 0           @PREFIXES = @{ $gateway . '::PREFIXES' };
  0            
109 0 0         if (@PREFIXES) {
110 0           for (@PREFIXES) {
111 0 0         if ( $sms->{tn}->fits($_) ) {
112 0           push @realgates, $gate;
113 0           last;
114             }
115             }
116             } else {
117 0           push @realgates, $gate;
118             }
119             }
120 0           @gates = @realgates;
121             }
122 0 0 0       if (%hash and $hash{sorted} eq 'reliability') {
123 0           @gates = sort {$RELIABILITY{$b} <=> $RELIABILITY{$a}} @gates;
  0            
124             }
125 0           return @gates;
126             }
127              
128              
129             1;
130              
131             =head1 NAME
132              
133             WWW::SMS - sends SMS using service provided by free websites
134              
135             =head1 SYNOPSIS
136              
137             use WWW::SMS;
138             my $sms = WWW::SMS->new(
139             '39', #international prefix
140             '333', #operator prefix
141             '1234567', #phone number
142             'This is a test.', #message text
143             username => 'abcde', #optional parameters
144             passwd => 'edcba' #in hash fashion
145             );
146              
147             #or now even just
148             my $sms = WWW::SMS->new($whole_number, $smstext);
149            
150             for ( $sms->gateways(sorted => 'reliability') ) {
151             #for every compatible gateway
152             if ($sms->send( $_ ) { #try to send sms
153             last; #until it succeds
154             } else {
155             print $WWW::SMS:Error; #here is the error
156             }
157             }
158              
159             =head1 DESCRIPTION
160              
161             B a Perl framework for sending free SMSs over the web.
162              
163             A new B object must be created with the I method.
164             Once created you can send it through one of the available submodules.
165              
166             =over
167              
168             =item WWW::SMS->new(INTPREFIX, OPPREFIX, PHONE_NUMBER, MESSAGETEXT [, OPTIONS]);
169              
170             =item WWW::SMS->new(WHOLE_NUMBER, MESSAGETEXT [, OPTIONS]);
171              
172             This is the default SMS object constructor.
173              
174             C is the international prefix:
175             some gateways just don't use the international prefix,
176             but put something in here anyway.
177              
178             C is the operator prefix
179              
180             C not much to say
181              
182             C the alternative constructor use the
183             the whole number of your cellphone: it includes international prefix
184             and operator prefix. It relies on the database in I
185             to split your number in its 3 basic parts.
186             So if unsure just use the "three-part-phone-number" constructor.
187              
188             C even here not much to say. Submodules are going to cut
189             the SMS to the maximum allowed length by the operator. You can check
190             anyway the maximum length directly looking for the I constant
191             in submodules.
192              
193             C are passed in a hash fashion. The useful ones to set include
194              
195             =over
196              
197             C your HTTP proxy
198              
199             C The file where to store cookies. If not set, every cookie goes
200             in the file "lwpcookies.txt" in your working directory.
201              
202             C and C Used by registration based gateways
203              
204             Other parameters may be required by specific submodules.
205              
206             =back
207              
208             =back
209              
210              
211             =head1 METHODS
212              
213             =over
214              
215             =item $sms->send(C)
216              
217             Sends C<$sms> using C: returns I<1> if succesfull, I<0> if
218             there are errors. The last error is in the C<$WWW::SMS::Error> variable.
219              
220             C the gateway you wish to use for sending the SMS: must be a scalar.
221              
222             =item gateways([OPTIONS])
223              
224             Scans @INC directories and returns an ARRAY containing the names
225             of the available gateway submodules. If used upon a SMS object
226             the submodules list returned is filtered by the PREFIX capability.
227             Like this:
228              
229             WWW::SMS->gateways(); #returns every available gateway
230              
231             $sms->gateways(); #returns just the gateways that can send $sms
232              
233             #compatible gateways sorted by reliability
234             $sms->gateways(sorted => 'reliability');
235            
236              
237             =back
238              
239             =head1 SUBMODULE GUIDELINES
240              
241             So, now you got WWW::SMS but what's next? Well, all that's cool about it
242             resides in submodules. A submodule got to do the dirty work of GETting and
243             POSTing webpages.
244             How to write a submodule then?
245             There are a few points to observe:
246              
247             =over
248              
249             =item 1 Take a look at submodules provided as example first!
250              
251             Yes, copying and pasting a submodule structure is a good start point.
252              
253             =item 2 sub MAXLENGTH
254              
255             Please set the EXPORTable constant C to what is the maximum length
256             of SMS the gateway you are scripting for allow.
257              
258             =item 3 @PREFIXES
259              
260             C<@PREFIXES> got to be an array of C objects.
261             C->new takes 3 parameters: each one can be a scalar
262             or an array reference.
263             Each scalar or element of referenced arrays is a regular expression.
264             Code will check for the phone number to match at least one of the regexp
265             for each of intpref, prefix and phone_number. If you don't have regexp
266             for one of these fields just give I to C->new.
267             Take a look at other submodules to better make up your mind.
268              
269             =item 4 Steps and $WWW::SMS::Error
270              
271             Do GETs and POSTs as you want, using other submodules as you like.
272             Just remember to mark each GET or POST with a increasing step number.
273             And when you got an error please set the error variable C<$WWW::SMS::Error>
274             to something useful and include the step number in it, so debugging will
275             be easier. Then I.
276             If everything goes alright just I.
277              
278             =item 5 Post your module back to the community!
279              
280             That's important, cause having a high available number of working gateways
281             is difficult (websites keep changing pretty fast) so everybody should
282             share his/her new & cool submodules implementation. Thank you.
283              
284             =back
285              
286             =head1 COPYRIGHT
287              
288             Copyright 2001-2003
289             Giulio Motta I
290             Ivo Marino I.
291              
292             Project page at http://www-sms.sourceforge.net/
293              
294             This library is free software; you can redistribute it and/or
295             modify it under the same terms as Perl itself.
296              
297             =cut