class RelatonGb::GbBibliography

GB entry point class.

Public Class Methods

get(code, year = nil, opts = {}) click to toggle source

@param code [String] the GB standard Code to look up (e..g “GB/T 20223”) @param year [String] the year the standard was published (optional) @param opts [Hash] options; restricted to :all_parts if all-parts reference is required @return [String] Relaton XML serialisation of reference

# File lib/relaton_gb/gb_bibliography.rb, line 44
def get(code, year = nil, opts = {})
  if year.nil?
    /^(?<code1>[^-]+)-(?<year1>[^-]+)$/ =~ code
    unless code1.nil?
      code = code1
      year = year1
    end
  end

  code += ".1" if opts[:all_parts]
  code, year = code.split(/-/, 2) if /-/ =~ code
  ret = get1(code, year, opts)
  return nil if ret.nil?

  ret = ret.to_most_recent_reference unless year
  ret = ret.to_all_parts if opts[:all_parts]
  ret
end

Private Class Methods

fetch_pages(hits, threads) click to toggle source

@param hits [RelatonBib::HitCollection<RelatonBib::Hit>] @param threads [Integer] @return [Array<RelatonBib::GbBibliographicItem>]

# File lib/relaton_gb/gb_bibliography.rb, line 135
def fetch_pages(hits, threads)
  workers = RelatonBib::WorkersPool.new threads
  workers.worker { |w| { i: w[:i], hit: w[:hit].fetch } }
  hits.each_with_index { |hit, i| workers << { i: i, hit: hit } }
  workers.end
  workers.result.sort_by { |x| x[:i] }.map { |x| x[:hit] }
end
fetch_ref_err(code, year, missed_years) click to toggle source
# File lib/relaton_gb/gb_bibliography.rb, line 65
def fetch_ref_err(code, year, missed_years)
  id = year ? "#{code}:#{year}" : code
  warn "[relaton-gb] WARNING: no match found on the GB website "\
    "for #{id}. The code must be exactly like it is on the website."
  unless missed_years.empty?
    warn "[relaton-gb] (There was no match for #{year}, though there "\
      "were matches found for #{missed_years.join(', ')}.)"
  end
  if /\d-\d/.match? code
    warn "[relaton-gb] The provided document part may not exist, or the "\
      "document may no longer be published in parts."
  else
    warn "[relaton-gb] If you wanted to cite all document parts for the "\
      "reference, use \"#{code} (all parts)\".\nIf the document is not "\
      "a standard, use its document type abbreviation (TS, TR, PAS, "\
      "Guide)."
  end
  nil
end
get1(code, year, _opts) click to toggle source
# File lib/relaton_gb/gb_bibliography.rb, line 85
def get1(code, year, _opts)
  # search must include year whenever available
  searchcode = code + (year.nil? ? "" : "-#{year}")
  result = search_filter(searchcode) || return
  ret = results_filter(result, year)
  if ret[:ret]
    warn "[relaton-gb] (\"#{code}\") found #{ret[:ret].docidentifier.first.id}"
    ret[:ret]
  else
    fetch_ref_err(code, year, ret[:years])
  end
end
results_filter(result, year) click to toggle source

Sort through the results from Isobib, fetching them three at a time, and return the first result that matches the code, matches the year (if provided), and which # has a title (amendments do not). Only expects the first page of results to be populated. Does not match corrigenda etc (e.g. ISO 3166-1:2006/Cor 1:2007) If no match, returns any years which caused mismatch, for error reporting

# File lib/relaton_gb/gb_bibliography.rb, line 116
def results_filter(result, year) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength
  missed_years = []
  result.each_slice(3) do |s| # ISO website only allows 3 connections
    fetch_pages(s, 3).each do |r|
      return { ret: r } if !year

      r.date.select { |d| d.type == "published" }.each do |d|
        return { ret: r } if year.to_i == d.on(:year)

        missed_years << d.on(:year)
      end
    end
  end
  { years: missed_years }
end
search_filter(code) click to toggle source
# File lib/relaton_gb/gb_bibliography.rb, line 98
def search_filter(code)
  # search filter needs to incorporate year
  docidrx = %r{^[^\s]+\s[\d.-]+}
  warn "[relaton-gb] (\"#{code}\") fetching..."
  result = search(code)
  result.select do |hit|
    hit.docref && hit.docref.match(docidrx).to_s.include?(code)
  end
end