onix2 1.0.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.
Files changed (240) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +209 -0
  3. data/README.markdown +69 -0
  4. data/TODO +14 -0
  5. data/dtd/2.1r3/iso-amsa.ent +173 -0
  6. data/dtd/2.1r3/iso-amsb.ent +146 -0
  7. data/dtd/2.1r3/iso-amsc.ent +49 -0
  8. data/dtd/2.1r3/iso-amsn.ent +117 -0
  9. data/dtd/2.1r3/iso-amso.ent +77 -0
  10. data/dtd/2.1r3/iso-amsr.ent +205 -0
  11. data/dtd/2.1r3/iso-box.ent +67 -0
  12. data/dtd/2.1r3/iso-cyr1.ent +94 -0
  13. data/dtd/2.1r3/iso-cyr2.ent +53 -0
  14. data/dtd/2.1r3/iso-dia.ent +41 -0
  15. data/dtd/2.1r3/iso-grk3.ent +70 -0
  16. data/dtd/2.1r3/iso-lat1.ent +89 -0
  17. data/dtd/2.1r3/iso-lat2.ent +148 -0
  18. data/dtd/2.1r3/iso-mfrk.ent +79 -0
  19. data/dtd/2.1r3/iso-mopf.ent +53 -0
  20. data/dtd/2.1r3/iso-mscr.ent +79 -0
  21. data/dtd/2.1r3/iso-num.ent +103 -0
  22. data/dtd/2.1r3/iso-num.old.ent +103 -0
  23. data/dtd/2.1r3/iso-pub.ent +110 -0
  24. data/dtd/2.1r3/iso-tech.ent +183 -0
  25. data/dtd/2.1r3/onix-international.dtd +1012 -0
  26. data/dtd/2.1r3/onix-xhtml.elt +672 -0
  27. data/dtd/2.1r3/reference.elt +4758 -0
  28. data/dtd/2.1r3/xhtml-special.ent +79 -0
  29. data/dtd/2.1r3/xhtml-symbol.ent +242 -0
  30. data/lib/onix2.rb +85 -0
  31. data/lib/onix2/addressee_identifier.rb +29 -0
  32. data/lib/onix2/apa_product.rb +785 -0
  33. data/lib/onix2/audience_range.rb +37 -0
  34. data/lib/onix2/code_list_extractor.rb +69 -0
  35. data/lib/onix2/contributor.rb +55 -0
  36. data/lib/onix2/discount_coded.rb +29 -0
  37. data/lib/onix2/header.rb +68 -0
  38. data/lib/onix2/imprint.rb +31 -0
  39. data/lib/onix2/language.rb +29 -0
  40. data/lib/onix2/lists.rb +134 -0
  41. data/lib/onix2/market_representation.rb +38 -0
  42. data/lib/onix2/measure.rb +29 -0
  43. data/lib/onix2/media_file.rb +33 -0
  44. data/lib/onix2/other_text.rb +35 -0
  45. data/lib/onix2/price.rb +47 -0
  46. data/lib/onix2/product.rb +97 -0
  47. data/lib/onix2/product_identifier.rb +27 -0
  48. data/lib/onix2/publisher.rb +33 -0
  49. data/lib/onix2/reader.rb +157 -0
  50. data/lib/onix2/sales_restriction.rb +25 -0
  51. data/lib/onix2/sales_rights.rb +28 -0
  52. data/lib/onix2/sender_identifier.rb +29 -0
  53. data/lib/onix2/series.rb +28 -0
  54. data/lib/onix2/series_identifier.rb +27 -0
  55. data/lib/onix2/simple_product.rb +47 -0
  56. data/lib/onix2/stock.rb +29 -0
  57. data/lib/onix2/subject.rb +33 -0
  58. data/lib/onix2/supply_detail.rb +53 -0
  59. data/lib/onix2/title.rb +33 -0
  60. data/lib/onix2/version.rb +3 -0
  61. data/lib/onix2/website.rb +29 -0
  62. data/lib/onix2/writer.rb +86 -0
  63. data/spec/addressee_identifier_spec.rb +33 -0
  64. data/spec/apa_product_spec.rb +116 -0
  65. data/spec/audience_range_spec.rb +44 -0
  66. data/spec/contributor_spec.rb +38 -0
  67. data/spec/discount_coded_spec.rb +34 -0
  68. data/spec/header_spec.rb +153 -0
  69. data/spec/imprint_spec.rb +31 -0
  70. data/spec/language_spec.rb +38 -0
  71. data/spec/lists_spec.rb +33 -0
  72. data/spec/market_representation_spec.rb +33 -0
  73. data/spec/measure_spec.rb +38 -0
  74. data/spec/media_file_spec.rb +38 -0
  75. data/spec/other_text_spec.rb +33 -0
  76. data/spec/price_spec.rb +52 -0
  77. data/spec/product_identifier_spec.rb +34 -0
  78. data/spec/product_spec.rb +102 -0
  79. data/spec/publisher_spec.rb +33 -0
  80. data/spec/reader_spec.rb +155 -0
  81. data/spec/sales_restriction_spec.rb +27 -0
  82. data/spec/sender_identifier.rb +33 -0
  83. data/spec/series_identifier_spec.rb +33 -0
  84. data/spec/series_spec.rb +47 -0
  85. data/spec/spec_helper.rb +15 -0
  86. data/spec/stock_spec.rb +39 -0
  87. data/spec/subject_spec.rb +34 -0
  88. data/spec/supply_detail_spec.rb +97 -0
  89. data/spec/title_spec.rb +38 -0
  90. data/spec/website_spec.rb +33 -0
  91. data/spec/writer_spec.rb +78 -0
  92. data/support/codes/001.tsv +10 -0
  93. data/support/codes/002.tsv +5 -0
  94. data/support/codes/003.tsv +7 -0
  95. data/support/codes/005.tsv +13 -0
  96. data/support/codes/006.tsv +76 -0
  97. data/support/codes/007.tsv +123 -0
  98. data/support/codes/008.tsv +7 -0
  99. data/support/codes/009.tsv +7 -0
  100. data/support/codes/010.tsv +34 -0
  101. data/support/codes/011.tsv +11 -0
  102. data/support/codes/012.tsv +11 -0
  103. data/support/codes/013.tsv +7 -0
  104. data/support/codes/014.tsv +4 -0
  105. data/support/codes/015.tsv +13 -0
  106. data/support/codes/016.tsv +6 -0
  107. data/support/codes/017.tsv +90 -0
  108. data/support/codes/018.tsv +3 -0
  109. data/support/codes/019.tsv +7 -0
  110. data/support/codes/020.tsv +0 -0
  111. data/support/codes/021.tsv +31 -0
  112. data/support/codes/022.tsv +9 -0
  113. data/support/codes/023.tsv +9 -0
  114. data/support/codes/024.tsv +11 -0
  115. data/support/codes/025.tsv +29 -0
  116. data/support/codes/026.tsv +75 -0
  117. data/support/codes/027.tsv +75 -0
  118. data/support/codes/028.tsv +8 -0
  119. data/support/codes/029.tsv +16 -0
  120. data/support/codes/030.tsv +15 -0
  121. data/support/codes/031.tsv +3 -0
  122. data/support/codes/032.tsv +2 -0
  123. data/support/codes/033.tsv +36 -0
  124. data/support/codes/034.tsv +14 -0
  125. data/support/codes/035.tsv +6 -0
  126. data/support/codes/036.tsv +3 -0
  127. data/support/codes/037.tsv +6 -0
  128. data/support/codes/038.tsv +36 -0
  129. data/support/codes/039.tsv +8 -0
  130. data/support/codes/040.tsv +6 -0
  131. data/support/codes/041.tsv +6 -0
  132. data/support/codes/042.tsv +16 -0
  133. data/support/codes/043.tsv +4 -0
  134. data/support/codes/044.tsv +13 -0
  135. data/support/codes/045.tsv +12 -0
  136. data/support/codes/046.tsv +3 -0
  137. data/support/codes/047.tsv +4 -0
  138. data/support/codes/048.tsv +11 -0
  139. data/support/codes/049.tsv +84 -0
  140. data/support/codes/050.tsv +8 -0
  141. data/support/codes/051.tsv +27 -0
  142. data/support/codes/052.tsv +1 -0
  143. data/support/codes/053.tsv +3 -0
  144. data/support/codes/054.tsv +23 -0
  145. data/support/codes/055.tsv +13 -0
  146. data/support/codes/056.tsv +2 -0
  147. data/support/codes/057.tsv +5 -0
  148. data/support/codes/058.tsv +21 -0
  149. data/support/codes/059.tsv +4 -0
  150. data/support/codes/060.tsv +2 -0
  151. data/support/codes/061.tsv +3 -0
  152. data/support/codes/062.tsv +5 -0
  153. data/support/codes/063.tsv +0 -0
  154. data/support/codes/064.tsv +13 -0
  155. data/support/codes/065.tsv +25 -0
  156. data/support/codes/066.tsv +4 -0
  157. data/support/codes/067.tsv +2 -0
  158. data/support/codes/068.tsv +15 -0
  159. data/support/codes/069.tsv +4 -0
  160. data/support/codes/070.tsv +2 -0
  161. data/support/codes/071.tsv +9 -0
  162. data/support/codes/072.tsv +7 -0
  163. data/support/codes/073.tsv +36 -0
  164. data/support/codes/074.tsv +489 -0
  165. data/support/codes/075.tsv +2 -0
  166. data/support/codes/076.tsv +12 -0
  167. data/support/codes/077.tsv +19 -0
  168. data/support/codes/078.tsv +148 -0
  169. data/support/codes/079.tsv +17 -0
  170. data/support/codes/080.tsv +19 -0
  171. data/support/codes/081.tsv +11 -0
  172. data/support/codes/082.tsv +17 -0
  173. data/support/codes/083.tsv +68 -0
  174. data/support/codes/084.tsv +10 -0
  175. data/support/codes/085.tsv +23 -0
  176. data/support/codes/086.tsv +5 -0
  177. data/support/codes/087.tsv +6 -0
  178. data/support/codes/088.tsv +0 -0
  179. data/support/codes/089.tsv +1 -0
  180. data/support/codes/090.tsv +11 -0
  181. data/support/codes/091.tsv +248 -0
  182. data/support/codes/092.tsv +7 -0
  183. data/support/codes/093.tsv +13 -0
  184. data/support/codes/094.tsv +3 -0
  185. data/support/codes/095.tsv +3 -0
  186. data/support/codes/096.tsv +185 -0
  187. data/support/codes/097.tsv +1 -0
  188. data/support/codes/098.tsv +21 -0
  189. data/support/codes/099.tsv +24 -0
  190. data/support/codes/100.tsv +4 -0
  191. data/support/codes/101.tsv +2 -0
  192. data/support/codes/102.tsv +3 -0
  193. data/support/codes/121.tsv +127 -0
  194. data/support/codes/138.tsv +6 -0
  195. data/support/codes/139.tsv +70 -0
  196. data/support/codes/140.tsv +7 -0
  197. data/support/codes/141.tsv +10 -0
  198. data/support/codes/142.tsv +12 -0
  199. data/support/codes/143.tsv +7 -0
  200. data/support/codes/144.tsv +4 -0
  201. data/support/codes/145.tsv +5 -0
  202. data/support/codes/146.tsv +3 -0
  203. data/support/codes/147.tsv +7 -0
  204. data/support/codes/148.tsv +3 -0
  205. data/support/codes/149.tsv +4 -0
  206. data/support/codes/150.tsv +124 -0
  207. data/support/codes/151.tsv +7 -0
  208. data/support/codes/152.tsv +2 -0
  209. data/support/codes/153.tsv +14 -0
  210. data/support/codes/154.tsv +9 -0
  211. data/support/codes/155.tsv +5 -0
  212. data/support/codes/156.tsv +4 -0
  213. data/support/codes/157.tsv +4 -0
  214. data/support/codes/158.tsv +24 -0
  215. data/support/codes/159.tsv +6 -0
  216. data/support/codes/160.tsv +0 -0
  217. data/support/codes/161.tsv +3 -0
  218. data/support/codes/162.tsv +3 -0
  219. data/support/codes/163.tsv +7 -0
  220. data/support/codes/164.tsv +2 -0
  221. data/support/codes/165.tsv +2 -0
  222. data/support/codes/166.tsv +2 -0
  223. data/support/codes/167.tsv +3 -0
  224. data/support/codes/168.tsv +2 -0
  225. data/support/codes/169.tsv +3 -0
  226. data/support/codes/170.tsv +0 -0
  227. data/support/codes/171.tsv +2 -0
  228. data/support/codes/172.tsv +1 -0
  229. data/support/codes/173.tsv +2 -0
  230. data/support/codes/174.tsv +2 -0
  231. data/support/codes/175.tsv +175 -0
  232. data/support/codes/176.tsv +12 -0
  233. data/support/codes/177.tsv +2 -0
  234. data/support/codes/178.tsv +17 -0
  235. data/support/entities.txt +1499 -0
  236. data/support/extract.rb +25 -0
  237. data/support/switch-onix-2.1-short-to-reference.xsl +24 -0
  238. data/support/switch-onix-tagnames-1.1.xsl +25 -0
  239. data/support/switch-onix-tagnames-2.0.xsl +37 -0
  240. metadata +440 -0
@@ -0,0 +1,38 @@
1
+ # coding: utf-8
2
+
3
+ module ONIX2
4
+ class MarketRepresentation
5
+ include Virtus.model
6
+
7
+ attribute :agent_name
8
+ attribute :agent_role, Integer
9
+ attribute :market_country
10
+ attribute :market_territory
11
+ attribute :market_country_excluded
12
+ attribute :market_restriction_detail
13
+ attribute :market_publishing_status, Integer
14
+
15
+ def to_xml
16
+ MarketRepresentationRepresenter.new(self).to_xml
17
+ end
18
+
19
+ def self.from_xml(data)
20
+ MarketRepresentationRepresenter.new(self.new).from_xml(data)
21
+ end
22
+ end
23
+
24
+ class MarketRepresentationRepresenter < Representable::Decorator
25
+ include Representable::XML
26
+
27
+ self.representation_wrap = :MarketRepresentation
28
+
29
+ property :agent_name, as: "AgentName"
30
+ property :agent_role, as: "AgentRole", render_filter: ::ONIX2::Formatters::TWO_DIGITS
31
+ property :market_country, as: "MarketCountry"
32
+ property :market_territory, as: "MarketTerritory"
33
+ property :market_country_excluded, as: "MarketCountryExcluded"
34
+ property :market_restriction_detail, as: "MarketRestrictionDetail"
35
+ property :market_publishing_status, as: "MarketPublishingStatus", render_filter: ::ONIX2::Formatters::TWO_DIGITS
36
+ end
37
+ end
38
+
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+
3
+ module ONIX2
4
+ class Measure
5
+ include Virtus.model
6
+
7
+ attribute :measure_type_code, Integer
8
+ attribute :measurement #Integer or Decimal
9
+ attribute :measure_unit_code
10
+
11
+ def to_xml
12
+ MeasureRepresenter.new(self).to_xml
13
+ end
14
+
15
+ def self.from_xml(data)
16
+ MeasureRepresenter.new(self.new).from_xml(data)
17
+ end
18
+ end
19
+
20
+ class MeasureRepresenter < Representable::Decorator
21
+ include Representable::XML
22
+
23
+ self.representation_wrap = :Measure
24
+
25
+ property :measure_type_code, as: "MeasureTypeCode", render_filter: ::ONIX2::Formatters::TWO_DIGITS
26
+ property :measurement, as: "Measurement", render_filter: ::ONIX2::Formatters::DECIMAL, parse_filter: ->(value, *context) { value.is_a?(Integer) ? value.to_i : BigDecimal.new(value) }
27
+ property :measure_unit_code, as: "MeasureUnitCode"
28
+ end
29
+ end
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+
3
+ module ONIX2
4
+ class MediaFile
5
+ include Virtus.model
6
+
7
+ attribute :media_file_type_code, Integer
8
+ attribute :media_file_format_code, Integer
9
+ attribute :image_resolution
10
+ attribute :media_file_link_type_code, Integer
11
+ attribute :media_file_link
12
+
13
+ def to_xml
14
+ MediaFileRepresenter.new(self).to_xml
15
+ end
16
+
17
+ def self.from_xml(data)
18
+ MediaFileRepresenter.new(self.new).from_xml(data)
19
+ end
20
+ end
21
+
22
+ class MediaFileRepresenter < Representable::Decorator
23
+ include Representable::XML
24
+
25
+ self.representation_wrap = :MediaFile
26
+
27
+ property :media_file_type_code, as: "MediaFileTypeCode", render_filter: ::ONIX2::Formatters::TWO_DIGITS
28
+ property :media_file_format_code, as: "MediaFileFormatCode", render_filter: ::ONIX2::Formatters::TWO_DIGITS
29
+ property :image_resolution, as: "ImageResolution"
30
+ property :media_file_link_type_code, as: "MediaFileLinkTypeCode", render_filter: ::ONIX2::Formatters::TWO_DIGITS
31
+ property :media_file_link, as: "MediaFileLink"
32
+ end
33
+ end
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+
3
+ module ONIX2
4
+ class OtherText
5
+ include Virtus.model
6
+
7
+ attribute :text_type_code, Integer
8
+ attribute :text_format
9
+ attribute :text
10
+ attribute :text_link_type,Integer
11
+ attribute :text_link
12
+ attribute :text_author
13
+
14
+ def to_xml
15
+ OtherTextRepresenter.new(self).to_xml
16
+ end
17
+
18
+ def self.from_xml(data)
19
+ OtherTextRepresenter.new(self.new).from_xml(data)
20
+ end
21
+ end
22
+
23
+ class OtherTextRepresenter < Representable::Decorator
24
+ include Representable::XML
25
+
26
+ self.representation_wrap = :OtherText
27
+
28
+ property :text_type_code, as: "TextTypeCode", render_filter: ::ONIX2::Formatters::TWO_DIGITS
29
+ property :text_format, as: "TextFormat"
30
+ property :text, as: "Text"
31
+ property :text_link_type, as: "TextLinkType", render_filter: ::ONIX2::Formatters::TWO_DIGITS
32
+ property :text_link, as: "TextLink"
33
+ property :text_author, as: "TextAuthor"
34
+ end
35
+ end
@@ -0,0 +1,47 @@
1
+ # coding: utf-8
2
+
3
+ module ONIX2
4
+ class Price
5
+ include Virtus.model
6
+
7
+ attribute :price_type_code, Integer
8
+ attribute :price_type_qualifier, Integer
9
+ attribute :price_type_description
10
+ attribute :price_per, Integer
11
+ attribute :minimum_order_qty, Integer
12
+ attribute :class_of_trade
13
+ attribute :bic_discount_group_code
14
+ attribute :discounts_coded, Array[DiscountCoded]
15
+ attribute :price_status, Integer
16
+ attribute :price_amount, Decimal
17
+ attribute :currency_code
18
+ attribute :discount_percent, Decimal
19
+
20
+ def to_xml
21
+ PriceRepresenter.new(self).to_xml
22
+ end
23
+
24
+ def self.from_xml(data)
25
+ PriceRepresenter.new(self.new).from_xml(data)
26
+ end
27
+ end
28
+
29
+ class PriceRepresenter < Representable::Decorator
30
+ include Representable::XML
31
+
32
+ self.representation_wrap = :Price
33
+
34
+ property :price_type_code, as: "PriceTypeCode", render_filter: ::ONIX2::Formatters::TWO_DIGITS
35
+ property :price_type_qualifier, as: "PriceQualifier", render_filter: ::ONIX2::Formatters::TWO_DIGITS
36
+ property :price_type_description, as: "PriceTypeDescription"
37
+ property :price_per, as: "PricePer", render_filter: ::ONIX2::Formatters::TWO_DIGITS
38
+ property :minimum_order_qty, as: "MinimumOrderQuantity"
39
+ property :class_of_trade, as: "ClassOfTrade"
40
+ property :bic_discount_group_code, as: "BICDiscountGroupCode"
41
+ collection :discounts_coded, as: "DiscountCoded", extend: ONIX2::DiscountCodedRepresenter, class: ONIX2::DiscountCoded
42
+ property :price_status, as: "PriceStatus", render_filter: ::ONIX2::Formatters::TWO_DIGITS
43
+ property :price_amount, as: "PriceAmount", render_filter: ::ONIX2::Formatters::DECIMAL
44
+ property :currency_code, as: "CurrencyCode"
45
+ property :discount_percent, as: "DiscountPercent"
46
+ end
47
+ end
@@ -0,0 +1,97 @@
1
+ # coding: utf-8
2
+
3
+ module ONIX2
4
+ class Product
5
+ include Virtus.model
6
+
7
+ attribute :record_reference
8
+ attribute :notification_type, Integer
9
+ attribute :product_identifiers, Array[ONIX2::ProductIdentifier]
10
+ attribute :product_form
11
+ attribute :product_form_detail
12
+ attribute :series, Array[ONIX2::Series]
13
+ attribute :titles, Array[ONIX2::Title]
14
+ attribute :websites, Array[ONIX2::Website]
15
+ attribute :contributors, Array[ONIX2::Contributor]
16
+ attribute :edition_number, Integer
17
+ attribute :languages, Array[ONIX2::Language]
18
+ attribute :number_of_pages, Integer
19
+ attribute :basic_main_subject
20
+ attribute :bic_main_subject
21
+ attribute :subjects, Array[ONIX2::Subject]
22
+ attribute :audience_code
23
+ attribute :audience_ranges, Array[ONIX2::AudienceRange]
24
+ attribute :text, Array[ONIX2::OtherText]
25
+ attribute :media_files, Array[ONIX2::MediaFile]
26
+ attribute :imprints, Array[ONIX2::Imprint]
27
+ attribute :publishers, Array[ONIX2::Publisher]
28
+ attribute :publishing_status, Integer
29
+ attribute :publication_date
30
+ attribute :copyright_year, Integer
31
+ attribute :year_first_published, Integer
32
+ attribute :sales_restrictions, Array[ONIX2::SalesRestriction]
33
+ attribute :measurements, Array[ONIX2::Measure]
34
+ attribute :supply_details, Array[ONIX2::SupplyDetail]
35
+ attribute :market_representations, Array[ONIX2::MarketRepresentation]
36
+ attribute :sales_rights, Array[ONIX2::SalesRights]
37
+
38
+ # some deprecated attributes. Read only
39
+ # - See the measures array for the current way of specifying
40
+ # various measurements of the product
41
+ attribute :height, Decimal
42
+ attribute :width, Decimal
43
+ attribute :thickness, Decimal
44
+ attribute :weight, Decimal
45
+ attribute :dimensions
46
+
47
+ def to_xml
48
+ ProductRepresenter.new(self).to_xml
49
+ end
50
+
51
+ def self.from_xml(data)
52
+ ProductRepresenter.new(self.new).from_xml(data)
53
+ end
54
+ end
55
+
56
+ class ProductRepresenter < Representable::Decorator
57
+ include Representable::XML
58
+
59
+ self.representation_wrap = :Product
60
+
61
+ property :record_reference, as: "RecordReference"
62
+ property :notification_type, as: "NotificationType", render_filter: ::ONIX2::Formatters::TWO_DIGITS
63
+ collection :product_identifiers, as: "ProductIdentifier", extend: ONIX2::ProductIdentifierRepresenter, class: ONIX2::ProductIdentifier
64
+ property :product_form, as: "ProductForm"
65
+ property :product_form_detail, as: "ProductFormDetail", render_filter: ::ONIX2::Formatters::TWO_DIGITS
66
+ collection :series, as: "Series", extend: ONIX2::SeriesRepresenter, class: ONIX2::Series
67
+ collection :titles, as: "Title", extend: ONIX2::TitleRepresenter, class: ONIX2::Title
68
+ collection :websites, as: "Website", extend: ONIX2::WebsiteRepresenter, class: ONIX2::Website
69
+ collection :contributors, as: "Contributor", extend: ONIX2::ContributorRepresenter, class: ONIX2::Contributor
70
+ property :edition_number, as: "EditionNumber"
71
+ collection :languages, as: "Language", extend: ONIX2::LanguageRepresenter, class: ONIX2::Language
72
+ property :number_of_pages, as: "NumberOfPages"
73
+ property :basic_main_subject, as: "BASICMainSubject"
74
+ property :bic_main_subject, as: "BICMainSubject"
75
+ collection :subjects, as: "Subject", extend: ONIX2::SubjectRepresenter, class: ONIX2::Subject
76
+ property :audience_code, as: "AudienceCode", render_filter: ::ONIX2::Formatters::TWO_DIGITS
77
+ collection :audience_ranges, as: "AudienceRange", extend: ONIX2::AudienceRangeRepresenter, class: ONIX2::AudienceRange
78
+ collection :text, as: "OtherText", extend: ONIX2::OtherTextRepresenter, class: ONIX2::OtherText
79
+ collection :media_files, as: "MediaFile", extend: ONIX2::MediaFileRepresenter, class: ONIX2::MediaFile
80
+ collection :imprints, as: "Imprint", extend: ONIX2::ImprintRepresenter, class: ONIX2::Imprint
81
+ collection :publishers, as: "Publisher", extend: ONIX2::PublisherRepresenter, class: ONIX2::Publisher
82
+ property :publishing_status, as: "PublishingStatus", render_filter: ::ONIX2::Formatters::TWO_DIGITS
83
+ property :publication_date, as: "PublicationDate", render_filter: ::ONIX2::Formatters::YYYYMMDD, parse_filter: ->(value, *context) { Date.parse(value) rescue nil }
84
+ property :copyright_year, as: "CopyrightYear"
85
+ property :year_first_published, as: "YearFirstPublished"
86
+ collection :sales_restrictions, as: "SalesRestriction", extend: ONIX2::SalesRestrictionRepresenter, class: ONIX2::SalesRestriction
87
+ collection :measurements, as: "Measure", extend: ONIX2::MeasureRepresenter, class: ONIX2::Measure
88
+ collection :supply_details, as: "SupplyDetail", extend: ONIX2::SupplyDetailRepresenter, class: ONIX2::SupplyDetail
89
+ collection :market_representations, as: "MarketRepresentation", extend: ONIX2::MarketRepresentationRepresenter, class: ONIX2::MarketRepresentation
90
+ property :height, as: "Height"
91
+ property :width, as: "Width"
92
+ property :thickness, as: "Thickness"
93
+ property :weight, as: "Weight"
94
+ property :dimensions, as: "Dimensions"
95
+ collection :sales_rights, as: "SalesRights", extend: ONIX2::SalesRightsRepresenter, class: ONIX2::SalesRights
96
+ end
97
+ end
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+
3
+ module ONIX2
4
+ class ProductIdentifier
5
+ include Virtus.model
6
+
7
+ attribute :product_id_type, Integer
8
+ attribute :id_value
9
+
10
+ def to_xml
11
+ ProductIdentifierRepresenter.new(self).to_xml
12
+ end
13
+
14
+ def self.from_xml(data)
15
+ ProductIdentifierRepresenter.new(self.new).from_xml(data)
16
+ end
17
+ end
18
+
19
+ class ProductIdentifierRepresenter < Representable::Decorator
20
+ include Representable::XML
21
+
22
+ self.representation_wrap = :ProductIdentifier
23
+
24
+ property :product_id_type, as: "ProductIDType", render_filter: ::ONIX2::Formatters::TWO_DIGITS
25
+ property :id_value, as: "IDValue"
26
+ end
27
+ end
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+
3
+ module ONIX2
4
+ class Publisher
5
+ include Virtus.model
6
+
7
+ attribute :publishing_role, Integer
8
+ attribute :name_code_type, Integer
9
+ attribute :name_code_type_name
10
+ attribute :name_code_type_value
11
+ attribute :publisher_name
12
+
13
+ def to_xml
14
+ PublisherRepresenter.new(self).to_xml
15
+ end
16
+
17
+ def self.from_xml(data)
18
+ PublisherRepresenter.new(self.new).from_xml(data)
19
+ end
20
+ end
21
+
22
+ class PublisherRepresenter < Representable::Decorator
23
+ include Representable::XML
24
+
25
+ self.representation_wrap = :Publisher
26
+
27
+ property :publishing_role, as: "PublishingRole", render_filter: ::ONIX2::Formatters::TWO_DIGITS
28
+ property :name_code_type, as: "NameCodeType", render_filter: ::ONIX2::Formatters::TWO_DIGITS
29
+ property :name_code_type_name, as: "NameCodeTypeName"
30
+ property :name_code_type_value, as: "NameCodeTypeValue"
31
+ property :publisher_name, as: "PublisherName"
32
+ end
33
+ end
@@ -0,0 +1,157 @@
1
+ # coding: utf-8
2
+
3
+ require 'stringio'
4
+
5
+ module ONIX2
6
+
7
+ # This is the primary class for reading data from an ONIX file, and there's
8
+ # really not much to it
9
+ #
10
+ # Each file should contain a single header, and 1 or more products:
11
+ #
12
+ # reader = ONIX2::Reader.new("somefile.xml")
13
+ #
14
+ # puts reader.header.inspect
15
+ #
16
+ # reader.each do |product|
17
+ # puts product.inspect
18
+ # end
19
+ #
20
+ # The header will be returned as an ONIX2::Header object, and the product will
21
+ # be an ONIX2::Product.
22
+ #
23
+ # The ONIX2::Product class can be a bit of a hassle to work with, as data can be
24
+ # nested in it fairly deeply. To wrap all the products returned by the reader
25
+ # in a shim that provides simple accessor access to common attributes, pass the
26
+ # shim class as a second argument
27
+ #
28
+ # reader = ONIX2::Reader.new("somefile.xml", :product_class => ONIX2::APAProduct)
29
+ #
30
+ # puts reader.header.inspect
31
+ #
32
+ # reader.each do |product|
33
+ # puts product.inspect
34
+ # end
35
+ #
36
+ # APAProduct stands for Australian Publishers Association and provides simple
37
+ # access to the ONIX attributes that are commonly used in the Australian market.
38
+ #
39
+ # As well as accessing the file header, there are handful of other read only
40
+ # attributes that might be useful
41
+ #
42
+ # reader = ONIX2::Reader.new("somefile.xml")
43
+ #
44
+ # puts reader.version
45
+ # puts reader.xml_lang
46
+ # puts reader.xml_version
47
+ # puts reader.encoding
48
+ #
49
+ # The version attribute is particuarly useful. There are multiple revisions of the
50
+ # ONIX spec, and you may need to handle the file differently based on what
51
+ # version it is.
52
+ #
53
+ # == File Encoding
54
+ #
55
+ # ONIX2::Reader returns all strings as UTF-8. Source file encoding is detected by
56
+ # the encoding declaration at the top of the file, like so:
57
+ #
58
+ # <?xml version="1.0" encoding="iso-8859-1"?>
59
+ #
60
+ # If the encoding declaration is missing the file is assumed to be UTF-8.
61
+ #
62
+ # If the encoding declaration is missing or wrong and the file isn't UTF-8,
63
+ # you can manually set or override it like so:
64
+ #
65
+ # reader = ONIX2::Reader.new("somefile.xml", :encoding => "iso-8859-1")
66
+ #
67
+ # If the file contains invalid bytes for the source encoding an exception will
68
+ # be raised. This isn't ideal, but I'm still looking for ways to make this
69
+ # behaviour configurable.
70
+ #
71
+ # If you're running 1.9, you might imagine passing an IO stream that auto
72
+ # transcodes to UTF-8 into ONIX2::Reader might have the same effect, but that
73
+ # isn't the case. Nokogiri is used to parse the file, and it seems to ignore
74
+ # IO encoding and just read raw bytes.
75
+ #
76
+ class Reader
77
+ include Enumerable
78
+
79
+ attr_reader :header, :release
80
+
81
+ def initialize(input, *args)
82
+ opts = args.last.kind_of?(Hash) ? args.pop : {}
83
+ if args.size > 0
84
+ ActiveSupport::Deprecation.warn("Passing a klass as ONIX2::Reader's second argument is deprecated, use the :product_class option instead", caller)
85
+ end
86
+ @product_klass = opts[:product_class] || args.pop || ::ONIX2::Product
87
+
88
+ if input.kind_of?(String)
89
+ @file = File.open(input, "r")
90
+ @reader = Nokogiri::XML::Reader(@file, nil, opts[:encoding]) { |cfg| cfg.dtdload.noent }
91
+ elsif input.kind_of?(IO)
92
+ @reader = Nokogiri::XML::Reader(input, nil, opts[:encoding]) { |cfg| cfg.dtdload.noent }
93
+ else
94
+ raise ArgumentError, "Unable to read from file or IO stream"
95
+ end
96
+
97
+ @release = find_release
98
+ @header = find_header
99
+
100
+ @xml_lang ||= @reader.lang
101
+ @xml_version ||= @reader.xml_version.to_f
102
+ end
103
+
104
+ # Iterate over all the products in an ONIX file
105
+ #
106
+ def each(&block)
107
+ @reader.each do |node|
108
+ if @reader.node_type == 1 && @reader.name == "Product"
109
+ str = @reader.outer_xml
110
+ if str.nil?
111
+ yield @product_klass.new
112
+ else
113
+ yield @product_klass.from_xml(str)
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ def close
120
+ @reader.close if @reader
121
+ end
122
+
123
+ private
124
+
125
+ def find_release
126
+ 2.times do
127
+ @reader.read
128
+ if @reader.node_type == 1 && @reader.name == "ONIXMessage"
129
+ value = @reader.attributes["release"]
130
+ if value
131
+ return BigDecimal.new(value)
132
+ else
133
+ return nil
134
+ end
135
+ elsif @reader.node_type == 14
136
+ return nil
137
+ end
138
+ end
139
+ return nil
140
+ end
141
+
142
+ def find_header
143
+ 100.times do
144
+ @reader.read
145
+ if @reader.node_type == 1 && @reader.name == "Header"
146
+ str = @reader.outer_xml
147
+ if str.nil?
148
+ return ONIX2::Header.new
149
+ else
150
+ return ONIX2::Header.from_xml(str)
151
+ end
152
+ end
153
+ end
154
+ return nil
155
+ end
156
+ end
157
+ end