class MtgDb::Parsers::GathererParser

Constants

DEBUG

Attributes

cards[R]

Public Class Methods

new(uri = nil, response = nil, body = nil, code = nil) click to toggle source
Calls superclass method
# File lib/mtg_db/parsers.rb, line 13
def initialize(uri = nil, response = nil, body = nil, code = nil)
  super(uri, response, body, code)
  @cards = parse_cards
end

Private Instance Methods

cmc(node) click to toggle source
# File lib/mtg_db/parsers.rb, line 58
def cmc(node)
  node.search('span.convertedManaCost').text.strip
end
mana_cost(node) click to toggle source
# File lib/mtg_db/parsers.rb, line 48
def mana_cost(node)
  img_nodes = node.search('span.manaCost > img')
  mana_costs = img_nodes.collect do |img|
    cost = img['alt']
    # colorless mana cost if no abbreviation exists
    MANA_COST_ABBREVIATIONS[cost] || cost
  end
  mana_costs.join
end
name(node) click to toggle source
# File lib/mtg_db/parsers.rb, line 44
def name(node)
  node.search('span.cardTitle > a').text.strip
end
parse_cards() click to toggle source

Each page in standard format has a bunch of cards

# File lib/mtg_db/parsers.rb, line 21
def parse_cards
  cards = []
  card_nodes = search('tr.cardItem')
  card_nodes.each do |card_node|
    card = {}
    card[:name]      = name(card_node)
    card[:mana_cost] = mana_cost(card_node)
    card[:cmc]       = cmc(card_node)
    card[:rules]     = rules(card_node)
    card[:power]     = power(card_node)
    card[:toughness] = toughness(card_node)
    card[:set_versions] = set_versions(card_node)

    # Supertype, Subtype, P/T, Loyalty, Hand/Life Modifiers, etc are all stored in the same node
    type_data = type_data(card_node)
    card.merge! type_data

    cards << card
    p card if DEBUG
  end
  cards
end
planeswalker_data(node) click to toggle source
# File lib/mtg_db/parsers.rb, line 89
def planeswalker_data(node)
  loyalty_match = node.search('span.typeLine').text.match(/\( (.*) \)\z/xo)
  loyalty = 0
  if loyalty_match
    loyalty = loyalty_match[1]
  end
  { loyalty: loyalty }
end
power(node) click to toggle source
# File lib/mtg_db/parsers.rb, line 127
def power(node)
  # '(*/{^2})'.scan(PT_REGEX) => [[nil, nil, nil, nil, "*"], [nil, nil, nil, "{^2}", nil]]
  node.search('span.typeLine').text.match(PT_REGEX) do |match|
    return match['POWER']
  end
end
rules(node) click to toggle source
# File lib/mtg_db/parsers.rb, line 118
def rules(node)
  # node.search('div.rulesText').text.strip # doesn't account for images or multiple paragraphs formatting properly
  rules_nodeset = node.search('div.rulesText')
  rules_nodeset.search('img').each{ |node| node.replace("{#{node['alt']}}") } # replace images in the rules with the image alt text
  rules_text = ''
  rules_nodeset.search('p').each{ |node| rules_text << node.text + "\n" }
  return rules_text.chomp
end
set_versions(node) click to toggle source
# File lib/mtg_db/parsers.rb, line 141
def set_versions(node)
  set_versions_node = node.search('.setVersions')
  set_versions = set_versions_node.search('a').collect do |a|
    # multiverse_id
    query_str = URI.parse(a['href']).query
    params_h = URI.decode_www_form(query_str).to_h
    multiverse_id = params_h['multiverseid']

    # set abbreviation e.g. ALA
    img_src = a.search('img').first['src']
    query_str = URI.parse(img_src).query
    params_h = URI.decode_www_form(query_str).to_h
    set_abbreviation = params_h['set']

    # set version, e.g. Planeschase (Common), Shards of Alara (Rare)
    set_version = a.search('img').first['title']
    match = set_version.match(SET_VERSION_REGEX)
    set = match['SET']
    rarity = match['RARITY']

    { multiverse_id: multiverse_id, set: set, rarity: rarity, set_abbreviation: set_abbreviation }
  end
end
subtype(node) click to toggle source
# File lib/mtg_db/parsers.rb, line 109
def subtype(node)
  subtype = node.search('span.typeLine').text.split(/\u2014/)[1]
  unless subtype.nil?
    subtype.strip!
    subtype = subtype.partition("\r\n")[0]
  end
  subtype
end
supertype(node) click to toggle source

When the supertype is a Vanguard, there is a Hand/Life Modifier and when it's a Planeswalker, there is Loyalty. In either case, no Power/Toughness

# File lib/mtg_db/parsers.rb, line 100
def supertype(node)
  type_line = node.search('span.typeLine').text.strip
  supertype = case type_line
    when /\u2014/ then type_line.split(/\u2014/)[0].strip
    when /\r\n/   then type_line.split("\r\n")[0].strip
    else type_line.strip
  end
end
toughness(node) click to toggle source
# File lib/mtg_db/parsers.rb, line 134
def toughness(node)
  # '(*/{^2})'.scan(PT_REGEX) => [[nil, nil, nil, nil, "*"], [nil, nil, nil, "{^2}", nil]]
  node.search('span.typeLine').text.match(PT_REGEX) do |match|
    match['TOUGHNESS']
  end
end
type_data(node) click to toggle source
# File lib/mtg_db/parsers.rb, line 62
def type_data(node)
  type_hash = {}
  type_hash[:supertype] = supertype(node)
  type_hash[:subtype] = subtype(node)

  other_data = case type_hash[:supertype]
               when 'Vanguard' then vanguard_data(node)
               when 'Planeswalker' then planeswalker_data(node)
               else {}
               end

  type_hash.merge! other_data
end
vanguard_data(node) click to toggle source
# File lib/mtg_db/parsers.rb, line 76
def vanguard_data(node)
  type_line = node.search('span.typeLine').text

  components = type_line.split(/\r\n/)
  hand_life = components[-1].strip
  hand_life.match(PT_REGEX) do |match|
    # Hand/Life modifiers are prefixed with +/- operators
    hand_modifier = match['POWER'].to_i
    life_modifier = match['TOUGHNESS'].to_i
    return { hand_modifier: hand_modifier, life_modifier: life_modifier }
  end
end