1require "rss/maker/atom" 2 3module RSS 4 module Maker 5 module Atom 6 class Feed < RSSBase 7 def initialize(feed_version="1.0") 8 super 9 @feed_type = "atom" 10 @feed_subtype = "feed" 11 end 12 13 private 14 def make_feed 15 ::RSS::Atom::Feed.new(@version, @encoding, @standalone) 16 end 17 18 def setup_elements(feed) 19 setup_channel(feed) 20 setup_image(feed) 21 setup_items(feed) 22 end 23 24 class Channel < ChannelBase 25 include SetupDefaultLanguage 26 27 def to_feed(feed) 28 set_default_values do 29 setup_values(feed) 30 feed.dc_dates.clear 31 setup_other_elements(feed) 32 if image_favicon.about 33 icon = feed.class::Icon.new 34 icon.content = image_favicon.about 35 feed.icon = icon 36 end 37 unless have_required_values? 38 raise NotSetError.new("maker.channel", 39 not_set_required_variables) 40 end 41 end 42 end 43 44 def have_required_values? 45 super and 46 (!authors.empty? or 47 @maker.items.any? {|item| !item.authors.empty?}) 48 end 49 50 private 51 def required_variable_names 52 %w(id updated) 53 end 54 55 def variables 56 super + %w(id updated) 57 end 58 59 def variable_is_set? 60 super or !authors.empty? 61 end 62 63 def not_set_required_variables 64 vars = super 65 if authors.empty? and 66 @maker.items.all? {|item| item.author.to_s.empty?} 67 vars << "author" 68 end 69 vars << "title" unless title {|t| t.have_required_values?} 70 vars 71 end 72 73 def _set_default_values(&block) 74 keep = { 75 :id => id, 76 } 77 self.id ||= about 78 super(&block) 79 ensure 80 self.id = keep[:id] 81 end 82 83 class SkipDays < SkipDaysBase 84 def to_feed(*args) 85 end 86 87 class Day < DayBase 88 end 89 end 90 91 class SkipHours < SkipHoursBase 92 def to_feed(*args) 93 end 94 95 class Hour < HourBase 96 end 97 end 98 99 class Cloud < CloudBase 100 def to_feed(*args) 101 end 102 end 103 104 class Categories < CategoriesBase 105 class Category < CategoryBase 106 include AtomCategory 107 108 def self.not_set_name 109 "maker.channel.category" 110 end 111 end 112 end 113 114 class Links < LinksBase 115 class Link < LinkBase 116 include AtomLink 117 118 def self.not_set_name 119 "maker.channel.link" 120 end 121 end 122 end 123 124 AtomPersons.def_atom_persons(self, "author", "maker.channel.author") 125 AtomPersons.def_atom_persons(self, "contributor", 126 "maker.channel.contributor") 127 128 class Generator < GeneratorBase 129 include AtomGenerator 130 131 def self.not_set_name 132 "maker.channel.generator" 133 end 134 end 135 136 AtomTextConstruct.def_atom_text_construct(self, "rights", 137 "maker.channel.copyright", 138 "Copyright") 139 AtomTextConstruct.def_atom_text_construct(self, "subtitle", 140 "maker.channel.description", 141 "Description") 142 AtomTextConstruct.def_atom_text_construct(self, "title", 143 "maker.channel.title") 144 end 145 146 class Image < ImageBase 147 def to_feed(feed) 148 logo = feed.class::Logo.new 149 class << logo 150 alias_method(:url=, :content=) 151 end 152 set = setup_values(logo) 153 class << logo 154 remove_method(:url=) 155 end 156 if set 157 feed.logo = logo 158 set_parent(logo, feed) 159 setup_other_elements(feed, logo) 160 elsif variable_is_set? 161 raise NotSetError.new("maker.image", not_set_required_variables) 162 end 163 end 164 165 private 166 def required_variable_names 167 %w(url) 168 end 169 end 170 171 class Items < ItemsBase 172 def to_feed(feed) 173 normalize.each do |item| 174 item.to_feed(feed) 175 end 176 setup_other_elements(feed, feed.entries) 177 end 178 179 class Item < ItemBase 180 def to_feed(feed) 181 set_default_values do 182 entry = feed.class::Entry.new 183 set = setup_values(entry) 184 entry.dc_dates.clear 185 setup_other_elements(feed, entry) 186 if set 187 feed.entries << entry 188 set_parent(entry, feed) 189 elsif variable_is_set? 190 raise NotSetError.new("maker.item", not_set_required_variables) 191 end 192 end 193 end 194 195 def have_required_values? 196 set_default_values do 197 super and title {|t| t.have_required_values?} 198 end 199 end 200 201 private 202 def required_variable_names 203 %w(id updated) 204 end 205 206 def variables 207 super + ["updated"] 208 end 209 210 def not_set_required_variables 211 vars = super 212 vars << "title" unless title {|t| t.have_required_values?} 213 vars 214 end 215 216 def _set_default_values(&block) 217 keep = { 218 :id => id, 219 } 220 self.id ||= link 221 super(&block) 222 ensure 223 self.id = keep[:id] 224 end 225 226 class Guid < GuidBase 227 def to_feed(feed, current) 228 end 229 end 230 231 class Enclosure < EnclosureBase 232 def to_feed(feed, current) 233 end 234 end 235 236 class Source < SourceBase 237 def to_feed(feed, current) 238 source = current.class::Source.new 239 setup_values(source) 240 current.source = source 241 set_parent(source, current) 242 setup_other_elements(feed, source) 243 current.source = nil if source.to_s == "<source/>" 244 end 245 246 private 247 def required_variable_names 248 [] 249 end 250 251 def variables 252 super + ["updated"] 253 end 254 255 AtomPersons.def_atom_persons(self, "author", 256 "maker.item.source.author") 257 AtomPersons.def_atom_persons(self, "contributor", 258 "maker.item.source.contributor") 259 260 class Categories < CategoriesBase 261 class Category < CategoryBase 262 include AtomCategory 263 264 def self.not_set_name 265 "maker.item.source.category" 266 end 267 end 268 end 269 270 class Generator < GeneratorBase 271 include AtomGenerator 272 273 def self.not_set_name 274 "maker.item.source.generator" 275 end 276 end 277 278 class Icon < IconBase 279 def to_feed(feed, current) 280 icon = current.class::Icon.new 281 class << icon 282 alias_method(:url=, :content=) 283 end 284 set = setup_values(icon) 285 class << icon 286 remove_method(:url=) 287 end 288 if set 289 current.icon = icon 290 set_parent(icon, current) 291 setup_other_elements(feed, icon) 292 elsif variable_is_set? 293 raise NotSetError.new("maker.item.source.icon", 294 not_set_required_variables) 295 end 296 end 297 298 private 299 def required_variable_names 300 %w(url) 301 end 302 end 303 304 class Links < LinksBase 305 class Link < LinkBase 306 include AtomLink 307 308 def self.not_set_name 309 "maker.item.source.link" 310 end 311 end 312 end 313 314 class Logo < LogoBase 315 include AtomLogo 316 317 def self.not_set_name 318 "maker.item.source.logo" 319 end 320 end 321 322 maker_name_base = "maker.item.source." 323 maker_name = "#{maker_name_base}rights" 324 AtomTextConstruct.def_atom_text_construct(self, "rights", 325 maker_name) 326 maker_name = "#{maker_name_base}subtitle" 327 AtomTextConstruct.def_atom_text_construct(self, "subtitle", 328 maker_name) 329 maker_name = "#{maker_name_base}title" 330 AtomTextConstruct.def_atom_text_construct(self, "title", 331 maker_name) 332 end 333 334 class Categories < CategoriesBase 335 class Category < CategoryBase 336 include AtomCategory 337 338 def self.not_set_name 339 "maker.item.category" 340 end 341 end 342 end 343 344 AtomPersons.def_atom_persons(self, "author", "maker.item.author") 345 AtomPersons.def_atom_persons(self, "contributor", 346 "maker.item.contributor") 347 348 class Links < LinksBase 349 class Link < LinkBase 350 include AtomLink 351 352 def self.not_set_name 353 "maker.item.link" 354 end 355 end 356 end 357 358 AtomTextConstruct.def_atom_text_construct(self, "rights", 359 "maker.item.rights") 360 AtomTextConstruct.def_atom_text_construct(self, "summary", 361 "maker.item.description", 362 "Description") 363 AtomTextConstruct.def_atom_text_construct(self, "title", 364 "maker.item.title") 365 366 class Content < ContentBase 367 def to_feed(feed, current) 368 content = current.class::Content.new 369 if setup_values(content) 370 content.src = nil if content.src and content.content 371 current.content = content 372 set_parent(content, current) 373 setup_other_elements(feed, content) 374 elsif variable_is_set? 375 raise NotSetError.new("maker.item.content", 376 not_set_required_variables) 377 end 378 end 379 380 alias_method(:xml, :xml_content) 381 382 private 383 def required_variable_names 384 if out_of_line? 385 %w(type) 386 elsif xml_type? 387 %w(xml_content) 388 else 389 %w(content) 390 end 391 end 392 393 def variables 394 if out_of_line? 395 super 396 elsif xml_type? 397 super + %w(xml) 398 else 399 super 400 end 401 end 402 403 def xml_type? 404 _type = type 405 return false if _type.nil? 406 _type == "xhtml" or 407 /(?:\+xml|\/xml)$/i =~ _type or 408 %w(text/xml-external-parsed-entity 409 application/xml-external-parsed-entity 410 application/xml-dtd).include?(_type.downcase) 411 end 412 end 413 end 414 end 415 416 class Textinput < TextinputBase 417 end 418 end 419 end 420 421 add_maker("atom", "1.0", Atom::Feed) 422 add_maker("atom:feed", "1.0", Atom::Feed) 423 add_maker("atom1.0", "1.0", Atom::Feed) 424 add_maker("atom1.0:feed", "1.0", Atom::Feed) 425 end 426end 427