life-api 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: da009a2372ce299d656a0cdb99331a4c91c75e23
4
+ data.tar.gz: 4c956cdb158ab68669badb15bba6480ba9e8e824
5
+ SHA512:
6
+ metadata.gz: a4a8acdc289d333e7f19f2fb7300b7bbe570da378d132a70edc77b1c15d13aa6706b37f6634efbe26600544e903b4ef8d610a26bd87ad1a4447d244e84e39a78
7
+ data.tar.gz: 70c680fd0ba26ed01ec0cb403c75949dc9c161806d46046dce8dd8d994d25327a2c6c87d2461ec5054212cf1dfc4e50d027adad64263e1a530ea5de051424c7a
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in life-api.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Anton Maminov
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,207 @@
1
+ # Life::API
2
+
3
+ A Ruby library for interfacing with life:)'s undocumented/unannounced API.
4
+
5
+ [life:)](http://life.com.ua) — GSM operator in Ukraine.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```
12
+ gem 'life-api'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ ```
18
+ $ bundle
19
+ ```
20
+
21
+ Or install it yourself as:
22
+
23
+ ```
24
+ $ gem install life-api
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ First of all require the `life-api` library.
30
+
31
+ ```ruby
32
+ require 'life-api'
33
+ ```
34
+
35
+ ### Authentication
36
+
37
+ You can authenticate with life:) in two ways: with password or with token.
38
+
39
+ Authentication with password to the life:) API is accomplished using a phone number(`msisdn`) starting with a plus sign ("+") and the country code("380"), and SuperPassword(`password`).
40
+
41
+ ```ruby
42
+ life = Life::API.new(msisdn: msisdn, password: password)
43
+ life.sign_in
44
+ token = life.token
45
+ sub_id = life.sub_id
46
+ ```
47
+
48
+ > To obtain the SuperPassword send an SMS with key word PASSWORD to number 125, or enter life:) menu by dialing `*125#`, choose Manage account and then SuperPassword service or call `*125*779#`.
49
+
50
+ or
51
+
52
+ ```ruby
53
+ life = Life::API.new
54
+ life.token = token
55
+ life.sub_id = sub_id
56
+ ```
57
+
58
+ Now you can make requests to the API.
59
+
60
+ ### API Examples
61
+
62
+ Below you can see some the methods for working with life:) data.
63
+
64
+ #### Returns advanced information on the current subscriber
65
+ ```
66
+ life.get_summary_data
67
+ ```
68
+
69
+ Sample response
70
+
71
+ ```
72
+ {"method"=>"getSummaryData",
73
+ "responseCode"=>"0",
74
+ "subscriber"=>
75
+ {"attribute"=>
76
+ [{"name"=>"ICCID", "content"=>"89380062300016907xxx"},
77
+ {"name"=>"PUK", "content"=>"25159xxx"},
78
+ {"name"=>"PUK2", "content"=>"00036xxx"},
79
+ {"name"=>"PIN2", "content"=>"55xx"},
80
+ {"name"=>"IMSI", "content"=>"25506109310xxxx"},
81
+ {"name"=>"PIN", "content"=>"70xx"},
82
+ {"name"=>"LINE_STATE", "content"=>"ACT/STD"},
83
+ {"name"=>"USE_COMMON_MAIN", "content"=>"false"},
84
+ {"name"=>"LINE_ACTIVATION_DATE",
85
+ "content"=>"2010-03-02T11:28:07.392+02:00"},
86
+ {"name"=>"LANGUAGE_ID", "content"=>"uk_tr"},
87
+ {"name"=>"DEVICE_NAME", "content"=>"HTC Sensation (PG58130)"},
88
+ {"name"=>"LINE_SUSPEND_DATE", "content"=>"2014-03-21T00:00:00+02:00"}],
89
+ "balance"=>
90
+ [{"code"=>"Line_Main", "amount"=>"12.83"},
91
+ {"code"=>"Line_Bonus", "amount"=>"0.00"},
92
+ {"code"=>"Line_Debt", "amount"=>"0.00"}],
93
+ "bundleFreeMigration"=>{"amount"=>"0"},
94
+ "tariff"=>{"code"=>"IND_PRE_YOUTH", "name"=>"Crazy day"}}}
95
+ ```
96
+
97
+ #### Returns the balance of the current subscriber
98
+
99
+ ```
100
+ life.get_balances
101
+ ```
102
+
103
+ Sample response
104
+
105
+ ```
106
+ {"method"=>"getBalances",
107
+ "responseCode"=>"0",
108
+ "balance"=>
109
+ [{"code"=>"Bundle_Gprs_Internet",
110
+ "amount"=>"0.00",
111
+ "measure"=>"Bytes",
112
+ "name"=>"Free Internet"},
113
+ {"code"=>"Bundle_Gprs_Wap",
114
+ "amount"=>"0.00",
115
+ "measure"=>"Bytes",
116
+ "name"=>"Free Internet [WAP]"},
117
+ {"code"=>"Bundle_Gprs_Internet_Youth",
118
+ "amount"=>"32624640.00",
119
+ "measure"=>"Bytes",
120
+ "name"=>"Internet [Crazy Day]"},
121
+ {"code"=>"Bundle_Usage_Internet_Weekly",
122
+ "amount"=>"0.00",
123
+ "measure"=>"Bytes",
124
+ "name"=>"Used Internet [Week]"},
125
+ {"code"=>"Bundle_Mms_Ukraine",
126
+ "amount"=>"0.00",
127
+ "measure"=>"MMS",
128
+ "name"=>"Free MMS [in Ukraine]"},
129
+ {"code"=>"Bundle_Sms_Ukraine",
130
+ "amount"=>"40.00",
131
+ "measure"=>"SMS",
132
+ "name"=>"Free SMS [in Ukraine]"},
133
+ {"code"=>"Bundle_Youth_Voice_Omo_Pstn",
134
+ "amount"=>"2160.00",
135
+ "measure"=>"Seconds",
136
+ "name"=>"100 min «life:) Сrazy day maximum» [other mob operators]"},
137
+ {"code"=>"Bundle_UsageN_FF_FREE",
138
+ "amount"=>"0.00",
139
+ "measure"=>"Seconds",
140
+ "name"=>"Free minutes [Family Numbers]"},
141
+ {"code"=>"Bundle_UsageN_Onnet_Region",
142
+ "amount"=>"0.00",
143
+ "measure"=>"Seconds",
144
+ "name"=>"Free minutes [Free life:) Donbas]"},
145
+ {"code"=>"Bundle_Voice_Onnet",
146
+ "amount"=>"24000.00",
147
+ "measure"=>"Seconds",
148
+ "name"=>"Free minutes [life:) network]"},
149
+ {"code"=>"Bundle_Voice_Offnet",
150
+ "amount"=>"0.00",
151
+ "measure"=>"Seconds",
152
+ "name"=>
153
+ "Free minutes [other mobile operators and fixed numbers of Ukraine]"},
154
+ {"code"=>"Line_Bonus",
155
+ "amount"=>"0.00",
156
+ "measure"=>"UAH",
157
+ "name"=>"Line Bonus"},
158
+ {"code"=>"Line_Main",
159
+ "amount"=>"12.83",
160
+ "measure"=>"UAH",
161
+ "name"=>"Line Main"}]}
162
+ ```
163
+
164
+ #### Returns payments history for calendar month in format 'YYYY-mm'
165
+
166
+ ```
167
+ life.get_payments_history('2013-03')
168
+ ```
169
+
170
+ Sample response
171
+
172
+ ```
173
+ {"method"=>"getPaymentsHistory",
174
+ "responseCode"=>"0",
175
+ "payments"=>
176
+ {"sum"=>"50.00",
177
+ "payment"=>
178
+ [{"date"=>"2013-03-21",
179
+ "time"=>"10:40:12",
180
+ "type"=>"Payment via WEB",
181
+ "sum"=>"10.00"},
182
+ {"date"=>"2013-03-21",
183
+ "time"=>"13:25:28",
184
+ "type"=>"Payment via WEB",
185
+ "sum"=>"40.00"}]}}
186
+ ```
187
+
188
+ ## Supported Rubies
189
+
190
+ Tested with the following Ruby versions:
191
+
192
+ * MRI 1.9.3
193
+ * MRI 2.0.0
194
+
195
+ ## Contributing
196
+
197
+ 1. Fork it
198
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
199
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
200
+ 4. Push to the branch (`git push origin my-new-feature`)
201
+ 5. Create new Pull Request
202
+
203
+ ## License and Author
204
+
205
+ Copyright (c) 2013-2015 by Anton Maminov
206
+
207
+ This library is distributed under the MIT license. Please see the LICENSE file.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,44 @@
1
+ # encoding: utf-8
2
+
3
+ require 'bundler'
4
+ Bundler.setup :default
5
+
6
+ require 'logger'
7
+ require 'life-api'
8
+
9
+ puts Life::API::VERSION
10
+
11
+ msisdn = '+38xxxxxxxxx'
12
+ password = ''
13
+
14
+ life = Life::API.new(msisdn: msisdn, password: password, lang: 'en')
15
+ life.log = Logger.new($stderr)
16
+ life.sign_in
17
+
18
+ summary_data = life.get_summary_data
19
+
20
+ tariff = summary_data['subscriber']['tariff']['name']
21
+ puts "Tariff: #{tariff}"
22
+
23
+ line_suspend_date = summary_data['subscriber']['attribute'].select{ |f| f['name'] == "LINE_SUSPEND_DATE" }.first['content']
24
+ line_suspend_date = Time.mktime(line_suspend_date).strftime("%d.%m.%Y")
25
+ puts "Suspend date: #{line_suspend_date}"
26
+
27
+ puts
28
+
29
+ balance = summary_data['subscriber']['balance']
30
+ main = balance.select{ |f| f['code'] == 'Line_Main' }.first['amount']
31
+ bonus = balance.select{ |f| f['code'] == 'Line_Bonus' }.first['amount']
32
+ debt = balance.select{ |f| f['code'] == 'Line_Debt' }.first['amount']
33
+ puts "Main: #{main} ₴"
34
+ puts "Bonus: #{bonus} ₴"
35
+ puts "Dept: #{debt} ₴"
36
+
37
+
38
+ puts "\nBalances:"
39
+ balances = life.get_balances
40
+ balances['balance'].keep_if{ |i| i['amount'].to_i != 0 }.each do |i|
41
+ puts " * #{i['name']}: #{i['amount']} #{i['measure']}"
42
+ end
43
+
44
+ life.sign_out
@@ -0,0 +1,114 @@
1
+ # encoding: utf-8
2
+
3
+ # The list of available API method names:
4
+ # (16/22)
5
+ #
6
+ # [-] activateDeactivateService
7
+ # [+] callMeBack
8
+ # [+] changeLanguage
9
+ # [+] changeSuperPassword
10
+ # [-] changeTariff
11
+ # [+] getAvailableTariffs
12
+ # [+] getBalances
13
+ # [+] getExpensesSummary
14
+ # [+] getLanguages
15
+ # [+] getPaymentsHistory
16
+ # [-] getSeparateBalances
17
+ # [+] getServices
18
+ # [+] getSummaryData
19
+ # [+] getToken
20
+ # [+] getUIProperties
21
+ # [-] offerAction
22
+ # [+] refillBalanceByScratchCard
23
+ # [-] removeFromPreProcessing
24
+ # [+] requestBalanceTransfer
25
+ # [+] signIn
26
+ # [+] signOut
27
+ # [-] transferBalance
28
+
29
+ module Life
30
+ class API
31
+ def sign_in
32
+ xml = request('signIn', { msisdn: @msisdn, superPassword: @password })
33
+ @token = xml['token']
34
+ @sub_id = xml['subId']
35
+ return xml
36
+ end
37
+
38
+ def sign_out
39
+ request('signOut', { msisdn: @msisdn, subId: @sub_id })
40
+ end
41
+
42
+ def change_super_password(old_password, new_password)
43
+ request('changeSuperPassword', base_api_parameters.merge({ oldPassword: old_password, newPassword: new_password }))
44
+ end
45
+
46
+ def get_token
47
+ request('getToken', { msisdn: @msisdn, subId: @sub_id })
48
+ end
49
+
50
+ # +last_date_update+ is DateTime object
51
+ #
52
+ def get_ui_properties(language_id, last_date_update)
53
+ request('getUIProperties', {
54
+ accessKeyCode: @access_key_code,
55
+ languageId: language_id,
56
+ osType: @os_type,
57
+ lastDateUpdate: last_date_update,
58
+ })
59
+ end
60
+
61
+ def get_summary_data
62
+ request('getSummaryData', base_api_parameters)
63
+ end
64
+
65
+ def get_services
66
+ request('getServices', base_api_parameters)
67
+ end
68
+
69
+ def get_available_tariffs
70
+ request('getAvailableTariffs', base_api_parameters)
71
+ end
72
+
73
+ def get_balances
74
+ request('getBalances', base_api_parameters)
75
+ end
76
+
77
+ def get_languages
78
+ request('getLanguages', base_api_parameters)
79
+ end
80
+
81
+ def change_language(new_language_id)
82
+ request('changeLanguage', base_api_parameters.merge({ newLanguageId: new_language_id}))
83
+ end
84
+
85
+ def call_me_back(msisdn_b)
86
+ request('callMeBack', base_api_parameters.merge({ msisdnB: msisdn_b }))
87
+ end
88
+
89
+ def request_balance_transfer(msisdn_b)
90
+ request('requestBalanceTransfer', base_api_parameters.merge({ msisdnB: msisdn_b }))
91
+ end
92
+
93
+ # Payments history for calendar month +month_period+
94
+ #
95
+ # +month_period+ - A string like 'yyyy-MM' that represent month of year
96
+ #
97
+ def get_payments_history(month_period)
98
+ request('getPaymentsHistory', base_api_parameters.merge({ monthPeriod: month_period }))
99
+ end
100
+
101
+ # Summary expenses report for calendar month +month_period+
102
+ #
103
+ # +month_period+ - A string like 'yyyy-MM' that represent month of year
104
+ #
105
+ def get_expenses_summary(month_period)
106
+ request('getExpensesSummary', base_api_parameters.merge({ monthPeriod: month_period }))
107
+ end
108
+
109
+ def refill_balance_by_scratch_card(secret_code)
110
+ request('refillBalanceByScratchCard', base_api_parameters.merge({ secretCode: secret_code}))
111
+ end
112
+
113
+ end
114
+ end
@@ -0,0 +1,5 @@
1
+ module Life
2
+ class API
3
+ VERSION = "0.1.5"
4
+ end
5
+ end
data/lib/life-api.rb ADDED
@@ -0,0 +1,171 @@
1
+ # encoding: utf-8
2
+
3
+ require 'uri'
4
+ require 'cgi'
5
+ require 'net/https'
6
+ require 'openssl'
7
+ require 'base64'
8
+
9
+ require 'xmlsimple'
10
+
11
+ require "life-api/methods"
12
+ require "life-api/version"
13
+
14
+ # The Life::API library is used for interactions with a api.life.com.ua website.
15
+ # life:) — GSM operator in Ukraine
16
+ #
17
+ # == Example
18
+ #
19
+ # require 'life-api'
20
+ # require 'logger'
21
+ #
22
+ # life = Life::API.new(msisdn: msisdn, password: password, lang: 'uk')
23
+ # life.log = Logger.new($stderr)
24
+ # life.sign_in
25
+ # life.get_summary_data
26
+ # life.sign_out
27
+ #
28
+ module Life
29
+
30
+ class MethodError < ArgumentError; end
31
+
32
+ RESPONSE_CODES = {
33
+ '0' => 'SUCCESSFULY_PERFORMED',
34
+ '-1' => 'METHOD_INVOCATION_TIMEOUT',
35
+ '-2' => 'INTERNAL_ERROR',
36
+ '-3' => 'INVALID_PARAMETERS_LIST',
37
+ '-4' => 'VENDOR_AUTHORIZATION_FAILED',
38
+ '-5' => 'VENDOR_ACCESS_KEY_EXPIRED',
39
+ '-6' => 'VENDOR_AUTHENTICATION_FAILED',
40
+ '-7' => 'SUPERPASS_CHECKING_FAILED',
41
+ '-8' => 'INCORRECT_SUBSCRIBER_ID',
42
+ '-9' => 'INCORRECT_SUBSRIBER_STATE',
43
+ '-10' => 'SUPERPASS_BLOCKED',
44
+ '-11' => 'SUBSCRIBER_ID_NOT_FOUND',
45
+ '-12' => 'TOKEN_EXPIRED',
46
+ '-13' => 'CHANGE_TARIFF_FAILED',
47
+ '-14' => 'SERVICE_ACTIVATION_FAILED',
48
+ '-15' => 'OFFER_ACTIVATION_FAILED',
49
+ '-16' => 'GET_TARIFFS_FAILED',
50
+ '-17' => 'GET_SERVICES_FAILED',
51
+ '-18' => 'REMOVE_SERVICE_FROM_PREPROCESSING_FAILED',
52
+ '-19' => 'LOGIC_IS_BLOCKING',
53
+ '-20' => 'TOO_MANY_REQUESTS',
54
+ '-40' => 'PAYMENTS_OR_EXPENSES_MISSED',
55
+ '-21474833648' => 'INTERNAL_APPLICATION_ERROR',
56
+ }
57
+
58
+ class API
59
+ attr_accessor :token, :sub_id
60
+
61
+ class << self
62
+ # Default logger for all Life::API instances
63
+ #
64
+ # Life::API.log = Logger.new($stderr)
65
+ #
66
+ attr_accessor :log
67
+ end
68
+
69
+ # Create a new API object using the given parameters.
70
+ #
71
+ # == Required parameters
72
+ #
73
+ # * +:msisdn+ - telephone number in format '38063*******'
74
+ # * +:password+ - life:) super password
75
+ # * +:lang+ - 'uk', 'ru' or 'en'
76
+ #
77
+ def initialize(params = {})
78
+ @msisdn = params.delete(:msisdn)
79
+ @password = params.delete(:password)
80
+ @lang = params.delete(:lang) || 'uk'
81
+
82
+ @log = nil
83
+
84
+ @os_type = 'ANDROID'
85
+
86
+ @api_url = 'https://api.life.com.ua/mobile/'
87
+ @access_key_code = '7'
88
+ @application_key = 'E6j_$4UnR_)0b'
89
+ end
90
+
91
+ # The current logger. If no logger has been set Life::API.log is used.
92
+ #
93
+ def log
94
+ @log || Life::API.log
95
+ end
96
+
97
+ # Sets the +logger+ used by this instance of Life::API
98
+ #
99
+ def log= logger
100
+ @log = logger
101
+ end
102
+
103
+ def request(method, params = {})
104
+ params = { accessKeyCode: @access_key_code }.merge(params)
105
+ url = create_signed_url(method, params)
106
+
107
+ log.debug("[#{method}] request: #{url}") if log
108
+
109
+ uri = URI(url)
110
+ request = Net::HTTP::Get.new(uri.request_uri)
111
+
112
+ response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(request) }
113
+
114
+ log.debug("[#{method}] response: #{response.body}") if log
115
+
116
+ xml = parse_xml(response.body)
117
+
118
+ if xml['responseCode']
119
+ if xml['responseCode'] == '0'
120
+ return xml
121
+ else
122
+ error_message = Life::RESPONSE_CODES[xml['responseCode']]
123
+ error_message ||= "Unknown error code #{xml['responseCode']}"
124
+ raise MethodError, error_message
125
+ end
126
+ else
127
+ raise MethodError, "Unknown error: #{xml}"
128
+ end
129
+
130
+ end
131
+
132
+ private
133
+
134
+ def create_signed_url(method, params)
135
+ query = create_param(params)
136
+ str = method + '?' + query + '&signature='
137
+
138
+ digest = OpenSSL::Digest.new('sha1')
139
+ hash = OpenSSL::HMAC.digest(digest, @application_key, str)
140
+
141
+ hash = Base64.encode64(hash).chomp
142
+
143
+ str += urlencode(hash)
144
+
145
+ return @api_url + str
146
+ end
147
+
148
+ # Returns a string representation of the receiver suitable for use as a URL query string
149
+ #
150
+ def create_param(params)
151
+ params.map do |key, value|
152
+ "#{urlencode(key)}=#{urlencode(value)}"
153
+ end.sort * '&'
154
+ end
155
+
156
+ # URL-encode a string
157
+ #
158
+ def urlencode(str)
159
+ return CGI.escape(str.to_s)
160
+ end
161
+
162
+ def parse_xml(str)
163
+ return XmlSimple.xml_in(str, { 'ForceArray' => false })
164
+ end
165
+
166
+ def base_api_parameters
167
+ return { msisdn: @msisdn, languageId: @lang, osType: @os_type, token: @token }
168
+ end
169
+
170
+ end
171
+ end
data/life-api.gemspec ADDED
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'life-api/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "life-api"
8
+ gem.version = Life::API::VERSION
9
+ gem.authors = ["Anton Maminov"]
10
+ gem.email = ["anton.linux@gmail.com"]
11
+ gem.description = %q{A Ruby interface to the life:) API}
12
+ gem.summary = %q{The Life::API library is used for interactions with a api.life.com.ua website}
13
+ gem.homepage = "https://github.com/mamantoha/life-api"
14
+ gem.license = "MIT"
15
+
16
+ gem.files = `git ls-files`.split($/)
17
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
+ gem.require_paths = ["lib"]
20
+
21
+ gem.add_runtime_dependency('xml-simple', '~> 1.1.2')
22
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: life-api
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.5
5
+ platform: ruby
6
+ authors:
7
+ - Anton Maminov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-06-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: xml-simple
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.1.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.1.2
27
+ description: A Ruby interface to the life:) API
28
+ email:
29
+ - anton.linux@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - Gemfile
35
+ - LICENSE
36
+ - README.md
37
+ - Rakefile
38
+ - examples/get_balance.rb
39
+ - lib/life-api.rb
40
+ - lib/life-api/methods.rb
41
+ - lib/life-api/version.rb
42
+ - life-api.gemspec
43
+ homepage: https://github.com/mamantoha/life-api
44
+ licenses:
45
+ - MIT
46
+ metadata: {}
47
+ post_install_message:
48
+ rdoc_options: []
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubyforge_project:
63
+ rubygems_version: 2.4.7
64
+ signing_key:
65
+ specification_version: 4
66
+ summary: The Life::API library is used for interactions with a api.life.com.ua website
67
+ test_files: []