boursorama 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/LICENSE +13 -0
  2. data/README.md +49 -0
  3. data/lib/boursorama.rb +147 -0
  4. metadata +65 -0
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright (c) 2011 Mael Clerambault <mael@clerambault.fr>
2
+
3
+ Permission to use, copy, modify, and distribute this software for any
4
+ purpose with or without fee is hereby granted, provided that the above
5
+ copyright notice and this permission notice appear in all copies.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
@@ -0,0 +1,49 @@
1
+ API Ruby pour Boursorama
2
+ ========================
3
+
4
+ Ceci est une bibliothèque en Ruby pour accéder aux service de banque en ligne de [Boursorama](http://boursorama.com).
5
+
6
+ Pour accéder au code source : <http://github.com/hanklords/boursorama>
7
+
8
+ Utilisation
9
+ -----------
10
+
11
+ Voici comment utiliser la bibliothèque :
12
+
13
+ ### Connexion
14
+
15
+ require "boursorama"
16
+
17
+ boursorama = Boursorama.new('...Identifiant...', '...Mot de passe...')
18
+
19
+ ### Comptes
20
+
21
+ boursorama.accounts.each {|account|
22
+ puts account.name, account.number, account.total
23
+ }
24
+
25
+ ### Mouvements
26
+
27
+ Lister les mouvements sur le premier compte en décembre 2010 :
28
+
29
+ boursorama.accounts.first.mouvements(Time.new(2010, 12))
30
+
31
+ ### Relevés
32
+
33
+ Télécharger le dernier relevé de comptes :
34
+
35
+ boursorama.accounts.first.releves.each {|releve|
36
+ puts releve.name
37
+ File.open(releve.name, "w") {|f| f.write releve.body}
38
+ }
39
+
40
+ ### Téléchargements
41
+
42
+ Télécharger les mouvements en format texte :
43
+
44
+ boursorama.accounts.first.telechargement_creation
45
+ sleep 5 # Pause pour laisser le serveur traiter la demande...
46
+ boursorama.accounts.first.telechargements.each {|r|
47
+ puts r.name
48
+ File.open(r.name, "w") {|f| f.write r.body}
49
+ }
@@ -0,0 +1,147 @@
1
+ # encoding: UTF-8
2
+
3
+ require "net/http"
4
+ require "nokogiri"
5
+
6
+ class Boursorama
7
+ VERSION='0.1'
8
+
9
+ class Account
10
+ Mouvement = Struct.new(:date, :name, :type, :value)
11
+
12
+ class Releve
13
+ attr_reader :name
14
+ def initialize(session, name, url); @session, @name, @url = session, name, url end
15
+ def body; @session.get(@url).body end
16
+ end
17
+
18
+ class Telechargement
19
+ def initialize(session, bibliothequeAS400, fichierAS400, numeroMembre, nomFichier, numeroOrdre, isFichierDispo)
20
+ @session, @bibliothequeAS400, @fichierAS400, @numeroMembre, @nomFichier, @numeroOrdre, @isFichierDispo = session, bibliothequeAS400, fichierAS400, numeroMembre, nomFichier, numeroOrdre, isFichierDispo
21
+ end
22
+
23
+ def name; @nomFichier end
24
+ def body
25
+ @session.post(TELECHARGEMENT) {|req|
26
+ req.form_data = {
27
+ 'bibliothequeAS400' => @bibliothequeAS400,
28
+ 'fichierAS400' => @fichierAS400,
29
+ 'numeroMembre' => @numeroMembre,
30
+ 'nomFichier' => @nomFichier,
31
+ 'numeroOrdre' => @numeroOrdre,
32
+ 'isFichierDispo' => @isFichierDispo,
33
+ 'downloading' => "yes"
34
+ }
35
+ }.body
36
+ end
37
+ end
38
+
39
+ MOUVEMENTS = "/clients/comptes/banque/detail/mouvements.phtml"
40
+ RELEVES_COMPTES_AJAX = "/ajax/clients/comptes/ereporting/releves_comptes_ajax.php"
41
+ TELECHARGEMENT_CREATION = "/clients/comptes/banque/detail/telechargement_creation.phtml"
42
+ TELECHARGEMENT = "/clients/comptes/banque/detail/telechargement.phtml"
43
+
44
+ attr_reader :name, :number, :total
45
+ def initialize(session, node)
46
+ @session = session
47
+ @name = node.at("td.account-name a").text
48
+ @number = node.at("td.account-number").text.strip
49
+ @total = node.at("td.account-total span").text
50
+ # @url = node.at("td.account-name a")["href"]
51
+ end
52
+
53
+ def releves(endtime = nil, starttime = nil)
54
+ endtime ||= Time.new
55
+ starttime ||= endtime - 2678400
56
+ res = @session.post(RELEVES_COMPTES_AJAX) {|req|
57
+ req["X-Requested-With"] = "XMLHttpRequest"
58
+ req.form_data = {
59
+ 'univers' => "Banque", 'type_demande' => "", 'numero_compte' => @number,
60
+ 'starttime' => starttime.strftime("%d/%m/%Y"), 'endtime' => endtime.strftime("%d/%m/%Y")}
61
+ }
62
+
63
+ doc = Nokogiri::HTML(res.body, nil, "iso-8859-1")
64
+ doc.search("a").map {|r| Releve.new(@session, r.text.gsub("/", "\u2044"), r['href'])}
65
+ end
66
+
67
+ def telechargement_creation(endtime = nil, starttime = nil, formatFichier = "X")
68
+ endtime ||= Time.new
69
+ starttime ||= endtime - 2678400
70
+ res = @session.post(TELECHARGEMENT_CREATION) {|req|
71
+ req.form_data = {
72
+ 'formatFichier' => formatFichier,
73
+ 'periode1' => "choixUtilisateur",
74
+ 'startTime' => starttime.strftime("%d/%m/%Y"),
75
+ 'endTime' => endtime.strftime("%d/%m/%Y")
76
+ }
77
+ }
78
+ end
79
+
80
+ def telechargements
81
+ doc = Nokogiri::HTML(@session.get(TELECHARGEMENT).body)
82
+ doc.search("form[name='telechargement'] input[name='infos']").map {|i|
83
+ Telechargement.new(@session, *i["onclick"].scan(/'([\w\.]+)'/).flatten)
84
+ }
85
+ end
86
+
87
+ def mouvements(date = nil)
88
+ url = MOUVEMENTS
89
+ url += "?month=#{date.month}&year=#{date.year}" if date
90
+ doc = Nokogiri::HTML(@session.get(url).body)
91
+ doc.search("#customer-page tbody tr").map {|m|
92
+ tds = m.search("td")
93
+ next if tds.size == 0 or tds.size < 6
94
+ date, name, type, valuen, valuep = tds[0].text, tds[2].text.strip, tds[2].at("div")["title"], tds[3].text, tds[4].text
95
+ date = Time.new(*date.split("/").reverse)
96
+ value = valuen.empty? ? valuep : valuen
97
+ value = value.gsub(/[^0-9,-]/,'').sub(",", ".").to_f
98
+ type.sub!("Nature de l'opération : ", "")
99
+ Mouvement.new date, name, type, value
100
+ }.compact
101
+ end
102
+ end
103
+
104
+ HOST = "www.boursorama.com"
105
+ LOGIN = "/logunique.phtml"
106
+ SYNTHESE = "/clients/synthese.phtml"
107
+ USER_AGENT = "boursorama.rb/#{VERSION}"
108
+
109
+ def get(url)
110
+ http = Net::HTTP.new(HOST, 443)
111
+ http.use_ssl = true
112
+ req = Net::HTTP::Get.new(url)
113
+ req["User-Agent"] = USER_AGENT
114
+ req["Cookie"] = @cookies.map {|k,v| "#{k}=#{v}"}.join("; ")
115
+
116
+ http.request(req)
117
+ end
118
+
119
+ def post(url)
120
+ http = Net::HTTP.new(HOST, 443)
121
+ http.use_ssl = true
122
+ req = Net::HTTP::Post.new(url)
123
+ req["User-Agent"] = USER_AGENT
124
+ req["Cookie"] = @cookies.map {|k,v| "#{k}=#{v}"}.join("; ") if @cookies
125
+ yield req if block_given?
126
+
127
+ http.request(req)
128
+ end
129
+
130
+ def login(user, password)
131
+ @cookies = nil
132
+ res = post(LOGIN) {|req| req.form_data = {'login' => user, 'password' => password}}
133
+ @cookies = Hash[*res.get_fields("set-cookie").map {|c| c.sub(/;.*$/, "").split("=") }.flatten]
134
+ end
135
+
136
+ def initialize(user, password)
137
+ login(user, password)
138
+
139
+ @synthese = Nokogiri::HTML(get(SYNTHESE).body)
140
+ end
141
+
142
+ def inspect; "#<#{self.class}:0x#{object_id}>" end
143
+
144
+ def accounts
145
+ @synthese.search("#synthese-list tr.L10").map {|acc| Account.new(self, acc) }
146
+ end
147
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: boursorama
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ version: "0.1"
9
+ platform: ruby
10
+ authors:
11
+ - "Ma\xC3\xABl Cl\xC3\xA9rambault"
12
+ autorequire:
13
+ bindir: bin
14
+ cert_chain: []
15
+
16
+ date: 2011-02-14 00:00:00 +01:00
17
+ default_executable:
18
+ dependencies: []
19
+
20
+ description:
21
+ email: mael@clerambault.fr
22
+ executables: []
23
+
24
+ extensions: []
25
+
26
+ extra_rdoc_files: []
27
+
28
+ files:
29
+ - lib/boursorama.rb
30
+ - LICENSE
31
+ - README.md
32
+ has_rdoc: true
33
+ homepage: http://hanklords.github.com/boursorama
34
+ licenses: []
35
+
36
+ post_install_message:
37
+ rdoc_options: []
38
+
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ segments:
47
+ - 0
48
+ version: "0"
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ segments:
55
+ - 0
56
+ version: "0"
57
+ requirements: []
58
+
59
+ rubyforge_project:
60
+ rubygems_version: 1.3.7
61
+ signing_key:
62
+ specification_version: 3
63
+ summary: Boursorama Ruby API
64
+ test_files: []
65
+