procore 0.8.7 → 0.8.8

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: 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