halcyon_api 0.0.5
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/.gitignore +53 -0
- data/.rspec +3 -0
- data/.rubocop.yml +2 -0
- data/.travis.yml +24 -0
- data/Gemfile +2 -0
- data/LICENSE +21 -0
- data/README.md +8 -0
- data/halcyon_api.gemspec +25 -0
- data/lib/halcyon_api/client.rb +256 -0
- data/lib/halcyon_api/region.rb +104 -0
- data/lib/halcyon_api/version.rb +7 -0
- data/lib/halcyon_api.rb +20 -0
- data/spec/cassettes/api_key.yml +47 -0
- data/spec/cassettes/match.yml +103 -0
- data/spec/cassettes/matches.yml +203 -0
- data/spec/cassettes/player.yml +53 -0
- data/spec/cassettes/players.yml +153 -0
- data/spec/cassettes/samples.yml +253 -0
- data/spec/cassettes/status.yml +41 -0
- data/spec/cassettes/telemetry.yml +1140 -0
- data/spec/lib/halcyon_api/client_spec.rb +249 -0
- data/spec/lib/halcyon_api/region_spec.rb +70 -0
- data/spec/lib/halcyon_api_spec.rb +8 -0
- data/spec/spec_helper.rb +117 -0
- data/spec/support/klasses.rb +18 -0
- metadata +151 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c8c3807da4860d5d3f787f40e11787745c32ad41ebe0d45cbefa6b11c4e1dcf6
|
4
|
+
data.tar.gz: bbe9a110a5c1d7424896e863d5527ed8140ad9b3e7d5da61bdb052bc64c412d5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 48220ccd8c382fb62dd0cf7d031971fd8df7ba1ad8c7307d76a80225d494295f0cb20bd5627525eca1bbff9a8f4a33889878b4f1f20725871a296cc2f97319d7
|
7
|
+
data.tar.gz: 54b8a60360aee1625c2e3bf8dac0a7a4f57bf62692aa6a3ec3e7c2630c822ab875944084961cc3a1f7bc2a6028a017f77b5e3ff8b0ec1d725429e31fb1d94dde
|
data/.gitignore
ADDED
@@ -0,0 +1,53 @@
|
|
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
|
51
|
+
|
52
|
+
# idea ide
|
53
|
+
.idea
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
- 2.5.0
|
4
|
+
- 2.4.0
|
5
|
+
- 2.3.3
|
6
|
+
- 2.2
|
7
|
+
- 2.1
|
8
|
+
- 2.0
|
9
|
+
sudo: false
|
10
|
+
gemfile: Gemfile
|
11
|
+
script: bundle exec rspec spec
|
12
|
+
addons:
|
13
|
+
code_climate:
|
14
|
+
repo_token: adb0d5afb7471b3ec7edc3820093500b1176c6e8bc42b831098274bac1b18516
|
15
|
+
after_success:
|
16
|
+
- bundle exec codeclimate-test-reporter
|
17
|
+
deploy:
|
18
|
+
provider: rubygems
|
19
|
+
api_key:
|
20
|
+
secure: fTWdFlk9onlQHFJZD/VxqqjnprBYUORe9cH3hXL/MkoS9yxNGT0XLVlS2OcG2SN8AzWfhrwZCpn9+OlL9etSgwSoPccWHEkUOZCkEpLL1GP5DH0OXoq9ZE+VMHFj8iOI+j9azM4xc5HrnwHagKZFfDt4aFHCZMeXrXbuwROCgzp/CvsZt7OGwOvmP0519M33pA3ltZaUQc56iGKhSUAfT2CK0DPkv1l8H4lB5UV26SwqlWJxRFT8cnfJ5tPqN8jWM1SXsOP7aCupmEuOmz1UFpPHGZHh9E9sTOw/kGwV5HSYu4VFbyURDoQY/X8A3h5b+LsFwDPoX0u7fxZCdLJ3VQ2t+rfT3os9HRZBG75Oux/QBPayZJQYcUqfQDsOIljahLe4Xe7ElHO2/uFH2AONpt6ZoenjTgS0b/0Pu7sSzPhra+MIZxgHeE37SQl3l0mnPKnd2Ysvu/mnaD2BW/TD0kLN50gPQneHiUbO7k2VTtxM/l1gbnWc8W6C0YRnslV3YGOjfR9wD2hAfwun2Jvoax+WfoNQJ3ZuOceBotaifrSgxipWQM68Ad3Ou1PQjuXFSbI/Cm6tafPVbU6pItrNiBUee0nR9pwLY3lnSiCHbd+WvEbXQPqQWysPIghG0m4QXErPxxWA65ppOBTbdYI3xG6GdFC4xhS9Gb0SJnRmfwI=
|
21
|
+
gem: halcyon_api
|
22
|
+
on:
|
23
|
+
tags: true
|
24
|
+
repo: shikatadev/halcyon_api
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2018 Ethan Tang
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
# Halcyon API
|
2
|
+
[](https://travis-ci.org/shikatadev/vainglory-api)
|
3
|
+
[](https://codeclimate.com/github/shikatadev/vainglory-api/maintainability)
|
4
|
+
[](https://codeclimate.com/github/shikatadev/vainglory-api/test_coverage)
|
5
|
+
|
6
|
+
A Ruby libary wrapper for the Vainglory API
|
7
|
+
|
8
|
+
---
|
data/halcyon_api.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
$LOAD_PATH.push File.expand_path('../lib', __FILE__)
|
2
|
+
require 'halcyon_api/version'
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = 'halcyon_api'
|
6
|
+
s.version = HalcyonAPI::VERSION.dup
|
7
|
+
s.date = HalcyonAPI::RELEASE_DATE.dup
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.summary = 'Vainglory API'
|
10
|
+
s.description = 'A Ruby libary wrapper for the Vainglory API'
|
11
|
+
s.authors = ['Ethan Tang']
|
12
|
+
s.homepage = 'https://github.com/shikatadev/halcyon_api'
|
13
|
+
s.license = 'MIT'
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- spec/*`.split("\n")
|
17
|
+
s.require_paths = ['lib']
|
18
|
+
s.required_ruby_version = '>= 2.0'
|
19
|
+
|
20
|
+
s.add_development_dependency 'webmock', '~> 2.3'
|
21
|
+
s.add_development_dependency 'vcr', '~> 3.0'
|
22
|
+
s.add_development_dependency 'rspec', '~> 3.5'
|
23
|
+
s.add_development_dependency 'simplecov', '~> 0.14'
|
24
|
+
s.add_development_dependency 'codeclimate-test-reporter', '~> 1.0'
|
25
|
+
end
|
@@ -0,0 +1,256 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'ostruct'
|
3
|
+
require 'openssl'
|
4
|
+
require 'net/http'
|
5
|
+
require 'halcyon_api/region'
|
6
|
+
|
7
|
+
module HalcyonAPI
|
8
|
+
# Used to interface with the official Vainglory API
|
9
|
+
#
|
10
|
+
# @see https://developer.vainglorygame.com/docs Vainglory API Documentation
|
11
|
+
# @see https://developer.vainglorygame.com/docs#payload Vainglory API "Payload"
|
12
|
+
# @see https://developer.vainglorygame.com/docs#rate-limits Vainglory API "Rate Limits"
|
13
|
+
class Client
|
14
|
+
# The base URL used for most requests
|
15
|
+
BASE_URL = 'https://api.dc01.gamelockerapp.com'.freeze
|
16
|
+
|
17
|
+
# A new instance of Client.
|
18
|
+
#
|
19
|
+
# @param (String) api_key your Vainglory API key
|
20
|
+
# @param (String) region_identifier the name or short name for your specified Region shard
|
21
|
+
# @example Initialize a new client
|
22
|
+
# client = VaingloryAPI::Client.new('API_KEY', 'na')
|
23
|
+
# @return [Client] a new instance of the client
|
24
|
+
# @note Requires a valid region short name.
|
25
|
+
# @see VaingloryAPI::Region::SHORT_NAMES
|
26
|
+
def initialize(api_key, region_identifier = 'na')
|
27
|
+
@api_key = api_key
|
28
|
+
@region = Region.find(region_identifier)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Gets batches of random match data
|
32
|
+
#
|
33
|
+
# @param [Hash] filter_params the parameters used to filter results
|
34
|
+
# @option filter_params [String] 'page[offset]' (0) Allows paging over results
|
35
|
+
# @option filter_params [String] 'page[limit]' (50) Values less than 50 and great than 2 are supported.
|
36
|
+
# @option filter_params [String] 'sort' (createdAt) By default, Matches are sorted by creation time ascending.
|
37
|
+
# @option filter_params [String] 'filter[createdAt-start]' (3hrs ago) Must occur before end time. Format is iso8601
|
38
|
+
# @option filter_params [String] 'filter[createdAt-end]' (Now) Queries search the last 3 hrs. Format is iso8601
|
39
|
+
# @example Get samples
|
40
|
+
# client = VaingloryAPI::Client.new('API_KEY', 'na')
|
41
|
+
# client.samples
|
42
|
+
# @return [OpenStruct] the response and metadata
|
43
|
+
# @see https://developer.vainglorygame.com/docs#samples Vainglory API "Samples"
|
44
|
+
# @see https://developer.vainglorygame.com/docs#pagination Vainglory API "Pagination"
|
45
|
+
# @see https://developer.vainglorygame.com/docs#sorting Vainglory API "Sorting"
|
46
|
+
def samples(filter_params = {})
|
47
|
+
get_request(shard_endpoint_uri('samples', filter_params))
|
48
|
+
end
|
49
|
+
|
50
|
+
# Gets data from matches (multiple)
|
51
|
+
#
|
52
|
+
# @param [Hash] filter_params the parameters used to filter results
|
53
|
+
# @option filter_params [String] 'page[offset]' (0) Allows paging over results
|
54
|
+
# @option filter_params [String] 'page[limit]' (50) Values less than 50 and great than 2 are supported.
|
55
|
+
# @option filter_params [String] 'sort' (createdAt) By default, Matches are sorted by creation time ascending.
|
56
|
+
# @option filter_params [String] 'filter[createdAt-start]' (3hrs ago) Must occur before end time. Format is iso8601
|
57
|
+
# @option filter_params [String] 'filter[createdAt-end]' (Now) Queries search the last 3 hrs. Format is iso8601
|
58
|
+
# @option filter_params [String] 'filter[playerNames]' Filters by player name, separated by commas.
|
59
|
+
# @option filter_params [String] 'filter[playerIds]' Filters by player Id, separated by commas.
|
60
|
+
# @option filter_params [String] 'filter[teamNames]' Filters by team names. Team names are the same as the in game team tags.
|
61
|
+
# @option filter_params [String] 'filter[gameMode]' Filters by Game Mode
|
62
|
+
# @example Get matches
|
63
|
+
# client = VaingloryAPI::Client.new('API_KEY', 'na')
|
64
|
+
# client.matches
|
65
|
+
# @example Get matches with a filter
|
66
|
+
# client = VaingloryAPI::Client.new('API_KEY', 'na')
|
67
|
+
# client.matches('filter[playerNames]' => 'player_name')
|
68
|
+
# @return [OpenStruct] the response and metadata
|
69
|
+
# @see https://developer.vainglorygame.com/docs#get-a-collection-of-matches Vainglory API "Get a collection of Matches"
|
70
|
+
# @see https://developer.vainglorygame.com/docs#rosters Vainglory API "Rosters"
|
71
|
+
# @see https://developer.vainglorygame.com/docs#match-data-summary Vainglory API "Match Data Summary"
|
72
|
+
# @see https://developer.vainglorygame.com/docs#pagination Vainglory API "Pagination"
|
73
|
+
# @see https://developer.vainglorygame.com/docs#sorting Vainglory API "Sorting"
|
74
|
+
def matches(filter_params = {})
|
75
|
+
get_request(shard_endpoint_uri('matches', filter_params))
|
76
|
+
end
|
77
|
+
|
78
|
+
# Gets data for a single match
|
79
|
+
#
|
80
|
+
# @param [String] match_id the ID of the requested match
|
81
|
+
# @example Get a single match
|
82
|
+
# client = VaingloryAPI::Client.new('API_KEY', 'na')
|
83
|
+
# client.match('MATCH_ID')
|
84
|
+
# @return [OpenStruct] the response and metadata
|
85
|
+
# @see https://developer.vainglorygame.com/docs#get-a-single-match Vainglory API "Get a single Match"
|
86
|
+
# @see https://developer.vainglorygame.com/docs#rosters Vainglory API "Rosters"
|
87
|
+
# @see https://developer.vainglorygame.com/docs#match-data-summary Vainglory API "Match Data Summary"
|
88
|
+
def match(match_id)
|
89
|
+
get_request(shard_endpoint_uri("matches/#{match_id}"))
|
90
|
+
end
|
91
|
+
|
92
|
+
# Gets data about players (one or more)
|
93
|
+
#
|
94
|
+
# @param [String] player_name the in-game name (IGN) of a player
|
95
|
+
# @param [String] additional_player_names additional IGNs for search for
|
96
|
+
# @example Search for a player
|
97
|
+
# client = VaingloryAPI::Client.new('API_KEY', 'na')
|
98
|
+
# client.players('player_name')
|
99
|
+
# @example Search for multiple players
|
100
|
+
# client = VaingloryAPI::Client.new('API_KEY', 'na')
|
101
|
+
# client.players('player_name', 'player_name2')
|
102
|
+
# @return [OpenStruct] the response and metadata
|
103
|
+
# @see https://developer.vainglorygame.com/docs#get-a-collection-of-players Vainglory API "Get a collection of players"
|
104
|
+
def players(player_name, *additional_player_names)
|
105
|
+
player_names = [player_name].concat(additional_player_names)
|
106
|
+
filter_params = { 'filter[playerNames]' => player_names.join(',') }
|
107
|
+
|
108
|
+
get_request(shard_endpoint_uri('players', filter_params))
|
109
|
+
end
|
110
|
+
|
111
|
+
# Gets data for a single player
|
112
|
+
#
|
113
|
+
# @param [String] player_id the ID of the requested player
|
114
|
+
# @example Get a single player
|
115
|
+
# client = VaingloryAPI::Client.new('API_KEY', 'na')
|
116
|
+
# client.match('PLAYER_ID')
|
117
|
+
# @return [OpenStruct] the response and metadata
|
118
|
+
# @see https://developer.vainglorygame.com/docs#get-a-single-player Vainglory API "Get a single Player"
|
119
|
+
def player(player_id)
|
120
|
+
get_request(shard_endpoint_uri("players/#{player_id}"))
|
121
|
+
end
|
122
|
+
|
123
|
+
# Gets telemtry data from a specified URL
|
124
|
+
#
|
125
|
+
# @param [String] url the URL of the requested Telemetry data
|
126
|
+
# @example Get telemetry data
|
127
|
+
# client = VaingloryAPI::Client.new('API_KEY', 'na')
|
128
|
+
# client.telemetry('TELEMETRY_URL')
|
129
|
+
# @return [OpenStruct] the response and metadata
|
130
|
+
# @see https://developer.vainglorygame.com/docs#telemetry Vainglory API "Telemetry"
|
131
|
+
def telemetry(url)
|
132
|
+
get_request(URI(url), true, false)
|
133
|
+
end
|
134
|
+
|
135
|
+
# Gets aggregated lifetime information about teams (multiple)
|
136
|
+
#
|
137
|
+
# @param [Hash] _filter_params the parameters used to filter results
|
138
|
+
# @option _filter_params [String] 'filter[teamNames]' Filters by team name
|
139
|
+
# @option _filter_params [String] 'filter[teamIds]' Filters by team ID
|
140
|
+
# @raise [NotImplementedError] this endpoint is not yet available
|
141
|
+
# @see https://developer.vainglorygame.com/docs#teams-coming-soon Vainglory API "Get a collection of Teams"
|
142
|
+
def teams(_filter_params = {})
|
143
|
+
raise(NotImplementedError, 'Coming soon!')
|
144
|
+
end
|
145
|
+
|
146
|
+
# Gets aggregated lifetime information about a single team
|
147
|
+
#
|
148
|
+
# @raise [NotImplementedError] this endpoint is not yet available
|
149
|
+
# @see https://developer.vainglorygame.com/docs#get-a-single-team Vainglory API "Get a single Team"
|
150
|
+
def team(_team_id)
|
151
|
+
raise(NotImplementedError, 'Coming soon!')
|
152
|
+
end
|
153
|
+
|
154
|
+
# Checks to see if a link object exists for a given code
|
155
|
+
#
|
156
|
+
# @raise [NotImplementedError] this endpoint is not yet available
|
157
|
+
# @see https://developer.vainglorygame.com/docs#links-coming-soon Vainglory API "Links"
|
158
|
+
def link(_link_id)
|
159
|
+
raise(NotImplementedError, 'Coming soon!')
|
160
|
+
end
|
161
|
+
|
162
|
+
# Gets current API version and release date
|
163
|
+
#
|
164
|
+
# @example Get the API's status information
|
165
|
+
# client = VaingloryAPI::Client.new('API_KEY', 'na')
|
166
|
+
# client.status
|
167
|
+
# @return [OpenStruct] the response and metadata
|
168
|
+
# @see https://developer.vainglorygame.com/docs#versioning Vainglory API "Versioning"
|
169
|
+
def status
|
170
|
+
get_request_without_headers(endpoint_uri('status'))
|
171
|
+
end
|
172
|
+
|
173
|
+
private
|
174
|
+
|
175
|
+
def region_identifier
|
176
|
+
@region.short_name
|
177
|
+
end
|
178
|
+
|
179
|
+
def get_request_without_headers(uri)
|
180
|
+
get_request(uri, false)
|
181
|
+
end
|
182
|
+
|
183
|
+
def get_request(uri, with_headers = true, with_auth = true)
|
184
|
+
req = Net::HTTP::Get.new(uri)
|
185
|
+
req = apply_headers(req, with_auth) if with_headers
|
186
|
+
|
187
|
+
request(uri, req)
|
188
|
+
end
|
189
|
+
|
190
|
+
def apply_headers(req, with_auth = true)
|
191
|
+
req['Authorization'] = "Bearer #{@api_key}" if with_auth
|
192
|
+
req['X-TITLE-ID'] = 'semc-vainglory'
|
193
|
+
req['Accept'] = 'application/vnd.api+json'
|
194
|
+
|
195
|
+
req
|
196
|
+
end
|
197
|
+
|
198
|
+
def request(uri, req)
|
199
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
200
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
201
|
+
http.use_ssl = true
|
202
|
+
|
203
|
+
response(http.request(req))
|
204
|
+
end
|
205
|
+
|
206
|
+
def shard_endpoint_uri(path, filter_params = {})
|
207
|
+
endpoint_uri("shards/#{region_identifier}/#{path}", filter_params)
|
208
|
+
end
|
209
|
+
|
210
|
+
def endpoint_uri(path, filter_params = {})
|
211
|
+
uri = URI(endpoint_url(path))
|
212
|
+
uri.query = URI.encode_www_form(filter_params)
|
213
|
+
|
214
|
+
uri
|
215
|
+
end
|
216
|
+
|
217
|
+
def endpoint_url(path)
|
218
|
+
[BASE_URL, path].join('/')
|
219
|
+
end
|
220
|
+
|
221
|
+
def response(response_data)
|
222
|
+
response_object = serialize_response_data(response_data.body)
|
223
|
+
metadata = serialize_response_metadata(response_data)
|
224
|
+
|
225
|
+
# Add metadata members to response_object
|
226
|
+
metadata.each do |k, v|
|
227
|
+
response_object[k] = v
|
228
|
+
end
|
229
|
+
|
230
|
+
response_object
|
231
|
+
end
|
232
|
+
|
233
|
+
def serialize_response_metadata(response_data)
|
234
|
+
response_code = response_data.code.to_i
|
235
|
+
|
236
|
+
{
|
237
|
+
code: response_code,
|
238
|
+
success?: response_code < 400,
|
239
|
+
rate_limit: response_data['X-RateLimit-Limit'].to_i,
|
240
|
+
rate_remaining: response_data['X-RateLimit-Remaining'].to_i,
|
241
|
+
rate_reset: response_data['X-RateLimit-Reset'].to_i,
|
242
|
+
raw: response_data
|
243
|
+
}
|
244
|
+
end
|
245
|
+
|
246
|
+
def serialize_response_data(raw_response_body)
|
247
|
+
data = JSON.parse(raw_response_body, object_class: OpenStruct)
|
248
|
+
|
249
|
+
if data.is_a?(Array)
|
250
|
+
OpenStruct.new(data: data)
|
251
|
+
else
|
252
|
+
data
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
module HalcyonAPI
|
4
|
+
# Helper class for metadata pertaining to regions
|
5
|
+
#
|
6
|
+
# @see https://developer.vainglorygame.com/docs#regions Vainglory API "Regions"
|
7
|
+
class Region
|
8
|
+
# Arrays of metadata about each region
|
9
|
+
DB = [
|
10
|
+
['general', 'na', 'North America'],
|
11
|
+
['general', 'eu', 'Europe'],
|
12
|
+
['general', 'sa', 'South America'],
|
13
|
+
['general', 'ea', 'East Asia'],
|
14
|
+
['general', 'sg', 'Southeast Asia (SEA)'],
|
15
|
+
['tournament', 'tournament-na', 'North America Tournaments'],
|
16
|
+
['tournament', 'tournament-eu', 'Europe Tournaments'],
|
17
|
+
['tournament', 'tournament-sa', 'South America Tournaments'],
|
18
|
+
['tournament', 'tournament-ea', 'East Asia Tournaments'],
|
19
|
+
['tournament', 'tournament-sg', 'Southeast Asia Tournaments']
|
20
|
+
].freeze
|
21
|
+
|
22
|
+
# Unique Region types (general, tournament, etc...) extracted from DB metadata
|
23
|
+
TYPES = DB.map { |region_data| region_data[0] }.uniq.freeze
|
24
|
+
|
25
|
+
# Valid short names (na, eu, etc...) extracted from DB metadata
|
26
|
+
SHORT_NAMES = DB.map { |region_data| region_data[1] }.freeze
|
27
|
+
|
28
|
+
# @return [String] the name of the region
|
29
|
+
attr_reader :name
|
30
|
+
|
31
|
+
# @return [String] the short name of the region
|
32
|
+
attr_reader :short_name
|
33
|
+
|
34
|
+
# @return [String] the type of region
|
35
|
+
attr_reader :type
|
36
|
+
|
37
|
+
# A new instance of Region.
|
38
|
+
#
|
39
|
+
# @param (String) identifier the name or short name of a region
|
40
|
+
# @return [Region] a new instance of a Region
|
41
|
+
# @raise [HalcyonAPI::RegionNameError] if the identifier is not found
|
42
|
+
# @see SHORT_NAMES
|
43
|
+
# @see DB
|
44
|
+
def initialize(identifier)
|
45
|
+
data = self.class.detect_region_info(identifier)
|
46
|
+
@type = data[0]
|
47
|
+
@short_name = data[1]
|
48
|
+
@name = data[2]
|
49
|
+
rescue NoMethodError
|
50
|
+
raise(RegionNameError, "Couldn't find region for '#{identifier}'")
|
51
|
+
end
|
52
|
+
|
53
|
+
# Alias method for short name
|
54
|
+
#
|
55
|
+
# @return [String] the "short name" of the region
|
56
|
+
def abbreviation
|
57
|
+
@short_name
|
58
|
+
end
|
59
|
+
|
60
|
+
# Compares region to another region.
|
61
|
+
#
|
62
|
+
# @example Compare two regions
|
63
|
+
# HalcyonAPI::Region['na'].eql? VaingloryAPI::Region['na'] # => true
|
64
|
+
# HalcyonAPI::Region['na'].eql? VaingloryAPI::Region['sg'] # => false
|
65
|
+
# @param [VaingloryAPU::Region] other another region to compare for quality
|
66
|
+
# @return [Boolean] whether all attributes match
|
67
|
+
def eql?(other)
|
68
|
+
%i(name short_name type).all? { |a| send(a) == other.send(a) }
|
69
|
+
end
|
70
|
+
|
71
|
+
class << self
|
72
|
+
alias find new
|
73
|
+
alias [] new
|
74
|
+
|
75
|
+
# Checks if short name is known
|
76
|
+
#
|
77
|
+
# @example Checking if a short name is valid
|
78
|
+
# HalcyonAPI::Region.valid_short_name?('na') # => true
|
79
|
+
# HalcyonAPI::Region.valid_short_name?('QQ') # => false
|
80
|
+
# @param [String] short_name the short name of a desired region
|
81
|
+
# @return [Boolean] whether the short name is known
|
82
|
+
# @see SHORT_NAMES
|
83
|
+
# @see DB
|
84
|
+
def valid_short_name?(short_name)
|
85
|
+
SHORT_NAMES.include?(short_name)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Detects region data from DB constant
|
89
|
+
#
|
90
|
+
# @example Detecting region data from DB
|
91
|
+
# HalcyonAPI::Region.detech_region_info('na')
|
92
|
+
# @param [String] identifier the name or short name of the desired region
|
93
|
+
# @return [Array] if region data is found
|
94
|
+
# @return [nil] if region data is not found
|
95
|
+
# @see DB
|
96
|
+
def detect_region_info(identifier)
|
97
|
+
DB.detect { |region_data| region_data[1, 2].include?(identifier) }
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Helper exception class used to notify user of invalid names
|
103
|
+
class RegionNameError < ArgumentError; end
|
104
|
+
end
|
data/lib/halcyon_api.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'halcyon_api/client'
|
2
|
+
|
3
|
+
# A Ruby libary wrapper for the Vainglory API
|
4
|
+
#
|
5
|
+
# @author Ethan Tang
|
6
|
+
module HalcyonAPI
|
7
|
+
# Alias for VaingloryAPI::Client constructor
|
8
|
+
#
|
9
|
+
# @overload new(api_key, region)
|
10
|
+
# @param api_key (String) your Vainglory API key
|
11
|
+
# @param region (String) the short name for your specified Region shard
|
12
|
+
# @param (see HalcyonAPI::Client#initialize)
|
13
|
+
# @example Initialize a new client
|
14
|
+
# client = VaingloryAPI.new('API_KEY', 'na')
|
15
|
+
# @return [HalcyonAPI::Client] an instance of the client
|
16
|
+
# @see VaingloryAPI::Client#initialize
|
17
|
+
def self.new(*args)
|
18
|
+
Client.new(*args)
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: https://api.dc01.gamelockerapp.com/shards/na/samples
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
Accept-Encoding:
|
11
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
12
|
+
Accept:
|
13
|
+
- application/vnd.api+json
|
14
|
+
User-Agent:
|
15
|
+
- Ruby
|
16
|
+
Host:
|
17
|
+
- api.dc01.gamelockerapp.com
|
18
|
+
Authorization:
|
19
|
+
- Bearer invalid-api-key
|
20
|
+
X-Title-Id:
|
21
|
+
- semc-vainglory
|
22
|
+
response:
|
23
|
+
status:
|
24
|
+
code: 401
|
25
|
+
message: Unauthorized
|
26
|
+
headers:
|
27
|
+
Date:
|
28
|
+
- Tue, 06 Jun 2017 22:11:52 GMT
|
29
|
+
Content-Type:
|
30
|
+
- application/vnd.api+json
|
31
|
+
Content-Length:
|
32
|
+
- '62'
|
33
|
+
Connection:
|
34
|
+
- keep-alive
|
35
|
+
Vary:
|
36
|
+
- Accept-Encoding
|
37
|
+
X-Request-Id:
|
38
|
+
- 9776fd2e-6ac6-4814-83a9-d4f5d342a9c9
|
39
|
+
X-Title-Id:
|
40
|
+
- semc-vainglory
|
41
|
+
body:
|
42
|
+
encoding: ASCII-8BIT
|
43
|
+
string: |
|
44
|
+
{"errors":[{"title":"Unauthorized"}]}
|
45
|
+
http_version:
|
46
|
+
recorded_at: Tue, 06 Jun 2017 22:11:52 GMT
|
47
|
+
recorded_with: VCR 3.0.3
|