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
@@ -0,0 +1,172 @@
|
|
1
|
+
require "rss/atom"
|
2
|
+
|
3
|
+
require "rss/maker/base"
|
4
|
+
|
5
|
+
module RSS
|
6
|
+
module Maker
|
7
|
+
module AtomPersons
|
8
|
+
module_function
|
9
|
+
def def_atom_persons(klass, name, maker_name, plural=nil)
|
10
|
+
plural ||= "#{name}s"
|
11
|
+
klass_name = Utils.to_class_name(name)
|
12
|
+
plural_klass_name = Utils.to_class_name(plural)
|
13
|
+
|
14
|
+
klass.class_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
15
|
+
class #{plural_klass_name} < #{plural_klass_name}Base
|
16
|
+
class #{klass_name} < #{klass_name}Base
|
17
|
+
def to_feed(feed, current)
|
18
|
+
#{name} = feed.class::#{klass_name}.new
|
19
|
+
set = setup_values(#{name})
|
20
|
+
unless set
|
21
|
+
raise NotSetError.new(#{maker_name.dump},
|
22
|
+
not_set_required_variables)
|
23
|
+
end
|
24
|
+
current.#{plural} << #{name}
|
25
|
+
set_parent(#{name}, current)
|
26
|
+
setup_other_elements(#{name})
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
def required_variable_names
|
31
|
+
%w(name)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
EOC
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
module AtomTextConstruct
|
40
|
+
class << self
|
41
|
+
def def_atom_text_construct(klass, name, maker_name, klass_name=nil,
|
42
|
+
atom_klass_name=nil)
|
43
|
+
klass_name ||= Utils.to_class_name(name)
|
44
|
+
atom_klass_name ||= Utils.to_class_name(name)
|
45
|
+
|
46
|
+
klass.class_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
47
|
+
class #{klass_name} < #{klass_name}Base
|
48
|
+
include #{self.name}
|
49
|
+
def to_feed(feed, current)
|
50
|
+
#{name} = current.class::#{atom_klass_name}.new
|
51
|
+
if setup_values(#{name})
|
52
|
+
current.#{name} = #{name}
|
53
|
+
set_parent(#{name}, current)
|
54
|
+
setup_other_elements(feed)
|
55
|
+
elsif variable_is_set?
|
56
|
+
raise NotSetError.new(#{maker_name.dump},
|
57
|
+
not_set_required_variables)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
EOC
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
def required_variable_names
|
67
|
+
if type == "xhtml"
|
68
|
+
%w(xml_content)
|
69
|
+
else
|
70
|
+
%w(content)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def variables
|
75
|
+
if type == "xhtml"
|
76
|
+
super + %w(xhtml)
|
77
|
+
else
|
78
|
+
super
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
module AtomCategory
|
84
|
+
def to_feed(feed, current)
|
85
|
+
category = feed.class::Category.new
|
86
|
+
set = setup_values(category)
|
87
|
+
if set
|
88
|
+
current.categories << category
|
89
|
+
set_parent(category, current)
|
90
|
+
setup_other_elements(feed)
|
91
|
+
else
|
92
|
+
raise NotSetError.new(self.class.not_set_name,
|
93
|
+
not_set_required_variables)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
def required_variable_names
|
99
|
+
%w(term)
|
100
|
+
end
|
101
|
+
|
102
|
+
def variables
|
103
|
+
super + ["term", "scheme"]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
module AtomLink
|
108
|
+
def to_feed(feed, current)
|
109
|
+
link = feed.class::Link.new
|
110
|
+
set = setup_values(link)
|
111
|
+
if set
|
112
|
+
current.links << link
|
113
|
+
set_parent(link, current)
|
114
|
+
setup_other_elements(feed)
|
115
|
+
else
|
116
|
+
raise NotSetError.new(self.class.not_set_name,
|
117
|
+
not_set_required_variables)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
private
|
122
|
+
def required_variable_names
|
123
|
+
%w(href)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
module AtomGenerator
|
128
|
+
def to_feed(feed, current)
|
129
|
+
generator = current.class::Generator.new
|
130
|
+
if setup_values(generator)
|
131
|
+
current.generator = generator
|
132
|
+
set_parent(generator, current)
|
133
|
+
setup_other_elements(feed)
|
134
|
+
elsif variable_is_set?
|
135
|
+
raise NotSetError.new(self.class.not_set_name,
|
136
|
+
not_set_required_variables)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
private
|
141
|
+
def required_variable_names
|
142
|
+
%w(content)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
module AtomLogo
|
147
|
+
def to_feed(feed, current)
|
148
|
+
logo = current.class::Logo.new
|
149
|
+
class << logo
|
150
|
+
alias_method(:uri=, :content=)
|
151
|
+
end
|
152
|
+
set = setup_values(logo)
|
153
|
+
class << logo
|
154
|
+
remove_method(:uri=)
|
155
|
+
end
|
156
|
+
if set
|
157
|
+
current.logo = logo
|
158
|
+
set_parent(logo, current)
|
159
|
+
setup_other_elements(feed)
|
160
|
+
elsif variable_is_set?
|
161
|
+
raise NotSetError.new(self.class.not_set_name,
|
162
|
+
not_set_required_variables)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
private
|
167
|
+
def required_variable_names
|
168
|
+
%w(uri)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
@@ -0,0 +1,868 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
require 'rss/rss'
|
4
|
+
|
5
|
+
module RSS
|
6
|
+
module Maker
|
7
|
+
class Base
|
8
|
+
extend Utils::InheritedReader
|
9
|
+
|
10
|
+
OTHER_ELEMENTS = []
|
11
|
+
NEED_INITIALIZE_VARIABLES = []
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def other_elements
|
15
|
+
inherited_array_reader("OTHER_ELEMENTS")
|
16
|
+
end
|
17
|
+
def need_initialize_variables
|
18
|
+
inherited_array_reader("NEED_INITIALIZE_VARIABLES")
|
19
|
+
end
|
20
|
+
|
21
|
+
def inherited_base
|
22
|
+
::RSS::Maker::Base
|
23
|
+
end
|
24
|
+
|
25
|
+
def inherited(subclass)
|
26
|
+
subclass.const_set("OTHER_ELEMENTS", [])
|
27
|
+
subclass.const_set("NEED_INITIALIZE_VARIABLES", [])
|
28
|
+
end
|
29
|
+
|
30
|
+
def add_other_element(variable_name)
|
31
|
+
self::OTHER_ELEMENTS << variable_name
|
32
|
+
end
|
33
|
+
|
34
|
+
def add_need_initialize_variable(variable_name, init_value="nil")
|
35
|
+
self::NEED_INITIALIZE_VARIABLES << [variable_name, init_value]
|
36
|
+
end
|
37
|
+
|
38
|
+
def def_array_element(name, plural=nil, klass_name=nil)
|
39
|
+
include Enumerable
|
40
|
+
extend Forwardable
|
41
|
+
|
42
|
+
plural ||= "#{name}s"
|
43
|
+
klass_name ||= Utils.to_class_name(name)
|
44
|
+
def_delegators("@#{plural}", :<<, :[], :[]=, :first, :last)
|
45
|
+
def_delegators("@#{plural}", :push, :pop, :shift, :unshift)
|
46
|
+
def_delegators("@#{plural}", :each, :size, :empty?, :clear)
|
47
|
+
|
48
|
+
add_need_initialize_variable(plural, "[]")
|
49
|
+
|
50
|
+
module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
51
|
+
def new_#{name}
|
52
|
+
#{name} = self.class::#{klass_name}.new(@maker)
|
53
|
+
@#{plural} << #{name}
|
54
|
+
if block_given?
|
55
|
+
yield #{name}
|
56
|
+
else
|
57
|
+
#{name}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
alias new_child new_#{name}
|
61
|
+
|
62
|
+
def to_feed(*args)
|
63
|
+
@#{plural}.each do |#{name}|
|
64
|
+
#{name}.to_feed(*args)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def replace(elements)
|
69
|
+
@#{plural}.replace(elements.to_a)
|
70
|
+
end
|
71
|
+
EOC
|
72
|
+
end
|
73
|
+
|
74
|
+
def def_classed_element_without_accessor(name, class_name=nil)
|
75
|
+
class_name ||= Utils.to_class_name(name)
|
76
|
+
add_other_element(name)
|
77
|
+
add_need_initialize_variable(name, "make_#{name}")
|
78
|
+
module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
79
|
+
private
|
80
|
+
def setup_#{name}(feed, current)
|
81
|
+
@#{name}.to_feed(feed, current)
|
82
|
+
end
|
83
|
+
|
84
|
+
def make_#{name}
|
85
|
+
self.class::#{class_name}.new(@maker)
|
86
|
+
end
|
87
|
+
EOC
|
88
|
+
end
|
89
|
+
|
90
|
+
def def_classed_element(name, class_name=nil, attribute_name=nil)
|
91
|
+
def_classed_element_without_accessor(name, class_name)
|
92
|
+
if attribute_name
|
93
|
+
module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
94
|
+
def #{name}
|
95
|
+
if block_given?
|
96
|
+
yield(@#{name})
|
97
|
+
else
|
98
|
+
@#{name}.#{attribute_name}
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def #{name}=(new_value)
|
103
|
+
@#{name}.#{attribute_name} = new_value
|
104
|
+
end
|
105
|
+
EOC
|
106
|
+
else
|
107
|
+
attr_reader name
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def def_classed_elements(name, attribute, plural_class_name=nil,
|
112
|
+
plural_name=nil, new_name=nil)
|
113
|
+
plural_name ||= "#{name}s"
|
114
|
+
new_name ||= name
|
115
|
+
def_classed_element(plural_name, plural_class_name)
|
116
|
+
local_variable_name = "_#{name}"
|
117
|
+
new_value_variable_name = "new_value"
|
118
|
+
additional_setup_code = nil
|
119
|
+
if block_given?
|
120
|
+
additional_setup_code = yield(local_variable_name,
|
121
|
+
new_value_variable_name)
|
122
|
+
end
|
123
|
+
module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
124
|
+
def #{name}
|
125
|
+
#{local_variable_name} = #{plural_name}.first
|
126
|
+
#{local_variable_name} ? #{local_variable_name}.#{attribute} : nil
|
127
|
+
end
|
128
|
+
|
129
|
+
def #{name}=(#{new_value_variable_name})
|
130
|
+
#{local_variable_name} =
|
131
|
+
#{plural_name}.first || #{plural_name}.new_#{new_name}
|
132
|
+
#{additional_setup_code}
|
133
|
+
#{local_variable_name}.#{attribute} = #{new_value_variable_name}
|
134
|
+
end
|
135
|
+
EOC
|
136
|
+
end
|
137
|
+
|
138
|
+
def def_other_element(name)
|
139
|
+
attr_accessor name
|
140
|
+
def_other_element_without_accessor(name)
|
141
|
+
end
|
142
|
+
|
143
|
+
def def_other_element_without_accessor(name)
|
144
|
+
add_need_initialize_variable(name)
|
145
|
+
add_other_element(name)
|
146
|
+
module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
147
|
+
def setup_#{name}(feed, current)
|
148
|
+
if !@#{name}.nil? and current.respond_to?(:#{name}=)
|
149
|
+
current.#{name} = @#{name}
|
150
|
+
end
|
151
|
+
end
|
152
|
+
EOC
|
153
|
+
end
|
154
|
+
|
155
|
+
def def_csv_element(name, type=nil)
|
156
|
+
def_other_element_without_accessor(name)
|
157
|
+
attr_reader(name)
|
158
|
+
converter = ""
|
159
|
+
if type == :integer
|
160
|
+
converter = "{|v| Integer(v)}"
|
161
|
+
end
|
162
|
+
module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
163
|
+
def #{name}=(value)
|
164
|
+
@#{name} = Utils::CSV.parse(value)#{converter}
|
165
|
+
end
|
166
|
+
EOC
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
attr_reader :maker
|
171
|
+
def initialize(maker)
|
172
|
+
@maker = maker
|
173
|
+
@default_values_are_set = false
|
174
|
+
initialize_variables
|
175
|
+
end
|
176
|
+
|
177
|
+
def have_required_values?
|
178
|
+
not_set_required_variables.empty?
|
179
|
+
end
|
180
|
+
|
181
|
+
def variable_is_set?
|
182
|
+
variables.any? {|var| not __send__(var).nil?}
|
183
|
+
end
|
184
|
+
|
185
|
+
private
|
186
|
+
def initialize_variables
|
187
|
+
self.class.need_initialize_variables.each do |variable_name, init_value|
|
188
|
+
instance_eval("@#{variable_name} = #{init_value}", __FILE__, __LINE__)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def setup_other_elements(feed, current=nil)
|
193
|
+
current ||= current_element(feed)
|
194
|
+
self.class.other_elements.each do |element|
|
195
|
+
__send__("setup_#{element}", feed, current)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def current_element(feed)
|
200
|
+
feed
|
201
|
+
end
|
202
|
+
|
203
|
+
def set_default_values(&block)
|
204
|
+
return yield if @default_values_are_set
|
205
|
+
|
206
|
+
begin
|
207
|
+
@default_values_are_set = true
|
208
|
+
_set_default_values(&block)
|
209
|
+
ensure
|
210
|
+
@default_values_are_set = false
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def _set_default_values(&block)
|
215
|
+
yield
|
216
|
+
end
|
217
|
+
|
218
|
+
def setup_values(target)
|
219
|
+
set = false
|
220
|
+
if have_required_values?
|
221
|
+
variables.each do |var|
|
222
|
+
setter = "#{var}="
|
223
|
+
if target.respond_to?(setter)
|
224
|
+
value = __send__(var)
|
225
|
+
if value
|
226
|
+
target.__send__(setter, value)
|
227
|
+
set = true
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
set
|
233
|
+
end
|
234
|
+
|
235
|
+
def set_parent(target, parent)
|
236
|
+
target.parent = parent if target.class.need_parent?
|
237
|
+
end
|
238
|
+
|
239
|
+
def variables
|
240
|
+
self.class.need_initialize_variables.find_all do |name, init|
|
241
|
+
"nil" == init
|
242
|
+
end.collect do |name, init|
|
243
|
+
name
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
def not_set_required_variables
|
248
|
+
required_variable_names.find_all do |var|
|
249
|
+
__send__(var).nil?
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
def required_variables_are_set?
|
254
|
+
required_variable_names.each do |var|
|
255
|
+
return false if __send__(var).nil?
|
256
|
+
end
|
257
|
+
true
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
module AtomPersonConstructBase
|
262
|
+
def self.append_features(klass)
|
263
|
+
super
|
264
|
+
|
265
|
+
klass.class_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
266
|
+
%w(name uri email).each do |element|
|
267
|
+
attr_accessor element
|
268
|
+
add_need_initialize_variable(element)
|
269
|
+
end
|
270
|
+
EOC
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
module AtomTextConstructBase
|
275
|
+
module EnsureXMLContent
|
276
|
+
class << self
|
277
|
+
def included(base)
|
278
|
+
super
|
279
|
+
base.class_eval do
|
280
|
+
%w(type content xml_content).each do |element|
|
281
|
+
attr_reader element
|
282
|
+
attr_writer element if element != "xml_content"
|
283
|
+
add_need_initialize_variable(element)
|
284
|
+
end
|
285
|
+
|
286
|
+
alias_method(:xhtml, :xml_content)
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
def ensure_xml_content(content)
|
292
|
+
xhtml_uri = ::RSS::Atom::XHTML_URI
|
293
|
+
unless content.is_a?(RSS::XML::Element) and
|
294
|
+
["div", xhtml_uri] == [content.name, content.uri]
|
295
|
+
children = content
|
296
|
+
children = [children] unless content.is_a?(Array)
|
297
|
+
children = set_xhtml_uri_as_default_uri(children)
|
298
|
+
content = RSS::XML::Element.new("div", nil, xhtml_uri,
|
299
|
+
{"xmlns" => xhtml_uri},
|
300
|
+
children)
|
301
|
+
end
|
302
|
+
content
|
303
|
+
end
|
304
|
+
|
305
|
+
def xml_content=(content)
|
306
|
+
@xml_content = ensure_xml_content(content)
|
307
|
+
end
|
308
|
+
|
309
|
+
def xhtml=(content)
|
310
|
+
self.xml_content = content
|
311
|
+
end
|
312
|
+
|
313
|
+
private
|
314
|
+
def set_xhtml_uri_as_default_uri(children)
|
315
|
+
children.collect do |child|
|
316
|
+
if child.is_a?(RSS::XML::Element) and
|
317
|
+
child.prefix.nil? and child.uri.nil?
|
318
|
+
RSS::XML::Element.new(child.name, nil, ::RSS::Atom::XHTML_URI,
|
319
|
+
child.attributes.dup,
|
320
|
+
set_xhtml_uri_as_default_uri(child.children))
|
321
|
+
else
|
322
|
+
child
|
323
|
+
end
|
324
|
+
end
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
def self.append_features(klass)
|
329
|
+
super
|
330
|
+
|
331
|
+
klass.class_eval do
|
332
|
+
include EnsureXMLContent
|
333
|
+
end
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
module SetupDefaultDate
|
338
|
+
private
|
339
|
+
def _set_default_values(&block)
|
340
|
+
keep = {
|
341
|
+
:date => date,
|
342
|
+
:dc_dates => dc_dates.to_a.dup,
|
343
|
+
}
|
344
|
+
_date = date
|
345
|
+
if _date and !dc_dates.any? {|dc_date| dc_date.value == _date}
|
346
|
+
dc_date = self.class::DublinCoreDates::DublinCoreDate.new(self)
|
347
|
+
dc_date.value = _date.dup
|
348
|
+
dc_dates.unshift(dc_date)
|
349
|
+
end
|
350
|
+
self.date ||= self.dc_date
|
351
|
+
super(&block)
|
352
|
+
ensure
|
353
|
+
date = keep[:date]
|
354
|
+
dc_dates.replace(keep[:dc_dates])
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
class RSSBase < Base
|
359
|
+
class << self
|
360
|
+
def make(version, &block)
|
361
|
+
new(version).make(&block)
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
%w(xml_stylesheets channel image items textinput).each do |element|
|
366
|
+
attr_reader element
|
367
|
+
add_need_initialize_variable(element, "make_#{element}")
|
368
|
+
module_eval(<<-EOC, __FILE__, __LINE__)
|
369
|
+
private
|
370
|
+
def setup_#{element}(feed)
|
371
|
+
@#{element}.to_feed(feed)
|
372
|
+
end
|
373
|
+
|
374
|
+
def make_#{element}
|
375
|
+
self.class::#{Utils.to_class_name(element)}.new(self)
|
376
|
+
end
|
377
|
+
EOC
|
378
|
+
end
|
379
|
+
|
380
|
+
attr_reader :feed_version
|
381
|
+
alias_method(:rss_version, :feed_version)
|
382
|
+
attr_accessor :version, :encoding, :standalone
|
383
|
+
|
384
|
+
def initialize(feed_version)
|
385
|
+
super(self)
|
386
|
+
@feed_type = nil
|
387
|
+
@feed_subtype = nil
|
388
|
+
@feed_version = feed_version
|
389
|
+
@version = "1.0"
|
390
|
+
@encoding = "UTF-8"
|
391
|
+
@standalone = nil
|
392
|
+
end
|
393
|
+
|
394
|
+
def make
|
395
|
+
if block_given?
|
396
|
+
yield(self)
|
397
|
+
to_feed
|
398
|
+
else
|
399
|
+
nil
|
400
|
+
end
|
401
|
+
end
|
402
|
+
|
403
|
+
def to_feed
|
404
|
+
feed = make_feed
|
405
|
+
setup_xml_stylesheets(feed)
|
406
|
+
setup_elements(feed)
|
407
|
+
setup_other_elements(feed)
|
408
|
+
if feed.valid?
|
409
|
+
feed
|
410
|
+
else
|
411
|
+
nil
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
private
|
416
|
+
remove_method :make_xml_stylesheets
|
417
|
+
def make_xml_stylesheets
|
418
|
+
XMLStyleSheets.new(self)
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
class XMLStyleSheets < Base
|
423
|
+
def_array_element("xml_stylesheet", nil, "XMLStyleSheet")
|
424
|
+
|
425
|
+
class XMLStyleSheet < Base
|
426
|
+
|
427
|
+
::RSS::XMLStyleSheet::ATTRIBUTES.each do |attribute|
|
428
|
+
attr_accessor attribute
|
429
|
+
add_need_initialize_variable(attribute)
|
430
|
+
end
|
431
|
+
|
432
|
+
def to_feed(feed)
|
433
|
+
xss = ::RSS::XMLStyleSheet.new
|
434
|
+
guess_type_if_need(xss)
|
435
|
+
set = setup_values(xss)
|
436
|
+
if set
|
437
|
+
feed.xml_stylesheets << xss
|
438
|
+
end
|
439
|
+
end
|
440
|
+
|
441
|
+
private
|
442
|
+
def guess_type_if_need(xss)
|
443
|
+
if @type.nil?
|
444
|
+
xss.href = @href
|
445
|
+
@type = xss.type
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
449
|
+
def required_variable_names
|
450
|
+
%w(href type)
|
451
|
+
end
|
452
|
+
end
|
453
|
+
end
|
454
|
+
|
455
|
+
class ChannelBase < Base
|
456
|
+
include SetupDefaultDate
|
457
|
+
|
458
|
+
%w(cloud categories skipDays skipHours).each do |name|
|
459
|
+
def_classed_element(name)
|
460
|
+
end
|
461
|
+
|
462
|
+
%w(generator copyright description title).each do |name|
|
463
|
+
def_classed_element(name, nil, "content")
|
464
|
+
end
|
465
|
+
|
466
|
+
[
|
467
|
+
["link", "href", Proc.new {|target,| "#{target}.href = 'self'"}],
|
468
|
+
["author", "name"],
|
469
|
+
["contributor", "name"],
|
470
|
+
].each do |name, attribute, additional_setup_maker|
|
471
|
+
def_classed_elements(name, attribute, &additional_setup_maker)
|
472
|
+
end
|
473
|
+
|
474
|
+
%w(id about language
|
475
|
+
managingEditor webMaster rating docs date
|
476
|
+
lastBuildDate ttl).each do |element|
|
477
|
+
attr_accessor element
|
478
|
+
add_need_initialize_variable(element)
|
479
|
+
end
|
480
|
+
|
481
|
+
def pubDate
|
482
|
+
date
|
483
|
+
end
|
484
|
+
|
485
|
+
def pubDate=(date)
|
486
|
+
self.date = date
|
487
|
+
end
|
488
|
+
|
489
|
+
def updated
|
490
|
+
date
|
491
|
+
end
|
492
|
+
|
493
|
+
def updated=(date)
|
494
|
+
self.date = date
|
495
|
+
end
|
496
|
+
|
497
|
+
alias_method(:rights, :copyright)
|
498
|
+
alias_method(:rights=, :copyright=)
|
499
|
+
|
500
|
+
alias_method(:subtitle, :description)
|
501
|
+
alias_method(:subtitle=, :description=)
|
502
|
+
|
503
|
+
def icon
|
504
|
+
image_favicon.about
|
505
|
+
end
|
506
|
+
|
507
|
+
def icon=(url)
|
508
|
+
image_favicon.about = url
|
509
|
+
end
|
510
|
+
|
511
|
+
def logo
|
512
|
+
maker.image.url
|
513
|
+
end
|
514
|
+
|
515
|
+
def logo=(url)
|
516
|
+
maker.image.url = url
|
517
|
+
end
|
518
|
+
|
519
|
+
class SkipDaysBase < Base
|
520
|
+
def_array_element("day")
|
521
|
+
|
522
|
+
class DayBase < Base
|
523
|
+
%w(content).each do |element|
|
524
|
+
attr_accessor element
|
525
|
+
add_need_initialize_variable(element)
|
526
|
+
end
|
527
|
+
end
|
528
|
+
end
|
529
|
+
|
530
|
+
class SkipHoursBase < Base
|
531
|
+
def_array_element("hour")
|
532
|
+
|
533
|
+
class HourBase < Base
|
534
|
+
%w(content).each do |element|
|
535
|
+
attr_accessor element
|
536
|
+
add_need_initialize_variable(element)
|
537
|
+
end
|
538
|
+
end
|
539
|
+
end
|
540
|
+
|
541
|
+
class CloudBase < Base
|
542
|
+
%w(domain port path registerProcedure protocol).each do |element|
|
543
|
+
attr_accessor element
|
544
|
+
add_need_initialize_variable(element)
|
545
|
+
end
|
546
|
+
end
|
547
|
+
|
548
|
+
class CategoriesBase < Base
|
549
|
+
def_array_element("category", "categories")
|
550
|
+
|
551
|
+
class CategoryBase < Base
|
552
|
+
%w(domain content label).each do |element|
|
553
|
+
attr_accessor element
|
554
|
+
add_need_initialize_variable(element)
|
555
|
+
end
|
556
|
+
|
557
|
+
alias_method(:term, :domain)
|
558
|
+
alias_method(:term=, :domain=)
|
559
|
+
alias_method(:scheme, :content)
|
560
|
+
alias_method(:scheme=, :content=)
|
561
|
+
end
|
562
|
+
end
|
563
|
+
|
564
|
+
class LinksBase < Base
|
565
|
+
def_array_element("link")
|
566
|
+
|
567
|
+
class LinkBase < Base
|
568
|
+
%w(href rel type hreflang title length).each do |element|
|
569
|
+
attr_accessor element
|
570
|
+
add_need_initialize_variable(element)
|
571
|
+
end
|
572
|
+
end
|
573
|
+
end
|
574
|
+
|
575
|
+
class AuthorsBase < Base
|
576
|
+
def_array_element("author")
|
577
|
+
|
578
|
+
class AuthorBase < Base
|
579
|
+
include AtomPersonConstructBase
|
580
|
+
end
|
581
|
+
end
|
582
|
+
|
583
|
+
class ContributorsBase < Base
|
584
|
+
def_array_element("contributor")
|
585
|
+
|
586
|
+
class ContributorBase < Base
|
587
|
+
include AtomPersonConstructBase
|
588
|
+
end
|
589
|
+
end
|
590
|
+
|
591
|
+
class GeneratorBase < Base
|
592
|
+
%w(uri version content).each do |element|
|
593
|
+
attr_accessor element
|
594
|
+
add_need_initialize_variable(element)
|
595
|
+
end
|
596
|
+
end
|
597
|
+
|
598
|
+
class CopyrightBase < Base
|
599
|
+
include AtomTextConstructBase
|
600
|
+
end
|
601
|
+
|
602
|
+
class DescriptionBase < Base
|
603
|
+
include AtomTextConstructBase
|
604
|
+
end
|
605
|
+
|
606
|
+
class TitleBase < Base
|
607
|
+
include AtomTextConstructBase
|
608
|
+
end
|
609
|
+
end
|
610
|
+
|
611
|
+
class ImageBase < Base
|
612
|
+
%w(title url width height description).each do |element|
|
613
|
+
attr_accessor element
|
614
|
+
add_need_initialize_variable(element)
|
615
|
+
end
|
616
|
+
|
617
|
+
def link
|
618
|
+
@maker.channel.link
|
619
|
+
end
|
620
|
+
end
|
621
|
+
|
622
|
+
class ItemsBase < Base
|
623
|
+
def_array_element("item")
|
624
|
+
|
625
|
+
attr_accessor :do_sort, :max_size
|
626
|
+
|
627
|
+
def initialize(maker)
|
628
|
+
super
|
629
|
+
@do_sort = false
|
630
|
+
@max_size = -1
|
631
|
+
end
|
632
|
+
|
633
|
+
def normalize
|
634
|
+
if @max_size >= 0
|
635
|
+
sort_if_need[0...@max_size]
|
636
|
+
else
|
637
|
+
sort_if_need[0..@max_size]
|
638
|
+
end
|
639
|
+
end
|
640
|
+
|
641
|
+
private
|
642
|
+
def sort_if_need
|
643
|
+
if @do_sort.respond_to?(:call)
|
644
|
+
@items.sort do |x, y|
|
645
|
+
@do_sort.call(x, y)
|
646
|
+
end
|
647
|
+
elsif @do_sort
|
648
|
+
@items.sort do |x, y|
|
649
|
+
y <=> x
|
650
|
+
end
|
651
|
+
else
|
652
|
+
@items
|
653
|
+
end
|
654
|
+
end
|
655
|
+
|
656
|
+
class ItemBase < Base
|
657
|
+
include SetupDefaultDate
|
658
|
+
|
659
|
+
%w(guid enclosure source categories content).each do |name|
|
660
|
+
def_classed_element(name)
|
661
|
+
end
|
662
|
+
|
663
|
+
%w(rights description title).each do |name|
|
664
|
+
def_classed_element(name, nil, "content")
|
665
|
+
end
|
666
|
+
|
667
|
+
[
|
668
|
+
["author", "name"],
|
669
|
+
["link", "href", Proc.new {|target,| "#{target}.href = 'alternate'"}],
|
670
|
+
["contributor", "name"],
|
671
|
+
].each do |name, attribute|
|
672
|
+
def_classed_elements(name, attribute)
|
673
|
+
end
|
674
|
+
|
675
|
+
%w(date comments id published).each do |element|
|
676
|
+
attr_accessor element
|
677
|
+
add_need_initialize_variable(element)
|
678
|
+
end
|
679
|
+
|
680
|
+
def pubDate
|
681
|
+
date
|
682
|
+
end
|
683
|
+
|
684
|
+
def pubDate=(date)
|
685
|
+
self.date = date
|
686
|
+
end
|
687
|
+
|
688
|
+
def updated
|
689
|
+
date
|
690
|
+
end
|
691
|
+
|
692
|
+
def updated=(date)
|
693
|
+
self.date = date
|
694
|
+
end
|
695
|
+
|
696
|
+
alias_method(:summary, :description)
|
697
|
+
alias_method(:summary=, :description=)
|
698
|
+
|
699
|
+
def <=>(other)
|
700
|
+
_date = date || dc_date
|
701
|
+
_other_date = other.date || other.dc_date
|
702
|
+
if _date and _other_date
|
703
|
+
_date <=> _other_date
|
704
|
+
elsif _date
|
705
|
+
1
|
706
|
+
elsif _other_date
|
707
|
+
-1
|
708
|
+
else
|
709
|
+
0
|
710
|
+
end
|
711
|
+
end
|
712
|
+
|
713
|
+
class GuidBase < Base
|
714
|
+
%w(isPermaLink content).each do |element|
|
715
|
+
attr_accessor element
|
716
|
+
add_need_initialize_variable(element)
|
717
|
+
end
|
718
|
+
end
|
719
|
+
|
720
|
+
class EnclosureBase < Base
|
721
|
+
%w(url length type).each do |element|
|
722
|
+
attr_accessor element
|
723
|
+
add_need_initialize_variable(element)
|
724
|
+
end
|
725
|
+
end
|
726
|
+
|
727
|
+
class SourceBase < Base
|
728
|
+
%w(authors categories contributors generator icon
|
729
|
+
logo rights subtitle title).each do |name|
|
730
|
+
def_classed_element(name)
|
731
|
+
end
|
732
|
+
|
733
|
+
[
|
734
|
+
["link", "href"],
|
735
|
+
].each do |name, attribute|
|
736
|
+
def_classed_elements(name, attribute)
|
737
|
+
end
|
738
|
+
|
739
|
+
%w(id content date).each do |element|
|
740
|
+
attr_accessor element
|
741
|
+
add_need_initialize_variable(element)
|
742
|
+
end
|
743
|
+
|
744
|
+
alias_method(:url, :link)
|
745
|
+
alias_method(:url=, :link=)
|
746
|
+
|
747
|
+
def updated
|
748
|
+
date
|
749
|
+
end
|
750
|
+
|
751
|
+
def updated=(date)
|
752
|
+
self.date = date
|
753
|
+
end
|
754
|
+
|
755
|
+
private
|
756
|
+
AuthorsBase = ChannelBase::AuthorsBase
|
757
|
+
CategoriesBase = ChannelBase::CategoriesBase
|
758
|
+
ContributorsBase = ChannelBase::ContributorsBase
|
759
|
+
GeneratorBase = ChannelBase::GeneratorBase
|
760
|
+
|
761
|
+
class IconBase < Base
|
762
|
+
%w(url).each do |element|
|
763
|
+
attr_accessor element
|
764
|
+
add_need_initialize_variable(element)
|
765
|
+
end
|
766
|
+
end
|
767
|
+
|
768
|
+
LinksBase = ChannelBase::LinksBase
|
769
|
+
|
770
|
+
class LogoBase < Base
|
771
|
+
%w(uri).each do |element|
|
772
|
+
attr_accessor element
|
773
|
+
add_need_initialize_variable(element)
|
774
|
+
end
|
775
|
+
end
|
776
|
+
|
777
|
+
class RightsBase < Base
|
778
|
+
include AtomTextConstructBase
|
779
|
+
end
|
780
|
+
|
781
|
+
class SubtitleBase < Base
|
782
|
+
include AtomTextConstructBase
|
783
|
+
end
|
784
|
+
|
785
|
+
class TitleBase < Base
|
786
|
+
include AtomTextConstructBase
|
787
|
+
end
|
788
|
+
end
|
789
|
+
|
790
|
+
CategoriesBase = ChannelBase::CategoriesBase
|
791
|
+
AuthorsBase = ChannelBase::AuthorsBase
|
792
|
+
LinksBase = ChannelBase::LinksBase
|
793
|
+
ContributorsBase = ChannelBase::ContributorsBase
|
794
|
+
|
795
|
+
class RightsBase < Base
|
796
|
+
include AtomTextConstructBase
|
797
|
+
end
|
798
|
+
|
799
|
+
class DescriptionBase < Base
|
800
|
+
include AtomTextConstructBase
|
801
|
+
end
|
802
|
+
|
803
|
+
class ContentBase < Base
|
804
|
+
include AtomTextConstructBase::EnsureXMLContent
|
805
|
+
|
806
|
+
%w(src).each do |element|
|
807
|
+
attr_accessor(element)
|
808
|
+
add_need_initialize_variable(element)
|
809
|
+
end
|
810
|
+
|
811
|
+
def xml_content=(content)
|
812
|
+
content = ensure_xml_content(content) if inline_xhtml?
|
813
|
+
@xml_content = content
|
814
|
+
end
|
815
|
+
|
816
|
+
alias_method(:xml, :xml_content)
|
817
|
+
alias_method(:xml=, :xml_content=)
|
818
|
+
|
819
|
+
def inline_text?
|
820
|
+
[nil, "text", "html"].include?(@type)
|
821
|
+
end
|
822
|
+
|
823
|
+
def inline_html?
|
824
|
+
@type == "html"
|
825
|
+
end
|
826
|
+
|
827
|
+
def inline_xhtml?
|
828
|
+
@type == "xhtml"
|
829
|
+
end
|
830
|
+
|
831
|
+
def inline_other?
|
832
|
+
!out_of_line? and ![nil, "text", "html", "xhtml"].include?(@type)
|
833
|
+
end
|
834
|
+
|
835
|
+
def inline_other_text?
|
836
|
+
return false if @type.nil? or out_of_line?
|
837
|
+
/\Atext\//i.match(@type) ? true : false
|
838
|
+
end
|
839
|
+
|
840
|
+
def inline_other_xml?
|
841
|
+
return false if @type.nil? or out_of_line?
|
842
|
+
/[\+\/]xml\z/i.match(@type) ? true : false
|
843
|
+
end
|
844
|
+
|
845
|
+
def inline_other_base64?
|
846
|
+
return false if @type.nil? or out_of_line?
|
847
|
+
@type.include?("/") and !inline_other_text? and !inline_other_xml?
|
848
|
+
end
|
849
|
+
|
850
|
+
def out_of_line?
|
851
|
+
not @src.nil? and @content.nil?
|
852
|
+
end
|
853
|
+
end
|
854
|
+
|
855
|
+
class TitleBase < Base
|
856
|
+
include AtomTextConstructBase
|
857
|
+
end
|
858
|
+
end
|
859
|
+
end
|
860
|
+
|
861
|
+
class TextinputBase < Base
|
862
|
+
%w(title description name link).each do |element|
|
863
|
+
attr_accessor element
|
864
|
+
add_need_initialize_variable(element)
|
865
|
+
end
|
866
|
+
end
|
867
|
+
end
|
868
|
+
end
|