diff --git a/.gitignore b/.gitignore index 0722494..7c3b81d 100644 --- a/.gitignore +++ b/.gitignore @@ -24,4 +24,4 @@ /config/master.key .byebug_history -solr +/solr/* diff --git a/.lando.yml b/.lando.yml index f9cda7e..4b326e4 100644 --- a/.lando.yml +++ b/.lando.yml @@ -21,6 +21,12 @@ services: core: findingaids config: dir: "solr/solr_configs/pulfalight-production/conf" + pulmap: + type: solr:8.4 + portforward: true + core: pulmap + config: + dir: "solr/solr_configs/pulmap/conf" proxy: catalog_solr: - catalog.dev.solr.lndo.site:8983 @@ -28,3 +34,5 @@ proxy: - dpul.dev.solr.lndo.site:8983 findingaids_solr: - findingaids.dev.solr.lndo.site:8983 + pulmap: + - pulmap.dev.solr.lndo.site:8983 diff --git a/app/controllers/art_museum_controller.rb b/app/controllers/art_museum_controller.rb index d2d6ed4..38222e0 100644 --- a/app/controllers/art_museum_controller.rb +++ b/app/controllers/art_museum_controller.rb @@ -1,22 +1,10 @@ # frozen_string_literal: true -class ArtMuseumController < ApplicationController +class ArtMuseumController < ServiceController rescue_from ActionController::ParameterMissing, with: :show_query_errors - def show - @art_museum_query = ArtMuseum.new(query_terms: query_params) - render json: art_museum_query.our_response + def initialize + super + @service = ArtMuseum end - - private - - def query_params - params.require(:query) - end - - def show_query_errors(exception) - render json: { error: exception.message }, status: :bad_request - end - - attr_reader :art_museum_query end diff --git a/app/controllers/catalog_controller.rb b/app/controllers/catalog_controller.rb index 208917b..dd1010b 100644 --- a/app/controllers/catalog_controller.rb +++ b/app/controllers/catalog_controller.rb @@ -1,22 +1,10 @@ # frozen_string_literal: true -class CatalogController < ApplicationController +class CatalogController < ServiceController rescue_from ActionController::ParameterMissing, with: :show_query_errors - def show - @catalog_query = Catalog.new(query_terms: query_params) - render json: catalog_query.our_response + def initialize + super + @service = Catalog end - - private - - def query_params - params.require(:query) - end - - def show_query_errors(exception) - render json: { error: exception.message }, status: :bad_request - end - - attr_reader :catalog_query end diff --git a/app/controllers/dpul_controller.rb b/app/controllers/dpul_controller.rb index b159cb8..7c5633f 100644 --- a/app/controllers/dpul_controller.rb +++ b/app/controllers/dpul_controller.rb @@ -1,22 +1,10 @@ # frozen_string_literal: true -class DpulController < ApplicationController +class DpulController < ServiceController rescue_from ActionController::ParameterMissing, with: :show_query_errors - def show - @dpul_query = Dpul.new(query_terms: query_params) - render json: dpul_query.our_response + def initialize + super + @service = Dpul end - - private - - def query_params - params.require(:query) - end - - def show_query_errors(exception) - render json: { error: exception.message }, status: :bad_request - end - - attr_reader :dpul_query end diff --git a/app/controllers/findingaids_controller.rb b/app/controllers/findingaids_controller.rb index daab27d..72a0fa7 100644 --- a/app/controllers/findingaids_controller.rb +++ b/app/controllers/findingaids_controller.rb @@ -1,22 +1,10 @@ # frozen_string_literal: true -class FindingaidsController < ApplicationController +class FindingaidsController < ServiceController rescue_from ActionController::ParameterMissing, with: :show_query_errors - def show - @findingaids_query = Findingaids.new(query_terms: query_params) - render json: findingaids_query.our_response + def initialize + super + @service = Findingaids end - - private - - def query_params - params.require(:query) - end - - def show_query_errors(exception) - render json: { error: exception.message }, status: :bad_request - end - - attr_reader :findingaids_query end diff --git a/app/controllers/pulmap_controller.rb b/app/controllers/pulmap_controller.rb new file mode 100644 index 0000000..32d47fd --- /dev/null +++ b/app/controllers/pulmap_controller.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +class PulmapController < ServiceController + rescue_from ActionController::ParameterMissing, with: :show_query_errors + + def initialize + super + @service = Pulmap + end +end diff --git a/app/controllers/service_controller.rb b/app/controllers/service_controller.rb new file mode 100644 index 0000000..2b39cd6 --- /dev/null +++ b/app/controllers/service_controller.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class ServiceController < ApplicationController + def show + @query = service.new(query_terms: query_params) + + render json: query.our_response + end + + private + + attr_reader :query, :service + + def query_params + params.require(:query) + end + + def show_query_errors(exception) + render json: { error: exception.message }, status: :bad_request + end +end diff --git a/app/models/pulmap.rb b/app/models/pulmap.rb new file mode 100644 index 0000000..437ab71 --- /dev/null +++ b/app/models/pulmap.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +# This class is responsible for querying Findingaids (aka PULFAlight) +class Pulmap + include ActiveModel::API + include Parsed + include Solr + attr_reader :query_terms, :service, :service_response + + def initialize(query_terms:) + @query_terms = query_terms + @service = 'pulmap' + @service_response = solr_service_response(query_terms:) + end + + def solr_collection + 'pulmap' + end + + def solr_fields + %w[uuid dc_title_s dc_creator_sm dc_publisher_s dc_format_s dc_description_s dc_rights_s layer_geom_type_s] + end + + def solr_sort + 'score desc' + end + + def more_link + @service = 'maps' + super + end +end diff --git a/app/models/pulmap_document.rb b/app/models/pulmap_document.rb new file mode 100644 index 0000000..868bc77 --- /dev/null +++ b/app/models/pulmap_document.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +# This class is responsible for getting relevant +# metadata from Pulmap's JSON +class PulmapDocument < Document + private + + def id + json[:uuid] + end + + def url + "https://maps.princeton.edu/catalog/#{id}" + end + + def title + json[:dc_title_s] + end + + def creator + json[:dc_creator_sm]&.first + end + + def publisher + json[:dc_publisher_s] + end + + def type + json[:dc_format_s] + end + + def description + json[:dc_description_s] + end + + def doc_keys + [:rights, :layer_geom_type] + end + + def rights + json[:dc_rights_s] + end + + def layer_geom_type + json[:layer_geom_type_s] + end +end diff --git a/config/allsearch.yml b/config/allsearch.yml index 93e524b..2f0e97c 100644 --- a/config/allsearch.yml +++ b/config/allsearch.yml @@ -17,6 +17,12 @@ default: &default port: 8983 collection: "pulfalight-production" ssl: true + pulmap: + solr: + host: "lib-solr8-prod.princeton.edu" + port: 8983 + collection: "pulmap" + ssl: true development: <<: *default @@ -40,6 +46,13 @@ development: port: <%= ENV["lando_findingaids_solr_conn_port"] %> collection: "findingaids" ssl: false + + pulmap: + solr: + host: <%= ENV["lando_pulmap_solr_conn_host"] %> + port: <%= ENV["lando_pulmap_solr_conn_port"] %> + collection: "pulmap" + ssl: false staging: <<: *default diff --git a/config/routes.rb b/config/routes.rb index c3434d2..d49acc9 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -9,4 +9,5 @@ get '/search/catalog/', to: 'catalog#show', defaults: { format: 'json' } get '/search/dpul/', to: 'dpul#show', defaults: { format: 'json' } get '/search/findingaids/', to: 'findingaids#show', defaults: { format: 'json' } + get '/search/pulmap', to: 'pulmap#show', defaults: { format: 'json' } end diff --git a/spec/fixtures/files/solr/pulmap/scribner.json b/spec/fixtures/files/solr/pulmap/scribner.json new file mode 100644 index 0000000..be76df0 --- /dev/null +++ b/spec/fixtures/files/solr/pulmap/scribner.json @@ -0,0 +1,72 @@ +{ + "responseHeader":{ + "zkConnected":true, + "status":0, + "QTime":0, + "params":{ + "ps":"0", + "indent":"2", + "echoParams":"all", + "fl":"uuid,dc_title_s,dc_creator_sm,dc_publisher_s,dc_format_s,dc_description_s,dc_rights_s,layer_geom_type_s", + "publisher_qf":"\n dc_publisher_ti^5\n dc_creator_tmi\n ", + "subject_qf":"\n dc_subject_tmi\n dct_spatial_tmi\n ", + "_forwardedCount":"1", + "tie":"0.01", + "defType":"edismax", + "qf":"\n text^1\n dc_description_ti^2\n dc_creator_tmi^3\n dc_publisher_ti^3\n dct_isPartOf_tmi^4\n dc_subject_tmi^5\n dct_spatial_tmi^5\n dct_temporal_tmi^5\n dc_title_ti^6\n dc_rights_ti^7\n dct_provenance_ti^8\n layer_geom_type_ti^9\n layer_slug_ti^10\n dc_identifier_ti^10\n ", + "title_qf":"\n dc_title_ti^10\n dct_isPartOf_tmi\n ", + "wt":"json", + "mm":"1<-1 3<50% 6<90%", + "qs":"1", + "q.alt":"*:*", + "facet.field":["dct_isPartOf_sm", + "dct_provenance_s", + "dct_spatial_sm", + "dc_creator_sm", + "dc_format_s", + "dc_language_s", + "dc_publisher_s", + "dc_rights_s", + "dc_subject_sm", + "layer_geom_type_s", + "solr_year_i"], + "publisher_pf":"\n dc_publisher_ti^5\n dc_creator_tmi\n ", + "subject_pf":"\n dc_subject_tmi\n dct_spatial_tmi\n ", + "start":"0", + "sort":"score desc", + "rows":"3", + "q":"scribner", + "facet.limit":"10", + "spellcheck":"true", + "pf":"\n text^1\n dc_description_ti^2\n dc_creator_tmi^3\n dc_publisher_ti^3\n dct_isPartOf_tmi^4\n dc_subject_tmi^5\n dct_spatial_tmi^5\n dct_temporal_tmi^5\n dc_title_ti^6\n dc_rights_ti^7\n dct_provenance_ti^8\n layer_geom_type_ti^9\n layer_slug_ti^10\n dc_identifier_ti^10\n ", + "title_pf":"\n dc_title_ti^10\n dct_isPartOf_tmi\n ", + "facet.mincount":"1", + "facet":"false"}}, + "response":{"numFound":16,"start":0,"docs":[ + { + "dc_rights_s":"Public", + "dc_title_s":"Indiana.", + "dc_description_s":"Shows railroads and canals.; Compiled according to Census of 1880 and latest surveys.; From: Encyclopaedia Britannica, 9th ed. Vol. XII, plate VII. Scale approximately 1:2,000,000", + "dc_format_s":"JPEG", + "dc_publisher_s":"Scribner"}, + { + "uuid":"princeton-6682x6396", + "dc_title_s":"South America : wall-atlas", + "dc_rights_s":"Public", + "dc_description_s":"\"Card series.\" Relief shown by hachures and form lines. \"Entered according to Act of Congress in the year 1865 by Charles Scribner & Co. ...\" Inset: Profiles from west to east. Wall map. Scribner, Armstrong, & Co. flourished ca. 1871-1879. cf. Tooley's dictionary of mapmakers.", + "dc_creator_sm":["Guyot, A. (Arnold), 1807-1884"], + "dc_publisher_s":"New York : Published by Scribner, Armstrong & Co. ... [between 1871 and 1879].", + "layer_geom_type_s":"Image", + "dc_format_s":"TIFF"}, + { + "uuid":"princeton-2b88qf00b", + "dc_title_s":"Africa : wall-atlas", + "dc_rights_s":"Public", + "dc_description_s":"\"Card series.\" Relief shown by hachures and form lines. \"Entered according to Act of Congress in the year 1865 by Charles Scribner & Co. ...\" Insets: Profiles from north to south -- Profiles from east to west. Wall map. Scribner, Armstrong, & Co. flourished ca. 1871-1879. cf. Tooley's dictionary of mapmakers.", + "dc_creator_sm":["Guyot, A. (Arnold), 1807-1884"], + "dc_publisher_s":"New York : Scribner, Armstrong, & Co. [between 1871 and 1879].", + "layer_geom_type_s":"Image", + "dc_format_s":"TIFF"}] + }, + "spellcheck":{ + "suggestions":[]}} \ No newline at end of file diff --git a/spec/requests/pulmap_spec.rb b/spec/requests/pulmap_spec.rb new file mode 100644 index 0000000..a6f717a --- /dev/null +++ b/spec/requests/pulmap_spec.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'GET /search/pulmap' do + it 'returns json' do + stub_request(:get, 'https://lib-solr8-prod.princeton.edu:8983/solr/pulmap/select?facet=false&fl=uuid,dc_title_s,dc_creator_sm,dc_publisher_s,dc_format_s,dc_description_s,dc_rights_s,layer_geom_type_s&q=scribner&rows=3&sort=score%20desc') + .to_return(status: 200, body: file_fixture('solr/pulmap/scribner.json')) + get '/search/pulmap?query=scribner' + + expect(response).to be_successful + expect(response.content_type).to eq('application/json; charset=utf-8') + end + + context 'with a search term' do + before do + stub_request(:get, 'https://lib-solr8-prod.princeton.edu:8983/solr/pulmap/select?facet=false&fl=uuid,dc_title_s,dc_creator_sm,dc_publisher_s,dc_format_s,dc_description_s,dc_rights_s,layer_geom_type_s&q=scribner&rows=3&sort=score%20desc') + .to_return(status: 200, body: file_fixture('solr/pulmap/scribner.json')) + end + + # rubocop:disable Layout/LineLength + let(:expected_response) do + { number: 16, + more: 'https://maps.princeton.edu/catalog?q=scribner&search_field=all_fields', + records: [ + { title: 'South America : wall-atlas', + creator: 'Guyot, A. (Arnold), 1807-1884', + description: "\"Card series.\" Relief shown by hachures and form lines. \"Entered according to Act of Congress in the year 1865 by Charles Scribner & Co. ...\" Inset: Profiles from west to east. Wall map. Scribner, Armstrong, & Co. flourished ca. 1871-1879. cf. Tooley's dictionary of mapmakers.", + publisher: 'New York : Published by Scribner, Armstrong & Co. ... [between 1871 and 1879].', + id: 'princeton-6682x6396', + type: 'TIFF', + url: 'https://maps.princeton.edu/catalog/princeton-6682x6396', + other_fields: { + layer_geom_type: 'Image', + rights: 'Public' + } } + ] } + end + # rubocop:enable Layout/LineLength + + it 'can take a parameter' do + get '/search/pulmap?query=scribner' + + expect(response).to be_successful + response_body = JSON.parse(response.body, symbolize_names: true) + + expect(response_body.keys).to contain_exactly(:number, :more, :records) + expect(response_body[:number]).to eq(expected_response[:number]) + expect(response_body[:records].second.keys).to contain_exactly(:title, :creator, :description, + :publisher, :id, + :type, :url, + :other_fields) + + expect(response_body[:records].second).to match(expected_response[:records].first) + end + + it 'only returns the first three records' do + get '/search/pulmap?query=scribner' + + response_body = JSON.parse(response.body, symbolize_names: true) + + expect(response_body[:records].size).to eq(3) + end + end + + context 'without a search term' do + it 'returns a 422 unprocessable response' do + get '/search/pulmap?query=' + + expect(response).to be_bad_request + end + end +end