fabricio 1.0.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 +7 -0
- data/.codeclimate.yml +12 -0
- data/.idea/runConfigurations/IRB_console__fabricio.xml +23 -0
- data/.rspec +2 -0
- data/.rubocop.yml +1156 -0
- data/.travis.yml +10 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +149 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/docs/api_reference.md +611 -0
- data/docs/swagger-api.json +553 -0
- data/fabricio.gemspec +29 -0
- data/lib/fabricio.rb +2 -0
- data/lib/fabricio/authorization/abstract_session_storage.rb +26 -0
- data/lib/fabricio/authorization/authorization_client.rb +122 -0
- data/lib/fabricio/authorization/memory_session_storage.rb +35 -0
- data/lib/fabricio/authorization/session.rb +21 -0
- data/lib/fabricio/client/client.rb +92 -0
- data/lib/fabricio/models/abstract_model.rb +17 -0
- data/lib/fabricio/models/app.rb +24 -0
- data/lib/fabricio/models/build.rb +23 -0
- data/lib/fabricio/models/organization.rb +22 -0
- data/lib/fabricio/models/point.rb +17 -0
- data/lib/fabricio/networking/app_request_model_factory.rb +229 -0
- data/lib/fabricio/networking/build_request_model_factory.rb +103 -0
- data/lib/fabricio/networking/network_client.rb +101 -0
- data/lib/fabricio/networking/organization_request_model_factory.rb +27 -0
- data/lib/fabricio/networking/request_model.rb +39 -0
- data/lib/fabricio/services/app_service.rb +146 -0
- data/lib/fabricio/services/build_service.rb +59 -0
- data/lib/fabricio/services/organization_service.rb +33 -0
- data/lib/fabricio/version.rb +3 -0
- metadata +163 -0
@@ -0,0 +1,229 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'fabricio/networking/request_model'
|
3
|
+
|
4
|
+
module Fabricio
|
5
|
+
module Networking
|
6
|
+
# This factory creates request models for fetching data for App model object
|
7
|
+
class AppRequestModelFactory
|
8
|
+
|
9
|
+
# Server constants
|
10
|
+
FABRIC_API_URL = 'https://fabric.io'
|
11
|
+
FABRIC_GRAPHQL_API_URL = 'https://api-dash.fabric.io/graphql'
|
12
|
+
FABRIC_API_PATH = '/api/v2'
|
13
|
+
FABRIC_APPS_ENDPOINT = '/apps'
|
14
|
+
FABRIC_ORGANIZATIONS_ENDPOINT = '/organizations'
|
15
|
+
|
16
|
+
# Returns a request model for obtaining the list of all apps
|
17
|
+
#
|
18
|
+
# @return [Fabricio::Networking::RequestModel]
|
19
|
+
def all_apps_request_model
|
20
|
+
model = Fabricio::Networking::RequestModel.new do |config|
|
21
|
+
config.type = :GET
|
22
|
+
config.base_url = FABRIC_API_URL
|
23
|
+
config.api_path = FABRIC_API_PATH + FABRIC_APPS_ENDPOINT
|
24
|
+
end
|
25
|
+
model
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns a request model for obtaining a specific app
|
29
|
+
#
|
30
|
+
# @param app_id [String]
|
31
|
+
# @return [Fabricio::Networking::RequestModel]
|
32
|
+
def get_app_request_model(app_id)
|
33
|
+
path = "#{FABRIC_API_PATH}#{app_endpoint(app_id)}"
|
34
|
+
model = Fabricio::Networking::RequestModel.new do |config|
|
35
|
+
config.type = :GET
|
36
|
+
config.base_url = FABRIC_API_URL
|
37
|
+
config.api_path = path
|
38
|
+
end
|
39
|
+
model
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns a request model for obtaining the count of active users at the current moment
|
43
|
+
#
|
44
|
+
# @param session [Fabricio::Authorization::Session]
|
45
|
+
# @param app_id [String]
|
46
|
+
# @return [Fabricio::Networking::RequestModel]
|
47
|
+
def active_now_request_model(session, app_id)
|
48
|
+
path = growth_analytics_endpoint(session, app_id, 'active_now')
|
49
|
+
model = Fabricio::Networking::RequestModel.new do |config|
|
50
|
+
config.type = :GET
|
51
|
+
config.base_url = FABRIC_API_URL
|
52
|
+
config.api_path = path
|
53
|
+
end
|
54
|
+
model
|
55
|
+
end
|
56
|
+
|
57
|
+
# Returns a request model for obtaining the count of daily new users
|
58
|
+
#
|
59
|
+
# @param session [Fabricio::Authorization::Session]
|
60
|
+
# @param app_id [String]
|
61
|
+
# @param start_time [String] Timestamp of the start date
|
62
|
+
# @param end_time [String] Timestamp of the end date
|
63
|
+
# @return [Fabricio::Networking::RequestModel]
|
64
|
+
def daily_new_request_model(session, app_id, start_time, end_time)
|
65
|
+
path = growth_analytics_endpoint(session, app_id, 'daily_new')
|
66
|
+
params = time_range_params(start_time, end_time)
|
67
|
+
model = Fabricio::Networking::RequestModel.new do |config|
|
68
|
+
config.type = :GET
|
69
|
+
config.base_url = FABRIC_API_URL
|
70
|
+
config.api_path = path
|
71
|
+
config.params = params
|
72
|
+
end
|
73
|
+
model
|
74
|
+
end
|
75
|
+
|
76
|
+
# Returns a request model for obtaining the count of daily active users
|
77
|
+
#
|
78
|
+
# @param session [Fabricio::Authorization::Session]
|
79
|
+
# @param app_id [String]
|
80
|
+
# @param start_time [String] Timestamp of the start date
|
81
|
+
# @param end_time [String] Timestamp of the end date
|
82
|
+
# @param build [String] The version of the build. E.g. '4.0.1 (38)'
|
83
|
+
# @return [Fabricio::Networking::RequestModel]
|
84
|
+
def daily_active_request_model(session, app_id, start_time, end_time, build)
|
85
|
+
path = growth_analytics_endpoint(session, app_id, 'daily_active')
|
86
|
+
params = time_range_params(start_time, end_time)
|
87
|
+
params['build'] = build
|
88
|
+
model = Fabricio::Networking::RequestModel.new do |config|
|
89
|
+
config.type = :GET
|
90
|
+
config.base_url = FABRIC_API_URL
|
91
|
+
config.api_path = path
|
92
|
+
config.params = params
|
93
|
+
end
|
94
|
+
model
|
95
|
+
end
|
96
|
+
|
97
|
+
# Returns a request model for obtaining the count of sessions
|
98
|
+
#
|
99
|
+
# @param session [Fabricio::Authorization::Session]
|
100
|
+
# @param app_id [String]
|
101
|
+
# @param start_time [String] Timestamp of the start date
|
102
|
+
# @param end_time [String] Timestamp of the end date
|
103
|
+
# @param build [String] The version of the build. E.g. '4.0.1 (38)'
|
104
|
+
# @return [Fabricio::Networking::RequestModel]
|
105
|
+
def total_sessions_request_model(session, app_id, start_time, end_time, build)
|
106
|
+
path = growth_analytics_endpoint(session, app_id, 'total_sessions_scalar')
|
107
|
+
params = {
|
108
|
+
'start' => start_time,
|
109
|
+
'end' => end_time,
|
110
|
+
'build' => build
|
111
|
+
}
|
112
|
+
model = Fabricio::Networking::RequestModel.new do |config|
|
113
|
+
config.type = :GET
|
114
|
+
config.base_url = FABRIC_API_URL
|
115
|
+
config.api_path = path
|
116
|
+
config.params = params
|
117
|
+
end
|
118
|
+
model
|
119
|
+
end
|
120
|
+
|
121
|
+
# Returns a request model for obtaining the count of app crashes
|
122
|
+
#
|
123
|
+
# @param app_id [String]
|
124
|
+
# @param start_time [String] Timestamp of the start date
|
125
|
+
# @param end_time [String] Timestamp of the end date
|
126
|
+
# @param builds [Array] Multiple build versions. E.g. ['4.0.1 (38)']
|
127
|
+
# @return [Fabricio::Networking::RequestModel]
|
128
|
+
def crash_count_request_model(app_id, start_time, end_time, builds)
|
129
|
+
headers = {
|
130
|
+
'Content-Type' => 'application/json'
|
131
|
+
}
|
132
|
+
builds_string = builds.map { |build|
|
133
|
+
"\"#{build}\""
|
134
|
+
}.join(',')
|
135
|
+
body = {
|
136
|
+
'query' => "query AppScalars($app_id:String!,$type:IssueType!) {project(externalId:$app_id) {crashlytics {scalars:scalars(synthesizedBuildVersions:[#{builds_string}],type:$type,start:#{start_time},end:#{end_time}) {crashes}}}}",
|
137
|
+
'variables' => {
|
138
|
+
'app_id' => app_id,
|
139
|
+
'type' => 'crash'
|
140
|
+
}
|
141
|
+
}.to_json
|
142
|
+
model = Fabricio::Networking::RequestModel.new do |config|
|
143
|
+
config.type = :POST
|
144
|
+
config.base_url = FABRIC_GRAPHQL_API_URL
|
145
|
+
config.headers = headers
|
146
|
+
config.body = body
|
147
|
+
end
|
148
|
+
model
|
149
|
+
end
|
150
|
+
|
151
|
+
# Returns a request model for obtaining the count of ooms
|
152
|
+
#
|
153
|
+
# @param app_id [String]
|
154
|
+
# @param days [Integer] Count of days for obtaining oomfree data
|
155
|
+
# @param builds [Array] Multiple build versions. E.g. ['4.0.1 (38)']
|
156
|
+
# @return [Fabricio::Networking::RequestModel]
|
157
|
+
def oom_count_request_model(app_id, days, builds)
|
158
|
+
headers = {
|
159
|
+
'Content-Type' => 'application/json'
|
160
|
+
}
|
161
|
+
body = {
|
162
|
+
'query' => 'query oomCountForDaysForBuild($app_id: String!, $builds: [String!]!, $days: Int!) { project(externalId: $app_id) { crashlytics{ oomCounts(builds: $builds, days: $days){ timeSeries{ allTimeCount } } oomSessionCounts(builds: $builds, days: $days){ timeSeries{ allTimeCount } } } } }',
|
163
|
+
'variables' => {
|
164
|
+
'app_id' => app_id,
|
165
|
+
'days' => days,
|
166
|
+
'builds' => builds
|
167
|
+
}
|
168
|
+
}.to_json
|
169
|
+
model = Fabricio::Networking::RequestModel.new do |config|
|
170
|
+
config.type = :POST
|
171
|
+
config.base_url = FABRIC_GRAPHQL_API_URL
|
172
|
+
config.headers = headers
|
173
|
+
config.body = body
|
174
|
+
end
|
175
|
+
model
|
176
|
+
end
|
177
|
+
|
178
|
+
private
|
179
|
+
|
180
|
+
# Returns an API path to some growth analytic endpoint
|
181
|
+
#
|
182
|
+
# @param session [Fabricio::Authorization::Session]
|
183
|
+
# @param app_id [String]
|
184
|
+
# @param name [String]
|
185
|
+
# @return [String]
|
186
|
+
def growth_analytics_endpoint(session, app_id, name)
|
187
|
+
"#{FABRIC_API_PATH}#{org_app_endpoint(session, app_id)}/growth_analytics/#{name}.json"
|
188
|
+
end
|
189
|
+
|
190
|
+
# Returns an API path to organization endpoint
|
191
|
+
#
|
192
|
+
# @param session [Fabricio::Authorization::Session]
|
193
|
+
# @param app_id [String]
|
194
|
+
# @return [String]
|
195
|
+
def org_app_endpoint(session, app_id)
|
196
|
+
"#{org_endpoint(session)}/#{app_endpoint(app_id)}"
|
197
|
+
end
|
198
|
+
|
199
|
+
# Returns an API path to app endpoint
|
200
|
+
#
|
201
|
+
# @param app_id [String]
|
202
|
+
# @return [String]
|
203
|
+
def app_endpoint(app_id)
|
204
|
+
"/#{FABRIC_APPS_ENDPOINT}/#{app_id}"
|
205
|
+
end
|
206
|
+
|
207
|
+
# Returns an API path to app endpoint
|
208
|
+
#
|
209
|
+
# @param session [Fabricio::Authorization::Session]
|
210
|
+
# @return [String]
|
211
|
+
def org_endpoint(session)
|
212
|
+
"/#{FABRIC_ORGANIZATIONS_ENDPOINT}/#{session.organization_id}"
|
213
|
+
end
|
214
|
+
|
215
|
+
# Returns an API path to app endpoint
|
216
|
+
#
|
217
|
+
# @param start_time [String]
|
218
|
+
# @param end_time [String]
|
219
|
+
# @return [Hash]
|
220
|
+
def time_range_params(start_time, end_time)
|
221
|
+
{
|
222
|
+
'start' => start_time,
|
223
|
+
'end' => end_time
|
224
|
+
}
|
225
|
+
end
|
226
|
+
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'fabricio/networking/request_model'
|
2
|
+
|
3
|
+
module Fabricio
|
4
|
+
module Networking
|
5
|
+
# This factory creates request models for fetching data for Build model object
|
6
|
+
class BuildRequestModelFactory
|
7
|
+
|
8
|
+
# Server constants
|
9
|
+
FABRIC_API_URL = 'https://fabric.io'
|
10
|
+
FABRIC_API_PATH = '/api/v2'
|
11
|
+
FABRIC_APPS_ENDPOINT = '/apps'
|
12
|
+
FABRIC_ORGANIZATIONS_ENDPOINT = '/organizations'
|
13
|
+
|
14
|
+
# Returns a request model for obtaining the list of all builds for a specific app
|
15
|
+
#
|
16
|
+
# @param session [Fabricio::Authorization::Session]
|
17
|
+
# @param app_id [String]
|
18
|
+
# @return [Fabricio::Networking::RequestModel]
|
19
|
+
def all_builds_request_model(session, app_id)
|
20
|
+
path = "#{FABRIC_API_PATH}#{org_app_endpoint(session, app_id)}/beta_distribution/releases"
|
21
|
+
model = Fabricio::Networking::RequestModel.new do |config|
|
22
|
+
config.type = :GET
|
23
|
+
config.base_url = FABRIC_API_URL
|
24
|
+
config.api_path = path
|
25
|
+
end
|
26
|
+
model
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns a request model for obtaining a specific build for a specific app
|
30
|
+
#
|
31
|
+
# @param session [Fabricio::Authorization::Session]
|
32
|
+
# @param app_id [String]
|
33
|
+
# @param version [String] The version number. E.g. '4.0.0'
|
34
|
+
# @param build_number [String] The build number. E.g. '48'
|
35
|
+
# @return [Fabricio::Networking::RequestModel]
|
36
|
+
def get_build_request_model(session, app_id, version, build_number)
|
37
|
+
path = "#{FABRIC_API_PATH}#{org_app_endpoint(session, app_id)}/beta_distribution/releases"
|
38
|
+
params = {
|
39
|
+
'app[display_version]' => version,
|
40
|
+
'app[build_version]' => build_number
|
41
|
+
}
|
42
|
+
model = Fabricio::Networking::RequestModel.new do |config|
|
43
|
+
config.type = :GET
|
44
|
+
config.base_url = FABRIC_API_URL
|
45
|
+
config.api_path = path
|
46
|
+
config.params = params
|
47
|
+
end
|
48
|
+
model
|
49
|
+
end
|
50
|
+
|
51
|
+
# Returns a request model for obtaining an array of top versions for a given app
|
52
|
+
#
|
53
|
+
# @param session [Fabricio::Authorization::Session]
|
54
|
+
# @param app_id [String]
|
55
|
+
# @param start_time [String] Timestamp of the start date
|
56
|
+
# @param end_time [String] Timestamp of the end date
|
57
|
+
# @return [Fabricio::Networking::RequestModel]
|
58
|
+
def top_versions_request_model(session, app_id, start_time, end_time)
|
59
|
+
path = "#{FABRIC_API_PATH}#{org_app_endpoint(session, app_id)}/growth_analytics/top_builds"
|
60
|
+
params = {
|
61
|
+
'app_id' => app_id,
|
62
|
+
'start' => start_time,
|
63
|
+
'end' => end_time
|
64
|
+
}
|
65
|
+
model = Fabricio::Networking::RequestModel.new do |config|
|
66
|
+
config.type = :GET
|
67
|
+
config.base_url = FABRIC_API_URL
|
68
|
+
config.api_path = path
|
69
|
+
config.params = params
|
70
|
+
end
|
71
|
+
model
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
# Returns an API path to app endpoint
|
77
|
+
#
|
78
|
+
# @param app_id [String]
|
79
|
+
# @return [String]
|
80
|
+
def app_endpoint(app_id)
|
81
|
+
"/#{FABRIC_APPS_ENDPOINT}/#{app_id}"
|
82
|
+
end
|
83
|
+
|
84
|
+
# Returns an API path to app endpoint
|
85
|
+
#
|
86
|
+
# @param session [Fabricio::Authorization::Session]
|
87
|
+
# @return [String]
|
88
|
+
def org_endpoint(session)
|
89
|
+
"/#{FABRIC_ORGANIZATIONS_ENDPOINT}/#{session.organization_id}"
|
90
|
+
end
|
91
|
+
|
92
|
+
# Returns an API path to organization endpoint
|
93
|
+
#
|
94
|
+
# @param session [Fabricio::Authorization::Session]
|
95
|
+
# @param app_id [String]
|
96
|
+
# @return [String]
|
97
|
+
def org_app_endpoint(session, app_id)
|
98
|
+
"#{org_endpoint(session)}/#{app_endpoint(app_id)}"
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'fabricio/networking/request_model'
|
3
|
+
require 'fabricio/authorization/authorization_client'
|
4
|
+
require 'fabricio/authorization/abstract_session_storage'
|
5
|
+
|
6
|
+
module Fabricio
|
7
|
+
module Networking
|
8
|
+
# This class makes network requests based on request models
|
9
|
+
class NetworkClient
|
10
|
+
|
11
|
+
# Initializes a new NetworkClient object
|
12
|
+
#
|
13
|
+
# @param authorization_client [Fabricio::Authorization::AuthorizationClient]
|
14
|
+
# @param session_storage [Fabricio::Authorization::AbstractSessionStorage]
|
15
|
+
# @return [Fabricio::Networking::NetworkClient]
|
16
|
+
def initialize(authorization_client = nil, session_storage = nil)
|
17
|
+
@authorization_client = authorization_client
|
18
|
+
@session_storage = session_storage
|
19
|
+
@is_refreshing_session = false
|
20
|
+
end
|
21
|
+
|
22
|
+
# Performs a network request based on a passed request model
|
23
|
+
#
|
24
|
+
# @param model [Fabricio::Networking::RequestModel]
|
25
|
+
# @return [String]
|
26
|
+
def perform_request(model)
|
27
|
+
session = @session_storage.obtain_session
|
28
|
+
model = sign_model(model, session)
|
29
|
+
|
30
|
+
connection = Faraday.new(:url => model.base_url) do |faraday|
|
31
|
+
faraday.adapter Faraday.default_adapter
|
32
|
+
end
|
33
|
+
|
34
|
+
if model.type == :GET
|
35
|
+
result = perform_get_request(connection, model)
|
36
|
+
elsif model.type == :POST
|
37
|
+
result = perform_post_request(connection, model)
|
38
|
+
end
|
39
|
+
|
40
|
+
# If there is an authorization error and we aren't already trying to refresh it, we make a refresh session call and retry the initial network request.
|
41
|
+
is_authorization_error = result.success? == false && [401, 402].include?(result.status)
|
42
|
+
if is_authorization_error && @is_refreshing_session == false
|
43
|
+
refreshed_session = @authorization_client.refresh(session)
|
44
|
+
@session_storage.store_session(refreshed_session)
|
45
|
+
|
46
|
+
@is_refreshing_session = true
|
47
|
+
return perform_request(model)
|
48
|
+
end
|
49
|
+
|
50
|
+
# If authorization returns 401 and refresh session operation failed we throw exception
|
51
|
+
if is_authorization_error && @is_refreshing_session == true
|
52
|
+
raise StandardError.new('Can`t refresh session. Try once again later or repeat authorization manually')
|
53
|
+
end
|
54
|
+
|
55
|
+
if is_authorization_error == false
|
56
|
+
@is_refreshing_session = false
|
57
|
+
end
|
58
|
+
result
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
# Signs a request model with authorization data
|
64
|
+
#
|
65
|
+
# @param model [Fabricio::Networking::RequestModel]
|
66
|
+
# @param session [Fabricio::Authorization::Session]
|
67
|
+
# @return [String]
|
68
|
+
def sign_model(model, session)
|
69
|
+
model.headers['Authorization'] = "Bearer #{session.access_token}"
|
70
|
+
model
|
71
|
+
end
|
72
|
+
|
73
|
+
# Performs a GET network request based on a passed request model
|
74
|
+
#
|
75
|
+
# @param connection [Faraday::Connection]
|
76
|
+
# @param model [Fabricio::Networking::RequestModel]
|
77
|
+
# @return [String]
|
78
|
+
def perform_get_request(connection, model)
|
79
|
+
connection.get do |req|
|
80
|
+
req.url model.api_path
|
81
|
+
req.headers = model.headers
|
82
|
+
req.params = model.params
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Performs a POST network request based on a passed request model
|
87
|
+
#
|
88
|
+
# @param connection [Faraday::Connection]
|
89
|
+
# @param model [Fabricio::Networking::RequestModel]
|
90
|
+
# @return [String]
|
91
|
+
def perform_post_request(connection, model)
|
92
|
+
connection.post do |req|
|
93
|
+
req.url model.api_path
|
94
|
+
req.headers = model.headers
|
95
|
+
req.body = model.body
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'fabricio/networking/request_model'
|
2
|
+
|
3
|
+
module Fabricio
|
4
|
+
module Networking
|
5
|
+
# This factory creates request models for fetching data for Organization model object
|
6
|
+
class OrganizationRequestModelFactory
|
7
|
+
|
8
|
+
# Server constants
|
9
|
+
FABRIC_API_URL = 'https://fabric.io'
|
10
|
+
FABRIC_API_PATH = '/api/v2'
|
11
|
+
FABRIC_ORGANIZATIONS_ENDPOINT = '/organizations'
|
12
|
+
|
13
|
+
# Returns a request model for obtaining the organization data
|
14
|
+
#
|
15
|
+
# @return [Fabricio::Networking::RequestModel]
|
16
|
+
def get_organization_request_model
|
17
|
+
model = Fabricio::Networking::RequestModel.new do |config|
|
18
|
+
config.type = :GET
|
19
|
+
config.base_url = FABRIC_API_URL
|
20
|
+
config.api_path = FABRIC_API_PATH + FABRIC_ORGANIZATIONS_ENDPOINT
|
21
|
+
end
|
22
|
+
model
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|