nokotime-ruby-client 0.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.
@@ -0,0 +1,50 @@
1
+ module Nokotime
2
+ module Request
3
+ class MultiplePages
4
+ attr_reader :path
5
+ attr_reader :params
6
+ attr_reader :last_responses
7
+
8
+ def get(path, params: {})
9
+ @path ||= path
10
+ @params ||= params.compact
11
+
12
+ retrieve_all_pages
13
+
14
+ self
15
+ end
16
+
17
+ private
18
+
19
+ def retrieve_all_pages
20
+ @last_responses ||= client.get_in_parallel(
21
+ path, 2, total_pages, params: params
22
+ )
23
+
24
+ @last_responses.unshift([@first_response])
25
+ @last_responses.flatten!
26
+ end
27
+
28
+ def total_pages
29
+ @total_pages ||= first_page.total_pages
30
+ end
31
+
32
+ def first_page
33
+ @first_page ||= first_single_page.get(
34
+ path, params: params
35
+ )
36
+ @first_response = @first_page.last_response
37
+
38
+ @first_page
39
+ end
40
+
41
+ def first_single_page
42
+ @first_single_page ||= SinglePage.new
43
+ end
44
+
45
+ def client
46
+ @client ||= Connection.new
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,71 @@
1
+ module Nokotime
2
+ module Request
3
+ class SinglePage
4
+ attr_reader :last_response
5
+ attr_reader :raw_links
6
+
7
+ def initialize
8
+ @last_response = nil
9
+ @raw_links = nil
10
+ end
11
+
12
+ def get(path, params: {}, request_options: {})
13
+ @last_response = client.get(
14
+ path,
15
+ params: params,
16
+ request_options: request_options
17
+ )
18
+
19
+ @raw_links = @last_response.headers["link"] || []
20
+
21
+ self
22
+ end
23
+
24
+ def next
25
+ next? ? get(paginator.next) : nil
26
+ end
27
+
28
+ def next?
29
+ paginator.next
30
+ end
31
+
32
+ def prev
33
+ prev? ? get(paginator.prev) : nil
34
+ end
35
+
36
+ def prev?
37
+ paginator.prev
38
+ end
39
+
40
+ def last
41
+ last? ? get(paginator.last) : nil
42
+ end
43
+
44
+ def last?
45
+ paginator.last
46
+ end
47
+
48
+ def first
49
+ first? ? get(paginator.first) : nil
50
+ end
51
+
52
+ def first?
53
+ paginator.first
54
+ end
55
+
56
+ def total_pages
57
+ paginator.total_pages.to_i
58
+ end
59
+
60
+ private
61
+
62
+ def paginator
63
+ @paginator = Paginator.new(raw_links)
64
+ end
65
+
66
+ def client
67
+ @client = Connection.new
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,74 @@
1
+ module Nokotime
2
+ module Validator
3
+ # rubocop:disable Metrics/BlockLength
4
+ module EntrySchema
5
+ ENTRY_SCHEMA = Dry::Validation.Schema do
6
+ configure do
7
+ config.namespace = :entry
8
+ config.messages_file = File.join(__dir__, "validation.yml")
9
+
10
+ predicates(RestrictedHash)
11
+
12
+ def valid_tag_filter_type
13
+ %w(and combination of)
14
+ end
15
+
16
+ # rubocop:disable Metrics/MethodLength
17
+ def allowed_keys
18
+ %i(
19
+ user_ids
20
+ description
21
+ project_ids
22
+ tag_ids
23
+ tag_filter_type
24
+ invoice_ids
25
+ import_ids
26
+ from
27
+ to
28
+ invoiced
29
+ invoiced_at_from
30
+ invoiced_at_to
31
+ updated_from
32
+ updated_to
33
+ billable
34
+ approved_at_from
35
+ approved_at_to
36
+ approved_by_ids
37
+ per_page
38
+ )
39
+ end
40
+ # rubocop:enable Metrics/MethodLength
41
+ end
42
+
43
+ restricted_hash?(allowed_keys) do
44
+ optional(:user_ids).filled :str?
45
+ optional(:description).filled :str?
46
+ optional(:project_ids).filled :str?
47
+ optional(:tag_ids).filled :str?
48
+ optional(:tag_filter_type).filled :str?
49
+ optional(:tag_filter_type).
50
+ value(included_in?: valid_tag_filter_type)
51
+ optional(:invoice_ids).filled :str?
52
+ optional(:import_ids).filled :str?
53
+ optional(:from).filled :str?
54
+ optional(:to).filled :str?
55
+ optional(:invoiced).filled :bool?
56
+ optional(:invoiced_at_from).filled :str?
57
+ optional(:invoiced_at_to).filled :str?
58
+ optional(:updated_from).filled :str?
59
+ optional(:updated_to).filled :str?
60
+ optional(:billable).filled :bool?
61
+ optional(:approved_at_from).filled :str?
62
+ optional(:approved_at_to).filled :str?
63
+ optional(:approved_by_ids).filled :str?
64
+ optional(:per_page).filled :int?
65
+ end
66
+ end
67
+ # rubocop:enable Metrics/BlockLength
68
+
69
+ def self.validate(attributes)
70
+ ENTRY_SCHEMA.call(attributes)
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,28 @@
1
+ module Nokotime
2
+ module Validator
3
+ module ProjectGroupSchema
4
+ PROJECT_GROUP_SCHEMA = Dry::Validation.Schema do
5
+ configure do
6
+ config.namespace = :project_group
7
+ config.messages_file = File.join(__dir__, "validation.yml")
8
+
9
+ predicates(RestrictedHash)
10
+
11
+ def allowed_keys
12
+ %i(name project_ids per_page)
13
+ end
14
+ end
15
+
16
+ restricted_hash?(allowed_keys) do
17
+ optional(:name).filled :str?
18
+ optional(:project_ids).filled :str?
19
+ optional(:per_page).filled :int?
20
+ end
21
+ end
22
+
23
+ def self.validate(attributes)
24
+ PROJECT_GROUP_SCHEMA.call(attributes)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,49 @@
1
+ module Nokotime
2
+ module Validator
3
+ module ProjectSchema
4
+ PROJECT_SCHEMA = Dry::Validation.Schema do
5
+ configure do
6
+ config.namespace = :project
7
+ config.messages_file = File.join(__dir__, "validation.yml")
8
+
9
+ predicates(RestrictedHash)
10
+
11
+ def allowed_keys
12
+ %i(
13
+ name
14
+ project_group_ids
15
+ billing_increment
16
+ enabled
17
+ billable
18
+ per_page
19
+ )
20
+ end
21
+
22
+ def valid_increment
23
+ %w(1 5 6 10 15)
24
+ end
25
+
26
+ def valid_increment?(_options, values)
27
+ values.split(",").all? do |value|
28
+ valid_increment.include?(value)
29
+ end
30
+ end
31
+ end
32
+
33
+ restricted_hash?(allowed_keys) do
34
+ optional(:name).filled :str?
35
+ optional(:project_group_ids).filled :str?
36
+ optional(:billing_increment).filled :str?
37
+ optional(:billing_increment).filled(valid_increment?: {})
38
+ optional(:enabled).filled :bool?
39
+ optional(:billable).filled :bool?
40
+ optional(:per_page).filled :int?
41
+ end
42
+ end
43
+
44
+ def self.validate(attributes)
45
+ PROJECT_SCHEMA.call(attributes)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,11 @@
1
+ module Nokotime
2
+ module Validator
3
+ module RestrictedHash
4
+ include Dry::Logic::Predicates
5
+
6
+ predicate(:restricted_hash?) do |allowed_keys, hash|
7
+ (hash.keys - allowed_keys).empty?
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,28 @@
1
+ module Nokotime
2
+ module Validator
3
+ module TagSchema
4
+ TAG_SCHEMA = Dry::Validation.Schema do
5
+ configure do
6
+ config.namespace = :tag
7
+ config.messages_file = File.join(__dir__, "validation.yml")
8
+
9
+ predicates(RestrictedHash)
10
+
11
+ def allowed_keys
12
+ %i(name billable per_page)
13
+ end
14
+ end
15
+
16
+ restricted_hash?(allowed_keys) do
17
+ optional(:name).filled :str?
18
+ optional(:billable).filled :bool?
19
+ optional(:per_page).filled :int?
20
+ end
21
+ end
22
+
23
+ def self.validate(attributes)
24
+ TAG_SCHEMA.call(attributes)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,41 @@
1
+ module Nokotime
2
+ module Validator
3
+ module UserSchema
4
+ USER_SCHEMA = Dry::Validation.Schema do
5
+ EMAIL_REGEX = /\A[^@\s]+@[^@\s]+\z/.freeze
6
+
7
+ configure do
8
+ config.namespace = :user
9
+ config.messages_file = File.join(__dir__, "validation.yml")
10
+
11
+ predicates(RestrictedHash)
12
+
13
+ def valid_roles
14
+ %w(supervisor leader coworker contractor)
15
+ end
16
+
17
+ def valid_states
18
+ %w(disabled pending active suspended)
19
+ end
20
+
21
+ def allowed_keys
22
+ %i(name email role state per_page)
23
+ end
24
+ end
25
+
26
+ restricted_hash?(allowed_keys) do
27
+ optional(:name).filled :str?
28
+ optional(:email).filled :str?
29
+ optional(:email).value(format?: EMAIL_REGEX)
30
+ optional(:role).value(included_in?: valid_roles)
31
+ optional(:state).value(included_in?: valid_states)
32
+ optional(:per_page).filled :int?
33
+ end
34
+ end
35
+
36
+ def self.validate(attributes)
37
+ USER_SCHEMA.call(attributes)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,14 @@
1
+ en:
2
+ errors:
3
+ rules:
4
+ user:
5
+ restricted_hash?: "has unknown keys. Allowed keys are: name, email, role, state and per_page"
6
+ project:
7
+ restricted_hash?: "has unknown keys. Allowed keys are: name, project_group_ids, billing_increment, enabled, billable and per_page"
8
+ valid_increment?: "has invalid values. Allowed values are: 1, 5, 6, 10, 15"
9
+ entry:
10
+ restricted_hash?: "has unknown keys. Allowed keys are: user_ids, description, project_ids, tag_ids, tag_filter_type, invoice_ids, import_ids, from, to, invoiced, invoice_at_from, invoice_at_to, updated_from, updated_to, billable, approved_at_from, approved_at_to, approved_by_ids and per_page"
11
+ tag:
12
+ restricted_hash?: "has unknown keys. Allowed keys are: name, billable and per_page"
13
+ project_group:
14
+ restricted_hash?: "has unknown keys. Allowed keys are: name, project ids and per_page"
@@ -0,0 +1,3 @@
1
+ module Nokotime
2
+ VERSION = "0.1.0".freeze
3
+ end
@@ -0,0 +1,45 @@
1
+ lib = File.expand_path("lib", __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+
4
+ require "nokotime/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "nokotime-ruby-client"
8
+ spec.version = Nokotime::VERSION
9
+ spec.authors = ["Domenico Giuseppe Garofoli"]
10
+ spec.email = ["sirion1987@gmail.com"]
11
+
12
+ spec.summary = "Ruby client for Noko API."
13
+ spec.description = "Ruby client for Noko API. #ruby #client #nokotime"
14
+ spec.homepage = "https://github.com/sirion1987/nokotime-ruby-client"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
18
+ `git ls-files -z`.split("\x0").reject do |f|
19
+ f.match(%r{^(test|spec|features)/})
20
+ end
21
+ end
22
+ spec.bindir = "exe"
23
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
+ spec.require_paths = ["lib"]
25
+
26
+ spec.required_ruby_version = ">= 2.4.0"
27
+
28
+ spec.add_development_dependency "bundler"
29
+ spec.add_development_dependency "coveralls"
30
+ spec.add_development_dependency "rake"
31
+ spec.add_development_dependency "rspec"
32
+ spec.add_development_dependency "rubocop"
33
+ spec.add_development_dependency "rubocop-performance"
34
+ spec.add_development_dependency "rubocop-rspec"
35
+ spec.add_development_dependency "simplecov"
36
+ spec.add_development_dependency "simplecov-console"
37
+ spec.add_development_dependency "vcr"
38
+ spec.add_development_dependency "webmock"
39
+
40
+ spec.add_runtime_dependency "dotenv"
41
+ spec.add_runtime_dependency "dry-validation"
42
+ spec.add_runtime_dependency "faraday", ">= 0.15.2"
43
+ spec.add_runtime_dependency "faraday_middleware", ">= 0.12"
44
+ spec.add_runtime_dependency "typhoeus"
45
+ end
metadata ADDED
@@ -0,0 +1,304 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nokotime-ruby-client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Domenico Giuseppe Garofoli
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-06-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: coveralls
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: rake
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'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop-performance
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop-rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: simplecov
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: simplecov-console
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: vcr
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: webmock
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: dotenv
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: dry-validation
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :runtime
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: faraday
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: 0.15.2
202
+ type: :runtime
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: 0.15.2
209
+ - !ruby/object:Gem::Dependency
210
+ name: faraday_middleware
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - ">="
214
+ - !ruby/object:Gem::Version
215
+ version: '0.12'
216
+ type: :runtime
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - ">="
221
+ - !ruby/object:Gem::Version
222
+ version: '0.12'
223
+ - !ruby/object:Gem::Dependency
224
+ name: typhoeus
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - ">="
228
+ - !ruby/object:Gem::Version
229
+ version: '0'
230
+ type: :runtime
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - ">="
235
+ - !ruby/object:Gem::Version
236
+ version: '0'
237
+ description: 'Ruby client for Noko API. #ruby #client #nokotime'
238
+ email:
239
+ - sirion1987@gmail.com
240
+ executables: []
241
+ extensions: []
242
+ extra_rdoc_files: []
243
+ files:
244
+ - ".env.test.sample"
245
+ - ".gitignore"
246
+ - ".rspec"
247
+ - ".rubocop.yml"
248
+ - ".travis.yml"
249
+ - CODE_OF_CONDUCT.md
250
+ - Gemfile
251
+ - Gemfile.lock
252
+ - LICENSE.txt
253
+ - README.md
254
+ - Rakefile
255
+ - bin/console
256
+ - bin/setup
257
+ - lib/nokotime.rb
258
+ - lib/nokotime/authentication.rb
259
+ - lib/nokotime/client/entries.rb
260
+ - lib/nokotime/client/project_groups.rb
261
+ - lib/nokotime/client/projects.rb
262
+ - lib/nokotime/client/tags.rb
263
+ - lib/nokotime/client/users.rb
264
+ - lib/nokotime/configuration.rb
265
+ - lib/nokotime/connection.rb
266
+ - lib/nokotime/errors/configuration.rb
267
+ - lib/nokotime/errors/connection.rb
268
+ - lib/nokotime/errors/invalid_params.rb
269
+ - lib/nokotime/paginator.rb
270
+ - lib/nokotime/request/multiple_pages.rb
271
+ - lib/nokotime/request/single_page.rb
272
+ - lib/nokotime/validator/entry_schema.rb
273
+ - lib/nokotime/validator/project_group_schema.rb
274
+ - lib/nokotime/validator/project_schema.rb
275
+ - lib/nokotime/validator/restricted_hash.rb
276
+ - lib/nokotime/validator/tag_schema.rb
277
+ - lib/nokotime/validator/user_schema.rb
278
+ - lib/nokotime/validator/validation.yml
279
+ - lib/nokotime/version.rb
280
+ - nokotime-ruby-client.gemspec
281
+ homepage: https://github.com/sirion1987/nokotime-ruby-client
282
+ licenses:
283
+ - MIT
284
+ metadata: {}
285
+ post_install_message:
286
+ rdoc_options: []
287
+ require_paths:
288
+ - lib
289
+ required_ruby_version: !ruby/object:Gem::Requirement
290
+ requirements:
291
+ - - ">="
292
+ - !ruby/object:Gem::Version
293
+ version: 2.4.0
294
+ required_rubygems_version: !ruby/object:Gem::Requirement
295
+ requirements:
296
+ - - ">="
297
+ - !ruby/object:Gem::Version
298
+ version: '0'
299
+ requirements: []
300
+ rubygems_version: 3.0.3
301
+ signing_key:
302
+ specification_version: 4
303
+ summary: Ruby client for Noko API.
304
+ test_files: []