From 84391c8e8811f95b8069b9dce82cb014e56d36f1 Mon Sep 17 00:00:00 2001 From: Jessie Keck Date: Fri, 20 Nov 2020 16:38:52 -0800 Subject: [PATCH 1/2] Add an isbn attribute to the MarcRecord class and add the MARC 020 or to it. --- app/models/upload.rb | 9 ++++++++- db/migrate/20201120180608_add_isbn_to_marc_record.rb | 6 ++++++ db/schema.rb | 4 +++- 3 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20201120180608_add_isbn_to_marc_record.rb diff --git a/app/models/upload.rb b/app/models/upload.rb index 2368d806..1936d77c 100644 --- a/app/models/upload.rb +++ b/app/models/upload.rb @@ -69,7 +69,8 @@ def extract_marc_record_metadata(file, service) marc001: record['001']&.value, file_id: file.id, upload_id: id, - marc: record + marc: record, + isbn: record_isbn(record) ) out.checksum ||= Digest::MD5.hexdigest(record.to_xml.to_s) @@ -77,4 +78,10 @@ def extract_marc_record_metadata(file, service) yield out end end + + def record_isbn(record) + marc020 = record['020'] || {} + + (marc020['a'] || marc020['z'])&.[](/^x?\d+/) + end end diff --git a/db/migrate/20201120180608_add_isbn_to_marc_record.rb b/db/migrate/20201120180608_add_isbn_to_marc_record.rb new file mode 100644 index 00000000..d0ab5029 --- /dev/null +++ b/db/migrate/20201120180608_add_isbn_to_marc_record.rb @@ -0,0 +1,6 @@ +class AddIsbnToMarcRecord < ActiveRecord::Migration[6.0] + def change + add_column :marc_records, :isbn, :string + add_index :marc_records, :isbn + end +end diff --git a/db/schema.rb b/db/schema.rb index e822aff0..cddcc80f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2020_11_20_154520) do +ActiveRecord::Schema.define(version: 2020_11_20_180608) do create_table "active_storage_attachments", force: :cascade do |t| t.string "name", null: false @@ -150,8 +150,10 @@ t.bigint "length" t.bigint "index" t.string "checksum" + t.string "isbn" t.index ["file_id", "marc001"], name: "index_marc_records_on_file_id_and_marc001" t.index ["file_id"], name: "index_marc_records_on_file_id" + t.index ["isbn"], name: "index_marc_records_on_isbn" t.index ["upload_id", "marc001"], name: "index_marc_records_on_upload_id_and_marc001" t.index ["upload_id"], name: "index_marc_records_on_upload_id" end From 826203c303065039130689747b3690f0cba940dc Mon Sep 17 00:00:00 2001 From: Jessie Keck Date: Fri, 20 Nov 2020 16:39:50 -0800 Subject: [PATCH 2/2] Add a simple UI/API to search for MARC records by ISBN and return a response of those records grouped by organization --- app/controllers/lookup_controller.rb | 26 +++++++++++++++++++++++ app/views/lookup/index.html.erb | 31 ++++++++++++++++++++++++++++ app/views/lookup/index.json.jbuilder | 11 ++++++++++ config/routes.rb | 1 + 4 files changed, 69 insertions(+) create mode 100644 app/controllers/lookup_controller.rb create mode 100644 app/views/lookup/index.html.erb create mode 100644 app/views/lookup/index.json.jbuilder diff --git a/app/controllers/lookup_controller.rb b/app/controllers/lookup_controller.rb new file mode 100644 index 00000000..35674b5c --- /dev/null +++ b/app/controllers/lookup_controller.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +## +# Controller to lookup MARC records based on standard numbers (e.g. ISBN) +class LookupController < ApplicationController + skip_authorization_check + + def index + return {} if index_params[:isbn].blank? + + @response = grouped_marc_records + end + + def index_params + params.permit(:isbn) + end + helper_method :index_params + + private + + def grouped_marc_records + MarcRecord.includes(:organization).where(isbn: index_params[:isbn]).group_by(&:organization).select do |org, _| + can? :read, org + end + end +end diff --git a/app/views/lookup/index.html.erb b/app/views/lookup/index.html.erb new file mode 100644 index 00000000..182c7af3 --- /dev/null +++ b/app/views/lookup/index.html.erb @@ -0,0 +1,31 @@ +
+
+

Marc Records

+
+ <%= link_to "view as JSON", url_for(index_params.merge(format: :json)) %> + + + + + + + + + + + <% @response.each do |organization, marc_records| %> + + + + + <% marc_records.each do |marc_record| %> + + + + + + <% end %> + <% end %> + +
marc001StreamDownload
<%= organization.name %>
<%= marc_record.marc001 %><%= link_to(marc_record.stream.display_name, organization_stream_path(organization, marc_record.stream)) %><%= link_to('marc21', marc21_organization_marc_record_url(organization, marc_record)) %>, <%= link_to('marcxml', marcxml_organization_marc_record_url(organization, marc_record)) %>
+
diff --git a/app/views/lookup/index.json.jbuilder b/app/views/lookup/index.json.jbuilder new file mode 100644 index 00000000..a4b18fe9 --- /dev/null +++ b/app/views/lookup/index.json.jbuilder @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +json.total @response&.values&.sum(&:count) || 0 +json.isbn index_params[:isbn] +json.organizations @response do |organization, records| + json.extract! organization, :id, :name, :slug + json.records records do |record| + json.extract! record, :id, :marc001, :bytecount, :length, :checksum + json.url organization_marc_record_url(record.organization, record) + end +end diff --git a/config/routes.rb b/config/routes.rb index 4735ed77..b7be6b3c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -6,6 +6,7 @@ get '/documentation/:id', to: 'pages#show', as: :pages get '/api', to: 'pages#api' + resources :lookup, only: :index get 'contact_emails/confirm/:token', to: 'contact_emails#confirm', as: :contact_email_confirmation