im_onix 1.0.2 → 1.1.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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -0
  3. data/.yardopts +1 -0
  4. data/Gemfile +8 -0
  5. data/LICENSE.md +7 -0
  6. data/README.md +3 -3
  7. data/Rakefile +10 -0
  8. data/bin/html_codelist_to_yml.rb +14 -15
  9. data/bin/onix_bench.rb +1 -0
  10. data/bin/onix_pp.rb +4 -8
  11. data/bin/onix_serialize.rb +27 -0
  12. data/doc-src/handlers.rb +154 -0
  13. data/im_onix.gemspec +32 -0
  14. data/lib/im_onix.rb +0 -1
  15. data/lib/onix/addressee.rb +10 -0
  16. data/lib/onix/code.rb +108 -282
  17. data/lib/onix/collateral_detail.rb +24 -17
  18. data/lib/onix/collection.rb +38 -0
  19. data/lib/onix/collection_sequence.rb +7 -0
  20. data/lib/onix/contributor.rb +40 -39
  21. data/lib/onix/date.rb +73 -109
  22. data/lib/onix/descriptive_detail.rb +90 -417
  23. data/lib/onix/discount_coded.rb +3 -16
  24. data/lib/onix/entity.rb +28 -62
  25. data/lib/onix/epub_usage_constraint.rb +7 -0
  26. data/lib/onix/epub_usage_limit.rb +6 -0
  27. data/lib/onix/extent.rb +39 -0
  28. data/lib/onix/helper.rb +25 -25
  29. data/lib/onix/identifier.rb +13 -54
  30. data/lib/onix/language.rb +8 -0
  31. data/lib/onix/market.rb +5 -0
  32. data/lib/onix/market_publishing_detail.rb +20 -0
  33. data/lib/onix/onix21.rb +76 -139
  34. data/lib/onix/onix_message.rb +87 -100
  35. data/lib/onix/price.rb +19 -39
  36. data/lib/onix/product.rb +141 -637
  37. data/lib/onix/product_form_feature.rb +7 -0
  38. data/lib/onix/product_part.rb +89 -0
  39. data/lib/onix/product_supplies_extractor.rb +275 -0
  40. data/lib/onix/product_supply.rb +17 -58
  41. data/lib/onix/publishing_detail.rb +16 -32
  42. data/lib/onix/related_material.rb +4 -3
  43. data/lib/onix/related_product.rb +9 -29
  44. data/lib/onix/related_work.rb +3 -17
  45. data/lib/onix/sales_outlet.rb +2 -10
  46. data/lib/onix/sales_restriction.rb +8 -21
  47. data/lib/onix/sales_rights.rb +1 -5
  48. data/lib/onix/sender.rb +12 -0
  49. data/lib/onix/serializer.rb +156 -0
  50. data/lib/onix/subject.rb +9 -30
  51. data/lib/onix/subset.rb +88 -78
  52. data/lib/onix/supply_detail.rb +42 -0
  53. data/lib/onix/supporting_resource.rb +29 -86
  54. data/lib/onix/tax.rb +9 -18
  55. data/lib/onix/territory.rb +23 -17
  56. data/lib/onix/title_detail.rb +22 -0
  57. data/lib/onix/title_element.rb +32 -0
  58. data/lib/onix/website.rb +3 -16
  59. metadata +53 -34
@@ -1,20 +1,7 @@
1
1
  module ONIX
2
2
  class DiscountCoded < SubsetDSL
3
- element "DiscountCodeType", :text
4
- element "DiscountCodeTypeName", :text
5
- element "DiscountCode", :text
6
-
7
- # shortcuts
8
- def code_type
9
- @discount_code_type
10
- end
11
-
12
- def code_type_name
13
- @discount_code_type_name
14
- end
15
-
16
- def code
17
- @discount_code
18
- end
3
+ element "DiscountCodeType", :text, :shortcut => :code_type
4
+ element "DiscountCodeTypeName", :text, :shortcut => :code_type_name
5
+ element "DiscountCode", :text, :shortcut => :code
19
6
  end
20
7
  end
@@ -5,6 +5,7 @@ require 'onix/website'
5
5
  module ONIX
6
6
  module EntityHelper
7
7
  end
8
+
8
9
  class Entity < SubsetDSL
9
10
  # entity name
10
11
  attr_accessor :name
@@ -37,16 +38,16 @@ module ONIX
37
38
  super
38
39
  n.children.each do |t|
39
40
  case t
40
- when tag_match(self.class.name_tag)
41
- @name=t.text
42
- when tag_match(self.class.role_tag)
43
- if self.class.role_class
44
- @role=self.class.role_class.parse(t)
45
- end
46
- when tag_match(self.class.identifier_tag)
47
- if self.class.identifier_class
48
- @identifiers << self.class.identifier_class.parse(t)
49
- end
41
+ when tag_match(self.class.name_tag)
42
+ @name = t.text
43
+ when tag_match(self.class.role_tag)
44
+ if self.class.role_class
45
+ @role = self.class.role_class.parse(t)
46
+ end
47
+ when tag_match(self.class.identifier_tag)
48
+ if self.class.identifier_class
49
+ @identifiers << self.class.identifier_class.parse(t)
50
+ end
50
51
  end
51
52
  end
52
53
  end
@@ -61,75 +62,40 @@ module ONIX
61
62
  def self.role_class
62
63
  nil
63
64
  end
64
- end
65
-
66
- class Agent < Entity
67
- def self.prefix
68
- "Agent"
69
- end
70
65
 
71
- def self.identifier_class
72
- AgentIdentifier
66
+ def self.entity_setup prefix, identifier, role = nil
67
+ define_singleton_method :prefix do
68
+ return prefix
69
+ end
70
+ define_singleton_method :identifier_class do
71
+ return identifier
72
+ end
73
+ define_singleton_method :role_class do
74
+ return role
75
+ end
73
76
  end
77
+ end
74
78
 
75
- def self.role_class
76
- AgentRole
77
- end
79
+ class Agent < Entity
80
+ entity_setup "Agent", AgentIdentifier, AgentRole
78
81
  end
79
82
 
80
83
  class Imprint < Entity
81
- def self.prefix
82
- "Imprint"
83
- end
84
-
85
- def self.identifier_class
86
- ImprintIdentifier
87
- end
88
-
89
- def self.role_class
90
- nil
91
- end
84
+ entity_setup "Imprint", ImprintIdentifier
92
85
  end
93
86
 
94
87
  class Supplier < Entity
95
88
  elements "Website", :subset
96
-
97
- def self.prefix
98
- "Supplier"
99
- end
100
-
101
- def self.identifier_class
102
- SupplierIdentifier
103
- end
104
-
105
- def self.role_class
106
- SupplierRole
107
- end
89
+ entity_setup "Supplier", SupplierIdentifier, SupplierRole
108
90
  end
109
91
 
110
92
  class Publisher < Entity
111
93
  elements "Website", :subset
94
+ entity_setup "Publisher", PublisherIdentifier, PublishingRole
112
95
 
113
- def initialize
114
- super
115
- @websites = []
116
- end
117
-
118
- def self.prefix
119
- "Publisher"
120
- end
121
-
96
+ # @note role tag is not PublisherRole but PublishingRole
122
97
  def self.role_tag
123
98
  "PublishingRole"
124
99
  end
125
-
126
- def self.identifier_class
127
- PublisherIdentifier
128
- end
129
-
130
- def self.role_class
131
- PublishingRole
132
- end
133
100
  end
134
-
135
101
  end
@@ -0,0 +1,7 @@
1
+ module ONIX
2
+ class EpubUsageConstraint < SubsetDSL
3
+ element "EpubUsageType", :subset, :shortcut => :type
4
+ element "EpubUsageStatus", :subset, :shortcut => :status
5
+ elements "EpubUsageLimit", :subset, :shortcut => :limits
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ module ONIX
2
+ class EpubUsageLimit < SubsetDSL
3
+ element "EpubUsageUnit", :subset, :shortcut => :unit
4
+ element "Quantity", :integer
5
+ end
6
+ end
@@ -0,0 +1,39 @@
1
+ module ONIX
2
+ class Extent < SubsetDSL
3
+ element "ExtentType", :subset, :shortcut => :type
4
+ element "ExtentUnit", :subset, :shortcut => :unit
5
+ element "ExtentValue", :text, :shortcut => :value
6
+
7
+ scope :filesize, lambda { human_code_match(:extent_type, /Filesize/) }
8
+ scope :page, lambda { human_code_match(:extent_type, /Page/) }
9
+
10
+ # @!group High level
11
+
12
+ # bytes count
13
+ # @return [Integer]
14
+ def bytes
15
+ case @extent_unit.human
16
+ when "Bytes"
17
+ @extent_value.to_i
18
+ when "Kbytes"
19
+ (@extent_value.to_f * 1024).to_i
20
+ when "Mbytes"
21
+ (@extent_value.to_f * 1024 * 1024).to_i
22
+ else
23
+ nil
24
+ end
25
+ end
26
+
27
+ # pages count
28
+ # @return [Integer]
29
+ def pages
30
+ if @extent_unit.human == "Pages"
31
+ @extent_value.to_i
32
+ else
33
+ nil
34
+ end
35
+ end
36
+
37
+ # @!endgroup
38
+ end
39
+ end
@@ -2,23 +2,23 @@ module ONIX
2
2
  class Helper
3
3
  # convert arbitrary arg to File/String
4
4
  def self.arg_to_data(arg)
5
- data=""
5
+ data = ""
6
6
  case arg
7
- when String
8
- if File.file?(arg)
9
- data=File.read(arg)
10
- else
11
- data=arg
12
- end
13
- when File, Tempfile
14
- data=arg.read
7
+ when String
8
+ if File.file?(arg)
9
+ data = File.read(arg)
10
+ else
11
+ data = arg
12
+ end
13
+ when File, Tempfile
14
+ data = arg.read
15
15
  end
16
16
  data
17
17
  end
18
18
 
19
19
  # traverse each product as xml string
20
- def self.each_xml_product(arg, &block)
21
- data=self.arg_to_data(arg)
20
+ def self.each_xml_product(arg, &block)
21
+ data = self.arg_to_data(arg)
22
22
  Nokogiri::XML::Reader(data).each do |node|
23
23
  if node.name == 'Product' and node.node_type == Nokogiri::XML::Reader::TYPE_ELEMENT
24
24
  yield(node.outer_xml)
@@ -29,11 +29,11 @@ module ONIX
29
29
  # traverse each product as xml string with added ONIXMessage
30
30
  def self.each_xml_product_as_full_message(arg, &block)
31
31
  self.each_xml_product(arg) do |p|
32
- yield("<ONIXMessage>\n"+p+"\n</ONIXMessage>\n")
32
+ yield("<ONIXMessage>\n" + p + "\n</ONIXMessage>\n")
33
33
  end
34
34
  end
35
35
 
36
- def self.text_at(n,xpath)
36
+ def self.text_at(n, xpath)
37
37
  if n.at_xpath(xpath)
38
38
  n.at_xpath(xpath).text.strip
39
39
  else
@@ -41,24 +41,24 @@ module ONIX
41
41
  end
42
42
  end
43
43
 
44
- def self.mandatory_text_at(n,xpath)
45
- self.text_at(n,xpath)
44
+ def self.mandatory_text_at(n, xpath)
45
+ self.text_at(n, xpath)
46
46
  end
47
47
 
48
48
  def self.strip_html(html)
49
- html.gsub(/&nbsp;/," ").gsub(/<[^>]*(>+|\s*\z)/m, '')
49
+ html.gsub(/&nbsp;/, " ").gsub(/<[^>]*(>+|\s*\z)/m, '')
50
50
  end
51
51
 
52
- def self.to_date(date_format,date_str_f)
52
+ def self.to_date(date_format, date_str_f)
53
53
  case date_format
54
- when "00"
55
- Date.strptime(date_str_f, "%Y%m%d")
56
- when "01"
57
- Date.strptime(date_str_f, "%Y%m")
58
- when "14"
59
- Time.strptime(date_str_f, "%Y%m%dT%H%M%S")
60
- else
61
- nil
54
+ when "00"
55
+ Date.strptime(date_str_f, "%Y%m%d")
56
+ when "01"
57
+ Date.strptime(date_str_f, "%Y%m")
58
+ when "14"
59
+ Time.strptime(date_str_f, "%Y%m%dT%H%M%S")
60
+ else
61
+ nil
62
62
  end
63
63
  end
64
64
 
@@ -1,15 +1,7 @@
1
1
  module ONIX
2
2
  class Identifier < SubsetDSL
3
- element "IDValue", :text
4
- element "IDTypeName", :text
5
-
6
- def value
7
- @id_value
8
- end
9
-
10
- def name
11
- @id_type_name
12
- end
3
+ element "IDValue", :text, :shortcut => :value
4
+ element "IDTypeName", :text, :shortcut => :name
13
5
 
14
6
  def type
15
7
  nil
@@ -21,80 +13,47 @@ module ONIX
21
13
  end
22
14
 
23
15
  class SenderIdentifier < Identifier
24
- element "SenderIDType", :subset
25
- def type
26
- @sender_id_type
27
- end
16
+ element "SenderIDType", :subset, :shortcut => :type
28
17
  end
29
18
 
30
19
  class AddresseeIdentifier < Identifier
31
- element "AddresseeIDType", :subset
32
- def type
33
- @addressee_id_type
34
- end
20
+ element "AddresseeIDType", :subset, :shortcut => :type
35
21
  end
36
22
 
37
23
  class AgentIdentifier < Identifier
38
- element "AgentIDType", :subset
39
- def type
40
- @agent_id_type
41
- end
24
+ element "AgentIDType", :subset, :shortcut => :type
42
25
  end
43
26
 
44
27
  class ImprintIdentifier < Identifier
45
- element "ImprintIDType", :subset
46
- def type
47
- @imprint_id_type
48
- end
28
+ element "ImprintIDType", :subset, :shortcut => :type
49
29
  end
50
30
 
51
31
  class PublisherIdentifier < Identifier
52
- element "PublisherIDType", :subset
53
- def type
54
- @publisher_id_type
55
- end
32
+ element "PublisherIDType", :subset, :shortcut => :type
56
33
  end
57
34
 
58
35
  class SupplierIdentifier < Identifier
59
- element "SupplierIDType", :subset
60
- def type
61
- @supplier_id_type
62
- end
36
+ element "SupplierIDType", :subset, :shortcut => :type
63
37
  end
64
38
 
65
39
  class NameIdentifier < Identifier
66
- element "NameIDType", :subset
67
- def type
68
- @name_id_type
69
- end
40
+ element "NameIDType", :subset, :shortcut => :type
70
41
  end
71
42
 
72
43
  class CollectionIdentifier < Identifier
73
- element "CollectionIDType", :subset
74
- def type
75
- @collection_id_type
76
- end
44
+ element "CollectionIDType", :subset, :shortcut => :type
77
45
  end
78
46
 
79
47
  class ProductIdentifier < Identifier
80
- element "ProductIDType", :subset
81
- def type
82
- @product_id_type
83
- end
48
+ element "ProductIDType", :subset, :shortcut => :type
84
49
  end
85
50
 
86
51
  class SalesOutletIdentifier < Identifier
87
- element "SalesOutletIDType", :subset
88
- def type
89
- @sales_outlet_id_type
90
- end
52
+ element "SalesOutletIDType", :subset, :shortcut => :type
91
53
  end
92
54
 
93
55
  class WorkIdentifier < Identifier
94
- element "WorkIDType", :subset
95
- def type
96
- @work_id_type
97
- end
56
+ element "WorkIDType", :subset, :shortcut => :type
98
57
  end
99
58
 
100
59
  module EanMethods
@@ -0,0 +1,8 @@
1
+ module ONIX
2
+ class Language < SubsetDSL
3
+ element "LanguageRole", :subset, :shortcut => :role
4
+ element "LanguageCode", :subset, :shortcut => :code
5
+
6
+ scope :of_text, lambda { human_code_match(:language_role, "LanguageOfText") }
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ module ONIX
2
+ class Market < SubsetDSL
3
+ element "Territory", :subset
4
+ end
5
+ end
@@ -0,0 +1,20 @@
1
+ module ONIX
2
+ class MarketPublishingDetail < SubsetDSL
3
+ elements "PublisherRepresentative", :subset, {:klass => "Agent"}
4
+ element "MarketPublishingStatus", :subset
5
+ elements "MarketDate", :subset
6
+
7
+ # @!group High level
8
+
9
+ # market availability date
10
+ # @return [Date]
11
+ def availability_date
12
+ av = @market_dates.availability.first
13
+ if av
14
+ av.date
15
+ end
16
+ end
17
+
18
+ # @!endgroup
19
+ end
20
+ end
@@ -2,13 +2,13 @@ module ONIX
2
2
  module ONIX21
3
3
  class ShortToRef
4
4
  def self.names
5
- @shortnames||=YAML.load(File.open(File.dirname(__FILE__) + "/../../data/onix21/shortnames.yml"))
5
+ @shortnames ||= YAML.load(File.open(File.dirname(__FILE__) + "/../../data/onix21/shortnames.yml"))
6
6
  end
7
7
  end
8
8
 
9
9
  class RefToShort
10
10
  def self.names
11
- @refnames||=ShortToRef.names.invert
11
+ @refnames ||= ShortToRef.names.invert
12
12
  end
13
13
  end
14
14
 
@@ -16,12 +16,13 @@ module ONIX
16
16
  def self.short_to_ref(name)
17
17
  ONIX::ONIX21::ShortToRef.names[name]
18
18
  end
19
+
19
20
  def self.ref_to_short(name)
20
21
  ONIX::ONIX21::RefToShort.names[name]
21
22
  end
22
23
 
23
24
  def self.get_class(name)
24
- if ONIX::ONIX21.const_defined?(name,false)
25
+ if ONIX::ONIX21.const_defined?(name, false)
25
26
  ONIX::ONIX21.const_get(name)
26
27
  else
27
28
  ONIX.const_get(name)
@@ -33,11 +34,11 @@ module ONIX
33
34
 
34
35
  class CodeFromYaml < Code
35
36
  def self.hash
36
- @hash||=YAML.load(File.open(File.dirname(__FILE__) + "/../../data/onix21/codelists/codelist-#{self.code_ident}.yml"))[:codelist]
37
+ @hash ||= YAML.load(File.open(File.dirname(__FILE__) + "/../../data/onix21/codelists/codelist-#{self.code_ident}.yml"))[:codelist]
37
38
  end
38
39
 
39
40
  def self.list
40
- self.hash.to_a.map{|h| h.first}
41
+ self.hash.to_a.map { |h| h.first }
41
42
  end
42
43
 
43
44
  def self.code_ident
@@ -47,6 +48,7 @@ module ONIX
47
48
 
48
49
  class EpubType < CodeFromYaml
49
50
  private
51
+
50
52
  def self.code_ident
51
53
  10
52
54
  end
@@ -54,6 +56,7 @@ module ONIX
54
56
 
55
57
  class TextTypeCode < CodeFromYaml
56
58
  private
59
+
57
60
  def self.code_ident
58
61
  33
59
62
  end
@@ -61,6 +64,7 @@ module ONIX
61
64
 
62
65
  class MediaFileTypeCode < CodeFromYaml
63
66
  private
67
+
64
68
  def self.code_ident
65
69
  38
66
70
  end
@@ -68,6 +72,7 @@ module ONIX
68
72
 
69
73
  class MediaFileFormatCode < CodeFromYaml
70
74
  private
75
+
71
76
  def self.code_ident
72
77
  36
73
78
  end
@@ -75,6 +80,7 @@ module ONIX
75
80
 
76
81
  class MediaFileLinkTypeCode < CodeFromYaml
77
82
  private
83
+
78
84
  def self.code_ident
79
85
  37
80
86
  end
@@ -83,95 +89,60 @@ module ONIX
83
89
  # ONIX 2.1 subset
84
90
 
85
91
  class Title < SubsetDSL
86
- element "TitleType", :subset
87
- element "TitleText", :text
92
+ element "TitleType", :subset, :shortcut => :type
93
+ element "TitleText", :text, :shortcut => :title
88
94
  element "TitlePrefix", :text
89
95
  element "TitleWithoutPrefix", :text
90
96
  element "AbbreviatedLength", :integer
91
97
  element "Subtitle", :text
92
-
93
- def type
94
- @title_type
95
- end
96
-
97
- def title
98
- @title_text
99
- end
100
98
  end
101
99
 
102
100
  class OtherText < SubsetDSL
103
- element "TextTypeCode", :subset
101
+ element "TextTypeCode", :subset, :shortcut => :type
104
102
  element "TextFormat", :text
105
103
  element "Text", :text
106
-
107
- def type
108
- @text_type_code
109
- end
104
+ element "TextLinkType", :text
105
+ element "TextLink", :text
110
106
  end
111
107
 
112
108
  class MediaFile < SubsetDSL
113
- element "MediaFileTypeCode", :subset
114
- element "MediaFileFormatCode", :subset
115
- element "MediaFileLinkTypeCode", :subset
116
- element "MediaFileLink", :text
117
-
118
- def type
119
- @media_file_type_code
120
- end
121
-
122
- def format
123
- @media_file_format_code
124
- end
125
-
126
- def link_type
127
- @media_file_link_type_code
128
- end
129
-
130
- def link
131
- @media_file_link
132
- end
109
+ element "MediaFileTypeCode", :subset, :shortcut => :type
110
+ element "MediaFileFormatCode", :subset, :shortcut => :format
111
+ element "MediaFileLinkTypeCode", :subset, :shortcut => :link_type
112
+ element "MediaFileLink", :text, :shortcut => :link
133
113
  end
134
114
 
135
115
  class Territory
136
116
  attr_accessor :countries
137
117
 
138
118
  def initialize(countries)
139
- @countries=countries
119
+ @countries = countries
140
120
  end
141
121
 
142
- def +v
122
+ def + v
143
123
  Territory.new((@countries + v.countries).uniq)
144
124
  end
145
125
 
146
- def -v
126
+ def - v
147
127
  Territory.new((@countries - v.countries).uniq)
148
128
  end
149
129
  end
150
130
 
151
131
  class Price < SubsetDSL
152
132
  element "PriceTypeCode", :subset, :klass => "PriceType"
153
- element "PriceAmount", :float, {:parse_lambda => lambda { |v| (v*100).round }}
154
- element "PriceQualifier", :subset
133
+ element "PriceAmount", :float, {
134
+ :shortcut => :amount,
135
+ :parse_lambda => lambda { |v| (v * 100).round }
136
+ }
137
+ element "PriceQualifier", :subset, :shortcut => :qualifier
155
138
  element "DiscountCoded", :subset
156
- element "CurrencyCode", :text
139
+ element "CurrencyCode", :text, :shortcut => :currency
157
140
  elements "CountryCode", :text
158
141
  element "PriceEffectiveFrom", :text
159
142
  element "PriceEffectiveUntil", :text
160
143
 
161
- def amount
162
- @price_amount
163
- end
164
-
165
- def currency
166
- @currency_code
167
- end
168
-
169
- def qualifier
170
- @price_qualifier
171
- end
172
-
173
144
  def including_tax?
174
- if @price_type_code.human =~/IncludingTax/
145
+ if @price_type_code.human =~ /IncludingTax/
175
146
  true
176
147
  else
177
148
  false
@@ -180,13 +151,13 @@ module ONIX
180
151
 
181
152
  def from_date
182
153
  if @price_effective_from
183
- Date.strptime(@price_effective_from,"%Y%m%d")
154
+ Date.strptime(@price_effective_from, "%Y%m%d")
184
155
  end
185
156
  end
186
157
 
187
158
  def until_date
188
159
  if @price_effective_until
189
- Date.strptime(@price_effective_until,"%Y%m%d")
160
+ Date.strptime(@price_effective_until, "%Y%m%d")
190
161
  end
191
162
  end
192
163
 
@@ -199,12 +170,11 @@ module ONIX
199
170
  end
200
171
  end
201
172
 
202
-
203
173
  class Supplier
204
174
  attr_accessor :name
205
175
  attr_accessor :role
206
176
 
207
- def initialize(name,role)
177
+ def initialize(name, role)
208
178
  @name = name
209
179
  @role = role
210
180
  end
@@ -225,19 +195,18 @@ module ONIX
225
195
 
226
196
  element "AvailabilityCode", :text
227
197
  element "ProductAvailability", :text
228
- element "OnSaleDate", :text, {:parse_lambda => lambda { |v| Date.strptime(v, "%Y%m%d") }}
198
+ element "OnSaleDate", :text, {
199
+ :shortcut => :availability_date,
200
+ :parse_lambda => lambda { |v| Date.strptime(v, "%Y%m%d") }
201
+ }
229
202
  elements "Price", :subset
230
203
 
231
- def availability_date
232
- @on_sale_date
233
- end
234
-
235
204
  def available?
236
- @product_availability=="20" or @availability_code == "IP"
205
+ @product_availability == "20" or @availability_code == "IP"
237
206
  end
238
207
 
239
208
  def suppliers
240
- [Supplier.new(self.supplier_name,self.supplier_role)]
209
+ [Supplier.new(self.supplier_name, self.supplier_role)]
241
210
  end
242
211
  end
243
212
 
@@ -246,7 +215,7 @@ module ONIX
246
215
  element "RightsCountry", :text
247
216
 
248
217
  def not_for_sale?
249
- ["03","04","05","06"].include?(@sales_rights_type)
218
+ ["03", "04", "05", "06"].include?(@sales_rights_type)
250
219
  end
251
220
 
252
221
  def territory
@@ -266,56 +235,31 @@ module ONIX
266
235
  include EanMethods
267
236
  include ProprietaryIdMethods
268
237
 
269
- element "RelationCode", :text
270
- elements "ProductIdentifier", :subset
271
-
272
- def product=v
273
- end
274
-
275
- def identifiers
276
- @product_identifiers
277
- end
238
+ element "RelationCode", :text, :shortcut => :code
239
+ elements "ProductIdentifier", :subset, :shortcut => :identifiers
278
240
 
279
- def code
280
- @relation_code
241
+ def product= v
281
242
  end
282
243
  end
283
244
 
284
245
  class MainSubject < SubsetDSL
285
- element "SubjectCode", :text
286
- element "SubjectHeadingText", :text
287
- element "MainSubjectSchemeIdentifier", :subset, :klass=>"SubjectSchemeIdentifier"
288
- element "SubjectSchemeName", :text
289
- element "SubjectSchemeVersion", :text
290
-
291
- # shortcuts
292
- def code
293
- @subject_code
294
- end
295
-
296
- def heading_text
297
- @subject_heading_text
298
- end
299
-
300
- def scheme_identifier
301
- @main_subject_scheme_identifier
302
- end
303
-
304
- def scheme_name
305
- @subject_scheme_name
306
- end
307
-
308
- def scheme_version
309
- @subject_scheme_version
310
- end
246
+ element "SubjectCode", :text, :shortcut => :code
247
+ element "SubjectHeadingText", :text, :shortcut => :heading_text
248
+ element "MainSubjectSchemeIdentifier", :subset, {
249
+ :shortcut => :scheme_identifier,
250
+ :klass => "SubjectSchemeIdentifier"
251
+ }
252
+ element "SubjectSchemeName", :text, :shortcut => :scheme_name
253
+ element "SubjectSchemeVersion", :text, :shortcut => :scheme_version
311
254
  end
312
255
 
313
256
  class Product < SubsetDSL
314
257
  include EanMethods
258
+ include IsbnMethods
315
259
  include ProprietaryIdMethods
316
260
 
317
261
  element "RecordReference", :text
318
- elements "ProductIdentifier", :subset
262
+ elements "ProductIdentifier", :subset, :shortcut => :identifiers
319
263
  element "NotificationType", :subset
320
264
  element "RecordSourceName", :text
321
265
  elements "Title", :subset
@@ -347,7 +291,7 @@ module ONIX
347
291
  element "PublishingStatus", :text
348
292
  element "PublicationDate", :text, {:parse_lambda => lambda { |v| Date.strptime(v, "%Y%m%d") }}
349
293
 
350
- elements "RelatedProduct", :subset
294
+ elements "RelatedProduct", :subset, :shortcut => :related
351
295
 
352
296
  elements "SupplyDetail", :subset
353
297
 
@@ -360,45 +304,41 @@ module ONIX
360
304
  element "NoEdition", :ignore
361
305
  element "NoSeries", :ignore
362
306
 
363
- # shortcuts
364
- def identifiers
365
- @product_identifiers
366
- end
367
-
368
307
  # default LanguageCode from ONIXMessage
369
308
  attr_accessor :default_language_of_text
370
309
  # default code from ONIXMessage
371
310
  attr_accessor :default_currency_code
372
311
 
312
+ # @!group High level
313
+
373
314
  def title
374
315
  product_title.title
375
316
  end
376
317
 
377
- # :category: High level
378
318
  # product subtitle string
379
319
  def subtitle
380
320
  product_title.subtitle
381
321
  end
382
322
 
383
323
  def product_title
384
- @titles.select { |td| td.type.human=~/DistinctiveTitle/ }.first
324
+ @titles.select { |td| td.type.human =~ /DistinctiveTitle/ }.first
385
325
  end
386
326
 
387
327
  def bisac_categories_codes
388
- cats=[]
328
+ cats = []
389
329
  if @basic_main_subject
390
330
  cats << @basic_main_subject
391
331
  end
392
- cats+=(@main_subjects + @subjects).select { |s| s.scheme_identifier.human=="BisacSubjectHeading" }.map{|s| s.code}
332
+ cats += (@main_subjects + @subjects).select { |s| s.scheme_identifier.human == "BisacSubjectHeading" }.map { |s| s.code }
393
333
  cats
394
334
  end
395
335
 
396
336
  def clil_categories_codes
397
- (@main_subjects + @subjects).select { |s| s.scheme_identifier.human=="Clil" }.map{|s| s.code}
337
+ (@main_subjects + @subjects).select { |s| s.scheme_identifier.human == "Clil" }.map { |s| s.code }
398
338
  end
399
339
 
400
340
  def keywords
401
- kws=(@main_subjects + @subjects).select { |s| s.scheme_identifier.human=="Keywords" }.map { |kw| kw.heading_text }.compact
341
+ kws = (@main_subjects + @subjects).select { |s| s.scheme_identifier.human == "Keywords" }.map { |kw| kw.heading_text }.compact
402
342
  kws.map { |kw| kw.split(/;|,|\n/) }.flatten.map { |kw| kw.strip }
403
343
  end
404
344
 
@@ -409,10 +349,10 @@ module ONIX
409
349
 
410
350
  # product LanguageCode of text
411
351
  def language_of_text
412
- lang=nil
413
- l=@languages.select { |l| l.role.human=="LanguageOfText" }.first
352
+ lang = nil
353
+ l = @languages.select { |l| l.role.human == "LanguageOfText" }.first
414
354
  if l
415
- lang=l.code
355
+ lang = l.code
416
356
  end
417
357
  lang || @default_language_of_text
418
358
  end
@@ -447,7 +387,7 @@ module ONIX
447
387
  end
448
388
 
449
389
  def description
450
- desc_contents=@other_texts.select{|tc| tc.type.human=="MainDescription"} + @other_texts.select{|tc| tc.type.human=="LongDescription"} + @other_texts.select{|tc| tc.type.human=="ShortDescriptionannotation"}
390
+ desc_contents = @other_texts.select { |tc| tc.type.human == "MainDescription" } + @other_texts.select { |tc| tc.type.human == "LongDescription" } + @other_texts.select { |tc| tc.type.human == "ShortDescriptionannotation" }
451
391
  if desc_contents.length > 0
452
392
  desc_contents.first.text
453
393
  else
@@ -468,17 +408,17 @@ module ONIX
468
408
  end
469
409
 
470
410
  def countries
471
- territory=Territory.new(CountryCode.list)
411
+ territory = Territory.new(CountryCode.list)
472
412
  @sales_rights.each do |sr|
473
413
  if sr.not_for_sale?
474
- territory=territory-sr.territory
414
+ territory = territory - sr.territory
475
415
  else
476
- territory=territory+sr.territory
416
+ territory = territory + sr.territory
477
417
  end
478
418
  end
479
419
 
480
420
  @not_for_sales.each do |sr|
481
- territory=territory-sr.territory
421
+ territory = territory - sr.territory
482
422
  end
483
423
 
484
424
  territory.countries
@@ -502,10 +442,6 @@ module ONIX
502
442
 
503
443
  include ProductSuppliesExtractor
504
444
 
505
- def related
506
- @related_products
507
- end
508
-
509
445
  # doesn't apply
510
446
  def parts
511
447
  []
@@ -517,7 +453,7 @@ module ONIX
517
453
  end
518
454
 
519
455
  def digital?
520
- @product_form=="DG"
456
+ @product_form == "DG"
521
457
  end
522
458
 
523
459
  def available?
@@ -525,7 +461,7 @@ module ONIX
525
461
  end
526
462
 
527
463
  def available_for_country?(country)
528
- self.supplies_for_country(country).select{|s| s[:available]}.length > 0 and self.available?
464
+ self.supplies_for_country(country).select { |s| s[:available] }.length > 0 and self.available?
529
465
  end
530
466
 
531
467
  def pages
@@ -543,7 +479,7 @@ module ONIX
543
479
  end
544
480
 
545
481
  def frontcover_url
546
- fc=@media_files.select { |mf| mf.media_file_type_code.human=="ImageFrontCover" && mf.media_file_link_type_code.human=="Url"}
482
+ fc = @media_files.select { |mf| mf.media_file_type_code.human == "ImageFrontCover" && mf.media_file_link_type_code.human == "Url" }
547
483
  if fc.length > 0
548
484
  fc.first.link
549
485
  else
@@ -551,7 +487,7 @@ module ONIX
551
487
  end
552
488
  end
553
489
 
554
- # TODO
490
+ # TODO
555
491
  def publisher_collection_title
556
492
  nil
557
493
  end
@@ -583,7 +519,7 @@ module ONIX
583
519
  end
584
520
 
585
521
  def print_product
586
- @related_products.select { |rp| rp.code=="13" }.first
522
+ @related_products.select { |rp| rp.code == "13" }.first
587
523
  end
588
524
 
589
525
  # DEPRECATED see print_product instead
@@ -595,10 +531,11 @@ module ONIX
595
531
  nil
596
532
  end
597
533
 
534
+ # @!endgroup
535
+
598
536
  def method_missing(method)
599
537
  raise "WARN #{method} not found"
600
538
  end
601
-
602
539
  end
603
540
  end
604
541
  end