Skip to content

Commit 9394f8a

Browse files
committed
FOLIOSYNC-12 create HyacinthSynchronizer class to handle downloading and syncing logic
1 parent b95e97a commit 9394f8a

2 files changed

Lines changed: 148 additions & 20 deletions

File tree

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# frozen_string_literal: true
2+
3+
module FolioSync
4+
module FolioToHyacinth
5+
class HyacinthSynchronizer
6+
attr_reader :downloading_errors, :syncing_errors
7+
8+
def initialize
9+
# @logger = Logger.new($stdout)
10+
end
11+
12+
# Performs MARC downloads and syncs resources to Hyacinth
13+
# @param [Integer] last_x_hours Records newer than this are synced.
14+
def download_and_sync_folio_to_hyacinth_records(last_x_hours)
15+
download_marc_from_folio(last_x_hours)
16+
prepare_hyacinth_records
17+
end
18+
19+
def download_marc_from_folio(last_x_hours)
20+
downloader = FolioSync::FolioToHyacinth::MarcDownloader.new
21+
downloader.download_965hyacinth_marc_records(last_x_hours)
22+
23+
return if downloader.downloading_errors.blank?
24+
25+
puts "Error downloading MARC records from FOLIO: #{downloader.downloading_errors}"
26+
@downloading_errors = downloader.downloading_errors
27+
end
28+
29+
def prepare_hyacinth_records
30+
marc_files = Dir.glob(downloaded_marc_files_path)
31+
puts "Processing #{marc_files.count} MARC files"
32+
33+
marc_files.each do |marc_file_path|
34+
process_marc_file(marc_file_path)
35+
end
36+
end
37+
38+
private
39+
40+
def downloaded_marc_files_path
41+
"#{Rails.configuration.folio_to_hyacinth[:download_directory]}/*.mrc"
42+
end
43+
44+
def process_marc_file(marc_file_path)
45+
folio_hrid = extract_hrid_from_filename(marc_file_path)
46+
hyacinth_results = fetch_hyacinth_results(marc_file_path)
47+
puts "Found #{hyacinth_results.length} Hyacinth records for FOLIO HRID #{folio_hrid}"
48+
49+
case hyacinth_results.length
50+
when 0
51+
create_new_hyacinth_record(marc_file_path, folio_hrid)
52+
when 1
53+
update_existing_hyacinth_record(marc_file_path, hyacinth_results.first, folio_hrid)
54+
else
55+
handle_multiple_records_error(folio_hrid)
56+
end
57+
rescue StandardError => e
58+
puts "Failed to process #{folio_hrid}: #{e.message}"
59+
@syncing_errors << "Error processing #{folio_hrid}: #{e.message}"
60+
end
61+
62+
def extract_hrid_from_filename(marc_file_path)
63+
File.basename(marc_file_path, '.mrc')
64+
end
65+
66+
def create_new_hyacinth_record(marc_file_path, folio_hrid)
67+
puts "Creating new Hyacinth record for #{folio_hrid}"
68+
69+
new_record = FolioToHyacinthRecord.new(marc_file_path)
70+
response = FolioSync::Hyacinth::Client.instance.create_new_record(
71+
new_record.digital_object_data,
72+
publish: true
73+
)
74+
75+
puts "Created record for #{folio_hrid}: #{response.inspect}"
76+
response
77+
end
78+
79+
def update_existing_hyacinth_record(marc_file_path, existing_record, folio_hrid)
80+
puts "Updating existing Hyacinth record for #{folio_hrid}"
81+
82+
preserved_data = { 'identifiers' => existing_record['identifiers'] }
83+
updated_record = FolioToHyacinthRecord.new(marc_file_path, preserved_data)
84+
85+
response = FolioSync::Hyacinth::Client.instance.update_existing_record(
86+
existing_record['pid'],
87+
updated_record.digital_object_data,
88+
publish: true
89+
)
90+
91+
puts "Updated record #{existing_record['pid']}: #{response.inspect}"
92+
response
93+
end
94+
95+
def handle_multiple_records_error(folio_hrid)
96+
error_message = "Multiple Hyacinth records found for FOLIO HRID #{folio_hrid}"
97+
puts error_message
98+
@syncing_errors << error_message
99+
end
100+
101+
def fetch_hyacinth_results(marc_file_path)
102+
folio_hrid = File.basename(marc_file_path, '.mrc')
103+
potential_clio_identifier = "clio#{folio_hrid}"
104+
client = FolioSync::Hyacinth::Client.instance
105+
client.find_by_identifier(potential_clio_identifier,
106+
{ f: { digital_object_type_display_label_sim: ['Item'] } })
107+
end
108+
end
109+
end
110+
end

lib/tasks/hyacinth_sync.rake

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,32 @@
33
namespace :folio_sync do
44
namespace :folio_to_hyacinth do
55
task run: :environment do
6-
modified_since = ENV['modified_since']
7-
modified_since_num =
8-
if modified_since && !modified_since.strip.empty?
9-
begin
10-
Integer(modified_since)
11-
rescue ArgumentError
12-
puts 'Error: modified_since must be an integer (number of hours).'
13-
exit 1
14-
end
15-
end
16-
17-
downloader = FolioSync::FolioToHyacinth::MarcDownloader.new
18-
downloader.download_965hyacinth_marc_records(modified_since_num)
19-
20-
if downloader.downloading_errors.present?
21-
puts "Errors encountered during MARC download: #{downloader.downloading_errors}"
22-
exit 1
23-
end
6+
puts 'Starting Folio to Hyacinth sync task...'
7+
synchronizer = FolioSync::FolioToHyacinth::HyacinthSynchronizer.new
8+
synchronizer.download_and_sync_folio_to_hyacinth_records(24)
249
end
2510

11+
# task run: :environment do
12+
# modified_since = ENV['modified_since']
13+
# modified_since_num =
14+
# if modified_since && !modified_since.strip.empty?
15+
# begin
16+
# Integer(modified_since)
17+
# rescue ArgumentError
18+
# puts 'Error: modified_since must be an integer (number of hours).'
19+
# exit 1
20+
# end
21+
# end
22+
23+
# downloader = FolioSync::FolioToHyacinth::MarcDownloader.new
24+
# downloader.download_965hyacinth_marc_records(modified_since_num)
25+
26+
# if downloader.downloading_errors.present?
27+
# puts "Errors encountered during MARC download: #{downloader.downloading_errors}"
28+
# exit 1
29+
# end
30+
# end
31+
2632
task download_single_file: :environment do
2733
FolioSync::Rake::EnvValidator.validate!(
2834
['hrid'],
@@ -62,10 +68,14 @@ namespace :folio_sync do
6268
pid = results.first['pid']
6369
puts "Found 1 record with pid: #{pid}."
6470

71+
puts results.first.inspect
72+
6573
# Get only the data needed for update
6674
preserved_data = { 'identifiers' => results.first['identifiers'] }
6775
updated_record = FolioToHyacinthRecord.new(marc_file_path, preserved_data)
6876
puts "Updated record digital object data: #{updated_record.digital_object_data}"
77+
78+
# return
6979
response = client.update_existing_record(pid, updated_record.digital_object_data, publish: true)
7080
puts "Response from Hyacinth when updating record #{pid}: #{response.inspect}"
7181
else
@@ -91,7 +101,7 @@ namespace :folio_sync do
91101
end
92102

93103
# Add 965p field with value academic_commons, ensure 965$a is set to 965hyacinth
94-
marc_record.append(MARC::DataField.new('965', ' ', ' ', ['a', '965hyacinth'], ['p', 'academic_commons'], ['p', 'test']))
104+
marc_record.append(MARC::DataField.new('965', ' ', ' ', ['a', '965hyacinth'], ['p', 'Test']))
95105
puts "Modified MARC record with new 965 field: #{marc_record.inspect}"
96106

97107
new_filepath = Rails.root.join(Rails.configuration.folio_to_hyacinth[:download_directory], 'modified_marc.mrc')
@@ -100,7 +110,15 @@ namespace :folio_sync do
100110
writer.write(marc_record)
101111
writer.close
102112
end
103-
puts "Final MARC record: #{marc_record.inspect}"
113+
# puts "Final MARC record: #{marc_record}"
114+
115+
reader = MARC::Reader.new(new_filepath.to_s)
116+
reader.each do |record|
117+
# Get author fields by supplying a list of tags
118+
record.fields.each_by_tag(['965']) do |field|
119+
puts field
120+
end
121+
end
104122
end
105123

106124
task create_new_hyacinth_record: :environment do

0 commit comments

Comments
 (0)