rubysl-rss 1.0.0

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