im_onix 1.0.2 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
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