class WikiData::Fetcher

Constants

LOOKUP_FILE

Attributes

id[R]
item[R]

Public Class Methods

find(ids) click to toggle source
# File lib/wikidata/fetcher.rb, line 12
def self.find(ids)
  Hash[Wikisnakker::Item.find(ids).map { |wditem| [wditem.id, new(item: wditem)] }]
end
new(h) click to toggle source
# File lib/wikidata/fetcher.rb, line 20
def initialize(h)
  if h[:id]
    @item = Wikisnakker::Item.find(h[:id]) or raise "No such item #{h[:id]}"
    @id = @item.id or raise "No ID for #{h[:id]} = #{@item}"
    warn "Different ID (#{@id}) for #{h[:id]}" if @id != h[:id]
  elsif h[:item]
    # Already have a Wikisnakker::Item, eg from a bulk lookup
    @item = h[:item]
    @id = @item.id or raise "No ID for #{h[:id]} = #{@item}"
  else
    raise 'No id'
  end
end
wikidata_properties() click to toggle source
# File lib/wikidata/fetcher.rb, line 16
def self.wikidata_properties
  @wikidata_properties ||= JSON.parse(open(LOOKUP_FILE).read, symbolize_names: true)
end

Public Instance Methods

data(*lang) click to toggle source
# File lib/wikidata/fetcher.rb, line 34
def data(*lang)
  return unless item

  data = {
    id:   id,
    name: first_label_used(lang | ['en']),
  }.merge(labels).merge(wikipedia_links)

  # Short-circuit if there are no claims
  return data if item.properties.empty?

  # Short-circuit if this is not a human
  unless human?
    warn "‼ #{id} is_instance_of #{type.join(' & ')}. Skipping"
    return nil
  end

  unknown_properties.each do |p|
    puts "⁇ Unknown property: https://www.wikidata.org/wiki/Property:#{p} for #{id}"
  end

  wanted_properties.each do |p|
    val = property_value(p)
    next warn "Unknown value for #{p} for #{id}" unless val
    data[want[p].to_sym] = val
  end

  data
end

Private Instance Methods

first_label_used(language_codes) click to toggle source
# File lib/wikidata/fetcher.rb, line 112
def first_label_used(language_codes)
  prefered = (item.labels.keys & language_codes.map(&:to_sym)).first or return
  item.labels[prefered][:value]
end
human?() click to toggle source
# File lib/wikidata/fetcher.rb, line 80
def human?
  type.include? 'human'
end
labels() click to toggle source
# File lib/wikidata/fetcher.rb, line 92
def labels
  # remove any bracketed element at the end
  Hash[item.labels.map do |k, v|
    ["name__#{k.to_s.tr('-', '_')}".to_sym, v[:value].sub(/ \(.*?\)$/, '')]
  end]
end
property_value(property) click to toggle source
# File lib/wikidata/fetcher.rb, line 105
def property_value(property)
  val = item[property].value rescue nil or return
  return val unless val.respond_to?(:label)
  return unless val.labels
  val.label('en')
end
skip() click to toggle source
# File lib/wikidata/fetcher.rb, line 68
def skip
  @skip ||= self.class.wikidata_properties[:skip]
end
type() click to toggle source
# File lib/wikidata/fetcher.rb, line 76
def type
  item.P31s.map { |p| p.value.label('en') }
end
unknown_properties() click to toggle source
# File lib/wikidata/fetcher.rb, line 84
def unknown_properties
  item.properties.reject { |c| skip[c] || want[c] }
end
want() click to toggle source
# File lib/wikidata/fetcher.rb, line 72
def want
  @want ||= self.class.wikidata_properties[:want]
end
wanted_properties() click to toggle source
# File lib/wikidata/fetcher.rb, line 88
def wanted_properties
  item.properties & want.keys
end