#!/usr/bin/perl # login to a bank and check balance use strict; use Perl6::Slurp; use JSON::XS (); # import nothing use Template::Simple; use CGI::Minimal; use Date::Format; use CGI::Carp; # to get the timestamps in the error log use lib '/home/ilia/byob/perllib'; use Finance::Bank::PC; use Finance::Bank::CIBC; use constant CACHE_PATH => '/home/ilia/byob/pages/cache'; my $SCRIPT_NAME = "check_balance.pl"; my $json_parser = JSON::XS->new->ascii(); # get the configuration (bank card numbers and passwords) my $credentials_json = slurp('/home/ilia/.byob/credentials.json'); my $credentials = $json_parser->decode($credentials_json); # receive global cgi parameters my $cgi = CGI::Minimal->new(); exit if ($cgi->truncated); my $action = $cgi->param('action'); my $bank_name = $cgi->param('bank'); # setup templates my $tmpl = Template::Simple->new(); my $template_accounts = < [%bank_name%] - as of [%mtime%]
Account Name
Available
Posted
[%START row%] [%name%] [%available%] [%posted%] [%END row%] TMPL_ACCOUNTS my $template_details = < [%bank_name%] - [%account_name%] - as of [%timestamp%] Date Info Debit Credit [%START row%] [%date%] [%info%] [%debit%] [%credit%] [%END row%] TMPL_DETAILS # let the action begin my $bank; my %common_props = ( bank_id => $bank_name, cache_path => CACHE_PATH ); #$common_props{cache_expiry} = 0; # DEBUG: force use cache # try to instantiate bank # bank_name is bank class followed by dash and bank id eval { my ($bank_class) = split /-/, $bank_name; $bank_class = uc $bank_class; $bank_class = "Finance::Bank::$bank_class"; $bank = $bank_class->new( { %common_props, card_number => $credentials->{uc $bank_name}->{CARD_NUMBER}, password=> $credentials->{uc $bank_name}->{PASSWORD}, } ); }; if ( $@ ) { warn_to_screen("unknown bank_name: $bank_name. "); exit; } my $action_map = { 'all' => \&send_all, 'accounts_json' => \&send_accounts_json, 'details_json' => \&send_details_json, 'accounts' => \&send_accounts, 'details' => \&send_details, }; my $sub = $action_map->{ $cgi->param('action') } || \&send_unknown_action; $sub->(); sub send_all { # send account details as JSON in the X-JSON header and all the accounts as HTML my $accounts = $bank->accounts(); my $mtime = $bank->get_cache_mtime_for_accounts(); my $details_per_account = {}; foreach my $account ( @$accounts ) { $details_per_account->{$account->{name}} = $bank->details($account->{name}); } print_json_header($details_per_account); print_accounts($accounts, { mtime => $mtime, login_link => $bank->{config}->{LOGIN_FORM_URL} }); } sub send_accounts_json { my $accounts = $bank->accounts(); print_headers({'Content-type'=>'application/x-json'}); print_json($accounts); } sub send_details_json { my $account_name = $cgi->param('account_name'); my $details = $bank->details($account_name); print_headers({'Content-type'=>'application/x-json'}); print_json($details); } sub send_accounts { print_accounts($bank->accounts()); } sub send_details { my $account_name = $cgi->param('account_name'); print_details($bank->details($account_name), $account_name); } sub send_unknown_action { warn_to_screen("unknown action: $action"); exit; } sub print_accounts { # accounts is an arrayref my ($accounts, $extra_data) = @_; print_generic($accounts, $template_accounts, $extra_data); } sub print_details { # details is an arrayref of hashrefs my ($details, $account_name) = @_; print_generic($details, $template_details, { account_name => $account_name }); } sub print_generic { my ($rows, $template, $extra_data) = @_; $extra_data ||= {}; my $timestamp = timestamp(); my $data = { row => $rows, bank_name => uc($bank_name), timestamp => $timestamp, %$extra_data, }; my $rendered = $tmpl->render($template, $data); print_headers(); print $$rendered; } sub to_json { my ($struct) = @_; return $json_parser->encode($struct); } sub print_json_header { my ($struct) = @_; print 'X-JSON: ' . to_json($struct) . "\n"; } sub print_json { my ($struct) = @_; print to_json($struct) . "\n"; } sub timestamp { my @lt = localtime(time); return strftime('%Y-%m-%d %T', @lt), } sub print_headers { my $args = shift; my $headers = {}; $headers->{'Content-type'} = $args->{'Content-type'} || 'text/html'; print "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0, max-age=0\n"; print "Pragma: no-cache\n"; print "Expires: Thu, 01 Jan 1970 00:00:00 GMT\n"; #print "Content-type: text/html; charset=utf-8\n\n"; print "Content-type: $headers->{'Content-type'}\n\n"; } sub warn_to_screen { print_headers(); print @_; }