ecoportal-api 0.5.1 → 0.5.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7169c71eba9b00510c284c1561fea403cdecb456cf929b4039f27d758a47801c
4
- data.tar.gz: e160bb67d93052c68be9cfb33b3cdc9e582aceaa0685309021ffa24d1af14cfd
3
+ metadata.gz: 168542de09c5a87edcd4952acdf84cdf01944c03339238a27c310e29b71e9c14
4
+ data.tar.gz: 2f43b32d289f6232eccff32516717ab82cd86cbe0144d6f8f2eac74f30637cd8
5
5
  SHA512:
6
- metadata.gz: 6e2c2aa49ba1f1a1b1492bce6933df97a142ad3b05f102697607b58307361d2349cbb076bf5e2ffbb734cc6582e83effc897497a549746c8e1ddb653d95d2df1
7
- data.tar.gz: d414cf5182137cecf1e82a7289af347ad1329ea4c917abe14879672788359189a496c8896e9049ad2e18fb504920f945c849e1b0021bb5cdb21d0d9745f071c7
6
+ metadata.gz: 1c539315189039d7baed7c48db646969525a47d51cdd88b63a2ac53b651f089aa6e219fa91624943700c1c73144525d9482f4cff8b9e1ca5cbbc9862c0a138e4
7
+ data.tar.gz: 3c145a2fcea2c476fb39ad914b6b3ec2ff390ffe5378ab9795ddd466238f0af55fbbae59a5e87cadb415a49165cf0e05d6697e45dc74bd6235581c30268d1e45
@@ -0,0 +1,55 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.5.1
3
+ Exclude:
4
+ - 'config/routes.rb'
5
+
6
+ Metrics/LineLength:
7
+ Enabled: false
8
+ Metrics/BlockLength:
9
+ ExcludedMethods: [context, describe]
10
+ Max: 50
11
+ Metrics/MethodLength:
12
+ Max: 50
13
+ Metrics/ClassLength:
14
+ Max: 200
15
+ Metrics/AbcSize:
16
+ Max: 30
17
+
18
+ ParameterLists:
19
+ Max: 5
20
+ CountKeywordArgs: false
21
+
22
+ Style/StringLiterals:
23
+ Enabled: false
24
+ Style/FrozenStringLiteralComment:
25
+ Enabled: false
26
+ Style/CommentedKeyword:
27
+ Enabled: false
28
+ Style/MultilineBlockChain:
29
+ Enabled: false
30
+ Style/Documentation:
31
+ Enabled: false
32
+ Style/StringLiteralsInInterpolation:
33
+ Enabled: false
34
+ Style/AndOr:
35
+ Enabled: false
36
+
37
+ Layout/SpaceInsideHashLiteralBraces:
38
+ Enabled: false
39
+ Layout/SpaceInsideBlockBraces:
40
+ Enabled: false
41
+ Layout/SpaceAroundOperators:
42
+ Enabled: false
43
+ Layout/ExtraSpacing:
44
+ AllowForAlignment: true
45
+ Layout/AccessModifierIndentation:
46
+ EnforcedStyle: indent
47
+ Layout/DotPosition:
48
+ EnforcedStyle: trailing
49
+ Layout/MultilineMethodCallIndentation:
50
+ EnforcedStyle: indented
51
+ Layout/IndentHash:
52
+ Enabled: false
53
+
54
+ Naming/VariableNumber:
55
+ EnforcedStyle: snake_case
@@ -0,0 +1,34 @@
1
+ # Change Log
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ ## [0.5.8] - 2020-06-23
5
+
6
+ ### Added
7
+ ### Changed
8
+ ### Fixed
9
+ - `Ecoportal::API::V1::Person#filter_tags=`: `original_doc["filter_tags"]` is `nil` when creating a person
10
+ - `Ecoportal::API::Internal::Account#policy_group_ids=`: `original_doc["account"]` is `nil` when creating a person
11
+
12
+
13
+ ## [0.5.7] - 2020-06-22
14
+
15
+ ### Added
16
+ - `Ecoportal::API::V1::PersonSchema`: added `enable_tags` & `tags` properties
17
+ - `Ecoportal::API::Internal::Preferences`: added missing fields for **kiosk**
18
+ ### Changed
19
+ - `Ecoportal::API::V1::People::JOB_TIMEOUT`: from 1 minute to 3 minutes
20
+ - `Ecoportal::API::V1::Person#filter_tags=`: will preserve the original order of the matching tags
21
+ * this change is to prevent `as_update` to generate false update positives
22
+ - `Ecoportal::API::Internal::Account#policy_group_ids=`: will preserve the original order of the matching ids
23
+ * this change is to prevent `as_update` to generate false update positives
24
+ ### Fixed
25
+ - `Ecoportal::API::Internal::Preferences`: access `doc` using string keys (not with `symbol` keys)
26
+
27
+
28
+ ## [0.5.6] - 2020-06-08
29
+
30
+ ### Added
31
+ - this `CHANGELOG.md` file
32
+ - person model: `freemium` core property
33
+ ### Changed
34
+ ### Fixed
@@ -10,5 +10,5 @@ require "ecoportal/api"
10
10
  # require "pry"
11
11
  # Pry.start
12
12
 
13
- require "irb"
14
- IRB.start(__FILE__)
13
+ require "pry"
14
+ Pry.start(__FILE__)
@@ -7,7 +7,7 @@ Gem::Specification.new do |spec|
7
7
  spec.name = "ecoportal-api"
8
8
  spec.version = Ecoportal::API::VERSION
9
9
  spec.authors = ["Tapio Saarinen"]
10
- spec.email = ["tapio@ecoportal.co.nz", "rien@ecoportal.co.nz", "oscar@ecoportal.co.nz"]
10
+ spec.email = ["tapio@ecoportal.co.nz", "rien@ecoportal.co.nz", "oscar@ecoportal.co.nz", "bozydar@ecoportal.co.nz"]
11
11
 
12
12
  spec.summary = %q{A collection of helpers for interacting with the ecoPortal MS's various APIs}
13
13
  spec.homepage = "https://www.ecoportal.com"
@@ -20,11 +20,12 @@ Gem::Specification.new do |spec|
20
20
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
21
  spec.require_paths = ["lib"]
22
22
 
23
- spec.add_development_dependency "bundler", "~> 1.16"
24
- spec.add_development_dependency "rake", "~> 10.0"
25
- spec.add_development_dependency "rspec", "~> 3.0"
23
+ spec.add_development_dependency "bundler", "~> 2.1", ">= 2.1.3"
24
+ spec.add_development_dependency "rake", "~> 12.0"
25
+ spec.add_development_dependency "rspec", "~> 3", ">= 3.9"
26
26
  spec.add_development_dependency "yard", "~> 0.9", ">= 0.9.18"
27
- spec.add_development_dependency "redcarpet", "~> 3.4", ">= 3.4.0"
27
+ spec.add_development_dependency "redcarpet", "~> 3.5", ">= 3.5.0"
28
+ spec.add_development_dependency "pry"
28
29
 
29
30
  spec.add_dependency 'http', '~> 3'
30
31
  spec.add_dependency 'hash-polyfill', '~> 0'
@@ -12,6 +12,17 @@ module Ecoportal
12
12
  embeds_one :permissions, key: "permissions_custom", klass: :permissions_class
13
13
  embeds_one :preferences, klass: :preferences_class
14
14
 
15
+ # Sets the `policy_group_ids`
16
+ def policy_group_ids=(value)
17
+ unless value.is_a?(Array)
18
+ raise "policy_group_ids= needs to be passed an Array, got #{value.class}"
19
+ end
20
+
21
+ ini_ids = (original_doc && original_doc["policy_group_ids"]) || []
22
+ # preserve original order to avoid false updates
23
+ doc["policy_group_ids"] = (ini_ids & value) + (value - ini_ids)
24
+ end
25
+
15
26
  # Sets the `permissions_preset`.
16
27
  # @note basically the same as `permissions_preset=` but when `"custom"`, it's changed to `nil`
17
28
  # @param value [nil, String] preset name.
@@ -7,8 +7,17 @@ module Ecoportal
7
7
  :show_shortcuts,
8
8
  :show_coming_soon,
9
9
  :show_recently_visited_forms,
10
- :show_tasks
11
- ].each do |field|
10
+ :show_tasks,
11
+ :show_task_bubbles,
12
+ :kiosk_enabled,
13
+ :kiosk_workflow_message,
14
+ :kiosk_create_button_label,
15
+ :kiosk_create_button_help,
16
+ :kiosk_return_button_label,
17
+ :kiosk_return_button_help,
18
+ :kiosk_dashboard_button_label,
19
+ :kiosk_dashboard_button_help
20
+ ].map(&:to_s).each do |field|
12
21
  define_method(field) do
13
22
  if doc.key?(field)
14
23
  doc[field]
@@ -7,7 +7,10 @@ module Ecoportal
7
7
  include Enumerable
8
8
  include Common::DocHelpers
9
9
 
10
- class_resolver :person_class, "Ecoportal::API::V1::Person"
10
+ JOB_TIMEOUT = 240
11
+ DELAY_STATUS_CHECK = 5
12
+
13
+ class_resolver :person_class, "Ecoportal::API::V1::Person"
11
14
 
12
15
  attr_reader :client
13
16
 
@@ -19,7 +22,7 @@ module Ecoportal
19
22
 
20
23
  # Iterates all the people of the organization.
21
24
  # @note
22
- # - it ignores the key `results_from:` of `params:`.
25
+ # - it ignores the key `cursor_id:` of `params:`.
23
26
  # - `each` is called by `to_a`
24
27
  # @param params [Hash]
25
28
  # @option params [String] :per_page the number of people you get per request.
@@ -28,15 +31,15 @@ module Ecoportal
28
31
  # @yieldparam person [Person]
29
32
  def each(params: {}, &block)
30
33
  return to_enum(:each) unless block
31
- results_from = nil
34
+ cursor_id = nil
32
35
  loop do
33
- params.update(results_from: results_from) if results_from
36
+ params.update(cursor_id: cursor_id) if cursor_id
34
37
  response = client.get("/people", params: params)
35
38
  raise "Request failed." unless response.success?
36
39
  response.body["results"].each do |person|
37
40
  yield person_class.new(person)
38
41
  end
39
- break unless (results_from = response.body["next_results_from"])
42
+ break unless (cursor_id = response.body["cursor_id"])
40
43
  end
41
44
  self
42
45
  end
@@ -56,7 +59,7 @@ module Ecoportal
56
59
  # @param doc [String, Hash, Person] data containing an `id` (internal or external) of the target person.
57
60
  # @return [WrappedResponse] an object with the api response.
58
61
  def get(doc)
59
- response = client.get("/people/"+CGI::escape(get_id(doc)))
62
+ response = client.get("/people/"+CGI.escape(get_id(doc)))
60
63
  Common::WrappedResponse.new(response, person_class)
61
64
  end
62
65
 
@@ -66,7 +69,7 @@ module Ecoportal
66
69
  def update(doc)
67
70
  body = get_body(doc)
68
71
  id = get_id(doc)
69
- client.patch("/people/"+CGI::escape(id), data: body)
72
+ client.patch("/people/"+CGI.escape(id), data: body)
70
73
  end
71
74
 
72
75
  # Requests to create a person via api.
@@ -83,7 +86,7 @@ module Ecoportal
83
86
  def upsert(doc)
84
87
  body = get_body(doc)
85
88
  id = get_id(doc)
86
- client.post("/people/"+CGI::escape(id), data: body)
89
+ client.post("/people/"+CGI.escape(id), data: body)
87
90
  end
88
91
 
89
92
  # Requests to completelly remove from an organization an existing person via api.
@@ -91,13 +94,14 @@ module Ecoportal
91
94
  # @return [Response] an object with the api response.
92
95
  def delete(doc)
93
96
  id = get_id(doc)
94
- client.delete("/people/"+CGI::escape(id))
97
+ client.delete("/people/"+CGI.escape(id))
95
98
  end
96
99
 
97
100
  # Creates a `BatchOperation` and yields it to the given bock.
98
101
  # @yield [batch_op] adds multiple api requests for the current batch.
99
102
  # @yieldparam batch_op [BatchOperation]
100
- def batch
103
+ def batch(job_mode: true, &block)
104
+ return job(&block) if job_mode
101
105
  operation = Common::BatchOperation.new("/people", person_class, logger: client.logger)
102
106
  yield operation
103
107
  # The batch operation is responsible for logging the output
@@ -108,12 +112,72 @@ module Ecoportal
108
112
  end
109
113
  end
110
114
 
115
+ def job
116
+ operation = Common::BatchOperation.new("/people", person_class, logger: client.logger)
117
+ yield operation
118
+ # The batch operation is responsible for logging the output
119
+ job_id = create_job(operation)
120
+ status = wait_for_job_completion(job_id)
121
+
122
+ if status&.complete?
123
+ operation.process_response job_result(job_id, operation)
124
+ else
125
+ raise "Job `#{job_id}` not complete. Probably timeout after #{JOB_TIMEOUT} seconds. Current status: #{status}"
126
+ end
127
+ end
128
+
111
129
  # Creates a new `Person` object.
112
130
  # @return [Person] new empty person object of the current version.
113
131
  def new
114
132
  person_class.new
115
133
  end
116
134
 
135
+ private
136
+
137
+ JobStatus = Struct.new(:id, :complete?, :errored?, :progress)
138
+ def job_status(job_id)
139
+ response = client.get("/people/job/#{CGI.escape(job_id)}/status")
140
+
141
+ raise "Status error" unless response.success?
142
+ JobStatus.new(
143
+ response.body["id"],
144
+ response.body["complete"],
145
+ response.body["errored"],
146
+ response.body["progress"]
147
+ )
148
+ end
149
+
150
+ def job_result(job_id, operation)
151
+ # The batch operation is responsible for logging the output
152
+ client.without_response_logging do
153
+ client.get("/people/job/#{CGI.escape(job_id)}").tap do |response|
154
+ operation.process_response(response)
155
+ end
156
+ end
157
+ end
158
+
159
+ def wait_for_job_completion(job_id)
160
+ # timeout library is evil. So we make poor-man timeout.
161
+ # https://jvns.ca/blog/2015/11/27/why-rubys-timeout-is-dangerous-and-thread-dot-raise-is-terrifying/
162
+ before = Time.now
163
+ while true
164
+ status = job_status(job_id)
165
+ break status if status.complete?
166
+ break status if Time.now >= before + JOB_TIMEOUT
167
+ sleep(DELAY_STATUS_CHECK)
168
+ status
169
+ end
170
+ end
171
+
172
+ def create_job(operation)
173
+ job_id = nil
174
+ client.without_response_logging do
175
+ client.post("/people/job", data: operation.as_json).tap do |response|
176
+ job_id = response.body["id"]
177
+ end
178
+ end
179
+ job_id
180
+ end
117
181
  end
118
182
  end
119
183
  end
@@ -8,7 +8,7 @@ module Ecoportal
8
8
  # @attr_reader subordinates [Integer] the number of people this person is supervisor of.
9
9
  # @attr details [PersonDetails, nil] the details of the person or `nil` if missing.
10
10
  class Person < Common::BaseModel
11
- passthrough :id, :external_id, :name, :email, :supervisor_id, :subordinates, :filter_tags
11
+ passthrough :id, :external_id, :name, :email, :supervisor_id, :subordinates, :filter_tags, :freemium
12
12
 
13
13
  class_resolver :person_schema_class, "Ecoportal::API::V1::PersonSchema"
14
14
  class_resolver :person_details_class, "Ecoportal::API::V1::PersonDetails"
@@ -49,12 +49,16 @@ module Ecoportal
49
49
  unless value.is_a?(Array)
50
50
  raise "filter_tags= needs to be passed an Array, got #{value.class}"
51
51
  end
52
- doc["filter_tags"] = value.map do |tag|
52
+ end_tags = value.map do |tag|
53
53
  unless tag.match(VALID_TAG_REGEX)
54
54
  raise "Invalid filter tag #{tag.inspect}"
55
55
  end
56
56
  tag.upcase
57
57
  end
58
+
59
+ ini_tags = (original_doc && original_doc["filter_tags"]) || []
60
+ # preserve original order to avoid false updates
61
+ doc["filter_tags"] = (ini_tags & end_tags) + (end_tags - ini_tags)
58
62
  end
59
63
 
60
64
  def as_json
@@ -3,6 +3,7 @@ module Ecoportal
3
3
  class V1
4
4
  class PersonSchema < Common::BaseModel
5
5
  passthrough :id, :name
6
+ passthrough :enable_tags, :tags
6
7
 
7
8
  class_resolver :schema_field_class, "Ecoportal::API::V1::SchemaField"
8
9
 
@@ -1,5 +1,5 @@
1
1
  module Ecoportal
2
2
  module API
3
- VERSION = "0.5.1"
3
+ VERSION = "0.5.8"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ecoportal-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.5.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tapio Saarinen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-08-01 00:00:00.000000000 Z
11
+ date: 2020-06-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,42 +16,54 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.16'
19
+ version: '2.1'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 2.1.3
20
23
  type: :development
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
27
  - - "~>"
25
28
  - !ruby/object:Gem::Version
26
- version: '1.16'
29
+ version: '2.1'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 2.1.3
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: rake
29
35
  requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
31
37
  - - "~>"
32
38
  - !ruby/object:Gem::Version
33
- version: '10.0'
39
+ version: '12.0'
34
40
  type: :development
35
41
  prerelease: false
36
42
  version_requirements: !ruby/object:Gem::Requirement
37
43
  requirements:
38
44
  - - "~>"
39
45
  - !ruby/object:Gem::Version
40
- version: '10.0'
46
+ version: '12.0'
41
47
  - !ruby/object:Gem::Dependency
42
48
  name: rspec
43
49
  requirement: !ruby/object:Gem::Requirement
44
50
  requirements:
45
51
  - - "~>"
46
52
  - !ruby/object:Gem::Version
47
- version: '3.0'
53
+ version: '3'
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '3.9'
48
57
  type: :development
49
58
  prerelease: false
50
59
  version_requirements: !ruby/object:Gem::Requirement
51
60
  requirements:
52
61
  - - "~>"
53
62
  - !ruby/object:Gem::Version
54
- version: '3.0'
63
+ version: '3'
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '3.9'
55
67
  - !ruby/object:Gem::Dependency
56
68
  name: yard
57
69
  requirement: !ruby/object:Gem::Requirement
@@ -78,20 +90,34 @@ dependencies:
78
90
  requirements:
79
91
  - - ">="
80
92
  - !ruby/object:Gem::Version
81
- version: 3.4.0
93
+ version: 3.5.0
82
94
  - - "~>"
83
95
  - !ruby/object:Gem::Version
84
- version: '3.4'
96
+ version: '3.5'
85
97
  type: :development
86
98
  prerelease: false
87
99
  version_requirements: !ruby/object:Gem::Requirement
88
100
  requirements:
89
101
  - - ">="
90
102
  - !ruby/object:Gem::Version
91
- version: 3.4.0
103
+ version: 3.5.0
92
104
  - - "~>"
93
105
  - !ruby/object:Gem::Version
94
- version: '3.4'
106
+ version: '3.5'
107
+ - !ruby/object:Gem::Dependency
108
+ name: pry
109
+ requirement: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ type: :development
115
+ prerelease: false
116
+ version_requirements: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
95
121
  - !ruby/object:Gem::Dependency
96
122
  name: http
97
123
  requirement: !ruby/object:Gem::Requirement
@@ -125,14 +151,17 @@ email:
125
151
  - tapio@ecoportal.co.nz
126
152
  - rien@ecoportal.co.nz
127
153
  - oscar@ecoportal.co.nz
154
+ - bozydar@ecoportal.co.nz
128
155
  executables: []
129
156
  extensions: []
130
157
  extra_rdoc_files: []
131
158
  files:
132
159
  - ".gitignore"
133
160
  - ".rspec"
161
+ - ".rubocop.yml"
134
162
  - ".travis.yml"
135
163
  - ".yardopts"
164
+ - CHANGELOG.md
136
165
  - Gemfile
137
166
  - Gemfile.lock
138
167
  - LICENSE