2010-03-20 3 views
1

пытаясь окунуться в Feedzirra здесь.Ruby - Feedzirra и обновления

У меня есть все настройки и все, и вы можете даже получить результаты и обновления, но что-то странное происходит.

я придумал следующий код:

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 

Правильно, что я делаю выше, начиная с большой подачей, а затем только получать обновления. Я уверен, что я должен делать что-то глупое, так как хотя я могу получать обновления и хранить их в одной и той же переменной экземпляра, я впервые не смогу их получить.

Очевидно, это происходит из-за того, что я переписываю свою переменную экземпляра только с обновлениями и теряю весь объект фида.

Я тогда думал об изменении кода для этого:

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

Ну, я не перезаписать что-нибудь, и это должно быть путь правильно?

НЕПРАВИЛЬНО, это означает, что я обречен всегда стараюсь, чтобы получить обновления на тот же статический объект подачи, так как хотя я получаю обновление на переменном, я никогда на самом деле обновление моего «статический объект подачи», и новые добавленные элементы будут добавлены к моим «feed.new_entries», поскольку они в теории являются новыми.

Я уверен, что я пропустил здесь шаг, но я был бы очень признателен, если бы кто-то мог пролить свет на него. Я проработал этот код часами и не могу справиться с этим.

Очевидно, что это должно работать нормально, если я сделал что-то вроде:

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

Потому что это переинициализировать мою переменную экземпляра с совершенно новым объектом подачи, и обновления будут приходить снова.

Но это также означает, что любое новое обновление, добавленное в тот момент, будет потеряно, а также массивный overkill, так как мне придется снова загрузить вещь.

Заранее благодарен!

+0

Как часто вы повторить попытку фид? Если вы получите его в первый раз, а затем посмотрите еще раз, вы не увидите никаких изменений, если фид не обновился в то время, заставив меня подумать, что вы видите правильное поведение. Что-то еще, чтобы рассмотреть потенциальную проблему хранения информации в памяти и повторного использования переменной. Если ваш код умирает, вы теряете состояние и вам придется перезагружать все каналы, которые вы отслеживаете целиком. Это может быть очень дорогостоящим, если вы отслеживаете 1000 каналов. Для одного канала это не большая часть сделки, но для большого числа вам нужна база данных для отслеживания состояний. –

ответ

6

Как сделать обновления, это немного несовместимо с текущим API.Этот пример показывает, что лучший способ сделать это:

# 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. 

В принципе, вы должны будете спасти от четырех элементов данных (FEED_URL, LAST_MODIFIED, ETAG, и URL-адрес самой последней записи). Затем, когда вы хотите делать обновления, вы создаете новый объект фида и вызываете обновление на .

+0

Не могли бы вы сохранить обновленный файл в вашем db, а не перестраивать его каждый раз? – Nader

0

Вы можете установить @rssObject в обновленный канал.

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

Число записей в @rssObject будет увеличиваться по мере поступления новых записей. Итак, если первая выборка находит 10 записей, а затем находит 10 новых записей, то @rssObject.entries.size будет 20.

Обратите внимание, что вы можете сделать это независимо от того, находит ли update новые записи. Если feed.updated? является ложным, feed будет оригинальным объектом подачи, @rssObject.

4

Я думаю, что более очевидным решением было бы добавить :if_modified_since вариант fetch_and_parse метода класса Feed см https://github.com/pauldix/feedzirra/blob/master/lib/feedzirra/feed.rb#L116 и https://github.com/pauldix/feedzirra/blob/master/lib/feedzirra/feed.rb#L206

+0

Определенно это намного лучше и элегантно, чем принятый ответ – roody