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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.travis.yml +8 -0
- data/Gemfile +4 -0
- data/LICENSE +25 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/lib/rss.rb +1 -0
- data/lib/rss/0.9.rb +428 -0
- data/lib/rss/1.0.rb +452 -0
- data/lib/rss/2.0.rb +111 -0
- data/lib/rss/atom.rb +749 -0
- data/lib/rss/content.rb +31 -0
- data/lib/rss/content/1.0.rb +10 -0
- data/lib/rss/content/2.0.rb +12 -0
- data/lib/rss/converter.rb +162 -0
- data/lib/rss/dublincore.rb +161 -0
- data/lib/rss/dublincore/1.0.rb +13 -0
- data/lib/rss/dublincore/2.0.rb +13 -0
- data/lib/rss/dublincore/atom.rb +17 -0
- data/lib/rss/image.rb +193 -0
- data/lib/rss/itunes.rb +410 -0
- data/lib/rss/maker.rb +44 -0
- data/lib/rss/maker/0.9.rb +467 -0
- data/lib/rss/maker/1.0.rb +434 -0
- data/lib/rss/maker/2.0.rb +223 -0
- data/lib/rss/maker/atom.rb +172 -0
- data/lib/rss/maker/base.rb +868 -0
- data/lib/rss/maker/content.rb +21 -0
- data/lib/rss/maker/dublincore.rb +124 -0
- data/lib/rss/maker/entry.rb +163 -0
- data/lib/rss/maker/feed.rb +429 -0
- data/lib/rss/maker/image.rb +111 -0
- data/lib/rss/maker/itunes.rb +242 -0
- data/lib/rss/maker/slash.rb +33 -0
- data/lib/rss/maker/syndication.rb +18 -0
- data/lib/rss/maker/taxonomy.rb +118 -0
- data/lib/rss/maker/trackback.rb +61 -0
- data/lib/rss/parser.rb +541 -0
- data/lib/rss/rexmlparser.rb +54 -0
- data/lib/rss/rss.rb +1312 -0
- data/lib/rss/slash.rb +49 -0
- data/lib/rss/syndication.rb +67 -0
- data/lib/rss/taxonomy.rb +145 -0
- data/lib/rss/trackback.rb +288 -0
- data/lib/rss/utils.rb +111 -0
- data/lib/rss/xml-stylesheet.rb +105 -0
- data/lib/rss/xml.rb +71 -0
- data/lib/rss/xmlparser.rb +93 -0
- data/lib/rss/xmlscanner.rb +121 -0
- data/lib/rubysl/rss.rb +2 -0
- data/lib/rubysl/rss/rss.rb +19 -0
- data/lib/rubysl/rss/version.rb +5 -0
- data/rubysl-rss.gemspec +23 -0
- metadata +153 -0
data/lib/rss/itunes.rb
ADDED
@@ -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
|
data/lib/rss/maker.rb
ADDED
@@ -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"
|