milkfarm-onix 0.7.7 → 0.8.3

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.
Files changed (64) hide show
  1. data/CHANGELOG +31 -1
  2. data/README.markdown +24 -2
  3. data/lib/onix.rb +3 -16
  4. data/lib/onix/addressee_identifier.rb +0 -1
  5. data/lib/onix/apa_product.rb +19 -2
  6. data/lib/onix/audience_range.rb +6 -7
  7. data/lib/onix/contributor.rb +0 -1
  8. data/lib/onix/header.rb +0 -1
  9. data/lib/onix/imprint.rb +0 -1
  10. data/lib/onix/language.rb +0 -1
  11. data/lib/onix/lists/contributor_role.rb +99 -0
  12. data/lib/onix/market_representation.rb +0 -1
  13. data/lib/onix/measure.rb +0 -1
  14. data/lib/onix/media_file.rb +0 -1
  15. data/lib/onix/normaliser.rb +0 -77
  16. data/lib/onix/other_text.rb +0 -1
  17. data/lib/onix/price.rb +0 -1
  18. data/lib/onix/product.rb +3 -2
  19. data/lib/onix/product_identifier.rb +0 -1
  20. data/lib/onix/publisher.rb +0 -1
  21. data/lib/onix/reader.rb +39 -96
  22. data/lib/onix/sales_restriction.rb +0 -1
  23. data/lib/onix/sender_identifier.rb +0 -1
  24. data/lib/onix/series.rb +8 -8
  25. data/lib/onix/series_identifier.rb +0 -1
  26. data/lib/onix/set.rb +76 -0
  27. data/lib/onix/sl_product.rb +32 -45
  28. data/lib/onix/stock.rb +0 -1
  29. data/lib/onix/subject.rb +0 -1
  30. data/lib/onix/supply_detail.rb +0 -1
  31. data/lib/onix/title.rb +0 -1
  32. data/lib/onix/website.rb +0 -1
  33. data/lib/onix/writer.rb +1 -1
  34. data/spec/apa_product_spec.rb +44 -4
  35. data/spec/audience_range_spec.rb +5 -7
  36. data/spec/contributor_spec.rb +2 -4
  37. data/spec/header_spec.rb +2 -4
  38. data/spec/imprint_spec.rb +4 -6
  39. data/spec/language_spec.rb +5 -7
  40. data/spec/market_representation_spec.rb +2 -4
  41. data/spec/measure_spec.rb +2 -4
  42. data/spec/media_file_spec.rb +2 -4
  43. data/spec/normaliser_spec.rb +1 -78
  44. data/spec/other_text_spec.rb +2 -4
  45. data/spec/price_spec.rb +2 -4
  46. data/spec/product_identifier_spec.rb +2 -4
  47. data/spec/product_spec.rb +2 -5
  48. data/spec/publisher_spec.rb +2 -4
  49. data/spec/reader_spec.rb +15 -22
  50. data/spec/sales_restriction_spec.rb +2 -4
  51. data/spec/sender_identifier.rb +2 -4
  52. data/spec/series_identifier_spec.rb +5 -7
  53. data/spec/series_spec.rb +4 -6
  54. data/spec/set_spec.rb +32 -0
  55. data/spec/sl_product_spec.rb +76 -24
  56. data/spec/spec_helper.rb +8 -0
  57. data/spec/stock_spec.rb +2 -4
  58. data/spec/subject_spec.rb +2 -4
  59. data/spec/supply_detail_spec.rb +2 -4
  60. data/spec/title_spec.rb +2 -4
  61. data/spec/website_spec.rb +2 -4
  62. data/spec/writer_spec.rb +1 -4
  63. metadata +64 -28
  64. data/lib/onix/common.rb +0 -26
@@ -3,7 +3,6 @@
3
3
  module ONIX
4
4
  class OtherText
5
5
  include ROXML
6
- include ONIX::Common
7
6
 
8
7
  xml_name "OtherText"
9
8
 
data/lib/onix/price.rb CHANGED
@@ -3,7 +3,6 @@
3
3
  module ONIX
4
4
  class Price
5
5
  include ROXML
6
- include ONIX::Common
7
6
 
8
7
  xml_name "Price"
9
8
 
data/lib/onix/product.rb CHANGED
@@ -3,16 +3,16 @@
3
3
  module ONIX
4
4
  class Product
5
5
  include ROXML
6
- include ONIX::Common
7
6
 
8
7
  xml_name "Product"
9
-
8
+
10
9
  xml_accessor :record_reference, :from => "RecordReference"
11
10
  xml_accessor :notification_type, :from => "NotificationType", :as => Fixnum, :to_xml => ONIX::Formatters.two_digit
12
11
  xml_accessor :product_identifiers, :from => "ProductIdentifier", :as => [ONIX::ProductIdentifier]
13
12
  xml_accessor :product_form, :from => "ProductForm"
14
13
  xml_accessor :product_form_detail, :from => "ProductFormDetail"
15
14
  xml_accessor :series, :from => "Series", :as => [ONIX::Series]
15
+ xml_accessor :sets, :from => "Set", :as => [ONIX::Set]
16
16
  xml_accessor :titles, :from => "Title", :as => [ONIX::Title]
17
17
  xml_accessor :websites, :from => "Website", :as => [ONIX::Website]
18
18
  xml_accessor :contributors, :from => "Contributor", :as => [ONIX::Contributor]
@@ -54,6 +54,7 @@ module ONIX
54
54
  def initialize
55
55
  self.product_identifiers = []
56
56
  self.series = []
57
+ self.sets = []
57
58
  self.titles = []
58
59
  self.contributors = []
59
60
  self.websites = []
@@ -3,7 +3,6 @@
3
3
  module ONIX
4
4
  class ProductIdentifier
5
5
  include ROXML
6
- include ONIX::Common
7
6
 
8
7
  xml_name "ProductIdentifier"
9
8
 
@@ -3,7 +3,6 @@
3
3
  module ONIX
4
4
  class Publisher
5
5
  include ROXML
6
- include ONIX::Common
7
6
 
8
7
  xml_name "Publisher"
9
8
 
data/lib/onix/reader.rb CHANGED
@@ -53,31 +53,39 @@ module ONIX
53
53
  class Reader
54
54
  include Enumerable
55
55
 
56
- attr_reader :header , :version, :xml_lang, :xml_version, :encoding
56
+ attr_reader :header, :release
57
57
 
58
58
  def initialize(input, product_klass = ::ONIX::Product)
59
59
  if input.kind_of?(String)
60
- @reader = LibXML::XML::Reader.file(input)
60
+ @file = File.open(input, "r")
61
+ @reader = Nokogiri::XML::Reader(@file) { |cfg| cfg.dtdload.noent }
61
62
  elsif input.kind_of?(IO)
62
- @reader = LibXML::XML::Reader.io(input)
63
+ @reader = Nokogiri::XML::Reader(input) { |cfg| cfg.dtdload.noent }
63
64
  else
64
65
  raise ArgumentError, "Unable to read from file or IO stream"
65
66
  end
66
67
 
67
68
  @product_klass = product_klass
68
69
 
69
- @header = read_next
70
+ @release = find_release
71
+ @header = find_header
70
72
 
71
- @xml_lang ||= @reader.xml_lang
73
+ @xml_lang ||= @reader.lang
72
74
  @xml_version ||= @reader.xml_version.to_f
73
- @encoding ||= encoding_const_to_name(@reader.encoding)
74
75
  end
75
76
 
76
77
  # Iterate over all the products in an ONIX file
77
78
  #
78
79
  def each(&block)
79
- while obj = read_next
80
- yield obj
80
+ @reader.each do |node|
81
+ if @reader.node_type == 1 && @reader.name == "Product"
82
+ str = @reader.outer_xml
83
+ if str.nil?
84
+ yield @product_klass.new
85
+ else
86
+ yield @product_klass.from_xml(str)
87
+ end
88
+ end
81
89
  end
82
90
  end
83
91
 
@@ -87,101 +95,36 @@ module ONIX
87
95
 
88
96
  private
89
97
 
90
- # Walk the ONIX file, and grab the next header or product fragment.
91
- #
92
- def read_next
93
- while @reader.read
94
-
95
- if @reader.node_type == LibXML::XML::Reader::TYPE_DOCUMENT_TYPE
96
- # TODO restore ONIX version extraction. The following expand()
97
- # call is triggering unpredictable behaviour in libxml-ruby
98
- # 1.1.3 with libxml2 2.7.3. Sometimes segfaults, othertimes
99
- # cryptic errors about the input file being truncated or
100
- # incomplete
101
- #uri = @reader.expand.to_s.dup
102
- #m, major, minor, rev = *uri.match(/.+(\d)\.(\d)\/(\d*).*/)
103
- #@version = [major.to_i, minor.to_i, rev.to_i]
104
- elsif @reader.node_type == LibXML::XML::Reader::TYPE_ELEMENT
105
- if @reader.name == "Header"
106
- str = normalise_string_encoding(@reader.read_outer_xml.to_s.dup)
107
- if str.size == 0
108
- return ONIX::Header.new
109
- else
110
- return ONIX::Header.from_xml(str)
111
- end
112
- elsif @reader.name == "Product"
113
- str = normalise_string_encoding(@reader.read_outer_xml.to_s.dup)
114
- if str.size == 0
115
- return @product_klass.new
116
- else
117
- return @product_klass.from_xml(str)
118
- end
98
+ def find_release
99
+ 2.times do
100
+ @reader.read
101
+ if @reader.node_type == 1 && @reader.name == "ONIXMessage"
102
+ value = @reader.attributes["release"]
103
+ if value
104
+ return BigDecimal.new(value)
105
+ else
106
+ return nil
119
107
  end
108
+ elsif @reader.node_type == 14
109
+ return nil
120
110
  end
121
111
  end
122
-
123
- return nil
124
- rescue LibXML::XML::Error => e
125
112
  return nil
126
113
  end
127
114
 
128
- # XML::Reader seems to transparently convert all input data to utf-8, howver
129
- # on Ruby 1.9 it fails to correctly set the encoding on the strings.
130
- #
131
- def normalise_string_encoding(str)
132
- if RUBY_VERSION >= "1.9"
133
- return str.dup.force_encoding("utf-8")
134
- else
135
- str
136
- end
137
- end
138
-
139
- # simple mapping of encoding constants to a string
140
- #
141
- def encoding_const_to_name(const)
142
- return nil if const.nil?
143
- case const
144
- when LibXML::XML::Encoding::UTF_8
145
- "utf-8"
146
- when LibXML::XML::Encoding::UTF_16LE
147
- "utf-16le"
148
- when LibXML::XML::Encoding::UTF_16BE
149
- "utf-16be"
150
- when LibXML::XML::Encoding::UCS_4LE
151
- "ucs-4le"
152
- when LibXML::XML::Encoding::UCS_4BE
153
- "ucs-4be"
154
- when LibXML::XML::Encoding::UCS_2
155
- "ucs-2"
156
- when LibXML::XML::Encoding::ISO_8859_1
157
- "iso-8859-1"
158
- when LibXML::XML::Encoding::ISO_8859_2
159
- "iso-8859-2"
160
- when LibXML::XML::Encoding::ISO_8859_3
161
- "iso-8859-3"
162
- when LibXML::XML::Encoding::ISO_8859_4
163
- "iso-8859-4"
164
- when LibXML::XML::Encoding::ISO_8859_5
165
- "iso-8859-5"
166
- when LibXML::XML::Encoding::ISO_8859_6
167
- "iso-8859-6"
168
- when LibXML::XML::Encoding::ISO_8859_7
169
- "iso-8859-7"
170
- when LibXML::XML::Encoding::ISO_8859_8
171
- "iso-8859-8"
172
- when LibXML::XML::Encoding::ISO_8859_9
173
- "iso-8859-9"
174
- when LibXML::XML::Encoding::ISO_2022_JP
175
- "iso-2022-jp"
176
- when LibXML::XML::Encoding::SHIFT_JIS
177
- "shift-jis"
178
- when LibXML::XML::Encoding::EUC_JP
179
- "euc-jp"
180
- when LibXML::XML::Encoding::ASCII
181
- "ascii"
182
- else
183
- nil
115
+ def find_header
116
+ 100.times do
117
+ @reader.read
118
+ if @reader.node_type == 1 && @reader.name == "Header"
119
+ str = @reader.outer_xml
120
+ if str.nil?
121
+ return ONIX::Header.new
122
+ else
123
+ return ONIX::Header.from_xml(str)
124
+ end
125
+ end
184
126
  end
127
+ return nil
185
128
  end
186
129
  end
187
130
  end
@@ -3,7 +3,6 @@
3
3
  module ONIX
4
4
  class SalesRestriction
5
5
  include ROXML
6
- include ONIX::Common
7
6
 
8
7
  xml_name "SalesRestriction"
9
8
 
@@ -3,7 +3,6 @@
3
3
  module ONIX
4
4
  class SenderIdentifier
5
5
  include ROXML
6
- include ONIX::Common
7
6
 
8
7
  xml_name "SenderIdentifier"
9
8
 
data/lib/onix/series.rb CHANGED
@@ -3,17 +3,16 @@
3
3
  module ONIX
4
4
  class Series
5
5
  include ROXML
6
- include ONIX::Common
7
6
 
8
7
  xml_name "Series"
9
8
 
10
9
  xml_accessor :series_identifiers, :from => "SeriesIdentifier", :as => [ONIX::SeriesIdentifier]
11
10
  xml_accessor :title_of_series, :from => "TitleOfSeries"
12
-
11
+
13
12
  def initialize
14
13
  self.series_identifiers = []
15
14
  end
16
-
15
+
17
16
  # retrieve the proprietary series ID
18
17
  def proprietary_series_id
19
18
  series_identifier(1).andand.id_value
@@ -23,7 +22,7 @@ module ONIX
23
22
  def proprietary_series_id=(id)
24
23
  series_identifier_set(1, id)
25
24
  end
26
-
25
+
27
26
  # retrieve the issn
28
27
  def issn
29
28
  series_identifier(2).andand.id_value
@@ -33,7 +32,7 @@ module ONIX
33
32
  def issn=(id)
34
33
  series_identifier_set(2, id)
35
34
  end
36
-
35
+
37
36
  # retrieve the value of a particular ID
38
37
  def series_identifier(type)
39
38
  identifier = series_identifiers.find { |id| id.series_id_type == type }
@@ -42,16 +41,17 @@ module ONIX
42
41
  # set the value of a particular ID
43
42
  def series_identifier_set(type, value)
44
43
  series_indentifier_id = series_identifiers.find { |id| id.series_id_type == type }
45
-
44
+
46
45
  # create a new series identifier record if we need to
47
46
  if series_indentifier_id.nil?
48
47
  series_indentifier_id = ONIX::SeriesIdentifier.new
49
48
  end
50
-
49
+
51
50
  series_indentifier_id.series_id_type = type
52
51
  series_indentifier_id.id_value = value
53
-
52
+
54
53
  series_identifiers << series_indentifier_id
55
54
  end
55
+
56
56
  end
57
57
  end
@@ -3,7 +3,6 @@
3
3
  module ONIX
4
4
  class SeriesIdentifier
5
5
  include ROXML
6
- include ONIX::Common
7
6
 
8
7
  xml_name "SeriesIdentifier"
9
8
 
data/lib/onix/set.rb ADDED
@@ -0,0 +1,76 @@
1
+ # coding: utf-8
2
+
3
+ module ONIX
4
+ class Set
5
+ include ROXML
6
+
7
+ xml_name "Set"
8
+
9
+ xml_accessor :product_identifiers, :from => "ProductIdentifier", :as => [ONIX::ProductIdentifier]
10
+ xml_accessor :title_of_set, :from => "TitleOfSet"
11
+
12
+ def initialize
13
+ self.product_identifiers = []
14
+ end
15
+
16
+ # retrieve the proprietary set ID
17
+ def proprietary_set_id
18
+ product_identifier(1).andand.id_value
19
+ end
20
+
21
+ # set a new proprietary set ID
22
+ def proprietary_set_id=(id)
23
+ product_identifier_set(1, id)
24
+ end
25
+
26
+ # retrieve the 10-digit isbn
27
+ def isbn10
28
+ product_identifier(2).andand.id_value
29
+ end
30
+
31
+ # set a new 10-digit isbn
32
+ def isbn10=(id)
33
+ product_identifier_set(2, id)
34
+ end
35
+
36
+ # retrieve the 13-digit isbn
37
+ def isbn
38
+ product_identifier(15).andand.id_value
39
+ end
40
+
41
+ # set a new 13-digit isbn
42
+ def isbn=(id)
43
+ product_identifier_set(15, id)
44
+ end
45
+
46
+ # retrieve the lccn
47
+ def lccn
48
+ product_identifier(13).andand.id_value
49
+ end
50
+
51
+ # set a new lccn
52
+ def lccn=(id)
53
+ product_identifier_set(13, id)
54
+ end
55
+
56
+ # retrieve the value of a particular ID
57
+ def product_identifier(type)
58
+ identifier = product_identifiers.find { |id| id.product_id_type == type }
59
+ end
60
+
61
+ # set the value of a particular ID
62
+ def product_identifier_set(type, value)
63
+ product_identifier_id = product_identifiers.find { |id| id.product_id_type == type }
64
+
65
+ # create a new set identifier record if we need to
66
+ if product_identifier_id.nil?
67
+ product_identifier_id = ONIX::ProductIdentifier.new
68
+ end
69
+
70
+ product_identifier_id.product_id_type = type
71
+ product_identifier_id.id_value = value
72
+
73
+ product_identifiers << product_identifier_id
74
+ end
75
+ end
76
+ end
@@ -2,18 +2,11 @@
2
2
 
3
3
  module ONIX
4
4
  class SLProduct < APAProduct
5
-
5
+
6
6
  delegate :audience_code, :audience_code=
7
7
  delegate :copyright_year, :copyright_year=
8
8
  delegate :product_form_detail, :product_form_detail=
9
9
 
10
- alias_method :old_initialize, :initialize
11
- def initialize(*args)
12
- result = old_initialize(*args)
13
- result.audience_code = 4 # Primary & secondary/elementary & high school
14
- result
15
- end
16
-
17
10
  # retrieve the value of a particular ID
18
11
  def series(str)
19
12
  product.series.find { |id| id.title_of_series == str }
@@ -36,47 +29,41 @@ module ONIX
36
29
  end
37
30
  end
38
31
 
39
- # retrieve the "language of text" (role=1) language code for this particular product
40
- def language_code
41
- language(1).andand.language_code
42
- end
43
-
44
- # set a new "language of text" (role=1) language code for this particular product
45
- def language_code=(str)
46
- language_set(1, str)
47
- end
48
-
49
- # retrieve the "language of text" (role=1) country code for this particular product
50
- def country_code
51
- language(1).andand.country_code
32
+ # retrieve the value of a particular ID
33
+ def set(str)
34
+ product.sets.find { |id| id.title_of_set == str }
52
35
  end
53
36
 
54
- # set a new "language of text" (role=1) country code for this particular product
55
- def country_code=(str)
56
- language_set(1, language_code, str)
37
+ # set the value of a particular ID
38
+ def set=(value)
39
+ # process based on value type
40
+ if value.is_a?(Set)
41
+ str = value.title_of_set
42
+ set_id = value
43
+ else
44
+ str = value
45
+ set_id = ONIX::Set.new
46
+ set_id.title_of_set = value
47
+ end
48
+ # check if exists already
49
+ unless set(str)
50
+ product.sets << set_id
51
+ end
57
52
  end
58
53
 
59
- # retrieve the value of a particular language
60
- def language(type)
61
- product.languages.find { |l| l.language_role == type }
54
+ # retrieve an array of all languages
55
+ def languages
56
+ product.languages.collect { |language| language.language_code}
62
57
  end
63
58
 
64
- # set the value of a particular language
65
- def language_set(type, value, value2=nil)
66
- l = language(type)
67
-
68
- # create a new language record if we need to
69
- if l.nil?
70
- l = ONIX::Language.new
71
- l.language_role = type
72
- product.languages << l
73
- end
74
-
75
- # cannot set country_code without language_code
76
- unless value.nil?
77
- l.language_code = value.to_s # mandatory
78
- l.country_code = value2.to_s if value2 # optional
79
- end
59
+ # set a new language to this product
60
+ # str should be the languages name code (US)
61
+ def add_language(str, role = "1", country = "US")
62
+ language = ::ONIX::Language.new
63
+ language.language_role = role
64
+ language.language_code = str
65
+ language.country_code = country
66
+ product.languages << language
80
67
  end
81
68
 
82
69
  # retrieve the dewey for this title
@@ -99,7 +86,7 @@ module ONIX
99
86
  def us_grade_range=(range=[])
100
87
  audience_range_set(11, range[0], range[1])
101
88
  end
102
-
89
+
103
90
  # retrieve the value of a particular audience range
104
91
  def audience_range(type)
105
92
  product.audience_ranges.find { |a| a.audience_range_qualifier == type }
@@ -126,6 +113,6 @@ module ONIX
126
113
  end
127
114
  a.audience_range_precisions = ["01"] if min.nil? || max.nil?
128
115
  end
129
-
116
+
130
117
  end
131
118
  end