panoptes-client 0.2.7 → 0.2.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 +4 -4
- data/.hound.yml +2 -0
- data/.ruby-style.yml +206 -0
- data/CHANGELOG.md +8 -0
- data/data/doorkeeper-jwt-production.pub +14 -0
- data/data/doorkeeper-jwt-staging.pub +14 -0
- data/lib/panoptes/client.rb +53 -67
- data/lib/panoptes/client/cellect.rb +22 -0
- data/lib/panoptes/client/comments.rb +16 -0
- data/lib/panoptes/client/discussions.rb +1 -1
- data/lib/panoptes/client/me.rb +4 -1
- data/lib/panoptes/client/projects.rb +6 -6
- data/lib/panoptes/client/subject_sets.rb +5 -5
- data/lib/panoptes/client/subjects.rb +2 -2
- data/lib/panoptes/client/user_groups.rb +6 -6
- data/lib/panoptes/client/version.rb +1 -1
- data/lib/panoptes/client/workflows.rb +2 -2
- data/lib/panoptes/endpoints/base_endpoint.rb +102 -0
- data/lib/panoptes/endpoints/json_api_endpoint.rb +26 -0
- data/lib/panoptes/endpoints/json_endpoint.rb +18 -0
- data/lib/panoptes/session.rb +6 -0
- data/lib/panoptes/talk_client.rb +2 -22
- data/panoptes-client.gemspec +2 -0
- metadata +40 -3
- data/lib/panoptes/concerns/common_client.rb +0 -77
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3621f283592595fbf4099b4bfc445e5114b0e18e
|
4
|
+
data.tar.gz: 3a54d9787e2b0db82594ccd408376696161a780c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 516d1f3d47837241e73c0a30cc21ea3691c367b290a39284f088d98873d1c4aa8b2c63ba8b97ce2325dfc8befbedd170d4e473ca3497e2ca8cc0ec2dc8eeae43
|
7
|
+
data.tar.gz: 5d3f8289862edb747d826bce689ad3f3eff82ab310c7e7ff29d13998bfc807671982ae68baf3f8658cf0a5b793614da7c8b98cb45cc791d941556a4462c5b194
|
data/.hound.yml
ADDED
data/.ruby-style.yml
ADDED
@@ -0,0 +1,206 @@
|
|
1
|
+
inherit_from: .rubocop_todo.yml
|
2
|
+
|
3
|
+
AllCops:
|
4
|
+
Exclude:
|
5
|
+
- "vendor/**/*"
|
6
|
+
- "db/schema.rb"
|
7
|
+
UseCache: false
|
8
|
+
|
9
|
+
Style/DotPosition:
|
10
|
+
Description: Checks the position of the dot in multi-line method calls.
|
11
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#consistent-multi-line-chains
|
12
|
+
Enabled: true
|
13
|
+
EnforcedStyle: leading
|
14
|
+
SupportedStyles:
|
15
|
+
- leading
|
16
|
+
- trailing
|
17
|
+
Style/FileName:
|
18
|
+
Description: Use snake_case for source file names.
|
19
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#snake-case-files
|
20
|
+
Enabled: true
|
21
|
+
Exclude: []
|
22
|
+
Style/GuardClause:
|
23
|
+
Description: Check for conditionals that can be replaced with guard clauses
|
24
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-nested-conditionals
|
25
|
+
Enabled: false
|
26
|
+
MinBodyLength: 1
|
27
|
+
Style/IfUnlessModifier:
|
28
|
+
Description: Favor modifier if/unless usage when you have a single-line body.
|
29
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#if-as-a-modifier
|
30
|
+
Enabled: false
|
31
|
+
MaxLineLength: 80
|
32
|
+
Style/OptionHash:
|
33
|
+
Description: Don't use option hashes when you can use keyword arguments.
|
34
|
+
Enabled: false
|
35
|
+
Style/ParallelAssignment:
|
36
|
+
Enabled: false
|
37
|
+
Style/PercentLiteralDelimiters:
|
38
|
+
Description: Use `%`-literal delimiters consistently
|
39
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#percent-literal-braces
|
40
|
+
Enabled: false
|
41
|
+
PreferredDelimiters:
|
42
|
+
"%": "()"
|
43
|
+
"%i": "()"
|
44
|
+
"%q": "()"
|
45
|
+
"%Q": "()"
|
46
|
+
"%r": "{}"
|
47
|
+
"%s": "()"
|
48
|
+
"%w": "()"
|
49
|
+
"%W": "()"
|
50
|
+
"%x": "()"
|
51
|
+
Style/PredicateName:
|
52
|
+
Description: Check the names of predicate methods.
|
53
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#bool-methods-qmark
|
54
|
+
Enabled: true
|
55
|
+
NamePrefix:
|
56
|
+
- is_
|
57
|
+
- has_
|
58
|
+
- have_
|
59
|
+
NamePrefixBlacklist:
|
60
|
+
- is_
|
61
|
+
Exclude:
|
62
|
+
- spec/**/*
|
63
|
+
Style/RaiseArgs:
|
64
|
+
Description: Checks the arguments passed to raise/fail.
|
65
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#exception-class-messages
|
66
|
+
Enabled: false
|
67
|
+
EnforcedStyle: exploded
|
68
|
+
SupportedStyles:
|
69
|
+
- compact
|
70
|
+
- exploded
|
71
|
+
Style/SignalException:
|
72
|
+
Description: Checks for proper usage of fail and raise.
|
73
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#fail-method
|
74
|
+
Enabled: false
|
75
|
+
EnforcedStyle: semantic
|
76
|
+
SupportedStyles:
|
77
|
+
- only_raise
|
78
|
+
- only_fail
|
79
|
+
- semantic
|
80
|
+
Style/SingleLineBlockParams:
|
81
|
+
Description: Enforces the names of some block params.
|
82
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#reduce-blocks
|
83
|
+
Enabled: false
|
84
|
+
Methods:
|
85
|
+
- reduce:
|
86
|
+
- a
|
87
|
+
- e
|
88
|
+
- inject:
|
89
|
+
- a
|
90
|
+
- e
|
91
|
+
Style/SingleLineMethods:
|
92
|
+
Description: Avoid single-line methods.
|
93
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-single-line-methods
|
94
|
+
Enabled: false
|
95
|
+
AllowIfMethodIsEmpty: true
|
96
|
+
Metrics/AbcSize:
|
97
|
+
Description: A calculated magnitude based on number of assignments, branches, and
|
98
|
+
conditions.
|
99
|
+
Enabled: false
|
100
|
+
Max: 15
|
101
|
+
Metrics/ClassLength:
|
102
|
+
Description: Avoid classes longer than 100 lines of code.
|
103
|
+
Enabled: false
|
104
|
+
CountComments: false
|
105
|
+
Max: 100
|
106
|
+
Metrics/LineLength:
|
107
|
+
Enabled: false
|
108
|
+
Metrics/ModuleLength:
|
109
|
+
CountComments: false
|
110
|
+
Max: 100
|
111
|
+
Description: Avoid modules longer than 100 lines of code.
|
112
|
+
Enabled: false
|
113
|
+
Metrics/CyclomaticComplexity:
|
114
|
+
Description: A complexity metric that is strongly correlated to the number of test
|
115
|
+
cases needed to validate a method.
|
116
|
+
Enabled: false
|
117
|
+
Max: 6
|
118
|
+
Metrics/MethodLength:
|
119
|
+
Description: Avoid methods longer than 10 lines of code.
|
120
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#short-methods
|
121
|
+
Enabled: false
|
122
|
+
CountComments: false
|
123
|
+
Max: 10
|
124
|
+
Metrics/ParameterLists:
|
125
|
+
Description: Avoid parameter lists longer than three or four parameters.
|
126
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#too-many-params
|
127
|
+
Enabled: false
|
128
|
+
Max: 5
|
129
|
+
CountKeywordArgs: true
|
130
|
+
Metrics/PerceivedComplexity:
|
131
|
+
Description: A complexity metric geared towards measuring complexity for a human
|
132
|
+
reader.
|
133
|
+
Enabled: false
|
134
|
+
Max: 7
|
135
|
+
Lint/AssignmentInCondition:
|
136
|
+
Description: Don't use assignment in conditions.
|
137
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#safe-assignment-in-condition
|
138
|
+
Enabled: false
|
139
|
+
AllowSafeAssignment: true
|
140
|
+
Style/InlineComment:
|
141
|
+
Description: Avoid inline comments.
|
142
|
+
Enabled: false
|
143
|
+
Style/AccessorMethodName:
|
144
|
+
Description: Check the naming of accessor methods for get_/set_.
|
145
|
+
Enabled: false
|
146
|
+
Style/Alias:
|
147
|
+
Description: Use alias_method instead of alias.
|
148
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#alias-method
|
149
|
+
Enabled: false
|
150
|
+
Style/Documentation:
|
151
|
+
Description: Document classes and non-namespace modules.
|
152
|
+
Enabled: false
|
153
|
+
Style/DoubleNegation:
|
154
|
+
Description: Checks for uses of double negation (!!).
|
155
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-bang-bang
|
156
|
+
Enabled: false
|
157
|
+
Style/EachWithObject:
|
158
|
+
Description: Prefer `each_with_object` over `inject` or `reduce`.
|
159
|
+
Enabled: false
|
160
|
+
Style/EmptyLiteral:
|
161
|
+
Description: Prefer literals to Array.new/Hash.new/String.new.
|
162
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#literal-array-hash
|
163
|
+
Enabled: false
|
164
|
+
Style/ModuleFunction:
|
165
|
+
Description: Checks for usage of `extend self` in modules.
|
166
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#module-function
|
167
|
+
Enabled: false
|
168
|
+
Style/OneLineConditional:
|
169
|
+
Description: Favor the ternary operator(?:) over if/then/else/end constructs.
|
170
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#ternary-operator
|
171
|
+
Enabled: false
|
172
|
+
Style/PerlBackrefs:
|
173
|
+
Description: Avoid Perl-style regex back references.
|
174
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-perl-regexp-last-matchers
|
175
|
+
Enabled: false
|
176
|
+
Style/Send:
|
177
|
+
Description: Prefer `Object#__send__` or `Object#public_send` to `send`, as `send`
|
178
|
+
may overlap with existing methods.
|
179
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#prefer-public-send
|
180
|
+
Enabled: false
|
181
|
+
Style/SpecialGlobalVars:
|
182
|
+
Description: Avoid Perl-style global variables.
|
183
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-cryptic-perlisms
|
184
|
+
Enabled: false
|
185
|
+
Style/VariableInterpolation:
|
186
|
+
Description: Don't interpolate global, instance and class variables directly in
|
187
|
+
strings.
|
188
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#curlies-interpolate
|
189
|
+
Enabled: false
|
190
|
+
Style/WhenThen:
|
191
|
+
Description: Use when x then ... for one-line cases.
|
192
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#one-line-cases
|
193
|
+
Enabled: false
|
194
|
+
Lint/EachWithObjectArgument:
|
195
|
+
Description: Check for immutable argument given to each_with_object.
|
196
|
+
Enabled: true
|
197
|
+
Lint/HandleExceptions:
|
198
|
+
Description: Don't suppress exception.
|
199
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#dont-hide-exceptions
|
200
|
+
Enabled: false
|
201
|
+
Lint/LiteralInCondition:
|
202
|
+
Description: Checks of literals used in conditions.
|
203
|
+
Enabled: false
|
204
|
+
Lint/LiteralInInterpolation:
|
205
|
+
Description: Checks for literals used in interpolation.
|
206
|
+
Enabled: false
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
# 0.2.8
|
2
|
+
|
3
|
+
* Merged Client and TalkClient: `client.discussions` is now just on Client. TalkClient is still present as an alias for Client
|
4
|
+
* Add `client.create_comment` to post a comment in a talk discussions
|
5
|
+
* Add `client.current_user` to get information contained in the authentication token, if given
|
6
|
+
* Add `client.cellect_workflows` to get information on workflows using the cellect services
|
7
|
+
* Add `client.cellect_subjects` to get subject information for a given cellect workflow
|
8
|
+
|
1
9
|
# 0.2.7
|
2
10
|
|
3
11
|
* Add `TalkClient` to interact with the talk api.
|
@@ -0,0 +1,14 @@
|
|
1
|
+
-----BEGIN PUBLIC KEY-----
|
2
|
+
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvbmZ42QexoMJ1J9z47Y2
|
3
|
+
7q5qvtE1mblpOnN7g4ItumcnoCv8xfdbhnzkHj/YBtqVoHhAVNwxSJKyQ4tZBehg
|
4
|
+
yYMRzLzBeWO8vG8V/NqM/tmUXca3rvPqt8I7zMoesSggawwz3/Gsa6KFC0OLjDh+
|
5
|
+
vE1HlqNX6usKiGmt6fv3KVU9cjtfREIieXgr36nkJDtIVJ2/hX1LY/v0+AEjZaFj
|
6
|
+
IzXSihNkjPnq2ymdm0YtV0Mmy1sK4qBY8c/zCWQ9lisILu+/Ix2YwVlDXeV9CErE
|
7
|
+
31b2jkPUVfLbCyeGPEIbYJw2pSiFWkuDR2VZaq+qeUbAwDfeu1OwueMZMt54vSYF
|
8
|
+
AKOxqMJtkrf8hxLSBZepk9sTS20T7gaEUyBhyeycarQqY34+VwG6UqLSy2H/Mq7r
|
9
|
+
5J8x7fnZPAtkFizcu/YDsELmD7Rw8SQ389NzApLi1jx8eSTZT+nqetU4FPs4CGCd
|
10
|
+
A/XMj2kAz/IA7LbV4hhbx1tTwTo88Xzk9knTknFv1/sE/j+KeUTeA9dE7EniIgOg
|
11
|
+
V01zobEXAP5Eyf3+OwYv+Qvq3cV2BvRZfEBhzj1RezVEh187hfCtCaSVf3YrEeL2
|
12
|
+
MM74OPotMaVyaJFxj/GxhrahOgSv4TbMYk93d+vcIa0clO7wXrJJXoWwi3XpQvk7
|
13
|
+
SwgqmRqSTqDuxJqlJAuVhmMCAwEAAQ==
|
14
|
+
-----END PUBLIC KEY-----
|
@@ -0,0 +1,14 @@
|
|
1
|
+
-----BEGIN PUBLIC KEY-----
|
2
|
+
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEArqLiWfs+Nm3BBMu9bcma
|
3
|
+
JaFhfSpKoHwsFjzRzkdFO0uKXPkS5nJq3UD/ZORr31XKYmwlbhGBzvpBUSoTmsjj
|
4
|
+
AXXP9cOlX/opoojuII2JXoUPjZH+YDl4y4M7YzXLyVKYW0FYR2pBXyhtEL9Lx0Ny
|
5
|
+
Nw2DW6p7Z9RwoU46WkapjMWor2wAlpnUM4ngDM/7ysEg8oi9KExrXlI4MCH1sVqj
|
6
|
+
U++8zkIXarqyDnyVk94ZoGA8EEqjeK3s3HonGG/DZyoj7OMcRa81fm94Sage5PWd
|
7
|
+
sJfgUw8bcj3/h/boRIJSMwRv1IJVQxz2o44es6dN+12q3hpXBhCfVZWz3MgoJFpt
|
8
|
+
t3e+KHB3UDBEIo55aPgbUAeuWV1IrBqZIQWLZcce4pzgS+A+0JgeetwbzubjHfZu
|
9
|
+
8FQ/d+29M8N+R+TOS2WzVXCKzEZtw1BZ8V595X1Rf9FcklnA6CH32LybQD4/4ALz
|
10
|
+
JGx2WaCa2246pgJzT7fIo/L/bgRuEsBfwMR+wcOVr7yroFrndEyw1eGv2RuFsLNH
|
11
|
+
JwOjF+MTg/wtvaI8AXSTCSeKfoljUndNsiPTO8gJmiAq4yWFiMP1fKm/uczN6PKy
|
12
|
+
rYdQDSMt3a8UXZbw+9DocHDD0VvDHg6zuaa75tZrb7WvGrO7kbhUrJYwNCAbD2kN
|
13
|
+
Ca6VZnNmmy57yB/+jhBSNkECAwEAAQ==
|
14
|
+
-----END PUBLIC KEY-----
|
data/lib/panoptes/client.rb
CHANGED
@@ -1,19 +1,18 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
1
|
+
require 'panoptes/endpoints/json_api_endpoint'
|
2
|
+
require 'panoptes/endpoints/json_endpoint'
|
3
|
+
|
4
|
+
require 'panoptes/client/cellect'
|
5
|
+
require 'panoptes/client/comments'
|
6
|
+
require 'panoptes/client/discussions'
|
7
|
+
require 'panoptes/client/me'
|
8
|
+
require 'panoptes/client/projects'
|
9
|
+
require 'panoptes/client/subject_sets'
|
10
|
+
require 'panoptes/client/subjects'
|
11
|
+
require 'panoptes/client/user_groups'
|
12
|
+
require 'panoptes/client/workflows'
|
8
13
|
|
9
14
|
module Panoptes
|
10
15
|
class Client
|
11
|
-
class GenericError < StandardError; end
|
12
|
-
class ConnectionFailed < GenericError; end
|
13
|
-
class ResourceNotFound < GenericError; end
|
14
|
-
class ServerError < GenericError; end
|
15
|
-
|
16
|
-
include Panoptes::CommonClient
|
17
16
|
include Panoptes::Client::Me
|
18
17
|
include Panoptes::Client::Projects
|
19
18
|
include Panoptes::Client::Subjects
|
@@ -21,73 +20,60 @@ module Panoptes
|
|
21
20
|
include Panoptes::Client::UserGroups
|
22
21
|
include Panoptes::Client::Workflows
|
23
22
|
|
24
|
-
|
25
|
-
|
26
|
-
handle_response(response)
|
27
|
-
end
|
28
|
-
|
29
|
-
def post(path, body = {})
|
30
|
-
response = conn.post("/api" + path, body)
|
31
|
-
handle_response(response)
|
32
|
-
end
|
23
|
+
include Panoptes::Client::Discussions
|
24
|
+
include Panoptes::Client::Comments
|
33
25
|
|
34
|
-
|
35
|
-
headers = {}
|
36
|
-
headers["If-Match"] = etag if etag
|
26
|
+
include Panoptes::Client::Cellect
|
37
27
|
|
38
|
-
|
39
|
-
|
28
|
+
class GenericError < StandardError; end
|
29
|
+
class ConnectionFailed < GenericError; end
|
30
|
+
class ResourceNotFound < GenericError; end
|
31
|
+
class ServerError < GenericError; end
|
32
|
+
class NotLoggedIn < GenericError; end
|
33
|
+
|
34
|
+
attr_reader :env, :auth, :panoptes, :talk, :cellect
|
35
|
+
|
36
|
+
def initialize(env: :production, auth: {}, public_key_path: nil)
|
37
|
+
@env = env
|
38
|
+
@auth = auth
|
39
|
+
@public_key_path = public_key_path
|
40
|
+
@panoptes = Panoptes::Endpoints::JsonApiEndpoint.new(
|
41
|
+
auth: auth, url: panoptes_url, prefix: '/api'
|
42
|
+
)
|
43
|
+
@talk = Panoptes::Endpoints::JsonApiEndpoint.new(
|
44
|
+
auth: auth, url: talk_url
|
45
|
+
)
|
46
|
+
@cellect = Panoptes::Endpoints::JsonEndpoint.new(
|
47
|
+
url: panoptes_url, prefix: '/cellect'
|
48
|
+
)
|
40
49
|
end
|
41
50
|
|
42
|
-
def
|
43
|
-
|
44
|
-
headers["If-Match"] = etag if etag
|
51
|
+
def current_user
|
52
|
+
raise NotLoggedIn unless @auth[:token]
|
45
53
|
|
46
|
-
|
47
|
-
|
54
|
+
payload, = JWT.decode @auth[:token], jwt_signing_public_key, algorithm: 'RS512'
|
55
|
+
payload.fetch('data')
|
48
56
|
end
|
49
57
|
|
50
|
-
def
|
51
|
-
|
52
|
-
headers["If-Match"] = etag if etag
|
53
|
-
|
54
|
-
response = conn.delete("/api" + path, query, headers)
|
55
|
-
handle_response(response)
|
58
|
+
def jwt_signing_public_key
|
59
|
+
@jwt_signing_public_key ||= OpenSSL::PKey::RSA.new(File.read(@public_key_path))
|
56
60
|
end
|
57
61
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
last_response = get(next_path, query)
|
65
|
-
if block_given?
|
66
|
-
yield data, last_response
|
67
|
-
else
|
68
|
-
data[resource].concat(last_response[resource]) if data[resource].is_a?(Array)
|
69
|
-
data["meta"][resource].merge!(last_response["meta"][resource])
|
70
|
-
data["links"].merge!(last_response["links"])
|
71
|
-
end
|
62
|
+
def panoptes_url
|
63
|
+
case env
|
64
|
+
when :production, 'production'.freeze
|
65
|
+
'https://panoptes.zooniverse.org'.freeze
|
66
|
+
else
|
67
|
+
'https://panoptes-staging.zooniverse.org'.freeze
|
72
68
|
end
|
73
|
-
|
74
|
-
data
|
75
|
-
end
|
76
|
-
|
77
|
-
private
|
78
|
-
|
79
|
-
def conn
|
80
|
-
@conn
|
81
69
|
end
|
82
70
|
|
83
|
-
def
|
84
|
-
case
|
85
|
-
when
|
86
|
-
|
87
|
-
when 400..600
|
88
|
-
raise ServerError.new(response.body)
|
71
|
+
def talk_url
|
72
|
+
case env
|
73
|
+
when :production, 'production'.freeze
|
74
|
+
'https://talk.zooniverse.org'.freeze
|
89
75
|
else
|
90
|
-
|
76
|
+
'https://talk-staging.zooniverse.org'.freeze
|
91
77
|
end
|
92
78
|
end
|
93
79
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
|
3
|
+
module Panoptes
|
4
|
+
class Client
|
5
|
+
module Cellect
|
6
|
+
# Fetches all cellect-enabled, launched workflows.
|
7
|
+
#
|
8
|
+
# @return [Hash] the list of workflows
|
9
|
+
def cellect_workflows
|
10
|
+
cellect.get '/workflows'
|
11
|
+
end
|
12
|
+
|
13
|
+
# Fetches all active subjects for a cellect-enabled workflow.
|
14
|
+
#
|
15
|
+
# @param workflow_id [Integer] the id of the workflow
|
16
|
+
# @return [Hash] the list of subjects
|
17
|
+
def cellect_subjects(workflow_id)
|
18
|
+
cellect.get '/subjects', workflow_id: workflow_id
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Panoptes
|
2
|
+
class Client
|
3
|
+
module Comments
|
4
|
+
# Post a comment to a talk discussion
|
5
|
+
#
|
6
|
+
# @param discussion_id [Integer] filter by focussable id
|
7
|
+
# @param focus_type [String] filter by focussable type
|
8
|
+
# @return list of discussions
|
9
|
+
def create_comment(discussion_id:, body:)
|
10
|
+
user_id = current_user["id"]
|
11
|
+
response = talk.post("/comments", comments: {discussion_id: discussion_id, body: body, user_id: user_id})
|
12
|
+
response.fetch("comments")[0]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/panoptes/client/me.rb
CHANGED
@@ -10,7 +10,7 @@ module Panoptes
|
|
10
10
|
params = {}
|
11
11
|
params[:search] = search if search
|
12
12
|
|
13
|
-
paginate("/projects", params)["projects"]
|
13
|
+
panoptes.paginate("/projects", params)["projects"]
|
14
14
|
end
|
15
15
|
|
16
16
|
# Starts a background process to generate a new CSV export of all the classifications in the project.
|
@@ -19,7 +19,7 @@ module Panoptes
|
|
19
19
|
# @return [Hash] the medium information where the export will be stored when it's generated
|
20
20
|
def create_classifications_export(project_id)
|
21
21
|
params = {media: {content_type: "text/csv", metadata: { recipients: []}}}
|
22
|
-
post("/projects/#{project_id}/classifications_export", params)["media"].first
|
22
|
+
panoptes.post("/projects/#{project_id}/classifications_export", params)["media"].first
|
23
23
|
end
|
24
24
|
|
25
25
|
# Starts a background process to generate a new CSV export of all the subjects in the project.
|
@@ -28,7 +28,7 @@ module Panoptes
|
|
28
28
|
# @return [Hash] the medium information where the export will be stored when it's generated
|
29
29
|
def create_subjects_export(project_id)
|
30
30
|
params = {media: {content_type: "text/csv", metadata: { recipients: []}}}
|
31
|
-
post("/projects/#{project_id}/subjects_export", params)["media"].first
|
31
|
+
panoptes.post("/projects/#{project_id}/subjects_export", params)["media"].first
|
32
32
|
end
|
33
33
|
|
34
34
|
# Starts a background process to generate a new CSV export of all the workflows in the project.
|
@@ -37,7 +37,7 @@ module Panoptes
|
|
37
37
|
# @return [Hash] the medium information where the export will be stored when it's generated
|
38
38
|
def create_workflows_export(project_id)
|
39
39
|
params = {media: {content_type: "text/csv", metadata: { recipients: []}}}
|
40
|
-
post("/projects/#{project_id}/workflows_export", params)["media"].first
|
40
|
+
panoptes.post("/projects/#{project_id}/workflows_export", params)["media"].first
|
41
41
|
end
|
42
42
|
|
43
43
|
# Starts a background process to generate a new CSV export of all the workflow_contents in the project.
|
@@ -46,7 +46,7 @@ module Panoptes
|
|
46
46
|
# @return [Hash] the medium information where the export will be stored when it's generated
|
47
47
|
def create_workflow_contents_export(project_id)
|
48
48
|
params = {media: {content_type: "text/csv", metadata: { recipients: []}}}
|
49
|
-
post("/projects/#{project_id}/workflow_contents_export", params)["media"].first
|
49
|
+
panoptes.post("/projects/#{project_id}/workflow_contents_export", params)["media"].first
|
50
50
|
end
|
51
51
|
|
52
52
|
# Starts a background process to generate a new CSV export of the aggretation results of the project.
|
@@ -55,7 +55,7 @@ module Panoptes
|
|
55
55
|
# @return [Hash] the medium information where the export will be stored when it's generated
|
56
56
|
def create_aggregations_export(project_id)
|
57
57
|
params = {media: {content_type: "application/x-gzip", metadata: { recipients: []}}}
|
58
|
-
post("/projects/#{project_id}/aggregations_export", params)["media"].first
|
58
|
+
panoptes.post("/projects/#{project_id}/aggregations_export", params)["media"].first
|
59
59
|
end
|
60
60
|
end
|
61
61
|
end
|
@@ -2,25 +2,25 @@ module Panoptes
|
|
2
2
|
class Client
|
3
3
|
module SubjectSets
|
4
4
|
def subject_set(subject_set_id)
|
5
|
-
response = get("/subject_sets/#{subject_set_id}")
|
5
|
+
response = panoptes.get("/subject_sets/#{subject_set_id}")
|
6
6
|
response.fetch("subject_sets").find {|i| i.fetch("id").to_s == subject_set_id.to_s }
|
7
7
|
end
|
8
8
|
|
9
9
|
def create_subject_set(attributes)
|
10
|
-
response = post("/subject_sets", subject_sets: attributes)
|
10
|
+
response = panoptes.post("/subject_sets", subject_sets: attributes)
|
11
11
|
response.fetch("subject_sets").first
|
12
12
|
end
|
13
13
|
|
14
14
|
def update_subject_set(subject_set_id, attributes)
|
15
|
-
response =
|
15
|
+
response = panoptes.connection.get("/api/subject_sets/#{subject_set_id}")
|
16
16
|
etag = response.headers["ETag"]
|
17
17
|
|
18
|
-
response = put("/subject_sets/#{subject_set_id}", {subject_sets: attributes}, etag: etag)
|
18
|
+
response = panoptes.put("/subject_sets/#{subject_set_id}", {subject_sets: attributes}, etag: etag)
|
19
19
|
response.fetch("subject_sets").first
|
20
20
|
end
|
21
21
|
|
22
22
|
def add_subjects_to_subject_set(subject_set_id, subject_ids)
|
23
|
-
response = post("/subject_sets/#{subject_set_id}/links/subjects", subjects: subject_ids)
|
23
|
+
response = panoptes.post("/subject_sets/#{subject_set_id}/links/subjects", subjects: subject_ids)
|
24
24
|
true
|
25
25
|
end
|
26
26
|
end
|
@@ -9,7 +9,7 @@ module Panoptes
|
|
9
9
|
query = {}
|
10
10
|
query[:subject_set_id] = subject_set_id
|
11
11
|
|
12
|
-
response = get("/subjects", query)
|
12
|
+
response = panoptes.get("/subjects", query)
|
13
13
|
response.fetch("subjects")
|
14
14
|
end
|
15
15
|
|
@@ -20,7 +20,7 @@ module Panoptes
|
|
20
20
|
# @param subject_id [Integer] the ID of a subject associated with that workflow (through one of the assigned subject_sets)
|
21
21
|
# @return nothing
|
22
22
|
def retire_subject(workflow_id, subject_id, reason: nil)
|
23
|
-
post("/workflows/#{workflow_id}/retired_subjects", {
|
23
|
+
panoptes.post("/workflows/#{workflow_id}/retired_subjects", {
|
24
24
|
admin: true,
|
25
25
|
subject_id: subject_id,
|
26
26
|
retirement_reason: reason
|
@@ -7,31 +7,31 @@ module Panoptes
|
|
7
7
|
# @param name [String] The name of the user group. Must be unique for the entirity of Zooniverse.
|
8
8
|
# @return [Hash] The created user group.
|
9
9
|
def create_user_group(name)
|
10
|
-
post("/user_groups", user_groups: {
|
10
|
+
panoptes.post("/user_groups", user_groups: {
|
11
11
|
name: name
|
12
12
|
})["user_groups"][0]
|
13
13
|
end
|
14
14
|
|
15
15
|
def user_groups
|
16
|
-
get("/user_groups")["user_groups"]
|
16
|
+
panoptes.get("/user_groups")["user_groups"]
|
17
17
|
end
|
18
18
|
|
19
19
|
def join_user_group(user_group_id, user_id, join_token:)
|
20
|
-
post("/memberships", memberships: {
|
20
|
+
panoptes.post("/memberships", memberships: {
|
21
21
|
join_token: join_token,
|
22
22
|
links: {user: user_id, user_group: user_group_id}
|
23
23
|
})["memberships"][0]
|
24
24
|
end
|
25
25
|
|
26
26
|
def remove_user_from_user_group(user_group_id, user_id)
|
27
|
-
delete("/user_groups/#{user_group_id}/links/users/#{user_id}")
|
27
|
+
panoptes.delete("/user_groups/#{user_group_id}/links/users/#{user_id}")
|
28
28
|
end
|
29
29
|
|
30
30
|
def delete_user_group(user_group_id)
|
31
|
-
response =
|
31
|
+
response = panoptes.connection.get("/api/user_groups/#{user_group_id}")
|
32
32
|
etag = response.headers["ETag"]
|
33
33
|
|
34
|
-
delete("/user_groups/#{user_group_id}", {}, etag: etag)
|
34
|
+
panoptes.delete("/user_groups/#{user_group_id}", {}, etag: etag)
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
@@ -2,12 +2,12 @@ module Panoptes
|
|
2
2
|
class Client
|
3
3
|
module Workflows
|
4
4
|
def workflow(workflow_id)
|
5
|
-
response = get("/workflows/#{workflow_id}")
|
5
|
+
response = panoptes.get("/workflows/#{workflow_id}")
|
6
6
|
response.fetch("workflows").find {|i| i.fetch("id").to_s == workflow_id.to_s }
|
7
7
|
end
|
8
8
|
|
9
9
|
def create_workflow(attributes)
|
10
|
-
response = post("/workflows", workflows: attributes)
|
10
|
+
response = panoptes.post("/workflows", workflows: attributes)
|
11
11
|
response.fetch("workflows").first
|
12
12
|
end
|
13
13
|
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'faraday_middleware'
|
3
|
+
require 'faraday/panoptes'
|
4
|
+
|
5
|
+
module Panoptes
|
6
|
+
module Endpoints
|
7
|
+
class BaseEndpoint
|
8
|
+
attr_reader :auth, :url, :prefix
|
9
|
+
|
10
|
+
# @param auth [Hash<token: String, client_id: String, client_secret: String>] Authentication details
|
11
|
+
# * either nothing,
|
12
|
+
# * a hash with +:token+ (an existing OAuth user token),
|
13
|
+
# * or a hash with +:client_id+ and +:client_secret+
|
14
|
+
# (a keypair for an OAuth Application).
|
15
|
+
# @param url [String] API location to use.
|
16
|
+
# @param prefix [String] An optional API url prefix
|
17
|
+
# @yield Allows an optional block to configure the faraday connection
|
18
|
+
# @yieldparam faraday [Faraday::Connection] The faraday connection
|
19
|
+
def initialize(auth: {}, url: nil, prefix: nil, &config)
|
20
|
+
@auth = auth
|
21
|
+
@url = url
|
22
|
+
@prefix = prefix
|
23
|
+
@config = config
|
24
|
+
end
|
25
|
+
|
26
|
+
def connection
|
27
|
+
@connection ||= Faraday.new(url) do |faraday|
|
28
|
+
auth_request faraday, auth
|
29
|
+
configure faraday
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def get(path, query = {})
|
34
|
+
request :get, path, query
|
35
|
+
end
|
36
|
+
|
37
|
+
def post(path, body = {})
|
38
|
+
request :post, path, body
|
39
|
+
end
|
40
|
+
|
41
|
+
def put(path, body = {}, etag: nil)
|
42
|
+
request :put, path, body, etag_header(etag)
|
43
|
+
end
|
44
|
+
|
45
|
+
def patch(path, body = {}, etag: nil)
|
46
|
+
request :patch, path, body, etag_header(etag)
|
47
|
+
end
|
48
|
+
|
49
|
+
def delete(path, query = {}, etag: nil)
|
50
|
+
request :delete, path, query, etag_header(etag)
|
51
|
+
end
|
52
|
+
|
53
|
+
def etag_header(etag)
|
54
|
+
{}.tap do |headers|
|
55
|
+
headers['If-Match'] = etag if etag
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def request(method, path, *args)
|
60
|
+
path = "#{prefix}/#{path}" if prefix
|
61
|
+
handle_response connection.send(method, path, *args)
|
62
|
+
end
|
63
|
+
|
64
|
+
def handle_response(response)
|
65
|
+
case response.status
|
66
|
+
when 404
|
67
|
+
raise ResourceNotFound, status: response.status, body: response.body
|
68
|
+
when 400..600
|
69
|
+
raise ServerError.new, response.body
|
70
|
+
else
|
71
|
+
response.body
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
protected
|
76
|
+
|
77
|
+
def configure(faraday)
|
78
|
+
if @config
|
79
|
+
@config.call faraday
|
80
|
+
else
|
81
|
+
faraday.request :panoptes_api_v1
|
82
|
+
faraday.request :json
|
83
|
+
faraday.response :json
|
84
|
+
faraday.adapter Faraday.default_adapter
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def auth_request(faraday, auth)
|
89
|
+
if auth[:token]
|
90
|
+
faraday.request :panoptes_access_token,
|
91
|
+
url: url,
|
92
|
+
access_token: auth[:token]
|
93
|
+
elsif auth[:client_id] && auth[:client_secret]
|
94
|
+
faraday.request :panoptes_client_credentials,
|
95
|
+
url: url,
|
96
|
+
client_id: auth[:client_id],
|
97
|
+
client_secret: auth[:client_secret]
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require_relative 'base_endpoint'
|
2
|
+
|
3
|
+
module Panoptes
|
4
|
+
module Endpoints
|
5
|
+
class JsonApiEndpoint < BaseEndpoint
|
6
|
+
# Get a path and perform automatic depagination
|
7
|
+
def paginate(path, query, resource: nil)
|
8
|
+
resource = path.split('/').last if resource.nil?
|
9
|
+
data = last_response = get(path, query)
|
10
|
+
|
11
|
+
while next_path = last_response['meta'][resource]['next_href']
|
12
|
+
last_response = get(next_path, query)
|
13
|
+
if block_given?
|
14
|
+
yield data, last_response
|
15
|
+
else
|
16
|
+
data[resource].concat(last_response[resource]) if data[resource].is_a?(Array)
|
17
|
+
data['meta'][resource].merge!(last_response['meta'][resource])
|
18
|
+
data['links'].merge!(last_response['links'])
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
data
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative 'base_endpoint'
|
2
|
+
|
3
|
+
module Panoptes
|
4
|
+
module Endpoints
|
5
|
+
class JsonEndpoint < BaseEndpoint
|
6
|
+
# Automatically configured connection to use JSON requests/responses
|
7
|
+
# @see Panoptes::Endpoints::BaseEndpoint#initialize
|
8
|
+
def initialize(auth: {}, url: nil, prefix: nil, &config)
|
9
|
+
super auth: auth, url: url, prefix: prefix do |faraday|
|
10
|
+
config&.call faraday
|
11
|
+
faraday.request :json
|
12
|
+
faraday.response :json
|
13
|
+
faraday.adapter Faraday.default_adapter
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/panoptes/talk_client.rb
CHANGED
@@ -1,25 +1,5 @@
|
|
1
|
-
require "panoptes/concerns/common_client"
|
2
|
-
require "panoptes/client/discussions"
|
3
|
-
|
4
1
|
module Panoptes
|
5
|
-
|
6
|
-
|
7
|
-
include Panoptes::Client::Discussions
|
8
|
-
|
9
|
-
# @param auth [Hash] Authentication details
|
10
|
-
# * either nothing,
|
11
|
-
# * a hash with +:token+ (an existing OAuth user token),
|
12
|
-
# * or a hash with +:client_id+ and +:client_secret+ (a keypair for an OAuth Application).
|
13
|
-
# A client is the main interface to the talk v2 API.
|
14
|
-
# @param url [String] Optional override for the API location to use. Defaults to the official talk api production environment.
|
15
|
-
# @param auth_url [String] Optional override for the auth API location to use. Defaults to the official api production environment.
|
16
|
-
def initialize(auth: {}, url: PROD_TALK_API_URL, auth_url: PROD_API_URL)
|
17
|
-
super(auth: auth, url: url, auth_url: auth_url)
|
18
|
-
end
|
19
|
-
|
20
|
-
def get(path, query = {})
|
21
|
-
response = conn.get(path, query)
|
22
|
-
handle_response(response)
|
23
|
-
end
|
2
|
+
# Backwards compat
|
3
|
+
class TalkClient < Client
|
24
4
|
end
|
25
5
|
end
|
data/panoptes-client.gemspec
CHANGED
@@ -20,9 +20,11 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.add_dependency "faraday"
|
22
22
|
spec.add_dependency "faraday-panoptes", "~> 0.2.0"
|
23
|
+
spec.add_dependency "jwt", "~> 1.5.0"
|
23
24
|
|
24
25
|
spec.add_development_dependency "bundler", "~> 1.11"
|
25
26
|
spec.add_development_dependency "rake", "~> 10.0"
|
26
27
|
spec.add_development_dependency "rspec", "~> 3.0"
|
28
|
+
spec.add_development_dependency "timecop", "~> 0.8.0"
|
27
29
|
spec.add_development_dependency "yard"
|
28
30
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: panoptes-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marten Veldthuis
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-08-
|
11
|
+
date: 2016-08-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 0.2.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: jwt
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.5.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.5.0
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: bundler
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,6 +94,20 @@ dependencies:
|
|
80
94
|
- - "~>"
|
81
95
|
- !ruby/object:Gem::Version
|
82
96
|
version: '3.0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: timecop
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 0.8.0
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.8.0
|
83
111
|
- !ruby/object:Gem::Dependency
|
84
112
|
name: yard
|
85
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -102,7 +130,9 @@ extensions: []
|
|
102
130
|
extra_rdoc_files: []
|
103
131
|
files:
|
104
132
|
- ".gitignore"
|
133
|
+
- ".hound.yml"
|
105
134
|
- ".rspec"
|
135
|
+
- ".ruby-style.yml"
|
106
136
|
- ".travis.yml"
|
107
137
|
- CHANGELOG.md
|
108
138
|
- CODE_OF_CONDUCT.md
|
@@ -112,8 +142,12 @@ files:
|
|
112
142
|
- Rakefile
|
113
143
|
- bin/console
|
114
144
|
- bin/setup
|
145
|
+
- data/doorkeeper-jwt-production.pub
|
146
|
+
- data/doorkeeper-jwt-staging.pub
|
115
147
|
- lib/panoptes-client.rb
|
116
148
|
- lib/panoptes/client.rb
|
149
|
+
- lib/panoptes/client/cellect.rb
|
150
|
+
- lib/panoptes/client/comments.rb
|
117
151
|
- lib/panoptes/client/discussions.rb
|
118
152
|
- lib/panoptes/client/me.rb
|
119
153
|
- lib/panoptes/client/projects.rb
|
@@ -122,7 +156,10 @@ files:
|
|
122
156
|
- lib/panoptes/client/user_groups.rb
|
123
157
|
- lib/panoptes/client/version.rb
|
124
158
|
- lib/panoptes/client/workflows.rb
|
125
|
-
- lib/panoptes/
|
159
|
+
- lib/panoptes/endpoints/base_endpoint.rb
|
160
|
+
- lib/panoptes/endpoints/json_api_endpoint.rb
|
161
|
+
- lib/panoptes/endpoints/json_endpoint.rb
|
162
|
+
- lib/panoptes/session.rb
|
126
163
|
- lib/panoptes/talk_client.rb
|
127
164
|
- panoptes-client.gemspec
|
128
165
|
homepage: https://github.com/zooniverse/panoptes-client.rb
|
@@ -1,77 +0,0 @@
|
|
1
|
-
require 'faraday'
|
2
|
-
require 'faraday_middleware'
|
3
|
-
require 'faraday/panoptes'
|
4
|
-
|
5
|
-
require "panoptes/client/version"
|
6
|
-
|
7
|
-
module Panoptes
|
8
|
-
module CommonClient
|
9
|
-
PROD_API_URL = "https://panoptes.zooniverse.org".freeze
|
10
|
-
PROD_TALK_API_URL = "https://talk.zooniverse.org".freeze
|
11
|
-
|
12
|
-
# A client is the main interface to the API.
|
13
|
-
#
|
14
|
-
# @param auth [Hash] Authentication details
|
15
|
-
# * either nothing,
|
16
|
-
# * a hash with +:token+ (an existing OAuth user token),
|
17
|
-
# * or a hash with +:client_id+ and +:client_secret+ (a keypair for an OAuth Application).
|
18
|
-
# @param url [String] API location to use.
|
19
|
-
# @param auth_url [String] Auth API location to use.
|
20
|
-
def initialize(auth: {}, url: PROD_API_URL, auth_url: PROD_API_URL)
|
21
|
-
@conn = Faraday.new(url: url) do |faraday|
|
22
|
-
case
|
23
|
-
when auth[:token]
|
24
|
-
faraday.request :panoptes_access_token,
|
25
|
-
url: auth_url,
|
26
|
-
access_token: auth[:token]
|
27
|
-
when auth[:client_id] && auth[:client_secret]
|
28
|
-
faraday.request :panoptes_client_credentials,
|
29
|
-
url: auth_url,
|
30
|
-
client_id: auth[:client_id],
|
31
|
-
client_secret: auth[:client_secret]
|
32
|
-
end
|
33
|
-
|
34
|
-
faraday.request :panoptes_api_v1
|
35
|
-
faraday.request :json
|
36
|
-
faraday.response :json
|
37
|
-
faraday.adapter Faraday.default_adapter
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
# Get a path and perform automatic depagination
|
42
|
-
def paginate(path, query, resource: nil)
|
43
|
-
resource = path.split("/").last if resource.nil?
|
44
|
-
data = last_response = get(path, query)
|
45
|
-
|
46
|
-
while next_path = last_response["meta"][resource]["next_href"]
|
47
|
-
last_response = get(next_path, query)
|
48
|
-
if block_given?
|
49
|
-
yield data, last_response
|
50
|
-
else
|
51
|
-
data[resource].concat(last_response[resource]) if data[resource].is_a?(Array)
|
52
|
-
data["meta"][resource].merge!(last_response["meta"][resource])
|
53
|
-
data["links"].merge!(last_response["links"])
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
data
|
58
|
-
end
|
59
|
-
|
60
|
-
private
|
61
|
-
|
62
|
-
def conn
|
63
|
-
@conn
|
64
|
-
end
|
65
|
-
|
66
|
-
def handle_response(response)
|
67
|
-
case response.status
|
68
|
-
when 404
|
69
|
-
raise ResourceNotFound, status: response.status, body: response.body
|
70
|
-
when 400..600
|
71
|
-
raise ServerError.new(response.body)
|
72
|
-
else
|
73
|
-
response.body
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|