im_onix 1.0.2 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -0
  3. data/.yardopts +1 -0
  4. data/Gemfile +8 -0
  5. data/LICENSE.md +7 -0
  6. data/README.md +3 -3
  7. data/Rakefile +10 -0
  8. data/bin/html_codelist_to_yml.rb +14 -15
  9. data/bin/onix_bench.rb +1 -0
  10. data/bin/onix_pp.rb +4 -8
  11. data/bin/onix_serialize.rb +27 -0
  12. data/doc-src/handlers.rb +154 -0
  13. data/im_onix.gemspec +32 -0
  14. data/lib/im_onix.rb +0 -1
  15. data/lib/onix/addressee.rb +10 -0
  16. data/lib/onix/code.rb +108 -282
  17. data/lib/onix/collateral_detail.rb +24 -17
  18. data/lib/onix/collection.rb +38 -0
  19. data/lib/onix/collection_sequence.rb +7 -0
  20. data/lib/onix/contributor.rb +40 -39
  21. data/lib/onix/date.rb +73 -109
  22. data/lib/onix/descriptive_detail.rb +90 -417
  23. data/lib/onix/discount_coded.rb +3 -16
  24. data/lib/onix/entity.rb +28 -62
  25. data/lib/onix/epub_usage_constraint.rb +7 -0
  26. data/lib/onix/epub_usage_limit.rb +6 -0
  27. data/lib/onix/extent.rb +39 -0
  28. data/lib/onix/helper.rb +25 -25
  29. data/lib/onix/identifier.rb +13 -54
  30. data/lib/onix/language.rb +8 -0
  31. data/lib/onix/market.rb +5 -0
  32. data/lib/onix/market_publishing_detail.rb +20 -0
  33. data/lib/onix/onix21.rb +76 -139
  34. data/lib/onix/onix_message.rb +87 -100
  35. data/lib/onix/price.rb +19 -39
  36. data/lib/onix/product.rb +141 -637
  37. data/lib/onix/product_form_feature.rb +7 -0
  38. data/lib/onix/product_part.rb +89 -0
  39. data/lib/onix/product_supplies_extractor.rb +275 -0
  40. data/lib/onix/product_supply.rb +17 -58
  41. data/lib/onix/publishing_detail.rb +16 -32
  42. data/lib/onix/related_material.rb +4 -3
  43. data/lib/onix/related_product.rb +9 -29
  44. data/lib/onix/related_work.rb +3 -17
  45. data/lib/onix/sales_outlet.rb +2 -10
  46. data/lib/onix/sales_restriction.rb +8 -21
  47. data/lib/onix/sales_rights.rb +1 -5
  48. data/lib/onix/sender.rb +12 -0
  49. data/lib/onix/serializer.rb +156 -0
  50. data/lib/onix/subject.rb +9 -30
  51. data/lib/onix/subset.rb +88 -78
  52. data/lib/onix/supply_detail.rb +42 -0
  53. data/lib/onix/supporting_resource.rb +29 -86
  54. data/lib/onix/tax.rb +9 -18
  55. data/lib/onix/territory.rb +23 -17
  56. data/lib/onix/title_detail.rb +22 -0
  57. data/lib/onix/title_element.rb +32 -0
  58. data/lib/onix/website.rb +3 -16
  59. metadata +53 -34
@@ -1,45 +1,41 @@
1
1
  module ONIX
2
2
  class TextContent < SubsetDSL
3
- element "TextType", :subset
3
+ element "TextType", :subset, :shortcut => :type
4
4
  element "ContentAudience", :subset
5
5
  element "Text", :text
6
6
  element "TextAuthor", :text
7
7
  element "SourceTitle", :text
8
8
 
9
- scope :description, lambda { human_code_match(:text_type, "Description")}
10
- scope :short_description, lambda { human_code_match(:text_type, "ShortDescriptionannotation")}
11
-
12
- # shortcuts
13
- def type
14
- @text_type
15
- end
9
+ scope :description, lambda { human_code_match(:text_type, "Description") }
10
+ scope :short_description, lambda { human_code_match(:text_type, "ShortDescriptionannotation") }
16
11
  end
17
12
 
18
13
  class CollateralDetail < SubsetDSL
19
14
  elements "TextContent", :subset
20
15
  elements "SupportingResource", :subset
21
16
 
17
+ # @!group High level
18
+
19
+ # product description string including HTML
20
+ # @return [String]
22
21
  def description
23
- desc_contents=@text_contents.description + @text_contents.short_description
22
+ desc_contents = @text_contents.description + @text_contents.short_description
24
23
  if desc_contents.length > 0
25
24
  desc_contents.first.text
26
- else
27
- nil
28
25
  end
29
26
  end
30
27
 
31
- # largest frontcover if multiple
32
28
  def frontcover_resource
33
- fc=@supporting_resources.front_cover
29
+ fc = @supporting_resources.front_cover
34
30
  if fc.length > 0
35
31
  if fc.length > 1
36
- best_found=fc.select{|c| c.versions.last and c.versions.last.image_width}.sort { |c1, c2| c2.versions.last.image_width <=> c1.versions.last.image_width }.first
32
+ best_found = fc.select { |c| c.versions.last and c.versions.last.image_width }.sort { |c1, c2| c2.versions.last.image_width <=> c1.versions.last.image_width }.first
37
33
  if best_found
38
34
  # we take larger one
39
35
  best_found.versions.last
40
36
  else
41
37
  # we try first that is not gif
42
- fc.select{|sr| not sr.versions.last.file_format=="Gif"}.first.versions.last
38
+ fc.select { |sr| not sr.versions.last.file_format == "Gif" }.first.versions.last
43
39
  end
44
40
  else
45
41
  fc.first.versions.last
@@ -47,18 +43,22 @@ module ONIX
47
43
  end
48
44
  end
49
45
 
46
+ # product larger front cover URL string
47
+ # @return [String]
50
48
  def frontcover_url
51
49
  if self.frontcover_resource
52
50
  self.frontcover_resource.links.first.strip
53
51
  end
54
52
  end
55
53
 
54
+ # product larger front cover last updated date
56
55
  def frontcover_last_updated
57
56
  if self.frontcover_resource
58
- self.frontcover_resource.last_updated
57
+ self.frontcover_resource.last_updated
59
58
  end
60
59
  end
61
60
 
61
+ # product larger front cover mimetype
62
62
  def frontcover_mimetype
63
63
  if self.frontcover_resource
64
64
  self.frontcover_resource.file_mimetype
@@ -66,29 +66,36 @@ module ONIX
66
66
  end
67
67
 
68
68
  def epub_sample_resource
69
- es=@supporting_resources.sample_content.select{|sr| sr.versions.last and sr.versions.last.file_format=="Epub"}.first
69
+ es = @supporting_resources.sample_content.select { |sr| sr.versions.last and sr.versions.last.file_format == "Epub" }.first
70
70
  if es
71
71
  es.versions.last
72
72
  end
73
73
  end
74
74
 
75
+ # Epub sample URL
76
+ # @return [String]
75
77
  def epub_sample_url
76
78
  if self.epub_sample_resource
77
79
  self.epub_sample_resource.links.first.strip
78
80
  end
79
81
  end
80
82
 
83
+ # Epub sample last updated
84
+ # @return [Date]
81
85
  def epub_sample_last_updated
82
86
  if self.epub_sample_resource
83
87
  self.epub_sample_resource.last_updated
84
88
  end
85
89
  end
86
90
 
91
+ # Epub sample mimetype
92
+ # @return [String]
87
93
  def epub_sample_mimetype
88
94
  if self.epub_sample_resource
89
95
  self.epub_sample_resource.file_mimetype
90
96
  end
91
97
  end
92
98
 
99
+ # @!endgroup
93
100
  end
94
101
  end
@@ -0,0 +1,38 @@
1
+ module ONIX
2
+ class Collection < SubsetDSL
3
+ element "CollectionType", :subset, :shortcut => :type
4
+ elements "CollectionIdentifier", :subset, :shortcut => :identifiers
5
+ elements "TitleDetail", :subset
6
+ elements "CollectionSequence", :subset, :shortcut => :sequences
7
+
8
+ scope :publisher, lambda { human_code_match(:collection_type, "PublisherCollection") }
9
+
10
+ # @!group High level
11
+
12
+ # collection title string
13
+ def title
14
+ if collection_title_element
15
+ collection_title_element.title
16
+ end
17
+ end
18
+
19
+ # collection subtitle string
20
+ def subtitle
21
+ if collection_title_element
22
+ collection_title_element.subtitle
23
+ end
24
+ end
25
+
26
+ def collection_title_element
27
+ distinctive_title = @title_details.distinctive_title.first
28
+ #select { |td| td.type.human=~/DistinctiveTitle/}.first
29
+ if distinctive_title
30
+ distinctive_title.title_elements.collection_level.first
31
+ #select { |te| te.level.human=~/CollectionLevel/ or te.level.human=~/Subcollection/ }.first
32
+ end
33
+ end
34
+
35
+ # @!endgroup
36
+
37
+ end
38
+ end
@@ -0,0 +1,7 @@
1
+ module ONIX
2
+ class CollectionSequence < SubsetDSL
3
+ element "CollectionSequenceType", :subset, :shortcut => :type
4
+ element "CollectionSequenceTypeName", :string, :shortcut => :type_name
5
+ element "CollectionSequenceNumber", :string, :shortcut => :number
6
+ end
7
+ end
@@ -4,72 +4,73 @@ require 'onix/website'
4
4
  module ONIX
5
5
  class Contributor < SubsetDSL
6
6
  element "SequenceNumber", :integer
7
- element "ContributorRole", :subset
8
- elements "NameIdentifier", :subset
9
-
7
+ element "ContributorRole", :subset, :shortcut => :role
8
+ elements "NameIdentifier", :subset, :shortcut => :identifiers
10
9
  element "PersonName", :text
11
10
  element "PersonNameInverted", :text
12
-
13
- element "NamesBeforeKey", :text
11
+ element "NamesBeforeKey", :text, :shortcut => :name_before_key
14
12
  element "KeyNames", :text
15
-
13
+ element "CorporateName", :text
14
+ element "CorporateNameInverted", :text
16
15
  element "BiographicalNote", :text
17
16
  elements "Website", :subset
18
- element "ContributorPlace", :subset
19
-
20
- def role
21
- @contributor_role
22
- end
23
-
24
- def identifiers
25
- @name_identifiers
26
- end
27
-
28
- def place
29
- @contributor_place
30
- end
31
-
32
- def name_before_key
33
- @names_before_key
34
- end
17
+ element "ContributorPlace", :subset, :shortcut => :place
18
+ elements "ContributorDate", :subset, :shortcut => :dates
35
19
 
36
- # :category: High level
20
+ # @!group High level
37
21
  # flatten person name (firstname lastname)
22
+ # @return [String]
38
23
  def name
39
- if @person_name
40
- @person_name
41
- else
42
- if @key_names
43
- if @names_before_key
44
- "#{@names_before_key} #{@key_names}"
45
- else
46
- @key_names
47
- end
24
+ return @person_name if @person_name
25
+
26
+ if @key_names
27
+ if @names_before_key
28
+ return "#{@names_before_key} #{@key_names}"
29
+ else
30
+ return @key_names
48
31
  end
49
32
  end
33
+
34
+ @corporate_name
50
35
  end
51
36
 
52
- # :category: High level
53
37
  # inverted flatten person name
38
+ # @return [String]
54
39
  def inverted_name
55
- @person_name_inverted
40
+ @person_name_inverted || @corporate_name_inverted
56
41
  end
57
42
 
58
- # :category: High level
59
43
  # biography string with HTML
44
+ # @return [String]
60
45
  def biography
61
46
  @biographical_note
62
47
  end
63
48
 
64
- # :category: High level
65
49
  # raw biography string without HTML
50
+ # @return [String]
66
51
  def raw_biography
67
52
  if self.biography
68
53
  Helper.strip_html(self.biography).gsub(/\s+/, " ")
69
- else
70
- nil
71
54
  end
72
55
  end
56
+
57
+ # date of birth
58
+ # @return [Time]
59
+ def birth_date
60
+ if contributor_date = @contributor_dates.find { |d| d.role.human == "DateOfBirth" }
61
+ contributor_date.date.to_time
62
+ end
63
+ end
64
+
65
+ # date of death
66
+ # @return [Time]
67
+ def death_date
68
+ if contributor_date = @contributor_dates.find { |d| d.role.human == "DateOfDeath" }
69
+ contributor_date.date.to_time
70
+ end
71
+ end
72
+
73
+ # @!endgroup
73
74
  end
74
75
 
75
76
  class ContributorPlace < SubsetDSL
@@ -1,18 +1,17 @@
1
1
  module ONIX
2
-
3
2
  module DateHelper
4
3
  attr_accessor :date_format, :date
5
4
 
6
5
  def parse_date(n)
7
- @date_format=DateFormat.from_code("00")
8
- date_txt=nil
9
- @date=nil
6
+ @date_format = DateFormat.from_code("00")
7
+ date_txt = nil
8
+ @date = nil
10
9
  n.elements.each do |t|
11
10
  case t
12
- when tag_match("DateFormat")
13
- @date_format=DateFormat.parse(t)
14
- when tag_match("Date")
15
- date_txt=t.text
11
+ when tag_match("DateFormat")
12
+ @date_format = DateFormat.parse(t)
13
+ when tag_match("Date")
14
+ date_txt = t.text
16
15
  end
17
16
 
18
17
  if t["dateformat"]
@@ -20,29 +19,29 @@ module ONIX
20
19
  end
21
20
  end
22
21
 
23
- code_format=format_from_code(@date_format.code)
24
- text_format=format_from_string(date_txt)
22
+ code_format = format_from_code(@date_format.code)
23
+ text_format = format_from_string(date_txt)
25
24
 
26
- format=code_format
25
+ format = code_format
27
26
 
28
- if code_format!=text_format
29
- # puts "EEE date #{n.text} (#{text_format}) do not match code #{@format.code} (#{code_format})"
30
- format=text_format
27
+ if code_format != text_format
28
+ # puts "EEE date #{n.text} (#{text_format}) do not match code #{@format.code} (#{code_format})"
29
+ format = text_format
31
30
  end
32
31
 
33
32
  begin
34
33
  if format
35
34
  case @date_format.code
36
- when "00"
37
- @date=Date.strptime(date_txt, format)
38
- when "01"
39
- @date=Date.strptime(date_txt, format)
40
- when "05"
41
- @date=Date.strptime(date_txt, format)
42
- when "14"
43
- @date=Time.strptime(date_txt, format)
44
- else
45
- @date=nil
35
+ when "00"
36
+ @date = Date.strptime(date_txt, format)
37
+ when "01"
38
+ @date = Date.strptime(date_txt, format)
39
+ when "05"
40
+ @date = Date.strptime(date_txt, format)
41
+ when "14"
42
+ @date = Time.strptime(date_txt, format)
43
+ else
44
+ @date = nil
46
45
  end
47
46
  end
48
47
  rescue
@@ -52,33 +51,33 @@ module ONIX
52
51
 
53
52
  def format_from_code(code)
54
53
  case code
55
- when "00"
56
- "%Y%m%d"
57
- when "01"
58
- "%Y%m"
59
- when "05"
60
- "%Y"
61
- when "14"
62
- "%Y%m%dT%H%M%S%z"
63
- else
64
- nil
54
+ when "00"
55
+ "%Y%m%d"
56
+ when "01"
57
+ "%Y%m"
58
+ when "05"
59
+ "%Y"
60
+ when "14"
61
+ "%Y%m%dT%H%M%S%z"
62
+ else
63
+ nil
65
64
  end
66
65
  end
67
66
 
68
67
  def format_from_string(str)
69
68
  case str
70
- when /^\d{4}\d{2}\d{2}T\d{2}\d{2}\d{2}/
71
- "%Y%m%dT%H%M%S%z"
72
- when /^\d{4}\-\d{2}\-\d{2}$/
73
- "%Y-%m-%d"
74
- when /^\d{4}\d{2}\d{2}$/
75
- "%Y%m%d"
76
- when /^\d{4}\d{2}$/
77
- "%Y%m"
78
- when /^\d{4}$/
79
- "%Y"
80
- else
81
- nil
69
+ when /^\d{4}\d{2}\d{2}T\d{2}\d{2}\d{2}/
70
+ "%Y%m%dT%H%M%S%z"
71
+ when /^\d{4}\-\d{2}\-\d{2}$/
72
+ "%Y-%m-%d"
73
+ when /^\d{4}\d{2}\d{2}$/
74
+ "%Y%m%d"
75
+ when /^\d{4}\d{2}$/
76
+ "%Y%m"
77
+ when /^\d{4}$/
78
+ "%Y"
79
+ else
80
+ nil
82
81
  end
83
82
  end
84
83
 
@@ -87,17 +86,8 @@ module ONIX
87
86
  end
88
87
  end
89
88
 
90
- class MarketDate < SubsetDSL
89
+ class BaseDate < SubsetDSL
91
90
  include DateHelper
92
- element "Date", :ignore
93
- element "DateFormat", :ignore
94
- element "MarketDateRole", :subset
95
-
96
- scope :availability, lambda { human_code_match(:market_date_role, ["PublicationDate","EmbargoDate"])}
97
-
98
- def role
99
- @market_date_role
100
- end
101
91
 
102
92
  def parse(n)
103
93
  super
@@ -105,79 +95,53 @@ module ONIX
105
95
  end
106
96
  end
107
97
 
108
- class PriceDate < SubsetDSL
109
- include DateHelper
98
+ class MarketDate < BaseDate
110
99
  element "Date", :ignore
111
100
  element "DateFormat", :ignore
112
- element "PriceDateRole", :subset
113
-
114
- scope :from_date, lambda { human_code_match(:price_date_role, "FromDate")}
115
- scope :until_date, lambda { human_code_match(:price_date_role, "UntilDate")}
101
+ element "MarketDateRole", :subset, :shortcut => :role
116
102
 
117
- def role
118
- @price_date_role
119
- end
120
-
121
- def parse(n)
122
- super
123
- parse_date(n)
124
- end
103
+ scope :availability, lambda { human_code_match(:market_date_role, ["PublicationDate", "EmbargoDate"]) }
125
104
  end
126
105
 
127
- class SupplyDate < SubsetDSL
128
- include DateHelper
106
+ class PriceDate < BaseDate
129
107
  element "Date", :ignore
130
108
  element "DateFormat", :ignore
131
- element "SupplyDateRole", :subset
132
-
133
- scope :availability, lambda { human_code_match(:supply_date_role, ["ExpectedAvailabilityDate","EmbargoDate"])}
109
+ element "PriceDateRole", :subset, :shortcut => :role
134
110
 
135
- def role
136
- @supply_date_role
137
- end
138
-
139
- def parse(n)
140
- super
141
- parse_date(n)
142
- end
111
+ scope :from_date, lambda { human_code_match(:price_date_role, "FromDate") }
112
+ scope :until_date, lambda { human_code_match(:price_date_role, "UntilDate") }
143
113
  end
144
114
 
145
- class PublishingDate < SubsetDSL
146
- include DateHelper
115
+ class SupplyDate < BaseDate
147
116
  element "Date", :ignore
148
117
  element "DateFormat", :ignore
149
- element "PublishingDateRole", :subset
118
+ element "SupplyDateRole", :subset, :shortcut => :role
150
119
 
151
- scope :publication, lambda { human_code_match(:publishing_date_role, ["PublicationDate","PublicationDateOfPrintCounterpart"])}
152
- scope :embargo, lambda { human_code_match(:publishing_date_role, "EmbargoDate")}
153
- scope :preorder_embargo, lambda { human_code_match(:publishing_date_role, "PreorderEmbargoDate")}
154
- scope :public_announcement, lambda { human_code_match(:publishing_date_role, "PublicAnnouncementDate")}
120
+ scope :availability, lambda { human_code_match(:supply_date_role, ["ExpectedAvailabilityDate", "EmbargoDate"]) }
121
+ end
155
122
 
156
- def role
157
- @publishing_date_role
158
- end
123
+ class PublishingDate < BaseDate
124
+ element "Date", :ignore
125
+ element "DateFormat", :ignore
126
+ element "PublishingDateRole", :subset, :shortcut => :role
159
127
 
160
- def parse(n)
161
- super
162
- parse_date(n)
163
- end
128
+ scope :publication, lambda { human_code_match(:publishing_date_role, ["PublicationDate", "PublicationDateOfPrintCounterpart"]) }
129
+ scope :embargo, lambda { human_code_match(:publishing_date_role, "EmbargoDate") }
130
+ scope :preorder_embargo, lambda { human_code_match(:publishing_date_role, "PreorderEmbargoDate") }
131
+ scope :public_announcement, lambda { human_code_match(:publishing_date_role, "PublicAnnouncementDate") }
164
132
  end
165
133
 
166
- class ContentDate < SubsetDSL
167
- include DateHelper
134
+ class ContentDate < BaseDate
168
135
  element "Date", :ignore
169
136
  element "DateFormat", :ignore
170
- element "ContentDateRole", :subset
171
-
172
- scope :last_updated, lambda { human_code_match(:content_date_role, "LastUpdated")}
137
+ element "ContentDateRole", :subset, :shortcut => :role
173
138
 
174
- def role
175
- @content_date_role
176
- end
139
+ scope :last_updated, lambda { human_code_match(:content_date_role, "LastUpdated") }
140
+ end
177
141
 
178
- def parse(n)
179
- super
180
- parse_date(n)
181
- end
142
+ class ContributorDate < BaseDate
143
+ element "Date", :ignore
144
+ element "DateFormat", :ignore
145
+ element "ContributorDateRole", :subset, :shortcut => :role
182
146
  end
183
147
  end