#!/usr/bin/ruby # cli interface to labanquepostale website # Y. Guillot 2007, WtfPLv2 require 'libhttpclient' # usage: # ./lbp.rb # ./lbp.rb la # ./lbp.rb la +500 # move 500e ccp -> la # list of count nrs CNTS = { 'la' => '0123456789Z', 'ccp' => '1234567Z123' } login, p = '1231234567Z', 'pass' # login = ccp[7, 3] + ccp[0, 7] to = 'ccp' to = ARGV.shift if CNTS.keys.include? ARGV.first amt = ARGV.shift.to_f h = HttpClient.new 'https://voscomptesenligne.labanquepostale.fr:443/' h.get "/voscomptes/canalXHTML/identif.ea?origin=portail&ident=#{login}&x=10&y=13" pd = h.post_allowed.first h.post pd.url, pd.vars.merge('username' => login, 'password' => p) begin h.get 'statique/index.jsp' h.get '../authentification/liste_contrat_atos.ea' h.get('/voscomptes/canalXHTML/releve/syntheseAssurancesEtComptes.ea') h.get('/voscomptes/canalXHTML/personnalisation/aiguillage/aiguillagePersonnalisation.ea') #h.get('liste_comptes.jsp') resume = h.curpage.get_text.gsub("\240", ' ').to_a puts resume if $VERBOSE resume -= resume.grep(/1 EUR = 6.55957|Le relev. de votre situation|Votre nouveau site|D.couvrez-le et visualisez|Nouveaut|alerte sur seuil|charge du client|charger gratuitement|Comptes courants|Euros .*Francs|Comptes .pargne|Gestion de compte par Internet|Encours pr.ts|^\s*$|Montant du capital|L'assureur ne s'engage|Contrats d'assurance|et si vous passiez|Acceder au service |directement depuis votre espace s.curis/i) resume = resume.join.gsub(/(-?\d?\d?\d(?: \d\d\d)*,\d\d)\s+(-?[\d ]+,\d\d)/, '\\1') puts resume, '' if amt != 0 # virement from = CNTS[to == 'ccp' ? 'la' : 'ccp' ] to = CNTS[to] || raise('bad dest') to, from = from, to if amt < 0 montant = '%.2f' % amt.abs h.referer = 'https://voscomptesenligne.labanquepostale.fr/voscomptes/canalXHTML/frame/navdroite/menugauche.jsp?n=1' h.get_url_allowed << '/voscomptes/canalXHTML/f_virementSafran.jsp' h.get '/voscomptes/canalXHTML/f_virementSafran.jsp?n=11' pg = h.get '/voscomptes/canalXHTML/virementsafran/aiguillage/saisieComptes.ea' curidx = fidx = tidx = curpart = nil pg.parse.each { |e| case e.type when 'select' case e['name'] when 'idxCompteEmetteur'; curpart = :frm when 'idxCompteReceveur'; curpart = :to end when '/select'; curpart = nil when 'option'; curidx = e['value'] when 'String' fidx = curidx if curpart == :frm and e['content'].include? from tidx = curidx if curpart == :to and e['content'].include? to end } raise 'noidx' if not fidx or not tidx pd = h.post_allowed.first pg = h.post pd.url, pd.vars.merge('idxCompteEmetteur' => fidx, 'idxCompteReceveur' => tidx) pd = h.post_allowed.first pg = h.post pd.url, pd.vars.merge('montant' => montant) puts pg.get_text sleep 3 href = curhref = nil pg.parse.each { |e| case e.type when 'a'; curhref = e['href'] when '/a'; curhref = nil when 'String'; href = curhref if e['content'] =~ /confirmer/i end } pg = h.get href puts pg.get_text h.referer = 'https://voscomptesenligne.labanquepostale.fr/voscomptes/canalXHTML/frame/navdroite/menugauche.jsp?n=1' h.get_url_allowed << '/voscomptes/canalXHTML/authentification/deconnexion.ea' h.get '/voscomptes/canalXHTML/authentification/deconnexion.ea' exit end # account summary (CCP only) compte = h.get("/voscomptes/canalXHTML/releve/releve_ccp.ea?compte.numero=#{CNTS[to]}&typeRecherche=10").get_text.gsub("'", "'") mvts = compte.to_a st = mvts.index(mvts.grep(/Date Libell.* Euros Francs/i).first) ed = mvts.index(mvts.grep(/1 Eur = 6,55957/i).first) mvts = mvts[st+1..ed-1] mvts.each_with_index { |nom, idx| nom.chomp! nom.strip! if (mnt = mvts.delete_at(idx+1)).to_s.reverse =~ /(\d\d,(?:\d\d\d\240)*\d\d?\d?-?)\s+(\d\d,(?:\d\d\d\240)*\d\d?\d?-?)(.*?)$/ anom, eur = $3.to_s.reverse, $2.reverse eur.gsub! "\240", ' ' eur = eur.rjust(eur.to_i > 0 ? 9 : 20) nom << ' ' << anom nom.gsub! "\240", ' ' nom.replace eur.ljust(24) + nom.strip else nom << ' ' << mnt.inspect end } puts mvts.reverse puts resume ensure h.referer = 'https://voscomptesenligne.labanquepostale.fr/voscomptes/canalXHTML/frame/navdroite/menugauche.jsp?n=1' h.get_url_allowed << '/voscomptes/canalXHTML/authentification/deconnexion.ea' h.get '/voscomptes/canalXHTML/authentification/deconnexion.ea' end # save the summary in a global history file File.open(File.expand_path('~/.ccp'), 'r+') { |fd| all = fd.read.to_a + mvts.reverse all.each { |l| l.chomp! ; l.chomp!(" ") } out = all.compact.uniq.sort_by { |l| ([$3.to_i, $2.to_i, $1.to_i, $4] if l =~ %r{(\d\d)/(\d\d?)/(\d\d\d\d) (.*)}).to_a } fd.pos = 0 fd.puts out fd.truncate fd.pos } if to == 'ccp' # save only main account history