| 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__ |