Grab some pvp stats in World of Warcraft
Stats 2v2 updated at 08/09/2017 for the first 4966 best EU players | |
Priest Discipline [================================================] 12.36% - 614 | |
Shaman Restoration [=========================================== ] 10.99% - 546 | |
Druid Restoration [================================== ] 8.88% - 441 | |
Druid Feral Combat [================================== ] 8.8% - 437 | |
Demon Hunter Havoc [========================= ] 6.44% - 320 | |
Warrior Arms [====================== ] 5.76% - 286 | |
Paladin Holy [====================== ] 5.6% - 278 | |
Rogue Subtlety [==================== ] 5.07% - 252 | |
Death Knight Frost [=================== ] 4.87% - 242 | |
Paladin Retribution [================ ] 4.05% - 201 | |
Priest Shadow [============= ] 3.34% - 166 | |
Death Knight Unholy [============= ] 3.28% - 163 | |
Monk Windwalker [=========== ] 2.8% - 139 | |
Monk Mistweaver [========= ] 2.44% - 121 | |
Shaman Elemental [========= ] 2.19% - 109 | |
Druid Balance [======= ] 1.81% - 90 | |
Rogue Assassination [====== ] 1.61% - 80 | |
Shaman Enhancement [====== ] 1.55% - 77 | |
Priest Holy [==== ] 1.13% - 56 | |
Warlock Affliction [==== ] 0.99% - 49 | |
Mage Frost [==== ] 0.95% - 47 | |
Hunter Survival [=== ] 0.77% - 38 | |
Hunter Marksmanship [=== ] 0.68% - 34 | |
Warlock Destruction [== ] 0.42% - 21 | |
Paladin Protection [== ] 0.42% - 21 | |
Warlock Demonology [= ] 0.36% - 18 | |
Druid Guardian [= ] 0.36% - 18 | |
Mage Arcane [= ] 0.34% - 17 | |
Death Knight Blood [= ] 0.32% - 16 | |
Warrior Fury [= ] 0.32% - 16 | |
Mage Fire [= ] 0.26% - 13 | |
Hunter Beast Mastery [= ] 0.22% - 11 | |
Demon Hunter Vengeance [= ] 0.18% - 9 | |
Warrior Protection [= ] 0.16% - 8 | |
Monk Brewmaster [= ] 0.16% - 8 | |
Rogue Outlaw [ ] 0.08% - 4 | |
Stats 3v3 updated at 08/09/2017 for the first 4958 best EU players | |
Shaman Restoration [================================================] 10.49% - 520 | |
Warrior Arms [================================== ] 7.32% - 363 | |
Priest Discipline [=============================== ] 6.88% - 341 | |
Druid Feral Combat [=============================== ] 6.76% - 335 | |
Paladin Holy [============================= ] 6.23% - 309 | |
Priest Shadow [============================ ] 6.17% - 306 | |
Demon Hunter Havoc [========================= ] 5.49% - 272 | |
Druid Restoration [======================= ] 5.02% - 249 | |
Death Knight Frost [===================== ] 4.68% - 232 | |
Rogue Subtlety [=================== ] 4.24% - 210 | |
Paladin Retribution [=================== ] 4.07% - 202 | |
Mage Frost [=============== ] 3.33% - 165 | |
Shaman Elemental [============== ] 3.07% - 152 | |
Warlock Affliction [============= ] 2.86% - 142 | |
Hunter Marksmanship [============= ] 2.84% - 141 | |
Warlock Destruction [============= ] 2.84% - 141 | |
Druid Balance [============= ] 2.84% - 141 | |
Death Knight Unholy [============ ] 2.56% - 127 | |
Monk Windwalker [============ ] 2.56% - 127 | |
Monk Mistweaver [========= ] 1.9% - 94 | |
Shaman Enhancement [======== ] 1.73% - 86 | |
Mage Arcane [===== ] 1.13% - 56 | |
Warlock Demonology [=== ] 0.73% - 36 | |
Priest Holy [=== ] 0.67% - 33 | |
Hunter Survival [=== ] 0.61% - 30 | |
Mage Fire [== ] 0.54% - 27 | |
Rogue Assassination [== ] 0.5% - 25 | |
Warrior Fury [== ] 0.44% - 22 | |
Druid Guardian [= ] 0.26% - 13 | |
Death Knight Blood [= ] 0.26% - 13 | |
Hunter Beast Mastery [= ] 0.24% - 12 | |
Paladin Protection [= ] 0.2% - 10 | |
Demon Hunter Vengeance [= ] 0.18% - 9 | |
Monk Brewmaster [= ] 0.16% - 8 | |
Warrior Protection [ ] 0.1% - 5 | |
Rogue Outlaw [ ] 0.08% - 4 |
require 'net/http' | |
require 'json' | |
require 'tty-progressbar' | |
SPECID_MAP = { | |
250 => 'Death Knight Blood', | |
251 => 'Death Knight Frost', | |
252 => 'Death Knight Unholy', | |
577 => 'Demon Hunter Havoc', | |
581 => 'Demon Hunter Vengeance', | |
102 => 'Druid Balance', | |
103 => 'Druid Feral Combat', | |
104 => 'Druid Guardian', | |
105 => 'Druid Restoration', | |
253 => 'Hunter Beast Mastery', | |
254 => 'Hunter Marksmanship', | |
255 => 'Hunter Survival', | |
62 => 'Mage Arcane', | |
63 => 'Mage Fire', | |
64 => 'Mage Frost', | |
268 => 'Monk Brewmaster', | |
269 => 'Monk Windwalker', | |
270 => 'Monk Mistweaver', | |
65 => 'Paladin Holy', | |
66 => 'Paladin Protection', | |
70 => 'Paladin Retribution', | |
256 => 'Priest Discipline', | |
257 => 'Priest Holy', | |
258 => 'Priest Shadow', | |
259 => 'Rogue Assassination', | |
260 => 'Rogue Outlaw', | |
261 => 'Rogue Subtlety', | |
262 => 'Shaman Elemental', | |
263 => 'Shaman Enhancement', | |
264 => 'Shaman Restoration', | |
265 => 'Warlock Affliction', | |
266 => 'Warlock Demonology', | |
267 => 'Warlock Destruction', | |
71 => 'Warrior Arms', | |
72 => 'Warrior Fury', | |
73 => 'Warrior Protection' | |
} | |
APIKEY = 'YOURAPIKEY' | |
%w(2v2 3v3).each do |bracket| | |
api_endpoint = "https://eu.api.battle.net/wow/leaderboard/#{bracket}?locale=en_GB&apikey=#{APIKEY}" | |
result = Net::HTTP.get(URI.parse(api_endpoint)) | |
leaderboard = JSON.parse(result) | |
counters = {} | |
leaderboard['rows'].each do |row| | |
counters[row['specId']] = (counters[row['specId']] || 0) + 1 | |
end | |
counters.delete(0) | |
counters = counters.sort{|x, y| y[1] <=> x[1]} | |
max = counters.map(&:last).max | |
sum = counters.map(&:last).sum | |
padding = SPECID_MAP.values.map(&:size).max | |
puts "Stats #{bracket} updated at #{Time.now.strftime('%d/%m/%Y')} for the first #{sum} best EU players\n" | |
counters.each do |data| | |
bar = TTY::ProgressBar.new("#{SPECID_MAP[data[0]].ljust(padding)} [:bar] #{(data[1]*100.0/sum).round(2)}% - :current", total: max, width: 70 - padding) | |
bar.current = data[1] | |
bar.start | |
bar.stop | |
end | |
end |
require 'nokogiri' | |
require 'open-uri' | |
require 'gruff' | |
# Extend Pie chart class to set custom labels | |
class LabeledPie < Gruff::Pie | |
def data(name, data_points = [], options = {}) | |
super(name, data_points, options[:color]) | |
@data.each { |data_array| data_array << options[:label] } | |
end | |
private | |
def slice_class | |
CustomLabeledSlice | |
end | |
class CustomLabeledSlice < ::Gruff::Pie::PieSlice | |
def label | |
data_array[3] || super | |
end | |
end | |
end | |
# URL where we grab the data | |
url = 'https://worldofwarcraft.com/en-gb/game/pvp/leaderboards' | |
# Wow Class colors | |
COLORS = { | |
'mage' => '#68ccef', | |
'monk' => '#00ffba', | |
'priest' => '#ffffff', | |
'warlock' => '#9382c9', | |
'deathknight' => '#c41e3b', | |
'paladin' => '#f48cba', | |
'warrior' => '#c69b6d', | |
'rogue' => '#fff468', | |
'shaman' => '#2359ff', | |
'druid' => '#ff7c0a', | |
'demonhunter' => '#a330c9', | |
'hunter' => '#aad372' | |
} | |
%w(2v2 3v3).each do |arena| | |
# Plus 1 the counter when we found the wow class in the leaderboard | |
counters = { | |
'mage' => 0, | |
'monk' => 0, | |
'priest' => 0, | |
'warlock' => 0, | |
'deathknight' => 0, | |
'paladin' => 0, | |
'warrior' => 0, | |
'rogue' => 0, | |
'shaman' => 0, | |
'druid' => 0, | |
'demonhunter' => 0, | |
'hunter' => 0 | |
} | |
tot = 0 | |
# Parse the 10 pages of the leaderboard | |
10.times do |i| | |
doc = Nokogiri::HTML(open("#{url}/#{arena}?page=#{i+1}")) | |
doc.search('a.Character').each do |row| | |
regexp = counters.keys.reduce(){|x,y| "#{x}|#{y}"} | |
klass = row[:class].downcase[/#{regexp}/] | |
if klass | |
counters[klass] += 1 | |
tot += 1 | |
end | |
end | |
end | |
# Sort counters | |
counters = counters.sort{|x, y| y[1] <=> x[1]} | |
# Generate pie graph | |
g = LabeledPie.new | |
g.title = "Stats #{arena} updated at #{Time.now.strftime('%d/%m/%Y')} for\nthe first #{tot} best EU players" | |
g.legend_font_size = 14 | |
g.marker_font_size = 12 | |
g.colors = [] | |
counters.each { |klass, counter| g.colors << COLORS[klass] } | |
counters.each do |klass, counter| | |
g.data(klass.capitalize, counter, label: "#{klass.capitalize}: #{(counter*100.0/tot).round}% (#{counter})") | |
end | |
g.write("stats_#{arena}.png") | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment