Skip to content

Instantly share code, notes, and snippets.

@xaviershay
Created April 7, 2018 21:01
Show Gist options
  • Save xaviershay/557ebfa506701db9bc70b2a71814d24c to your computer and use it in GitHub Desktop.
Save xaviershay/557ebfa506701db9bc70b2a71814d24c to your computer and use it in GitHub Desktop.
Analyzing splits IO data
require 'net/http'
require 'json'
require 'fileutils'
game_id = "3414" # ori_de
def cache(key, &block)
path = "cache/key-#{key.tr("/", "-")}"
FileUtils.mkdir_p(File.dirname(path))
if File.exists?(path)
Marshal.load(File.read(path))
else
result = block.call
File.write(path, Marshal.dump(result))
result
end
end
def api_get(path, paginated: false)
if paginated
current_page = 1
key = path + "-page-#{current_page}"
results = []
while true
response = cache(key) do
url = 'https://splits.io/api/v3' + path + "?page=#{current_page}"
uri = URI.parse(url)
pp uri.request_uri
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri.request_uri)
response = http.request(request)
end
results += JSON.parse(response.body).fetch("runs")
break if results.length >= response['total'].to_i
current_page += 1
end
results
else
cache(path) do
url = 'https://splits.io/api/v3' + path
uri = URI.parse(url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri.request_uri)
response = http.request(request)
JSON.parse(response.body)
end
end
end
game = api_get("/games/#{game_id}")
require 'pp'
category_ids = game.fetch('game').fetch('categories')
.select {|x|
name = x.fetch('name')
name == "All Skills" || (
name =~ /all skills/i &&
name =~ /no oob/i)
}
.map {|x| x.fetch('id') }
run_ids = category_ids.flat_map do |category_id|
category = api_get("/games/#{game_id}/categories/#{category_id}/runs", paginated: true)
category.map {|x| x.fetch('path') }
end
runs = run_ids.map do |run_path|
api_get("/runs#{run_path}").fetch('run')
end
data = runs.map do |run|
user = run.fetch('user')
next unless user
splits = run.fetch('splits')
idx = splits.find_index {|x| x.fetch('name') =~ /Wall Jump/i || x.fetch('name') =~ /Spiderman/i}
if idx && idx < 3 # Some people (TROJANDUDE) have Spiderman for climb
wj = splits[idx]
# [user.fetch('name'), wj.fetch('finish_time')]
sob = splits[0..idx].map {|x| x.fetch('best').fetch('duration') }.sum
[user.fetch('name'), sob]
end
end.compact.sort_by {|(name, time)| [name, time] }
data = data
.uniq(&:first)
.sort_by {|x| x[1] }
def format_seconds(s)
"#{(s / 60).to_i}:%02d.%03d" % [s % 60, (s - s.to_i) * 1000]
end
data.each do |(name, time)|
puts [name, format_seconds(time)].join("\t")
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment