• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pulibrary / bibdata / 373ad6ff-fad2-405a-ab26-3d30fb5ceecf

24 Dec 2024 08:24PM UTC coverage: 91.938% (+0.08%) from 91.859%
373ad6ff-fad2-405a-ab26-3d30fb5ceecf

Pull #2563

circleci

maxkadel
Put attaching xml files in their own batch
Pull Request #2563: I2321 Shift SCSB full index tasks into separate background jobs

152 of 156 new or added lines in 10 files covered. (97.44%)

65 existing lines in 17 files now uncovered.

3478 of 3783 relevant lines covered (91.94%)

366.14 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.49
/app/models/scsb/partner_updates/update.rb
1
module Scsb
1✔
2
  class PartnerUpdates
1✔
3
    class Update
1✔
4
      attr_accessor :dump
1✔
5
      def initialize(dump:, dump_file_type:, timestamp:)
1✔
6
        @last_dump = timestamp
11✔
7
        @dump = dump
11✔
8
        @dump_file_type = dump_file_type
11✔
9
        @s3_bucket = Scsb::S3Bucket.partner_transfer_client
11✔
10
        @scsb_file_dir = ENV['SCSB_FILE_DIR']
11✔
11
        @update_directory = ENV['SCSB_PARTNER_UPDATE_DIRECTORY'] || '/tmp/updates'
11✔
12
      end
13

14
      def process_partner_updates(files:, file_prefix: 'scsb_update_')
1✔
15
        xml_files = []
3✔
16
        files.each do |file|
3✔
17
          xml_files << Scsb::PartnerUpdates::Update.extract_files(file:, update_directory: @update_directory)
3✔
18
        end
19
        xml_files.flatten.each do |file|
3✔
20
          Scsb::PartnerUpdates::Update.attach_cleaned_dump_file(file:, dump_id: @dump.id, file_prefix:, dump_file_type: @dump_file_type)
6✔
21
        end
22
      end
23

24
      def self.extract_files(file:, update_directory:)
1✔
25
        extracted_files = []
18✔
26
        filename = File.basename(file, '.zip')
18✔
27
        filename.gsub!(/^[^_]+_([0-9]+)_([0-9]+).*$/, '\1_\2')
18✔
28
        file_increment = 1
18✔
29
        Zip::File.open(file) do |zip_file|
18✔
30
          zip_file.each do |entry|
16✔
31
            target = "#{update_directory}/#{filename}_#{file_increment}.xml"
32✔
32
            extracted_files << target
32✔
33
            entry.extract(target)
32✔
34
            file_increment += 1
32✔
35
          end
36
        end
37
        File.unlink(file)
17✔
38
        extracted_files
17✔
39
      end
40

41
      def self.attach_cleaned_dump_file(file:, dump_id:, file_prefix:, dump_file_type: :recap_records_full)
1✔
42
        scsb_file_dir = ENV['SCSB_FILE_DIR']
32✔
43
        @inv_xml = []
32✔
44
        @tab_newline = []
32✔
45
        @leader = []
32✔
46
        @composed_chars = []
32✔
47
        @bad_utf8 = []
32✔
48
        original_filename = File.basename(file)
32✔
49
        reader = MARC::XMLReader.new(file.to_s, external_encoding: 'UTF-8')
32✔
50
        new_filepath = "#{scsb_file_dir}/#{file_prefix}#{original_filename}"
32✔
51
        writer = MARC::XMLWriter.new(new_filepath)
32✔
52
        reader.each { |record| writer.write(process_record(record)) }
96✔
53
        writer.close
32✔
54
        File.unlink(file) if dump_file_type == :recap_records
32✔
55
        Dump.attach_dump_file(dump_id:, filepath: new_filepath, dump_file_type:)
32✔
56
      end
57

58
      def self.process_record(record)
1✔
59
        record = field_delete(['856', '959'], record)
65✔
60
        record.leader[5] = 'c' if record.leader[5].eql?('d')
65✔
61
        if bad_utf8?(record)
65✔
UNCOV
62
          @bad_utf8 << record['001']
×
63
          record = bad_utf8_fix(record)
×
64
        end
65
        if invalid_xml_chars?(record)
65✔
UNCOV
66
          @inv_xml << record['001']
×
67
          record = invalid_xml_fix(record)
×
68
        end
69
        if tab_newline_char?(record)
65✔
70
          @tab_newline << record['001']
3✔
71
          record = tab_newline_fix(record)
3✔
72
        end
73
        if leader_errors?(record)
65✔
74
          @leader << record['001']
10✔
75
          record = leaderfix(record)
10✔
76
        end
77
        if composed_chars_errors?(record)
65✔
78
          @composed_chars << record['001']
19✔
79
          record = composed_chars_normalize(record)
19✔
80
        end
81
        record = extra_space_fix(record)
65✔
82
        empty_subfield_fix(record)
65✔
83
      end
84

85
      def add_error(message:)
1✔
UNCOV
86
        error = Array.wrap(@dump.event.error)
×
UNCOV
87
        error << message
×
UNCOV
88
        @dump.event.error = error.join("; ")
×
UNCOV
89
        @dump.event.save
×
90
      end
91

92
      def log_record_fixes
1✔
93
        log_file = {
94
          inv_xml: @inv_xml,
8✔
95
          tab_newline: @tab_newline,
96
          leader: @leader,
97
          composed_chars: @composed_chars,
98
          bad_utf8: @bad_utf8
99
        }
100
        filepath = log_file_name
8✔
101
        File.write(filepath, log_file.to_json.to_s)
8✔
102
        Dump.attach_dump_file(dump_id: @dump.id, filepath:, dump_file_type: :log_file)
8✔
103
      end
104

105
      def log_file_name
1✔
106
        "#{@scsb_file_dir}/fixes_#{@last_dump.to_time.strftime('%Y_%m_%d')}.json"
8✔
107
      end
108

109
      def self.generated_date(dump_id:)
1✔
110
        dump = Dump.find(dump_id)
1✔
111
        dump.generated_date = date_strings(dump:).map { |str| DateTime.parse(str) }.sort.first
10✔
112
      end
113

114
      def self.date_strings(dump:)
1✔
115
        dump.dump_files.map do |df|
1✔
116
          if df.dump_file_type == "recap_records_full_metadata"
9✔
117
            File.basename(df.path).split("_")[3]
3✔
118
          else
119
            File.basename(df.path).split("_")[2]
6✔
120
          end
121
        end
122
      end
123

124
      def set_generated_date
1✔
125
        @dump.generated_date = date_strings.map { |str| DateTime.parse(str) }.sort.first
40✔
126
      end
127

128
      def date_strings
1✔
129
        @dump.dump_files.map do |df|
8✔
130
          if df.dump_file_type == "recap_records_full_metadata"
32✔
131
            File.basename(df.path).split("_")[3]
10✔
132
          else
133
            File.basename(df.path).split("_")[2]
22✔
134
          end
135
        end
136
      end
137

138
      def prepare_directory
1✔
139
        FileUtils.mkdir_p(@update_directory)
8✔
140
      end
141
    end
142
  end
143
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc