life-api 0.1.5 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: da009a2372ce299d656a0cdb99331a4c91c75e23
4
- data.tar.gz: 4c956cdb158ab68669badb15bba6480ba9e8e824
2
+ SHA256:
3
+ metadata.gz: 3ab973f0fa83d1c3ec3d65e7616dbdaabb750617b29dc2fa22fca5512dfb8c87
4
+ data.tar.gz: a6a8efe3674708ad92dc25508a397ad25e0fe92b460e12a93a9a87b5d66268ce
5
5
  SHA512:
6
- metadata.gz: a4a8acdc289d333e7f19f2fb7300b7bbe570da378d132a70edc77b1c15d13aa6706b37f6634efbe26600544e903b4ef8d610a26bd87ad1a4447d244e84e39a78
7
- data.tar.gz: 70c680fd0ba26ed01ec0cb403c75949dc9c161806d46046dce8dd8d994d25327a2c6c87d2461ec5054212cf1dfc4e50d027adad64263e1a530ea5de051424c7a
6
+ metadata.gz: c52dbd3a68326cf970ea9ea88def6e674452a6d90654d1086b2029050d02800fcf9880dbe899906663932fb0ce50dc85a41535ac54694012898ec6f8070ffee5
7
+ data.tar.gz: 6240318d52c514efc60d73c299b80a0bb8de6e60f19c497ffa953dacd774f2f472a8096f30ef07aa031cdcd5b98db345e2214def14bf7cbd45fae2f5199ca3da
@@ -0,0 +1 @@
1
+ Gemfile.lock
@@ -0,0 +1 @@
1
+ 2.5.0
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in life-api.gemspec
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013 Anton Maminov
1
+ Copyright (c) 2013-2018 Anton Maminov
2
2
 
3
3
  MIT License
4
4
 
@@ -19,4 +19,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
19
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
20
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
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.
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Life::API
2
2
 
3
- A Ruby library for interfacing with life:)'s undocumented/unannounced API.
3
+ A Ruby library for interfacing with lifecell's undocumented/unannounced API.
4
4
 
5
- [life:)](http://life.com.ua) — GSM operator in Ukraine.
5
+ [lifecell](http://lifecell.com.ua) — GSM operator in Ukraine.
6
6
 
7
7
  ## Installation
8
8
 
@@ -36,16 +36,19 @@ require 'life-api'
36
36
 
37
37
  You can authenticate with life:) in two ways: with password or with token.
38
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`).
39
+ Authentication with password to the life:) API is accomplished using a phone number(`msisdn`) starting with the country code("380"), and SuperPassword(`password`).
40
40
 
41
41
  ```ruby
42
+ msisdn = '38063xxxxxxx'
43
+ password = 'xxxxxx'
44
+
42
45
  life = Life::API.new(msisdn: msisdn, password: password)
43
46
  life.sign_in
44
47
  token = life.token
45
48
  sub_id = life.sub_id
46
49
  ```
47
50
 
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#`.
51
+ > To obtain the SuperPassword send an SMS with key word PAROL to number 123.
49
52
 
50
53
  or
51
54
 
@@ -63,7 +66,7 @@ Below you can see some the methods for working with life:) data.
63
66
 
64
67
  #### Returns advanced information on the current subscriber
65
68
  ```
66
- life.get_summary_data
69
+ life.summary_data
67
70
  ```
68
71
 
69
72
  Sample response
@@ -97,7 +100,7 @@ Sample response
97
100
  #### Returns the balance of the current subscriber
98
101
 
99
102
  ```
100
- life.get_balances
103
+ life.balances
101
104
  ```
102
105
 
103
106
  Sample response
@@ -164,7 +167,7 @@ Sample response
164
167
  #### Returns payments history for calendar month in format 'YYYY-mm'
165
168
 
166
169
  ```
167
- life.get_payments_history('2013-03')
170
+ life.payments_history('2013-03')
168
171
  ```
169
172
 
170
173
  Sample response
@@ -189,8 +192,7 @@ Sample response
189
192
 
190
193
  Tested with the following Ruby versions:
191
194
 
192
- * MRI 1.9.3
193
- * MRI 2.0.0
195
+ * MRI 2.3.0
194
196
 
195
197
  ## Contributing
196
198
 
@@ -202,6 +204,6 @@ Tested with the following Ruby versions:
202
204
 
203
205
  ## License and Author
204
206
 
205
- Copyright (c) 2013-2015 by Anton Maminov
207
+ Copyright (c) 2013-2018 by Anton Maminov
206
208
 
207
209
  This library is distributed under the MIT license. Please see the LICENSE file.
data/Rakefile CHANGED
@@ -1 +1,3 @@
1
- require "bundler/gem_tasks"
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'bundler'
4
4
  Bundler.setup :default
@@ -8,36 +8,35 @@ require 'life-api'
8
8
 
9
9
  puts Life::API::VERSION
10
10
 
11
- msisdn = '+38xxxxxxxxx'
12
- password = ''
11
+ msisdn = '38xxxxxxxxx'
12
+ password = 'xxxxxx'
13
13
 
14
14
  life = Life::API.new(msisdn: msisdn, password: password, lang: 'en')
15
15
  life.log = Logger.new($stderr)
16
16
  life.sign_in
17
17
 
18
- summary_data = life.get_summary_data
18
+ summary_data = life.summary_data
19
19
 
20
20
  tariff = summary_data['subscriber']['tariff']['name']
21
21
  puts "Tariff: #{tariff}"
22
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")
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
25
  puts "Suspend date: #{line_suspend_date}"
26
26
 
27
27
  puts
28
28
 
29
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']
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
33
  puts "Main: #{main} ₴"
34
34
  puts "Bonus: #{bonus} ₴"
35
35
  puts "Dept: #{debt} ₴"
36
36
 
37
-
38
37
  puts "\nBalances:"
39
- balances = life.get_balances
40
- balances['balance'].keep_if{ |i| i['amount'].to_i != 0 }.each do |i|
38
+ balances = life.balances
39
+ balances['balance'].keep_if { |i| i['amount'].to_i != 0 }.each do |i|
41
40
  puts " * #{i['name']}: #{i['amount']} #{i['measure']}"
42
41
  end
43
42
 
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'uri'
4
4
  require 'cgi'
@@ -8,11 +8,11 @@ require 'base64'
8
8
 
9
9
  require 'xmlsimple'
10
10
 
11
- require "life-api/methods"
12
- require "life-api/version"
11
+ require 'life-api/methods'
12
+ require 'life-api/version'
13
13
 
14
- # The Life::API library is used for interactions with a api.life.com.ua website.
15
- # life:) GSM operator in Ukraine
14
+ # The Life::API library is used for interactions with a https://api.life.com.ua.
15
+ # lifecell - GSM operator in Ukraine
16
16
  #
17
17
  # == Example
18
18
  #
@@ -26,7 +26,6 @@ require "life-api/version"
26
26
  # life.sign_out
27
27
  #
28
28
  module Life
29
-
30
29
  class MethodError < ArgumentError; end
31
30
 
32
31
  RESPONSE_CODES = {
@@ -52,9 +51,10 @@ module Life
52
51
  '-19' => 'LOGIC_IS_BLOCKING',
53
52
  '-20' => 'TOO_MANY_REQUESTS',
54
53
  '-40' => 'PAYMENTS_OR_EXPENSES_MISSED',
55
- '-21474833648' => 'INTERNAL_APPLICATION_ERROR',
56
- }
54
+ '-21474833648' => 'INTERNAL_APPLICATION_ERROR'
55
+ }.freeze
57
56
 
57
+ # :nodoc:
58
58
  class API
59
59
  attr_accessor :token, :sub_id
60
60
 
@@ -71,7 +71,7 @@ module Life
71
71
  # == Required parameters
72
72
  #
73
73
  # * +:msisdn+ - telephone number in format '38063*******'
74
- # * +:password+ - life:) super password
74
+ # * +:password+ - super password
75
75
  # * +:lang+ - 'uk', 'ru' or 'en'
76
76
  #
77
77
  def initialize(params = {})
@@ -96,40 +96,41 @@ module Life
96
96
 
97
97
  # Sets the +logger+ used by this instance of Life::API
98
98
  #
99
- def log= logger
100
- @log = logger
101
- end
99
+ attr_writer :log
102
100
 
103
101
  def request(method, params = {})
104
102
  params = { accessKeyCode: @access_key_code }.merge(params)
105
103
  url = create_signed_url(method, params)
106
104
 
107
- log.debug("[#{method}] request: #{url}") if log
105
+ log&.debug("[#{method}] request: #{url}")
108
106
 
109
- uri = URI(url)
110
- request = Net::HTTP::Get.new(uri.request_uri)
107
+ response = response(url)
111
108
 
112
- response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(request) }
109
+ log&.debug("[#{method}] response: #{response.body}")
113
110
 
114
- log.debug("[#{method}] response: #{response.body}") if log
111
+ xml = parse_xml(response.body)
112
+ return xml if xml['responseCode'] == '0'
113
+ raise_error!(xml)
114
+ end
115
115
 
116
- xml = parse_xml(response.body)
116
+ private
117
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
118
+ def raise_error!(xml)
119
+ raise MethodError, "Unknown error: #{xml}" unless xml['responseCode']
129
120
 
121
+ error_message = Life::RESPONSE_CODES[xml['responseCode']]
122
+ error_message ||= "Unknown error code #{xml['responseCode']}"
123
+ raise MethodError, error_message
130
124
  end
131
125
 
132
- private
126
+ def response(url)
127
+ uri = URI(url)
128
+ request = Net::HTTP::Get.new(uri.request_uri)
129
+
130
+ Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
131
+ http.request(request)
132
+ end
133
+ end
133
134
 
134
135
  def create_signed_url(method, params)
135
136
  query = create_param(params)
@@ -142,11 +143,11 @@ module Life
142
143
 
143
144
  str += urlencode(hash)
144
145
 
145
- return @api_url + str
146
+ @api_url + str
146
147
  end
147
148
 
148
- # Returns a string representation of the receiver suitable for use as a URL query string
149
- #
149
+ # Returns a string representation of the receiver suitable for use
150
+ # as a URL query string
150
151
  def create_param(params)
151
152
  params.map do |key, value|
152
153
  "#{urlencode(key)}=#{urlencode(value)}"
@@ -154,18 +155,16 @@ module Life
154
155
  end
155
156
 
156
157
  # URL-encode a string
157
- #
158
158
  def urlencode(str)
159
- return CGI.escape(str.to_s)
159
+ CGI.escape(str.to_s)
160
160
  end
161
161
 
162
162
  def parse_xml(str)
163
- return XmlSimple.xml_in(str, { 'ForceArray' => false })
163
+ XmlSimple.xml_in(str, 'ForceArray' => false)
164
164
  end
165
165
 
166
166
  def base_api_parameters
167
- return { msisdn: @msisdn, languageId: @lang, osType: @os_type, token: @token }
167
+ { msisdn: @msisdn, languageId: @lang, osType: @os_type, token: @token }
168
168
  end
169
-
170
169
  end
171
170
  end
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  # The list of available API method names:
4
4
  # (16/22)
@@ -26,89 +26,134 @@
26
26
  # [+] signOut
27
27
  # [-] transferBalance
28
28
 
29
+ # :nodoc:
29
30
  module Life
31
+ # :nodoc:
30
32
  class API
31
33
  def sign_in
32
- xml = request('signIn', { msisdn: @msisdn, superPassword: @password })
34
+ xml = request('signIn', msisdn: @msisdn, superPassword: @password)
33
35
  @token = xml['token']
34
36
  @sub_id = xml['subId']
35
- return xml
37
+ xml
36
38
  end
37
39
 
38
40
  def sign_out
39
- request('signOut', { msisdn: @msisdn, subId: @sub_id })
41
+ request(
42
+ 'signOut',
43
+ msisdn: @msisdn,
44
+ subId: @sub_id
45
+ )
40
46
  end
41
47
 
42
48
  def change_super_password(old_password, new_password)
43
- request('changeSuperPassword', base_api_parameters.merge({ oldPassword: old_password, newPassword: new_password }))
49
+ request(
50
+ 'changeSuperPassword',
51
+ base_api_parameters.merge(
52
+ oldPassword: old_password,
53
+ newPassword: new_password
54
+ )
55
+ )
44
56
  end
45
57
 
46
- def get_token
47
- request('getToken', { msisdn: @msisdn, subId: @sub_id })
58
+ def token
59
+ request(
60
+ 'getToken',
61
+ msisdn: @msisdn, subId: @sub_id
62
+ )
48
63
  end
49
64
 
50
65
  # +last_date_update+ is DateTime object
51
66
  #
52
- def get_ui_properties(language_id, last_date_update)
53
- request('getUIProperties', {
67
+ def ui_properties(language_id, last_date_update)
68
+ request(
69
+ 'getUIProperties',
54
70
  accessKeyCode: @access_key_code,
55
71
  languageId: language_id,
56
72
  osType: @os_type,
57
- lastDateUpdate: last_date_update,
58
- })
73
+ lastDateUpdate: last_date_update
74
+ )
59
75
  end
60
76
 
61
- def get_summary_data
62
- request('getSummaryData', base_api_parameters)
77
+ def summary_data
78
+ request(
79
+ 'getSummaryData',
80
+ base_api_parameters
81
+ )
63
82
  end
64
83
 
65
- def get_services
84
+ def services
66
85
  request('getServices', base_api_parameters)
67
86
  end
68
87
 
69
- def get_available_tariffs
70
- request('getAvailableTariffs', base_api_parameters)
88
+ def available_tariffs
89
+ request(
90
+ 'getAvailableTariffs',
91
+ base_api_parameters
92
+ )
71
93
  end
72
94
 
73
- def get_balances
74
- request('getBalances', base_api_parameters)
95
+ def balances
96
+ request(
97
+ 'getBalances',
98
+ base_api_parameters
99
+ )
75
100
  end
76
101
 
77
- def get_languages
78
- request('getLanguages', base_api_parameters)
102
+ def languages
103
+ request(
104
+ 'getLanguages',
105
+ base_api_parameters
106
+ )
79
107
  end
80
108
 
81
109
  def change_language(new_language_id)
82
- request('changeLanguage', base_api_parameters.merge({ newLanguageId: new_language_id}))
110
+ request(
111
+ 'changeLanguage',
112
+ base_api_parameters.merge(newLanguageId: new_language_id)
113
+ )
83
114
  end
84
115
 
85
116
  def call_me_back(msisdn_b)
86
- request('callMeBack', base_api_parameters.merge({ msisdnB: msisdn_b }))
117
+ request(
118
+ 'callMeBack',
119
+ base_api_parameters.merge(msisdnB: msisdn_b)
120
+ )
87
121
  end
88
122
 
89
123
  def request_balance_transfer(msisdn_b)
90
- request('requestBalanceTransfer', base_api_parameters.merge({ msisdnB: msisdn_b }))
124
+ request(
125
+ 'requestBalanceTransfer',
126
+ base_api_parameters.merge(msisdnB: msisdn_b)
127
+ )
91
128
  end
92
129
 
93
130
  # Payments history for calendar month +month_period+
94
131
  #
95
132
  # +month_period+ - A string like 'yyyy-MM' that represent month of year
96
133
  #
97
- def get_payments_history(month_period)
98
- request('getPaymentsHistory', base_api_parameters.merge({ monthPeriod: month_period }))
134
+ def payments_history(month_period)
135
+ request(
136
+ 'getPaymentsHistory',
137
+ base_api_parameters.merge(monthPeriod: month_period)
138
+ )
99
139
  end
100
140
 
101
141
  # Summary expenses report for calendar month +month_period+
102
142
  #
103
143
  # +month_period+ - A string like 'yyyy-MM' that represent month of year
104
144
  #
105
- def get_expenses_summary(month_period)
106
- request('getExpensesSummary', base_api_parameters.merge({ monthPeriod: month_period }))
145
+ def expenses_summary(month_period)
146
+ request(
147
+ 'getExpensesSummary',
148
+ base_api_parameters.merge(monthPeriod: month_period)
149
+ )
107
150
  end
108
151
 
109
152
  def refill_balance_by_scratch_card(secret_code)
110
- request('refillBalanceByScratchCard', base_api_parameters.merge({ secretCode: secret_code}))
153
+ request(
154
+ 'refillBalanceByScratchCard',
155
+ base_api_parameters.merge(secretCode: secret_code)
156
+ )
111
157
  end
112
-
113
158
  end
114
159
  end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Life
2
4
  class API
3
- VERSION = "0.1.5"
5
+ VERSION = '0.2.0'
4
6
  end
5
7
  end
@@ -1,22 +1,25 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  lib = File.expand_path('../lib', __FILE__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
  require 'life-api/version'
5
6
 
6
7
  Gem::Specification.new do |gem|
7
- gem.name = "life-api"
8
+ gem.name = 'life-api'
8
9
  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"
10
+ gem.authors = ['Anton Maminov']
11
+ gem.email = ['anton.maminov@gmail.com']
12
+ gem.description = 'A Ruby interface to the life:) API'
13
+ gem.summary = 'The Life::API library is used for interactions with a api.life.com.ua website'
14
+ gem.homepage = 'https://github.com/mamantoha/life-api'
15
+ gem.license = 'MIT'
15
16
 
16
- gem.files = `git ls-files`.split($/)
17
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
18
+ gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
18
19
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
- gem.require_paths = ["lib"]
20
+ gem.require_paths = ['lib']
20
21
 
21
22
  gem.add_runtime_dependency('xml-simple', '~> 1.1.2')
23
+ gem.add_development_dependency('pry')
24
+ gem.add_development_dependency('rubocop')
22
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: life-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anton Maminov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-03 00:00:00.000000000 Z
11
+ date: 2018-01-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: xml-simple
@@ -24,13 +24,43 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 1.1.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubocop
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
27
55
  description: A Ruby interface to the life:) API
28
56
  email:
29
- - anton.linux@gmail.com
57
+ - anton.maminov@gmail.com
30
58
  executables: []
31
59
  extensions: []
32
60
  extra_rdoc_files: []
33
61
  files:
62
+ - ".gitignore"
63
+ - ".ruby-version"
34
64
  - Gemfile
35
65
  - LICENSE
36
66
  - README.md
@@ -60,7 +90,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
60
90
  version: '0'
61
91
  requirements: []
62
92
  rubyforge_project:
63
- rubygems_version: 2.4.7
93
+ rubygems_version: 2.7.3
64
94
  signing_key:
65
95
  specification_version: 4
66
96
  summary: The Life::API library is used for interactions with a api.life.com.ua website