docbase 3.0.0 → 3.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +1 -0
- data/docbase.gemspec +1 -2
- data/lib/docbase/client.rb +54 -28
- data/lib/docbase/version.rb +1 -1
- data/lib/docbase.rb +0 -1
- metadata +9 -17
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: db7bc6f5163f765c5a16ec85c3a190c894e87b484acac0901458f44b81ca0355
|
|
4
|
+
data.tar.gz: 0eaace24913ca86fa825a2da026da6f9aff7e3a5cad1af5df1f505a91ec39d6e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 84a27324711539c8ffaea3365cbb1b75b8b2d6041d9f385b4994099657e183d4d42929c873701b4fed2e682c4164e240a03e5417f89c5897d20c2be3efd90fb4
|
|
7
|
+
data.tar.gz: 7a715b93cad6b2167bb98ca766698924e87ad63aa3034afe977fc60a97c07130cbb10c6f259e4a80c4fcad674abdea15b6a422faffa157378af5305d2e40c9f0
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## 3.1.0
|
|
2
|
+
|
|
3
|
+
* faradayを2.14.4以上3未満に変更し、faraday_middlewareへの依存を削除(faraday 2.14.3以前では使えなくなります)
|
|
4
|
+
* `access_token`を差し替えても古いトークンで送信される不具合を修正
|
|
5
|
+
* IDやチーム名が不正なときはURLに埋め込まず`ArgumentError`にするように
|
|
6
|
+
* 利用制限時のリトライに上限を追加(3回まで、1回の待ちは60秒まで)。有効な`X-RateLimit-Reset`がない429はリトライしない
|
|
7
|
+
|
|
1
8
|
## 3.0.0
|
|
2
9
|
|
|
3
10
|
* DocBase API v3対応
|
data/README.md
CHANGED
|
@@ -35,6 +35,7 @@ client = DocBase::Client.new(access_token: 'your_access_token', team: 'your_team
|
|
|
35
35
|
* retry_on_rate_limit_exceeded
|
|
36
36
|
* [#16](https://github.com/krayinc/docbase-ruby/issues/16)
|
|
37
37
|
* true or false
|
|
38
|
+
* When true, a 429 response is retried after waiting until `X-RateLimit-Reset`, up to 3 times and at most 60 seconds per wait. A 429 response without a valid `X-RateLimit-Reset` is returned without retrying.
|
|
38
39
|
|
|
39
40
|
### profile
|
|
40
41
|
|
data/docbase.gemspec
CHANGED
data/lib/docbase/client.rb
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
module DocBase
|
|
2
2
|
class Client
|
|
3
3
|
DEFAULT_URL = 'https://api.docbase.io'
|
|
4
|
+
TEAM_FORMAT = /\A[a-z0-9]+(-[a-z0-9]+)*\z/
|
|
5
|
+
ID_FORMAT = /\A[1-9][0-9]*\z/
|
|
4
6
|
USER_AGENT = "DocBase Ruby Gem #{DocBase::VERSION}"
|
|
7
|
+
MAX_RATE_LIMIT_RETRIES = 3
|
|
8
|
+
MAX_RATE_LIMIT_WAIT_SECONDS = 60
|
|
5
9
|
|
|
6
10
|
class NotSetTeamError < StandardError; end
|
|
7
11
|
class NotSetPostIdError < StandardError; end
|
|
@@ -18,6 +22,8 @@ module DocBase
|
|
|
18
22
|
|
|
19
23
|
def team!
|
|
20
24
|
raise NotSetTeamError unless @team
|
|
25
|
+
raise ArgumentError, "invalid team: #{@team.inspect}" unless TEAM_FORMAT.match?(@team.to_s)
|
|
26
|
+
|
|
21
27
|
@team
|
|
22
28
|
end
|
|
23
29
|
|
|
@@ -36,13 +42,13 @@ module DocBase
|
|
|
36
42
|
def user_groups(user_id, page: 1, per_page: 20)
|
|
37
43
|
request(
|
|
38
44
|
method: :get,
|
|
39
|
-
path: "/teams/#{team!}/users/#{user_id}/groups",
|
|
45
|
+
path: "/teams/#{team!}/users/#{id_segment(user_id)}/groups",
|
|
40
46
|
params: { page: page, per_page: per_page }
|
|
41
47
|
)
|
|
42
48
|
end
|
|
43
49
|
|
|
44
50
|
def delete_user(id)
|
|
45
|
-
request(method: :delete, path: "/teams/#{team!}/users/#{id}")
|
|
51
|
+
request(method: :delete, path: "/teams/#{team!}/users/#{id_segment(id)}")
|
|
46
52
|
end
|
|
47
53
|
|
|
48
54
|
def tags
|
|
@@ -54,7 +60,7 @@ module DocBase
|
|
|
54
60
|
end
|
|
55
61
|
|
|
56
62
|
def group(id)
|
|
57
|
-
request(method: :get, path: "/teams/#{team!}/groups/#{id}")
|
|
63
|
+
request(method: :get, path: "/teams/#{team!}/groups/#{id_segment(id)}")
|
|
58
64
|
end
|
|
59
65
|
|
|
60
66
|
def create_group(params)
|
|
@@ -78,7 +84,7 @@ module DocBase
|
|
|
78
84
|
end
|
|
79
85
|
|
|
80
86
|
def post(id)
|
|
81
|
-
request(method: :get, path: "/teams/#{team!}/posts/#{id}")
|
|
87
|
+
request(method: :get, path: "/teams/#{team!}/posts/#{id_segment(id)}")
|
|
82
88
|
end
|
|
83
89
|
|
|
84
90
|
def posts(q: '*', page: 1, per_page: 20)
|
|
@@ -106,21 +112,21 @@ module DocBase
|
|
|
106
112
|
end
|
|
107
113
|
|
|
108
114
|
def delete_post(id)
|
|
109
|
-
request(method: :delete, path: "/teams/#{team!}/posts/#{id}")
|
|
115
|
+
request(method: :delete, path: "/teams/#{team!}/posts/#{id_segment(id)}")
|
|
110
116
|
end
|
|
111
117
|
|
|
112
118
|
def archive_post(id)
|
|
113
|
-
request(method: :put, path: "/teams/#{team!}/posts/#{id}/archive")
|
|
119
|
+
request(method: :put, path: "/teams/#{team!}/posts/#{id_segment(id)}/archive")
|
|
114
120
|
end
|
|
115
121
|
|
|
116
122
|
def unarchive_post(id)
|
|
117
|
-
request(method: :put, path: "/teams/#{team!}/posts/#{id}/unarchive")
|
|
123
|
+
request(method: :put, path: "/teams/#{team!}/posts/#{id_segment(id)}/unarchive")
|
|
118
124
|
end
|
|
119
125
|
|
|
120
126
|
def comments(post_id, page: 1, per_page: 20, order: 'asc', created_after: nil, created_before: nil)
|
|
121
127
|
request(
|
|
122
128
|
method: :get,
|
|
123
|
-
path: "/teams/#{team!}/posts/#{post_id}/comments",
|
|
129
|
+
path: "/teams/#{team!}/posts/#{id_segment(post_id)}/comments",
|
|
124
130
|
params: {
|
|
125
131
|
page: page,
|
|
126
132
|
per_page: per_page,
|
|
@@ -140,13 +146,13 @@ module DocBase
|
|
|
140
146
|
end
|
|
141
147
|
|
|
142
148
|
def delete_comment(id)
|
|
143
|
-
request(method: :delete, path: "/teams/#{team!}/comments/#{id}")
|
|
149
|
+
request(method: :delete, path: "/teams/#{team!}/comments/#{id_segment(id)}")
|
|
144
150
|
end
|
|
145
151
|
|
|
146
152
|
def good_jobs(post_id, page: 1, per_page: 100, order: 'asc', created_after: nil, created_before: nil)
|
|
147
153
|
request(
|
|
148
154
|
method: :get,
|
|
149
|
-
path: "/teams/#{team!}/posts/#{post_id}/good_jobs",
|
|
155
|
+
path: "/teams/#{team!}/posts/#{id_segment(post_id)}/good_jobs",
|
|
150
156
|
params: {
|
|
151
157
|
page: page,
|
|
152
158
|
per_page: per_page,
|
|
@@ -158,11 +164,11 @@ module DocBase
|
|
|
158
164
|
end
|
|
159
165
|
|
|
160
166
|
def create_good_job(post_id, params = {})
|
|
161
|
-
request(method: :post, path: "/teams/#{team!}/posts/#{post_id}/good_jobs", params: params)
|
|
167
|
+
request(method: :post, path: "/teams/#{team!}/posts/#{id_segment(post_id)}/good_jobs", params: params)
|
|
162
168
|
end
|
|
163
169
|
|
|
164
170
|
def delete_good_job(post_id, good_job_id)
|
|
165
|
-
request(method: :delete, path: "/teams/#{team!}/posts/#{post_id}/good_jobs/#{good_job_id}")
|
|
171
|
+
request(method: :delete, path: "/teams/#{team!}/posts/#{id_segment(post_id)}/good_jobs/#{id_segment(good_job_id)}")
|
|
166
172
|
end
|
|
167
173
|
|
|
168
174
|
def upload(paths)
|
|
@@ -180,11 +186,24 @@ module DocBase
|
|
|
180
186
|
end
|
|
181
187
|
|
|
182
188
|
def attachment(id)
|
|
183
|
-
request(method: :get, path: "/teams/#{team!}/attachments/#{id}", for_binary: true)
|
|
189
|
+
request(method: :get, path: "/teams/#{team!}/attachments/#{path_segment(id)}", for_binary: true)
|
|
184
190
|
end
|
|
185
191
|
|
|
186
192
|
private
|
|
187
193
|
|
|
194
|
+
def id_segment(id)
|
|
195
|
+
raise ArgumentError, "invalid id: #{id.inspect}" unless ID_FORMAT.match?(id.to_s)
|
|
196
|
+
|
|
197
|
+
id.to_s
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def path_segment(value)
|
|
201
|
+
value = value.to_s
|
|
202
|
+
raise ArgumentError, "invalid id: #{value.inspect}" if value.empty? || value == '.' || value == '..'
|
|
203
|
+
|
|
204
|
+
URI.encode_www_form_component(value).gsub('+', '%20')
|
|
205
|
+
end
|
|
206
|
+
|
|
188
207
|
def except(hash, reject_key)
|
|
189
208
|
hash.reject { |key, _| key == reject_key }
|
|
190
209
|
end
|
|
@@ -206,28 +225,35 @@ module DocBase
|
|
|
206
225
|
|
|
207
226
|
def headers
|
|
208
227
|
{
|
|
209
|
-
'Accept'
|
|
210
|
-
'User-Agent'
|
|
211
|
-
'X-DocBaseToken' => access_token,
|
|
228
|
+
'Accept' => 'application/json',
|
|
229
|
+
'User-Agent' => USER_AGENT,
|
|
212
230
|
}
|
|
213
231
|
end
|
|
214
232
|
|
|
215
233
|
def request(method:, path:, params: nil, for_binary: false)
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
234
|
+
retries = 0
|
|
235
|
+
loop do
|
|
236
|
+
conn = for_binary ? connection_for_binary : connection
|
|
237
|
+
response = conn.send(method, path, params, 'X-DocBaseToken' => access_token)
|
|
238
|
+
return response unless retry_on_rate_limit_exceeded && response.status == 429
|
|
239
|
+
|
|
240
|
+
reset_time = rate_limit_reset_time(response)
|
|
241
|
+
return response if reset_time.nil? || retries >= MAX_RATE_LIMIT_RETRIES
|
|
242
|
+
|
|
243
|
+
retries += 1
|
|
244
|
+
wait_for(reset_time)
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def rate_limit_reset_time(response)
|
|
249
|
+
reset_time = Integer(response.headers['x-ratelimit-reset'].to_s, exception: false)
|
|
250
|
+
reset_time if reset_time && reset_time > 0
|
|
225
251
|
end
|
|
226
252
|
|
|
227
253
|
def wait_for(reset_time)
|
|
228
|
-
wait_time = reset_time - Time.now.to_i
|
|
229
|
-
|
|
230
|
-
sleep wait_time
|
|
254
|
+
wait_time = (reset_time - Time.now.to_i).clamp(0, MAX_RATE_LIMIT_WAIT_SECONDS)
|
|
255
|
+
puts "DocBase API Rate limit exceeded: will retry at #{(Time.now + wait_time).strftime("%Y/%m/%d %H:%M:%S")}."
|
|
256
|
+
sleep wait_time if wait_time > 0
|
|
231
257
|
end
|
|
232
258
|
end
|
|
233
259
|
end
|
data/lib/docbase/version.rb
CHANGED
data/lib/docbase.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: docbase
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- ttakuru88
|
|
@@ -29,28 +29,20 @@ dependencies:
|
|
|
29
29
|
requirements:
|
|
30
30
|
- - ">="
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version:
|
|
33
|
-
|
|
34
|
-
prerelease: false
|
|
35
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
-
requirements:
|
|
37
|
-
- - ">="
|
|
32
|
+
version: 2.14.4
|
|
33
|
+
- - "<"
|
|
38
34
|
- !ruby/object:Gem::Version
|
|
39
|
-
version:
|
|
40
|
-
- !ruby/object:Gem::Dependency
|
|
41
|
-
name: faraday_middleware
|
|
42
|
-
requirement: !ruby/object:Gem::Requirement
|
|
43
|
-
requirements:
|
|
44
|
-
- - ">="
|
|
45
|
-
- !ruby/object:Gem::Version
|
|
46
|
-
version: 0.12.2
|
|
35
|
+
version: '3'
|
|
47
36
|
type: :runtime
|
|
48
37
|
prerelease: false
|
|
49
38
|
version_requirements: !ruby/object:Gem::Requirement
|
|
50
39
|
requirements:
|
|
51
40
|
- - ">="
|
|
52
41
|
- !ruby/object:Gem::Version
|
|
53
|
-
version:
|
|
42
|
+
version: 2.14.4
|
|
43
|
+
- - "<"
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '3'
|
|
54
46
|
description: DocBase API Client, written in Ruby
|
|
55
47
|
email:
|
|
56
48
|
- asaumi+docbase-ruby@kray.jp
|
|
@@ -91,7 +83,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
91
83
|
- !ruby/object:Gem::Version
|
|
92
84
|
version: '0'
|
|
93
85
|
requirements: []
|
|
94
|
-
rubygems_version: 4.0.
|
|
86
|
+
rubygems_version: 4.0.20
|
|
95
87
|
specification_version: 4
|
|
96
88
|
summary: DocBase API Client, written in Ruby
|
|
97
89
|
test_files: []
|