Skip to content

Commit

Permalink
Add ISBN file and job
Browse files Browse the repository at this point in the history
Co-authored-by: Beck Davis <[email protected]>
Co-authored-by: Jane Sandberg <[email protected]>
Co-authored-by: Mark Zelesky <[email protected]>
  • Loading branch information
4 people committed Mar 27, 2024
1 parent 5480c70 commit fdeee1f
Show file tree
Hide file tree
Showing 9 changed files with 695 additions and 0 deletions.
106 changes: 106 additions & 0 deletions app/models/gobi/isbn_file.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# frozen_string_literal: false

module Gobi
class IsbnFile
attr_reader :received_items_file, :bib_hash
def initialize(temp_file:)
@received_items_file = temp_file
@bib_hash = {}
end

def process
CSV.foreach(received_items_file, headers: true, encoding: 'bom|utf-8') do |row|
next unless published_within_five_years?(row:)
next unless relevant_library_code?(row:)
isbns = isbns_for_report(row:)
next if isbns.blank?
build_bib_hash(row:)
end
write_bib_hash_to_csv
Gobi::IsbnReportJob.working_file_name
end

def build_bib_hash(row:)
bib_id = row["MMS Id"]
if @bib_hash[bib_id]
@bib_hash[bib_id][:loc_combos] << loc_combo(row:)
else
@bib_hash[bib_id] = {
isbns: isbns_for_report(row:),
loc_combos: [loc_combo(row:)]
}
end
end

def write_bib_hash_to_csv
CSV.open(Gobi::IsbnReportJob.working_file_path, 'a', headers: true, encoding: 'bom|utf-8', col_sep: "|") do |csv|
@bib_hash.each do |_bib, data|
code_string = code_string(loc_combos: data[:loc_combos])
data[:isbns].each do |isbn|
csv << [isbn, code_string, Rails.application.config.gobi_sftp.gobi_account_code]
end
end
end
end

def code_string(loc_combos:)
limited_locations = Rails.application.config.gobi_locations.limited_locations
shared_locations = Rails.application.config.gobi_locations.shared_locations
has_limited_locations = (loc_combos & limited_locations)
has_shared_locations = (loc_combos & shared_locations)
has_circ_locations = (loc_combos - has_limited_locations - has_shared_locations).present?
code_string = ''
code_string << 'Cir' if has_circ_locations
code_string << 'NC' if has_limited_locations.present?
code_string << 'RCP' if has_shared_locations.present?
code_string
end

def loc_combo(row:)
library = row['Library Code']
location = row['Location Code']
[library, location].join('$')
end

# with items published in the last 5 years
# Edge cases: 202u (sometime in the 2020s), 9999, publication dates in the future
def published_within_five_years?(row:)
pub_year = row["Begin Publication Date"]
return false if pub_year == '9999' || pub_year.nil?

pub_year.sub!('u', '0')
return false if pub_year.to_i < Time.current.year - 5

true
end

# that are not Library Code zobsolete, online, resshare
def relevant_library_code?(row:)
return true unless %w[zobsolete online resshare].include?(row["Library Code"])

false
end

# Need to have a row for each valid ISBN
# Could convert to 13 digit ISBN and de-dup
def isbns_for_report(row:)
isbns = row["ISBN Valid"].split("\; ").map { |isbn| isbn.delete(':') }
isbns.select! { |isbn| isbn.size == 13 || isbn.size == 10 }
isbns.map { |isbn| convert_to_isbn_thirteen(isbn:) }.uniq
end

def convert_to_isbn_thirteen(isbn:)
return isbn if isbn.length == 13

isbn.chop!
isbn.prepend('978')
check_digit_arr = isbn.split("").map(&:to_i)
modulo = check_digit_arr.each_with_index.map do |num, index|
index.odd? ? num * 3 : num * 1
end.sum % 10
check_digit = modulo.zero? ? 0 : 10 - modulo
isbn << check_digit.to_s
isbn
end
end
end
55 changes: 55 additions & 0 deletions app/models/gobi/isbn_report_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# frozen_string_literal: true

module Gobi
class IsbnReportJob < LibJob
attr_reader :report_downloader, :report_uploader

def initialize
super(category: 'Gobi:IsbnReports')
@report_downloader = ReportDownloader.new(
sftp: AlmaSftp.new,
file_pattern: 'received_items_published_last_5_years_\d{12}.csv',
input_sftp_base_dir: '/alma/isbns',
process_class: Gobi::IsbnFile
)
@report_uploader = ReportUploader.new(
sftp: GobiSftp.new,
working_file_names: [IsbnReportJob.working_file_name],
working_file_directory: Rails.application.config.gobi_sftp.working_directory,
output_sftp_base_dir: Rails.application.config.gobi_sftp.output_sftp_base_dir
)
end

def self.working_file_path
working_file_directory = Rails.application.config.gobi_sftp.working_directory
FileUtils.mkdir_p(working_file_directory) unless File.exist?(working_file_directory)
File.join(working_file_directory, IsbnReportJob.working_file_name)
end

def self.working_file_name
date = Time.now.utc.strftime('%Y-%m-%d')
"#{date}-gobi-isbn-updates.txt"
end

def handle(data_set:)
create_csv
report_downloader.run
report_uploader.run
rename_files_on_sftp
data_set.data = "Number of ISBNs sent: #{CSV.read(IsbnReportJob.working_file_path).length}"
data_set
end

def rename_files_on_sftp
AlmaSftp.new.start do |sftp|
report_downloader.remote_filenames.each do |file_name|
sftp.rename(file_name, "#{file_name}.processed")
end
end
end

def create_csv
CSV.open(IsbnReportJob.working_file_path, 'w', encoding: 'bom|utf-8', col_sep: "|")
end
end
end
1 change: 1 addition & 0 deletions config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ def config_for(*args)

config.alma_sftp = config_for(:alma_sftp)
config.gobi_sftp = config_for(:gobi_sftp)
config.gobi_locations = config_for(:gobi_locations)
config.oclc_sftp = config_for(:oclc_sftp)
config.lc_call_slips = config_for(:lc_call_slips)
config.peoplesoft = config_for(:peoplesoft)
Expand Down
85 changes: 85 additions & 0 deletions config/gobi_locations.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
default: &default
limited_locations:
- arch$ref
- arch$la
- eastasian$cjkref
- eastasian$ref
- eastasian$hyref
- engineer$ref
- firestone$aas
- firestone$dra
- firestone$dr
- firestone$drrr
- firestone$flm
- firestone$sc
- firestone$se
- firestone$slav
- firestone$sh
- firestone$shs
- firestone$sne
- firestone$spc
- firestone$sss
- firestone$ssa
- firestone$srel
- firestone$gestf
- firestone$dss
- firestone$fis
- firestone$sps
- firestone$seref
- firestone$egsr
- firestone$gss
- firestone$noncirc
- firestone$necnc
- firestone$clasnc
- firestone$xlnc
- firestone$secw
- firestone$ssrcfo
- firestone$ssrcdc
- plasma$ref
- plasma$rr
- plasma$la
- plasma$li
- plasma$theses
- plasma$nb
- lewis$lal
- lewis$laf
- lewis$refid
- lewis$ref
- marquand$fesrf
- marquand$ph
- marquand$phref
- marquand$ref
- mendel$rg
- mendel$facs
- mendel$ref
- mendel$pe
- mudd$scamudd
- rare$gestrare
- rare$scactsn
- rare$scathx
- rare$scahsvm
- rare$scagax
- rare$scaex
- rare$scamss
- rare$scawa
- rare$scahsvc
- rare$scawhs
- stokes$ref
shared_locations:
- recap$pa
- recap$gp
- mendel$qk
- firestone$pf
- marquand$pv

development:
<<: *default

test:
<<: *default

staging: &staging
<<: *default

production:
<<: *staging
Loading

0 comments on commit fdeee1f

Please sign in to comment.