Created
May 22, 2015 23:17
-
-
Save turizoft/4d4140d3656b2efca40e to your computer and use it in GitHub Desktop.
Task to read a games database from an API
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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