procore 0.8.7 → 0.8.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: 0e9072c893654842077d13100acc0afa9f78a4af28e902748494c58f467c8350
4
- data.tar.gz: b78ba6679d1dfbc2d96d0b395a9778278eac1979efa1fccb5bb3063d81b7430d
3
+ metadata.gz: cc64539748539d38af7f3dedc9a825ae8dff0f84939a53cddf1bf124dcba6c0a
4
+ data.tar.gz: 3a5bbe135e42bbf3d05e7d68a45829bf6dc185334e73ea579ca88cee66ccb757
5
5
  SHA512:
6
- metadata.gz: e36b749b1c34f1f87316c1530a4668bc4e52914fd5b60e29d4a5055755957dbcf46d87028b62baaedec45de57815ba93d4dd305f04dd19fb7972114fe350a8a7
7
- data.tar.gz: c49008dd2ccf0cc0d37fc1457462328a0916161a9bb54c1bd1c35c9d537ccd284b90d319e4c67cadce4b6afc530a37f80347af163877fc52978f69f39c07e4ae
6
+ metadata.gz: f3450511913a6f4c6933a263dfc05d4b564f49978bc334ae043100f4b028b3191dbc486ef0f42bc623da510e3922789a6abbc8120d8f7539e1164c06f91452c5
7
+ data.tar.gz: 2f82f682587398a82831a024a86fff4c986edc4927828a4fb478ef58a6d3b45f080a3dc9822aaf4c7a1a1ac212d7bf53b829efeaa5286d246d86be305a8fe92e
@@ -7,6 +7,7 @@ rvm:
7
7
 
8
8
  services:
9
9
  - redis-server
10
+ - memcached
10
11
 
11
12
  before_install:
12
13
  - gem update --system
@@ -1,5 +1,19 @@
1
1
  ## Unreleased
2
2
 
3
+ ## 0.8.8 (October 17, 2019)
4
+
5
+ * Expose #sync, a method that enables calling sync-actions
6
+
7
+ *Patrick Koperwas*
8
+
9
+ * Addition of contribution guidelines to README
10
+
11
+ *Megan O'Neill*
12
+
13
+ * Fix TravisCI failures
14
+
15
+ *Patrick Koperwas*
16
+
3
17
  ## 0.8.7 (April 18, 2019)
4
18
 
5
19
  * Add api_version to allow calls to procore rest endpoints
data/README.md CHANGED
@@ -10,6 +10,7 @@
10
10
  - [Pagination](#pagination)
11
11
  - [Navigating Through Paginated Results](#navigating-through-paginated-results)
12
12
  - [Change Number of Results](#change-number-of-results)
13
+ - [Sync Actions](#sync-actions)
13
14
  - [Configuration](#configuration)
14
15
  - [Stores](#stores)
15
16
  - [Session Store](#session-store)
@@ -19,6 +20,7 @@
19
20
  - [File Store](#file-store)
20
21
  - [Memory Store](#memory-store)
21
22
  - [Full Example](#full-example)
23
+ - [Contributing](#contributing)
22
24
 
23
25
  ## Installation
24
26
 
@@ -39,8 +41,8 @@ Stores automatically manage tokens for you - refreshing, revoking and storage
39
41
  are abstracted away to make your code as simple as possible. There are several
40
42
  different [types of stores](#stores) available to you.
41
43
 
42
- The Client class exposes `#get`, `#post`, `#put`, `#patch` and `#delete` methods
43
- to you.
44
+ The Client class exposes `#get`, `#post`, `#put`, `#patch`, '#sync' and
45
+ `#delete` methods to you.
44
46
 
45
47
  ```ruby
46
48
  get(path, query: {})
@@ -48,6 +50,7 @@ post(path, body: {}, options: {})
48
50
  put(path, body: {}, options: {})
49
51
  patch(path, body: {}, options: {})
50
52
  delete(path, query: {})
53
+ sync(path, body: {}, options: {})
51
54
  ```
52
55
 
53
56
  All paths are relative - the gem will handle expanding `client.get("me")` to
@@ -259,6 +262,49 @@ puts first_page.pagination
259
262
  Notice that because `per_page` has been set to 250, there are only two pages of
260
263
  results (500 resources / 250 page size = 2 pages).
261
264
 
265
+ ## Sync Actions
266
+ The Sync action enables batch creation or updates to resources using a single
267
+ call. When using a Sync action, the resources to be created or updated can be
268
+ specified by supplying either an `id` or an `origin_id` in the request body.
269
+ Utilizing the `origin_id` attribute for batch operations is often preferable as
270
+ it allows you to easily link to external systems by maintaining your own list of
271
+ unique resource identifiers outside of Procore.
272
+
273
+ The caller provides an array of hashes, each hash containing the attributes for
274
+ a single resource. The attribute names in each hash match those used by the
275
+ Create and Update actions for the resource. Attributes for a maximum of 1000
276
+ resources within a collection may be passed with each call. The API will always
277
+ return an HTTP status of 200.
278
+
279
+ The response body contains two attributes - `entities` and `errors`. The
280
+ attributes for each successfully created or updated resource will appear in the
281
+ entities list. The attributes for each resource will match those returned by the
282
+ Show action. For each resource which could not be created or updated, the
283
+ attributes supplied by the caller are present in the errors list, along with an
284
+ additional errors attribute which provides reasons for the failure.
285
+
286
+ [Continue reading
287
+ here.](https://developers.procore.com/documentation/using-sync-actions)
288
+
289
+ Example Usage:
290
+
291
+ ```ruby
292
+ client.sync(
293
+ "projects/sync",
294
+ body: {
295
+ updates: [
296
+ { id: 1, name: "Update 1" },
297
+ { id: 2, name: "Update 2" },
298
+ { id: 3, name: "Update 3" },
299
+ ...
300
+ ...
301
+ { id: 5055, name: "Update 5055" },
302
+ ]
303
+ },
304
+ options: { batch_size: 500, company_id: 1 },
305
+ )
306
+ ```
307
+
262
308
  ## Configuration
263
309
 
264
310
  The Procore Gem exposes a configuration with several options.
@@ -273,6 +319,11 @@ Procore.configure do |config|
273
319
  # instead of production.
274
320
  config.host = ENV.fetch("PROCORE_BASE_API_PATH", "https://app.procore.com")
275
321
 
322
+ # When using #sync action, sets the default batch size to use for chunking
323
+ # up a request body. Example: if the size is set to 500, and 2,000 updates
324
+ # are desired, 4 requests will be made. Note, the maximum size is 1000.
325
+ config.default_batch_size = 500
326
+
276
327
  # Integer: Number of times to retry a failed API call. Reasons an API call
277
328
  # could potentially fail:
278
329
  # 1. Service is briefly down or unreachable
@@ -433,6 +484,27 @@ class ProjectsController
433
484
  end
434
485
  end
435
486
  ```
487
+ ## Contributing
488
+
489
+ To contribute to the gem, please clone the repo and cut a new branch. In the PR update the changelog with a short explanation of what you've changed, and your name under the "Unreleased" section. Example changelog update:
490
+
491
+ ```markdown
492
+ ## Unreleased
493
+
494
+ * Short sentence of what has changed
495
+
496
+ *Your Name*
497
+ ```
498
+
499
+ Please **do not** bump the gem version in your PR. This will be done in a follow up PR by the gem maintainers.
500
+
501
+ ### Tests
502
+
503
+ To run the specs run the following command:
504
+ ```bash
505
+ $ bundle exec rake test
506
+ ```
507
+
436
508
 
437
509
  ## License
438
510
 
@@ -77,7 +77,20 @@ module Procore
77
77
  # @return [String]
78
78
  attr_accessor :user_agent
79
79
 
80
+ # @!attribute [rw] default_batch_size
81
+ # @note defaults to Defaults::BATCH_SIZE
82
+ #
83
+ # When using #sync action, sets the default batch size to use for chunking
84
+ # up a request body. Example, if the size is set to 500 and 2,000 updates
85
+ # are desired, 4 requests will be made.
86
+ #
87
+ # Note: The maximum size is 1,000
88
+ #
89
+ # @return [Integer]
90
+ attr_accessor :default_batch_size
91
+
80
92
  def initialize
93
+ @default_batch_size = Procore::Defaults::BATCH_SIZE
81
94
  @host = Procore::Defaults::API_ENDPOINT
82
95
  @logger = nil
83
96
  @max_retries = 1
@@ -9,6 +9,9 @@ module Procore
9
9
  # Default User Agent header string
10
10
  USER_AGENT = "Procore Ruby Gem #{Procore::VERSION}".freeze
11
11
 
12
+ # Default size to use for batch requests
13
+ BATCH_SIZE = 500
14
+
12
15
  def self.client_options
13
16
  {
14
17
  host: Procore.configuration.host,
@@ -48,7 +48,7 @@ module Procore
48
48
 
49
49
  # @param path [String] URL path
50
50
  # @param body [Hash] Body parameters to send with the request
51
- # @param options [Hash} Extra request options
51
+ # @param options [Hash] Extra request options
52
52
  # @option options [String] :idempotency_token | :company_id
53
53
  #
54
54
  # @example Usage
@@ -82,7 +82,7 @@ module Procore
82
82
 
83
83
  # @param path [String] URL path
84
84
  # @param body [Hash] Body parameters to send with the request
85
- # @param options [Hash} Extra request options
85
+ # @param options [Hash] Extra request options
86
86
  # @option options [String] :idempotency_token | :company_id
87
87
  #
88
88
  # @example Usage
@@ -112,7 +112,7 @@ module Procore
112
112
 
113
113
  # @param path [String] URL path
114
114
  # @param body [Hash] Body parameters to send with the request
115
- # @param options [Hash} Extra request options
115
+ # @param options [Hash] Extra request options
116
116
  # @option options [String] :idempotency_token | :company_id
117
117
  #
118
118
  # @example Usage
@@ -144,6 +144,72 @@ module Procore
144
144
  end
145
145
  end
146
146
 
147
+ # @param path [String] URL path
148
+ # @param body [Hash] Body parameters to send with the request
149
+ # @param options [Hash] Extra request options
150
+ # @option options [String | Integer] :company_id | :batch_size
151
+ #
152
+ # @example Usage
153
+ # client.sync(
154
+ # "projects/sync",
155
+ # body: {
156
+ # updates: [
157
+ # { id: 1, name: "Update 1" },
158
+ # { id: 2, name: "Update 2" },
159
+ # { id: 3, name: "Update 3" },
160
+ # ...
161
+ # ...
162
+ # { id: 5055, name: "Update 5055" },
163
+ # ]
164
+ # },
165
+ # options: { batch_size: 500, company_id: 1 },
166
+ # )
167
+ #
168
+ # @return [Response]
169
+ def sync(path, body: {}, options: {})
170
+ full_path = full_path(path)
171
+
172
+ batch_size = options[:batch_size] ||
173
+ Procore.configuration.default_batch_size
174
+
175
+ if batch_size > 1000
176
+ batch_size = 1000
177
+ end
178
+
179
+ Util.log_info(
180
+ "API Request Initiated",
181
+ path: full_path,
182
+ method: "SYNC",
183
+ batch_size: batch_size,
184
+ )
185
+
186
+ groups = body[:updates].in_groups_of(batch_size, false)
187
+
188
+ responses = groups.map do |group|
189
+ batched_body = body.merge(updates: group)
190
+ with_response_handling(request_body: batched_body) do
191
+ RestClient::Request.execute(
192
+ method: :patch,
193
+ url: full_path,
194
+ payload: payload(batched_body),
195
+ headers: headers(options),
196
+ timeout: Procore.configuration.timeout,
197
+ )
198
+ end
199
+ end
200
+
201
+ Procore::Response.new(
202
+ body: responses.reduce({}) do |combined, response|
203
+ combined.deep_merge(response.body) { |_, v1, v2| v1 + v2 }
204
+ end.to_json,
205
+ headers: responses.map(&:headers).inject({}, &:deep_merge),
206
+ code: 200,
207
+ request: responses.last&.request,
208
+ request_body: body,
209
+ api_version: api_version,
210
+ )
211
+ end
212
+
147
213
  # @param path [String] URL path
148
214
  # @param query [Hash] Query options to pass along with the request
149
215
  # @option options [String] :company_id
@@ -1,3 +1,3 @@
1
1
  module Procore
2
- VERSION = "0.8.7".freeze
2
+ VERSION = "0.8.8".freeze
3
3
  end
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
32
32
  spec.add_development_dependency "rake"
33
33
  spec.add_development_dependency "redis"
34
34
  spec.add_development_dependency "rubocop"
35
- spec.add_development_dependency "sqlite3", "~> 1.3.6"
35
+ spec.add_development_dependency "sqlite3"
36
36
  spec.add_development_dependency "webmock"
37
37
 
38
38
  spec.add_dependency "activesupport", "> 2.4"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: procore
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.7
4
+ version: 0.8.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Procore Engineering
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-04-18 00:00:00.000000000 Z
11
+ date: 2019-10-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -154,16 +154,16 @@ dependencies:
154
154
  name: sqlite3
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
- - - "~>"
157
+ - - ">="
158
158
  - !ruby/object:Gem::Version
159
- version: 1.3.6
159
+ version: '0'
160
160
  type: :development
161
161
  prerelease: false
162
162
  version_requirements: !ruby/object:Gem::Requirement
163
163
  requirements:
164
- - - "~>"
164
+ - - ">="
165
165
  - !ruby/object:Gem::Version
166
- version: 1.3.6
166
+ version: '0'
167
167
  - !ruby/object:Gem::Dependency
168
168
  name: webmock
169
169
  requirement: !ruby/object:Gem::Requirement