quakelive_api 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.travis.yml +3 -2
  4. data/CHANGELOG.md +11 -0
  5. data/README.md +6 -2
  6. data/lib/quakelive_api/base.rb +23 -23
  7. data/lib/quakelive_api/game_time.rb +5 -5
  8. data/lib/quakelive_api/parser/awards.rb +21 -21
  9. data/lib/quakelive_api/parser/base.rb +1 -1
  10. data/lib/quakelive_api/parser/statistics.rb +17 -17
  11. data/lib/quakelive_api/parser/summary.rb +25 -24
  12. data/lib/quakelive_api/profile/awards/base.rb +10 -10
  13. data/lib/quakelive_api/profile/awards/career_milestones.rb +1 -1
  14. data/lib/quakelive_api/profile/awards/experience.rb +1 -1
  15. data/lib/quakelive_api/profile/awards/mad_skillz.rb +1 -1
  16. data/lib/quakelive_api/profile/awards/social_life.rb +4 -5
  17. data/lib/quakelive_api/profile/awards/sweet_success.rb +1 -1
  18. data/lib/quakelive_api/profile/statistics.rb +7 -7
  19. data/lib/quakelive_api/profile/summary.rb +21 -21
  20. data/lib/quakelive_api/version.rb +1 -1
  21. data/quakelive_api.gemspec +7 -6
  22. data/test/fixtures/awards/career_milestones.yml +262 -0
  23. data/test/fixtures/awards/experience.yml +1019 -0
  24. data/test/fixtures/profiles/emqz.yml +331 -0
  25. data/test/fixtures/profiles/error.yml +53 -0
  26. data/test/fixtures/profiles/full/awards_experience.yml +1019 -0
  27. data/test/fixtures/profiles/full/awards_milestones.yml +262 -0
  28. data/test/fixtures/profiles/full/awards_skillz.yml +592 -0
  29. data/test/fixtures/profiles/full/awards_social.yml +163 -0
  30. data/test/fixtures/profiles/full/awards_success.yml +449 -0
  31. data/test/fixtures/profiles/full/statistics.yml +438 -0
  32. data/test/fixtures/profiles/full/summary.yml +331 -0
  33. data/test/fixtures/profiles/mariano.yml +329 -0
  34. data/test/fixtures/profiles/not_existing.yml +57 -0
  35. data/test/fixtures/statistics/xsi.yml +438 -0
  36. data/test/quakelive_api/profile/awards/career_milestones_test.rb +8 -9
  37. data/test/quakelive_api/profile/awards/experience_test.rb +6 -7
  38. data/test/quakelive_api/profile/statistics_test.rb +31 -37
  39. data/test/quakelive_api/profile/summary_test.rb +60 -51
  40. data/test/quakelive_api/profile_test.rb +37 -32
  41. data/test/test_helper.rb +10 -30
  42. metadata +71 -72
  43. data/test/fixtures/awards/career.txt +0 -382
  44. data/test/fixtures/awards/experience.txt +0 -769
  45. data/test/fixtures/awards/mad_skillz.txt +0 -915
  46. data/test/fixtures/awards/social_life.txt +0 -155
  47. data/test/fixtures/awards/sweet_success.txt +0 -684
  48. data/test/fixtures/profile/error.txt +0 -24
  49. data/test/fixtures/profile/not_found.txt +0 -36
  50. data/test/fixtures/profile/summary.txt +0 -383
  51. data/test/fixtures/statistics/emqz.txt +0 -431
  52. data/test/fixtures/statistics/xsi.txt +0 -558
  53. data/test/fixtures/summary/emqz.txt +0 -304
  54. data/test/fixtures/summary/mariano.txt +0 -380
  55. data/test/quakelive_api/profile/awards/mad_skillz_test.rb +0 -38
  56. data/test/quakelive_api/profile/awards/social_life_test.rb +0 -38
  57. data/test/quakelive_api/profile/awards/sweet_success_test.rb +0 -38
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 709a918a29beb2d88f7beb75da2c7f6096adc835
4
+ data.tar.gz: d4a6265dead1d076be6ae38443f2c089c99a41ed
5
+ SHA512:
6
+ metadata.gz: e9840762fc084ddc77e0073bc7ec2bc45c2766e8e22f56bed4aee3b3e9b4399aeefc9879d01a02ee65e9ae97bd55b2e9becdeaca5b1b3b11567fbbc93ec5f531
7
+ data.tar.gz: aa5dee7c81d9251820f6b8b0fa8a54f5fc314d15aeeec57527e52c3529da9264c63a7310673c195e71849d100f916a84a06265445b8385cc967e214209588c3a
data/.gitignore CHANGED
@@ -19,3 +19,4 @@ tmp
19
19
  .rvmrc
20
20
  .ruby-gemset
21
21
  coverage/
22
+ vendor/
data/.travis.yml CHANGED
@@ -1,9 +1,10 @@
1
1
  language: ruby
2
2
 
3
3
  rvm:
4
- - 1.9.2
5
4
  - 1.9.3
6
- - 2.0.0
5
+ - 2.0
6
+ - 2.1
7
+ - ruby-head
7
8
 
8
9
  notifications:
9
10
  email: false
data/CHANGELOG.md ADDED
@@ -0,0 +1,11 @@
1
+ ## 0.1.0
2
+ _no breaking changes_
3
+
4
+ - removed duplicated tests, utilized to VCR
5
+ - updated some profile summary selectors (related to QL redesign)
6
+ - Ruby 1.9 hash syntax
7
+ - cosmetic code fixes
8
+
9
+ ## 0.0.1
10
+
11
+ - Initial release
data/README.md CHANGED
@@ -1,7 +1,11 @@
1
- [![Code Climate](https://codeclimate.com/github/emq/quakelive_api.png)](https://codeclimate.com/github/emq/quakelive_api) [![Build Status](https://travis-ci.org/emq/quakelive_api.png?branch=master)](https://travis-ci.org/emq/quakelive_api)
2
-
3
1
  # QuakeliveApi
4
2
 
3
+ [![Code Climate](https://codeclimate.com/github/emq/quakelive_api.png)](https://codeclimate.com/github/emq/quakelive_api)
4
+ [![Build Status](https://travis-ci.org/emq/quakelive_api.png?branch=master)](https://travis-ci.org/emq/quakelive_api)
5
+ [![Coverage Status](https://coveralls.io/repos/emq/quakelive_api/badge.png)](https://coveralls.io/r/emq/quakelive_api)
6
+ [![Dependency Status](https://gemnasium.com/emq/quakelive_api.png)](https://gemnasium.com/emq/quakelive_api)
7
+ [![Gem Version](https://badge.fury.io/rb/quakelive_api.png)](http://badge.fury.io/rb/quakelive_api)
8
+
5
9
  This gem fetches (basic) publicly available data from [QuakeLive site][1]. Unfortunately currently there is no real API provided by ID so we're forced to parse html to get what we can. It will go down in flames if QL changes its internal html structure, so be prepared for that too.
6
10
 
7
11
  The dirty job is made under `Parser` module (nothing pretty there, but response from QL is not pretty as well).
@@ -18,35 +18,35 @@ module QuakeliveApi
18
18
 
19
19
  private
20
20
 
21
- def get
22
- Net::HTTP.get(URI.parse(URI::encode("#{QuakeliveApi.site}#{url}")))
23
- end
21
+ def get
22
+ Net::HTTP.get(URI.parse(URI::encode("#{QuakeliveApi.site}#{url}")))
23
+ end
24
24
 
25
- def url
26
- raise NotImplementedError
27
- end
25
+ def url
26
+ raise NotImplementedError
27
+ end
28
28
 
29
- def parser
30
- @parser
31
- end
29
+ def parser
30
+ @parser
31
+ end
32
32
 
33
- def set_parser(document)
34
- @parser ||= ::QuakeliveApi::Parser.const_get(self.class.class_name).new(document)
35
- end
33
+ def set_parser(document)
34
+ @parser ||= ::QuakeliveApi::Parser.const_get(self.class.class_name).new(document)
35
+ end
36
36
 
37
- def self.class_name
38
- name.split('::').last
39
- end
37
+ def self.class_name
38
+ name.split('::').last
39
+ end
40
40
 
41
- def setup_variables!
42
- raise Error::PlayerNotFound if parser.invalid_player?
43
- raise Error::RequestError if parser.request_error?
41
+ def setup_variables!
42
+ raise Error::PlayerNotFound if parser.invalid_player?
43
+ raise Error::RequestError if parser.request_error?
44
44
 
45
- setup_variables
46
- end
45
+ setup_variables
46
+ end
47
47
 
48
- def setup_variables
49
- raise NotImplementedError
50
- end
48
+ def setup_variables
49
+ raise NotImplementedError
50
+ end
51
51
  end
52
52
  end
@@ -25,10 +25,10 @@ module QuakeliveApi
25
25
 
26
26
  private
27
27
 
28
- def reverse_match(string)
29
- attrs = string.split(/\.|:/).reverse.map { |a| a.to_i }
30
- (4 - attrs.size).times { attrs << 0 }
31
- Interval.new(*attrs)
32
- end
28
+ def reverse_match(string)
29
+ attrs = string.split(/\.|:/).reverse.map { |a| a.to_i }
30
+ (4 - attrs.size).times { attrs << 0 }
31
+ Interval.new(*attrs)
32
+ end
33
33
  end
34
34
  end
@@ -15,30 +15,30 @@ module QuakeliveApi
15
15
 
16
16
  private
17
17
 
18
- def selectors
19
- {
20
- :earned => ".detailArea",
21
- :unearned => ".detailArea_off"
22
- }
23
- end
18
+ def selectors
19
+ {
20
+ earned: ".detailArea",
21
+ unearned: ".detailArea_off"
22
+ }
23
+ end
24
24
 
25
- def parse_node(node)
26
- attrs = {
27
- :icon => node.at('img')['src'],
28
- :info => node.at('img')['title'],
29
- :name => node.at('span.bigRedTxt').content,
30
- :description => node.at('span.blktxt_11').content,
31
- :awarded => awarded_at(node)
32
- }
33
- Items::Award.new(attrs)
34
- end
25
+ def parse_node(node)
26
+ attrs = {
27
+ icon: node.at('img')['src'],
28
+ info: node.at('img')['title'],
29
+ name: node.at('span.bigRedTxt').content,
30
+ description: node.at('span.blktxt_11').content,
31
+ awarded: awarded_at(node)
32
+ }
33
+ Items::Award.new(attrs)
34
+ end
35
35
 
36
- def awarded_at(node)
37
- return unless node.css('ul.fl li').count >= 3
36
+ def awarded_at(node)
37
+ return unless node.css('ul.fl li').count >= 3
38
38
 
39
- matches = node.at('ul.fl li:first-child').content.match(/(\d{2})\/(\d{2})\/(\d{4})/)
40
- Date.new(matches[3].to_i, matches[1].to_i, matches[2].to_i) unless matches.nil?
41
- end
39
+ matches = node.at('ul.fl li:first-child').content.match(/(\d{2})\/(\d{2})\/(\d{4})/)
40
+ Date.new(matches[3].to_i, matches[1].to_i, matches[2].to_i) unless matches.nil?
41
+ end
42
42
  end
43
43
 
44
44
  class CareerMilestones < Awards; end
@@ -6,7 +6,7 @@ module QuakeliveApi
6
6
  end
7
7
 
8
8
  def invalid_player?
9
- document.css('.prf_header span').text =~ /Player not found/
9
+ document.css('.profile_title').text =~ /Unknown Player/
10
10
  end
11
11
 
12
12
  def request_error?
@@ -5,14 +5,14 @@ module QuakeliveApi
5
5
  def weapons
6
6
  document.css(selector(:weapon)).each_with_index.map do |node, idx|
7
7
  attrs = {
8
- :name => node.text,
9
- :frags => frags(weapon_next(:frags, idx)),
10
- :accuracy => accuracy(weapon_next(:accuracy, idx)),
11
- :usage => usage(weapon_next(:usage, idx))
8
+ name: node.text,
9
+ frags: frags(weapon_next(:frags, idx)),
10
+ accuracy: accuracy(weapon_next(:accuracy, idx)),
11
+ usage: usage(weapon_next(:usage, idx))
12
12
  }
13
13
 
14
14
  hits, shots = hits_shots(weapon_next(:accuracy, idx))
15
- attrs.merge!(:hits => hits, :shots => shots)
15
+ attrs.merge!(hits: hits, shots: shots)
16
16
 
17
17
  Items::Weapon.new(attrs)
18
18
  end
@@ -26,13 +26,13 @@ module QuakeliveApi
26
26
  next if no_records?
27
27
 
28
28
  attrs = {
29
- :title => node.at('.col_st_gametype').text.strip,
30
- :played => to_integer(node.at('.col_st_played').text),
31
- :finished => to_integer(node.at('.col_st_finished').text),
32
- :wins => to_integer(node.at('.col_st_wins').text),
33
- :quits => to_integer(node.at('.col_st_withdraws').text),
34
- :completed => to_integer(node.at('.col_st_completeperc').text.gsub('%','')),
35
- :wins_percentage => to_integer(node.at('.col_st_winperc').text.gsub('%',''))
29
+ title: node.at('.col_st_gametype').text.strip,
30
+ played: to_integer(node.at('.col_st_played').text),
31
+ finished: to_integer(node.at('.col_st_finished').text),
32
+ wins: to_integer(node.at('.col_st_wins').text),
33
+ quits: to_integer(node.at('.col_st_withdraws').text),
34
+ completed: to_integer(node.at('.col_st_completeperc').text.gsub('%','')),
35
+ wins_percentage: to_integer(node.at('.col_st_winperc').text.gsub('%',''))
36
36
  }
37
37
  Items::Record.new(attrs)
38
38
  end
@@ -42,11 +42,11 @@ module QuakeliveApi
42
42
 
43
43
  def selectors
44
44
  {
45
- :weapon => ".prf_weapons .col_weapon",
46
- :frags => ".col_frags",
47
- :accuracy => ".col_accuracy",
48
- :usage => ".col_usage",
49
- :record => ".qlv_profile_section_statistics .prf_record > div"
45
+ weapon: ".prf_weapons .col_weapon",
46
+ frags: ".col_frags",
47
+ accuracy: ".col_accuracy",
48
+ usage: ".col_usage",
49
+ record: ".qlv_profile_section_statistics .prf_record > div"
50
50
  }
51
51
  end
52
52
 
@@ -7,11 +7,12 @@ module QuakeliveApi
7
7
  end
8
8
 
9
9
  def nick
10
- document.at(selector(:nick)).text
10
+ document.at(selector(:nick)).xpath('text()').text.strip
11
11
  end
12
12
 
13
13
  def clan
14
- (c = document.at(selector(:clan))) ? c.text : nil
14
+ clan_tag = document.at(selector(:clan))
15
+ clan_tag.text if clan_tag
15
16
  end
16
17
 
17
18
  def model
@@ -27,12 +28,12 @@ module QuakeliveApi
27
28
 
28
29
  def last_game
29
30
  node = vitals.at selector(:last)
30
- node ? decode_time(node['title']) : nil
31
+ decode_time(node['title']) if node
31
32
  end
32
33
 
33
34
  def time_played
34
35
  node = vitals.at selector(:played)
35
- node ? GameTime.new(node['title']) : nil
36
+ GameTime.new(node['title']) if node
36
37
  end
37
38
 
38
39
  def wins
@@ -88,7 +89,7 @@ module QuakeliveApi
88
89
  Items::RecentGame.new(gametype, finish, played, image)
89
90
  end.compact
90
91
 
91
- games.any? ? games : nil
92
+ games if games.any?
92
93
  end
93
94
 
94
95
  def recent_competitors
@@ -96,36 +97,36 @@ module QuakeliveApi
96
97
  next if node.at('.rcmp_none')
97
98
 
98
99
  icon = decode_background node.at('.usericon_standard_lg')['style']
99
- nick = node.at('a.player_nick_dark').text
100
+ nick = node.at('a.player_nick_dark').xpath('child::text()').to_s
100
101
  played = decode_time(node.at('span.text_tooltip')['title'])
101
102
 
102
103
  Items::Competitor.new(icon, nick, played )
103
104
  end.compact
104
105
 
105
- competitors.any? ? competitors : nil
106
+ competitors if competitors.any?
106
107
  end
107
108
 
108
109
  private
109
110
 
110
111
  def selectors
111
112
  {
112
- :country => ".playername img",
113
- :nick => "#prf_player_name",
114
- :clan => ".playername a.clan",
115
- :model => ".prf_imagery div",
116
- :vitals => ".prf_vitals p",
117
- :member => "b:contains('Member Since')",
118
- :last => "b:contains('Last Game') + span",
119
- :played => "b:contains('Time Played') + span",
120
- :wins => "b:contains('Wins')",
121
- :losses => "b:contains('Losses')",
122
- :frags => "b:contains('Frags')",
123
- :hits => "b:contains('Hits')",
124
- :accuracy => "b:contains('Accuracy')",
125
- :favs => ".prf_faves b",
126
- :awards => ".prf_awards .awd_details",
127
- :games => ".recent_match",
128
- :competitors => "#qlv_profileBottomInset .rcmp_block"
113
+ country: "img.playerflag",
114
+ nick: ".profile_title",
115
+ clan: ".profile_title a.clan",
116
+ model: ".prf_imagery div",
117
+ vitals: ".prf_vitals p",
118
+ member: "b:contains('Member Since')",
119
+ last: "b:contains('Last Game') + span",
120
+ played: "b:contains('Time Played') + span",
121
+ wins: "b:contains('Wins')",
122
+ losses: "b:contains('Losses')",
123
+ frags: "b:contains('Frags')",
124
+ hits: "b:contains('Hits')",
125
+ accuracy: "b:contains('Accuracy')",
126
+ favs: ".prf_faves b",
127
+ awards: ".prf_awards .awd_details",
128
+ games: ".recent_match",
129
+ competitors: "#qlv_profileBottomInset .rcmp_block"
129
130
  }
130
131
  end
131
132
 
@@ -6,18 +6,18 @@ module QuakeliveApi
6
6
 
7
7
  private
8
8
 
9
- def page
10
- raise NotImplementedError
11
- end
9
+ def page
10
+ raise NotImplementedError
11
+ end
12
12
 
13
- def url
14
- "/profile/awards/#{player_name}/#{page}"
15
- end
13
+ def url
14
+ "/profile/awards/#{player_name}/#{page}"
15
+ end
16
16
 
17
- def setup_variables
18
- @earned = parser.earned
19
- @unearned = parser.unearned
20
- end
17
+ def setup_variables
18
+ @earned = parser.earned
19
+ @unearned = parser.unearned
20
+ end
21
21
  end
22
22
  end
23
23
  end
@@ -3,7 +3,7 @@ module QuakeliveApi
3
3
  module Awards
4
4
  class CareerMilestones < Base # 18 awards
5
5
 
6
- private
6
+ private
7
7
 
8
8
  def page
9
9
  3
@@ -3,7 +3,7 @@ module QuakeliveApi
3
3
  module Awards
4
4
  class Experience < Base # 36 awards
5
5
 
6
- private
6
+ private
7
7
 
8
8
  def page
9
9
  1
@@ -3,7 +3,7 @@ module QuakeliveApi
3
3
  module Awards
4
4
  class MadSkillz < Base # 43 awards
5
5
 
6
- private
6
+ private
7
7
 
8
8
  def page
9
9
  2
@@ -3,12 +3,11 @@ module QuakeliveApi
3
3
  module Awards
4
4
  class SocialLife < Base # 6 awards
5
5
 
6
- private
7
-
8
- def page
9
- 5
10
- end
6
+ private
11
7
 
8
+ def page
9
+ 5
10
+ end
12
11
  end
13
12
  end
14
13
  end
@@ -3,7 +3,7 @@ module QuakeliveApi
3
3
  module Awards
4
4
  class SweetSuccess < Base # 32 awards
5
5
 
6
- private
6
+ private
7
7
 
8
8
  def page
9
9
  4
@@ -5,14 +5,14 @@ module QuakeliveApi
5
5
 
6
6
  private
7
7
 
8
- def url
9
- "/profile/statistics/#{player_name}"
10
- end
8
+ def url
9
+ "/profile/statistics/#{player_name}"
10
+ end
11
11
 
12
- def setup_variables
13
- @weapons = parser.weapons
14
- @records = parser.records
15
- end
12
+ def setup_variables
13
+ @weapons = parser.weapons
14
+ @records = parser.records
15
+ end
16
16
  end
17
17
  end
18
18
  end
@@ -8,28 +8,28 @@ module QuakeliveApi
8
8
 
9
9
  private
10
10
 
11
- def url
12
- "/profile/summary/#{player_name}"
13
- end
11
+ def url
12
+ "/profile/summary/#{player_name}"
13
+ end
14
14
 
15
- def setup_variables
16
- @country = parser.country
17
- @nick = parser.nick
18
- @clan = parser.clan
19
- @model = parser.model
20
- @member_since = parser.member_since
21
- @last_game = parser.last_game
22
- @time_played = parser.time_played
23
- @wins = parser.wins
24
- @accuracy = parser.accuracy
25
- @losses, @quits = parser.losses_quits
26
- @frags, @deaths = parser.frags_deaths
27
- @hits, @shots = parser.hits_shots
28
- @favourite = parser.favourites
29
- @recent_awards = parser.awards
30
- @recent_games = parser.recent_games
31
- @recent_competitors = parser.recent_competitors
32
- end
15
+ def setup_variables
16
+ @country = parser.country
17
+ @nick = parser.nick
18
+ @clan = parser.clan
19
+ @model = parser.model
20
+ @member_since = parser.member_since
21
+ @last_game = parser.last_game
22
+ @time_played = parser.time_played
23
+ @wins = parser.wins
24
+ @accuracy = parser.accuracy
25
+ @losses, @quits = parser.losses_quits
26
+ @frags, @deaths = parser.frags_deaths
27
+ @hits, @shots = parser.hits_shots
28
+ @favourite = parser.favourites
29
+ @recent_awards = parser.awards
30
+ @recent_games = parser.recent_games
31
+ @recent_competitors = parser.recent_competitors
32
+ end
33
33
  end
34
34
  end
35
35
  end
@@ -1,3 +1,3 @@
1
1
  module QuakeliveApi
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -18,11 +18,12 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_dependency "nokogiri", ">= 1.5"
21
+ spec.add_dependency 'nokogiri', '>= 1.5'
22
22
 
23
- spec.add_development_dependency "bundler", "~> 1.3"
24
- spec.add_development_dependency "rake"
25
- spec.add_development_dependency "minitest", "~> 5.0.0"
26
- spec.add_development_dependency "webmock", "~> 1.12.0"
27
- spec.add_development_dependency "simplecov", "~> 0.8.0.pre"
23
+ spec.add_development_dependency 'bundler', '~> 1.3'
24
+ spec.add_development_dependency 'rake'
25
+ spec.add_development_dependency 'minitest', '~> 5.2.0'
26
+ spec.add_development_dependency 'webmock', '~> 1.18.0'
27
+ spec.add_development_dependency 'vcr', '~> 2.9.2'
28
+ spec.add_development_dependency 'coveralls', '~> 0.7.1'
28
29
  end