rubysl-rss 1.0.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.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.travis.yml +8 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE +25 -0
  6. data/README.md +29 -0
  7. data/Rakefile +1 -0
  8. data/lib/rss.rb +1 -0
  9. data/lib/rss/0.9.rb +428 -0
  10. data/lib/rss/1.0.rb +452 -0
  11. data/lib/rss/2.0.rb +111 -0
  12. data/lib/rss/atom.rb +749 -0
  13. data/lib/rss/content.rb +31 -0
  14. data/lib/rss/content/1.0.rb +10 -0
  15. data/lib/rss/content/2.0.rb +12 -0
  16. data/lib/rss/converter.rb +162 -0
  17. data/lib/rss/dublincore.rb +161 -0
  18. data/lib/rss/dublincore/1.0.rb +13 -0
  19. data/lib/rss/dublincore/2.0.rb +13 -0
  20. data/lib/rss/dublincore/atom.rb +17 -0
  21. data/lib/rss/image.rb +193 -0
  22. data/lib/rss/itunes.rb +410 -0
  23. data/lib/rss/maker.rb +44 -0
  24. data/lib/rss/maker/0.9.rb +467 -0
  25. data/lib/rss/maker/1.0.rb +434 -0
  26. data/lib/rss/maker/2.0.rb +223 -0
  27. data/lib/rss/maker/atom.rb +172 -0
  28. data/lib/rss/maker/base.rb +868 -0
  29. data/lib/rss/maker/content.rb +21 -0
  30. data/lib/rss/maker/dublincore.rb +124 -0
  31. data/lib/rss/maker/entry.rb +163 -0
  32. data/lib/rss/maker/feed.rb +429 -0
  33. data/lib/rss/maker/image.rb +111 -0
  34. data/lib/rss/maker/itunes.rb +242 -0
  35. data/lib/rss/maker/slash.rb +33 -0
  36. data/lib/rss/maker/syndication.rb +18 -0
  37. data/lib/rss/maker/taxonomy.rb +118 -0
  38. data/lib/rss/maker/trackback.rb +61 -0
  39. data/lib/rss/parser.rb +541 -0
  40. data/lib/rss/rexmlparser.rb +54 -0
  41. data/lib/rss/rss.rb +1312 -0
  42. data/lib/rss/slash.rb +49 -0
  43. data/lib/rss/syndication.rb +67 -0
  44. data/lib/rss/taxonomy.rb +145 -0
  45. data/lib/rss/trackback.rb +288 -0
  46. data/lib/rss/utils.rb +111 -0
  47. data/lib/rss/xml-stylesheet.rb +105 -0
  48. data/lib/rss/xml.rb +71 -0
  49. data/lib/rss/xmlparser.rb +93 -0
  50. data/lib/rss/xmlscanner.rb +121 -0
  51. data/lib/rubysl/rss.rb +2 -0
  52. data/lib/rubysl/rss/rss.rb +19 -0
  53. data/lib/rubysl/rss/version.rb +5 -0
  54. data/rubysl-rss.gemspec +23 -0
  55. metadata +153 -0
@@ -0,0 +1,410 @@
1
+ require 'rss/2.0'
2
+
3
+ module RSS
4
+ ITUNES_PREFIX = 'itunes'
5
+ ITUNES_URI = 'http://www.itunes.com/dtds/podcast-1.0.dtd'
6
+
7
+ Rss.install_ns(ITUNES_PREFIX, ITUNES_URI)
8
+
9
+ module ITunesModelUtils
10
+ include Utils
11
+
12
+ def def_class_accessor(klass, name, type, *args)
13
+ normalized_name = name.gsub(/-/, "_")
14
+ full_name = "#{ITUNES_PREFIX}_#{normalized_name}"
15
+ klass_name = "ITunes#{Utils.to_class_name(normalized_name)}"
16
+
17
+ case type
18
+ when :element, :attribute
19
+ klass::ELEMENTS << full_name
20
+ def_element_class_accessor(klass, name, full_name, klass_name, *args)
21
+ when :elements
22
+ klass::ELEMENTS << full_name
23
+ def_elements_class_accessor(klass, name, full_name, klass_name, *args)
24
+ else
25
+ klass.install_must_call_validator(ITUNES_PREFIX, ITUNES_URI)
26
+ klass.install_text_element(normalized_name, ITUNES_URI, "?",
27
+ full_name, type, name)
28
+ end
29
+ end
30
+
31
+ def def_element_class_accessor(klass, name, full_name, klass_name,
32
+ recommended_attribute_name=nil)
33
+ klass.install_have_child_element(name, ITUNES_PREFIX, "?", full_name)
34
+ end
35
+
36
+ def def_elements_class_accessor(klass, name, full_name, klass_name,
37
+ plural_name, recommended_attribute_name=nil)
38
+ full_plural_name = "#{ITUNES_PREFIX}_#{plural_name}"
39
+ klass.install_have_children_element(name, ITUNES_PREFIX, "*",
40
+ full_name, full_plural_name)
41
+ end
42
+ end
43
+
44
+ module ITunesBaseModel
45
+ extend ITunesModelUtils
46
+
47
+ ELEMENTS = []
48
+
49
+ ELEMENT_INFOS = [["author"],
50
+ ["block", :yes_other],
51
+ ["explicit", :yes_clean_other],
52
+ ["keywords", :csv],
53
+ ["subtitle"],
54
+ ["summary"]]
55
+ end
56
+
57
+ module ITunesChannelModel
58
+ extend BaseModel
59
+ extend ITunesModelUtils
60
+ include ITunesBaseModel
61
+
62
+ ELEMENTS = []
63
+
64
+ class << self
65
+ def append_features(klass)
66
+ super
67
+
68
+ return if klass.instance_of?(Module)
69
+ ELEMENT_INFOS.each do |name, type, *additional_infos|
70
+ def_class_accessor(klass, name, type, *additional_infos)
71
+ end
72
+ end
73
+ end
74
+
75
+ ELEMENT_INFOS = [
76
+ ["category", :elements, "categories", "text"],
77
+ ["image", :attribute, "href"],
78
+ ["owner", :element],
79
+ ["new-feed-url"],
80
+ ] + ITunesBaseModel::ELEMENT_INFOS
81
+
82
+ class ITunesCategory < Element
83
+ include RSS09
84
+
85
+ @tag_name = "category"
86
+
87
+ class << self
88
+ def required_prefix
89
+ ITUNES_PREFIX
90
+ end
91
+
92
+ def required_uri
93
+ ITUNES_URI
94
+ end
95
+ end
96
+
97
+ [
98
+ ["text", "", true]
99
+ ].each do |name, uri, required|
100
+ install_get_attribute(name, uri, required)
101
+ end
102
+
103
+ ITunesCategory = self
104
+ install_have_children_element("category", ITUNES_URI, "*",
105
+ "#{ITUNES_PREFIX}_category",
106
+ "#{ITUNES_PREFIX}_categories")
107
+
108
+ def initialize(*args)
109
+ if Utils.element_initialize_arguments?(args)
110
+ super
111
+ else
112
+ super()
113
+ self.text = args[0]
114
+ end
115
+ end
116
+
117
+ def full_name
118
+ tag_name_with_prefix(ITUNES_PREFIX)
119
+ end
120
+
121
+ private
122
+ def maker_target(categories)
123
+ if text or !itunes_categories.empty?
124
+ categories.new_category
125
+ else
126
+ nil
127
+ end
128
+ end
129
+
130
+ def setup_maker_attributes(category)
131
+ category.text = text if text
132
+ end
133
+
134
+ def setup_maker_elements(category)
135
+ super(category)
136
+ itunes_categories.each do |sub_category|
137
+ sub_category.setup_maker(category)
138
+ end
139
+ end
140
+ end
141
+
142
+ class ITunesImage < Element
143
+ include RSS09
144
+
145
+ @tag_name = "image"
146
+
147
+ class << self
148
+ def required_prefix
149
+ ITUNES_PREFIX
150
+ end
151
+
152
+ def required_uri
153
+ ITUNES_URI
154
+ end
155
+ end
156
+
157
+ [
158
+ ["href", "", true]
159
+ ].each do |name, uri, required|
160
+ install_get_attribute(name, uri, required)
161
+ end
162
+
163
+ def initialize(*args)
164
+ if Utils.element_initialize_arguments?(args)
165
+ super
166
+ else
167
+ super()
168
+ self.href = args[0]
169
+ end
170
+ end
171
+
172
+ def full_name
173
+ tag_name_with_prefix(ITUNES_PREFIX)
174
+ end
175
+
176
+ private
177
+ def maker_target(target)
178
+ if href
179
+ target.itunes_image {|image| image}
180
+ else
181
+ nil
182
+ end
183
+ end
184
+
185
+ def setup_maker_attributes(image)
186
+ image.href = href
187
+ end
188
+ end
189
+
190
+ class ITunesOwner < Element
191
+ include RSS09
192
+
193
+ @tag_name = "owner"
194
+
195
+ class << self
196
+ def required_prefix
197
+ ITUNES_PREFIX
198
+ end
199
+
200
+ def required_uri
201
+ ITUNES_URI
202
+ end
203
+ end
204
+
205
+ install_must_call_validator(ITUNES_PREFIX, ITUNES_URI)
206
+ [
207
+ ["name"],
208
+ ["email"],
209
+ ].each do |name,|
210
+ ITunesBaseModel::ELEMENT_INFOS << name
211
+ install_text_element(name, ITUNES_URI, nil, "#{ITUNES_PREFIX}_#{name}")
212
+ end
213
+
214
+ def initialize(*args)
215
+ if Utils.element_initialize_arguments?(args)
216
+ super
217
+ else
218
+ super()
219
+ self.itunes_name = args[0]
220
+ self.itunes_email = args[1]
221
+ end
222
+ end
223
+
224
+ def full_name
225
+ tag_name_with_prefix(ITUNES_PREFIX)
226
+ end
227
+
228
+ private
229
+ def maker_target(target)
230
+ target.itunes_owner
231
+ end
232
+
233
+ def setup_maker_element(owner)
234
+ super(owner)
235
+ owner.itunes_name = itunes_name
236
+ owner.itunes_email = itunes_email
237
+ end
238
+ end
239
+ end
240
+
241
+ module ITunesItemModel
242
+ extend BaseModel
243
+ extend ITunesModelUtils
244
+ include ITunesBaseModel
245
+
246
+ class << self
247
+ def append_features(klass)
248
+ super
249
+
250
+ return if klass.instance_of?(Module)
251
+ ELEMENT_INFOS.each do |name, type|
252
+ def_class_accessor(klass, name, type)
253
+ end
254
+ end
255
+ end
256
+
257
+ ELEMENT_INFOS = ITunesBaseModel::ELEMENT_INFOS +
258
+ [["duration", :element, "content"]]
259
+
260
+ class ITunesDuration < Element
261
+ include RSS09
262
+
263
+ @tag_name = "duration"
264
+
265
+ class << self
266
+ def required_prefix
267
+ ITUNES_PREFIX
268
+ end
269
+
270
+ def required_uri
271
+ ITUNES_URI
272
+ end
273
+
274
+ def parse(duration, do_validate=true)
275
+ if do_validate and /\A(?:
276
+ \d?\d:[0-5]\d:[0-5]\d|
277
+ [0-5]?\d:[0-5]\d
278
+ )\z/x !~ duration
279
+ raise ArgumentError,
280
+ "must be one of HH:MM:SS, H:MM:SS, MM::SS, M:SS: " +
281
+ duration.inspect
282
+ end
283
+
284
+ components = duration.split(':')
285
+ components[3..-1] = nil if components.size > 3
286
+
287
+ components.unshift("00") until components.size == 3
288
+
289
+ components.collect do |component|
290
+ component.to_i
291
+ end
292
+ end
293
+
294
+ def construct(hour, minute, second)
295
+ components = [minute, second]
296
+ if components.include?(nil)
297
+ nil
298
+ else
299
+ components.unshift(hour) if hour and hour > 0
300
+ components.collect do |component|
301
+ "%02d" % component
302
+ end.join(":")
303
+ end
304
+ end
305
+ end
306
+
307
+ content_setup
308
+ alias_method(:value, :content)
309
+ remove_method(:content=)
310
+
311
+ attr_reader :hour, :minute, :second
312
+ def initialize(*args)
313
+ if Utils.element_initialize_arguments?(args)
314
+ super
315
+ else
316
+ super()
317
+ args = args[0] if args.size == 1 and args[0].is_a?(Array)
318
+ if args.size == 1
319
+ self.content = args[0]
320
+ elsif args.size > 3
321
+ raise ArgumentError,
322
+ "must be (do_validate, params), (content), " +
323
+ "(minute, second), ([minute, second]), " +
324
+ "(hour, minute, second) or ([hour, minute, second]): " +
325
+ args.inspect
326
+ else
327
+ @second, @minute, @hour = args.reverse
328
+ update_content
329
+ end
330
+ end
331
+ end
332
+
333
+ def content=(value)
334
+ if value.nil?
335
+ @content = nil
336
+ elsif value.is_a?(self.class)
337
+ self.content = value.content
338
+ else
339
+ begin
340
+ @hour, @minute, @second = self.class.parse(value, @do_validate)
341
+ rescue ArgumentError
342
+ raise NotAvailableValueError.new(tag_name, value)
343
+ end
344
+ @content = value
345
+ end
346
+ end
347
+ alias_method(:value=, :content=)
348
+
349
+ def hour=(hour)
350
+ @hour = @do_validate ? Integer(hour) : hour.to_i
351
+ update_content
352
+ hour
353
+ end
354
+
355
+ def minute=(minute)
356
+ @minute = @do_validate ? Integer(minute) : minute.to_i
357
+ update_content
358
+ minute
359
+ end
360
+
361
+ def second=(second)
362
+ @second = @do_validate ? Integer(second) : second.to_i
363
+ update_content
364
+ second
365
+ end
366
+
367
+ def full_name
368
+ tag_name_with_prefix(ITUNES_PREFIX)
369
+ end
370
+
371
+ private
372
+ def update_content
373
+ @content = self.class.construct(hour, minute, second)
374
+ end
375
+
376
+ def maker_target(target)
377
+ if @content
378
+ target.itunes_duration {|duration| duration}
379
+ else
380
+ nil
381
+ end
382
+ end
383
+
384
+ def setup_maker_element(duration)
385
+ super(duration)
386
+ duration.content = @content
387
+ end
388
+ end
389
+ end
390
+
391
+ class Rss
392
+ class Channel
393
+ include ITunesChannelModel
394
+ class Item; include ITunesItemModel; end
395
+ end
396
+ end
397
+
398
+ element_infos =
399
+ ITunesChannelModel::ELEMENT_INFOS + ITunesItemModel::ELEMENT_INFOS
400
+ element_infos.each do |name, type|
401
+ case type
402
+ when :element, :elements, :attribute
403
+ class_name = Utils.to_class_name(name)
404
+ BaseListener.install_class_name(ITUNES_URI, name, "ITunes#{class_name}")
405
+ else
406
+ accessor_base = "#{ITUNES_PREFIX}_#{name.gsub(/-/, '_')}"
407
+ BaseListener.install_get_text_element(ITUNES_URI, name, accessor_base)
408
+ end
409
+ end
410
+ end
@@ -0,0 +1,44 @@
1
+ require "rss/rss"
2
+
3
+ module RSS
4
+ module Maker
5
+ MAKERS = {}
6
+
7
+ class << self
8
+ def make(version, &block)
9
+ m = maker(version)
10
+ raise UnsupportedMakerVersionError.new(version) if m.nil?
11
+ m[:maker].make(m[:version], &block)
12
+ end
13
+
14
+ def maker(version)
15
+ MAKERS[version]
16
+ end
17
+
18
+ def add_maker(version, normalized_version, maker)
19
+ MAKERS[version] = {:maker => maker, :version => normalized_version}
20
+ end
21
+
22
+ def versions
23
+ MAKERS.keys.uniq.sort
24
+ end
25
+
26
+ def makers
27
+ MAKERS.values.collect {|info| info[:maker]}.uniq
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ require "rss/maker/1.0"
34
+ require "rss/maker/2.0"
35
+ require "rss/maker/feed"
36
+ require "rss/maker/entry"
37
+ require "rss/maker/content"
38
+ require "rss/maker/dublincore"
39
+ require "rss/maker/slash"
40
+ require "rss/maker/syndication"
41
+ require "rss/maker/taxonomy"
42
+ require "rss/maker/trackback"
43
+ require "rss/maker/image"
44
+ require "rss/maker/itunes"