im_onix 1.2.3 → 1.3.0
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/Gemfile +1 -6
- data/README.md +1 -1
- data/bin/onix_bench.rb +16 -0
- data/im_onix.gemspec +3 -1
- data/lib/onix/addressee.rb +2 -1
- data/lib/onix/barcode.rb +6 -0
- data/lib/onix/builder.rb +22 -6
- data/lib/onix/code.rb +42 -44
- data/lib/onix/date.rb +17 -11
- data/lib/onix/entity.rb +3 -2
- data/lib/onix/identifier.rb +69 -64
- data/lib/onix/market_publishing_detail.rb +1 -0
- data/lib/onix/onix21.rb +26 -24
- data/lib/onix/product.rb +7 -9
- data/lib/onix/product_part.rb +2 -2
- data/lib/onix/{product_supplies_extractor.rb → product_supplies_methods.rb} +3 -3
- data/lib/onix/publisher_representative.rb +11 -0
- data/lib/onix/related_product.rb +2 -2
- data/lib/onix/related_work.rb +2 -1
- data/lib/onix/sender.rb +1 -1
- data/lib/onix/serializer.rb +5 -5
- data/lib/onix/subset.rb +158 -114
- metadata +33 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1ae373f892a08b5321d26712145417619ca310f6a5d6f7bc67ad42049d65a7c9
|
4
|
+
data.tar.gz: c6b81828cef14da0196bd9e27e5a92fb6e95718e3e7261b8407f346f9e7dfe64
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3595015fab4b4c17898aedbb507189c81ba830cb0c76914b5b280965a574beffcf7bc31f2376c1667568ffadf4e7213b996e91cb89755f2bcee9296bad1a5cd5
|
7
|
+
data.tar.gz: 388f43af3200a38a9d3c20fb1e08e3157a2119a2b6faf91af9505c5b25b36a938c45d3faa6be2ebea90b31dc54bd84f498fa24875d258a067e043b0d0e87e525
|
data/Gemfile
CHANGED
data/README.md
CHANGED
data/bin/onix_bench.rb
CHANGED
@@ -8,10 +8,26 @@ filename = ARGV[0]
|
|
8
8
|
if filename
|
9
9
|
GC.start
|
10
10
|
old_memsize = ObjectSpace.count_objects_size[:TOTAL]
|
11
|
+
|
12
|
+
if ENV['PROFILE'] == 'yes'
|
13
|
+
require 'ruby-prof'
|
14
|
+
RubyProf.start
|
15
|
+
end
|
16
|
+
|
11
17
|
msg = ONIX::ONIXMessage.new
|
12
18
|
bench = Benchmark.measure do
|
13
19
|
msg.parse(filename)
|
14
20
|
end
|
21
|
+
|
22
|
+
if ENV['PROFILE'] == 'yes'
|
23
|
+
result = RubyProf.stop
|
24
|
+
printer = RubyProf::FlatPrinter.new(result)
|
25
|
+
printer.print(STDOUT, min_percent: 1.0)
|
26
|
+
|
27
|
+
printer = RubyProf::CallTreePrinter.new(result)
|
28
|
+
printer.print
|
29
|
+
end
|
30
|
+
|
15
31
|
GC.start
|
16
32
|
new_memsize = ObjectSpace.count_objects_size[:TOTAL]
|
17
33
|
puts "Parsed #{msg.products.length} products in #{bench.real.round(3)} seconds resulting in use of #{new_memsize - old_memsize} bytes of memory"
|
data/im_onix.gemspec
CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "im_onix"
|
7
|
-
spec.version = "1.
|
7
|
+
spec.version = "1.3.0"
|
8
8
|
spec.authors = ["Julien Boulnois"]
|
9
9
|
spec.email = ["jboulnois@immateriel.fr"]
|
10
10
|
|
@@ -25,6 +25,8 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_development_dependency "minitest"
|
26
26
|
spec.add_development_dependency 'yard'
|
27
27
|
spec.add_development_dependency 'shoulda'
|
28
|
+
spec.add_development_dependency "simplecov"
|
29
|
+
spec.add_development_dependency "ruby-prof"
|
28
30
|
|
29
31
|
spec.required_ruby_version = '>= 2.1'
|
30
32
|
|
data/lib/onix/addressee.rb
CHANGED
@@ -2,7 +2,8 @@ require 'onix/identifier'
|
|
2
2
|
|
3
3
|
module ONIX
|
4
4
|
class Addressee < SubsetDSL
|
5
|
-
include
|
5
|
+
include IdentifiersMethods::Gln
|
6
|
+
|
6
7
|
elements "AddresseeIdentifier", :subset, :shortcut => :identifiers, :cardinality => 0..n
|
7
8
|
element "AddresseeName", :text, :shortcut => :name, :cardinality => 0..1
|
8
9
|
element "ContactName", :text, :cardinality => 0..1
|
data/lib/onix/barcode.rb
ADDED
data/lib/onix/builder.rb
CHANGED
@@ -38,6 +38,8 @@ module ONIX
|
|
38
38
|
yield self
|
39
39
|
end
|
40
40
|
|
41
|
+
@lax = false
|
42
|
+
|
41
43
|
@parent = @doc
|
42
44
|
end
|
43
45
|
|
@@ -55,13 +57,27 @@ module ONIX
|
|
55
57
|
end.to_xml
|
56
58
|
end
|
57
59
|
|
60
|
+
# code in block will not check for validity
|
61
|
+
def lax &block
|
62
|
+
if block_given?
|
63
|
+
@lax = true
|
64
|
+
@arity ||= block.arity
|
65
|
+
if @arity <= 0
|
66
|
+
instance_eval(&block)
|
67
|
+
else
|
68
|
+
block.call(self)
|
69
|
+
end
|
70
|
+
@lax = false
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
58
74
|
def method_missing(method, *args, &block)
|
59
75
|
# :nodoc:
|
60
76
|
if @context && @context.respond_to?(method)
|
61
77
|
@context.send(method, *args, &block)
|
62
78
|
else
|
63
79
|
if @parent
|
64
|
-
parser_el = @parent.
|
80
|
+
parser_el = @parent.registered_elements[method.to_s]
|
65
81
|
if parser_el
|
66
82
|
if ONIX.const_defined?(parser_el.klass_name)
|
67
83
|
node = get_class(parser_el.klass_name, args)
|
@@ -82,7 +98,7 @@ module ONIX
|
|
82
98
|
when :ignore
|
83
99
|
when :subset
|
84
100
|
# FIXME: dirty
|
85
|
-
if @parent.class.included_modules.include?(
|
101
|
+
if @parent.class.included_modules.include?(DateMethods) && node.is_a?(DateFormat)
|
86
102
|
@parent.deprecated_date_format = true
|
87
103
|
end
|
88
104
|
node.attributes = get_attributes(args[1]) if args.length > 1
|
@@ -129,7 +145,9 @@ module ONIX
|
|
129
145
|
if arg.is_a?(String)
|
130
146
|
el = klass.from_code(arg)
|
131
147
|
unless el.human
|
132
|
-
|
148
|
+
unless @lax
|
149
|
+
raise BuilderInvalidCode, [klass.to_s, arg]
|
150
|
+
end
|
133
151
|
end
|
134
152
|
el
|
135
153
|
else
|
@@ -154,14 +172,12 @@ module ONIX
|
|
154
172
|
end
|
155
173
|
|
156
174
|
def get_class(nm, args)
|
157
|
-
el = nil
|
158
175
|
if ONIX.const_defined?(nm)
|
159
176
|
klass = ONIX.const_get(nm)
|
160
|
-
|
177
|
+
get_element(klass, args)
|
161
178
|
else
|
162
179
|
raise BuilderUndefinedElement, nm
|
163
180
|
end
|
164
|
-
el
|
165
181
|
end
|
166
182
|
|
167
183
|
def insert(node, &block)
|
data/lib/onix/code.rb
CHANGED
@@ -1,11 +1,10 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
1
|
require 'yaml'
|
3
2
|
|
4
3
|
module ONIX
|
5
4
|
class InvalidCodeAlias < StandardError
|
6
5
|
end
|
7
6
|
|
8
|
-
module
|
7
|
+
module CodeMethods
|
9
8
|
def parse(n)
|
10
9
|
parse_attributes(n.attributes)
|
11
10
|
@code = n.text
|
@@ -33,58 +32,56 @@ module ONIX
|
|
33
32
|
# @return [String] humanized string (eg: "Digital watermarking" become DigitalWatermarking, "PDF" become Pdf, "BISAC Subject Heading" become BisacSubjectHeading, etc)
|
34
33
|
attr_accessor :human
|
35
34
|
|
36
|
-
include
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
# create Code from human readable code
|
49
|
-
# @param [String] human human readable code
|
50
|
-
# @return [Code]
|
51
|
-
def self.from_human(human)
|
52
|
-
obj = self.new
|
53
|
-
obj.human = human
|
54
|
-
obj.code = self.hash.key(human)
|
55
|
-
unless obj.code
|
56
|
-
raise InvalidCodeAlias, [self.to_s, human]
|
35
|
+
include CodeMethods
|
36
|
+
|
37
|
+
class << self
|
38
|
+
# create Code from ONIX code
|
39
|
+
# @param [String] code ONIX code
|
40
|
+
# @return [Code]
|
41
|
+
def from_code(code)
|
42
|
+
obj = self.new
|
43
|
+
obj.code = code
|
44
|
+
obj.human = self.hash[code]
|
45
|
+
obj
|
57
46
|
end
|
58
|
-
obj
|
59
|
-
end
|
60
47
|
|
61
|
-
|
48
|
+
# create Code from human readable code
|
49
|
+
# @param [String] human human readable code
|
50
|
+
# @return [Code]
|
51
|
+
def from_human(human)
|
52
|
+
obj = self.new
|
53
|
+
obj.human = human
|
54
|
+
obj.code = self.hash.key(human)
|
55
|
+
unless obj.code
|
56
|
+
raise InvalidCodeAlias, [self.to_s, human]
|
57
|
+
end
|
58
|
+
obj
|
59
|
+
end
|
62
60
|
|
63
|
-
|
64
|
-
|
61
|
+
def hash
|
62
|
+
{}
|
63
|
+
end
|
65
64
|
end
|
66
65
|
end
|
67
66
|
|
68
67
|
class CodeFromYaml < Code
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
def self.hash
|
74
|
-
@hash ||= YAML.load(File.open(codelist_filename))[:codelist]
|
75
|
-
end
|
68
|
+
class << self
|
69
|
+
def hash
|
70
|
+
@hash ||= YAML.load(File.open(File.dirname(__FILE__) + "/../../data/codelists/codelist-#{self.code_ident}.yml"))[:codelist].freeze
|
71
|
+
end
|
76
72
|
|
77
|
-
|
78
|
-
|
79
|
-
|
73
|
+
def list
|
74
|
+
self.hash.keys
|
75
|
+
end
|
80
76
|
|
81
|
-
|
82
|
-
|
83
|
-
|
77
|
+
def code_ident
|
78
|
+
nil
|
79
|
+
end
|
84
80
|
|
85
|
-
|
86
|
-
|
87
|
-
|
81
|
+
def code_identifier code
|
82
|
+
define_singleton_method :code_ident do
|
83
|
+
return code
|
84
|
+
end
|
88
85
|
end
|
89
86
|
end
|
90
87
|
end
|
@@ -109,6 +106,7 @@ module ONIX
|
|
109
106
|
end
|
110
107
|
end
|
111
108
|
end
|
109
|
+
|
112
110
|
class NotificationType < CodeFromYaml
|
113
111
|
code_identifier 1
|
114
112
|
end
|
data/lib/onix/date.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module ONIX
|
2
|
-
module
|
2
|
+
module DateMethods
|
3
3
|
# @return [DateFormat]
|
4
4
|
attr_accessor :date_format
|
5
5
|
# @return [Date]
|
@@ -31,7 +31,7 @@ module ONIX
|
|
31
31
|
format = code_format
|
32
32
|
|
33
33
|
if code_format != text_format
|
34
|
-
puts "WARN incorrect date format #{text_format} != #{code_format}"
|
34
|
+
# puts "WARN incorrect date format #{text_format} != #{code_format}"
|
35
35
|
format = text_format
|
36
36
|
end
|
37
37
|
|
@@ -133,9 +133,15 @@ module ONIX
|
|
133
133
|
end
|
134
134
|
|
135
135
|
class BaseDate < SubsetDSL
|
136
|
-
include
|
137
|
-
|
138
|
-
|
136
|
+
include DateMethods
|
137
|
+
|
138
|
+
class << self
|
139
|
+
def date_elements(role)
|
140
|
+
element role, :subset, :shortcut => :role
|
141
|
+
element "DateFormat", :subset
|
142
|
+
element "Date", :text
|
143
|
+
end
|
144
|
+
end
|
139
145
|
|
140
146
|
# use former date representation
|
141
147
|
# @return [Boolean]
|
@@ -153,26 +159,26 @@ module ONIX
|
|
153
159
|
end
|
154
160
|
|
155
161
|
class MarketDate < BaseDate
|
156
|
-
|
162
|
+
date_elements "MarketDateRole"
|
157
163
|
|
158
164
|
scope :availability, lambda { human_code_match(:market_date_role, ["PublicationDate", "EmbargoDate"]) }
|
159
165
|
end
|
160
166
|
|
161
167
|
class PriceDate < BaseDate
|
162
|
-
|
168
|
+
date_elements "PriceDateRole"
|
163
169
|
|
164
170
|
scope :from_date, lambda { human_code_match(:price_date_role, "FromDate") }
|
165
171
|
scope :until_date, lambda { human_code_match(:price_date_role, "UntilDate") }
|
166
172
|
end
|
167
173
|
|
168
174
|
class SupplyDate < BaseDate
|
169
|
-
|
175
|
+
date_elements "SupplyDateRole"
|
170
176
|
|
171
177
|
scope :availability, lambda { human_code_match(:supply_date_role, ["ExpectedAvailabilityDate", "EmbargoDate"]) }
|
172
178
|
end
|
173
179
|
|
174
180
|
class PublishingDate < BaseDate
|
175
|
-
|
181
|
+
date_elements "PublishingDateRole"
|
176
182
|
|
177
183
|
scope :publication, lambda { human_code_match(:publishing_date_role, ["PublicationDate", "PublicationDateOfPrintCounterpart"]) }
|
178
184
|
scope :embargo, lambda { human_code_match(:publishing_date_role, "SalesEmbargoDate") }
|
@@ -181,12 +187,12 @@ module ONIX
|
|
181
187
|
end
|
182
188
|
|
183
189
|
class ContentDate < BaseDate
|
184
|
-
|
190
|
+
date_elements "ContentDateRole"
|
185
191
|
|
186
192
|
scope :last_updated, lambda { human_code_match(:content_date_role, "LastUpdated") }
|
187
193
|
end
|
188
194
|
|
189
195
|
class ContributorDate < BaseDate
|
190
|
-
|
196
|
+
date_elements "ContributorDateRole"
|
191
197
|
end
|
192
198
|
end
|
data/lib/onix/entity.rb
CHANGED
@@ -7,7 +7,7 @@ module ONIX
|
|
7
7
|
end
|
8
8
|
|
9
9
|
class Entity < SubsetDSL
|
10
|
-
include
|
10
|
+
include IdentifiersMethods::Gln
|
11
11
|
include EntityHelper
|
12
12
|
|
13
13
|
# @return [String]
|
@@ -60,7 +60,8 @@ module ONIX
|
|
60
60
|
end
|
61
61
|
|
62
62
|
class Imprint < SubsetDSL
|
63
|
-
include
|
63
|
+
include IdentifiersMethods::Gln
|
64
|
+
|
64
65
|
elements "ImprintIdentifier", :subset, :shortcut => :identifiers, :cardinality => 0..n
|
65
66
|
element "ImprintName", :text, :shortcut => :name, :cardinality => 0..1
|
66
67
|
end
|
data/lib/onix/identifier.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
module ONIX
|
2
2
|
class Identifier < SubsetDSL
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
class << self
|
4
|
+
def identifier_elements(id_type)
|
5
|
+
element id_type, :subset, :shortcut => :type, :cardinality => 1
|
6
|
+
element "IDTypeName", :text, :shortcut => :name, :cardinality => 0..1
|
7
|
+
element "IDValue", :text, :shortcut => :value, :cardinality => 1
|
8
|
+
end
|
8
9
|
end
|
9
10
|
|
10
11
|
def uniq_id
|
@@ -13,124 +14,128 @@ module ONIX
|
|
13
14
|
end
|
14
15
|
|
15
16
|
class SenderIdentifier < Identifier
|
16
|
-
|
17
|
+
identifier_elements "SenderIDType"
|
17
18
|
end
|
18
19
|
|
19
20
|
class AddresseeIdentifier < Identifier
|
20
|
-
|
21
|
+
identifier_elements "AddresseeIDType"
|
21
22
|
end
|
22
23
|
|
23
24
|
class RecordSourceIdentifier < Identifier
|
24
|
-
|
25
|
+
identifier_elements "RecordSourceIDType"
|
25
26
|
end
|
26
27
|
|
27
28
|
class AgentIdentifier < Identifier
|
28
|
-
|
29
|
+
identifier_elements "AgentIDType"
|
29
30
|
end
|
30
31
|
|
31
32
|
class ImprintIdentifier < Identifier
|
32
|
-
|
33
|
+
identifier_elements "ImprintIDType"
|
33
34
|
end
|
34
35
|
|
35
36
|
class PublisherIdentifier < Identifier
|
36
|
-
|
37
|
+
identifier_elements "PublisherIDType"
|
37
38
|
end
|
38
39
|
|
39
40
|
class SupplierIdentifier < Identifier
|
40
|
-
|
41
|
+
identifier_elements "SupplierIDType"
|
41
42
|
end
|
42
43
|
|
43
44
|
class NameIdentifier < Identifier
|
44
|
-
|
45
|
+
identifier_elements "NameIDType"
|
45
46
|
end
|
46
47
|
|
47
48
|
class CollectionIdentifier < Identifier
|
48
|
-
|
49
|
+
identifier_elements "CollectionIDType"
|
49
50
|
end
|
50
51
|
|
51
52
|
class ProductIdentifier < Identifier
|
52
|
-
|
53
|
+
identifier_elements "ProductIDType"
|
53
54
|
end
|
54
55
|
|
55
56
|
class ProductContactIdentifier < Identifier
|
56
|
-
|
57
|
+
identifier_elements "ProductContactIDType"
|
57
58
|
end
|
58
59
|
|
59
60
|
class SalesOutletIdentifier < Identifier
|
60
|
-
|
61
|
+
identifier_elements "SalesOutletIDType"
|
61
62
|
end
|
62
63
|
|
63
64
|
class WorkIdentifier < Identifier
|
64
|
-
|
65
|
+
identifier_elements "WorkIDType"
|
65
66
|
end
|
66
67
|
|
67
68
|
class SupplyContactIdentifier < Identifier
|
68
|
-
|
69
|
+
identifier_elements "SupplyContactIDType"
|
69
70
|
end
|
70
71
|
|
71
72
|
class TextItemIdentifier < Identifier
|
72
|
-
|
73
|
+
identifier_elements "TextItemIDType"
|
73
74
|
end
|
74
75
|
|
75
|
-
module
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
ean_identifier
|
81
|
-
|
82
|
-
|
76
|
+
module IdentifiersMethods
|
77
|
+
module Ean
|
78
|
+
# EAN string identifier from identifiers
|
79
|
+
# @return [String]
|
80
|
+
def ean
|
81
|
+
if ean_identifier
|
82
|
+
ean_identifier.value
|
83
|
+
else
|
84
|
+
nil
|
85
|
+
end
|
83
86
|
end
|
84
|
-
end
|
85
87
|
|
86
|
-
|
87
|
-
def ean_identifier
|
88
|
-
self.identifiers.select { |id| id.type.human=="Gtin13" }.first || self.identifiers.select { |id| id.type.human=="Isbn13" }.first
|
89
|
-
end
|
90
|
-
end
|
88
|
+
private
|
91
89
|
|
92
|
-
|
93
|
-
|
94
|
-
# @return [String]
|
95
|
-
def isbn13
|
96
|
-
if isbn13_identifier
|
97
|
-
isbn13_identifier.value
|
98
|
-
else
|
99
|
-
nil
|
90
|
+
def ean_identifier
|
91
|
+
self.identifiers.select { |id| id.type.human == "Gtin13" }.first || self.identifiers.select { |id| id.type.human == "Isbn13" }.first
|
100
92
|
end
|
101
93
|
end
|
102
94
|
|
103
|
-
|
104
|
-
|
105
|
-
|
95
|
+
module Isbn
|
96
|
+
# ISBN-13 string identifier from identifiers
|
97
|
+
# @return [String]
|
98
|
+
def isbn13
|
99
|
+
if isbn13_identifier
|
100
|
+
isbn13_identifier.value
|
101
|
+
else
|
102
|
+
nil
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
def isbn13_identifier
|
109
|
+
self.identifiers.select { |id| id.type.human == "Isbn13" }.first
|
110
|
+
end
|
106
111
|
end
|
107
|
-
end
|
108
112
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
113
|
+
module Gln
|
114
|
+
# GLN string identifier from identifiers
|
115
|
+
# @return [String]
|
116
|
+
def gln
|
117
|
+
if gln_identifier
|
118
|
+
if gln_identifier.value =~ /\d{13}/
|
119
|
+
gln_identifier.value
|
120
|
+
else
|
121
|
+
# puts "WARN Invalid GLN #{gln_identifier.value}"
|
122
|
+
nil
|
123
|
+
end
|
116
124
|
else
|
117
|
-
puts "Invalid GLN #{gln_identifier.value}"
|
118
125
|
nil
|
119
126
|
end
|
120
|
-
else
|
121
|
-
nil
|
122
127
|
end
|
123
|
-
end
|
124
128
|
|
125
|
-
|
126
|
-
|
127
|
-
|
129
|
+
# private
|
130
|
+
def gln_identifier
|
131
|
+
self.identifiers.select { |id| id.type.human == "Gln" }.first
|
132
|
+
end
|
128
133
|
end
|
129
|
-
end
|
130
134
|
|
131
|
-
|
132
|
-
|
133
|
-
|
135
|
+
module ProprietaryId
|
136
|
+
def proprietary_ids
|
137
|
+
self.identifiers.select { |id| id.type.human == "Proprietary" }
|
138
|
+
end
|
134
139
|
end
|
135
140
|
end
|
136
141
|
end
|