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