hockeyapp 0.0.15
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 +15 -0
- data/.gitignore +6 -0
- data/Gemfile +4 -0
- data/README.md +45 -0
- data/Rakefile +1 -0
- data/hockeyapp.gemspec +33 -0
- data/lib/hockeyapp.rb +25 -0
- data/lib/hockeyapp/config.rb +18 -0
- data/lib/hockeyapp/models/active_model_compliance.rb +10 -0
- data/lib/hockeyapp/models/app.rb +118 -0
- data/lib/hockeyapp/models/crash.rb +44 -0
- data/lib/hockeyapp/models/crash_group.rb +36 -0
- data/lib/hockeyapp/models/version.rb +91 -0
- data/lib/hockeyapp/services/android_urls.rb +30 -0
- data/lib/hockeyapp/services/ios_urls.rb +35 -0
- data/lib/hockeyapp/ws/client.rb +72 -0
- data/lib/hockeyapp/ws/ws.rb +96 -0
- data/spec/config_spec.rb +35 -0
- data/spec/hockey_app_spec.rb +13 -0
- data/spec/models/app_spec.rb +143 -0
- data/spec/models/crash_group_spec.rb +53 -0
- data/spec/models/crash_spec.rb +77 -0
- data/spec/models/version_spec.rb +85 -0
- data/spec/support/active_model_lint.rb +19 -0
- data/spec/support/fake_ws.rb +54 -0
- data/spec/support/responses/app.json +83 -0
- data/spec/support/responses/app_versions.json +34 -0
- data/spec/support/responses/apps.json +22 -0
- data/spec/support/responses/crash_groups.json +43 -0
- data/spec/support/responses/crashes.json +45 -0
- data/spec/support/responses/new_app.json +12 -0
- data/spec/support/responses/new_version.json +13 -0
- data/spec/support/rspec_helper.rb +18 -0
- data/spec/ws/client_spec.rb +153 -0
- data/spec/ws/ws_spec.rb +32 -0
- metadata +197 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NzMwMzc2ODYwMGRiMTQzYmIzNzBjOTUzYmI0ODk1NGMyNGE2ZmQ2Zg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
Yzk3ZmQ1MDg1MDI1YmI5YmU3MThiMzExMDJkOWQ1ZTA2ODk1MDI1OQ==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
MGQ2NWMyMTI5MzU2NDViMDM2ZDk0ODgyYzY0YzY5YzFhYzlhMmYwN2E3M2Uw
|
10
|
+
YjdhNjE4NjgyY2YyODE1YWE5MmI1ZGI5NDRmNTdiYzQ5MmZlZjAwODQ3NWZi
|
11
|
+
NjU5NTY3MWVkMTM1YzM0MDRiMmEzMmExNmFiZjMwOGVhYmM5ZWU=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ZGI5YzZlMTc0ZDZiODQyMGJkYmFiMDdiZjc0ZjEzZGI3ZWVkMTIyMGNhNTk3
|
14
|
+
NjA2MjNhMWNhOTNiNDFjODFlYmJhNjczN2M0ODE1YTg3MjFiMTIyMmU1NjMw
|
15
|
+
NTA3NjFmMTExNDA5Y2JmOWVlMTRmNGRhYTA1MTUwZmI0OWQ1MGI=
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# HockeyApp gem
|
2
|
+
|
3
|
+
This gem enables you to easily access the JSON Rest API of http://www.hockeyapp.net.
|
4
|
+
|
5
|
+
More info available on this API here : http://support.hockeyapp.net/kb/api
|
6
|
+
|
7
|
+
|
8
|
+
## Usage
|
9
|
+
|
10
|
+
### Configure your connection
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
HockeyApp::Config.configure do |config|
|
14
|
+
config.token = "ABCDEF"
|
15
|
+
end
|
16
|
+
```
|
17
|
+
|
18
|
+
### Make a client
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
client = HockeyApp.build_client
|
22
|
+
```
|
23
|
+
|
24
|
+
### Use the client
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
apps = client.get_apps
|
28
|
+
versions = apps.first.versions
|
29
|
+
crashes = apps.first.crashes
|
30
|
+
```
|
31
|
+
|
32
|
+
## Documentation
|
33
|
+
|
34
|
+
### Uploading a new version
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
@client ||= HockeyApp.build_client
|
38
|
+
|
39
|
+
app = HockeyApp::App.new(@client)
|
40
|
+
app.public_identifier = "aklsdjklajsd"
|
41
|
+
version = HockeyApp::Version.new(app, @client)
|
42
|
+
version.ipa = File.new('./app.ipa', 'r')
|
43
|
+
version.dsym = File.new('./dsym.dSYM.zip', 'r')
|
44
|
+
version = @client.post_new_version version
|
45
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/hockeyapp.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "hockeyapp"
|
6
|
+
s.version = "0.0.15"
|
7
|
+
s.authors = ["Philippe Van Eerdenbrugghe", "Paul Renson"]
|
8
|
+
s.email = ["philippe.vaneerdenbrugghe@tapptic.com", "paul.renson.ext@tapptic.com"]
|
9
|
+
s.homepage = ""
|
10
|
+
s.summary = %q{Wrapper for the hockeyapp REST API}
|
11
|
+
s.description = %q{This simple wrapper enables you to acces the hockeyapp REST API through simple ruby calls. You are rquired to configure a valid token before doing anyhting else}
|
12
|
+
|
13
|
+
s.rubyforge_project = "hockeyapp"
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
# specify any dependencies here; for example:
|
21
|
+
# s.add_development_dependency "rspec"
|
22
|
+
# s.add_runtime_dependency "rest-client"
|
23
|
+
s.add_runtime_dependency "rspec"
|
24
|
+
s.add_runtime_dependency "simplecov"
|
25
|
+
s.add_runtime_dependency "awesome_print"
|
26
|
+
s.add_runtime_dependency "rake"
|
27
|
+
s.add_runtime_dependency "multi_json"
|
28
|
+
|
29
|
+
|
30
|
+
s.add_runtime_dependency "httmultiparty"""
|
31
|
+
s.add_runtime_dependency "activemodel"
|
32
|
+
|
33
|
+
end
|
data/lib/hockeyapp.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'active_support/core_ext/object/blank'
|
2
|
+
require 'active_model'
|
3
|
+
require 'hockeyapp/models/active_model_compliance'
|
4
|
+
require "hockeyapp/models/app"
|
5
|
+
require 'hockeyapp/models/crash'
|
6
|
+
require 'hockeyapp/models/version'
|
7
|
+
require 'hockeyapp/models/crash_group'
|
8
|
+
require 'hockeyapp/ws/ws'
|
9
|
+
require 'hockeyapp/ws/client'
|
10
|
+
require 'hockeyapp/config'
|
11
|
+
require 'hockeyapp/services/android_urls'
|
12
|
+
require 'hockeyapp/services/ios_urls'
|
13
|
+
|
14
|
+
module HockeyApp
|
15
|
+
extend self
|
16
|
+
|
17
|
+
def build_client options = {}
|
18
|
+
ws = WS.new options
|
19
|
+
Client.new ws
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module HockeyApp
|
2
|
+
module Config
|
3
|
+
extend self
|
4
|
+
|
5
|
+
ATTRIBUTES = [:token, :base_uri]
|
6
|
+
|
7
|
+
attr_accessor *ATTRIBUTES
|
8
|
+
|
9
|
+
def configure
|
10
|
+
yield self
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_h
|
14
|
+
Hash[ATTRIBUTES.map{|a|[a, self.send("#{a.to_s}")]}]
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module HockeyApp
|
2
|
+
class App
|
3
|
+
extend ActiveModel::Naming
|
4
|
+
include ActiveModel::Conversion
|
5
|
+
include ActiveModel::Validations
|
6
|
+
include ActiveModelCompliance
|
7
|
+
|
8
|
+
ANDROID = 'Android'
|
9
|
+
IOS = 'iOS'
|
10
|
+
|
11
|
+
ATTRIBUTES = [:title, :minimum_os_version, :status, :company, :owner, :bundle_identifier, :device_family, :platform,
|
12
|
+
:public_identifier, :role, :release_type]
|
13
|
+
|
14
|
+
POST_PAYLOAD = [:status,:notes_type, :notify]
|
15
|
+
|
16
|
+
NOTES_TYPES_TO_SYM = {
|
17
|
+
0 => :textile,
|
18
|
+
1 => :markdown
|
19
|
+
}
|
20
|
+
|
21
|
+
|
22
|
+
NOTIFY_TO_BOOL = {
|
23
|
+
0 => false,
|
24
|
+
1 => true
|
25
|
+
}
|
26
|
+
|
27
|
+
STATUS_TO_SYM = {
|
28
|
+
1 => :deny,
|
29
|
+
2 => :allow
|
30
|
+
}
|
31
|
+
|
32
|
+
attr_accessor *ATTRIBUTES
|
33
|
+
attr_accessor *POST_PAYLOAD
|
34
|
+
|
35
|
+
|
36
|
+
validates :notes_type, :inclusion => { :in =>NOTES_TYPES_TO_SYM.keys }
|
37
|
+
validates :notify, :inclusion => { :in => NOTIFY_TO_BOOL.keys }
|
38
|
+
validates :status, :inclusion => { :in => STATUS_TO_SYM.keys }
|
39
|
+
|
40
|
+
|
41
|
+
def self.from_hash(h, client)
|
42
|
+
res = self.new client
|
43
|
+
ATTRIBUTES.each do |attribute|
|
44
|
+
res.send("#{attribute.to_s}=", h[attribute.to_s]) unless (h[attribute.to_s].nil?)
|
45
|
+
end
|
46
|
+
res
|
47
|
+
end
|
48
|
+
|
49
|
+
def initialize client
|
50
|
+
@client = client
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_key
|
54
|
+
[public_identifier] if persisted?
|
55
|
+
end
|
56
|
+
|
57
|
+
def platform= platform
|
58
|
+
@platform = platform
|
59
|
+
end
|
60
|
+
|
61
|
+
def crashes
|
62
|
+
@crashes ||= client.get_crashes(self)
|
63
|
+
end
|
64
|
+
|
65
|
+
def crash_reasons
|
66
|
+
@crash_reasons ||= client.get_crash_groups(self)
|
67
|
+
end
|
68
|
+
|
69
|
+
def versions
|
70
|
+
@versions ||= client.get_versions(self)
|
71
|
+
end
|
72
|
+
|
73
|
+
def last_version
|
74
|
+
sorted_version = versions.sort_by { |v| v.version.to_i}
|
75
|
+
sorted_version.last
|
76
|
+
end
|
77
|
+
|
78
|
+
def icon
|
79
|
+
"https://rink.hockeyapp.net/api/2/apps/#{public_identifier}?format=png"
|
80
|
+
end
|
81
|
+
|
82
|
+
def download_url
|
83
|
+
last_version.download_url
|
84
|
+
end
|
85
|
+
|
86
|
+
def direct_download_url
|
87
|
+
url_strategy.direct_download_url
|
88
|
+
end
|
89
|
+
|
90
|
+
def install_url
|
91
|
+
url_strategy.install_url
|
92
|
+
end
|
93
|
+
|
94
|
+
def create_version file, release_notes = ""
|
95
|
+
version = Version.new(self, @client)
|
96
|
+
version.ipa = file
|
97
|
+
version.notes = release_notes
|
98
|
+
client.post_new_version version
|
99
|
+
@versions = nil
|
100
|
+
end
|
101
|
+
|
102
|
+
def remove
|
103
|
+
client.remove_app self
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
attr_reader :client
|
111
|
+
|
112
|
+
def url_strategy
|
113
|
+
return HockeyApp::IOSAppUrls.new(self) if platform == IOS
|
114
|
+
return HockeyApp::AndroidAppUrls.new(self) if platform == ANDROID
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module HockeyApp
|
2
|
+
class Crash
|
3
|
+
extend ActiveModel::Naming
|
4
|
+
include ActiveModel::Conversion
|
5
|
+
include ActiveModel::Validations
|
6
|
+
include ActiveModelCompliance
|
7
|
+
|
8
|
+
ATTRIBUTES = [:crash_reason_id, :id, :jail_break, :created_at, :updated_at, :contact_string, :app_id, :bundle_version,
|
9
|
+
:app_version_id, :user_string, :has_description, :bundle_short_version, :has_log, :model, :oem, :os_version]
|
10
|
+
|
11
|
+
attr_accessor *ATTRIBUTES
|
12
|
+
attr_reader :app
|
13
|
+
|
14
|
+
|
15
|
+
def self.from_hash(h, app, client)
|
16
|
+
res = self.new app, client
|
17
|
+
ATTRIBUTES.each do |attribute|
|
18
|
+
res.send("#{attribute.to_s}=", h[attribute.to_s]) unless (h[attribute.to_s].nil?)
|
19
|
+
end
|
20
|
+
res
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize app, client
|
24
|
+
@app = app
|
25
|
+
@client = client
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
def log
|
30
|
+
@log ||= client.get_crash_log(self) if has_log
|
31
|
+
end
|
32
|
+
|
33
|
+
def description
|
34
|
+
@description ||= client.get_crash_description(self) if has_description
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
attr_accessor :client
|
41
|
+
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module HockeyApp
|
2
|
+
class CrashGroup
|
3
|
+
extend ActiveModel::Naming
|
4
|
+
include ActiveModel::Conversion
|
5
|
+
include ActiveModel::Validations
|
6
|
+
include ActiveModelCompliance
|
7
|
+
|
8
|
+
ATTRIBUTES = [:file, :reason, :status, :id, :crash_class, :bundle_version, :last_crash_at, :app_version_id,
|
9
|
+
:line, :updated_at, :method, :bundle_short_version, :number_of_crashes, :fixed, :created_at, :app_id]
|
10
|
+
|
11
|
+
|
12
|
+
attr_accessor *ATTRIBUTES
|
13
|
+
attr_reader :application
|
14
|
+
|
15
|
+
|
16
|
+
def self.from_hash(h, app, client)
|
17
|
+
res = self.new app, client
|
18
|
+
ATTRIBUTES.each do |attribute|
|
19
|
+
res.send("#{attribute.to_s}=", h[attribute.to_s]) unless (h[attribute.to_s].nil?)
|
20
|
+
end
|
21
|
+
res.send("crash_class=", h['class']) unless h['class'].nil? # we should not override the #class method
|
22
|
+
res
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize application, client
|
26
|
+
@application = application
|
27
|
+
@client = client
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
attr_reader :client
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module HockeyApp
|
2
|
+
class Version
|
3
|
+
extend ActiveModel::Naming
|
4
|
+
include ActiveModel::Conversion
|
5
|
+
include ActiveModel::Validations
|
6
|
+
include ActiveModelCompliance
|
7
|
+
|
8
|
+
ATTRIBUTES = [:id, :notes, :shortversion, :version, :mandatory, :timestamp, :appsize, :title, :download_url]
|
9
|
+
|
10
|
+
POST_PAYLOAD = [:status, :ipa, :dsym, :notes_type, :notify, :tags]
|
11
|
+
|
12
|
+
NOTES_TYPES_TO_SYM = {
|
13
|
+
0 => :textile,
|
14
|
+
1 => :markdown
|
15
|
+
}
|
16
|
+
|
17
|
+
|
18
|
+
NOTIFY_TO_BOOL = {
|
19
|
+
0 => false,
|
20
|
+
1 => true
|
21
|
+
}
|
22
|
+
|
23
|
+
STATUS_TO_SYM = {
|
24
|
+
1 => :deny,
|
25
|
+
2 => :allow
|
26
|
+
}
|
27
|
+
|
28
|
+
attr_accessor *ATTRIBUTES
|
29
|
+
attr_accessor *POST_PAYLOAD
|
30
|
+
attr_reader :app
|
31
|
+
|
32
|
+
validates :notes_type, :inclusion => { :in =>NOTES_TYPES_TO_SYM.keys }
|
33
|
+
validates :notify, :inclusion => { :in => NOTIFY_TO_BOOL.keys }
|
34
|
+
validates :status, :inclusion => { :in => STATUS_TO_SYM.keys }
|
35
|
+
|
36
|
+
|
37
|
+
def self.from_hash(h, app, client)
|
38
|
+
res = self.new app, client
|
39
|
+
ATTRIBUTES.each do |attribute|
|
40
|
+
res.send("#{attribute.to_s}=", h[attribute.to_s]) unless (h[attribute.to_s].nil?)
|
41
|
+
end
|
42
|
+
res
|
43
|
+
end
|
44
|
+
|
45
|
+
def initialize app, client
|
46
|
+
@app = app
|
47
|
+
@client = client
|
48
|
+
default_values!
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
def to_key
|
53
|
+
[@id] if persisted?
|
54
|
+
end
|
55
|
+
|
56
|
+
def crashes
|
57
|
+
@crashes ||= @app.crashes.select{|crash| "#{crash.app_version_id}" == @id.to_s}
|
58
|
+
end
|
59
|
+
|
60
|
+
def crash_reasons
|
61
|
+
@crash_groups ||= @app.crash_reasons.select{|crash_reason| "#{crash_reason.app_version_id}" == @id.to_s}
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
def direct_download_url
|
66
|
+
url_strategy.direct_download_url
|
67
|
+
end
|
68
|
+
|
69
|
+
def install_url
|
70
|
+
url_strategy.install_url
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
attr_reader :client
|
76
|
+
|
77
|
+
def default_values!
|
78
|
+
@dsym=nil
|
79
|
+
@notes="New version"
|
80
|
+
@notes_type=Version::NOTES_TYPES_TO_SYM.invert[:textile]
|
81
|
+
@notify=Version::NOTIFY_TO_BOOL.invert[false]
|
82
|
+
@status=Version::STATUS_TO_SYM.invert[:allow]
|
83
|
+
end
|
84
|
+
|
85
|
+
def url_strategy
|
86
|
+
return HockeyApp::IOSVersionUrls.new(self) if app.platform == HockeyApp::App::IOS
|
87
|
+
return HockeyApp::AndroidVersionUrls.new(self) if app.platform == HockeyApp::App::ANDROID
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|