Skip to content

Instantly share code, notes, and snippets.

@mattantonelli
Last active August 29, 2015 14:21
Show Gist options
  • Select an option

  • Save mattantonelli/c405f5d3a966e990ab7b to your computer and use it in GitHub Desktop.

Select an option

Save mattantonelli/c405f5d3a966e990ab7b to your computer and use it in GitHub Desktop.
Ruby API for parsing FFXIV Lodestone
#!/usr/bin/env ruby
# encoding: utf-8
require 'nokogiri'
require 'open-uri'
require 'json'
module LodestoneApi
CHARACTER_URL = 'http://na.finalfantasyxiv.com/lodestone/character'
DOW = %w(gladiator pugilist marauder lancer archer rogue)
DOM = %w(conjurer thaumaturge arcanist)
DOH = %w(carpenter blacksmith armorer goldsmith leatherworker weaver alchemist culinarian)
DOL = %w(miner botanist fisher)
def self.parse(options)
if options.include?(:id)
parse_id(options[:id])
elsif options.values_at(:name, :world).size == 2
id = find_id(*options.values_at(:name, :world))
parse_id(id)
else
abort 'Invalid lookup.'
end
end
def self.parse_id(char_id)
doc = character_page(char_id)
name = doc.css('title').text.split(' | ').first
title = doc.css('div.chara_title').text
image = doc.css('div.bg_chara_264 img').first['src']
disciple_of_war = hashify_levels(DOW, levels(doc, 'mc_title_fighter'))
disciple_of_magic = hashify_levels(DOM, levels(doc, 'mc_title_sorcerer'))
disciple_of_hand = hashify_levels(DOH, levels(doc, 'mc_title_crafter'))
disciple_of_land = hashify_levels(DOL, levels(doc, 'mc_title_gatherer'))
{ name: name, title: title, image: image, disciple_of_war: disciple_of_war,
disciple_of_magic: disciple_of_magic, disciple_of_hand: disciple_of_hand,
disciple_of_land: disciple_of_land }.to_json
end
private
def self.character_page(char_id)
Nokogiri::HTML(open("#{CHARACTER_URL}/#{char_id}"))
end
def self.search_page(name, world)
Nokogiri::HTML(open("#{CHARACTER_URL}?q=#{name.sub(' ', '+')}&worldname=#{world}"))
end
def self.find_id(name, world)
doc = search_page(name, world)
doc.css('h4.player_name_gold a').last['href'].split('/').last
end
def self.levels(doc, id)
doc.xpath("//h3[@id='#{id}']/following-sibling::ul").css('li').map(&:text)
end
def self.hashify_levels(names, levels)
Hash[names.zip(levels)]
end
end
# For testing on CLI
args = ARGV[0..-1]
if args.size == 1
puts LodestoneApi.parse(id: args[0])
elsif args.size == 2
puts LodestoneApi.parse(name: args[0], world: args[1])
else
puts LodestoneApi.parse(id: '2829821')
end
@mattantonelli
Copy link
Copy Markdown
Author

$ ./lodestone_api.rb 2829821

{"name":"Mizzteq Aran","title":"The Meat Axe",
"image":"http://img2.finalfantasyxiv.com/f/bb9d9a1c98e06a393df7cadd485dc910_be20385e18333edb329d4574f364a1f0fl0_640x873.jpg?1432323612",
"disciple_of_war":{"gladiator":"50","pugilist":"23","marauder":"50","lancer":"-","archer":"30","rogue":"-"},
"disciple_of_magic":{"conjurer":"50","thaumaturge":"30","arcanist":"50"},
"disciple_of_hand":{"carpenter":"2","blacksmith":"14","armorer":"7","goldsmith":"-","leatherworker":"-","weaver":"-","alchemist":"-","culinarian":"11"},
"disciple_of_land":{"miner":"19","botanist":"-","fisher":"50"}}
$ ./lodestone_api.rb "Mizzteq Aran" "Behemoth"

{"name":"Mizzteq Aran","title":"The Meat Axe",
"image":"http://img2.finalfantasyxiv.com/f/bb9d9a1c98e06a393df7cadd485dc910_be20385e18333edb329d4574f364a1f0fl0_640x873.jpg?1432323612",
"disciple_of_war":{"gladiator":"50","pugilist":"23","marauder":"50","lancer":"-","archer":"30","rogue":"-"},
"disciple_of_magic":{"conjurer":"50","thaumaturge":"30","arcanist":"50"},
"disciple_of_hand":{"carpenter":"2","blacksmith":"14","armorer":"7","goldsmith":"-","leatherworker":"-","weaver":"-","alchemist":"-","culinarian":"11"},
"disciple_of_land":{"miner":"19","botanist":"-","fisher":"50"}}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment