Skip to content

Instantly share code, notes, and snippets.

@turizoft
Created May 22, 2015 23:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save turizoft/4d4140d3656b2efca40e to your computer and use it in GitHub Desktop.
Save turizoft/4d4140d3656b2efca40e to your computer and use it in GitHub Desktop.
Task to read a games database from an API
require 'open-uri'
require 'nokogiri'
namespace :gamesdb do
#This method checks if there are new games in gamesdb and returns the api_id for the last added game
desc "Search for new games on Game db"
task :new_games? => :environment do
gamesdb_games = nokigiri_xml(game_list_url)
games = Game.where('api_id IS NOT NULL')
current_last = games.empty? ? 0 : games.last.api_id
gamedb_last = gamesdb_games.xpath('//id').last.text.to_i
puts gamedb_last - current_last > 0 ? "New games in Games db. \nLast game: #{gamedb_last} " : "Nothing new around here"
end
desc "Add new games from games db"
task :add_new_games => :environment do
#Initialize necesary
games = []
categories = Hash[Category.all.collect { |v| [v.name, v] }]
current_last = Game.where('api_id IS NOT NULL').count
gamesdb_games = nokigiri_xml(game_list_url).xpath('//id')
n = ENV['n'].nil? ? 0 : ENV['n'].to_i
total = 0
total1 = 1
gamesdb_games.each do |id|
if total1 > current_last
games << id.text
total += 1
end
break if n != 0 && total == n
total1 += 1
end
# Add games to db
begin
start_time = Time.now
p "Getting ready to add #{games.size} new game..."
games.each.each do |id|
print id + " "
Game.transaction do
CategoriesGame.transaction do
game_data = nokigiri_xml(game_detail_base_url + id)
game = Game.new({
api_id: game_data.at_css('id').try(:text),
name: game_data.at_css('GameTitle').try(:text),
release_date: game_data.at_css('ReleaseDate').try(:text),
description: game_data.at_css('Overview').try(:text),
esrb: esrb_to_number(game_data.at_css('ESRB').try(:text)),
players: players_to_number(game_data.at_css('Players').try(:text)),
coop: coop_to_boolean(game_data.at_css('Co-op').try(:text)),
publisher: game_data.at_css('Publisher').try(:text),
developer: game_data.at_css('Developer').try(:text),
trailer: game_data.at_css('Youtube').try(:text),
box_art: game_data.at_css('boxart[@side=front]').try(:text)
})
game_data.xpath('//genre').each do |category|
game.categories << categories["" + category]
end
game.save
print "ok "
end
end
end
rescue Exception => exc
p "#{exc.message}"
p "Running again..."
Rake::Task['gamesdb:add_new_games'].execute
end
p "#{games.size} Games added"
puts "Total Time = #{Time.now - start_time}s == #{(Time.now - start_time)/60.to_f}m"
end
#------------------------------ Methods ------------------------------------------
def game_list_url
'http://thegamesdb.net/api/PlatformGames.php?platform=pc'
end
def game_detail_base_url
'http://thegamesdb.net/api/GetGame.php?id='
end
def nokigiri_xml(url)
Nokogiri.XML open(url).read
end
def esrb_to_number(esrb)
case esrb
when 'M - Mature'
1
when 'T - Teen'
2
when 'E - Everyone'
3
when 'E10+ - Everyone 10+'
4
when 'RP - Rating Pending'
5
else
nil
end
end
def players_to_number(players)
case players
when '1'
1
when '2'
2
when '3'
3
when '4+'
4
else
nil
end
end
def coop_to_boolean(coop)
if coop.try(:downcase) == "yes"
true
elsif coop.try(:downcase) == "no"
false
else
nil
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment