-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #78 from LD4P/loc-lookup
Extend LOC lookup support from qa gem
- Loading branch information
Showing
4 changed files
with
274 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,7 +10,6 @@ | |
/.git | ||
/.gitignore | ||
/.rspec | ||
/.rubocop* | ||
/.qa_server_app | ||
|
||
/coverage/* | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# Overrides loc authority from qa gem to handle rdftypes for subauthorities | ||
|
||
require 'uri' | ||
|
||
module Qa::Authorities | ||
module Loc | ||
extend AuthorityWithSubAuthority | ||
|
||
require 'qa/authorities/loc/generic_authority' | ||
def self.subauthority_for(subauthority) | ||
validate_subauthority!(subauthority) | ||
GenericAuthority.new(subauthority) | ||
end | ||
|
||
extend LocSubauthority | ||
def self.subauthorities | ||
authorities + vocabularies + datatypes + preservation + rdftypes | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
# Overrides loc authority from qa gem to customize search output and handle | ||
# rdftypes for subauthorities | ||
|
||
module Qa::Authorities | ||
class Loc::GenericAuthority < Base | ||
attr_reader :subauthority | ||
def initialize(subauthority) | ||
@subauthority = subauthority | ||
end | ||
|
||
include WebServiceBase | ||
|
||
def response(url) | ||
uri = URI(url) | ||
conn = Faraday.new "#{uri.scheme}://#{uri.host}" | ||
conn.options.params_encoder = Faraday::FlatParamsEncoder | ||
conn.get do |req| | ||
req.headers['Accept'] = 'application/json' | ||
req.url uri.path | ||
req.params = Rack::Utils.parse_query(uri.query) | ||
end | ||
end | ||
|
||
def search(q) | ||
@raw_response = json(build_query_url(q)) | ||
parse_authority_response | ||
end | ||
|
||
def build_query_url(q) | ||
escaped_query = ERB::Util.url_encode(q) | ||
authority = Loc.get_authority(subauthority) | ||
rdftype = Loc.get_rdftype(subauthority) | ||
authority_fragment = Loc.get_url_for_authority(authority) + ERB::Util.url_encode(authority) | ||
rdftype_fragment = "&q=rdftype:#{ERB::Util.url_encode(rdftype)}" if rdftype | ||
"https://id.loc.gov/search/?q=#{escaped_query}&q=#{authority_fragment}#{rdftype_fragment}&format=json" | ||
end | ||
|
||
def find(id) | ||
json(find_url(id)) | ||
end | ||
|
||
def find_url(id) | ||
"https://id.loc.gov/authorities/#{@subauthority}/#{id}.json" | ||
end | ||
|
||
private | ||
|
||
# Reformats the data received from the LOC service | ||
# Filters for id uniqueness | ||
def parse_authority_response | ||
results = @raw_response.select { |response| response[0] == "atom:entry" }.map do |response| | ||
loc_response_to_qa(response_to_struct(response)) | ||
end | ||
results.uniq { |result| result["id"] } | ||
end | ||
|
||
# Converts most of the atom data into an OpenStruct object. | ||
# | ||
# Note that this is a pretty naive conversion. There should probably just | ||
# be a class that properly translates and stores the various pieces of | ||
# data, especially if this logic could be useful in other auth lookups. | ||
def response_to_struct(response) | ||
contents = response.each_with_object({}) do |result_parts, result| | ||
next unless result_parts[0] | ||
key = result_parts[0].sub('atom:', '').sub('dcterms:', '') | ||
info = result_parts[1] | ||
val = result_parts[2] | ||
|
||
case key | ||
when 'title', 'id', 'name', 'updated', 'created' | ||
result[key] = val | ||
when 'link' | ||
result["links"] ||= [] | ||
result["links"] << { "type" => info["type"], "href" => info["href"] } | ||
end | ||
end | ||
|
||
OpenStruct.new(contents) | ||
end | ||
|
||
# Simple conversion from LoC-based struct to QA hash | ||
def loc_response_to_qa(data) | ||
response = { | ||
"id" => data.id || data.title, | ||
"label" => data.title | ||
} | ||
|
||
response["uri"] = (data.links.find { |l| l["type"].nil? } || data.links[0])["href"] if data.links.present? | ||
|
||
response | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
# Overrides loc authority from qa gem to handle rdftypes for subauthorities | ||
|
||
module Qa::Authorities::LocSubauthority # rubocop:disable Metrics/ModuleLength | ||
def get_url_for_authority(authority) | ||
if authorities.include?(authority) then authority_base_url | ||
elsif vocabularies.include?(authority) then vocab_base_url | ||
elsif datatypes.include?(authority) then datatype_base_url | ||
elsif preservation.include?(authority) then vocab_preservation_base_url | ||
end | ||
end | ||
|
||
def get_authority(authority) | ||
rdftypes.include?(authority) ? authority.split('_')[0] : authority | ||
end | ||
|
||
def get_rdftype(authority) | ||
rdftypes.include?(authority) ? authority.split('_')[-1] : nil | ||
end | ||
|
||
def authorities | ||
[ | ||
"classification", | ||
"childrensSubjects", | ||
"demographicTerms", | ||
"genreForms", | ||
"names", | ||
"performanceMediums", | ||
"subjects" | ||
] | ||
end | ||
|
||
def vocabularies # rubocop:disable Metrics/MethodLength | ||
[ | ||
"actionsGranted", | ||
"agentType", | ||
"bookformat", | ||
"carriers", | ||
"classSchemes", | ||
"contentTypes", | ||
"countries", | ||
"descriptionConventions", | ||
"ethnographicTerms", | ||
"frequencies", | ||
"geographicAreas", | ||
"graphicMaterials", | ||
"iso639-1", | ||
"iso639-2", | ||
"iso639-5", | ||
"issuance", | ||
"languages", | ||
"marcauthen", | ||
"maspect", | ||
"maudience", | ||
"mbroadstd", | ||
"mcapturestorage", | ||
"mcolor", | ||
"mediaTypes", | ||
"mencformat", | ||
"menclvl", | ||
"mfiletype", | ||
"mfont", | ||
"mgeneration", | ||
"mgovtpubtype", | ||
"mgroove", | ||
"millus", | ||
"mlayout", | ||
"mmaterial", | ||
"mmusicformat", | ||
"mmusnotation", | ||
"mnotetype", | ||
"mplayback", | ||
"mplayspeed", | ||
"mpolarity", | ||
"mpresformat", | ||
"mproduction", | ||
"mprojection", | ||
"mrecmedium", | ||
"mrectype", | ||
"mreductionratio", | ||
"mregencoding", | ||
"mrelief", | ||
"mscale", | ||
"mscript", | ||
"mserialpubtype", | ||
"msoundcontent", | ||
"mspecplayback", | ||
"mstatus", | ||
"msupplcont", | ||
"mtactile", | ||
"mtapeconfig", | ||
"mtechnique", | ||
"mvidformat", | ||
"organizations", | ||
"preservation", | ||
"rbmscv", | ||
"rbmsrel", | ||
"relationship", | ||
"relators", | ||
"resourceComponents" | ||
] | ||
end | ||
|
||
def datatypes | ||
["edtf"] | ||
end | ||
|
||
def preservation # rubocop:disable Metrics/MethodLength | ||
[ | ||
"contentLocationType", | ||
"copyrightStatus", | ||
"cryptographicHashFunctions", | ||
"environmentCharacteristic", | ||
"environmentPurpose", | ||
"eventRelatedAgentRole", | ||
"eventRelatedObjectRole", | ||
"eventType", | ||
"formatRegistryRole", | ||
"hardwareType", | ||
"inhibitorTarget", | ||
"inhibitorType", | ||
"objectCategory", | ||
"preservationLevelRole", | ||
"relationshipSubType", | ||
"relationshipType", | ||
"rightsBasis", | ||
"rightsRelatedAgentRole", | ||
"signatureEncoding", | ||
"signatureMethod", | ||
"softwareType", | ||
"storageMedium" | ||
] | ||
end | ||
|
||
def rdftypes | ||
[ | ||
"names_ConferenceName", | ||
"names_CorporateName", | ||
"names_FamilyName", | ||
"names_Geographic", | ||
"names_PersonalName" | ||
] | ||
end | ||
|
||
private | ||
|
||
def vocab_base_url | ||
"cs%3Ahttp%3A%2F%2Fid.loc.gov%2Fvocabulary%2F" | ||
end | ||
|
||
def authority_base_url | ||
"cs%3Ahttp%3A%2F%2Fid.loc.gov%2Fauthorities%2F" | ||
end | ||
|
||
def datatype_base_url | ||
"cs%3Ahttp%3A%2F%2Fid.loc.gov%2Fdatatypes%2F" | ||
end | ||
|
||
def vocab_preservation_base_url | ||
"cs%3Ahttp%3A%2F%2Fid.loc.gov%2Fvocabulary%2Fpreservation%2F" | ||
end | ||
end |