fabricio 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +50 -0
- data/Gemfile.lock +61 -0
- data/README.md +27 -16
- data/lib/fabricio/models/issue.rb +39 -0
- data/lib/fabricio/models/issue_session.rb +27 -0
- data/lib/fabricio/networking/app_request_model_factory.rb +100 -1
- data/lib/fabricio/services/app_service.rb +56 -2
- data/lib/fabricio/services/organization_service.rb +0 -1
- data/lib/fabricio/version.rb +1 -1
- metadata +26 -22
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4b563c6a1abc94ee88a579aefa1b1cb3b8c0bada
|
|
4
|
+
data.tar.gz: 043e03e7cee36b10518f330ef120f14c9946aed7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 06da627bd804c6e2c976646e1485fde6c045379892c9378a7c61d6ca6c2cd47191d04e3213675484e5d54551feded46a557f5f2ee7ad2bcc62e6b5d2f2bdf427
|
|
7
|
+
data.tar.gz: a23c5b4a6af0dba6b52bb9f5813797ea8ef401af9ff341331902395507370ea8893fd712c848750c58e5b4514f8dd7a28594bf664e6f73dd18b3fc6e9175e16d
|
data/.gitignore
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
*.gem
|
|
2
|
+
*.rbc
|
|
3
|
+
/.config
|
|
4
|
+
/coverage/
|
|
5
|
+
/InstalledFiles
|
|
6
|
+
/pkg/
|
|
7
|
+
/spec/reports/
|
|
8
|
+
/spec/examples.txt
|
|
9
|
+
/test/tmp/
|
|
10
|
+
/test/version_tmp/
|
|
11
|
+
/tmp/
|
|
12
|
+
|
|
13
|
+
# Used by dotenv library to load environment variables.
|
|
14
|
+
# .env
|
|
15
|
+
|
|
16
|
+
## Specific to RubyMotion:
|
|
17
|
+
.dat*
|
|
18
|
+
.repl_history
|
|
19
|
+
build/
|
|
20
|
+
*.bridgesupport
|
|
21
|
+
build-iPhoneOS/
|
|
22
|
+
build-iPhoneSimulator/
|
|
23
|
+
|
|
24
|
+
## Specific to RubyMotion (use of CocoaPods):
|
|
25
|
+
#
|
|
26
|
+
# We recommend against adding the Pods directory to your .gitignore. However
|
|
27
|
+
# you should judge for yourself, the pros and cons are mentioned at:
|
|
28
|
+
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
|
|
29
|
+
#
|
|
30
|
+
# vendor/Pods/
|
|
31
|
+
|
|
32
|
+
## Documentation cache and generated files:
|
|
33
|
+
/.yardoc/
|
|
34
|
+
/_yardoc/
|
|
35
|
+
/doc/
|
|
36
|
+
/rdoc/
|
|
37
|
+
|
|
38
|
+
## Environment normalization:
|
|
39
|
+
/.bundle/
|
|
40
|
+
/vendor/bundle
|
|
41
|
+
/lib/bundler/man/
|
|
42
|
+
|
|
43
|
+
# for a library or gem, you might want to ignore these files since the code is
|
|
44
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
45
|
+
# Gemfile.lock
|
|
46
|
+
# .ruby-version
|
|
47
|
+
# .ruby-gemset
|
|
48
|
+
|
|
49
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
|
50
|
+
.rvmrc
|
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
fabricio (1.2.0)
|
|
5
|
+
faraday
|
|
6
|
+
|
|
7
|
+
GEM
|
|
8
|
+
remote: https://rubygems.org/
|
|
9
|
+
specs:
|
|
10
|
+
addressable (2.5.1)
|
|
11
|
+
public_suffix (~> 2.0, >= 2.0.2)
|
|
12
|
+
codeclimate-test-reporter (1.0.8)
|
|
13
|
+
simplecov (<= 0.13)
|
|
14
|
+
crack (0.4.3)
|
|
15
|
+
safe_yaml (~> 1.0.0)
|
|
16
|
+
diff-lcs (1.3)
|
|
17
|
+
docile (1.1.5)
|
|
18
|
+
faraday (0.12.1)
|
|
19
|
+
multipart-post (>= 1.2, < 3)
|
|
20
|
+
hashdiff (0.3.4)
|
|
21
|
+
json (2.1.0)
|
|
22
|
+
multipart-post (2.0.0)
|
|
23
|
+
public_suffix (2.0.5)
|
|
24
|
+
rake (10.5.0)
|
|
25
|
+
rspec (3.6.0)
|
|
26
|
+
rspec-core (~> 3.6.0)
|
|
27
|
+
rspec-expectations (~> 3.6.0)
|
|
28
|
+
rspec-mocks (~> 3.6.0)
|
|
29
|
+
rspec-core (3.6.0)
|
|
30
|
+
rspec-support (~> 3.6.0)
|
|
31
|
+
rspec-expectations (3.6.0)
|
|
32
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
33
|
+
rspec-support (~> 3.6.0)
|
|
34
|
+
rspec-mocks (3.6.0)
|
|
35
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
36
|
+
rspec-support (~> 3.6.0)
|
|
37
|
+
rspec-support (3.6.0)
|
|
38
|
+
safe_yaml (1.0.4)
|
|
39
|
+
simplecov (0.13.0)
|
|
40
|
+
docile (~> 1.1.0)
|
|
41
|
+
json (>= 1.8, < 3)
|
|
42
|
+
simplecov-html (~> 0.10.0)
|
|
43
|
+
simplecov-html (0.10.1)
|
|
44
|
+
webmock (3.0.1)
|
|
45
|
+
addressable (>= 2.3.6)
|
|
46
|
+
crack (>= 0.3.2)
|
|
47
|
+
hashdiff
|
|
48
|
+
|
|
49
|
+
PLATFORMS
|
|
50
|
+
ruby
|
|
51
|
+
|
|
52
|
+
DEPENDENCIES
|
|
53
|
+
codeclimate-test-reporter (~> 1.0.0)
|
|
54
|
+
fabricio!
|
|
55
|
+
rake (~> 10.0)
|
|
56
|
+
rspec (~> 3.0)
|
|
57
|
+
simplecov
|
|
58
|
+
webmock
|
|
59
|
+
|
|
60
|
+
BUNDLED WITH
|
|
61
|
+
1.12.5
|
data/README.md
CHANGED
|
@@ -13,17 +13,17 @@ There is a possibility that in some point of time it may break. Feel free to [po
|
|
|
13
13
|
|
|
14
14
|
## The Story Behind
|
|
15
15
|
|
|
16
|
-
[Fabric.io](http://fabric.io) is a great tool made for mobile application developers. It provides data about standard and out-of-memory crashes, active users, audience growth and a lot more. Unfortunately the only official way to work with this data is using Fabric.io website. That means - no automation and no integrations with other services.
|
|
16
|
+
[Fabric.io](http://fabric.io) is a great tool made for mobile application developers. It provides data about standard and out-of-memory crashes, active users, audience growth and a lot more. Unfortunately the only official way to work with this data is using Fabric.io website. That means - no automation and no integrations with other services.
|
|
17
17
|
|
|
18
18
|
We decided to fix this issue.
|
|
19
19
|
|
|
20
|
-
| Key Features
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
| | Key Features|
|
|
21
|
+
|---------|---------------|
|
|
22
|
+
|🍫 | Hides the complexity of different Fabric.io APIs behind a simple wrapper.|
|
|
23
|
+
|📚 | Provides data about organization, applications and builds.|
|
|
24
|
+
|💥 | Shows crash- and out-of-memory- free metrics.|
|
|
25
|
+
|⏰ | Automatically refreshes session in case of its expiration.|
|
|
26
|
+
|🛠 | Provides a simple way of adding your adapter for storing session data in a database of your choice.|
|
|
27
27
|
|
|
28
28
|
## Installation
|
|
29
29
|
|
|
@@ -40,20 +40,20 @@ And then execute:
|
|
|
40
40
|
Or install it yourself as:
|
|
41
41
|
|
|
42
42
|
$ gem install fabricio
|
|
43
|
-
|
|
43
|
+
|
|
44
44
|
## Quick Start
|
|
45
45
|
|
|
46
46
|
1. Create a `Fabricio::Client` object and configure it on initialization.
|
|
47
47
|
|
|
48
48
|
```ruby
|
|
49
49
|
require 'Fabricio'
|
|
50
|
-
|
|
50
|
+
|
|
51
51
|
client = Fabricio::Client.new do |config|
|
|
52
52
|
config.username = 'your_email'
|
|
53
53
|
config.password = 'your_password'
|
|
54
54
|
end
|
|
55
55
|
```
|
|
56
|
-
|
|
56
|
+
|
|
57
57
|
2. Use this client to query any data you want.
|
|
58
58
|
|
|
59
59
|
```ruby
|
|
@@ -62,15 +62,15 @@ Or install it yourself as:
|
|
|
62
62
|
client.app.crashfree('app_id', '1478736000', '1481328000' 'all') # Returns application crashfree for a given period of time
|
|
63
63
|
client.organization.get # Returns information about your organization
|
|
64
64
|
```
|
|
65
|
-
|
|
65
|
+
|
|
66
66
|
3. If you want to check the exact server output for a model, you can call `json` method on it:
|
|
67
67
|
|
|
68
68
|
`client.app.get('app_id').json`
|
|
69
|
-
|
|
69
|
+
|
|
70
70
|
You can call a method similar to any key in this hash:
|
|
71
|
-
|
|
71
|
+
|
|
72
72
|
`client.app.get('app_id').importance_level`
|
|
73
|
-
|
|
73
|
+
|
|
74
74
|
## Commands
|
|
75
75
|
|
|
76
76
|
### Organization
|
|
@@ -119,6 +119,18 @@ Obtains application crashfree.
|
|
|
119
119
|
|
|
120
120
|
Obtain top issues.
|
|
121
121
|
|
|
122
|
+
#### `client.app.single_issue('app_id', 'issue_external_id', start_timestamp, end_timestamp)`
|
|
123
|
+
|
|
124
|
+
Obtain single issue.
|
|
125
|
+
|
|
126
|
+
#### `client.app.issue_session('app_id', 'issue_external_id', 'session_id')`
|
|
127
|
+
|
|
128
|
+
Obtain issue session.
|
|
129
|
+
|
|
130
|
+
#### `client.app.add_comment('app_id', 'issue_external_id', 'message')`
|
|
131
|
+
|
|
132
|
+
Add comment.
|
|
133
|
+
|
|
122
134
|
#### `client.app.oomfree('app_id', 'start_timestamp', 'end_timestamp', 'builds')`
|
|
123
135
|
|
|
124
136
|
Obtains application out-of-memory free for a number of builds.
|
|
@@ -153,4 +165,3 @@ Thanks for help in dealing with API to Vadim Smal, Irina Dyagileva and Andrey Sm
|
|
|
153
165
|
## License
|
|
154
166
|
|
|
155
167
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
|
156
|
-
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
require 'fabricio/models/abstract_model'
|
|
2
|
+
|
|
3
|
+
module Fabricio
|
|
4
|
+
module Model
|
|
5
|
+
# This model represents an application build
|
|
6
|
+
class Issue < AbstractModel
|
|
7
|
+
attr_reader :id,
|
|
8
|
+
:displayId,
|
|
9
|
+
:externalId,
|
|
10
|
+
:title,
|
|
11
|
+
:subtitle,
|
|
12
|
+
:createdAt,
|
|
13
|
+
:type,
|
|
14
|
+
:state,
|
|
15
|
+
:latestSessionId,
|
|
16
|
+
:occurrenceCount,
|
|
17
|
+
:impactedDevices
|
|
18
|
+
|
|
19
|
+
# Returns a Build model object
|
|
20
|
+
#
|
|
21
|
+
# @param attributes [Hash]
|
|
22
|
+
# @return [Fabricio::Model::Build]
|
|
23
|
+
def initialize(attributes)
|
|
24
|
+
@id = attributes['id']
|
|
25
|
+
@displayId = attributes['displayId']
|
|
26
|
+
@externalId = attributes['externalId']
|
|
27
|
+
@title = attributes['title']
|
|
28
|
+
@subtitle = attributes['subtitle']
|
|
29
|
+
@createdAt = attributes['createdAt']
|
|
30
|
+
@type = attributes['type']
|
|
31
|
+
@state = attributes['state']
|
|
32
|
+
@latestSessionId = attributes['latestSessionId']
|
|
33
|
+
@occurrenceCount = attributes['occurrenceCount']
|
|
34
|
+
@impactedDevices = attributes['impactedDevices']
|
|
35
|
+
@json = attributes
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require 'fabricio/models/abstract_model'
|
|
2
|
+
|
|
3
|
+
module Fabricio
|
|
4
|
+
module Model
|
|
5
|
+
# This model represents an application build
|
|
6
|
+
class IssueSession < AbstractModel
|
|
7
|
+
attr_reader :id,
|
|
8
|
+
:created_at,
|
|
9
|
+
:header_link
|
|
10
|
+
:next_session_id
|
|
11
|
+
:prev_session_id
|
|
12
|
+
|
|
13
|
+
# Returns a Build model object
|
|
14
|
+
#
|
|
15
|
+
# @param attributes [Hash]
|
|
16
|
+
# @return [Fabricio::Model::Build]
|
|
17
|
+
def initialize(attributes)
|
|
18
|
+
@id = attributes['session_id']
|
|
19
|
+
@created_at = attributes['created_at']
|
|
20
|
+
@header_link = attributes['header_link']
|
|
21
|
+
@next_session_id = attributes['next_session_id']
|
|
22
|
+
@prev_session_id = attributes['prev_session_id']
|
|
23
|
+
@json = attributes
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -10,8 +10,10 @@ module Fabricio
|
|
|
10
10
|
FABRIC_API_URL = 'https://fabric.io'
|
|
11
11
|
FABRIC_GRAPHQL_API_URL = 'https://api-dash.fabric.io/graphql'
|
|
12
12
|
FABRIC_API_PATH = '/api/v2'
|
|
13
|
+
FABRIC_API_3_PATH = '/api/v3'
|
|
13
14
|
FABRIC_APPS_ENDPOINT = '/apps'
|
|
14
15
|
FABRIC_ORGANIZATIONS_ENDPOINT = '/organizations'
|
|
16
|
+
FABRIC_PROJECTS_ENDPOINT = '/projects'
|
|
15
17
|
|
|
16
18
|
# Returns a request model for obtaining the list of all apps
|
|
17
19
|
#
|
|
@@ -165,7 +167,7 @@ module Fabricio
|
|
|
165
167
|
}.join(',')
|
|
166
168
|
|
|
167
169
|
body = {
|
|
168
|
-
'query' => "query TopIssues($externalId_0:String!,$type_1:IssueType!,$start_2:UnixTimestamp!,$end_3:UnixTimestamp!,$filters_4:IssueFiltersType!,$state_5:IssueState!) {project(externalId:$externalId_0) {crashlytics {_appDetails1JwAD1:appDetails(synthesizedBuildVersions:[#{builds_string}],type:$type_1,start:$start_2,end:$end_3,filters:$filters_4) {topCrashInsightsMatchers {groupKey}},_issues4Eg1Tv:issues(synthesizedBuildVersions:[#{builds_string}],eventType:$type_1,start:$start_2,end:$end_3,state:$state_5,first:#{count},filters:$filters_4) {edges {node {externalId,displayId,createdAt,resolvedAt,title,subtitle,state,type,impactLevel,isObfuscated,occurrenceCount,impactedDevices,notesCount,earliestBuildVersion {buildVersion {name}},latestBuildVersion {buildVersion {name}},id},cursor},pageInfo {hasNextPage,hasPreviousPage}}},id}}",
|
|
170
|
+
'query' => "query TopIssues($externalId_0:String!,$type_1:IssueType!,$start_2:UnixTimestamp!,$end_3:UnixTimestamp!,$filters_4:IssueFiltersType!,$state_5:IssueState!) {project(externalId:$externalId_0) {crashlytics {_appDetails1JwAD1:appDetails(synthesizedBuildVersions:[#{builds_string}],type:$type_1,start:$start_2,end:$end_3,filters:$filters_4) {topCrashInsightsMatchers {groupKey}},_issues4Eg1Tv:issues(synthesizedBuildVersions:[#{builds_string}],eventType:$type_1,start:$start_2,end:$end_3,state:$state_5,first:#{count},filters:$filters_4) {edges {node {externalId,displayId,createdAt,resolvedAt,title,subtitle,state,type,impactLevel,isObfuscated,occurrenceCount,impactedDevices,latestSessionId,notesCount,earliestBuildVersion {buildVersion {name}},latestBuildVersion {buildVersion {name}},id},cursor},pageInfo {hasNextPage,hasPreviousPage}}},id}}",
|
|
169
171
|
'variables' => {
|
|
170
172
|
'externalId_0' => app_id,
|
|
171
173
|
'type_1' => 'all',
|
|
@@ -185,6 +187,83 @@ module Fabricio
|
|
|
185
187
|
model
|
|
186
188
|
end
|
|
187
189
|
|
|
190
|
+
# Returns a request model for obtaining single issue
|
|
191
|
+
#
|
|
192
|
+
# @param app_id [String]
|
|
193
|
+
# @param issue_external_id [String] Issue external identifier
|
|
194
|
+
# @param start_time [String] Timestamp of the start date
|
|
195
|
+
# @param end_time [String] Timestamp of the end date
|
|
196
|
+
# @return [Fabricio::Networking::RequestModel]
|
|
197
|
+
def single_issue_request_model(app_id, issue_external_id, start_time, end_time)
|
|
198
|
+
headers = {
|
|
199
|
+
'Content-Type' => 'application/json'
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
body = {
|
|
203
|
+
'query' => "query SingleIssue($externalId_0:String!,$start_1:UnixTimestamp!,$end_2:UnixTimestamp!,$granularity_3:TimeseriesGranularity!,$filters_4:IssueFiltersType!) {project(externalId:$externalId_0) {crashlytics {_issueeUsmi:issue(externalId:\"#{issue_external_id}\") {externalId,createdAt,displayId,title,subtitle,type,state,isObfuscated,supportsCrossVersion,_occurrenceCount2I980d:occurrenceCount(start:$start_1,end:$end_2),_impactedDevices2oATOx:impactedDevices(start:$start_1,end:$end_2),shareLink,latestSessionId,lockedAt,resolvedAt,exportUserIdsUrl,buildVersionBreakdown {occurrenceCount,buildVersion {externalId,createdAt,name,synthesizedBuildVersion}},earliestBuildVersion {buildVersion {externalId,createdAt,name,synthesizedBuildVersion}},latestBuildVersion {buildVersion {externalId,createdAt,name,synthesizedBuildVersion}},notes {externalId,createdAt,body,account {id,name,email}},_timeseries1niuOE:timeseries(granularity:$granularity_3,start:$start_1,end:$end_2) {eventsCount,groupByDimension,dimensionKey},_scalars1YYKRB:scalars(start:$start_1,end:$end_2,filters:$filters_4) {deviceMetrics {eventsCount,jailbrokenRatio,inFocusRatio,proximityOnRatio,freeRamMean,freeDiskMean},topOs {value,label,groupKey,eventsCount},topDevices {value,label,groupKey,eventsCount},topCrashInsightsMatchers {value,label,groupKey,eventsCount,issuesCount,impactedDevicesCount}},id}},id}}",
|
|
204
|
+
'variables' => {
|
|
205
|
+
'externalId_0' => app_id,
|
|
206
|
+
'start_1' => start_time,
|
|
207
|
+
'end_2' => end_time,
|
|
208
|
+
'granularity_3' => 'day',
|
|
209
|
+
'filters_4' => {}
|
|
210
|
+
}
|
|
211
|
+
}.to_json
|
|
212
|
+
model = Fabricio::Networking::RequestModel.new do |config|
|
|
213
|
+
config.type = :POST
|
|
214
|
+
config.base_url = FABRIC_GRAPHQL_API_URL
|
|
215
|
+
config.api_path = '?relayDebugName=SingleIssue'
|
|
216
|
+
config.headers = headers
|
|
217
|
+
config.body = body
|
|
218
|
+
end
|
|
219
|
+
model
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# Returns a request model for obtaining the count of ooms
|
|
223
|
+
#
|
|
224
|
+
# @param app_id [String]
|
|
225
|
+
# @param issue_external_id [String] Issue external identifier
|
|
226
|
+
# @param session_id [String] Session identifier
|
|
227
|
+
# @return [Fabricio::Networking::RequestModel]
|
|
228
|
+
def issue_session_request_model(app_id, issue_external_id, session_id)
|
|
229
|
+
headers = {
|
|
230
|
+
'Content-Type' => 'application/json'
|
|
231
|
+
}
|
|
232
|
+
path = issue_session_endpoint(app_id, issue_external_id, session_id)
|
|
233
|
+
model = Fabricio::Networking::RequestModel.new do |config|
|
|
234
|
+
config.type = :GET
|
|
235
|
+
config.base_url = FABRIC_API_URL
|
|
236
|
+
config.api_path = path
|
|
237
|
+
config.headers = headers
|
|
238
|
+
end
|
|
239
|
+
model
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
# Returns a request model for obtaining the count of ooms
|
|
243
|
+
#
|
|
244
|
+
# @param app_id [String]
|
|
245
|
+
# @param issue_external_id [String] Issue external identifier
|
|
246
|
+
# @param message [String] Comment message
|
|
247
|
+
# @return [Fabricio::Networking::RequestModel]
|
|
248
|
+
def add_comment_request_model(app_id, issue_external_id, message)
|
|
249
|
+
headers = {
|
|
250
|
+
'Content-Type' => 'application/json'
|
|
251
|
+
}
|
|
252
|
+
body = {
|
|
253
|
+
'body' => message,
|
|
254
|
+
|
|
255
|
+
}.to_json
|
|
256
|
+
path = add_comment_endpoint(app_id, issue_external_id)
|
|
257
|
+
model = Fabricio::Networking::RequestModel.new do |config|
|
|
258
|
+
config.type = :POST
|
|
259
|
+
config.base_url = FABRIC_API_URL
|
|
260
|
+
config.api_path = path
|
|
261
|
+
config.headers = headers
|
|
262
|
+
config.body = body
|
|
263
|
+
end
|
|
264
|
+
model
|
|
265
|
+
end
|
|
266
|
+
|
|
188
267
|
# Returns a request model for obtaining the count of ooms
|
|
189
268
|
#
|
|
190
269
|
# @param app_id [String]
|
|
@@ -214,6 +293,26 @@ module Fabricio
|
|
|
214
293
|
|
|
215
294
|
private
|
|
216
295
|
|
|
296
|
+
# Returns an API path to some issue session
|
|
297
|
+
#
|
|
298
|
+
# @param app_id [String]
|
|
299
|
+
# @param issue_id [String]
|
|
300
|
+
# @param session_id [String]
|
|
301
|
+
# @return [String]
|
|
302
|
+
def add_comment_endpoint(app_id, issue_id)
|
|
303
|
+
"#{FABRIC_API_3_PATH}#{FABRIC_PROJECTS_ENDPOINT}/#{app_id}/issues/#{issue_id}/notes"
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
# Returns an API path to some issue session
|
|
307
|
+
#
|
|
308
|
+
# @param app_id [String]
|
|
309
|
+
# @param issue_id [String]
|
|
310
|
+
# @param session_id [String]
|
|
311
|
+
# @return [String]
|
|
312
|
+
def issue_session_endpoint(app_id, issue_id, session_id)
|
|
313
|
+
"#{FABRIC_API_3_PATH}#{FABRIC_PROJECTS_ENDPOINT}/#{app_id}/issues/#{issue_id}/sessions/#{session_id}"
|
|
314
|
+
end
|
|
315
|
+
|
|
217
316
|
# Returns an API path to some growth analytic endpoint
|
|
218
317
|
#
|
|
219
318
|
# @param session [Fabricio::Authorization::Session]
|
|
@@ -2,6 +2,8 @@ require 'fabricio/networking/app_request_model_factory'
|
|
|
2
2
|
require 'fabricio/networking/network_client'
|
|
3
3
|
require 'fabricio/models/app'
|
|
4
4
|
require 'fabricio/models/point'
|
|
5
|
+
require 'fabricio/models/issue'
|
|
6
|
+
require 'fabricio/models/issue_session'
|
|
5
7
|
|
|
6
8
|
module Fabricio
|
|
7
9
|
module Service
|
|
@@ -128,11 +130,63 @@ module Fabricio
|
|
|
128
130
|
# @param end_time [String] Timestamp of the end date
|
|
129
131
|
# @param build [String] The version of the build. E.g. '4.0.1 (38)'
|
|
130
132
|
# @param count [Int] Number of issue
|
|
131
|
-
# @return [
|
|
133
|
+
# @return [Array<Fabricio::Model::Issue>]
|
|
132
134
|
def top_issues(id, start_time, end_time, builds, count)
|
|
133
135
|
request_model = @request_model_factory.top_issues_request_model(id, start_time, end_time, builds, count)
|
|
134
136
|
response = @network_client.perform_request(request_model)
|
|
135
|
-
JSON.parse(response.body)['data']['project']['crashlytics']['_issues4Eg1Tv']['edges'].map
|
|
137
|
+
JSON.parse(response.body)['data']['project']['crashlytics']['_issues4Eg1Tv']['edges'].map do |edge|
|
|
138
|
+
Fabricio::Model::Issue.new(edge['node'])
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# Obtains single issue
|
|
143
|
+
#
|
|
144
|
+
# @param id [String] Application identifier
|
|
145
|
+
# @param issue_external_id [String] Issue external identifier
|
|
146
|
+
# @param start_time [String] Timestamp of the start date
|
|
147
|
+
# @param end_time [String] Timestamp of the end date
|
|
148
|
+
# @return [Fabricio::Model::Issue]
|
|
149
|
+
def single_issue(id, issue_external_id, start_time, end_time)
|
|
150
|
+
request_model = @request_model_factory.single_issue_request_model(id, issue_external_id, start_time, end_time)
|
|
151
|
+
response = @network_client.perform_request(request_model)
|
|
152
|
+
Fabricio::Model::Issue.new(JSON.parse(response.body)['data']['project']['crashlytics']['_issueeUsmi'])
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# Obtains single issue
|
|
156
|
+
#
|
|
157
|
+
# @param id [String] Application identifier
|
|
158
|
+
# @param issue_external_id [String] Issue external identifier
|
|
159
|
+
# @param session_id [String] Session identifier
|
|
160
|
+
# @return [Fabricio::Model::Issue]
|
|
161
|
+
def issue_session(id, issue_external_id, session_id)
|
|
162
|
+
request_model = @request_model_factory.issue_session_request_model(id, issue_external_id, session_id)
|
|
163
|
+
response = @network_client.perform_request(request_model)
|
|
164
|
+
json = JSON.parse(response.body)
|
|
165
|
+
link = response.headers['Link']
|
|
166
|
+
unless link.nil?
|
|
167
|
+
json['header_link'] = link
|
|
168
|
+
link_parts = link.split(", ")
|
|
169
|
+
link_parts.each do |part|
|
|
170
|
+
if part.include? 'rel="prev"'
|
|
171
|
+
json['prev_session_id'] = part.sub('>; rel="prev"', "").sub('<', "").split("sessions/")[1]
|
|
172
|
+
elsif part.include? 'rel="next"'
|
|
173
|
+
json['next_session_id'] = part.sub('>; rel="next"', "").sub('<', "").split("sessions/")[1]
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
Fabricio::Model::IssueSession.new(json)
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Add comment to issue
|
|
181
|
+
#
|
|
182
|
+
# @param id [String] Application identifier
|
|
183
|
+
# @param issue_external_id [String] Issue external identifier
|
|
184
|
+
# @param message [String] Comment message
|
|
185
|
+
# @return [JSON]
|
|
186
|
+
def add_comment(id, issue_external_id, message)
|
|
187
|
+
request_model = @request_model_factory.add_comment_request_model(id, issue_external_id, message)
|
|
188
|
+
response = @network_client.perform_request(request_model)
|
|
189
|
+
JSON.parse(response.body)
|
|
136
190
|
end
|
|
137
191
|
|
|
138
192
|
# Obtains application OOM-free (Out of Memory).
|
data/lib/fabricio/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,97 +1,97 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fabricio
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Egor Tolstoy
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-
|
|
11
|
+
date: 2017-06-19 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
|
-
- -
|
|
17
|
+
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
19
|
version: '0'
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
|
-
- -
|
|
24
|
+
- - ">="
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: '0'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: rake
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
|
-
- - ~>
|
|
31
|
+
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
33
|
version: '10.0'
|
|
34
34
|
type: :development
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
|
-
- - ~>
|
|
38
|
+
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: '10.0'
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: rspec
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
44
44
|
requirements:
|
|
45
|
-
- - ~>
|
|
45
|
+
- - "~>"
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
47
|
version: '3.0'
|
|
48
48
|
type: :development
|
|
49
49
|
prerelease: false
|
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
51
|
requirements:
|
|
52
|
-
- - ~>
|
|
52
|
+
- - "~>"
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
54
|
version: '3.0'
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
56
|
name: webmock
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
58
58
|
requirements:
|
|
59
|
-
- -
|
|
59
|
+
- - ">="
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
61
|
version: '0'
|
|
62
62
|
type: :development
|
|
63
63
|
prerelease: false
|
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
65
|
requirements:
|
|
66
|
-
- -
|
|
66
|
+
- - ">="
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
68
|
version: '0'
|
|
69
69
|
- !ruby/object:Gem::Dependency
|
|
70
70
|
name: simplecov
|
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
|
72
72
|
requirements:
|
|
73
|
-
- -
|
|
73
|
+
- - ">="
|
|
74
74
|
- !ruby/object:Gem::Version
|
|
75
75
|
version: '0'
|
|
76
76
|
type: :development
|
|
77
77
|
prerelease: false
|
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
79
|
requirements:
|
|
80
|
-
- -
|
|
80
|
+
- - ">="
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
82
|
version: '0'
|
|
83
83
|
- !ruby/object:Gem::Dependency
|
|
84
84
|
name: codeclimate-test-reporter
|
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
|
86
86
|
requirements:
|
|
87
|
-
- - ~>
|
|
87
|
+
- - "~>"
|
|
88
88
|
- !ruby/object:Gem::Version
|
|
89
89
|
version: 1.0.0
|
|
90
90
|
type: :development
|
|
91
91
|
prerelease: false
|
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
93
|
requirements:
|
|
94
|
-
- - ~>
|
|
94
|
+
- - "~>"
|
|
95
95
|
- !ruby/object:Gem::Version
|
|
96
96
|
version: 1.0.0
|
|
97
97
|
description:
|
|
@@ -101,13 +101,15 @@ executables: []
|
|
|
101
101
|
extensions: []
|
|
102
102
|
extra_rdoc_files: []
|
|
103
103
|
files:
|
|
104
|
-
- .codeclimate.yml
|
|
105
|
-
- .
|
|
106
|
-
- .
|
|
107
|
-
- .
|
|
108
|
-
- .
|
|
104
|
+
- ".codeclimate.yml"
|
|
105
|
+
- ".gitignore"
|
|
106
|
+
- ".idea/runConfigurations/IRB_console__fabricio.xml"
|
|
107
|
+
- ".rspec"
|
|
108
|
+
- ".rubocop.yml"
|
|
109
|
+
- ".travis.yml"
|
|
109
110
|
- CODE_OF_CONDUCT.md
|
|
110
111
|
- Gemfile
|
|
112
|
+
- Gemfile.lock
|
|
111
113
|
- LICENSE.txt
|
|
112
114
|
- README.md
|
|
113
115
|
- Rakefile
|
|
@@ -125,6 +127,8 @@ files:
|
|
|
125
127
|
- lib/fabricio/models/abstract_model.rb
|
|
126
128
|
- lib/fabricio/models/app.rb
|
|
127
129
|
- lib/fabricio/models/build.rb
|
|
130
|
+
- lib/fabricio/models/issue.rb
|
|
131
|
+
- lib/fabricio/models/issue_session.rb
|
|
128
132
|
- lib/fabricio/models/organization.rb
|
|
129
133
|
- lib/fabricio/models/point.rb
|
|
130
134
|
- lib/fabricio/networking/app_request_model_factory.rb
|
|
@@ -146,17 +150,17 @@ require_paths:
|
|
|
146
150
|
- lib
|
|
147
151
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
148
152
|
requirements:
|
|
149
|
-
- -
|
|
153
|
+
- - ">="
|
|
150
154
|
- !ruby/object:Gem::Version
|
|
151
155
|
version: '0'
|
|
152
156
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
153
157
|
requirements:
|
|
154
|
-
- -
|
|
158
|
+
- - ">="
|
|
155
159
|
- !ruby/object:Gem::Version
|
|
156
160
|
version: '0'
|
|
157
161
|
requirements: []
|
|
158
162
|
rubyforge_project:
|
|
159
|
-
rubygems_version: 2.
|
|
163
|
+
rubygems_version: 2.5.1
|
|
160
164
|
signing_key:
|
|
161
165
|
specification_version: 4
|
|
162
166
|
summary: A simple gem that fetches mobile application statistics from Fabric.io API.
|