boursorama 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+