Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix citations #428

Merged
merged 7 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.4.2
2.4.3
10 changes: 7 additions & 3 deletions lib/generators/trln_argon/install_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,18 @@ def inject_local_env_loader
end
end

# rubocop:disable Layout/LineLength
def inject_into_dev_env
return if IO.read('config/environments/development.rb').include?('BetterErrors')
insert_into_file 'config/environments/development.rb', after: 'Rails.application.configure do' do
"\n\n require 'socket'\n\n local_ip = IPSocket.getaddress(Socket.gethostname)\n\n BetterErrors::Middleware.allow_ip! local_ip if defined? BetterErrors && Rails.env == :development\n"
"\n\n require 'socket'\n" \
" begin\n" \
" local_ip = IPSocket.getaddress(Socket.gethostname)\n" \
" rescue\n" \
" local_ip = \"127.0.0.1\"\n" \
" end\n" \
" BetterErrors::Middleware.allow_ip! local_ip if defined?(BetterErrors) && Rails.env.development?\n"
end
end
# rubocop:enable Layout/LineLength

def inject_catalog_controller_overrides
return if IO.read('config/application.rb').include?('local_env.yml')
Expand Down
2 changes: 1 addition & 1 deletion lib/trln_argon/hathitrust_controller_behavior.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def render_hathitrust_partial_to_string(full_text_url)
render_to_string('hathitrust/show',
locals: { hathitrust_argon_url_hash:
hathitrust_argon_url_hash(full_text_url) },
layout: false)
layout: false).gsub(/<!--.*?-->/m, '')
end

def hathitrust_argon_url_hash(full_text_url)
Expand Down
11 changes: 7 additions & 4 deletions lib/trln_argon/internet_archive_controller_behavior.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,13 @@ def key_ia_id_pairs(ia_ids)
end

def render_ia_partial_to_string(full_text_url)
render_to_string('internet_archive/show',
locals: { internet_archive_argon_url_hash:
ia_argon_url_hash(full_text_url) },
layout: false)
render_to_string(
'internet_archive/show',
locals: {
internet_archive_argon_url_hash: ia_argon_url_hash(full_text_url)
},
layout: false
).gsub(/<!--.*?-->/m, '')
end

def ia_argon_url_hash(full_text_url)
Expand Down
26 changes: 21 additions & 5 deletions lib/trln_argon/solr_document/citation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -94,15 +94,31 @@ def parse_authors_and_editors(docvalue)
end

def convert_to_bibtex_format(input)
identifier = input.detect { |key, _| key == 'id' }[1]
entry_type = input.detect { |key, _| key == 'type' }[1].split(',').first.strip.downcase
entry_type = map_entry_type(entry_type)
identifier = input.detect { |key, _| key == 'id' }&.last
entry_type = determine_entry_type(input)
# The bibtex string should look like this
# "@book{id, author = {Author, A.}, title = {Title}, journal = {Journal}, year = {2020}}"
formatted_pairs = input.reject { |key, _| ['id', 'type'].include?(key) }.map do |key, value|
formatted_pairs = generate_formatted_pairs(input)
"@#{entry_type}{#{identifier}, #{formatted_pairs.join(', ')}}"
rescue StandardError => e
puts "An error occurred: #{e.message}"
'No citations for this item.'
end

def determine_entry_type(input)
entry_type_value = input.detect { |key, _| key == 'type' }&.last
entry_type = if entry_type_value.to_s.strip.empty?
'book'
else
entry_type_value
end
map_entry_type(entry_type)
end

def generate_formatted_pairs(input)
input.reject { |key, _| ['id', 'type'].include?(key) }.map do |key, value|
"#{key} = {#{value}}"
end
"@#{entry_type}{#{identifier}, #{formatted_pairs.join(', ')}}"
end

def process_citations(bibliography, citation_hash)
Expand Down
59 changes: 59 additions & 0 deletions spec/lib/trln_argon/solr_document_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -931,4 +931,63 @@ class SolrDocumentTestClass
end
end
end

context 'when an error occurs during citation generation' do
describe '#generate_citation' do
let(:document) do
SolrDocument.new(
# Missing required fields
title: 'An Incomplete Title'
)
end

before do
allow(document).to receive(:generate_formatted_pairs).and_raise(StandardError)
end

it 'prints a server error message' do
expect { document.send(:convert_to_bibtex_format, document) }
.to output(a_string_starting_with('An error occurred:')).to_stdout
end

it 'returns a fallback message' do
expect(document.send(:convert_to_bibtex_format, document)).to eq('No citations for this item.')
end
end
end

describe '#determine_entry_type' do
let(:document) { SolrDocument.new }

context 'when type is present' do
it 'returns the correct entry type' do
input = { 'type' => 'Journal, Magazine, or Periodical' }
expect(document.send(:determine_entry_type, input)).to eq('article-journal')
end
end

context 'when type is present but empty' do
it 'defaults to book' do
input = { 'type' => '' }
expect(document.send(:determine_entry_type, input)).to eq('book')
end
end

context 'when type is not present' do
it 'defaults to book' do
input = {}
expect(document.send(:determine_entry_type, input)).to eq('book')
end
end
end

describe '#generate_formatted_pairs' do
let(:document) { SolrDocument.new }

it 'formats input pairs, excluding id and type' do
input = { 'id' => '123', 'type' => 'article', 'author' => 'Doe, John', 'title' => 'An Interesting Article' }
expected_output = ['author = {Doe, John}', 'title = {An Interesting Article}']
expect(document.send(:generate_formatted_pairs, input)).to eq(expected_output)
end
end
end
7 changes: 6 additions & 1 deletion spec/rails_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@

RSpec.configure do |config|
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# Update fixture paths configuration to be compatible with Rails 7.1 and later.
# Rails now expects `fixture_paths` to be an array rather than a singular string.
# This change is documented in the Rails 7.1 release notes:
# https://guides.rubyonrails.org/7_1_release_notes.html
# https://apidock.com/rails/v7.1.3.2/ActiveSupport/TestCase/fixture_paths%3D/class
config.fixture_paths = ["#{::Rails.root}/spec/fixtures"]

# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
Expand Down
6 changes: 3 additions & 3 deletions trln_argon.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Gem::Specification.new do |s|

s.files = Dir['{app,config,db,lib}/**/*', 'MIT-LICENSE', 'Rakefile', 'README.md']

s.add_dependency 'rails', '~> 7'
s.add_dependency 'rails', '~> 7.1'
s.add_dependency 'blacklight', '~> 7.0'
s.add_dependency 'blacklight_advanced_search', '~> 8.0.0.alpha2'
s.add_dependency 'blacklight-hierarchy', '~> 6.3'
Expand All @@ -36,7 +36,7 @@ Gem::Specification.new do |s|
s.add_dependency 'csl-styles', '~> 1.0'
s.add_dependency 'bibtex-ruby', '>= 4.4.6', '< 7'

s.add_development_dependency 'rspec-rails', '~> 5'
s.add_development_dependency 'rspec-rails', '~> 6'
s.add_development_dependency 'capybara', '~> 3.29'
s.add_development_dependency 'pry', '~> 0.14'
s.add_development_dependency 'rubocop', '~> 1.0'
Expand All @@ -52,7 +52,7 @@ Gem::Specification.new do |s|

# Conditionally constrain nokogiri & sqlite3 to versions that still work with Ruby 2.7
# TODO: remove when we are all using Ruby 3+.
if Gem::Requirement.new('< 3.0').satisfied_by?(Gem::Version.new(RUBY_VERSION))
if Gem::Requirement.new('< 3.1').satisfied_by?(Gem::Version.new(RUBY_VERSION))
s.add_dependency 'nokogiri', '< 1.16'
s.add_dependency 'sqlite3', '< 1.7'
end
Expand Down
Loading