diff --git a/app/controllers/qa/linked_data_terms_controller.rb b/app/controllers/qa/linked_data_terms_controller.rb index 6b7b4bcb..9bd4bdaa 100644 --- a/app/controllers/qa/linked_data_terms_controller.rb +++ b/app/controllers/qa/linked_data_terms_controller.rb @@ -222,9 +222,14 @@ def n3? format.casecmp?('n3') end + def ntriples? + format.casecmp?('ntriples') + end + def content_type_for_format return 'application/ld+json' if jsonld? return 'text/n3' if n3? + return 'application/n-triples' if ntriples? 'application/json' end diff --git a/app/controllers/qa/terms_controller.rb b/app/controllers/qa/terms_controller.rb index 76edef5f..75839739 100644 --- a/app/controllers/qa/terms_controller.rb +++ b/app/controllers/qa/terms_controller.rb @@ -95,9 +95,14 @@ def n3? format.casecmp?('n3') end + def ntriples? + format.casecmp?('ntriples') + end + def content_type_for_format return 'application/ld+json' if jsonld? return 'text/n3' if n3? + return 'application/n-triples' if ntriples? 'application/json' end end diff --git a/lib/qa/authorities/discogs/discogs_instance_builder.rb b/lib/qa/authorities/discogs/discogs_instance_builder.rb index 6ff6cb97..563122db 100644 --- a/lib/qa/authorities/discogs/discogs_instance_builder.rb +++ b/lib/qa/authorities/discogs/discogs_instance_builder.rb @@ -44,11 +44,12 @@ def get_identifiers_stmts(response) count = 1 return stmts unless response["identifiers"].present? response["identifiers"].each do |activity| - stmts << contruct_stmt_uri_object("Instance1", "http://id.loc.gov/ontologies/bibframe/identifiedBy", "Identifier#{count}") - stmts << contruct_stmt_uri_object("Identifier#{count}", rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/Identifier") - stmts << contruct_stmt_literal_object("Identifier#{count}", rdfs_label_predicate, activity["value"]) + stmts << contruct_stmt_uri_object(instance_uri, "http://id.loc.gov/ontologies/bibframe/identifiedBy", "iidn#{count}") + stmts << contruct_stmt_uri_object("iidn#{count}", rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/Identifier") + stmts << contruct_stmt_literal_object("iidn#{count}", rdfs_label_predicate, activity["value"]) count += 1 end + stmts.concat(build_year_statements(response)) if response["released"].present? stmts # w/out this line, building the graph throws an undefined method `graph_name=' error end @@ -64,7 +65,7 @@ def build_format_desc_stmts(descs, count) if df.present? stmts += build_format_characteristics(df, count) else - stmts << contruct_stmt_literal_object("Instance1", "http://id.loc.gov/ontologies/bibframe/editionStatement", desc) + stmts << contruct_stmt_literal_object(instance_uri, "http://id.loc.gov/ontologies/bibframe/editionStatement", desc) end end stmts @@ -77,15 +78,13 @@ def build_format_characteristics(df, count) stmts = [] case df["type"] when "playbackChannel" - stmts << contruct_stmt_uri_object("Instance1", "http://id.loc.gov/ontologies/bibframe/soundCharacteristic", df["uri"]) + stmts << contruct_stmt_uri_object(instance_uri, "http://id.loc.gov/ontologies/bibframe/soundCharacteristic", df["uri"]) stmts << contruct_stmt_uri_object(df["uri"], rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/PlaybackChannel") stmts << contruct_stmt_literal_object(df["uri"], rdfs_label_predicate, df["label"]) when "dimension" - stmts << contruct_stmt_uri_object("Instance1", "http://id.loc.gov/ontologies/bibframe/dimensions", df["label"]) + stmts << contruct_stmt_literal_object(instance_uri, "http://id.loc.gov/ontologies/bibframe/dimensions", df["label"]) when "playingSpeed" - stmts << contruct_stmt_uri_object("Instance1", "http://id.loc.gov/ontologies/bibframe/soundCharacteristic", "PlayingSpeed#{count}") - stmts << contruct_stmt_uri_object("PlayingSpeed#{count}", rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/PlayingSpeed") - stmts << contruct_stmt_literal_object("PlayingSpeed#{count}", rdfs_label_predicate, df["label"]) + stmts.concat(build_playing_speed_stmts(df["label"], count)) end stmts # w/out this line, building the graph throws an undefined method `graph_name=' error end @@ -98,13 +97,13 @@ def build_format_name_stmts(name) return stmts unless name.present? dc = discogs_formats[name.gsub(/\s+/, "")] if dc.present? - stmts << contruct_stmt_uri_object("Instance1", "http://id.loc.gov/ontologies/bibframe/carrier", dc["uri"]) + stmts << contruct_stmt_uri_object(instance_uri, "http://id.loc.gov/ontologies/bibframe/carrier", dc["uri"]) stmts << contruct_stmt_uri_object(dc["uri"], rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/Carrier") stmts << contruct_stmt_literal_object(dc["uri"], rdfs_label_predicate, dc["label"]) stmts.concat(build_base_materials(name)) else # if it's not a carrier, it's an edition statement - stmts << contruct_stmt_literal_object("Instance1", "http://id.loc.gov/ontologies/bibframe/editionStatement", name) + stmts << contruct_stmt_literal_object(instance_uri, "http://id.loc.gov/ontologies/bibframe/editionStatement", name) end stmts # w/out this line, building the graph throws an undefined method `graph_name=' error end @@ -116,7 +115,7 @@ def build_base_materials(name) return stmts unless name == "Vinyl" || name == "Shellac" id = name == "Vinyl" ? "300014502" : "300014918" - stmts << contruct_stmt_uri_object("Instance1", "http://id.loc.gov/ontologies/bibframe/baseMaterial", "http://vocab.getty.edu/aat/" + id) + stmts << contruct_stmt_uri_object(instance_uri, "http://id.loc.gov/ontologies/bibframe/baseMaterial", "http://vocab.getty.edu/aat/" + id) stmts << contruct_stmt_uri_object("http://vocab.getty.edu/aat/" + id, rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/BaseMaterial") stmts << contruct_stmt_literal_object("http://vocab.getty.edu/aat/" + id, rdfs_label_predicate, name) stmts # w/out this line, building the graph throws an undefined method `graph_name=' error @@ -129,13 +128,12 @@ def build_provision_activity_stmts(activities) # need to distinguish among different provision activities and roles count = 1 activities.each do |activity| - stmts << contruct_stmt_uri_object("Instance1", "http://id.loc.gov/ontologies/bibframe/provisionActivity", "ProvisionActivity#{count}") - stmts << contruct_stmt_uri_object("ProvisionActivity#{count}", rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/ProvisionActivity") - stmts << contruct_stmt_uri_object("ProvisionActivity#{count}", bf_agent_predicate, activity["name"]) - stmts << contruct_stmt_uri_object(activity["name"], rdf_type_predicate, bf_agent_type_object) - stmts << contruct_stmt_uri_object(activity["name"], bf_role_predicate, "PA_Role#{count}") - stmts << contruct_stmt_uri_object("PA_Role#{count}", rdf_type_predicate, bf_role_type_object) - stmts << contruct_stmt_literal_object("PA_Role#{count}", rdfs_label_predicate, activity["entity_type_name"]) + stmts << contruct_stmt_uri_object(instance_uri, "http://id.loc.gov/ontologies/bibframe/provisionActivity", "proact#{count}") + stmts << contruct_stmt_uri_object("proact#{count}", rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/ProvisionActivity") + stmts << contruct_stmt_uri_object("proact#{count}", bf_agent_predicate, "agentn3#{count}") + stmts << contruct_stmt_uri_object("agentn3#{count}", rdf_type_predicate, bf_agent_type_object) + stmts << contruct_stmt_literal_object("agentn3#{count}", rdfs_label_predicate, activity["name"]) + stmts += build_role_stmts("agentn3#{count}", "role3#{count}", activity["entity_type_name"]) count += 1 end stmts # w/out this line, building the graph throws an undefined method `graph_name=' error diff --git a/lib/qa/authorities/discogs/discogs_translation.rb b/lib/qa/authorities/discogs/discogs_translation.rb index b758b588..0b128cda 100644 --- a/lib/qa/authorities/discogs/discogs_translation.rb +++ b/lib/qa/authorities/discogs/discogs_translation.rb @@ -11,7 +11,7 @@ module DiscogsTranslation # to the URIs of corresponding objects in the Library of Congress vocabulary. # @param [Hash] the http response from discogs # @param [String] the subauthority - # @return [Array, String] requested RDF serialzation (supports: jsonld Array, n3 String) + # @return [Array, String] requested RDF serialzation (supports: jsonld Array, n3 String, n-triples String) def build_graph(response, subauthority = "", format: :jsonld) graph = RDF::Graph.new @@ -30,14 +30,17 @@ def compile_rdf_statements(response, subauthority) # all we need is a work and not an instance. If there's no subauthority, we can determine # if the discogs record is a master because it will have a main_release field. if master_only(response, subauthority) + self.work_uri = response["uri"] complete_rdf_stmts.concat(build_master_statements(response)) else # If the subauthority is not "master," we need to define an instance as well as a # work. If the discogs record has a master_id, fetch that and use the results to # build the statements for the work. master_resp = response["master_id"].present? ? json("https://api.discogs.com/masters/#{response['master_id']}") : response + self.work_uri = master_resp["uri"] if master_resp["uri"].present? && master_resp["uri"].include?("master") complete_rdf_stmts.concat(build_master_statements(master_resp)) # Now do the statements for the instance. + self.instance_uri = response["uri"] if response["uri"].present? complete_rdf_stmts.concat(build_instance_statements(response)) end end @@ -77,11 +80,12 @@ def build_instance_statements(response) # @return [Array] rdf statements def get_primary_work_definition(response) stmts = [] - stmts << contruct_stmt_uri_object("Work1", rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/Work") - stmts << contruct_stmt_uri_object("Work1", "http://id.loc.gov/ontologies/bibframe/title", "Work1Title") - stmts << contruct_stmt_literal_object("Work1Title", bf_main_title_predicate, response["title"]) - stmts << contruct_stmt_uri_object("Work1", rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/Audio") - stmts.concat(build_year_statements(response, "Work")) + stmts << contruct_stmt_uri_object(work_uri, rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/Work") + stmts << contruct_stmt_uri_object(work_uri, "http://id.loc.gov/ontologies/bibframe/title", "titlen1") + stmts << contruct_stmt_literal_object("titlen1", bf_main_title_predicate, response["title"]) + stmts << contruct_stmt_uri_object("titlen1", rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/Title") + stmts << contruct_stmt_uri_object(work_uri, rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/Audio") + stmts << contruct_stmt_literal_object(work_uri, "http://id.loc.gov/ontologies/bibframe/originDate", response["year"].to_s) if response["year"].present? stmts # w/out this line, building the graph throws an undefined method `graph_name=' error end @@ -89,14 +93,14 @@ def get_primary_work_definition(response) # @return [Array] rdf statements def get_primary_instance_definition(response) stmts = [] - stmts << contruct_stmt_uri_object("Work1", "http://id.loc.gov/ontologies/bibframe/hasInstance", "Instance1") - stmts << contruct_stmt_uri_object("Instance1", rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/Instance") - stmts << contruct_stmt_uri_object("Instance1", "http://id.loc.gov/ontologies/bibframe/title", "Instance1Title") - stmts << contruct_stmt_literal_object("Instance1Title", bf_main_title_predicate, response["title"]) - stmts << contruct_stmt_uri_object("Instance1", "http://id.loc.gov/ontologies/bibframe/identifiedBy", "IdentifierPrimary") - stmts << contruct_stmt_uri_object("IdentifierPrimary", rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/Identifier") - stmts << contruct_stmt_literal_object("IdentifierPrimary", "http://www.w3.org/1999/02/22-rdf-syntax-ns#value", response["id"]) - stmts.concat(build_year_statements(response, "Instance")) + stmts << contruct_stmt_uri_object(work_uri, "http://id.loc.gov/ontologies/bibframe/hasInstance", instance_uri) + stmts << contruct_stmt_uri_object(instance_uri, rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/Instance") + stmts << contruct_stmt_uri_object(instance_uri, "http://id.loc.gov/ontologies/bibframe/title", "titlen2") + stmts << contruct_stmt_literal_object("titlen2", bf_main_title_predicate, response["title"]) + stmts << contruct_stmt_uri_object("titlen2", rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/Title") + stmts << contruct_stmt_uri_object(instance_uri, "http://id.loc.gov/ontologies/bibframe/identifiedBy", "widn1") + stmts << contruct_stmt_uri_object("widn1", rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/Identifier") + stmts << contruct_stmt_literal_object("widn1", "http://www.w3.org/1999/02/22-rdf-syntax-ns#value", response["id"]) stmts # w/out this line, building the graph throws an undefined method `graph_name=' error end @@ -112,10 +116,11 @@ def get_primary_artists_stmts(response) # we need the primary artists later when we loop through the track list, so build this array primary_artists << artist - stmts << contruct_stmt_uri_object("Work1", "http://id.loc.gov/ontologies/bibframe/contribution", "Work1PrimaryContribution#{count}") - stmts << contruct_stmt_uri_object("Work1PrimaryContribution#{count}", rdf_type_predicate, "http://id.loc.gov/ontologies/bflc/PrimaryContribution") - stmts << contruct_stmt_uri_object("Work1PrimaryContribution#{count}", bf_agent_predicate, artist["name"]) - stmts << contruct_stmt_uri_object(artist["name"], rdf_type_predicate, bf_agent_type_object) + stmts << contruct_stmt_uri_object(work_uri, "http://id.loc.gov/ontologies/bibframe/contribution", "contrbn#{count}") + stmts << contruct_stmt_uri_object("contrbn#{count}", rdf_type_predicate, "http://id.loc.gov/ontologies/bflc/PrimaryContribution") + stmts << contruct_stmt_uri_object("contrbn#{count}", bf_agent_predicate, "agentn#{count}") + stmts << contruct_stmt_uri_object("agentn#{count}", rdf_type_predicate, bf_agent_type_object) + stmts << contruct_stmt_literal_object("agentn#{count}", rdfs_label_predicate, artist["name"]) count += 1 end end diff --git a/lib/qa/authorities/discogs/discogs_utils.rb b/lib/qa/authorities/discogs/discogs_utils.rb index 360e27f4..fcb92548 100644 --- a/lib/qa/authorities/discogs/discogs_utils.rb +++ b/lib/qa/authorities/discogs/discogs_utils.rb @@ -9,9 +9,11 @@ module DiscogsUtils # @param [String] either a string used to create a unique URI or an LOC uri in string format # @param [String] or [Class] either a BIBFRAME property uri in string format or an RDF::URI # @param [String] or [Class] strings can be a label or BIBFRAME class uri; class is always RDF::URI - # @return [Class] RDF::Statement with uri as the object + # @return [Class] RDF::Statement with either a uri or a bnode as the object def contruct_stmt_uri_object(subject, predicate, object) - RDF::Statement(RDF::URI.new(subject), RDF::URI(predicate), RDF::URI.new(object)) + s = subject.include?("http") ? RDF::URI.new(subject) : subject.to_sym + o = object.to_s.include?("http") ? RDF::URI.new(object) : object.to_sym + RDF::Statement(s, RDF::URI(predicate), o) end # Constructs an RDF statement where the subject and predicate are URIs and the object is a literal @@ -20,7 +22,8 @@ def contruct_stmt_uri_object(subject, predicate, object) # @param [String] or [Class] strings can be a label or BIBFRAME class uri; class is always RDF::URI # @return [Class] RDF::Statement with a literal as the object def contruct_stmt_literal_object(subject, predicate, object) - RDF::Statement(RDF::URI.new(subject), RDF::URI(predicate), RDF::Literal.new(object)) + s = subject.include?("http") ? RDF::URI.new(subject) : subject.to_sym + RDF::Statement(s, RDF::URI(predicate), RDF::Literal.new(object)) end # frequently used predicates and objects @@ -41,7 +44,7 @@ def bf_agent_predicate end def bf_agent_type_object - RDF::URI("http://id.loc.gov/ontologies/bibframe/Agent") + "http://id.loc.gov/ontologies/bibframe/Agent" end def bf_role_predicate @@ -49,7 +52,7 @@ def bf_role_predicate end def bf_role_type_object - RDF::URI("http://id.loc.gov/ontologies/bibframe/Role") + "http://id.loc.gov/ontologies/bibframe/Role" end def discogs_genres @@ -62,27 +65,36 @@ def discogs_formats # both the work and the instance require a statement for the release year # @param [Hash] the http response from discogs - # @param [String] either "Work" or "Instance" # @return [Array] rdf statements - def build_year_statements(response, type) + def build_year_statements(response) year_stmts = [] - if type == "Work" && response["year"].present? - year_stmts = get_year_rdf(type + "1", response["year"]) - elsif response["released"].present? - year_stmts = get_year_rdf(type + "1", response["released"]) - end + year_stmts << contruct_stmt_uri_object(instance_uri, "http://id.loc.gov/ontologies/bibframe/provisionActivity", "daten1") + year_stmts << contruct_stmt_uri_object("daten1", rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/Publication") + year_stmts << contruct_stmt_literal_object("daten1", RDF::URI("http://id.loc.gov/ontologies/bibframe/date"), response["released"].to_s) year_stmts # w/out this line, building the graph throws an undefined method `graph_name=' error end - # @param [String] either "Work1" or "Instance1" - # @param [String] 4-digit year in string format + # @param [Hash] the extraartists defined at the release level, not the track level + # @param [Integer] gives the role a unique uri + # @param [String] the entity type name # @return [Array] rdf statements - def get_year_rdf(type, year) - year_stmts = [] - year_stmts << contruct_stmt_uri_object(type, "http://id.loc.gov/ontologies/bibframe/provisionActivity", "#{type}ProvisionActivityDate") - year_stmts << contruct_stmt_uri_object("#{type}ProvisionActivityDate", rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/ProvisionActivity") - # Full RDF statement syntax as this one requires a datatype - year_stmts << RDF::Statement(RDF::URI.new("#{type}ProvisionActivityDate"), RDF::URI("http://id.loc.gov/ontologies/bibframe/date"), RDF::Literal.new(year.to_s, datatype: RDF::XSD.date)) + def build_role_stmts(subject_node, role_node, label) + stmts = [] + stmts << contruct_stmt_uri_object(subject_node, bf_role_predicate, role_node) + stmts << contruct_stmt_uri_object(role_node, rdf_type_predicate, bf_role_type_object) + stmts << contruct_stmt_literal_object(role_node, rdfs_label_predicate, label) + stmts # w/out this line, building the graph throws an undefined method `graph_name=' error + end + + # @param [String] the playing speed in string format + # @param [Integer] gives the playing speed a unique uri + # @return [Array] rdf statements + def build_playing_speed_stmts(label, count) + stmts = [] + stmts << contruct_stmt_uri_object(instance_uri, "http://id.loc.gov/ontologies/bibframe/soundCharacteristic", "speed#{count}") + stmts << contruct_stmt_uri_object("speed#{count}", rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/PlayingSpeed") + stmts << contruct_stmt_literal_object("speed#{count}", rdfs_label_predicate, label) + stmts # w/out this line, building the graph throws an undefined method `graph_name=' error end end end diff --git a/lib/qa/authorities/discogs/discogs_works_builder.rb b/lib/qa/authorities/discogs/discogs_works_builder.rb index 0ad619f2..3d4d467e 100644 --- a/lib/qa/authorities/discogs/discogs_works_builder.rb +++ b/lib/qa/authorities/discogs/discogs_works_builder.rb @@ -1,7 +1,7 @@ require 'rdf' module Qa::Authorities module Discogs - module DiscogsWorksBuilder # rubocop:disable Metrics/ModuleLength + module DiscogsWorksBuilder include Discogs::DiscogsUtils # @param [Hash] the http response from discogs @@ -12,27 +12,17 @@ def get_extra_artists_stmts(response) count = 1 return stmts unless response["extraartists"].present? response["extraartists"].each do |artist| - stmts << contruct_stmt_uri_object("Work1", "http://id.loc.gov/ontologies/bibframe/contribution", "Work1SecondaryContribution#{count}") - stmts << contruct_stmt_uri_object("Work1SecondaryContribution#{count}", rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/Contribution") - stmts << contruct_stmt_uri_object("Work1SecondaryContribution#{count}", bf_agent_predicate, artist["name"]) - stmts << contruct_stmt_uri_object(artist["name"], rdf_type_predicate, bf_agent_type_object) - stmts += build_artist_role_stmts(artist, count) + stmts << contruct_stmt_uri_object(work_uri, "http://id.loc.gov/ontologies/bibframe/contribution", "contrbn1#{count}") + stmts << contruct_stmt_uri_object("contrbn1#{count}", rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/Contribution") + stmts << contruct_stmt_uri_object("contrbn1#{count}", bf_agent_predicate, "agentn1#{count}") + stmts << contruct_stmt_uri_object("agentn1#{count}", rdf_type_predicate, bf_agent_type_object) + stmts << contruct_stmt_literal_object("agentn1#{count}", rdfs_label_predicate, artist["name"]) + stmts += build_role_stmts("agentn1#{count}", "rolen1#{count}", artist["role"]) count += 1 end stmts # w/out this line, building the graph throws an undefined method `graph_name=' error end - # @param [Hash] the extraartists defined at the release level, not the track level - # @param [Integer] gives the role a unique uri - # @return [Array] rdf statements - def build_artist_role_stmts(artist, count) - stmts = [] - stmts << contruct_stmt_uri_object(artist["name"], bf_role_predicate, "Work1SecondaryContributor_Role#{count}") - stmts << contruct_stmt_uri_object("Work1SecondaryContributor_Role#{count}", rdf_type_predicate, bf_role_type_object) - stmts << contruct_stmt_literal_object("Work1SecondaryContributor_Role#{count}", rdfs_label_predicate, artist["role"]) - stmts # w/out this line, building the graph throws an undefined method `graph_name=' error - end - # @param [Hash] the http response from discogs # @return [Array] rdf statements def get_genres_stmts(response) @@ -54,24 +44,13 @@ def build_genres(genre) stmts = [] dg = discogs_genres[genre.gsub(/\s+/, "")] if dg.present? - stmts << contruct_stmt_uri_object("Work1", "http://id.loc.gov/ontologies/bibframe/genreForm", dg["uri"]) + stmts << contruct_stmt_uri_object(work_uri, "http://id.loc.gov/ontologies/bibframe/genreForm", dg["uri"]) stmts << contruct_stmt_uri_object(dg["uri"], rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/GenreForm") stmts << contruct_stmt_literal_object(dg["uri"], rdfs_label_predicate, dg["label"]) end stmts # w/out this line, building the graph throws an undefined method `graph_name=' error end - # @param [String] the uri of the genreForm - # @param [String] the genreForm label - # @return [Array] rdf statements - def build_genres_and_styles(uri, dg_label) - stmts = [] - stmts << contruct_stmt_uri_object("Work1", "http://id.loc.gov/ontologies/bibframe/genreForm", uri) - stmts << contruct_stmt_uri_object(uri, rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/GenreForm") - stmts << contruct_stmt_literal_object(uri, rdfs_label_predicate, dg_label) - stmts # w/out this line, building the graph throws an undefined method `graph_name=' error - end - # @param [Hash] the http response from discogs # @return [Array] rdf statements def get_tracklist_artists_stmts(response) @@ -103,13 +82,13 @@ def build_artist_array(artists) # @return [Array] rdf statements def build_secondary_works(track, w_count) stmts = [] - stmts << contruct_stmt_uri_object("Work1", "http://id.loc.gov/ontologies/bibframe/hasPart", "Work#{w_count}") - stmts << contruct_stmt_uri_object("Work#{w_count}", rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/Work") - stmts << contruct_stmt_uri_object("Work#{w_count}", rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/Audio") - stmts << contruct_stmt_uri_object("Work#{w_count}", "http://id.loc.gov/ontologies/bibframe/title", "Work#{w_count}Title") - stmts << contruct_stmt_uri_object("Work#{w_count}Title", rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/Title") - stmts << contruct_stmt_literal_object("Work#{w_count}Title", bf_main_title_predicate, track["title"]) - stmts << contruct_stmt_literal_object("Work#{w_count}", "http://id.loc.gov/ontologies/bibframe/duration", track["duration"]) if track["duration"].present? + stmts << contruct_stmt_uri_object(work_uri, "http://id.loc.gov/ontologies/bibframe/hasPart", "workn#{w_count}") + stmts << contruct_stmt_uri_object("workn#{w_count}", rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/Work") + stmts << contruct_stmt_uri_object("workn#{w_count}", rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/Audio") + stmts << contruct_stmt_uri_object("workn#{w_count}", "http://id.loc.gov/ontologies/bibframe/title", "titlen3#{w_count}") + stmts << contruct_stmt_uri_object("titlen3#{w_count}", rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/Title") + stmts << contruct_stmt_literal_object("titlen3#{w_count}", bf_main_title_predicate, track["title"]) + stmts << contruct_stmt_literal_object("workn#{w_count}", "http://id.loc.gov/ontologies/bibframe/duration", track["duration"]) if track["duration"].present? stmts # w/out this line, building the graph throws an undefined method `graph_name=' error end @@ -120,10 +99,11 @@ def build_track_artists(artists, w_count) stmts = [] count = 1 artists.each do |artist| - stmts << contruct_stmt_uri_object("Work#{w_count}", "http://id.loc.gov/ontologies/bibframe/contribution", "Work#{w_count}PrimaryContribution#{count}") - stmts << contruct_stmt_uri_object("Work#{w_count}PrimaryContribution#{count}", rdf_type_predicate, "http://id.loc.gov/ontologies/bflc/PrimaryContribution") - stmts << contruct_stmt_uri_object("Work#{w_count}PrimaryContribution#{count}", bf_agent_predicate, artist["name"]) - stmts << contruct_stmt_uri_object(artist["name"], rdf_type_predicate, bf_agent_type_object) + stmts << contruct_stmt_uri_object("workn#{w_count}", "http://id.loc.gov/ontologies/bibframe/contribution", "contrbn#{w_count}#{count}") + stmts << contruct_stmt_uri_object("contrbn#{w_count}#{count}", rdf_type_predicate, "http://id.loc.gov/ontologies/bflc/PrimaryContribution") + stmts << contruct_stmt_uri_object("contrbn#{w_count}#{count}", bf_agent_predicate, "agentn#{w_count}#{count}") + stmts << contruct_stmt_uri_object("agentn#{w_count}#{count}", rdf_type_predicate, bf_agent_type_object) + stmts << contruct_stmt_literal_object("agentn#{w_count}#{count}", rdfs_label_predicate, artist["name"]) count += 1 end stmts # w/out this line, building the graph throws an undefined method `graph_name=' error @@ -137,13 +117,12 @@ def build_track_extraartists(extraartists, w_count) # to distinguish among contributors to a track/work and their roles count = 1 extraartists.each do |artist| - stmts << contruct_stmt_uri_object("Work#{w_count}", "http://id.loc.gov/ontologies/bibframe/contribution", "Work#{w_count}Contribution#{count}") - stmts << contruct_stmt_uri_object("Work#{w_count}Contribution#{count}", rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/Contribution") - stmts << contruct_stmt_uri_object("Work#{w_count}Contribution#{count}", bf_agent_predicate, artist["name"]) - stmts << contruct_stmt_uri_object(artist["name"], rdf_type_predicate, bf_agent_type_object) - stmts << contruct_stmt_uri_object(artist["name"], bf_role_predicate, "Work#{w_count}ContributorRole#{count}") - stmts << contruct_stmt_uri_object("Work#{w_count}ContributorRole#{count}", rdf_type_predicate, bf_role_type_object) - stmts << contruct_stmt_literal_object("Work#{w_count}ContributorRole#{count}", rdfs_label_predicate, artist["role"]) + stmts << contruct_stmt_uri_object("workn#{w_count}", "http://id.loc.gov/ontologies/bibframe/contribution", "contrbn#{w_count}2#{count}") + stmts << contruct_stmt_uri_object("contrbn#{w_count}2#{count}", rdf_type_predicate, "http://id.loc.gov/ontologies/bibframe/Contribution") + stmts << contruct_stmt_uri_object("contrbn#{w_count}2#{count}", bf_agent_predicate, "agentn#{w_count}2#{count}") + stmts << contruct_stmt_uri_object("agentn#{w_count}2#{count}", rdf_type_predicate, bf_agent_type_object) + stmts << contruct_stmt_literal_object("agentn#{w_count}2#{count}", rdfs_label_predicate, artist["name"]) + stmts += build_role_stmts("agentn#{w_count}2#{count}", "role2#{w_count}#{count}", artist["role"]) count += 1 end stmts # w/out this line, building the graph throws an undefined method `graph_name=' error diff --git a/lib/qa/authorities/discogs/generic_authority.rb b/lib/qa/authorities/discogs/generic_authority.rb index 744b3620..e55f15be 100644 --- a/lib/qa/authorities/discogs/generic_authority.rb +++ b/lib/qa/authorities/discogs/generic_authority.rb @@ -1,16 +1,19 @@ require 'rdf' +require 'rdf/ntriples' module Qa::Authorities class Discogs::GenericAuthority < Base include WebServiceBase include Discogs::DiscogsTranslation class_attribute :discogs_secret, :discogs_key - attr_accessor :primary_artists + attr_accessor :primary_artists, :selected_format, :work_uri, :instance_uri # @param [String] subauthority to use def initialize(subauthority) @subauthority = subauthority self.primary_artists = [] + self.work_uri = "http://generic.uri/workn1" + self.instance_uri = "http://generic.uri/instn1" end # @param [String] the query @@ -35,12 +38,14 @@ def search(q, tc) # # @param [String] the Discogs id of the selected item # @param [Class] QA::TermsController - # @return results in requested format (supports: json, jsonld, n3) + # @return results in requested format (supports: json, jsonld, n3, ntriples) def find(id, tc) response = tc.params["subauthority"].include?("all") ? fetch_discogs_results(id) : json(find_url(id, tc.params["subauthority"])) + self.selected_format = tc.params["format"] return response if response["message"].present? return build_graph(response, format: :jsonld) if jsonld?(tc) return build_graph(response, format: :n3) if n3?(tc) + return build_graph(response, format: :ntriples) if ntriples?(tc) response end @@ -164,8 +169,12 @@ def n3?(tc) format(tc).casecmp?('n3') end + def ntriples?(tc) + format(tc).casecmp?('ntriples') + end + def graph_format?(tc) - jsonld?(tc) || n3?(tc) + jsonld?(tc) || n3?(tc) || ntriples?(tc) end end end diff --git a/lib/qa/authorities/linked_data/find_term.rb b/lib/qa/authorities/linked_data/find_term.rb index d8a0971f..5f6b767a 100644 --- a/lib/qa/authorities/linked_data/find_term.rb +++ b/lib/qa/authorities/linked_data/find_term.rb @@ -89,6 +89,7 @@ def perform_normalization return "{}" unless full_graph.size.positive? return full_graph.dump(:jsonld, standard_prefixes: true) if jsonld? return full_graph.dump(:n3, standard_prefixes: true) if n3? + return full_graph.dump(:ntriples, standard_prefixes: true) if ntriples? filter_graph extract_uri @@ -201,6 +202,10 @@ def n3? @format && @format.casecmp?('n3') end + def ntriples? + @format && @format.casecmp?('ntriples') + end + def performance_data? @performance_data == true && !jsonld? end diff --git a/spec/controllers/linked_data_terms_controller_spec.rb b/spec/controllers/linked_data_terms_controller_spec.rb index 4299b3f5..bd8dec73 100644 --- a/spec/controllers/linked_data_terms_controller_spec.rb +++ b/spec/controllers/linked_data_terms_controller_spec.rb @@ -434,6 +434,15 @@ expect(response.body).to start_with "@prefix" end end + + context 'and it was requested as ntriples' do + it 'succeeds and returns term data as ntriples content type' do + get :show, params: { id: '530369', vocab: 'OCLC_FAST', format: 'ntriples' } + expect(response).to be_successful + expect(response.content_type).to eq 'application/n-triples' + expect(response.body).to include(' "Cornell University"') + end + end end context 'when cors headers are enabled' do @@ -605,6 +614,15 @@ end end + context 'and it was requested as ntriples' do + it 'succeeds and returns term data as ntriples content type' do + get :fetch, params: { uri: 'http://id.worldcat.org/fast/530369', vocab: 'LOD_TERM_URI_PARAM_CONFIG', format: 'ntriples' } + expect(response).to be_successful + expect(response.content_type).to eq 'application/n-triples' + expect(response.body).to include(' "Cornell University"') + end + end + context 'blank nodes not included in predicates list' do before do stub_request(:get, 'http://localhost/test_default/term?uri=http://id.worldcat.org/fast/530369wbn') diff --git a/spec/controllers/terms_controller_spec.rb b/spec/controllers/terms_controller_spec.rb index 0aa4c634..2f2a4b04 100644 --- a/spec/controllers/terms_controller_spec.rb +++ b/spec/controllers/terms_controller_spec.rb @@ -240,5 +240,17 @@ def search(_arg1, _arg2) expect(response.body).to start_with "@prefix" end end + context "with request for ntriples" do + before do + stub_request(:get, "https://api.discogs.com/releases/3380671") + .to_return(status: 200, body: webmock_fixture("discogs-find-response-json.json")) + end + it 'Access-Control-Allow-Origin is not present' do + get :show, params: { vocab: "discogs", subauthority: "release", id: "3380671", format: 'ntriples' } + expect(response).to be_successful + expect(response.content_type).to eq 'application/n-triples' + expect(response.body).to include('_:agentn1 "Dexter Gordon"') + end + end end end diff --git a/spec/lib/authorities/discogs/generic_authority_spec.rb b/spec/lib/authorities/discogs/generic_authority_spec.rb index 2d1d4faf..a5667e53 100644 --- a/spec/lib/authorities/discogs/generic_authority_spec.rb +++ b/spec/lib/authorities/discogs/generic_authority_spec.rb @@ -158,6 +158,28 @@ end end + context "ntriples format and subauthority master" do + let(:tc) { instance_double(Qa::TermsController) } + let :results do + authority.find("950011", tc) + end + before do + allow(Qa::TermsController).to receive(:new).and_return(tc) + allow(tc).to receive(:params).and_return('format' => "ntriples", 'subauthority' => "master") + end + + it "returns the Discogs data converted to ntriples for a given id" do + expect(results).to include("https://www.discogs.com/Billie-Holiday-And-Her-Orchestra-Blue-Moon-You-Go-To-My-Head/master/950011") + expect(results).to include("Blue Moon / You Go To My Head") + expect(results).to include("Billie Holiday And Her Orchestra") + expect(results).to include("Haven Gillespie") + expect(results).to include("1952") + expect(results).to include("Jazz") + expect(results).to include("Barney Kessel") + expect(results).to include("Guitar") + end + end + context "json-ld format and subauthority all" do let(:tc) { instance_double(Qa::TermsController) } let :results do @@ -208,6 +230,31 @@ expect(results).to include("1952") end end + + context "ntriples format and subauthority all" do + let(:tc) { instance_double(Qa::TermsController) } + let :results do + authority.find("7143179", tc) + end + before do + allow(Qa::TermsController).to receive(:new).and_return(tc) + allow(tc).to receive(:params).and_return('format' => "ntriples", 'subauthority' => "all") + end + + it "returns the Discogs data converted to ntriples for a given id" do + expect(results).to include("https://www.discogs.com/Billie-Holiday-And-Her-Orchestra-Blue-Moon-You-Go-To-My-Head/release/7143179") + expect(results).to include("You Go To My Head") + expect(results).to include("Rodgers & Hart") + expect(results).to include("Ray Brown") + expect(results).to include("1952") + expect(results).to include("Single") + expect(results).to include("mono") + expect(results).to include("45 RPM") + expect(results).to include("Vinyl") + expect(results).to include("http://id.loc.gov/vocabulary/carriers/sd") + expect(results).to include("1952") + end + end end end