From dc49d091cb03cecdc3434b326d57c0b6f0466821 Mon Sep 17 00:00:00 2001 From: Jeremy Prevost Date: Tue, 14 Oct 2025 17:27:41 -0400 Subject: [PATCH 1/4] Remove fact panels Why are these changes being introduced: * We are moving to TACOS suggestions instead of fact panels * Fact panels was an initial implementation we later extracted into TACOS Relevant ticket(s): * https://mitlibraries.atlassian.net/browse/USE-65 Document any side effects to this change: * Not all fact panels will be replaced initially with TACOS suggestions --- README.md | 1 - app/assets/stylesheets/partials/_panels.scss | 11 -- app/controllers/fact_controller.rb | 27 --- app/helpers/record_helper.rb | 7 - app/helpers/results_helper.rb | 4 - app/models/fact_doi.rb | 44 ----- app/models/fact_isbn.rb | 51 ----- app/models/fact_issn.rb | 63 ------- app/models/fact_pmid.rb | 42 ----- app/views/fact/doi.html.erb | 31 --- app/views/fact/isbn.html.erb | 21 --- app/views/fact/issn.html.erb | 16 -- app/views/fact/pmid.html.erb | 21 --- app/views/record/_sidebar.html.erb | 9 - app/views/search/_doi.html.erb | 8 - app/views/search/_isbn.html.erb | 8 - app/views/search/_issn.html.erb | 8 - app/views/search/_pmid.html.erb | 8 - app/views/search/results.html.erb | 9 - app/views/search/results_geo.html.erb | 9 - config/routes.rb | 5 - test/controllers/fact_controller_test.rb | 188 ------------------- test/controllers/search_controller_test.rb | 173 +++-------------- test/models/fact_issn_test.rb | 54 ------ 24 files changed, 23 insertions(+), 795 deletions(-) delete mode 100644 app/controllers/fact_controller.rb delete mode 100644 app/models/fact_doi.rb delete mode 100644 app/models/fact_isbn.rb delete mode 100644 app/models/fact_issn.rb delete mode 100644 app/models/fact_pmid.rb delete mode 100644 app/views/fact/doi.html.erb delete mode 100644 app/views/fact/isbn.html.erb delete mode 100644 app/views/fact/issn.html.erb delete mode 100644 app/views/fact/pmid.html.erb delete mode 100644 app/views/search/_doi.html.erb delete mode 100644 app/views/search/_isbn.html.erb delete mode 100644 app/views/search/_issn.html.erb delete mode 100644 app/views/search/_pmid.html.erb delete mode 100644 test/controllers/fact_controller_test.rb delete mode 100644 test/models/fact_issn_test.rb diff --git a/README.md b/README.md index cc26966f..3aae88d1 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,6 @@ See `Optional Environment Variables` for more information. - `BOOLEAN_OPTIONS`: comma separated list of values to present to testers on instances where `BOOLEAN_PICKER` feature is enabled. - `BOOLEAN_PICKER`: feature to allow users to select their preferred boolean type. If set, feature is enabled. This feature is only intended for internal team testing and should never be enabled in production (mostly because the UI is a mess more than it would cause harm). -- `FACT_PANELS_ENABLED`: Comma separated list of enabled fact panels. See `/views/results.html.erb` for implemented panels/valid options. Leave unset to disable all. - `FILTER_ACCESS_TO_FILES`: The name to use instead of "Access to files" for that filter / aggregation. - `FILTER_CONTENT_TYPE`: The name to use instead of "Content type" for that filter / aggregation. - `FILTER_CONTRIBUTOR`: The name to use instead of "Contributor" for that filter / aggregation. diff --git a/app/assets/stylesheets/partials/_panels.scss b/app/assets/stylesheets/partials/_panels.scss index 2f497600..170b5205 100644 --- a/app/assets/stylesheets/partials/_panels.scss +++ b/app/assets/stylesheets/partials/_panels.scss @@ -62,17 +62,6 @@ } } -.fact { - .panel { - margin-top: 0; - - .panel-heading { - margin-top: 0; - padding-top: 16.8px; - } - } -} - .ask-us { margin-top: 3rem; a { diff --git a/app/controllers/fact_controller.rb b/app/controllers/fact_controller.rb deleted file mode 100644 index 5bd4bf89..00000000 --- a/app/controllers/fact_controller.rb +++ /dev/null @@ -1,27 +0,0 @@ -class FactController < ApplicationController - layout false - - def doi - return unless params[:doi].present? - - @json = FactDoi.new.info(params[:doi]) - end - - def issn - return unless params[:issn].present? - - @json = FactIssn.new.info(params[:issn]) - end - - def isbn - return unless params[:isbn].present? - - @json = FactIsbn.new.info(params[:isbn]) - end - - def pmid - return unless params[:pmid].present? - - @json = FactPmid.new.info(params[:pmid].split.last) - end -end diff --git a/app/helpers/record_helper.rb b/app/helpers/record_helper.rb index 142ef5d6..d4b70033 100644 --- a/app/helpers/record_helper.rb +++ b/app/helpers/record_helper.rb @@ -1,11 +1,4 @@ module RecordHelper - def doi(metadata) - dois = metadata['identifiers']&.select { |id| id['kind'].downcase == 'doi' } - return unless dois.present? - - dois.first['value'] - end - def date_parse(date) return unless date.present? diff --git a/app/helpers/results_helper.rb b/app/helpers/results_helper.rb index 54e9a585..85b4860d 100644 --- a/app/helpers/results_helper.rb +++ b/app/helpers/results_helper.rb @@ -1,8 +1,4 @@ module ResultsHelper - def fact_enabled?(fact_type) - ENV.fetch('FACT_PANELS_ENABLED', false).split(',').include?(fact_type) - end - def results_summary(hits) hits.to_i >= 10_000 ? '10,000+ results' : "#{number_with_delimiter(hits)} results" end diff --git a/app/models/fact_doi.rb b/app/models/fact_doi.rb deleted file mode 100644 index 563ca1b8..00000000 --- a/app/models/fact_doi.rb +++ /dev/null @@ -1,44 +0,0 @@ -class FactDoi - def info(doi) - external_data = fetch(doi) - return if external_data == 'Error' - - metadata = extract_metadata(external_data) - metadata[:doi] = doi - metadata[:link_resolver_url] = link_resolver_url(metadata) - metadata - end - - def extract_metadata(external_data) - { - genre: external_data['genre'], - title: external_data['title'], - year: external_data['year'], - publisher: external_data['publisher'], - oa: external_data['is_oa'], - oa_status: external_data['oa_status'], - best_oa_location: external_data['best_oa_location'], - journal_issns: external_data['journal_issns'], - journal_name: external_data['journal_name'] - } - end - - def url(doi) - "https://api.unpaywall.org/v2/#{doi}?email=timdex@mit.edu" - end - - def fetch(doi) - resp = HTTP.headers(accept: 'application/json').get(url(doi)) - if resp.status == 200 - JSON.parse(resp.to_s) - else - Rails.logger.debug("Fact lookup error. DOI #{doi} detected but unpaywall returned no data") - Rails.logger.debug("URL: #{url(doi)}") - 'Error' - end - end - - def link_resolver_url(metadata) - "https://mit.primo.exlibrisgroup.com/discovery/openurl?institution=01MIT_INST&rfr_id=info:sid/mit.timdex.ui&rft.atitle=#{metadata[:title]}&rft.date=#{metadata[:year]}&rft.genre=#{metadata[:genre]}&rft.jtitle=#{metadata[:journal_name]}&rft_id=info:doi/#{metadata[:doi]}&vid=01MIT_INST:MIT" - end -end diff --git a/app/models/fact_isbn.rb b/app/models/fact_isbn.rb deleted file mode 100644 index 46596786..00000000 --- a/app/models/fact_isbn.rb +++ /dev/null @@ -1,51 +0,0 @@ -class FactIsbn - def info(isbn) - json = fetch_isbn(isbn) - return if json == 'Error' - - { - title: json['title'], - publish_date: json['publish_date'], - publishers: json['publishers'], - author_names: fetch_authors(json), - openurl: link_resolver_url(isbn) - } - end - - def base_url - 'https://openlibrary.org' - end - - def fetch_isbn(isbn) - url = [base_url, "/isbn/#{isbn}.json"].join - parse_response(url) - end - - def fetch_authors(isbn_json) - return unless isbn_json['authors'] - - authors = isbn_json['authors'].map { |a| a['key'] } - author_names = authors.map do |author| - url = [base_url, author, '.json'].join - json = parse_response(url) - json['name'] - end - author_names.join(' ; ') - end - - def parse_response(url) - resp = HTTP.headers(accept: 'application/json', 'Content-Type': 'application/json').follow.get(url) - - if resp.status == 200 - JSON.parse(resp.to_s) - else - Rails.logger.debug('Fact lookup error: openlibrary returned no data') - Rails.logger.debug("URL: #{url}") - 'Error' - end - end - - def link_resolver_url(isbn) - "https://mit.primo.exlibrisgroup.com/discovery/openurl?institution=01MIT_INST&vid=01MIT_INST:MIT&rft.isbn=#{isbn}" - end -end diff --git a/app/models/fact_issn.rb b/app/models/fact_issn.rb deleted file mode 100644 index e8431660..00000000 --- a/app/models/fact_issn.rb +++ /dev/null @@ -1,63 +0,0 @@ -class FactIssn - def info(issn) - return unless validate(issn) - - json = fetch(issn) - return if json == 'Error' - - metadata = extract_metadata(json) - metadata[:openurl] = openurl(issn) - metadata - end - - def extract_metadata(response) - { - title: response['message']['title'], - publisher: response['message']['publisher'] - } - end - - def url(issn) - "https://api.crossref.org/journals/#{issn}" - end - - def fetch(issn) - resp = HTTP.headers(accept: 'application/json').get(url(issn)) - if resp.status == 200 - JSON.parse(resp.to_s) - else - Rails.logger.debug("ISSN Lookup error. ISSN #{issn} detected but crossref returned no data") - Rails.logger.debug("URL: #{url(issn)}") - 'Error' - end - end - - def openurl(issn) - "https://mit.primo.exlibrisgroup.com/discovery/openurl?institution=01MIT_INST&rfr_id=info:sid/mit.timdex.ui&rft.issn=#{issn}&vid=01MIT_INST:MIT" - end - - def validate(candidate) - # This model is only called when the regex for an ISSN has indicated an ISSN - # of sufficient format is present - but the regex does not attempt to - # validate that the check digit in the ISSN spec is correct. This method - # does that calculation, so we can avoid sending nonsense requests to - # CrossRef or the Primo API for facially-valid ISSNs that actually are not, - # like "2015-2019". - # - # The algorithm is defined at - # https://datatracker.ietf.org/doc/html/rfc3044#section-2.2 - # An example calculation is shared at - # https://en.wikipedia.org/wiki/International_Standard_Serial_Number#Code_format - digits = candidate.gsub('-', '').chars[..6] - check_digit = candidate.last.downcase - sum = 0 - digits.each_with_index do |digit, idx| - sum += digit.to_i * (8 - idx.to_i) - end - actual_digit = 11 - sum.modulo(11) - actual_digit = 'x' if actual_digit == 10 - return true if actual_digit.to_s == check_digit.to_s - - false - end -end diff --git a/app/models/fact_pmid.rb b/app/models/fact_pmid.rb deleted file mode 100644 index dc9a7641..00000000 --- a/app/models/fact_pmid.rb +++ /dev/null @@ -1,42 +0,0 @@ -class FactPmid - def info(pmid) - xml = fetch(pmid) - return if xml == 'Error' - - data = extract_data(xml) - - if data.reject { |_k, v| v.empty? }.present? - data - else - Rails.logger.debug("Fact lookup error. PMID #{pmid} detected but ncbi returned no data") - nil - end - end - - def extract_data(xml) - { - article_title: xml.xpath('//ArticleTitle').text, - journal_title: xml.xpath('//Journal/Title').text, - journal_volume: xml.xpath('//Journal/JournalIssue/Volume').text, - journal_year: xml.xpath('//Journal/JournalIssue/PubDate/Year').text, - pages: xml.xpath('//Article/Pagination').text, - status: xml.xpath('//PublicationStatus').text - } - end - - def url(pmid) - "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&id=#{pmid}&retmode=xml" - end - - def fetch(pmid) - resp = HTTP.headers(accept: 'application/xml').get(url(pmid)) - - if resp.status == 200 - Nokogiri::XML(resp.to_s) - else - Rails.logger.debug("Fact lookup error. PMID #{pmid} detected but ncbi an error status") - Rails.logger.debug("URL: #{url(pmid)}") - 'Error' - end - end -end diff --git a/app/views/fact/doi.html.erb b/app/views/fact/doi.html.erb deleted file mode 100644 index 78baa8ca..00000000 --- a/app/views/fact/doi.html.erb +++ /dev/null @@ -1,31 +0,0 @@ -<% return unless @json.present? %> - -
- <% unless params[:slim].present? %> -
- <%= @json[:title] %>
-
- <% end %> - -
- In: <%= @json[:journal_name] %>, <%= @json[:year] %> - -
    -
  • - Open Access: - <% if @json[:oa] %> - <%= @json[:oa_status] %> - <% else %> - unknown - <% end %> -
  • -
  • Publisher: <%= @json[:publisher] %>
  • - - <% if @json[:oa] %> -
  • <%= link_to('Open Access Link', @json[:best_oa_location]["url"]) %> - <% end %> - -
  • <%= link_to('Check MIT Subscription Access', @json[:link_resolver_url]) %> -
-
-
diff --git a/app/views/fact/isbn.html.erb b/app/views/fact/isbn.html.erb deleted file mode 100644 index 92e0f69b..00000000 --- a/app/views/fact/isbn.html.erb +++ /dev/null @@ -1,21 +0,0 @@ -<% return unless @json.present? %> - -
-
- <%= link_to @json[:title], @json[:openurl] %> -
- -
-
    - <% if @json[:author_names].present? %> -
  • <%= @json[:author_names] %>
  • - <% end %> -
  • <%= @json[:publish_date] %> (<%= @json[:publishers].join('; ') %>)
  • -
-
- - -
diff --git a/app/views/fact/issn.html.erb b/app/views/fact/issn.html.erb deleted file mode 100644 index 01e608dc..00000000 --- a/app/views/fact/issn.html.erb +++ /dev/null @@ -1,16 +0,0 @@ -<% return unless @json.present? %> - -
-
- <%= link_to @json[:title], @json[:openurl] %> -
- -
-

Publisher: <%= @json[:publisher] %>

-
- - -
diff --git a/app/views/fact/pmid.html.erb b/app/views/fact/pmid.html.erb deleted file mode 100644 index 441043d4..00000000 --- a/app/views/fact/pmid.html.erb +++ /dev/null @@ -1,21 +0,0 @@ -<% return unless @json.present? %> - -
-
- <%= @json[:article_title] %> -
- -
-
    -
  • Journal: <%= @json[:journal_title] %>
  • -
  • Volume: <%= @json[:journal_volume] %>
  • -
  • Year: <%= @json[:journal_year] %>
  • -
  • Pages: <%= @json[:pages] %>
  • -
  • Publication Status: <%= @json[:status] %>
  • -
-
- - -
diff --git a/app/views/record/_sidebar.html.erb b/app/views/record/_sidebar.html.erb index 45b0584c..51e0c8fe 100644 --- a/app/views/record/_sidebar.html.erb +++ b/app/views/record/_sidebar.html.erb @@ -3,15 +3,6 @@ <% else %>