cacofonix 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (294) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -0
  3. data/.rvmrc +1 -0
  4. data/.travis.yml +10 -0
  5. data/CHANGELOG.md +205 -0
  6. data/CODE_OF_CONDUCT.md +74 -0
  7. data/Gemfile +5 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +76 -0
  10. data/Rakefile +6 -0
  11. data/TODO +14 -0
  12. data/bin/onix_extract_codelists +41 -0
  13. data/cacofonix.gemspec +39 -0
  14. data/data/9780194351898.xml +74 -0
  15. data/data/Ashgate Other.xml +382679 -0
  16. data/data/Bookwise_July_2008.xml +21611 -0
  17. data/data/Peribo Onix 0408.xml +17051 -0
  18. data/data/aau.xml +96 -0
  19. data/data/audience_range.xml +9 -0
  20. data/data/contributor.xml +6 -0
  21. data/data/control_chars.xml +74 -0
  22. data/data/entities.xml +78 -0
  23. data/data/extra_entities.xml +65 -0
  24. data/data/header.xml +21 -0
  25. data/data/header_invalid_sentdate.xml +21 -0
  26. data/data/hlasep08.xml +24519 -0
  27. data/data/imprint.xml +5 -0
  28. data/data/iso_8859_1.xml +58 -0
  29. data/data/jul.xml +24783 -0
  30. data/data/language.xml +7 -0
  31. data/data/market_representation.xml +11 -0
  32. data/data/measure.xml +6 -0
  33. data/data/media_file.xml +6 -0
  34. data/data/no_encoding.xml +78 -0
  35. data/data/no_xml_declaration.xml +95 -0
  36. data/data/other_text.xml +5 -0
  37. data/data/price.xml +5 -0
  38. data/data/product.xml +79 -0
  39. data/data/product_identifier.xml +5 -0
  40. data/data/product_invalid_pubdate.xml +42 -0
  41. data/data/publisher.xml +5 -0
  42. data/data/rba_FANT.xml +23 -0
  43. data/data/reference_with_release_attrib.xml +74 -0
  44. data/data/sales_restriction.xml +4 -0
  45. data/data/sales_rights.xml +35 -0
  46. data/data/sender_identifier.xml +5 -0
  47. data/data/series.xml +5 -0
  48. data/data/series_identifier.xml +6 -0
  49. data/data/short_tags.xml +191 -0
  50. data/data/short_tags_ivp.xml +231 -0
  51. data/data/sl_product.xml +81 -0
  52. data/data/stock.xml +5 -0
  53. data/data/subject.xml +6 -0
  54. data/data/supply_detail.xml +18 -0
  55. data/data/title.xml +6 -0
  56. data/data/two_products.xml +114 -0
  57. data/data/usd.xml +175 -0
  58. data/data/utf_16.xml +0 -0
  59. data/data/website.xml +6 -0
  60. data/examples/reader.rb +25 -0
  61. data/examples/reader_apa.rb +22 -0
  62. data/examples/writer.rb +13 -0
  63. data/examples/writer_apa.rb +38 -0
  64. data/lib/cacofonix.rb +151 -0
  65. data/lib/cacofonix/codelists/001.rb +16 -0
  66. data/lib/cacofonix/codelists/002.rb +11 -0
  67. data/lib/cacofonix/codelists/003.rb +13 -0
  68. data/lib/cacofonix/codelists/005.rb +20 -0
  69. data/lib/cacofonix/codelists/006.rb +82 -0
  70. data/lib/cacofonix/codelists/007.rb +129 -0
  71. data/lib/cacofonix/codelists/008.rb +13 -0
  72. data/lib/cacofonix/codelists/009.rb +13 -0
  73. data/lib/cacofonix/codelists/010.rb +52 -0
  74. data/lib/cacofonix/codelists/011.rb +17 -0
  75. data/lib/cacofonix/codelists/012.rb +17 -0
  76. data/lib/cacofonix/codelists/013.rb +13 -0
  77. data/lib/cacofonix/codelists/014.rb +10 -0
  78. data/lib/cacofonix/codelists/015.rb +19 -0
  79. data/lib/cacofonix/codelists/016.rb +12 -0
  80. data/lib/cacofonix/codelists/017.rb +96 -0
  81. data/lib/cacofonix/codelists/018.rb +11 -0
  82. data/lib/cacofonix/codelists/019.rb +13 -0
  83. data/lib/cacofonix/codelists/020.rb +7 -0
  84. data/lib/cacofonix/codelists/021.rb +39 -0
  85. data/lib/cacofonix/codelists/022.rb +15 -0
  86. data/lib/cacofonix/codelists/023.rb +19 -0
  87. data/lib/cacofonix/codelists/024.rb +17 -0
  88. data/lib/cacofonix/codelists/025.rb +35 -0
  89. data/lib/cacofonix/codelists/026.rb +86 -0
  90. data/lib/cacofonix/codelists/027.rb +90 -0
  91. data/lib/cacofonix/codelists/028.rb +14 -0
  92. data/lib/cacofonix/codelists/029.rb +25 -0
  93. data/lib/cacofonix/codelists/030.rb +22 -0
  94. data/lib/cacofonix/codelists/031.rb +9 -0
  95. data/lib/cacofonix/codelists/032.rb +8 -0
  96. data/lib/cacofonix/codelists/033.rb +43 -0
  97. data/lib/cacofonix/codelists/034.rb +21 -0
  98. data/lib/cacofonix/codelists/035.rb +12 -0
  99. data/lib/cacofonix/codelists/036.rb +9 -0
  100. data/lib/cacofonix/codelists/037.rb +12 -0
  101. data/lib/cacofonix/codelists/038.rb +43 -0
  102. data/lib/cacofonix/codelists/039.rb +14 -0
  103. data/lib/cacofonix/codelists/040.rb +12 -0
  104. data/lib/cacofonix/codelists/041.rb +12 -0
  105. data/lib/cacofonix/codelists/042.rb +22 -0
  106. data/lib/cacofonix/codelists/043.rb +12 -0
  107. data/lib/cacofonix/codelists/044.rb +22 -0
  108. data/lib/cacofonix/codelists/045.rb +19 -0
  109. data/lib/cacofonix/codelists/046.rb +15 -0
  110. data/lib/cacofonix/codelists/047.rb +10 -0
  111. data/lib/cacofonix/codelists/048.rb +17 -0
  112. data/lib/cacofonix/codelists/049.rb +91 -0
  113. data/lib/cacofonix/codelists/050.rb +14 -0
  114. data/lib/cacofonix/codelists/051.rb +36 -0
  115. data/lib/cacofonix/codelists/052.rb +7 -0
  116. data/lib/cacofonix/codelists/053.rb +10 -0
  117. data/lib/cacofonix/codelists/054.rb +29 -0
  118. data/lib/cacofonix/codelists/055.rb +23 -0
  119. data/lib/cacofonix/codelists/056.rb +8 -0
  120. data/lib/cacofonix/codelists/057.rb +11 -0
  121. data/lib/cacofonix/codelists/058.rb +29 -0
  122. data/lib/cacofonix/codelists/059.rb +13 -0
  123. data/lib/cacofonix/codelists/060.rb +8 -0
  124. data/lib/cacofonix/codelists/061.rb +9 -0
  125. data/lib/cacofonix/codelists/062.rb +11 -0
  126. data/lib/cacofonix/codelists/063.rb +7 -0
  127. data/lib/cacofonix/codelists/064.rb +19 -0
  128. data/lib/cacofonix/codelists/065.rb +34 -0
  129. data/lib/cacofonix/codelists/066.rb +10 -0
  130. data/lib/cacofonix/codelists/067.rb +8 -0
  131. data/lib/cacofonix/codelists/068.rb +22 -0
  132. data/lib/cacofonix/codelists/069.rb +10 -0
  133. data/lib/cacofonix/codelists/070.rb +8 -0
  134. data/lib/cacofonix/codelists/071.rb +16 -0
  135. data/lib/cacofonix/codelists/072.rb +13 -0
  136. data/lib/cacofonix/codelists/073.rb +42 -0
  137. data/lib/cacofonix/codelists/074.rb +495 -0
  138. data/lib/cacofonix/codelists/075.rb +8 -0
  139. data/lib/cacofonix/codelists/076.rb +18 -0
  140. data/lib/cacofonix/codelists/077.rb +25 -0
  141. data/lib/cacofonix/codelists/078.rb +173 -0
  142. data/lib/cacofonix/codelists/079.rb +25 -0
  143. data/lib/cacofonix/codelists/080.rb +26 -0
  144. data/lib/cacofonix/codelists/081.rb +45 -0
  145. data/lib/cacofonix/codelists/082.rb +23 -0
  146. data/lib/cacofonix/codelists/083.rb +74 -0
  147. data/lib/cacofonix/codelists/084.rb +16 -0
  148. data/lib/cacofonix/codelists/085.rb +29 -0
  149. data/lib/cacofonix/codelists/086.rb +11 -0
  150. data/lib/cacofonix/codelists/087.rb +12 -0
  151. data/lib/cacofonix/codelists/088.rb +7 -0
  152. data/lib/cacofonix/codelists/089.rb +7 -0
  153. data/lib/cacofonix/codelists/090.rb +17 -0
  154. data/lib/cacofonix/codelists/091.rb +257 -0
  155. data/lib/cacofonix/codelists/092.rb +14 -0
  156. data/lib/cacofonix/codelists/093.rb +19 -0
  157. data/lib/cacofonix/codelists/094.rb +9 -0
  158. data/lib/cacofonix/codelists/095.rb +9 -0
  159. data/lib/cacofonix/codelists/096.rb +191 -0
  160. data/lib/cacofonix/codelists/097.rb +7 -0
  161. data/lib/cacofonix/codelists/098.rb +27 -0
  162. data/lib/cacofonix/codelists/099.rb +30 -0
  163. data/lib/cacofonix/codelists/100.rb +12 -0
  164. data/lib/cacofonix/codelists/101.rb +8 -0
  165. data/lib/cacofonix/codelists/102.rb +9 -0
  166. data/lib/cacofonix/codelists/121.rb +164 -0
  167. data/lib/cacofonix/codelists/138.rb +12 -0
  168. data/lib/cacofonix/codelists/139.rb +76 -0
  169. data/lib/cacofonix/codelists/140.rb +13 -0
  170. data/lib/cacofonix/codelists/141.rb +16 -0
  171. data/lib/cacofonix/codelists/142.rb +18 -0
  172. data/lib/cacofonix/codelists/143.rb +13 -0
  173. data/lib/cacofonix/codelists/144.rb +12 -0
  174. data/lib/cacofonix/codelists/145.rb +13 -0
  175. data/lib/cacofonix/codelists/146.rb +9 -0
  176. data/lib/cacofonix/codelists/147.rb +16 -0
  177. data/lib/cacofonix/codelists/148.rb +9 -0
  178. data/lib/cacofonix/codelists/149.rb +10 -0
  179. data/lib/cacofonix/codelists/150.rb +130 -0
  180. data/lib/cacofonix/codelists/151.rb +13 -0
  181. data/lib/cacofonix/codelists/152.rb +8 -0
  182. data/lib/cacofonix/codelists/153.rb +20 -0
  183. data/lib/cacofonix/codelists/154.rb +15 -0
  184. data/lib/cacofonix/codelists/155.rb +11 -0
  185. data/lib/cacofonix/codelists/156.rb +10 -0
  186. data/lib/cacofonix/codelists/157.rb +10 -0
  187. data/lib/cacofonix/codelists/158.rb +32 -0
  188. data/lib/cacofonix/codelists/159.rb +12 -0
  189. data/lib/cacofonix/codelists/160.rb +10 -0
  190. data/lib/cacofonix/codelists/161.rb +9 -0
  191. data/lib/cacofonix/codelists/162.rb +12 -0
  192. data/lib/cacofonix/codelists/163.rb +17 -0
  193. data/lib/cacofonix/codelists/164.rb +11 -0
  194. data/lib/cacofonix/codelists/165.rb +9 -0
  195. data/lib/cacofonix/codelists/166.rb +9 -0
  196. data/lib/cacofonix/codelists/167.rb +9 -0
  197. data/lib/cacofonix/codelists/168.rb +8 -0
  198. data/lib/cacofonix/codelists/169.rb +9 -0
  199. data/lib/cacofonix/codelists/170.rb +7 -0
  200. data/lib/cacofonix/codelists/171.rb +8 -0
  201. data/lib/cacofonix/codelists/172.rb +7 -0
  202. data/lib/cacofonix/codelists/173.rb +8 -0
  203. data/lib/cacofonix/codelists/174.rb +8 -0
  204. data/lib/cacofonix/codelists/175.rb +206 -0
  205. data/lib/cacofonix/codelists/176.rb +20 -0
  206. data/lib/cacofonix/codelists/177.rb +8 -0
  207. data/lib/cacofonix/codelists/178.rb +24 -0
  208. data/lib/cacofonix/codelists/179.rb +7 -0
  209. data/lib/cacofonix/codelists/184.rb +11 -0
  210. data/lib/cacofonix/core/code.rb +106 -0
  211. data/lib/cacofonix/core/element.rb +275 -0
  212. data/lib/cacofonix/core/header.rb +45 -0
  213. data/lib/cacofonix/core/lists.rb +108 -0
  214. data/lib/cacofonix/core/reader.rb +166 -0
  215. data/lib/cacofonix/core/writer.rb +123 -0
  216. data/lib/cacofonix/elements/addressee_identifier.rb +6 -0
  217. data/lib/cacofonix/elements/agent_identifier.rb +6 -0
  218. data/lib/cacofonix/elements/audience.rb +8 -0
  219. data/lib/cacofonix/elements/audience_range.rb +15 -0
  220. data/lib/cacofonix/elements/batch_bonus.rb +7 -0
  221. data/lib/cacofonix/elements/bible.rb +12 -0
  222. data/lib/cacofonix/elements/complexity.rb +7 -0
  223. data/lib/cacofonix/elements/conference.rb +14 -0
  224. data/lib/cacofonix/elements/conference_sponsor.rb +8 -0
  225. data/lib/cacofonix/elements/conference_sponsor_identifier.rb +6 -0
  226. data/lib/cacofonix/elements/contained_item.rb +6 -0
  227. data/lib/cacofonix/elements/content_item.rb +21 -0
  228. data/lib/cacofonix/elements/contributor.rb +19 -0
  229. data/lib/cacofonix/elements/copyright_owner.rb +8 -0
  230. data/lib/cacofonix/elements/copyright_owner_identifier.rb +6 -0
  231. data/lib/cacofonix/elements/copyright_statement.rb +7 -0
  232. data/lib/cacofonix/elements/discount_coded.rb +8 -0
  233. data/lib/cacofonix/elements/extent.rb +8 -0
  234. data/lib/cacofonix/elements/identifier.rb +7 -0
  235. data/lib/cacofonix/elements/illustrations.rb +8 -0
  236. data/lib/cacofonix/elements/imprint.rb +9 -0
  237. data/lib/cacofonix/elements/language.rb +8 -0
  238. data/lib/cacofonix/elements/location_identifier.rb +8 -0
  239. data/lib/cacofonix/elements/main_subject.rb +9 -0
  240. data/lib/cacofonix/elements/market_date.rb +8 -0
  241. data/lib/cacofonix/elements/market_representation.rb +18 -0
  242. data/lib/cacofonix/elements/measure.rb +8 -0
  243. data/lib/cacofonix/elements/media_file.rb +16 -0
  244. data/lib/cacofonix/elements/name.rb +6 -0
  245. data/lib/cacofonix/elements/name_base.rb +17 -0
  246. data/lib/cacofonix/elements/new_supplier.rb +12 -0
  247. data/lib/cacofonix/elements/not_for_sale.rb +13 -0
  248. data/lib/cacofonix/elements/on_order_detail.rb +7 -0
  249. data/lib/cacofonix/elements/other_text.rb +17 -0
  250. data/lib/cacofonix/elements/page_run.rb +7 -0
  251. data/lib/cacofonix/elements/person_date.rb +8 -0
  252. data/lib/cacofonix/elements/person_name_identifier.rb +6 -0
  253. data/lib/cacofonix/elements/price.rb +46 -0
  254. data/lib/cacofonix/elements/prize.rb +10 -0
  255. data/lib/cacofonix/elements/product.rb +155 -0
  256. data/lib/cacofonix/elements/product_base.rb +61 -0
  257. data/lib/cacofonix/elements/product_classification.rb +8 -0
  258. data/lib/cacofonix/elements/product_form_feature.rb +8 -0
  259. data/lib/cacofonix/elements/product_identifier.rb +6 -0
  260. data/lib/cacofonix/elements/professional_affiliation.rb +7 -0
  261. data/lib/cacofonix/elements/publisher.rb +11 -0
  262. data/lib/cacofonix/elements/reissue.rb +9 -0
  263. data/lib/cacofonix/elements/related_product.rb +6 -0
  264. data/lib/cacofonix/elements/religious_text.rb +8 -0
  265. data/lib/cacofonix/elements/religious_text_feature.rb +8 -0
  266. data/lib/cacofonix/elements/sales_outlet.rb +7 -0
  267. data/lib/cacofonix/elements/sales_outlet_identifier.rb +6 -0
  268. data/lib/cacofonix/elements/sales_restriction.rb +7 -0
  269. data/lib/cacofonix/elements/sales_rights.rb +13 -0
  270. data/lib/cacofonix/elements/sender_identifier.rb +6 -0
  271. data/lib/cacofonix/elements/series.rb +11 -0
  272. data/lib/cacofonix/elements/series_identifier.rb +6 -0
  273. data/lib/cacofonix/elements/set.rb +13 -0
  274. data/lib/cacofonix/elements/stock.rb +16 -0
  275. data/lib/cacofonix/elements/stock_quantity_coded.rb +8 -0
  276. data/lib/cacofonix/elements/subject.rb +13 -0
  277. data/lib/cacofonix/elements/supplier_identifier.rb +6 -0
  278. data/lib/cacofonix/elements/supply_detail.rb +37 -0
  279. data/lib/cacofonix/elements/text_item.rb +11 -0
  280. data/lib/cacofonix/elements/text_item_identifier.rb +6 -0
  281. data/lib/cacofonix/elements/title.rb +11 -0
  282. data/lib/cacofonix/elements/website.rb +8 -0
  283. data/lib/cacofonix/elements/work_identifier.rb +6 -0
  284. data/lib/cacofonix/utils/code_list_extractor.rb +112 -0
  285. data/lib/cacofonix/utils/normaliser.rb +125 -0
  286. data/lib/cacofonix/version.rb +5 -0
  287. data/lib/cacofonix/wrappers/apa_product.rb +748 -0
  288. data/lib/cacofonix/wrappers/simple_product.rb +49 -0
  289. data/support/entities.txt +1499 -0
  290. data/support/extract.rb +25 -0
  291. data/support/switch-onix-2.1-short-to-reference.xsl +24 -0
  292. data/support/switch-onix-tagnames-1.1.xsl +25 -0
  293. data/support/switch-onix-tagnames-2.0.xsl +37 -0
  294. metadata +438 -0
@@ -0,0 +1,37 @@
1
+ # coding: utf-8
2
+
3
+ class Cacofonix::SupplyDetail < Cacofonix::Element
4
+ xml_name "SupplyDetail"
5
+ xml_accessor :supplier_ean_location_number, :from => "SupplierEANLocationNumber"
6
+ xml_accessor :supplier_san, :from => "SupplierSAN"
7
+ onix_composite :supplier_identifiers, Cacofonix::SupplierIdentifier
8
+ xml_accessor :supplier_name, :from => "SupplierName"
9
+ xml_accessor :telephone_number, :from => "TelephoneNumber"
10
+ xml_accessor :fax_number, :from => "FaxNumber"
11
+ xml_accessor :email_address, :from => "EmailAddress"
12
+ onix_composite :websites, Cacofonix::Website
13
+ onix_code_from_list :supplier_role, "SupplierRole", :list => 93
14
+ onix_spaced_codes_from_list :supply_to_countries, "SupplyToCountry", :list => 91
15
+ onix_spaced_codes_from_list :supply_to_territories, "SupplyToTerritory", :list => 49
16
+ onix_spaced_codes_from_list :supply_to_countries_excluded, "SupplyToCountryExcluded", :list => 91
17
+ xml_accessor :supply_restriction_detail, :from => "SupplyRestrictionDetail"
18
+ onix_code_from_list :returns_code_type, "ReturnsCodeType", :list => 53
19
+ xml_accessor :returns_code, :from => "ReturnsCode"
20
+ onix_date_accessor :last_date_for_returns, "LastDateForReturns"
21
+ onix_code_from_list :availability_code, "AvailabilityCode", :list => 54
22
+ alias_accessor :availability_status_code, :availability_code # back-compat
23
+ onix_code_from_list :product_availability, "ProductAvailability", :list => 65
24
+ onix_composite :new_supplier, Cacofonix::NewSupplier, :singular => true
25
+ onix_code_from_list :date_format, "DateFormat", :list => 55
26
+ xml_accessor :expected_ship_date, :from => "ExpectedShipDate"
27
+ onix_date_accessor :on_sale_date, "OnSaleDate"
28
+ xml_accessor :order_time, :from => "OrderTime", :as => Integer
29
+ onix_composite :stocks, Cacofonix::Stock
30
+ alias_accessor :stock, :stocks # back-compat
31
+ xml_accessor :pack_quantity, :from => "PackQuantity", :as => Integer
32
+ onix_code_from_list :audience_restriction_flag, "AudienceRestrictionFlag", :list => 56
33
+ xml_accessor :audience_restriction_note, :from => "AudienceRestrictionNote"
34
+ onix_code_from_list :unpriced_item_type, "UnpricedItemType", :list => 57
35
+ onix_composite :prices, Cacofonix::Price
36
+ onix_composite :reissue, Cacofonix::Reissue, :singular => true
37
+ end
@@ -0,0 +1,11 @@
1
+ # coding: utf-8
2
+
3
+ class Cacofonix::TextItem < Cacofonix::Element
4
+ xml_name "TextItem"
5
+ onix_code_from_list :text_item_type, "TextItemType", :list => 42
6
+ onix_composite :text_item_identifier, Cacofonix::TextItemIdentifier
7
+ xml_accessor :first_page_number, :from => "FirstPageNumber"
8
+ xml_accessor :last_page_number, :from => "LastPageNumber"
9
+ onix_composite :page_runs, Cacofonix::PageRun
10
+ xml_accessor :number_of_pages, :from => "NumberOfPages", :as => Integer
11
+ end
@@ -0,0 +1,6 @@
1
+ # coding: utf-8
2
+
3
+ class Cacofonix::TextItemIdentifier < Cacofonix::Identifier
4
+ xml_name "TextItemIdentifier"
5
+ onix_code_from_list :text_item_identifier, "TextItemIdentifier", :list => 43
6
+ end
@@ -0,0 +1,11 @@
1
+ # coding: utf-8
2
+
3
+ class Cacofonix::Title < Cacofonix::Element
4
+ xml_name "Title"
5
+ onix_code_from_list :title_type, "TitleType", :list => 15
6
+ xml_accessor :abbreviated_length, :from => "AbbreviatedLength", :as => Integer
7
+ xml_accessor :title_text, :from => "TitleText"
8
+ xml_accessor :title_prefix, :from => "TitlePrefix"
9
+ xml_accessor :title_without_prefix, :from => "TitleWithoutPrefix"
10
+ xml_accessor :subtitle, :from => "Subtitle"
11
+ end
@@ -0,0 +1,8 @@
1
+ # coding: utf-8
2
+
3
+ class Cacofonix::Website < Cacofonix::Element
4
+ xml_name "Website"
5
+ onix_code_from_list :website_role, "WebsiteRole", :list => 73
6
+ xml_accessor :website_description, :from => "WebsiteDescription"
7
+ xml_accessor :website_link, :from => "WebsiteLink"
8
+ end
@@ -0,0 +1,6 @@
1
+ # coding: utf-8
2
+
3
+ class Cacofonix::WorkIdentifier < Cacofonix::Identifier
4
+ xml_name "WorkIdentifier"
5
+ onix_code_from_list :work_id_type, "WorkIDType", :list => 16
6
+ end
@@ -0,0 +1,112 @@
1
+ # coding: utf-8
2
+
3
+ module Cacofonix
4
+
5
+ # A utility class that processes the code list XSD from the ONIX spec and
6
+ # creates a set of TSV files. The generated files are used by this library
7
+ # to make hashes of the code lists available to users.
8
+ #
9
+ class CodeListExtractor
10
+
11
+ FORMATS = [:tsv, :ruby]
12
+
13
+ # Creates a new extractor. Expects the path to a copy of the code lists
14
+ # file from the spec (called ONIX_BookProduct_CodeLists.xsd on my system).
15
+ #
16
+ def initialize(filename, format = :tsv)
17
+ raise ArgumentError, "#{filename} not found" unless File.file?(filename)
18
+
19
+ @filename = filename
20
+ raise "Unknown format: #{format}" unless FORMATS.include?(format)
21
+ @format = format
22
+ end
23
+
24
+ # Generate one file for each list in the specified format in the given
25
+ # directory. Creates the directory if it doesn't exist. This will
26
+ # overwrite any existing files.
27
+ #
28
+ def run(dir)
29
+ FileUtils.mkdir_p(dir)
30
+
31
+ each_list do |number, data|
32
+ send("write_to_#{@format}_format", dir, number, data)
33
+ end
34
+ end
35
+
36
+
37
+ private
38
+
39
+ def data
40
+ @data ||= File.open(@filename) { |f| f.read }
41
+ end
42
+
43
+ def document
44
+ @document ||= Nokogiri::XML(data)
45
+ @document.remove_namespaces! if @document.namespaces.size > 0
46
+ @document
47
+ end
48
+
49
+ def each_list(&block)
50
+ document.xpath("//simpleType").each do |node|
51
+ list_name = node.xpath("./@name").first.value
52
+ list_number = list_name[/List(\d+)/,1].to_i
53
+ if list_number > 0
54
+ yield list_number, list_data(list_number)
55
+ end
56
+ end
57
+ end
58
+
59
+ def list_data(num)
60
+ nodes = document.xpath("//simpleType[@name='List#{num}']/restriction/enumeration")
61
+ nodes.inject([]) do |arr, node|
62
+ code = node.xpath("./@value").first.value
63
+ desc = node.xpath("./annotation/documentation").first.text
64
+ ldesc = node.xpath("./annotation/documentation").last.text
65
+ arr.tap { |a| a << [code, desc, ldesc] }
66
+ end
67
+ end
68
+
69
+ def write_to_tsv_format(dir, number, data)
70
+ file = number.to_s.rjust(3, "0") + ".tsv"
71
+ path = File.join(dir, file)
72
+ out = data.collect { |row| row.join("\t") }.join("\n")
73
+ File.open(path, "w") { |f| f.write out }
74
+ end
75
+
76
+ def write_to_ruby_format(dir, number, data)
77
+ list_num = number.to_s.rjust(3, "0")
78
+ file = list_num + ".rb"
79
+ path = File.join(dir, file)
80
+ str2str = lambda { |str|
81
+ str.gsub!("\342\200\230", "'")
82
+ str.gsub!("\342\200\231", "'")
83
+ str.gsub!("\342\200\234", '"')
84
+ str.gsub!("\342\200\235", '"')
85
+ str.gsub!(/"/, '\"')
86
+ "\"#{str}\""
87
+ }
88
+ # An alternative format: two-dimensional array. More complete,
89
+ # but less addressable.
90
+ #
91
+ # out = ["# coding: utf-8"]
92
+ # out << "module Cacofonix; module CodeLists"
93
+ # out << " LIST_#{number} = ["
94
+ # out += data.collect { |row|
95
+ # row = row.collect { |f| " #{str2str.call(f)}" }
96
+ # " [\n#{row.join(",\n")}\n ]"
97
+ # }.join(",\n")
98
+ # out << " ]"
99
+ # out << "end; end"
100
+ out = ["# coding: utf-8\n"]
101
+ out << "module Cacofonix; module CodeLists"
102
+ out << " LIST_#{number} = {"
103
+ out << data.collect { |row|
104
+ " #{str2str.call(row[0])} => #{str2str.call(row[1])}"
105
+ }.join(",\n")
106
+ out << " }"
107
+ out << "end; end"
108
+ File.open(path, "w") { |f| f.write out.join("\n") }
109
+ end
110
+
111
+ end
112
+ end
@@ -0,0 +1,125 @@
1
+ # coding: utf-8
2
+
3
+ require 'tempfile'
4
+ require 'fileutils'
5
+
6
+ module Cacofonix
7
+
8
+ # A standalone class that can be used to normalise ONIX files
9
+ # into a standardised form. If you're accepting ONIX files from a wide range
10
+ # of suppliers, you're guarunteed to get all sorts of dialects.
11
+ #
12
+ # This will create a new file that:
13
+ #
14
+ # - is UTF-8 encoded
15
+ # - uses reference tags, not short
16
+ # - has no named entities (ndash, etc) other than &amp; &lt; and &gt;
17
+ #
18
+ # Usage:
19
+ #
20
+ # Cacofonix::Normaliser.process("oldfile.xml", "newfile.xml")
21
+ #
22
+ # Dependencies:
23
+ #
24
+ # At this stage the class depends on several external apps, all commonly available
25
+ # on *nix systems: xsltproc, isutf8, iconv and sed
26
+ #
27
+ class Normaliser
28
+
29
+ class << self
30
+
31
+ # normalise oldfile and save it as newfile. oldfile
32
+ # will be left untouched
33
+ #
34
+ def process(oldfile, newfile)
35
+ self.new(oldfile).normalise_to_path(newfile)
36
+ end
37
+ end
38
+
39
+ # NB: Newfile argument is deprecated.
40
+ #
41
+ def initialize(oldfile, newfile = nil)
42
+ raise ArgumentError, "#{oldfile} does not exist" unless File.file?(oldfile)
43
+ raise "xsltproc app not found" unless app_available?("xsltproc")
44
+ raise "tr app not found" unless app_available?("tr")
45
+
46
+ @oldfile = oldfile
47
+ @newfile = newfile
48
+ @curfile = next_tempfile
49
+ FileUtils.cp(@oldfile, @curfile)
50
+ @head = File.open(@oldfile, "r") { |f| f.read(1024) }
51
+ end
52
+
53
+ # This is deprecated - use normalise_to_path with a path.
54
+ def run
55
+ normalise_to_path(@newfile)
56
+ end
57
+
58
+ def normalise_to_path(newfile)
59
+ raise ArgumentError, "#{newfile} already exists" if File.file?(newfile)
60
+ @curfile = normalise_to_tempfile
61
+ FileUtils.cp(@curfile, newfile)
62
+ end
63
+
64
+ # Processes oldfile and puts the normalised result in a tempfile,
65
+ # returning the path to that tempfile.
66
+ #
67
+ def normalise_to_tempfile
68
+ src = @curfile
69
+
70
+ # remove short tags
71
+ if @head.include?("ONIXmessage")
72
+ dest = next_tempfile
73
+ to_reference_tags(src, dest)
74
+ src = dest
75
+ end
76
+
77
+ # remove control chars
78
+ dest = next_tempfile
79
+ remove_control_chars(src, dest)
80
+ dest
81
+ end
82
+
83
+ #private
84
+
85
+ # check the specified app is available on the system
86
+ #
87
+ def app_available?(app)
88
+ `which #{app}`.strip == "" ? false : true
89
+ end
90
+
91
+ # generate a temp filename
92
+ #
93
+ def next_tempfile
94
+ p = nil
95
+ Tempfile.open("onix") do |tf|
96
+ p = tf.path
97
+ tf.close!
98
+ end
99
+ p
100
+ end
101
+
102
+ # uses an XSLT stylesheet provided by edituer to convert
103
+ # a file from short tags to long tags.
104
+ #
105
+ # more detail here:
106
+ # http://www.editeur.org/files/ONIX%203/ONIX%20tagname%20converter%20v2.htm
107
+ #
108
+ def to_reference_tags(src, dest)
109
+ inpath = File.expand_path(src)
110
+ outpath = File.expand_path(dest)
111
+ xsltpath = File.dirname(__FILE__) + "/../../../support/switch-onix-2.1-short-to-reference.xsl"
112
+ `xsltproc -o #{outpath} #{xsltpath} #{inpath}`
113
+ end
114
+
115
+ # XML files shouldn't contain low ASCII control chars. Strip them.
116
+ #
117
+ def remove_control_chars(src, dest)
118
+ inpath = File.expand_path(src)
119
+ outpath = File.expand_path(dest)
120
+ `cat #{inpath} | tr -d "\\000-\\010\\013\\014\\016-\\037" > #{outpath}`
121
+ end
122
+
123
+ end
124
+
125
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cacofonix
4
+ VERSION = "0.10.0"
5
+ end
@@ -0,0 +1,748 @@
1
+ # coding: utf-8
2
+
3
+ module Cacofonix
4
+ class APAProduct < SimpleProduct
5
+
6
+ delegate :record_reference, :record_reference=
7
+ delegate :notification_type, :notification_type=
8
+ delegate :product_form, :product_form=
9
+ delegate :edition, :edition=
10
+ delegate :number_of_pages, :number_of_pages=
11
+ delegate :bic_main_subject, :bic_main_subject=
12
+ delegate :publishing_status, :publishing_status=
13
+ delegate :publication_date, :publication_date=
14
+
15
+ def measurement_system
16
+ @measurement_system ||= :metric
17
+ end
18
+
19
+ def measurement_system=(value)
20
+ if value == :metric || value == :imperial
21
+ @measurement_system = value
22
+ else
23
+ raise ArgumentError, "#{value} is not a recognised measurement system"
24
+ end
25
+ end
26
+
27
+ # retrieve the current EAN
28
+ def ean
29
+ identifier(3).try(:id_value)
30
+ end
31
+
32
+ # set a new EAN
33
+ def ean=(isbn)
34
+ identifier_set(3, isbn)
35
+ end
36
+
37
+ # retrieve the proprietary ID
38
+ def proprietary_id
39
+ identifier(1).tr(:id_value)
40
+ end
41
+
42
+ # set a new proprietary ID
43
+ def proprietary_id=(isbn)
44
+ identifier_set(1, isbn)
45
+ end
46
+
47
+ # retrieve the current ISBN 10
48
+ def isbn10
49
+ identifier(2).try(:id_value)
50
+ end
51
+
52
+ # set a new ISBN 10
53
+ def isbn10=(isbn)
54
+ identifier_set(2, isbn)
55
+ end
56
+
57
+ # retrieve the current ISBN 13
58
+ def isbn13
59
+ identifier(15).try(:id_value)
60
+ end
61
+
62
+ # set a new ISBN 13
63
+ def isbn13=(isbn)
64
+ identifier_set(15, isbn)
65
+ end
66
+
67
+ # retrieve the current title
68
+ def title
69
+ composite = product.titles.first
70
+ if composite.nil?
71
+ nil
72
+ else
73
+ composite.title_text || composite.title_without_prefix
74
+ end
75
+ end
76
+
77
+ # set a new title
78
+ def title=(str)
79
+ composite = product.titles.first
80
+ if composite.nil?
81
+ composite = Cacofonix::Title.new
82
+ composite.title_type = 1
83
+ product.titles << composite
84
+ end
85
+ composite.title_text = str
86
+ end
87
+
88
+ # retrieve the current subtitle
89
+ def subtitle
90
+ composite = product.titles.first
91
+ if composite.nil?
92
+ nil
93
+ else
94
+ composite.subtitle
95
+ end
96
+ end
97
+
98
+ # set a new subtitle
99
+ def subtitle=(str)
100
+ composite = product.titles.first
101
+ if composite.nil?
102
+ composite = Cacofonix::Title.new
103
+ composite.title_type = 1
104
+ product.titles << composite
105
+ end
106
+ composite.subtitle = str
107
+ end
108
+
109
+ def series
110
+ composite = product.series.first
111
+ composite.try(:title_of_series)
112
+ end
113
+
114
+ def series=(val)
115
+ composite = product.series.first
116
+ if composite.nil?
117
+ composite = Cacofonix::Series.new
118
+ product.series << composite
119
+ end
120
+ composite.title_of_series = val.to_s
121
+ end
122
+
123
+ # retrieve the current publisher website for this particular product
124
+ def publisher_website
125
+ website(2).try(:website_link)
126
+ end
127
+
128
+ # set a new publisher website for this particular product
129
+ def publisher_website=(str)
130
+ website_set(2, str)
131
+ end
132
+
133
+ # retrieve the current supplier website for this particular product
134
+ def supplier_website
135
+ website(12).try(:website_link)
136
+ end
137
+
138
+ # set a new supplier website for this particular product
139
+ def supplier_website=(str)
140
+ website_set(12, str)
141
+ end
142
+
143
+ # retrieve an array of all contributors
144
+ def contributors
145
+ product.contributors.collect { |contrib| contrib.person_name_inverted || contrib.person_name}
146
+ end
147
+
148
+ # set a new contributor to this product
149
+ # str should be the contributors name inverted (Healy, James)
150
+ def add_contributor(str, role = "A01")
151
+ contrib = ::Cacofonix::Contributor.new
152
+ contrib.sequence_number = product.contributors.size + 1
153
+ contrib.contributor_role = role
154
+ contrib.person_name_inverted = str
155
+ product.contributors << contrib
156
+ end
157
+
158
+ # return an array of BIC subjects for this title
159
+ # could be version 1 or version 2, most ONIX files don't
160
+ # specifiy
161
+ def bic_subjects
162
+ subjects = product.subjects.select { |sub| sub.subject_scheme_id.to_i == 12 }
163
+ subjects.collect { |sub| sub.subject_code}
164
+ end
165
+
166
+ # add a BIC subject code to the product
167
+ def add_bic_subject(code)
168
+ add_subject code, "12"
169
+ end
170
+
171
+ # return an array of BISAC subjects for this title
172
+ def bisac_subjects
173
+ subjects = product.subjects.select { |sub| sub.subject_scheme_id.to_i == 10 }
174
+ subjects.collect { |sub| sub.subject_code}
175
+ end
176
+
177
+ # add a BISAC subject code to the product
178
+ def add_bisac_subject(code)
179
+ add_subject code, "10"
180
+ end
181
+
182
+ # retrieve the url to the product cover image
183
+ def cover_url
184
+ media_file(4).try(:media_file_link)
185
+ end
186
+
187
+ # set the url to the product cover image
188
+ def cover_url=(url)
189
+ # 4 - cover image
190
+ # 1 - URI
191
+ media_file_set(4,1,url)
192
+ end
193
+
194
+ # retrieve the url to the high quality product cover image
195
+ def cover_url_hq
196
+ media_file(6).try(:media_file_link)
197
+ end
198
+
199
+ # set the url to the high quality product cover image
200
+ def cover_url_hq=(url)
201
+ # 6 - hq cover image
202
+ # 1 - URI
203
+ media_file_set(6,1,url)
204
+ end
205
+
206
+ # retrieve the url to the product thumbnail
207
+ def thumbnail_url
208
+ media_file(7).try(:media_file_link)
209
+ end
210
+
211
+ # set the url to the product cover image
212
+ def thumbnail_url=(url)
213
+ # 7 - thumbnail image
214
+ # 1 - URI
215
+ media_file_set(7,1,url)
216
+ end
217
+
218
+ # retrieve the main description
219
+ def main_description
220
+ other_text(1).try(:text)
221
+ end
222
+
223
+ # set the main description
224
+ def main_description=(t)
225
+ other_text_set(1,t)
226
+ end
227
+
228
+ # retrieve the short description
229
+ def short_description
230
+ other_text(2).try(:text)
231
+ end
232
+
233
+ # set the short description
234
+ def short_description=(t)
235
+ other_text_set(2,t)
236
+ end
237
+
238
+ # retrieve the long description
239
+ def long_description
240
+ other_text(3).try(:text)
241
+ end
242
+
243
+ # set the long description
244
+ def long_description=(t)
245
+ other_text_set(3,t)
246
+ end
247
+
248
+ # retrieve the imprint
249
+ def imprint
250
+ composite = product.imprints.first
251
+ composite ? composite.imprint_name : nil
252
+ end
253
+
254
+ # set a new imprint
255
+ def imprint=(str)
256
+ composite = product.imprints.first
257
+ if composite.nil?
258
+ composite = Cacofonix::Imprint.new
259
+ product.imprints << composite
260
+ end
261
+ composite.imprint_name = str
262
+ end
263
+
264
+ # retrieve the publisher
265
+ def publisher
266
+ publisher_get(1).try(:publisher_name)
267
+ end
268
+
269
+ # set a new publisher
270
+ def publisher=(str)
271
+ publisher_set(1, str)
272
+ end
273
+
274
+ # retrieve the sales restriction type
275
+ def sales_restriction_type
276
+ composite = product.sales_restrictions.first
277
+ composite.nil? ? nil : composite.imprint_name
278
+ end
279
+
280
+ # set a new sales restriction type
281
+ def sales_restriction_type=(type)
282
+ composite = product.sales_restrictions.first
283
+ if composite.nil?
284
+ composite = Cacofonix::SalesRestriction.new
285
+ product.sales_restrictions << composite
286
+ end
287
+ composite.sales_restriction_type = type
288
+ end
289
+
290
+ # retrieve the supplier name
291
+ def supplier_name
292
+ composite = product.supply_details.first
293
+ composite.nil? ? nil : composite.supplier_name
294
+ end
295
+
296
+ # set a new supplier name
297
+ def supplier_name=(str)
298
+ composite = find_or_create_supply_detail
299
+ composite.supplier_name = str
300
+ end
301
+
302
+ # retrieve the supplier phone number
303
+ def supplier_phone
304
+ composite = product.supply_details.first
305
+ composite.nil? ? nil : composite.telephone_number
306
+ end
307
+
308
+ # set a new supplier phone number
309
+ def supplier_phone=(str)
310
+ composite = find_or_create_supply_detail
311
+ composite.telephone_number = str
312
+ end
313
+
314
+ # retrieve the supplier fax number
315
+ def supplier_fax
316
+ composite = product.supply_details.first
317
+ composite.nil? ? nil : composite.fax_number
318
+ end
319
+
320
+ # set a new supplier fax number
321
+ def supplier_fax=(str)
322
+ composite = find_or_create_supply_detail
323
+ composite.fax_number = str
324
+ end
325
+
326
+ # retrieve the supplier email address
327
+ def supplier_email
328
+ composite = product.supply_details.first
329
+ composite.nil? ? nil : composite.email_address
330
+ end
331
+
332
+ # set a new supplier email address
333
+ def supplier_email=(str)
334
+ composite = find_or_create_supply_detail
335
+ composite.email_address = str
336
+ end
337
+
338
+ # retrieve the supply country code
339
+ def supply_country
340
+ composite = product.supply_details.first
341
+ composite.nil? ? nil : composite.supply_to_country
342
+ end
343
+
344
+ # set a new supply country code
345
+ def supply_country=(str)
346
+ composite = find_or_create_supply_detail
347
+ composite.supply_to_country = str
348
+ end
349
+
350
+ # retrieve the product availability code
351
+ def product_availability
352
+ composite = product.supply_details.first
353
+ composite.nil? ? nil : composite.product_availability
354
+ end
355
+
356
+ # set a new product availability
357
+ def product_availability=(num)
358
+ composite = find_or_create_supply_detail
359
+ composite.product_availability = num
360
+ end
361
+
362
+ # retrieve the number in stock
363
+ def on_hand
364
+ supply = find_or_create_supply_detail
365
+ composite = supply.stock.first
366
+ if composite.nil?
367
+ composite = Cacofonix::Stock.new
368
+ supply.stock << composite
369
+ end
370
+ composite.on_hand
371
+ end
372
+
373
+ # set a new in stock quantity
374
+ def on_hand=(num)
375
+ supply = find_or_create_supply_detail
376
+ composite = supply.stock.first
377
+ if composite.nil?
378
+ composite = Cacofonix::Stock.new
379
+ supply.stock << composite
380
+ end
381
+ composite.on_hand = num
382
+ end
383
+
384
+ # retrieve the number on order
385
+ def on_order
386
+ supply = find_or_create_supply_detail
387
+ composite = supply.stock.first
388
+ if composite.nil?
389
+ composite = Cacofonix::Stock.new
390
+ supply.stock << composite
391
+ end
392
+ composite.on_order
393
+ end
394
+
395
+ # set a new on order quantity
396
+ def on_order=(num)
397
+ supply = find_or_create_supply_detail
398
+ composite = supply.stock.first
399
+ if composite.nil?
400
+ composite = Cacofonix::Stock.new
401
+ supply.stock << composite
402
+ end
403
+ composite.on_order = num
404
+ end
405
+
406
+ # retrieve the supplier phone number
407
+ def pack_quantity
408
+ composite = product.supply_details.first
409
+ composite.nil? ? nil : composite.pack_quantity
410
+ end
411
+
412
+ # set a new supplier phone number
413
+ def pack_quantity=(val)
414
+ composite = find_or_create_supply_detail
415
+ composite.pack_quantity = val.to_i
416
+ end
417
+
418
+ # retrieve the rrp excluding any sales tax
419
+ def rrp_exc_sales_tax
420
+ price_get(1).try(:price_amount)
421
+ end
422
+
423
+ # set the rrp excluding any sales tax
424
+ def rrp_exc_sales_tax=(num)
425
+ price_set(1, num)
426
+ end
427
+
428
+ # retrieve the rrp including any sales tax
429
+ def rrp_inc_sales_tax
430
+ price_get(2).try(:price_amount)
431
+ end
432
+
433
+ # set the rrp including any sales tax
434
+ def rrp_inc_sales_tax=(num)
435
+ price_set(2, num)
436
+ end
437
+
438
+ # just get the first price we can find, regardless of the type.
439
+ # useful as a backup for reading files from that don't contain a type
440
+ def price
441
+ price_get(nil).try(:price_amount)
442
+ end
443
+
444
+ # retrieve the height of the product
445
+ #
446
+ # If APAProduct#measurement_system is metric, these will be in mm, otherwise they
447
+ # will be in inches.
448
+ #
449
+ def height
450
+ # TODO: auto unit conversion
451
+ measurement(1).try(:measurement)
452
+ end
453
+
454
+ # set the height of the book
455
+ #
456
+ # If APAProduct#measurement_system is metric, this should be in mm, otherwise it
457
+ # will be in inches.
458
+ #
459
+ def height=(value)
460
+ if measurement_system == :metric
461
+ measurement_set(1,value, "mm")
462
+ elsif measurement_system == :imperial
463
+ measurement_set(1,value, "in")
464
+ end
465
+ end
466
+
467
+ # retrieve the width of the product
468
+ #
469
+ # If APAProduct#measurement_system is metric, these will be in mm, otherwise they
470
+ # will be in inches.
471
+ #
472
+ def width
473
+ # TODO: auto unit conversion
474
+ measurement(2).try(:measurement)
475
+ end
476
+
477
+ # set the width of the product
478
+ #
479
+ # If APAProduct#measurement_system is metric, this should be in mm, otherwise it
480
+ # will be in inches.
481
+ #
482
+ def width=(value)
483
+ if measurement_system == :metric
484
+ measurement_set(2,value, "mm")
485
+ elsif measurement_system == :imperial
486
+ measurement_set(2,value, "in")
487
+ end
488
+ end
489
+
490
+ # retrieve the weight of the product
491
+ #
492
+ # If APAProduct#measurement_system is metric, these will be in grams, otherwise they
493
+ # will be in ounces.
494
+ #
495
+ def weight
496
+ # TODO: auto unit conversion
497
+ measurement(8).try(:measurement)
498
+ end
499
+
500
+ # set the weight of the product
501
+ #
502
+ # If APAProduct#measurement_system is metric, this should be in grams, otherwise it
503
+ # will be in ounces.
504
+ #
505
+ def weight=(value)
506
+ if measurement_system == :metric
507
+ measurement_set(8,value, "gr")
508
+ elsif measurement_system == :imperial
509
+ measurement_set(8,value, "oz")
510
+ end
511
+ end
512
+
513
+ # retrieve the thickness of the product
514
+ #
515
+ # If APAProduct#measurement_system is metric, these will be in mm, otherwise they
516
+ # will be in inches.
517
+ #
518
+ def thickness
519
+ # TODO: auto unit conversion
520
+ measurement(3).try(:measurement)
521
+ end
522
+
523
+ # set the thickness of the product
524
+ #
525
+ # If APAProduct#measurement_system is metric, this should be in mm, otherwise it
526
+ # will be in inches.
527
+ #
528
+ def thickness=(value)
529
+ if measurement_system == :metric
530
+ measurement_set(3,value, "mm")
531
+ elsif measurement_system == :imperial
532
+ measurement_set(3,value, "in")
533
+ end
534
+ end
535
+
536
+ def agent_name
537
+ reps = product.market_representations.first
538
+ return nil if reps.nil?
539
+ reps.agent_name
540
+ end
541
+
542
+ def agent_name=(value)
543
+ reps = product.market_representations.first
544
+ if reps.nil?
545
+ reps = Cacofonix::MarketRepresentation.new
546
+ product.market_representations << reps
547
+ end
548
+ reps.agent_name = value.to_s
549
+ end
550
+
551
+ def market_country
552
+ reps = product.market_representations.first
553
+ return nil if reps.nil?
554
+ reps.market_country
555
+ end
556
+
557
+ def market_country=(value)
558
+ reps = product.market_representations.first
559
+ if reps.nil?
560
+ reps = Cacofonix::MarketRepresentation.new
561
+ product.market_representations << reps
562
+ end
563
+ reps.market_country = value.to_s
564
+ end
565
+
566
+ def market_publishing_status
567
+ reps = product.market_representations.first
568
+ return nil if reps.nil?
569
+ reps.market_publishing_status
570
+ end
571
+
572
+ def market_publishing_status=(value)
573
+ reps = product.market_representations.first
574
+ if reps.nil?
575
+ reps = Cacofonix::MarketRepresentation.new
576
+ product.market_representations << reps
577
+ end
578
+ reps.market_publishing_status = value.to_i
579
+ end
580
+
581
+ private
582
+
583
+ # add a new subject to this product
584
+ # str should be the subject code
585
+ # type should be the code for the subject scheme you're using. See ONIX codelist 27.
586
+ # 12 is BIC
587
+ def add_subject(str, type = "12")
588
+ subject = ::Cacofonix::Subject.new
589
+ subject.subject_scheme_id = type.to_i
590
+ subject.subject_code = str
591
+ product.subjects << subject
592
+ end
593
+
594
+ def find_or_create_supply_detail
595
+ composite = product.supply_details.first
596
+ if composite.nil?
597
+ composite = Cacofonix::SupplyDetail.new
598
+ product.supply_details << composite
599
+ end
600
+ composite
601
+ end
602
+
603
+ # retrieve the value of a particular ID
604
+ def identifier(type)
605
+ product.product_identifiers.find { |id| id.product_id_type == type }
606
+ end
607
+
608
+ # set the value of a particular ID
609
+ def identifier_set(type, value)
610
+ isbn_id = identifier(type)
611
+
612
+ # create a new isbn record if we need to
613
+ if isbn_id.nil?
614
+ isbn_id = Cacofonix::ProductIdentifier.new
615
+ isbn_id.product_id_type = type
616
+ product.product_identifiers << isbn_id
617
+ end
618
+
619
+ isbn_id.id_value = value
620
+ end
621
+
622
+ # retrieve the value of a particular measurement
623
+ def measurement(type)
624
+ product.measurements.find { |m| m.measure_type_code == type }
625
+ end
626
+
627
+ # set the value of a particular measurement
628
+ def measurement_set(type, value, unit)
629
+ measure = measurement(type)
630
+
631
+ # create a new isbn record if we need to
632
+ if measure.nil?
633
+ measure = Cacofonix::Measure.new
634
+ measure.measure_type_code = type
635
+ product.measurements << measure
636
+ end
637
+
638
+ # store the new value
639
+ measure.measurement = value
640
+ measure.measure_unit_code = unit.to_s
641
+ end
642
+
643
+ # retrieve the value of a particular media file
644
+ def media_file(type)
645
+ product.media_files.find { |m| m.media_file_type_code == type }
646
+ end
647
+
648
+ # set the value of a particular ID
649
+ def media_file_set(type, link_type, value)
650
+ media = media_file(type)
651
+
652
+ # create a new isbn record if we need to
653
+ if media.nil?
654
+ media = Cacofonix::MediaFile.new
655
+ media.media_file_type_code = type
656
+ media.media_file_link_type_code = link_type
657
+ product.media_files << media
658
+ end
659
+
660
+ # store the new value
661
+ media.media_file_link = value.to_s
662
+ end
663
+
664
+ # retrieve the value of a particular price
665
+ def price_get(type)
666
+ supply = find_or_create_supply_detail
667
+ if type.nil?
668
+ supply.prices.first
669
+ else
670
+ supply.prices.find { |p| p.price_type_code == type }
671
+ end
672
+ end
673
+
674
+ # set the value of a particular price
675
+ def price_set(type, num)
676
+ p = price_get(type)
677
+
678
+ # create a new isbn record if we need to
679
+ if p.nil?
680
+ supply = find_or_create_supply_detail
681
+ p = Cacofonix::Price.new
682
+ p.price_type_code = type
683
+ supply.prices << p
684
+ end
685
+
686
+ # store the new value
687
+ p.price_amount = num
688
+ end
689
+
690
+ # retrieve the value of a particular publisher
691
+ def publisher_get(type)
692
+ product.publishers.find { |pub| pub.publishing_role == type }
693
+ end
694
+
695
+ # set the value of a particular ID
696
+ def publisher_set(type, value)
697
+ pub = publisher_get(type)
698
+
699
+ # create a new isbn record if we need to
700
+ if pub.nil?
701
+ pub = Cacofonix::Publisher.new
702
+ pub.publishing_role = type
703
+ product.publishers << pub
704
+ end
705
+
706
+ # store the new value
707
+ pub.publisher_name = value.to_s
708
+ end
709
+
710
+ # retrieve the value of a particular other text value
711
+ def other_text(type)
712
+ product.text.find { |t| t.text_type_code == type }
713
+ end
714
+
715
+ # set the value of a particular other text value
716
+ def other_text_set(type, value)
717
+ text = other_text(type)
718
+
719
+ if text.nil?
720
+ text = Cacofonix::OtherText.new
721
+ text.text_type_code = type
722
+ product.text << text
723
+ end
724
+
725
+ # store the new value
726
+ text.text = value.to_s
727
+ end
728
+
729
+ # retrieve the value of a particular website
730
+ def website(type)
731
+ product.websites.find { |site| site.website_role == type }
732
+ end
733
+
734
+ # set the value of a particular website
735
+ def website_set(type, value)
736
+ site = website(type)
737
+
738
+ # create a new website record if we need to
739
+ if site.nil?
740
+ site = Cacofonix::Website.new
741
+ site.website_role = type
742
+ product.websites << site
743
+ end
744
+
745
+ site.website_link = value.to_s
746
+ end
747
+ end
748
+ end