figo 1.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3133d62a73507bbdadc5bfc1a4090da15960f895
4
+ data.tar.gz: acb3d79e2d8870dba61f222bc36158050abab8db
5
+ SHA512:
6
+ metadata.gz: 8cb5a5c2ccd4483907c3304c2f842333ee033340f46b1ec23834b8d7c94039cd42fde6f413d7e8ee2a3bed9348722ab6eb63cc2259852ec91fc3152e6aed11c7
7
+ data.tar.gz: 31145565afb3cb72a68bf0705d3b26c31b56ed1595615e218034e33f7f96460fa96f188e966d44088a9713196b17eff9e2a81c0f8a5d78bf30a95e4dc650ca62
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ pkg
9
+ rdoc
10
+ spec/reports
11
+ test/tmp
12
+ test/version_tmp
13
+ tmp
14
+ Gemfile.lock
15
+
16
+ # YARD artifacts
17
+ .yardoc
18
+ _yardoc
19
+ doc/
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - jruby-19mode # JRuby in 1.9 mode
6
+ - rbx-19mode
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem "rake"
data/README.md ADDED
@@ -0,0 +1,41 @@
1
+ ruby-figo [![Build Status](https://secure.travis-ci.org/figo-connect/ruby-figo.png)](https://travis-ci.org/figo-connect/ruby-figo)
2
+ =========
3
+
4
+ Ruby bindings for the figo connect API: http://figo.me
5
+
6
+ Usage
7
+ =====
8
+
9
+ First, you've to install the gem
10
+
11
+ ```bash
12
+ gem install figo
13
+ ```
14
+
15
+ and require it
16
+
17
+ ```ruby
18
+ require "figo"
19
+ ```
20
+
21
+ Now you can create a new session and access data:
22
+
23
+ ```ruby
24
+ session = Figo::Session.new("ASHWLIkouP2O6_bgA2wWReRhletgWKHYjLqDaqb0LFfamim9RjexTo22ujRIP_cjLiRiSyQXyt2kM1eXU2XLFZQ0Hro15HikJQT_eNeT_9XQ")
25
+
26
+ # Print out a list of accounts.
27
+ session.accounts.each do |account|
28
+ puts account
29
+ puts account.balance
30
+ end
31
+
32
+ # Print out the list of all transactions of a specific account.
33
+ session.get_account("A1.2").transactions.each do |transaction|
34
+ puts transaction
35
+ end
36
+ ```
37
+
38
+ Requirements
39
+ ============
40
+
41
+ This gem requires Ruby 1.9.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new do |t|
4
+ t.libs << 'test'
5
+ end
6
+
7
+ desc "Run tests"
8
+ task :default => :test
data/figo.gemspec ADDED
@@ -0,0 +1,18 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "figo"
3
+ s.version = "1.0"
4
+ s.authors = ["Stefan Richter", "Michael Haller"]
5
+ s.email = ["stefan.richter@figo.me", "michael.haller@figo.me"]
6
+ s.homepage = "https://github.com/figo-connect/ruby-figo"
7
+ s.license = "MIT"
8
+ s.summary = %q{API wrapper for figo Connect.}
9
+ s.description = %q{Library to easily use the API of http://www.figo.me}
10
+
11
+ s.files = `git ls-files`.split("\n")
12
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
13
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
14
+ s.require_paths = ["lib"]
15
+
16
+ s.add_dependency "flt"
17
+ s.add_dependency "net-http-persistent"
18
+ end
data/lib/figo.rb ADDED
@@ -0,0 +1,243 @@
1
+ #
2
+ # Copyright (c) 2013 figo GmbH
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+
23
+ require "json"
24
+ require "logger"
25
+ require 'net/http/persistent'
26
+ require "digest/sha1"
27
+ require "./lib/models.rb"
28
+
29
+ $logger = Logger.new(STDOUT)
30
+
31
+ module Figo
32
+
33
+ API_ENDPOINT = "api.leanbank.com"
34
+
35
+ VALID_FINGERPRINTS = ["A6:FE:08:F4:A8:86:F9:C1:BF:4E:70:0A:BD:72:AE:B8:8E:B7:78:52",
36
+ "AD:A0:E3:2B:1F:CE:E8:44:F2:83:BA:AE:E4:7D:F2:AD:44:48:7F:1E"]
37
+
38
+ class Error < RuntimeError
39
+
40
+ def initialize(error, error_description) # :nodoc:
41
+ @error = error
42
+ @error_description = error_description
43
+ end
44
+
45
+ def to_s # :nodoc:
46
+ return @error_description
47
+ end
48
+
49
+ end
50
+
51
+ class HTTPS < Net::HTTP::Persistent # :nodoc:
52
+
53
+ def initialize(name = nil, proxy = nil)
54
+ super(name, proxy)
55
+
56
+ # Attribute ca_file must be set, otherwise verify_callback would never be called.
57
+ @ca_file = ""
58
+ @verify_callback = proc do |preverify_ok, store_context|
59
+ if preverify_ok and store_context.error == 0
60
+ certificate = OpenSSL::X509::Certificate.new(store_context.chain[0])
61
+ fingerprint = Digest::SHA1.hexdigest(certificate.to_der).upcase.scan(/../).join(":")
62
+ VALID_FINGERPRINTS.include?(fingerprint)
63
+ else
64
+ false
65
+ end
66
+ end
67
+ end
68
+
69
+ def request(uri, req = nil, &block)
70
+ response = super(uri, req, &block)
71
+
72
+ # Evaluate HTTP response.
73
+ case response
74
+ when Net::HTTPSuccess
75
+ return response
76
+ when Net::HTTPBadRequest
77
+ hash = JSON.parse(response.body)
78
+ raise Error.new(hash["error"], hash["error_description"])
79
+ when Net::HTTPUnauthorized
80
+ raise Error.new("unauthorized", "Missing, invalid or expired access token.")
81
+ when Net::HTTPForbidden
82
+ raise Error.new("forbidden", "Insufficient permission.")
83
+ when Net::HTTPNotFound
84
+ raise Error.new("not_found", "Requested object does not exist.")
85
+ when Net::HTTPMethodNotAllowed
86
+ raise Error.new("method_not_allowed", "Unexpected request method.")
87
+ when Net::HTTPServiceUnavailable
88
+ raise Error.new("service_unavailable", "Exceeded rate limit.")
89
+ else
90
+ $logger.warn("Querying the API failed when accessing '#{path}': #{response.code}")
91
+ raise Error.new("internal_server_error", "We are very sorry, but something went wrong.")
92
+ end
93
+ end
94
+
95
+ end
96
+
97
+ # Represents a non user-bound connection to the figo Connect API.
98
+ class Connection
99
+
100
+ # Create connection object with your client ID and client secret.
101
+ def initialize(client_id, client_secret, redirect_uri = nil)
102
+ @client_id = client_id
103
+ @client_secret = client_secret
104
+ @redirect_uri = redirect_uri
105
+ @https = HTTPS.new("figo-#{client_id}")
106
+ end
107
+
108
+ def query_api(path, data = nil) # :nodoc:
109
+ uri = URI("https://#{API_ENDPOINT}#{path}")
110
+ puts uri
111
+
112
+ # Setup HTTP request.
113
+ request = Net::HTTP::Post.new(path)
114
+ request.basic_auth(@client_id, @client_secret)
115
+ request["Content-Type"] = "application/x-www-form-urlencoded"
116
+ request['User-Agent'] = "ruby-figo"
117
+ request.body = URI.encode_www_form(data) unless data.nil?
118
+
119
+ # Send HTTP request.
120
+ response = @https.request(uri, request)
121
+
122
+ # Evaluate HTTP response.
123
+ return response.body == "" ? {} : JSON.parse(response.body)
124
+ end
125
+
126
+ # Get the URL a user should open in the web browser to start the login process.
127
+ def login_url(state, scope = nil)
128
+ data = { "response_type" => "code", "client_id" => @client_id, "state" => state }
129
+ data["redirect_uri"] = @redirect_uri unless @redirect_uri.nil?
130
+ data["scope"] = scope unless scope.nil?
131
+ return "https://#{API_ENDPOINT}/auth/code?" + URI.encode_www_form(data)
132
+ end
133
+
134
+ # Exchange authorization code or refresh token for access token.
135
+ def obtain_access_token(authorization_code_or_refresh_token, scope = nil)
136
+ # Authorization codes always start with "O" and refresh tokens always start with "R".
137
+ if authorization_code_or_refresh_token[0] == "O"
138
+ data = { "grant_type" => "authorization_code", "code" => authorization_code_or_refresh_token }
139
+ data["redirect_uri"] = @redirect_uri unless @redirect_uri.nil?
140
+ elsif authorization_code_or_refresh_token[0] == "R"
141
+ data = { "grant_type" => "refresh_token", "refresh_token" => authorization_code_or_refresh_token }
142
+ data["scope"] = scope unless scope.nil?
143
+ end
144
+ return query_api("/auth/token", data)
145
+ end
146
+
147
+ # Revoke refresh token or access token.
148
+ def revoke_token(refresh_token_or_access_token)
149
+ data = { "token" => refresh_token_or_access_token }
150
+ query_api("/auth/revoke?" + URI.encode_www_form(data))
151
+ return nil
152
+ end
153
+
154
+ end
155
+
156
+ # Represents a user-bound connection to the figo Connect API and allows access to the user's data.
157
+ class Session
158
+
159
+ # Create session object with access token.
160
+ def initialize(access_token)
161
+ @access_token = access_token
162
+ @https = HTTPS.new("figo-#{access_token}")
163
+ end
164
+
165
+ def query_api(path, data=nil, method="GET") # :nodoc:
166
+ uri = URI("https://#{API_ENDPOINT}#{path}")
167
+
168
+ # Setup HTTP request.
169
+ request = case method
170
+ when "POST"
171
+ Net::HTTP::Post.new(path)
172
+ when "PUT"
173
+ Net::HTTP::Put.new(path)
174
+ when "DELETE"
175
+ Net::HTTP::Delete.new(path)
176
+ else
177
+ Net::HTTP::Get.new(path)
178
+ end
179
+
180
+ request["Authorization"] = "Bearer #{@access_token}"
181
+ request["Content-Type"] = "application/json"
182
+ request['User-Agent'] = "ruby-figo"
183
+ request.body = JSON.generate(data) unless data.nil?
184
+
185
+ # Send HTTP request.
186
+ response = @https.request(uri, request)
187
+
188
+ # Evaluate HTTP response.
189
+ return response.body == "" ? {} : JSON.parse(response.body)
190
+ end
191
+
192
+ # Request list of accounts.
193
+ def accounts
194
+ response = query_api("/rest/accounts")
195
+ return response["accounts"].map {|account| Account.new(self, account)}
196
+ end
197
+
198
+ # Request specific account.
199
+ def get_account(account_id)
200
+ response = query_api("/rest/accounts/#{account_id}")
201
+ return Account.new(self, response)
202
+ end
203
+
204
+ # Request list of transactions.
205
+ def transactions(since = nil, start_id = nil, count = 1000, include_pending = false)
206
+ data = {}
207
+ data["since"] = (since.is_a?(Date) ? since.to_s : since) unless since.nil?
208
+ data["start_id"] = start_id unless start_id.nil?
209
+ data["count"] = count.to_s
210
+ data["include_pending"] = include_pending ? "1" : "0"
211
+ response = query_api("/rest/transactions?" + URI.encode_www_form(data))
212
+ return response["transactions"].map {|transaction| Transaction.new(self, transaction)}
213
+ end
214
+
215
+ # Request the URL a user should open in the web browser to start the synchronization process.
216
+ def sync_url(redirect_uri, state, disable_notifications = false, if_not_synced_since = 0)
217
+ data = { "redirect_uri" => redirect_uri, "state" => state, "disable_notifications" => disable_notifications, "if_not_synced_since" => if_not_synced_since }
218
+ response = query_api("/rest/sync", data, "POST")
219
+ return "https://#{API_ENDPOINT}/task/start?id=#{response["task_token"]}"
220
+ end
221
+
222
+ # Request list of registered notifications.
223
+ def notifications
224
+ response = query_api("/rest/notifications")
225
+ return response["notifications"].map {|notification| Notification.new(self, notification)}
226
+ end
227
+
228
+ # Register notification.
229
+ def add_notification(observe_key, notify_uri, state)
230
+ data = { "observe_key" => observe_key, "notify_uri" => notify_uri, "state" => state }
231
+ response = query_api("/rest/notifications", data, "POST")
232
+ return response["notification_id"]
233
+ end
234
+
235
+ # Unregister notification.
236
+ def remove_notification(notification_id)
237
+ query_api("/rest/notifications/#{notification_id}", nil, "DELETE")
238
+ return nil
239
+ end
240
+
241
+ end
242
+
243
+ end
data/lib/models.rb ADDED
@@ -0,0 +1,161 @@
1
+ #
2
+ # Copyright (c) 2013 figo GmbH
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+
23
+ require "date"
24
+ require "flt"
25
+
26
+ module Figo
27
+
28
+ # Set decimal precision to two digits.
29
+ Flt::DecNum.context.precision = 2
30
+
31
+ class AccountType
32
+ GIRO = "Giro account"
33
+ SAVINGS = "Savings account"
34
+ CREDIT_CARD = "Credit card"
35
+ LOAN = "Loan account"
36
+ PAYPAL = "PayPal"
37
+ UNKNOWN = "Unknown"
38
+ end
39
+
40
+ class TransactionType
41
+ TRANSFER = "Transfer"
42
+ STANDING_ORDER = "Standing order"
43
+ DIRECT_DEBIT = "Direct debit"
44
+ SALARY_OR_RENT = "Salary or rent"
45
+ ELECTRONIC_CASH = "Electronic cash"
46
+ GELDKARTE = "GeldKarte"
47
+ ATM = "ATM"
48
+ CHARGES_OR_INTEREST = "Charges or interest"
49
+ UNKNOWN = "Unknown"
50
+ end
51
+
52
+ class Base # :nodoc:
53
+
54
+ def initialize(session, hash)
55
+ @session = session
56
+
57
+ hash.each do |key, value|
58
+ if key == "status"
59
+ value = SynchronizationStatus.new(session, value)
60
+ elsif key == "amount" or key == "balance"
61
+ value = Flt::DecNum(value.to_s)
62
+ elsif key.end_with?("_date")
63
+ value = DateTime.iso8601(value)
64
+ elsif key.end_with?("_timestamp")
65
+ value = Date.iso8601(value)
66
+ end
67
+ instance_variable_set("@#{key}", value)
68
+ end
69
+ end
70
+
71
+ end
72
+
73
+ class Account < Base
74
+
75
+ attr_accessor :account_id
76
+ attr_accessor :bank_id
77
+ attr_accessor :name
78
+ attr_accessor :owner
79
+ attr_accessor :auto_sync
80
+ attr_accessor :account_number
81
+ attr_accessor :bank_code
82
+ attr_accessor :bank_name
83
+ attr_accessor :currency
84
+ attr_accessor :iban
85
+ attr_accessor :bic
86
+ attr_accessor :type
87
+ attr_accessor :icon
88
+ attr_accessor :in_total_balance
89
+ attr_accessor :preview
90
+ attr_accessor :status
91
+
92
+ # Request balance.
93
+ def balance
94
+ response = @session.query_api("/rest/accounts/#{@account_id}/balance")
95
+ return AccountBalance.new(@session, response)
96
+ end
97
+
98
+ # Request list of transactions.
99
+ def transactions(since = nil, start_id = nil, count = 1000, include_pending = false)
100
+ data = {}
101
+ data["since"] = (since.is_a?(Date) ? since.to_s : since) unless since.nil?
102
+ data["start_id"] = start_id unless start_id.nil?
103
+ data["count"] = count.to_s
104
+ data["include_pending"] = include_pending ? "1" : "0"
105
+ response = @session.query_api("/rest/accounts/#{@account_id}/transactions?" + URI.encode_www_form(data))
106
+ return response["transactions"].map {|transaction| Transaction.new(@session, transaction)}
107
+ end
108
+
109
+ end
110
+
111
+ class AccountBalance < Base
112
+
113
+ attr_accessor :balance
114
+ attr_accessor :balance_date
115
+ attr_accessor :credit_line
116
+ attr_accessor :monthly_spending_limit
117
+ attr_accessor :status
118
+
119
+ end
120
+
121
+ class Transaction < Base
122
+
123
+ attr_accessor :transaction_id
124
+ attr_accessor :account_id
125
+ attr_accessor :name
126
+ attr_accessor :account_number
127
+ attr_accessor :bank_code
128
+ attr_accessor :bank_name
129
+ attr_accessor :amount
130
+ attr_accessor :currency
131
+ attr_accessor :booking_date
132
+ attr_accessor :value_date
133
+ attr_accessor :purpose
134
+ attr_accessor :type
135
+ attr_accessor :booking_text
136
+ attr_accessor :booked
137
+ attr_accessor :creation_timestamp
138
+ attr_accessor :modification_timestamp
139
+ attr_accessor :visited
140
+
141
+ end
142
+
143
+ class SynchronizationStatus < Base
144
+
145
+ attr_accessor :code
146
+ attr_accessor :message
147
+ attr_accessor :sync_timestamp
148
+ attr_accessor :success_timestamp
149
+
150
+ end
151
+
152
+ class Notification < Base
153
+
154
+ attr_accessor :notification_id
155
+ attr_accessor :observe_key
156
+ attr_accessor :notify_uri
157
+ attr_accessor :state
158
+
159
+ end
160
+
161
+ end
data/test/test_figo.rb ADDED
@@ -0,0 +1,28 @@
1
+ #
2
+ # Copyright (c) 2013 figo GmbH
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+
23
+ require "test/unit"
24
+ require "figo"
25
+
26
+ class FigoTest < Test::Unit::TestCase
27
+
28
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: figo
3
+ version: !ruby/object:Gem::Version
4
+ version: "1.0"
5
+ platform: ruby
6
+ authors:
7
+ - Stefan Richter
8
+ - Michael Haller
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2013-06-04 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: flt
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - &id002
21
+ - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ type: :runtime
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: net-http-persistent
28
+ prerelease: false
29
+ requirement: &id003 !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - *id002
32
+ type: :runtime
33
+ version_requirements: *id003
34
+ description: Library to easily use the API of http://www.figo.me
35
+ email:
36
+ - stefan.richter@figo.me
37
+ - michael.haller@figo.me
38
+ executables: []
39
+
40
+ extensions: []
41
+
42
+ extra_rdoc_files: []
43
+
44
+ files:
45
+ - .gitignore
46
+ - .travis.yml
47
+ - Gemfile
48
+ - README.md
49
+ - Rakefile
50
+ - figo.gemspec
51
+ - lib/figo.rb
52
+ - lib/models.rb
53
+ - test/test_figo.rb
54
+ homepage: https://github.com/figo-connect/ruby-figo
55
+ licenses:
56
+ - MIT
57
+ metadata: {}
58
+
59
+ post_install_message:
60
+ rdoc_options: []
61
+
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - *id002
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - *id002
70
+ requirements: []
71
+
72
+ rubyforge_project:
73
+ rubygems_version: 2.0.3
74
+ signing_key:
75
+ specification_version: 4
76
+ summary: API wrapper for figo Connect.
77
+ test_files:
78
+ - test/test_figo.rb