Skip to content

Instantly share code, notes, and snippets.

@djberg96
Last active May 27, 2022 12:37
Show Gist options
  • Save djberg96/d4d1f168168ad44cda81669336f10cb8 to your computer and use it in GitHub Desktop.
Save djberg96/d4d1f168168ad44cda81669336f10cb8 to your computer and use it in GitHub Desktop.
# Find common games between users on BGG
require 'excon'
require 'awesome_print'
require 'oga'
require 'getopt/long'
require 'cgi'
# Looks like BGG redirects to non-www url's sometimes
Excon.defaults[:middlewares] << Excon::Middleware::RedirectFollower
# If this fails with a 302, try "https://boardgamegeek.com/xmlapi2/collection"
url = "https://www.boardgamegeek.com/xmlapi2/collection"
# e.g. ruby common_games.rb --user1 djberg96 --user2 jameycribbs
opts = Getopt::Long.getopts(
["--user1", "-u", Getopt::OPTIONAL],
["--user2", "-z", Getopt::REQUIRED],
["--debug", "-d", Getopt::BOOLEAN]
)
# Put real user id's here
user1 = opts['user1'] || "djberg96"
user2 = opts['user2']
if user2.nil? || user2.size.zero?
$stderr.puts "Please specify a user to compare with using the -z option"
exit
end
puts "Comparing #{user1} and #{user2}"
connection = Excon.new(url, :persistent => true)
response1 = connection.get(:query => {:username => user1, :own => 1})
response2 = connection.get(:query => {:username => user2, :own => 1, :persistent => false}) # close socket server-side
# Sleep 30 seconds and try one more time on a 202 (accepted) response.
# There's no time estimate provided in response, we have to guess.
if response1.status == 202
puts "BGG is building the collection for #{user1}. Waiting 30 seconds to try again."
sleep 30
response1 = Excon.get(url, :query => {:username => user1, :own => 1})
end
if response1.status > 399
$stderr.puts "Looks like something went wrong, got #{response.status} status from server"
exit
end
if response2.status == 202
puts "BGG is building the collection for #{user2}. Waiting 30 seconds to try again."
sleep 30
response2 = Excon.get(url, :query => {:username => user2, :own => 1})
end
if response2.status > 399
$stderr.puts "Looks like something went wrong, got #{response.status} status from server"
exit
end
document1 = Oga.parse_xml(response1.body)
document2 = Oga.parse_xml(response2.body)
collection1 = []
collection2 = []
# Collect both the name and original name in case a version is specified.
document1.xpath('items/item/name').each do |item|
collection1 << item.text
end
document1.xpath('items/item/originalname').each do |item|
collection1 << item.text
end
document2.xpath('items/item/name').each do |item|
collection2 << item.text
end
document2.xpath('items/item/originalname').each do |item|
collection2 << item.text
end
if opts['debug']
ap collection1.map{ |e| CGI.unescape(e) }
ap collection2.map{ |e| CGI.unescape(e) }
end
puts "The games that #{user1} and #{user2} have in common are:"
ap (collection1 & collection2).map{ |e| CGI.unescape(e) }.sort
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment