line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Finance::Bank::ABSA; |
2
|
1
|
|
|
1
|
|
15575
|
use strict; |
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
44
|
|
3
|
1
|
|
|
1
|
|
7
|
use Carp; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
113
|
|
4
|
|
|
|
|
|
|
our $VERSION = '0.03'; |
5
|
1
|
|
|
1
|
|
1243
|
use WWW::Mechanize; |
|
1
|
|
|
|
|
205888
|
|
|
1
|
|
|
|
|
45
|
|
6
|
1
|
|
|
1
|
|
14
|
use HTML::TokeParser; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
707
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
sub check_ABSA_balance { |
9
|
0
|
|
|
0
|
0
|
|
my ($class, %opts) = @_; |
10
|
0
|
|
|
|
|
|
my @accounts; |
11
|
0
|
0
|
|
|
|
|
croak "Must provide a security code" unless exists $opts{seccode}; |
12
|
0
|
0
|
|
|
|
|
croak "Must provide a banking id" unless exists $opts{bankingid}; |
13
|
0
|
0
|
|
|
|
|
croak "Must provide a password" unless exists $opts{mypassword}; |
14
|
|
|
|
|
|
|
|
15
|
0
|
|
|
|
|
|
my $self = bless { %opts }, $class; |
16
|
|
|
|
|
|
|
|
17
|
0
|
|
|
|
|
|
my $agent = WWW::Mechanize->new(); |
18
|
0
|
|
|
|
|
|
$agent->get("https://vs1.absa.co.za/ibs/UserAuthentication.do"); |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
# Filling in the login form. |
21
|
0
|
|
|
|
|
|
$agent->form("theForm"); |
22
|
0
|
|
|
|
|
|
$agent->field("AccessAccount", $opts{bankingid}); |
23
|
0
|
|
|
|
|
|
$agent->field("PIN", $opts{seccode}); |
24
|
0
|
|
|
|
|
|
$agent->click("button_processAuthenticate"); |
25
|
0
|
0
|
|
|
|
|
die unless ($agent->success); |
26
|
|
|
|
|
|
|
|
27
|
0
|
|
|
|
|
|
my @secletter = split(//, $opts{mypassword}); # put p/word into an array |
28
|
0
|
|
|
|
|
|
$agent->form("AuthPasswordForm"); |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
# Now comes to trickery to only provide the requested chars of password |
31
|
|
|
|
|
|
|
# Need to determine which of the input fields are class jc-pwdDgt |
32
|
|
|
|
|
|
|
# as input fields with class jc-pwdDgtDis aren't required for login |
33
|
|
|
|
|
|
|
# This is in order to not need to provide the whole password over the Net! |
34
|
0
|
0
|
|
|
|
|
my $testpwdDgt = HTML::TokeParser->new(\$agent->content) or die "$!"; |
35
|
0
|
|
|
|
|
|
$testpwdDgt->get_tag("form"); |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
# Go to first input field in form. |
38
|
0
|
|
|
|
|
|
my $pwdToken = $testpwdDgt->get_tag("input"); |
39
|
0
|
|
|
|
|
|
while ( $pwdToken->[1]{name} =~ /pwdDgt(\d+)/ ) # Step through all pwdDgt fields only |
40
|
|
|
|
|
|
|
# Setting $1 to the pwdDgt number |
41
|
|
|
|
|
|
|
{ |
42
|
0
|
0
|
|
|
|
|
if ( $pwdToken->[1]{class} eq "jc-pwdDgt" ) { # AHA - they want this char! |
43
|
0
|
|
|
|
|
|
$agent->field($pwdToken->[1]{name}, @secletter[$1]); |
44
|
|
|
|
|
|
|
} |
45
|
0
|
|
|
|
|
|
$pwdToken = $testpwdDgt->get_tag("input"); |
46
|
|
|
|
|
|
|
} |
47
|
|
|
|
|
|
|
|
48
|
0
|
|
|
|
|
|
$agent->click("button_processAuthPassword"); |
49
|
0
|
0
|
|
|
|
|
die unless ($agent->success); |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
# Now we have the data, we need to parse it. This is fragile. |
52
|
0
|
|
|
|
|
|
my $content = $agent->{content}; |
53
|
0
|
|
|
|
|
|
my ($split1, $split2) = split /\Balance Enquiries/, $content; |
54
|
0
|
|
|
|
|
|
my ($content, $split2) = split /Click on the account number for a statement/, $split2; |
55
|
|
|
|
|
|
|
|
56
|
0
|
0
|
|
|
|
|
my $stream = HTML::TokeParser->new(\$content) or die "$!"; |
57
|
0
|
|
|
|
|
|
$stream->get_tag("table"); |
58
|
0
|
|
|
|
|
|
$stream->get_tag("tr"); |
59
|
0
|
|
|
|
|
|
$stream->get_tag("tr"); |
60
|
0
|
|
|
|
|
|
$stream->get_tag("tr"); |
61
|
|
|
|
|
|
|
|
62
|
0
|
|
|
|
|
|
while (my $token = $stream->get_tag("tr")) { |
63
|
0
|
|
|
|
|
|
$token = $stream->get_tag("td"); |
64
|
0
|
0
|
|
|
|
|
if ($token->[1]{width} eq "5") { |
65
|
0
|
|
|
|
|
|
$stream->get_tag("td"); |
66
|
0
|
|
|
|
|
|
my $accountname = $stream->get_trimmed_text("/td"); |
67
|
0
|
|
|
|
|
|
$stream->get_tag("td"); |
68
|
0
|
|
|
|
|
|
my $accountnumber = $stream->get_trimmed_text("/td"); |
69
|
0
|
|
|
|
|
|
$stream->get_tag("td"); |
70
|
0
|
|
|
|
|
|
my $accountbalance = $stream->get_trimmed_text("/td"); |
71
|
0
|
|
|
|
|
|
my @strarray = split(//, $accountbalance); |
72
|
0
|
|
|
|
|
|
$stream->get_tag("td"); |
73
|
0
|
|
|
|
|
|
my $accountavailable = $stream->get_trimmed_text("/td"); |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
# Octal 240 is used from HTML3.2 spec to replace |
76
|
|
|
|
|
|
|
# See Entities.pm under your perl vendor tree |
77
|
|
|
|
|
|
|
# I choose to replace it here to easily/correctly cater for later formatting. |
78
|
0
|
|
|
|
|
|
$accountbalance =~ s/[, ]/./g; |
79
|
0
|
|
|
|
|
|
$accountbalance =~ s/\240//g; |
80
|
0
|
|
|
|
|
|
$accountavailable =~ s/[, ]/./g; |
81
|
0
|
|
|
|
|
|
$accountavailable =~ s/\240//g; |
82
|
0
|
|
|
|
|
|
$accountname =~ s/\240//g; |
83
|
|
|
|
|
|
|
|
84
|
0
|
|
|
|
|
|
push @accounts, { |
85
|
|
|
|
|
|
|
balance => $accountbalance, |
86
|
|
|
|
|
|
|
name => $accountname, |
87
|
|
|
|
|
|
|
available => $accountavailable, |
88
|
|
|
|
|
|
|
account => $accountnumber |
89
|
|
|
|
|
|
|
}; |
90
|
|
|
|
|
|
|
} |
91
|
|
|
|
|
|
|
} |
92
|
0
|
|
|
|
|
|
return @accounts; |
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
1; |
96
|
|
|
|
|
|
|
__END__ |