views:

174

answers:

2

Hi, trying to get my head around Feedzirra here.

I have it all setup and everything, and can even get results and updates, but something odd is going on.

I came up with the following code:

  def initialize(feed_url)
    @feed_url = feed_url
    @rssObject =  Feedzirra::Feed.fetch_and_parse(@feed_url)
  end

  def update_from_feed_continuously()    
    @rssObject = Feedzirra::Feed.update(@rssObject)
    if @rssObject.updated?
      puts @rssObject.new_entries.count
    else
      puts "nil"
    end
  end

Right, what I'm doing above, is starting with the big feed, and then only getting updates. I'm sure I must be doing something stupid, as even though I'm able to get the updates, and store them on the same instance variable, after the first time, I'm never able to get those again.

Obviously this happens because I'm overwriting my instance variable with only updates, and lose the full feed object.

I then thought about changing my code to this:

  def update_from_feed_continuously()    
    feed = Feedzirra::Feed.update(@rssObject)
    if feed.updated?
      puts feed.new_entries.count
    else
      puts "nil"
    end
  end

Well, I'm not overwriting anything and that should be the way to go right?

WRONG, this means I'm doomed to always try to get updates to the same static feed object, as although I get the updates on a variable, I'm never actually updating my "static feed object", and newly added items will be appended to my "feed.new_entries" as they in theory are new.

I'm sure I;m missing a step here, but I'd really appreciate if someone could shed me a light on it. I've been going through this code for hours, and can't get to grips with it.

Obviously it should work fine, if I did something like:

if feed.updated?
  puts feed.new_entries.count
  @rssObject = initialize(@feed_url)
else

Because that would reinitialize my instance variable with a brand new feed object, and the updates would come again.

But that also means that any new update added on that exact moment would be lost, as well as massive overkill, as I'd have to load the thing again.

Thanks in advance!

A: 

You can reset @rssObject to the updated feed.

feed = Feedzirra::Feed.update(@rssObject)
if feed.updated?
  puts feed.new_entries.count
  @rssObject = feed
else
  puts 'nil'
end

The number of entries in @rssObject will keep growing as new entries are found. So if the first fetch finds 10 entries, and then next finds 10 new entries, @rssObject.entries.size will be 20.

Note that you can do this regardless of whether update finds new entries. If feed.updated? is false, feed will be the original feed object, @rssObject.

benm
+1  A: 

How to do updates is a bit counterintuitive with the current API. This example shows the best way to do it:

# I'm using Atom here, but it could be anything. You don't need to know ahead of time.
# It will parse out to the correct format when it updates.
feed_to_update = Feedzirra::Parser::Atom.new
feed_to_update.feed_url = some_stored_feed_url
feed_to_update.etag = some_stored_feed_etag
feed_to_update.last_modified = some_stored_feed_last_modified

last_entry = Feedzirra::Parser::AtomEntry.new
last_entry.url = the_url_of_the_last_entry_for_a_feed

feed_to_update.entries = [last_entry]

updated_feed = Feedzirra::Feed.update(feed_to_update)

updated_feed.updated? # => nil if there is nothing new
updated_feed.new_entries # => [] if nothing new otherwise a collection of feedzirra entries
updated_feed.etag # => same as before if nothing new. although could change with comments added to entries.
updated_feed.last_modified # => same as before if nothing new. although could change with comments added to entries.

Basically, you'll have to save off four pieces of data (feed_url, last_modified, etag, and the url of the most recent entry). Then when you want to do updates you construct a new feed object and call update on that.

Paul Dix
Could you just save the updated_feed marshalled in your db as opposed to rebuilding it each time?
Nader