cacofonix 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/.rvmrc +1 -0
- data/.travis.yml +10 -0
- data/CHANGELOG.md +205 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +22 -0
- data/README.md +76 -0
- data/Rakefile +6 -0
- data/TODO +14 -0
- data/bin/onix_extract_codelists +41 -0
- data/cacofonix.gemspec +39 -0
- data/data/9780194351898.xml +74 -0
- data/data/Ashgate Other.xml +382679 -0
- data/data/Bookwise_July_2008.xml +21611 -0
- data/data/Peribo Onix 0408.xml +17051 -0
- data/data/aau.xml +96 -0
- data/data/audience_range.xml +9 -0
- data/data/contributor.xml +6 -0
- data/data/control_chars.xml +74 -0
- data/data/entities.xml +78 -0
- data/data/extra_entities.xml +65 -0
- data/data/header.xml +21 -0
- data/data/header_invalid_sentdate.xml +21 -0
- data/data/hlasep08.xml +24519 -0
- data/data/imprint.xml +5 -0
- data/data/iso_8859_1.xml +58 -0
- data/data/jul.xml +24783 -0
- data/data/language.xml +7 -0
- data/data/market_representation.xml +11 -0
- data/data/measure.xml +6 -0
- data/data/media_file.xml +6 -0
- data/data/no_encoding.xml +78 -0
- data/data/no_xml_declaration.xml +95 -0
- data/data/other_text.xml +5 -0
- data/data/price.xml +5 -0
- data/data/product.xml +79 -0
- data/data/product_identifier.xml +5 -0
- data/data/product_invalid_pubdate.xml +42 -0
- data/data/publisher.xml +5 -0
- data/data/rba_FANT.xml +23 -0
- data/data/reference_with_release_attrib.xml +74 -0
- data/data/sales_restriction.xml +4 -0
- data/data/sales_rights.xml +35 -0
- data/data/sender_identifier.xml +5 -0
- data/data/series.xml +5 -0
- data/data/series_identifier.xml +6 -0
- data/data/short_tags.xml +191 -0
- data/data/short_tags_ivp.xml +231 -0
- data/data/sl_product.xml +81 -0
- data/data/stock.xml +5 -0
- data/data/subject.xml +6 -0
- data/data/supply_detail.xml +18 -0
- data/data/title.xml +6 -0
- data/data/two_products.xml +114 -0
- data/data/usd.xml +175 -0
- data/data/utf_16.xml +0 -0
- data/data/website.xml +6 -0
- data/examples/reader.rb +25 -0
- data/examples/reader_apa.rb +22 -0
- data/examples/writer.rb +13 -0
- data/examples/writer_apa.rb +38 -0
- data/lib/cacofonix.rb +151 -0
- data/lib/cacofonix/codelists/001.rb +16 -0
- data/lib/cacofonix/codelists/002.rb +11 -0
- data/lib/cacofonix/codelists/003.rb +13 -0
- data/lib/cacofonix/codelists/005.rb +20 -0
- data/lib/cacofonix/codelists/006.rb +82 -0
- data/lib/cacofonix/codelists/007.rb +129 -0
- data/lib/cacofonix/codelists/008.rb +13 -0
- data/lib/cacofonix/codelists/009.rb +13 -0
- data/lib/cacofonix/codelists/010.rb +52 -0
- data/lib/cacofonix/codelists/011.rb +17 -0
- data/lib/cacofonix/codelists/012.rb +17 -0
- data/lib/cacofonix/codelists/013.rb +13 -0
- data/lib/cacofonix/codelists/014.rb +10 -0
- data/lib/cacofonix/codelists/015.rb +19 -0
- data/lib/cacofonix/codelists/016.rb +12 -0
- data/lib/cacofonix/codelists/017.rb +96 -0
- data/lib/cacofonix/codelists/018.rb +11 -0
- data/lib/cacofonix/codelists/019.rb +13 -0
- data/lib/cacofonix/codelists/020.rb +7 -0
- data/lib/cacofonix/codelists/021.rb +39 -0
- data/lib/cacofonix/codelists/022.rb +15 -0
- data/lib/cacofonix/codelists/023.rb +19 -0
- data/lib/cacofonix/codelists/024.rb +17 -0
- data/lib/cacofonix/codelists/025.rb +35 -0
- data/lib/cacofonix/codelists/026.rb +86 -0
- data/lib/cacofonix/codelists/027.rb +90 -0
- data/lib/cacofonix/codelists/028.rb +14 -0
- data/lib/cacofonix/codelists/029.rb +25 -0
- data/lib/cacofonix/codelists/030.rb +22 -0
- data/lib/cacofonix/codelists/031.rb +9 -0
- data/lib/cacofonix/codelists/032.rb +8 -0
- data/lib/cacofonix/codelists/033.rb +43 -0
- data/lib/cacofonix/codelists/034.rb +21 -0
- data/lib/cacofonix/codelists/035.rb +12 -0
- data/lib/cacofonix/codelists/036.rb +9 -0
- data/lib/cacofonix/codelists/037.rb +12 -0
- data/lib/cacofonix/codelists/038.rb +43 -0
- data/lib/cacofonix/codelists/039.rb +14 -0
- data/lib/cacofonix/codelists/040.rb +12 -0
- data/lib/cacofonix/codelists/041.rb +12 -0
- data/lib/cacofonix/codelists/042.rb +22 -0
- data/lib/cacofonix/codelists/043.rb +12 -0
- data/lib/cacofonix/codelists/044.rb +22 -0
- data/lib/cacofonix/codelists/045.rb +19 -0
- data/lib/cacofonix/codelists/046.rb +15 -0
- data/lib/cacofonix/codelists/047.rb +10 -0
- data/lib/cacofonix/codelists/048.rb +17 -0
- data/lib/cacofonix/codelists/049.rb +91 -0
- data/lib/cacofonix/codelists/050.rb +14 -0
- data/lib/cacofonix/codelists/051.rb +36 -0
- data/lib/cacofonix/codelists/052.rb +7 -0
- data/lib/cacofonix/codelists/053.rb +10 -0
- data/lib/cacofonix/codelists/054.rb +29 -0
- data/lib/cacofonix/codelists/055.rb +23 -0
- data/lib/cacofonix/codelists/056.rb +8 -0
- data/lib/cacofonix/codelists/057.rb +11 -0
- data/lib/cacofonix/codelists/058.rb +29 -0
- data/lib/cacofonix/codelists/059.rb +13 -0
- data/lib/cacofonix/codelists/060.rb +8 -0
- data/lib/cacofonix/codelists/061.rb +9 -0
- data/lib/cacofonix/codelists/062.rb +11 -0
- data/lib/cacofonix/codelists/063.rb +7 -0
- data/lib/cacofonix/codelists/064.rb +19 -0
- data/lib/cacofonix/codelists/065.rb +34 -0
- data/lib/cacofonix/codelists/066.rb +10 -0
- data/lib/cacofonix/codelists/067.rb +8 -0
- data/lib/cacofonix/codelists/068.rb +22 -0
- data/lib/cacofonix/codelists/069.rb +10 -0
- data/lib/cacofonix/codelists/070.rb +8 -0
- data/lib/cacofonix/codelists/071.rb +16 -0
- data/lib/cacofonix/codelists/072.rb +13 -0
- data/lib/cacofonix/codelists/073.rb +42 -0
- data/lib/cacofonix/codelists/074.rb +495 -0
- data/lib/cacofonix/codelists/075.rb +8 -0
- data/lib/cacofonix/codelists/076.rb +18 -0
- data/lib/cacofonix/codelists/077.rb +25 -0
- data/lib/cacofonix/codelists/078.rb +173 -0
- data/lib/cacofonix/codelists/079.rb +25 -0
- data/lib/cacofonix/codelists/080.rb +26 -0
- data/lib/cacofonix/codelists/081.rb +45 -0
- data/lib/cacofonix/codelists/082.rb +23 -0
- data/lib/cacofonix/codelists/083.rb +74 -0
- data/lib/cacofonix/codelists/084.rb +16 -0
- data/lib/cacofonix/codelists/085.rb +29 -0
- data/lib/cacofonix/codelists/086.rb +11 -0
- data/lib/cacofonix/codelists/087.rb +12 -0
- data/lib/cacofonix/codelists/088.rb +7 -0
- data/lib/cacofonix/codelists/089.rb +7 -0
- data/lib/cacofonix/codelists/090.rb +17 -0
- data/lib/cacofonix/codelists/091.rb +257 -0
- data/lib/cacofonix/codelists/092.rb +14 -0
- data/lib/cacofonix/codelists/093.rb +19 -0
- data/lib/cacofonix/codelists/094.rb +9 -0
- data/lib/cacofonix/codelists/095.rb +9 -0
- data/lib/cacofonix/codelists/096.rb +191 -0
- data/lib/cacofonix/codelists/097.rb +7 -0
- data/lib/cacofonix/codelists/098.rb +27 -0
- data/lib/cacofonix/codelists/099.rb +30 -0
- data/lib/cacofonix/codelists/100.rb +12 -0
- data/lib/cacofonix/codelists/101.rb +8 -0
- data/lib/cacofonix/codelists/102.rb +9 -0
- data/lib/cacofonix/codelists/121.rb +164 -0
- data/lib/cacofonix/codelists/138.rb +12 -0
- data/lib/cacofonix/codelists/139.rb +76 -0
- data/lib/cacofonix/codelists/140.rb +13 -0
- data/lib/cacofonix/codelists/141.rb +16 -0
- data/lib/cacofonix/codelists/142.rb +18 -0
- data/lib/cacofonix/codelists/143.rb +13 -0
- data/lib/cacofonix/codelists/144.rb +12 -0
- data/lib/cacofonix/codelists/145.rb +13 -0
- data/lib/cacofonix/codelists/146.rb +9 -0
- data/lib/cacofonix/codelists/147.rb +16 -0
- data/lib/cacofonix/codelists/148.rb +9 -0
- data/lib/cacofonix/codelists/149.rb +10 -0
- data/lib/cacofonix/codelists/150.rb +130 -0
- data/lib/cacofonix/codelists/151.rb +13 -0
- data/lib/cacofonix/codelists/152.rb +8 -0
- data/lib/cacofonix/codelists/153.rb +20 -0
- data/lib/cacofonix/codelists/154.rb +15 -0
- data/lib/cacofonix/codelists/155.rb +11 -0
- data/lib/cacofonix/codelists/156.rb +10 -0
- data/lib/cacofonix/codelists/157.rb +10 -0
- data/lib/cacofonix/codelists/158.rb +32 -0
- data/lib/cacofonix/codelists/159.rb +12 -0
- data/lib/cacofonix/codelists/160.rb +10 -0
- data/lib/cacofonix/codelists/161.rb +9 -0
- data/lib/cacofonix/codelists/162.rb +12 -0
- data/lib/cacofonix/codelists/163.rb +17 -0
- data/lib/cacofonix/codelists/164.rb +11 -0
- data/lib/cacofonix/codelists/165.rb +9 -0
- data/lib/cacofonix/codelists/166.rb +9 -0
- data/lib/cacofonix/codelists/167.rb +9 -0
- data/lib/cacofonix/codelists/168.rb +8 -0
- data/lib/cacofonix/codelists/169.rb +9 -0
- data/lib/cacofonix/codelists/170.rb +7 -0
- data/lib/cacofonix/codelists/171.rb +8 -0
- data/lib/cacofonix/codelists/172.rb +7 -0
- data/lib/cacofonix/codelists/173.rb +8 -0
- data/lib/cacofonix/codelists/174.rb +8 -0
- data/lib/cacofonix/codelists/175.rb +206 -0
- data/lib/cacofonix/codelists/176.rb +20 -0
- data/lib/cacofonix/codelists/177.rb +8 -0
- data/lib/cacofonix/codelists/178.rb +24 -0
- data/lib/cacofonix/codelists/179.rb +7 -0
- data/lib/cacofonix/codelists/184.rb +11 -0
- data/lib/cacofonix/core/code.rb +106 -0
- data/lib/cacofonix/core/element.rb +275 -0
- data/lib/cacofonix/core/header.rb +45 -0
- data/lib/cacofonix/core/lists.rb +108 -0
- data/lib/cacofonix/core/reader.rb +166 -0
- data/lib/cacofonix/core/writer.rb +123 -0
- data/lib/cacofonix/elements/addressee_identifier.rb +6 -0
- data/lib/cacofonix/elements/agent_identifier.rb +6 -0
- data/lib/cacofonix/elements/audience.rb +8 -0
- data/lib/cacofonix/elements/audience_range.rb +15 -0
- data/lib/cacofonix/elements/batch_bonus.rb +7 -0
- data/lib/cacofonix/elements/bible.rb +12 -0
- data/lib/cacofonix/elements/complexity.rb +7 -0
- data/lib/cacofonix/elements/conference.rb +14 -0
- data/lib/cacofonix/elements/conference_sponsor.rb +8 -0
- data/lib/cacofonix/elements/conference_sponsor_identifier.rb +6 -0
- data/lib/cacofonix/elements/contained_item.rb +6 -0
- data/lib/cacofonix/elements/content_item.rb +21 -0
- data/lib/cacofonix/elements/contributor.rb +19 -0
- data/lib/cacofonix/elements/copyright_owner.rb +8 -0
- data/lib/cacofonix/elements/copyright_owner_identifier.rb +6 -0
- data/lib/cacofonix/elements/copyright_statement.rb +7 -0
- data/lib/cacofonix/elements/discount_coded.rb +8 -0
- data/lib/cacofonix/elements/extent.rb +8 -0
- data/lib/cacofonix/elements/identifier.rb +7 -0
- data/lib/cacofonix/elements/illustrations.rb +8 -0
- data/lib/cacofonix/elements/imprint.rb +9 -0
- data/lib/cacofonix/elements/language.rb +8 -0
- data/lib/cacofonix/elements/location_identifier.rb +8 -0
- data/lib/cacofonix/elements/main_subject.rb +9 -0
- data/lib/cacofonix/elements/market_date.rb +8 -0
- data/lib/cacofonix/elements/market_representation.rb +18 -0
- data/lib/cacofonix/elements/measure.rb +8 -0
- data/lib/cacofonix/elements/media_file.rb +16 -0
- data/lib/cacofonix/elements/name.rb +6 -0
- data/lib/cacofonix/elements/name_base.rb +17 -0
- data/lib/cacofonix/elements/new_supplier.rb +12 -0
- data/lib/cacofonix/elements/not_for_sale.rb +13 -0
- data/lib/cacofonix/elements/on_order_detail.rb +7 -0
- data/lib/cacofonix/elements/other_text.rb +17 -0
- data/lib/cacofonix/elements/page_run.rb +7 -0
- data/lib/cacofonix/elements/person_date.rb +8 -0
- data/lib/cacofonix/elements/person_name_identifier.rb +6 -0
- data/lib/cacofonix/elements/price.rb +46 -0
- data/lib/cacofonix/elements/prize.rb +10 -0
- data/lib/cacofonix/elements/product.rb +155 -0
- data/lib/cacofonix/elements/product_base.rb +61 -0
- data/lib/cacofonix/elements/product_classification.rb +8 -0
- data/lib/cacofonix/elements/product_form_feature.rb +8 -0
- data/lib/cacofonix/elements/product_identifier.rb +6 -0
- data/lib/cacofonix/elements/professional_affiliation.rb +7 -0
- data/lib/cacofonix/elements/publisher.rb +11 -0
- data/lib/cacofonix/elements/reissue.rb +9 -0
- data/lib/cacofonix/elements/related_product.rb +6 -0
- data/lib/cacofonix/elements/religious_text.rb +8 -0
- data/lib/cacofonix/elements/religious_text_feature.rb +8 -0
- data/lib/cacofonix/elements/sales_outlet.rb +7 -0
- data/lib/cacofonix/elements/sales_outlet_identifier.rb +6 -0
- data/lib/cacofonix/elements/sales_restriction.rb +7 -0
- data/lib/cacofonix/elements/sales_rights.rb +13 -0
- data/lib/cacofonix/elements/sender_identifier.rb +6 -0
- data/lib/cacofonix/elements/series.rb +11 -0
- data/lib/cacofonix/elements/series_identifier.rb +6 -0
- data/lib/cacofonix/elements/set.rb +13 -0
- data/lib/cacofonix/elements/stock.rb +16 -0
- data/lib/cacofonix/elements/stock_quantity_coded.rb +8 -0
- data/lib/cacofonix/elements/subject.rb +13 -0
- data/lib/cacofonix/elements/supplier_identifier.rb +6 -0
- data/lib/cacofonix/elements/supply_detail.rb +37 -0
- data/lib/cacofonix/elements/text_item.rb +11 -0
- data/lib/cacofonix/elements/text_item_identifier.rb +6 -0
- data/lib/cacofonix/elements/title.rb +11 -0
- data/lib/cacofonix/elements/website.rb +8 -0
- data/lib/cacofonix/elements/work_identifier.rb +6 -0
- data/lib/cacofonix/utils/code_list_extractor.rb +112 -0
- data/lib/cacofonix/utils/normaliser.rb +125 -0
- data/lib/cacofonix/version.rb +5 -0
- data/lib/cacofonix/wrappers/apa_product.rb +748 -0
- data/lib/cacofonix/wrappers/simple_product.rb +49 -0
- data/support/entities.txt +1499 -0
- data/support/extract.rb +25 -0
- data/support/switch-onix-2.1-short-to-reference.xsl +24 -0
- data/support/switch-onix-tagnames-1.1.xsl +25 -0
- data/support/switch-onix-tagnames-2.0.xsl +37 -0
- 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,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,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 & < and >
|
|
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,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
|