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,438 +1,74 @@
1
- require 'onix/identifier'
1
+ require 'onix/collection'
2
+ require 'onix/collection_sequence'
3
+ require 'onix/epub_usage_constraint'
4
+ require 'onix/epub_usage_limit'
5
+ require 'onix/extent'
6
+ require 'onix/language'
7
+ require 'onix/product_form_feature'
8
+ require 'onix/product_part'
9
+ require 'onix/title_detail'
10
+ require 'onix/contributor'
11
+ require 'onix/subject'
2
12
 
3
13
  module ONIX
4
- class TitleElement < SubsetDSL
5
- element "TitleElementLevel", :subset
6
- element "TitleText", :text
7
- element "TitlePrefix", :text
8
- element "TitleWithoutPrefix", :text
9
- element "Subtitle", :text
10
- element "PartNumber", :integer
11
- element "SequenceNumber", :integer
12
-
13
- scope :product_level, lambda { human_code_match(:title_element_level, /Product/)}
14
- scope :collection_level, lambda { human_code_match(:title_element_level, /collection/i)}
15
-
16
- # shortcuts
17
- def level
18
- @title_element_level
19
- end
20
-
21
- # :category: High level
22
- # flatten title string
23
- def title
24
- if @title_text
25
- @title_text
26
- else
27
- if @title_without_prefix
28
- if @title_prefix
29
- "#{@title_prefix} #{@title_without_prefix}"
30
- else
31
- @title_without_prefix
32
- end
33
- end
34
- end
35
- end
36
- end
37
-
38
- class TitleDetail < SubsetDSL
39
- element "TitleType", :subset
40
- elements "TitleElement", :subset
41
-
42
- scope :distinctive_title, lambda { human_code_match(:title_type, /DistinctiveTitle/)}
43
-
44
- def type
45
- @title_type
46
- end
47
-
48
- # :category: High level
49
- # flatten title string
50
- def title
51
- title_element = @title_elements.product_level #select { |te| te.level.human=~/Product/ }
52
- if title_element.size > 0
53
- title_element.first.title
54
- else
55
- nil
56
- end
57
- end
58
- end
59
-
60
- class CollectionSequence < SubsetDSL
61
- element "CollectionSequenceType", :subset
62
- element "CollectionSequenceTypeName", :string
63
- element "CollectionSequenceNumber", :string
64
-
65
- def type
66
- @collection_sequence_number
67
- end
68
-
69
- def number
70
- @collection_sequence_number
71
- end
72
-
73
- def type_name
74
- @collection_sequence_type_name
75
- end
76
- end
77
-
78
- class Collection < SubsetDSL
79
- element "CollectionType", :subset
80
- elements "CollectionIdentifier", :subset
81
- elements "TitleDetail", :subset
82
- elements "CollectionSequence", :subset
83
-
84
- scope :publisher, lambda { human_code_match(:collection_type, "PublisherCollection")}
85
-
86
- # shortcuts
87
- def type
88
- @collection_type
89
- end
90
-
91
- def identifiers
92
- @collection_identifiers
93
- end
94
-
95
- def sequences
96
- @collection_sequences
97
- end
98
-
99
- # :category: High level
100
- # collection title string
101
- def title
102
- if collection_title_element
103
- collection_title_element.title
104
- end
105
- end
106
-
107
- # :category: High level
108
- # collection subtitle string
109
- def subtitle
110
- if collection_title_element
111
- collection_title_element.subtitle
112
- end
113
- end
114
-
115
- def collection_title_element
116
- distinctive_title=@title_details.distinctive_title.first
117
- #select { |td| td.type.human=~/DistinctiveTitle/}.first
118
- if distinctive_title
119
- distinctive_title.title_elements.collection_level.first
120
- #select { |te| te.level.human=~/CollectionLevel/ or te.level.human=~/Subcollection/ }.first
121
- end
122
- end
123
-
124
- end
125
-
126
- # product part use full Product to provide file protection and file size
127
- class ProductPart < SubsetDSL
128
- include EanMethods
129
- include ProprietaryIdMethods
130
-
131
- elements "ProductIdentifier", :subset
132
- element "ProductForm", :subset
133
- element "ProductFormDescription", :text
134
- elements "ProductFormDetail", :subset
135
- elements "ProductContentType", :subset
136
- element "NumberOfCopies", :integer
137
-
138
- # shortcuts
139
- def identifiers
140
- @product_identifiers
141
- end
142
-
143
- def form
144
- @product_form
145
- end
146
-
147
- def form_details
148
- @product_form_details
149
- end
150
-
151
- def content_types
152
- @product_content_types
153
- end
154
-
155
- # full Product if referenced in ONIXMessage
156
- def product
157
- @product
158
- end
159
-
160
- def product=v
161
- @product=v
162
- end
163
-
164
- # this ProductPart is part of Product
165
- def part_of
166
- @part_of
167
- end
168
-
169
- def part_of=v
170
- @part_of=v
171
- end
172
-
173
- # :category: High level
174
- # digital file format string (Epub,Pdf,AmazonKindle)
175
- def file_format
176
- self.file_formats.first.human if self.file_formats.first
177
- end
178
-
179
- def file_mimetype
180
- if self.file_formats.first
181
- self.file_formats.first.mimetype
182
- end
183
- end
184
-
185
- def file_formats
186
- @product_form_details.select { |fd| fd.code =~ /^E1.*/ }
187
- end
188
-
189
- def reflowable?
190
- return true if @product_form_details.select { |fd| fd.code == "E200" }.length > 0
191
- return false if @product_form_details.select { |fd| fd.code == "E201" }.length > 0
192
- end
193
-
194
- # :category: High level
195
- # part file description string
196
- def file_description
197
- @product_form_description
198
- end
199
-
200
- # :category: High level
201
- # raw part file description string without HTML
202
- def raw_file_description
203
- if @product_form_description
204
- Helper.strip_html(@product_form_description).gsub(/\s+/, " ").strip
205
- else
206
- nil
207
- end
208
- end
209
-
210
- # :category: High level
211
- # Protection type string (None, Watermarking, DRM, AdobeDRM)
212
- def protection_type
213
- if product
214
- product.protection_type
215
- else
216
- if part_of
217
- part_of.protection_type
218
- else
219
- nil
220
- end
221
- end
222
- end
223
-
224
- # :category: High level
225
- # List of protections type string (None, Watermarking, DRM, AdobeDRM)
226
- def protections
227
- if product
228
- product.protections
229
- else
230
- if part_of
231
- part_of.protections
232
- else
233
- nil
234
- end
235
- end
236
- end
237
-
238
- # :category: High level
239
- # digital file filesize in bytes
240
- def filesize
241
- if product
242
- product.filesize
243
- else
244
- nil
245
- end
246
- end
247
- end
248
-
249
- class Extent < SubsetDSL
250
- element "ExtentType", :subset
251
- element "ExtentUnit", :subset
252
- element "ExtentValue", :text
253
-
254
- scope :filesize, lambda { human_code_match(:extent_type, /Filesize/)}
255
- scope :page, lambda { human_code_match(:extent_type, /Page/)}
256
-
257
- # shortcuts
258
- def type
259
- @extent_type
260
- end
261
-
262
- def unit
263
- @extent_unit
264
- end
265
-
266
- def value
267
- @extent_value
268
- end
269
-
270
- def bytes
271
- case @extent_unit.human
272
- when "Bytes"
273
- @extent_value.to_i
274
- when "Kbytes"
275
- (@extent_value.to_f*1024).to_i
276
- when "Mbytes"
277
- (@extent_value.to_f*1024*1024).to_i
278
- else
279
- nil
280
- end
281
- end
282
-
283
- def pages
284
- if @extent_unit.human=="Pages"
285
- @extent_value.to_i
286
- else
287
- nil
288
- end
289
- end
290
- end
291
-
292
- class EpubUsageLimit < SubsetDSL
293
- element "EpubUsageUnit", :subset
294
- element "Quantity", :integer
295
-
296
- def unit
297
- @epub_usage_unit
298
- end
299
- end
300
-
301
- class EpubUsageConstraint < SubsetDSL
302
- element "EpubUsageType", :subset
303
- element "EpubUsageStatus", :subset
304
- elements "EpubUsageLimit", :subset
305
-
306
- # shortcuts
307
- def type
308
- @epub_usage_type
309
- end
310
-
311
- def status
312
- @epub_usage_status
313
- end
314
-
315
- def limits
316
- @epub_usage_limits
317
- end
318
- end
319
-
320
- class Language < SubsetDSL
321
- element "LanguageRole", :subset
322
- element "LanguageCode", :subset
323
-
324
- scope :of_text, lambda{human_code_match(:language_role, "LanguageOfText")}
325
-
326
- # shortcuts
327
- def role
328
- @language_role
329
- end
330
-
331
- def code
332
- @language_code
333
- end
334
- end
335
-
336
- class ProductFormFeature < SubsetDSL
337
- element "ProductFormFeatureType", :subset
338
- element "ProductFormFeatureValue", :text
339
- elements "ProductFormFeatureDescription", :text
340
-
341
- # shortcuts
342
- def type
343
- @product_form_feature_type
344
- end
345
-
346
- def value
347
- @product_form_feature_value
348
- end
349
-
350
- def descriptions
351
- @product_form_feature_descriptions
352
- end
353
- end
354
-
355
14
  class DescriptiveDetail < SubsetDSL
356
- element "ProductComposition", :subset
357
- element "ProductForm", :subset
358
- elements "ProductFormDetail", :subset
359
- elements "ProductFormFeature", :subset
360
- element "ProductFormDescription", :text
361
- element "PrimaryContentType", :subset, {:klass=>"ProductContentType"}
362
- elements "ProductContentType", :subset
15
+ element "ProductComposition", :subset, :shortcut => :composition
16
+ element "ProductForm", :subset, :shortcut => :form
17
+ elements "ProductFormDetail", :subset, :shortcut => :form_details
18
+ elements "ProductFormFeature", :subset, :shortcut => :form_features
19
+ element "ProductFormDescription", :text, :shortcut => :file_description
20
+ element "PrimaryContentType", :subset, {:klass => "ProductContentType"}
21
+ elements "ProductContentType", :subset, :shortcut => :content_types
363
22
  elements "EpubTechnicalProtection", :subset
364
23
  elements "EpubUsageConstraint", :subset
365
- elements "ProductPart", :subset
366
-
24
+ elements "ProductPart", :subset, :shortcut => :parts
367
25
  elements "Collection", :subset
368
26
  element "NoCollection", :ignore
369
-
370
27
  elements "TitleDetail", :subset
371
-
372
28
  elements "Contributor", :subset
373
-
374
29
  element "EditionType", :subset
375
30
  element "EditionNumber", :integer
376
31
  element "NoEdition", :ignore
377
-
378
32
  elements "Language", :subset
379
-
380
33
  elements "Extent", :subset
381
-
382
34
  elements "Subject", :subset
383
-
384
35
  elements "AudienceCode", :subset
385
36
 
386
- # shortcuts
387
- def form
388
- @product_form
389
- end
37
+ # @!group Shortcuts
390
38
 
391
- def form_details
392
- @product_form_details
39
+ def pages_extent
40
+ @extents.page.first
393
41
  end
394
42
 
395
- def form_features
396
- @product_form_features
43
+ def product_title_element
44
+ @title_details.distinctive_title.first.title_elements.product_level.first if @title_details.distinctive_title.first
397
45
  end
398
46
 
399
- def composition
400
- @product_composition
47
+ def file_formats
48
+ @product_form_details.select { |fd| fd.code =~ /^E1.*/ }
401
49
  end
402
50
 
403
- def parts
404
- @product_parts
405
- end
51
+ # @!endgroup
406
52
 
407
- def content_types
408
- @product_content_types
409
- end
53
+ # @!group High level
410
54
 
411
- # :category: High level
412
55
  # product title string
56
+ # @return [String]
413
57
  def title
414
58
  product_title_element.title if product_title_element
415
59
  end
416
60
 
417
- # :category: High level
418
61
  # product subtitle string
62
+ # @return [String]
419
63
  def subtitle
420
64
  product_title_element.subtitle if product_title_element
421
65
  end
422
66
 
423
- def product_title_element
424
- @title_details.distinctive_title.first.title_elements.product_level.first if @title_details.distinctive_title.first
425
- end
426
-
427
- def pages_extent
428
- @extents.page.first
429
- end
430
-
67
+ # page count
68
+ # @return [Integer]
431
69
  def pages
432
70
  if pages_extent
433
71
  pages_extent.pages
434
- else
435
- nil
436
72
  end
437
73
  end
438
74
 
@@ -440,6 +76,8 @@ module ONIX
440
76
  @extents.filesize.first
441
77
  end
442
78
 
79
+ # file size in bytes
80
+ # @return [Integer]
443
81
  def filesize
444
82
  if filesize_extent
445
83
  filesize_extent.bytes
@@ -448,18 +86,30 @@ module ONIX
448
86
  end
449
87
  end
450
88
 
89
+ # is digital ?
90
+ # @return [Boolean]
451
91
  def digital?
452
- if @product_form and @product_form.human=~/Digital/
92
+ if @product_form and @product_form.human =~ /Digital/
453
93
  true
454
94
  else
455
95
  false
456
96
  end
457
97
  end
458
98
 
99
+ # digital offer has DRM ?
100
+ # @return [Boolean]
101
+ def drmized?
102
+ @protections.any? { |p| p =~ /Drm/ }
103
+ end
104
+
105
+ # is digital offer streaming ?
106
+ # @return [Boolean]
459
107
  def streaming?
460
- @product_form.code=="EC"
108
+ @product_form.code == "EC"
461
109
  end
462
110
 
111
+ # is digital offer audio ?
112
+ # @return [Boolean]
463
113
  def audio?
464
114
  not audio_formats.empty?
465
115
  end
@@ -472,33 +122,35 @@ module ONIX
472
122
  @product_form_details.select { |fd| fd.code =~ /^A.*/ }
473
123
  end
474
124
 
125
+ # is digital offer a bundle ?
126
+ # @return [Boolean]
475
127
  def bundle?
476
- @product_composition.human=="MultipleitemRetailProduct"
128
+ @product_composition.human == "MultipleitemRetailProduct"
477
129
  end
478
130
 
131
+ # digital file format string (Epub,Pdf,AmazonKindle)
132
+ # @return [String]
479
133
  def file_format
480
- self.file_formats.first.human if self.file_formats.first
134
+ file_formats.first.human if file_formats.first
481
135
  end
482
136
 
137
+ # digital file format mimetype
138
+ # @return [String]
483
139
  def file_mimetype
484
- if self.file_formats.first
485
- self.file_formats.first.mimetype
140
+ if file_formats.first
141
+ file_formats.first.mimetype
486
142
  end
487
143
  end
488
144
 
489
- def file_formats
490
- @product_form_details.select { |fd| fd.code =~ /^E1.*/ }
491
- end
492
-
145
+ # is digital file reflowable ?
146
+ # @return [Boolean]
493
147
  def reflowable?
494
148
  return true if @product_form_details.select { |fd| fd.code == "E200" }.length > 0
495
149
  return false if @product_form_details.select { |fd| fd.code == "E201" }.length > 0
496
150
  end
497
151
 
498
- def file_description
499
- @product_form_description
500
- end
501
-
152
+ # protection type string
153
+ # @return [String]
502
154
  def protection_type
503
155
  if @epub_technical_protections.length > 0
504
156
  if @epub_technical_protections.length == 1
@@ -509,18 +161,18 @@ module ONIX
509
161
  end
510
162
  end
511
163
 
164
+ # protections string array
165
+ # @return [Array<String>]
512
166
  def protections
513
167
  return nil if @epub_technical_protections.length == 0
514
-
515
168
  @epub_technical_protections.map(&:human)
516
169
  end
517
170
 
171
+ # language of text
518
172
  def language_of_text
519
- l=@languages.of_text.first
173
+ l = @languages.of_text.first
520
174
  if l
521
175
  l.code
522
- else
523
- nil
524
176
  end
525
177
  end
526
178
 
@@ -528,25 +180,46 @@ module ONIX
528
180
  @collections.publisher.first
529
181
  end
530
182
 
183
+ # publisher collection title
184
+ # @return [String]
531
185
  def publisher_collection_title
532
186
  if self.publisher_collection
533
187
  self.publisher_collection.title
534
188
  end
535
189
  end
536
190
 
191
+ # BISAC categories
192
+ # @return [Array<Subject>]
537
193
  def bisac_categories
538
194
  @subjects.bisac
539
195
  end
540
196
 
197
+ # BISAC categories identifiers string array (eg: FIC000000)
198
+ # @return [Array<String>]
199
+ def bisac_categories_codes
200
+ self.bisac_categories.map { |c| c.code }.uniq
201
+ end
202
+
203
+ # BISAC categories
204
+ # @return [Array<Subject>]
541
205
  def clil_categories
542
206
  @subjects.clil
543
207
  end
544
208
 
209
+ # CLIL categories identifier string array
210
+ # @return [Array<String>]
211
+ def clil_categories_codes
212
+ self.clil_categories.map { |c| c.code }.uniq
213
+ end
214
+
215
+ # keywords string array
545
216
  def keywords
546
- kws=@subjects.keyword.map { |kw| kw.heading_text }.compact
547
- kws=kws.flat_map { |kw| kw.split(/;|,|\n/) }.map { |kw| kw.strip }
548
- kws.reject!{|k| k==""}
217
+ kws = @subjects.keyword.map { |kw| kw.heading_text }.compact
218
+ kws = kws.flat_map { |kw| kw.split(/;|,|\n/) }.map { |kw| kw.strip }
219
+ kws.reject! { |k| k == "" }
549
220
  kws
550
221
  end
222
+
223
+ # @!endgroup
551
224
  end
552
225
  end