ndr_import 11.1.0 → 11.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -1
- data/lib/ndr_import/csv_library.rb +5 -1
- data/lib/ndr_import/file/base.rb +7 -5
- data/lib/ndr_import/file/xml.rb +60 -5
- data/lib/ndr_import/helpers/file/xml_streaming.rb +8 -7
- data/lib/ndr_import/table.rb +1 -1
- data/lib/ndr_import/universal_importer_helper.rb +4 -3
- data/lib/ndr_import/version.rb +1 -1
- data/lib/ndr_import/xml/table.rb +2 -1
- metadata +19 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 77f2f2adb4de01a7dca5f2e004976a0f96e8d486f4bf573e24543c1a27b894dd
|
4
|
+
data.tar.gz: eb83c8b95408ee9761b513c9e9309a6b565fd937e7cfba585088bd3d7e7b2573
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6dcfa45678b041cbe5c298b43c935aa2dacc47da9421cfbc6d6f8e646049f89326fb7a7a41e6e5ea283a1114ce367e7cff92d77dd4b83db56775e1d69a93fc6e
|
7
|
+
data.tar.gz: 2443a1c7b4ab1f1c8fcc105cf7c3d29b1885f996e41ad55b65f0ea74d64fbe43042d50a2bb3943a5563374aa8bdc0dd3d47e066226f010922f1fd7e69c167641
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,14 @@
|
|
1
1
|
## [Unreleased]
|
2
|
-
=======
|
3
2
|
* no unreleased changes *
|
4
3
|
|
4
|
+
## 11.2.1 / 2024-11-18
|
5
|
+
### Fixed
|
6
|
+
* Support Ruby 3.2 and 3.3, Rails 7.1, 7.2 and 8.0
|
7
|
+
|
8
|
+
## 11.2.0 / 2024-04-10
|
9
|
+
### Added
|
10
|
+
* XML file/table metadata storage
|
11
|
+
|
5
12
|
## 11.1.0 / 2024-03-07
|
6
13
|
### Added
|
7
14
|
* XML table should not expect column mappings for empty nodes/elements
|
@@ -49,8 +49,12 @@ class << CSVLibrary
|
|
49
49
|
|
50
50
|
private
|
51
51
|
|
52
|
+
def deprecator
|
53
|
+
@deprecator ||= ActiveSupport::Deprecation.new(NdrImport::VERSION, 'NdrImport')
|
54
|
+
end
|
55
|
+
|
52
56
|
def deprecate(additional_message = nil)
|
53
|
-
|
57
|
+
deprecator.warn(<<~MESSAGE)
|
54
58
|
CSVLibrary is deprecated, and will be removed in a future version of ndr_import.
|
55
59
|
Please use standard functionality provided by Ruby's CSV library (#{additional_message}).
|
56
60
|
MESSAGE
|
data/lib/ndr_import/file/base.rb
CHANGED
@@ -9,6 +9,8 @@ module NdrImport
|
|
9
9
|
module File
|
10
10
|
# All common base file handler logic is defined here.
|
11
11
|
class Base
|
12
|
+
attr_accessor :file_metadata
|
13
|
+
|
12
14
|
def initialize(filename, format, options = {})
|
13
15
|
@filename = filename
|
14
16
|
@format = format
|
@@ -32,10 +34,10 @@ module NdrImport
|
|
32
34
|
yield @filename
|
33
35
|
end
|
34
36
|
|
35
|
-
# This method iterates over the tables in the given file and yields with
|
36
|
-
# a tablename
|
37
|
-
# every worksheet in the file and for a CSV file it
|
38
|
-
# file is one table).
|
37
|
+
# This method iterates over the tables in the given file and yields with three arguments:
|
38
|
+
# a tablename, a row enumerator (for that table) and any file metadata.
|
39
|
+
# For a spreadsheet it may yield for every worksheet in the file and for a CSV file it
|
40
|
+
# will only yield once (the entire file is one table).
|
39
41
|
#
|
40
42
|
# As single table files are in the majority, the Base implementation is defined for
|
41
43
|
# single table handlers and you will only need to implement the rows iterator. If your
|
@@ -45,7 +47,7 @@ module NdrImport
|
|
45
47
|
def tables
|
46
48
|
return enum_for(:tables) unless block_given?
|
47
49
|
|
48
|
-
yield nil, rows
|
50
|
+
yield nil, rows, file_metadata
|
49
51
|
end
|
50
52
|
|
51
53
|
private
|
data/lib/ndr_import/file/xml.rb
CHANGED
@@ -16,18 +16,73 @@ module NdrImport
|
|
16
16
|
super
|
17
17
|
|
18
18
|
@pattern_match_xpath = @options['pattern_match_record_xpath']
|
19
|
+
@xml_file_metadata = @options['xml_file_metadata']
|
20
|
+
@options['slurp'] ? prepare_slurped_file : prepare_streamed_file
|
19
21
|
end
|
20
22
|
|
21
23
|
private
|
22
24
|
|
25
|
+
def prepare_slurped_file
|
26
|
+
@doc = read_xml_file(@filename)
|
27
|
+
slurp_metadata_values
|
28
|
+
end
|
29
|
+
|
30
|
+
def prepare_streamed_file
|
31
|
+
with_encoding_check(@filename) do |stream, encoding|
|
32
|
+
@stream = stream
|
33
|
+
@encoding = encoding
|
34
|
+
end
|
35
|
+
stream_metadata_values
|
36
|
+
end
|
37
|
+
|
38
|
+
def slurp_metadata_values
|
39
|
+
return unless @xml_file_metadata.is_a?(Hash)
|
40
|
+
|
41
|
+
self.file_metadata = @xml_file_metadata.transform_values do |xpath|
|
42
|
+
@doc.xpath(xpath).inner_text
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def stream_metadata_values
|
47
|
+
return unless @xml_file_metadata.is_a?(Hash)
|
48
|
+
|
49
|
+
self.file_metadata = @xml_file_metadata.transform_values.with_index do |xpath, index|
|
50
|
+
# Ensure we're at the start of the stream each time
|
51
|
+
@stream.rewind unless index.zero?
|
52
|
+
|
53
|
+
metadata_from_stream(xpath)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def metadata_from_stream(xpath)
|
58
|
+
cursor = Cursor.new(xpath, false)
|
59
|
+
|
60
|
+
# If markup isn't well-formed, try to work around it:
|
61
|
+
options = Nokogiri::XML::ParseOptions::RECOVER
|
62
|
+
reader = Nokogiri::XML::Reader(@stream, nil, @encoding, options)
|
63
|
+
|
64
|
+
reader.each do |node|
|
65
|
+
case node.node_type
|
66
|
+
when Nokogiri::XML::Reader::TYPE_ELEMENT # "opening tag"
|
67
|
+
raise NestingError, node if cursor.in?(node)
|
68
|
+
|
69
|
+
cursor.enter(node)
|
70
|
+
return cursor.inner_text if cursor.send(:current_stack_match?)
|
71
|
+
when Nokogiri::XML::Reader::TYPE_END_ELEMENT # "closing tag"
|
72
|
+
cursor.leave(node)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
23
77
|
# Iterate through the file, yielding each 'xml_record_xpath' element in turn.
|
24
78
|
def rows(&block)
|
25
79
|
return enum_for(:rows) unless block
|
26
80
|
|
27
81
|
if @options['slurp']
|
28
|
-
record_elements
|
82
|
+
record_elements.each(&block)
|
29
83
|
else
|
30
|
-
|
84
|
+
@stream.rewind
|
85
|
+
each_node(@stream, @encoding, xml_record_xpath, @pattern_match_xpath, &block)
|
31
86
|
end
|
32
87
|
end
|
33
88
|
|
@@ -35,13 +90,13 @@ module NdrImport
|
|
35
90
|
@pattern_match_xpath ? @options['xml_record_xpath'] : "*/#{@options['xml_record_xpath']}"
|
36
91
|
end
|
37
92
|
|
38
|
-
def record_elements
|
93
|
+
def record_elements
|
39
94
|
if @pattern_match_xpath
|
40
|
-
doc.root.children.find_all do |element|
|
95
|
+
@doc.root.children.find_all do |element|
|
41
96
|
element.name =~ Regexp.new(@options['xml_record_xpath'])
|
42
97
|
end
|
43
98
|
else
|
44
|
-
doc.root.xpath(@options['xml_record_xpath'])
|
99
|
+
@doc.root.xpath(@options['xml_record_xpath'])
|
45
100
|
end
|
46
101
|
end
|
47
102
|
end
|
@@ -78,6 +78,10 @@ module NdrImport
|
|
78
78
|
match
|
79
79
|
end
|
80
80
|
|
81
|
+
def inner_text
|
82
|
+
dom_stubs[@stack].xpath(@xpath)&.inner_text
|
83
|
+
end
|
84
|
+
|
81
85
|
private
|
82
86
|
|
83
87
|
def in_empty_element?
|
@@ -134,21 +138,18 @@ module NdrImport
|
|
134
138
|
|
135
139
|
include UTF8Encoding
|
136
140
|
|
137
|
-
#
|
138
|
-
# each element matching `xpath` as they're found.
|
141
|
+
# Yields each element matching `xpath` from `stream` as they're found.
|
139
142
|
#
|
140
143
|
# In the case of dodgy encoding, may fall back to slurping the
|
141
144
|
# file, but will still use stream parsing for XML.
|
142
145
|
#
|
143
146
|
# Optionally pattern match the xpath
|
144
|
-
def each_node(
|
145
|
-
return enum_for(:each_node,
|
147
|
+
def each_node(stream, encoding, xpath, pattern_match_xpath = nil, &block)
|
148
|
+
return enum_for(:each_node, stream, encoding, xpath, pattern_match_xpath) unless block
|
146
149
|
|
147
150
|
require 'nokogiri'
|
148
151
|
|
149
|
-
|
150
|
-
stream_xml_nodes(stream, xpath, pattern_match_xpath, encoding, &block)
|
151
|
-
end
|
152
|
+
stream_xml_nodes(stream, xpath, pattern_match_xpath, encoding, &block)
|
152
153
|
end
|
153
154
|
|
154
155
|
private
|
data/lib/ndr_import/table.rb
CHANGED
@@ -59,7 +59,8 @@ module NdrImport
|
|
59
59
|
'xml_record_xpath' => table_mapping.try(:xml_record_xpath),
|
60
60
|
'slurp' => table_mapping.try(:slurp),
|
61
61
|
'yield_xml_record' => table_mapping.try(:yield_xml_record),
|
62
|
-
'pattern_match_record_xpath' => table_mapping.try(:pattern_match_record_xpath)
|
62
|
+
'pattern_match_record_xpath' => table_mapping.try(:pattern_match_record_xpath),
|
63
|
+
'xml_file_metadata' => table_mapping.try(:xml_file_metadata) }
|
63
64
|
|
64
65
|
tables = NdrImport::File::Registry.tables(filename, table_mapping.try(:format), options)
|
65
66
|
yield_tables_and_their_content(filename, tables, &block)
|
@@ -71,12 +72,12 @@ module NdrImport
|
|
71
72
|
def yield_tables_and_their_content(filename, tables, &block)
|
72
73
|
return enum_for(:yield_tables_and_their_content, filename, tables) unless block_given?
|
73
74
|
|
74
|
-
tables.each do |tablename, table_content|
|
75
|
+
tables.each do |tablename, table_content, file_metadata|
|
75
76
|
mapping = get_table_mapping(filename, tablename)
|
76
77
|
next if mapping.nil?
|
77
78
|
|
78
79
|
mapping.notifier = get_notifier(record_total(filename, table_content))
|
79
|
-
|
80
|
+
mapping.table_metadata = file_metadata || {}
|
80
81
|
yield(mapping, table_content)
|
81
82
|
end
|
82
83
|
end
|
data/lib/ndr_import/version.rb
CHANGED
data/lib/ndr_import/xml/table.rb
CHANGED
@@ -10,7 +10,8 @@ module NdrImport
|
|
10
10
|
require 'ndr_import/xml/column_mapping'
|
11
11
|
require 'ndr_import/xml/masked_mappings'
|
12
12
|
|
13
|
-
XML_OPTIONS = %w[pattern_match_record_xpath xml_record_xpath
|
13
|
+
XML_OPTIONS = %w[pattern_match_record_xpath xml_file_metadata xml_record_xpath
|
14
|
+
yield_xml_record].freeze
|
14
15
|
|
15
16
|
def self.all_valid_options
|
16
17
|
super - %w[delimiter header_lines footer_lines] + XML_OPTIONS
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ndr_import
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 11.1
|
4
|
+
version: 11.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- NCRS Development Team
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-11-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -33,7 +33,7 @@ dependencies:
|
|
33
33
|
version: '6.1'
|
34
34
|
- - "<"
|
35
35
|
- !ruby/object:Gem::Version
|
36
|
-
version: '
|
36
|
+
version: '8.1'
|
37
37
|
type: :runtime
|
38
38
|
prerelease: false
|
39
39
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: '6.1'
|
44
44
|
- - "<"
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: '
|
46
|
+
version: '8.1'
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: ndr_support
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -120,6 +120,20 @@ dependencies:
|
|
120
120
|
- - "~>"
|
121
121
|
- !ruby/object:Gem::Version
|
122
122
|
version: 0.9.5
|
123
|
+
- !ruby/object:Gem::Dependency
|
124
|
+
name: csv
|
125
|
+
requirement: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - ">="
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '0'
|
130
|
+
type: :runtime
|
131
|
+
prerelease: false
|
132
|
+
version_requirements: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - ">="
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
123
137
|
- !ruby/object:Gem::Dependency
|
124
138
|
name: docx
|
125
139
|
requirement: !ruby/object:Gem::Requirement
|
@@ -465,7 +479,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
465
479
|
- !ruby/object:Gem::Version
|
466
480
|
version: '0'
|
467
481
|
requirements: []
|
468
|
-
rubygems_version: 3.
|
482
|
+
rubygems_version: 3.3.27
|
469
483
|
signing_key:
|
470
484
|
specification_version: 4
|
471
485
|
summary: NDR Import
|