## # Repesents the items published by the firehoser (the feed entries). # They have accessors for the following fields : # - title # - summary # - link # - published # - unique_id # - chunks (long entries might be notified in several chunks) # - chunk (current chunk out of chunks) # # # # cool # cool # tag:pubhubsubbub-example-app,2009:ahhwdWJzdWJodWJidWItZXhhbXBsZS1hcHByDQsSBUVudHJ5GMGOEAw # 2010-03-25T16:57:18Z # # # require 'time' class Link def initialize(node) @node = node end def title @node["title"] end def href @node["href"] end def rel @node["rel"] end def type @node["type"] end end class Author def initialize(node) @node = node end def name if !@name if name = @node.at_xpath("./atom:name", {"atom" => "http://www.w3.org/2005/Atom"}) @name = name.text end end end def uri if !@uri if uri = @node.at_xpath("./atom:uri", {"atom" => "http://www.w3.org/2005/Atom"}) @uri = uri.text end end end def email if !@email if email = @node.at_xpath("./atom:email", {"atom" => "http://www.w3.org/2005/Atom"}) @email = email.text end end end end class Category def initialize(node) @node = node end def term @node["term"] end end class Location def initialize(node) @node = node end def point @point ||= @node.text end def lat @lat ||= point.split().first.to_f end def lon @lon ||= point.split().last.to_f end end class Item def initialize(node) @node = node end def title @title ||= @node.at_xpath("./atom:entry/atom:title", {"atom" => "http://www.w3.org/2005/Atom"}).text end def summary if !@summary if summary = @node.at_xpath("./atom:entry/atom:summary", {"atom" => "http://www.w3.org/2005/Atom"}) @summary = summary.text end end @summary end def content if !@content if content = @node.at_xpath("./atom:entry/atom:content", {"atom" => "http://www.w3.org/2005/Atom"}) @content = content.text end end @content end def unique_id @unique_id ||= @node.at_xpath("./atom:entry/atom:id", {"atom" => "http://www.w3.org/2005/Atom"}).text end def published if !@published if published = @node.at_xpath("./atom:entry/atom:published", {"atom" => "http://www.w3.org/2005/Atom"}).text @published = Time.parse(published) end end @published end def chunks @node["chunks"].to_i end def chunk @node["chunk"].to_i end def links if !@links @links = [] @node.xpath("./atom:entry/atom:link", {"atom" => "http://www.w3.org/2005/Atom"}).each do |node| @links.push(Link.new(node)) end end @links end def authors if !@authors @authors = [] @node.xpath("./atom:entry/atom:author", {"atom" => "http://www.w3.org/2005/Atom"}).each do |node| @authors.push(Author.new(node)) end end @authors end def categories if !@categories @categories = [] @node.xpath("./atom:entry/atom:category", {"atom" => "http://www.w3.org/2005/Atom"}).each do |node| @categories.push(Category.new(node)) end end @categories end def locations if !@locations @locations = [] @node.xpath("./atom:entry/georss:point", {"atom" => "http://www.w3.org/2005/Atom", "georss" => "http://www.georss.org/georss"}).each do |node| @locations.push(Location.new(node)) end end @locations end end ## # Notification : sent every time a feed has been fetched. It has the following methods: # - message_status : a simple message that gives information about the last fetch # - http_status : status of the http response # - feed_url : url of the feed # - next_fetch : Time when the feed will be fetched again (this is purely informative and it might change) # - items : array of new items detected (might be empty) # # # # # # 25002 bytes fetched in 0.73s for 1 new entries. # 2010-03-25T17:06:30+00:00 # PubSubHubBub example app # # # # # cool # cool # tag:pubhubsubbub-example-app,2009:ahhwdWJzdWJodWJidWItZXhhbXBsZS1hcHByDQsSBUVudHJ5GMGOEAw # 2010-03-25T16:57:18Z # # # # great # great # tag:pubhubsubbub-example-app,2009:ahhwdWJzdWJodWJidWItZXhhbXBsZS1hcHByDQsSBUVudHJ5GMGOEAx # 2010-03-25T16:57:19Z # # # # # # class NotificationStanza < Skates::Base::Stanza XMLNS = { "ps" => "http://jabber.org/protocol/pubsub#event", "ps2" => "http://jabber.org/protocol/pubsub", "sf" => "http://superfeedr.com/xmpp-pubsub-ext" } unless defined? XMLNS def next_fetch if !@next_fetch time = @node.at_xpath("./ps:event/sf:status/sf:next_fetch", XMLNS).text @next_fetch = Time.parse(time) end @next_fetch end def http_status @http_status ||= @node.at_xpath("./ps:event/sf:status/sf:http/@code", XMLNS).text.to_i end def feed_url @feed_url ||= @node.at_xpath("./ps:event/sf:status/@feed", XMLNS).text end def message_status @message_status ||= @node.at_xpath("./ps:event/sf:status/sf:http", XMLNS).text end def title @title ||= @node.at_xpath("./ps:event/sf:status/sf:title", XMLNS).text end def entries if !@entries @entries = [] @node.xpath("./ps:event/ps:items/ps2:item", XMLNS).each do |node| @entries.push(Item.new(node)) end end @entries end end