bnet 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +16 -0
- data/.travis.yml +15 -0
- data/Gemfile +4 -0
- data/Guardfile +13 -0
- data/LICENSE.txt +22 -0
- data/README.md +120 -0
- data/Rakefile +14 -0
- data/TODO.md +74 -0
- data/bnet.gemspec +34 -0
- data/fixtures/cassettes/diablo_hero_found.yml +1023 -0
- data/fixtures/cassettes/diablo_hero_notf_found.yml +48 -0
- data/fixtures/cassettes/diablo_hero_reload.yml +1023 -0
- data/fixtures/cassettes/find_diablo_career_doesnt_exist.yml +93 -0
- data/fixtures/cassettes/find_diablo_career_player_one_.yml +2803 -0
- data/fixtures/cassettes/sc2_profile_found.yml +523 -0
- data/fixtures/cassettes/sc2_profile_not_found.yml +49 -0
- data/fixtures/cassettes/wow_character_found.yml +46 -0
- data/fixtures/cassettes/wow_character_not_found.yml +42 -0
- data/fixtures/cassettes/wow_data_battlegroups_all.yml +45 -0
- data/fixtures/cassettes/wow_data_character_races_all.yml +45 -0
- data/lib/bnet.rb +34 -0
- data/lib/bnet/account.rb +4 -0
- data/lib/bnet/api.rb +21 -0
- data/lib/bnet/bnet_resource.rb +25 -0
- data/lib/bnet/client.rb +6 -0
- data/lib/bnet/configuration.rb +7 -0
- data/lib/bnet/diablo3.rb +11 -0
- data/lib/bnet/diablo3/career.rb +91 -0
- data/lib/bnet/diablo3/hero.rb +131 -0
- data/lib/bnet/diablo3/skill.rb +19 -0
- data/lib/bnet/starcraft2.rb +7 -0
- data/lib/bnet/starcraft2/profile.rb +94 -0
- data/lib/bnet/version.rb +3 -0
- data/lib/bnet/wow.rb +7 -0
- data/lib/bnet/wow/character.rb +78 -0
- data/lib/bnet/wow/data.rb +5 -0
- data/lib/bnet/wow/data/base.rb +54 -0
- data/lib/bnet/wow/data/battlegroup.rb +18 -0
- data/lib/bnet/wow/data/character_race.rb +15 -0
- data/spec/bnet/account_spec.rb +5 -0
- data/spec/bnet/api_spec.rb +20 -0
- data/spec/bnet/diablo3/career_spec.rb +57 -0
- data/spec/bnet/diablo3/hero_spec.rb +89 -0
- data/spec/bnet/diablo3/skill_spec.rb +26 -0
- data/spec/bnet/diablo3_spec.rb +19 -0
- data/spec/bnet/starcraft2/profile_spec.rb +53 -0
- data/spec/bnet/wow/character_spec.rb +57 -0
- data/spec/bnet/wow/data/base_spec.rb +9 -0
- data/spec/bnet/wow/data/battlegroup_spec.rb +17 -0
- data/spec/bnet/wow/data/character_race_spec.rb +19 -0
- data/spec/bnet/wow/data_spec.rb +21 -0
- data/spec/bnet_spec.rb +8 -0
- data/spec/secrets_and_all_that.rb.sample +8 -0
- data/spec/secrets_and_all_that.rb.travis +8 -0
- data/spec/spec_helper.rb +29 -0
- metadata +285 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
class Bnet::Diablo3::Skill < Bnet::BnetResource
|
2
|
+
|
3
|
+
attr_accessor :name, :rune
|
4
|
+
|
5
|
+
|
6
|
+
# Ags :
|
7
|
+
# {
|
8
|
+
# "skill" => { name: "", ... },
|
9
|
+
# "rune" => { name: "", ... }
|
10
|
+
# }
|
11
|
+
#
|
12
|
+
# Returns:
|
13
|
+
#
|
14
|
+
# #<Bnet::Diablo3::Skill:0x007fd111396360 @name: "", @rune=>
|
15
|
+
def self.from_api(response)
|
16
|
+
new(name: response['skill']['name'], rune: response['rune']['name'])
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# TODO: Associations for career, current_season
|
2
|
+
class Bnet::Starcraft2::Profile < Bnet::BnetResource
|
3
|
+
|
4
|
+
attr_accessor :profile_id, :realm, :display_name, :clan_name, :clan_tag,
|
5
|
+
:achievement_points, :swarm_level, :terran_level, :zerg_level,
|
6
|
+
:protoss_level, :acievement_points
|
7
|
+
|
8
|
+
PARAMS_MAPPING = {
|
9
|
+
"id" => :profile_id,
|
10
|
+
"realm" => :realm,
|
11
|
+
"displayName" => :display_name,
|
12
|
+
"clanName" => :clan_name,
|
13
|
+
"clanTag" => :clan_tag,
|
14
|
+
"career" => :career
|
15
|
+
}
|
16
|
+
|
17
|
+
def initialize args
|
18
|
+
args.each do |k,v|
|
19
|
+
instance_variable_set("@#{k}", v) unless v.nil?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Query Battlenet API for the SC2 profile recordand create an instance of an
|
24
|
+
# SC2 Profile.
|
25
|
+
#
|
26
|
+
# Hash Params:
|
27
|
+
# Required
|
28
|
+
# :realm - (required but defaults to '1')
|
29
|
+
# :profile_id - ID (Honestly i do not know why Blizzard still needs this if
|
30
|
+
# localized Battletag is unique enough)
|
31
|
+
# :name - Just the name string in the Battle tag.
|
32
|
+
# Optional
|
33
|
+
# :locale - (defaults to 'en_US')
|
34
|
+
# :api_key - the api key
|
35
|
+
#
|
36
|
+
# Example: If US account 'Playerone#1309' the profile can be accessible via
|
37
|
+
# web from 'http://us.battle.net/sc2/en/profile/2143215/1/PlayerOne/'
|
38
|
+
#
|
39
|
+
# find(region: 'us', profile_id: 2143215, name: 'PlayerOne')
|
40
|
+
#
|
41
|
+
# Returns a Profile object with the following attributes
|
42
|
+
#
|
43
|
+
# :profile_id, :realm, :display_name, :clan_name, :clan_tag,
|
44
|
+
# :achievement_points, :swarm_level, :terran_level, :zerg_level,
|
45
|
+
# :protoss_level, :acievement_points
|
46
|
+
def self.find args
|
47
|
+
region = args.delete(:region)
|
48
|
+
profile_id = args.delete(:profile_id)
|
49
|
+
name = args.delete(:name)
|
50
|
+
realm = args.delete(:realm) || '1'
|
51
|
+
locale = args.delete(:locale) || 'en_US'
|
52
|
+
api_key = args.delete(:api_key) || Bnet.configuration.api_key
|
53
|
+
|
54
|
+
base_api = Bnet::Starcraft2.new(region: region)
|
55
|
+
call_url = base_api.url + "profile/#{profile_id}/#{realm}/#{name}/?locale=#{locale}&apikey=#{api_key}"
|
56
|
+
|
57
|
+
begin
|
58
|
+
data = open(call_url)
|
59
|
+
raw_response = JSON.parse(data.read)
|
60
|
+
|
61
|
+
if Bnet::API.valid_call?(data.status, raw_response)
|
62
|
+
bnet_object = from_api(raw_response)
|
63
|
+
else
|
64
|
+
bnet_object = nil
|
65
|
+
end
|
66
|
+
|
67
|
+
rescue OpenURI::HTTPError => e
|
68
|
+
bnet_object = nil
|
69
|
+
end
|
70
|
+
|
71
|
+
return bnet_object
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
def career
|
76
|
+
@career ||= []
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.from_api(response)
|
80
|
+
bnet_resource = super(response)
|
81
|
+
if bnet_resource && response["achievements"]
|
82
|
+
bnet_resource.achievement_points = response["achievements"]["points"]["totalPoints"]
|
83
|
+
end
|
84
|
+
|
85
|
+
if bnet_resource && response["swarmLevels"]
|
86
|
+
bnet_resource.swarm_level = response["swarmLevels"]["level"]
|
87
|
+
bnet_resource.terran_level = response["swarmLevels"]["terran"]["level"]
|
88
|
+
bnet_resource.protoss_level = response["swarmLevels"]["protoss"]["level"]
|
89
|
+
bnet_resource.zerg_level = response["swarmLevels"]["zerg"]["level"]
|
90
|
+
end
|
91
|
+
|
92
|
+
bnet_resource
|
93
|
+
end
|
94
|
+
end
|
data/lib/bnet/version.rb
ADDED
data/lib/bnet/wow.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
class Bnet::WOW::Character < Bnet::BnetResource
|
2
|
+
|
3
|
+
attr_accessor :name, :realm, :battlegroup, :class, :race, :gender, :level,
|
4
|
+
:achievement_points, :total_honorable_kills, :calc_class
|
5
|
+
|
6
|
+
# Query Battlenet API for the character profile
|
7
|
+
#
|
8
|
+
# Hash Params:
|
9
|
+
# Required
|
10
|
+
# :region - (e.g. 'us', 'ea')
|
11
|
+
# :name - String name of the toon
|
12
|
+
# :realm - String name of the server the character is on (String)
|
13
|
+
# Optional
|
14
|
+
# :locale - String locale (defaults to 'en_US')
|
15
|
+
# :api_key - String api key
|
16
|
+
#
|
17
|
+
# Example : IF a character named 'AlexeiStukov' is on 'DragonMaw' 'US' server
|
18
|
+
#
|
19
|
+
# Bnet::WOW::Character.find(region: 'us', name: 'AlexeiStukov', realm: 'Dragonmaw')
|
20
|
+
#
|
21
|
+
# Returns a Character with the following attributes
|
22
|
+
#
|
23
|
+
# :name, :realm, :battlegroup, :class, :race, :gender, :level,
|
24
|
+
# :achievement_points, :total_honorable_kills, :calc_class
|
25
|
+
def self.find args
|
26
|
+
region = args.delete(:region)
|
27
|
+
realm = args.delete(:realm)
|
28
|
+
name = args.delete(:name)
|
29
|
+
locale = args.delete(:locale) || 'en_US'
|
30
|
+
api_key = args.delete(:api_key) || Bnet.configuration.api_key
|
31
|
+
|
32
|
+
base_api = Bnet::WOW.new(region: region)
|
33
|
+
call_url = base_api.url + "character/#{realm}/#{name}?locale=#{locale}&apikey=#{api_key}"
|
34
|
+
|
35
|
+
begin
|
36
|
+
data = open(call_url)
|
37
|
+
raw_response = JSON.parse(data.read)
|
38
|
+
|
39
|
+
if data.status == ['200', 'OK'] && raw_response["code"] != 'NOTFOUND'
|
40
|
+
bnet_object = from_api(raw_response)
|
41
|
+
else
|
42
|
+
bnet_object = nil
|
43
|
+
end
|
44
|
+
|
45
|
+
rescue OpenURI::HTTPError => e
|
46
|
+
bnet_object = nil
|
47
|
+
end
|
48
|
+
|
49
|
+
return bnet_object
|
50
|
+
end
|
51
|
+
|
52
|
+
def gender
|
53
|
+
case @gender
|
54
|
+
when 0
|
55
|
+
'Female'
|
56
|
+
when 1
|
57
|
+
'Male'
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def self.params_mapping
|
64
|
+
{
|
65
|
+
"name" => :name,
|
66
|
+
"realm" => :realm,
|
67
|
+
"battlegroup" => :battlegroup,
|
68
|
+
"class" => :class,
|
69
|
+
"race" => :race,
|
70
|
+
"gender" => :gender,
|
71
|
+
"level" => :level,
|
72
|
+
"achievement_points" => :achievement_points,
|
73
|
+
"calc_class" => :calc_class,
|
74
|
+
"total_honorable_kills" => :total_honorable_kills
|
75
|
+
}
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
class Bnet::WOW::Data::Base < Bnet::BnetResource
|
2
|
+
# Query Battlenet API for the the data based on the subclass's scope
|
3
|
+
#
|
4
|
+
# Hash Params:
|
5
|
+
# :region - (e.g. 'us', 'ea')
|
6
|
+
# :name - String name of the toon
|
7
|
+
# :realm - String name of the server the character is on (String)
|
8
|
+
# :locale - String locale (defaults to 'en_US')
|
9
|
+
# :api_key - String api key
|
10
|
+
#
|
11
|
+
# Example : If a character named 'AlexeiStukov' is on 'DragonMaw' 'US' server
|
12
|
+
def self.find_all(args)
|
13
|
+
region = args.delete(:region)
|
14
|
+
api_key = args.delete(:api_key) || Bnet::configuration.api_key
|
15
|
+
locale = args.delete(:locale) || 'en_US'
|
16
|
+
|
17
|
+
base_api = Bnet::WOW.new(region: region)
|
18
|
+
call_url = base_api.url + 'data/' + scopes[:url] + "?locale=#{locale}&apikey=#{api_key}"
|
19
|
+
|
20
|
+
begin
|
21
|
+
data = open(call_url)
|
22
|
+
raw_response = JSON.parse(data.read)
|
23
|
+
|
24
|
+
if Bnet::API.valid_call?(data.status, raw_response)
|
25
|
+
collection = collection_from_api(raw_response)
|
26
|
+
else
|
27
|
+
collection = []
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
rescue OpenURI::HTTPError => e
|
32
|
+
collection = []
|
33
|
+
end
|
34
|
+
|
35
|
+
return collection
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def self.collection_from_api(response_collection)
|
41
|
+
response_collection[scopes[:collection_root]].collect do |attrs|
|
42
|
+
from_api(attrs)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.url(collection_scope)
|
47
|
+
"#{Bnet::WOW.url}/data/#{collection_scope}"
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.scopes
|
51
|
+
self::SCOPES
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class Bnet::WOW::Data::Battlegroup < Bnet::WOW::Data::Base
|
2
|
+
attr :name, :slug
|
3
|
+
|
4
|
+
SCOPES = {
|
5
|
+
url: 'battlegroups/',
|
6
|
+
collection_root: 'battlegroups'
|
7
|
+
}
|
8
|
+
|
9
|
+
PARAMS_MAPPING = { "name" => :name, "slug" => :slug }
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def self.scopes
|
14
|
+
self::SCOPES
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class Bnet::WOW::Data::CharacterRace < Bnet::WOW::Data::Base
|
2
|
+
|
3
|
+
attr :race_id, :mask, :side, :name
|
4
|
+
|
5
|
+
SCOPES = {
|
6
|
+
url: 'character/races',
|
7
|
+
collection_root: 'races'
|
8
|
+
}
|
9
|
+
|
10
|
+
PARAMS_MAPPING = {
|
11
|
+
"id" => :race_id, "mask" => :mask,
|
12
|
+
"side" => :side, "name" => :name
|
13
|
+
}
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Bnet::API do
|
4
|
+
let(:instance) do
|
5
|
+
described_class.new(region: "eu")
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "initialization" do
|
9
|
+
it "can be initialized" do
|
10
|
+
expect(instance).to be_a_kind_of(described_class)
|
11
|
+
expect(instance.region).to eq("eu")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#url" do
|
16
|
+
it "returns the base url by region" do
|
17
|
+
expect(instance.url).to eq("https://eu.api.battle.net/")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Bnet::Diablo3::Career do
|
4
|
+
|
5
|
+
describe ".from_api" do
|
6
|
+
let(:attrs){
|
7
|
+
{
|
8
|
+
"heroes" => [], "lastheroplayed" => 'val', "lastupdated" => 'val',
|
9
|
+
"kills" => 'val', "timeplayed" => 'val', "fallenheroes" => 'val',
|
10
|
+
"paragonlevel" => 'val', "paragonlevelhardcore" => 'val',
|
11
|
+
"battletag" => 'val', "progression" => 'val'
|
12
|
+
}
|
13
|
+
}
|
14
|
+
subject{ described_class.from_api(attrs)}
|
15
|
+
it "is initialized" do
|
16
|
+
expect(subject).to be_a_kind_of(described_class)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe ".find(battle_tag: 'PlayerOne#1309', region: 'us')" do
|
21
|
+
subject(:career) { described_class.find(args) }
|
22
|
+
|
23
|
+
context "Playertag for the server exists" ,vcr: { cassette_name: 'find_diablo_career_player_one '} do
|
24
|
+
let(:args) do
|
25
|
+
{ battle_tag: 'PlayerOne#1309', region: 'us' }
|
26
|
+
end
|
27
|
+
it { is_expected.to_not be_nil }
|
28
|
+
|
29
|
+
it "sets account attributes that are of the json response" do
|
30
|
+
expect(career.battle_tag).to eq('PlayerOne#1309')
|
31
|
+
expect(career.region).to eq('us')
|
32
|
+
end
|
33
|
+
|
34
|
+
it "assigns autoloads the heroes" do
|
35
|
+
expect(career.heroes).to_not be_empty
|
36
|
+
|
37
|
+
career.heroes.each do |hero|
|
38
|
+
expect(hero).to be_a_kind_of(Bnet::Diablo3::Hero)
|
39
|
+
expect(hero.battle_tag).to eq('PlayerOne#1309')
|
40
|
+
expect(hero.region).to eq(career.region)
|
41
|
+
expect(hero.career).to be(career)
|
42
|
+
expect(hero.passive_skills).to_not be_empty
|
43
|
+
expect(hero.active_skills).to_not be_empty
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "Playertag for the server does not exist", vcr: { cassette_name: 'find_diablo_career_doesnt_exist'} do
|
50
|
+
let(:args) do
|
51
|
+
{ battle_tag: 'DoesntExist-42', region: 'us' }
|
52
|
+
end
|
53
|
+
it { is_expected.to be_nil }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Bnet::Diablo3::Hero do
|
4
|
+
|
5
|
+
describe ".find(battle_tag: 'PlayerOne-1309', region: 'us', hero_id: 1304986)" do
|
6
|
+
subject {described_class.find(args)}
|
7
|
+
|
8
|
+
context "Given the correct battle tag and hero id", vcr: {cassette_name: 'diablo_hero_found'} do
|
9
|
+
let(:args) do
|
10
|
+
{
|
11
|
+
battle_tag: 'PlayerOne-1309',
|
12
|
+
region: 'us',
|
13
|
+
hero_id: 1304986
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
it "Instantiates a hero " do
|
18
|
+
is_expected.to be_a_kind_of(described_class)
|
19
|
+
expect(subject.name).to eq('PlayerOne')
|
20
|
+
expect(subject.hero_class).to eq('wizard')
|
21
|
+
end
|
22
|
+
|
23
|
+
it "assigns skills" do
|
24
|
+
expect(subject.active_skills.map(&:name)).
|
25
|
+
to match_array([ "Magic Missile", "Arcane Orb",
|
26
|
+
"Hydra", "Familiar", "Magic Weapon",
|
27
|
+
"Teleport" ])
|
28
|
+
|
29
|
+
expect(subject.active_skills.map(&:rune)).
|
30
|
+
to match_array([ "Seeker", "Frozen Orb", "Frost Hydra", "Sparkflint",
|
31
|
+
"Force Weapon", "Fracture"])
|
32
|
+
|
33
|
+
expect(subject.passive_skills.map(&:name)).
|
34
|
+
to match_array([ "Elemental Exposure", "Prodigy", "Astral Presence",
|
35
|
+
"Cold Blooded" ])
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
context "Given the hero does not exist on that tag/realm", vcr: {cassette_name: 'diablo_hero_notf_found'} do
|
41
|
+
let(:args) do
|
42
|
+
{
|
43
|
+
battle_tag: 'DOESNTEXIST-666',
|
44
|
+
region: 'us',
|
45
|
+
hero_id: 666
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
it { is_expected.to be_nil }
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
describe ".from_api" do
|
55
|
+
|
56
|
+
context "Given the right parameters" do
|
57
|
+
let(:api_args) do
|
58
|
+
{ "paragonLevel" => 0, "seasonal" => false, "name" => "PlayerOne",
|
59
|
+
"id" => 1304986, "level" => 70, "hardcore" => false, "gender" => 0,
|
60
|
+
"dead" => false, "class" => "wizard", "last-updated" => 1397322512
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
subject { described_class.from_api(api_args) }
|
65
|
+
|
66
|
+
it "can be initialized" do
|
67
|
+
is_expected.to_not be_nil
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
describe "#reload" do
|
75
|
+
context "Hero since last update was level 69", vcr: {cassette_name: 'diablo_hero_reload'} do
|
76
|
+
let(:hero) do
|
77
|
+
described_class.new(battle_tag: 'PlayerOne#1309',region: 'us', hero_id: 1304986, level: 69)
|
78
|
+
end
|
79
|
+
it "Fetches update from the API and update the object" do
|
80
|
+
expect{hero.reload}.to change{hero.level}.from(69).to(70)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe '#career' do
|
86
|
+
it "returns a career object"
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|