ecoportal-api 0.4.3 → 0.5.6

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
2
  SHA256:
3
- metadata.gz: 5441ef892224dc43af0a9060cf90725d93640cc98a66642565962ace69eefa00
4
- data.tar.gz: 5c53d8665f94cae4e06f86b72cc4807ed8862908f0999156fd792d38c8a46ed5
3
+ metadata.gz: 31190d7d5719d21b732605d97eccaad0c042f9fc3212fc5f181e6e18e6f12771
4
+ data.tar.gz: e7bb04368723c7da36ca8408b05088ed09753c9f9fa53722b32c3ef0df3f6e0e
5
5
  SHA512:
6
- metadata.gz: 0102b941ada369991d37a24676fedf97055633b3df0b4b0198f5dfef7007ddc289b53c1e36cdf4a0aae4afa995a26b05c26a3d2df5aecdcfeabe6e53bf108650
7
- data.tar.gz: e3d0401ba1d6d91508812f549677e23fc60667cb794d22cafe82fc5bda8c344b529cf248856c36f1d13dad9d4e0bc8a00d66844f628686b6b3442035521f1a12
6
+ metadata.gz: f10ac460fa44b8750825f46648f54d394b36b9a4bec95b138724dd79f278db4014540bb268fecf9e4a3e719b8eb03da1d398a15203776706643eaa9437ba9fe8
7
+ data.tar.gz: 67185025081f552f608ba0512fce293ef5a731d31fee2b2132e276eda04f85bd135b0f268936209af1e948ff066f537d7834c005a302ca251f75359d7cfeb758
@@ -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,10 @@
1
+ # Change Log
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ ## [0.5.6] - 2020-06-xx
5
+
6
+ ### Added
7
+ - this `CHANGELOG.md` file
8
+ - person model: `freemium` core property
9
+ ### Changed
10
+ ### 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"]
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"
@@ -25,6 +25,7 @@ Gem::Specification.new do |spec|
25
25
  spec.add_development_dependency "rspec", "~> 3.0"
26
26
  spec.add_development_dependency "yard", "~> 0.9", ">= 0.9.18"
27
27
  spec.add_development_dependency "redcarpet", "~> 3.4", ">= 3.4.0"
28
+ spec.add_development_dependency "pry"
28
29
 
29
30
  spec.add_dependency 'http', '~> 3'
30
31
  spec.add_dependency 'hash-polyfill', '~> 0'
@@ -3,17 +3,15 @@ module Ecoportal
3
3
  class Internal
4
4
  class Account < Common::BaseModel
5
5
  passthrough :policy_group_ids, :landing_page_id, :permissions_preset, :permissions_custom,
6
- :preferences, :prefilter, :filter_tags, :login_provider_ids, :starred_ids, :accept_eula,
6
+ :preferences, :prefilter, :login_provider_ids, :starred_ids, :accept_eula,
7
7
  :send_invites, :default_tag
8
8
 
9
9
  class_resolver :preferences_class, "Ecoportal::API::Internal::Preferences"
10
10
  class_resolver :permissions_class, "Ecoportal::API::Internal::Permissions"
11
-
11
+
12
12
  embeds_one :permissions, key: "permissions_custom", klass: :permissions_class
13
13
  embeds_one :preferences, klass: :preferences_class
14
14
 
15
- VALID_TAG_REGEX = /^[A-Za-z0-9 &_'\/-]+$/
16
-
17
15
  # Sets the `permissions_preset`.
18
16
  # @note basically the same as `permissions_preset=` but when `"custom"`, it's changed to `nil`
19
17
  # @param value [nil, String] preset name.
@@ -28,22 +26,6 @@ module Ecoportal
28
26
  self.permissions_preset.nil? ? "custom" : self.permissions_preset
29
27
  end
30
28
 
31
- # Validates the string tags of the array, and sets the `filter_tags` property of the account.
32
- # @note all is set in upper case.
33
- # @raise [Exception] if there was any invalid string tag.
34
- # @param value [Array<String>] array of tags.
35
- def filter_tags=(value)
36
- unless value.is_a?(Array)
37
- raise "filter_tags= needs to be passed an Array, got #{value.class}"
38
- end
39
- doc["filter_tags"] = value.map do |tag|
40
- unless tag.match(VALID_TAG_REGEX)
41
- raise "Invalid filter tag #{tag.inspect}"
42
- end
43
- tag.upcase
44
- end
45
- end
46
-
47
29
  def as_json
48
30
  super.tap do |hash|
49
31
  if preset == "custom"
@@ -25,10 +25,7 @@ module Ecoportal
25
25
  when Internal::Account
26
26
  doc["account"] = JSON.parse(value.to_json)
27
27
  when Hash
28
- # TODO:
29
- # => missing send_invites
30
- # => better use an Internal::Account::PROPERTIES const for this kind of stuff
31
- doc["account"] = value.slice(%w[policy_group_ids landing_page_id permissions_preset permissions_custom preferences prefilter filter_tags login_provider_ids starred_ids])
28
+ doc["account"] = value.slice(*%w[policy_group_ids default_tag landing_page_id permissions_preset permissions_custom preferences prefilter login_provider_ids starred_ids])
32
29
  else
33
30
  # TODO
34
31
  raise "Invalid set on account: Need nil, Account or Hash; got #{value.class}"
@@ -7,7 +7,16 @@ module Ecoportal
7
7
  :show_shortcuts,
8
8
  :show_coming_soon,
9
9
  :show_recently_visited_forms,
10
- :show_tasks
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
11
20
  ].each do |field|
12
21
  define_method(field) do
13
22
  if doc.key?(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 = 60
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,12 +8,14 @@ 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
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"
15
15
  embeds_one :details, nullable: true, klass: :person_details_class
16
16
 
17
+ VALID_TAG_REGEX = /^[A-Za-z0-9 &_'\/-]+$/
18
+
17
19
  # Gets the supervisor (`Person`) of this person, with given his `supervisor_id`.
18
20
  #
19
21
  # **Example Usage**:
@@ -39,6 +41,22 @@ module Ecoportal
39
41
  self.supervisor_id = person&.id || person&.external_id
40
42
  end
41
43
 
44
+ # Validates the string tags of the array, and sets the `filter_tags` property of the account.
45
+ # @note all is set in upper case.
46
+ # @raise [Exception] if there was any invalid string tag.
47
+ # @param value [Array<String>] array of tags.
48
+ def filter_tags=(value)
49
+ unless value.is_a?(Array)
50
+ raise "filter_tags= needs to be passed an Array, got #{value.class}"
51
+ end
52
+ doc["filter_tags"] = value.map do |tag|
53
+ unless tag.match(VALID_TAG_REGEX)
54
+ raise "Invalid filter tag #{tag.inspect}"
55
+ end
56
+ tag.upcase
57
+ end
58
+ end
59
+
42
60
  def as_json
43
61
  super.merge "details" => details&.as_json
44
62
  end
@@ -1,5 +1,5 @@
1
1
  module Ecoportal
2
2
  module API
3
- VERSION = "0.4.3"
3
+ VERSION = "0.5.6"
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.4.3
4
+ version: 0.5.6
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-06-12 00:00:00.000000000 Z
11
+ date: 2020-06-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -92,6 +92,20 @@ dependencies:
92
92
  - - "~>"
93
93
  - !ruby/object:Gem::Version
94
94
  version: '3.4'
95
+ - !ruby/object:Gem::Dependency
96
+ name: pry
97
+ requirement: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
95
109
  - !ruby/object:Gem::Dependency
96
110
  name: http
97
111
  requirement: !ruby/object:Gem::Requirement
@@ -123,14 +137,19 @@ dependencies:
123
137
  description:
124
138
  email:
125
139
  - tapio@ecoportal.co.nz
140
+ - rien@ecoportal.co.nz
141
+ - oscar@ecoportal.co.nz
142
+ - bozydar@ecoportal.co.nz
126
143
  executables: []
127
144
  extensions: []
128
145
  extra_rdoc_files: []
129
146
  files:
130
147
  - ".gitignore"
131
148
  - ".rspec"
149
+ - ".rubocop.yml"
132
150
  - ".travis.yml"
133
151
  - ".yardopts"
152
+ - CHANGELOG.md
134
153
  - Gemfile
135
154
  - Gemfile.lock
136
155
  - LICENSE