bnet 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.gitignore +16 -0
  4. data/.travis.yml +15 -0
  5. data/Gemfile +4 -0
  6. data/Guardfile +13 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +120 -0
  9. data/Rakefile +14 -0
  10. data/TODO.md +74 -0
  11. data/bnet.gemspec +34 -0
  12. data/fixtures/cassettes/diablo_hero_found.yml +1023 -0
  13. data/fixtures/cassettes/diablo_hero_notf_found.yml +48 -0
  14. data/fixtures/cassettes/diablo_hero_reload.yml +1023 -0
  15. data/fixtures/cassettes/find_diablo_career_doesnt_exist.yml +93 -0
  16. data/fixtures/cassettes/find_diablo_career_player_one_.yml +2803 -0
  17. data/fixtures/cassettes/sc2_profile_found.yml +523 -0
  18. data/fixtures/cassettes/sc2_profile_not_found.yml +49 -0
  19. data/fixtures/cassettes/wow_character_found.yml +46 -0
  20. data/fixtures/cassettes/wow_character_not_found.yml +42 -0
  21. data/fixtures/cassettes/wow_data_battlegroups_all.yml +45 -0
  22. data/fixtures/cassettes/wow_data_character_races_all.yml +45 -0
  23. data/lib/bnet.rb +34 -0
  24. data/lib/bnet/account.rb +4 -0
  25. data/lib/bnet/api.rb +21 -0
  26. data/lib/bnet/bnet_resource.rb +25 -0
  27. data/lib/bnet/client.rb +6 -0
  28. data/lib/bnet/configuration.rb +7 -0
  29. data/lib/bnet/diablo3.rb +11 -0
  30. data/lib/bnet/diablo3/career.rb +91 -0
  31. data/lib/bnet/diablo3/hero.rb +131 -0
  32. data/lib/bnet/diablo3/skill.rb +19 -0
  33. data/lib/bnet/starcraft2.rb +7 -0
  34. data/lib/bnet/starcraft2/profile.rb +94 -0
  35. data/lib/bnet/version.rb +3 -0
  36. data/lib/bnet/wow.rb +7 -0
  37. data/lib/bnet/wow/character.rb +78 -0
  38. data/lib/bnet/wow/data.rb +5 -0
  39. data/lib/bnet/wow/data/base.rb +54 -0
  40. data/lib/bnet/wow/data/battlegroup.rb +18 -0
  41. data/lib/bnet/wow/data/character_race.rb +15 -0
  42. data/spec/bnet/account_spec.rb +5 -0
  43. data/spec/bnet/api_spec.rb +20 -0
  44. data/spec/bnet/diablo3/career_spec.rb +57 -0
  45. data/spec/bnet/diablo3/hero_spec.rb +89 -0
  46. data/spec/bnet/diablo3/skill_spec.rb +26 -0
  47. data/spec/bnet/diablo3_spec.rb +19 -0
  48. data/spec/bnet/starcraft2/profile_spec.rb +53 -0
  49. data/spec/bnet/wow/character_spec.rb +57 -0
  50. data/spec/bnet/wow/data/base_spec.rb +9 -0
  51. data/spec/bnet/wow/data/battlegroup_spec.rb +17 -0
  52. data/spec/bnet/wow/data/character_race_spec.rb +19 -0
  53. data/spec/bnet/wow/data_spec.rb +21 -0
  54. data/spec/bnet_spec.rb +8 -0
  55. data/spec/secrets_and_all_that.rb.sample +8 -0
  56. data/spec/secrets_and_all_that.rb.travis +8 -0
  57. data/spec/spec_helper.rb +29 -0
  58. 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,7 @@
1
+ module Bnet
2
+ class Starcraft2 < Bnet::API
3
+ def url
4
+ super + "sc2/"
5
+ end
6
+ end
7
+ 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
@@ -0,0 +1,3 @@
1
+ module Bnet
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,7 @@
1
+ module Bnet
2
+ class WOW < Bnet::API
3
+ def url
4
+ super + "wow/"
5
+ end
6
+ end
7
+ end
@@ -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,5 @@
1
+ module Bnet::WOW::Data
2
+ autoload :Base, 'bnet/wow/data/base'
3
+ autoload :Battlegroup, 'bnet/wow/data/battlegroup'
4
+ autoload :CharacterRace, 'bnet/wow/data/character_race'
5
+ 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,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe Bnet::Account do
4
+
5
+ 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