Skip to content

Instantly share code, notes, and snippets.

@EdConnell
Last active August 29, 2015 13:57
Show Gist options
  • Save EdConnell/9921844 to your computer and use it in GitHub Desktop.
Save EdConnell/9921844 to your computer and use it in GitHub Desktop.
Test script made for learning EVE Online API
require 'nokogiri'
require 'open-uri'
require 'sqlite3'
require 'csv'
BASE_URL = "https://api.eveonline.com/"
JUMP_URL = "map/Jumps.xml.aspx"
KILLS_URL = "map/Kills.xml.aspx"
SOV_URL = "map/Sovereignty.xml.aspx"
STATION_URL = "eve/ConquerableStationList.xml.aspx"
SYSTEMS_TO_IGNORE = (30000326..30000432).to_a + (30001449..30001525).to_a + (30001598..30001643).to_a
class Database
attr_reader :connection
def initialize
@connection = SQLite3::Database.new('universeDataDx.db')
@connection.results_as_hash = true
@connection.type_translation = true
end
def execute(query, arg)
connection.execute(query, arg)
end
end
class Universe
attr_reader :db, :solar_systems, :kills, :jumps, :names, :stations, :ids
attr_accessor :current_path
def initialize
@solar_systems = []
@kills = Nokogiri::XML(open(BASE_URL + KILLS_URL))
@jumps = Nokogiri::XML(open(BASE_URL + JUMP_URL))
@names = Nokogiri::XML(open(BASE_URL + SOV_URL))
@stations = Nokogiri::XML(open(BASE_URL + STATION_URL))
@ids = @names.xpath('//rowset/row').map {|row| row.attr('solarSystemID')}
@total_number_of_systems = @ids.count - SYSTEMS_TO_IGNORE.count
@db = Database.new
@current_path = nil
end
def build_and_save_universe
create_solar_systems
store_data_to_files
end
def create_solar_systems
puts "Building universe."
print "0% Complete"
ids.each_with_index do |id, index|
print_percentage_complete(index)
next if SYSTEMS_TO_IGNORE.include?(id.to_i)
self.current_path = "//row[@solarSystemID='#{id}']"
stats = Hash.new
stats[:kills] = Hash.new
stats[:id], stats[:kills][:pod_kills], stats[:kills][:ship_kills], stats[:kills][:npc_kills], stats[:jumps], stats[:station] = id,0,0,0,0, "F" #Defaults for solar systems incase there is no data to be retrieved
stats[:kills][:pod_kills], stats[:kills][:ship_kills], stats[:kills][:npc_kills] = kill_counts_from_xml if row_in_kills_exists?
stats[:jumps] = jump_count_from_xml if row_in_jumps_exists?
if row_in_stations_exists? || station_data_exists_in_db?(id)
stats[:station] = "T"
end
stats[:name] = system_name_from_xml
stats[:region_name] = find_region_name(id)
store_data(stats)
end
@current_path = nil
puts "\nUniverse complete."
puts self.count
end
def find_region_name(id)
regionID = db.execute("SELECT fromRegionID from mapSolarSystemJumps where fromSolarSystemID = ?", id)[0]['fromRegionID']
rescue NoMethodError
else
db.execute("SELECT regionName FROM mapRegions WHERE regionID = ? ", regionID)[0]['regionName']
end
def count
"There are #{@solar_systems.count} solar systems on record."
end
def jump_count_from_xml
jumps.xpath(current_path).attr('shipJumps')
end
def kill_counts_from_xml
return kills.xpath(current_path).attr('podKills').value, kills.xpath(current_path).attr('shipKills').value, kills.xpath(current_path).attr('factionKills').value
end
def system_name_from_xml
names.xpath(current_path).attr('solarSystemName').value
end
def print_percentage_complete(index)
print "\e[0K\r" + "#{percentage(index).round(1)}% Complete"
end
def percentage(index)
(index / @total_number_of_systems.to_f) * 100.0
end
def row_in_kills_exists?
kills.at(current_path)
end
def row_in_jumps_exists?
jumps.at(current_path)
end
def row_in_stations_exists?
stations.at(current_path)
end
def station_data_exists_in_db?(id)
db.execute("select * from mapDenormalize where solarSystemID = ? and itemName is not null and itemName not like '% - Star' and celestialIndex is null and orbitIndex is null", id) != []
end
def store_data(stats)
new_solar_system = SolarSystem.new(stats)
gather_neighbor_data(new_solar_system)
solar_systems << new_solar_system
end
def gather_neighbor_data(home_system)
neighbors = db.execute("SELECT toSolarSystemID FROM mapSolarSystemJumps where fromSolarSystemID = ?", home_system.id)
home_system.set_adjacent_solar_systems(neighbors)
end
def store_data_to_files
puts "Saving Solar System Data"
CSV.open('solarSystems.csv', 'w') do |file|
file << ['id', 'name', 'region', 'jumps', 'pod_kills', 'ship_kills', 'npc_kills', 'station']
print "0% Complete"
solar_systems.each_with_index do |system, index|
print_percentage_complete(index)
file << system.to_a
end
end
puts "\nSolar System Data Save Complete"
puts "Saving Solar System Jump Gate Data"
CSV.open('solarSystemMap.csv', 'w') do |file|
file << ['fromSystem', 'toSystems']
print "0% Complete"
solar_systems.each_with_index do |system, index|
print_percentage_complete(index)
file << system.adjacent_systems_array
end
end
puts "\nAll data has been saved. Good-bye!"
end
end
class SolarSystem
attr_reader :id, :name, :region, :station, :adjacent_systems
attr_accessor :jumps, :kills
def initialize(solar_system_hash)
@id = solar_system_hash[:id]
@jumps = solar_system_hash[:jumps]
@kills = solar_system_hash[:kills]
@name = solar_system_hash[:name]
@region = solar_system_hash[:region_name]
@station = solar_system_hash[:station]
@adjacent_systems = []
end
def set_adjacent_solar_systems(adjacent_systems_array)
adjacent_systems_array.each {|system| adjacent_systems << system['toSolarSystemID']}
end
def to_a
[id, name, region, jumps, kills[:pod_kills], kills[:ship_kills], kills[:npc_kills], station]
end
def adjacent_systems_array
[id, adjacent_systems.join(', ')]
end
end
eve = Universe.new
eve.build_and_save_universe
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment