fabricio 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +12 -0
  3. data/.idea/runConfigurations/IRB_console__fabricio.xml +23 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +1156 -0
  6. data/.travis.yml +10 -0
  7. data/CODE_OF_CONDUCT.md +74 -0
  8. data/Gemfile +4 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +149 -0
  11. data/Rakefile +6 -0
  12. data/bin/console +14 -0
  13. data/bin/setup +8 -0
  14. data/docs/api_reference.md +611 -0
  15. data/docs/swagger-api.json +553 -0
  16. data/fabricio.gemspec +29 -0
  17. data/lib/fabricio.rb +2 -0
  18. data/lib/fabricio/authorization/abstract_session_storage.rb +26 -0
  19. data/lib/fabricio/authorization/authorization_client.rb +122 -0
  20. data/lib/fabricio/authorization/memory_session_storage.rb +35 -0
  21. data/lib/fabricio/authorization/session.rb +21 -0
  22. data/lib/fabricio/client/client.rb +92 -0
  23. data/lib/fabricio/models/abstract_model.rb +17 -0
  24. data/lib/fabricio/models/app.rb +24 -0
  25. data/lib/fabricio/models/build.rb +23 -0
  26. data/lib/fabricio/models/organization.rb +22 -0
  27. data/lib/fabricio/models/point.rb +17 -0
  28. data/lib/fabricio/networking/app_request_model_factory.rb +229 -0
  29. data/lib/fabricio/networking/build_request_model_factory.rb +103 -0
  30. data/lib/fabricio/networking/network_client.rb +101 -0
  31. data/lib/fabricio/networking/organization_request_model_factory.rb +27 -0
  32. data/lib/fabricio/networking/request_model.rb +39 -0
  33. data/lib/fabricio/services/app_service.rb +146 -0
  34. data/lib/fabricio/services/build_service.rb +59 -0
  35. data/lib/fabricio/services/organization_service.rb +33 -0
  36. data/lib/fabricio/version.rb +3 -0
  37. 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