使用FeedJira创建RSS聚合器/阅读器

时间:2014-08-11 02:21:05

标签: ruby-on-rails web-applications rss rss-reader

我正在尝试在rails上的ruby中创建自己的rss阅读器应用程序。我希望能够在我的数据库中存储各种新闻故事,我可以从以后开始以一个漂亮的布局显示每个故事的标题,图像,摘要等。我正在使用feedjira库,我也是RoR的新手。我知道rails控制台中的这两个命令会获取rss feed并以某种方式解析它们:

urls = %w[http://feedjira.com/blog/feed.xml https://github.com/feedjira/feedjira/feed.xml]
feeds = Feedjira::Feed.fetch_and_parse urls

虽然这两个命令适用于rss feed,但我想知道如何配置我的数据库/模型,然后将我从Feedjira获取的新闻条目保存到数据库中。我试着在这个问题上看看有轨电视,但它看起来有点过时了。对此问题的任何帮助都将非常感谢!提前谢谢!

2 个答案:

答案 0 :(得分:2)

以这种方式:

创建如下模型:

class Entry < ActiveRecord::Base

  attr_accessible :guid, :source_site_id, :url, :title, :summary, :description, :published_at

  def self.update_from_feed(feed_name)
    feed = Feed.find_by_name(feed_name)
    feed_data = Feedjira::Feed.fetch_and_parse(feed.feed_url)
    add_entries(feed_data.entries, feed)
  end

  private
  def self.add_entries(entries, feed)
    entries.each do |entry|
      break if exists? :entry_id => entry.id

        create!(
            :entry_id     => entry.id,
            :feed_id      => feed.id,
            :url          => entry.url,
            :title        => entry.title.sanitize,
            :summary      => entry.summary.sanitize,
            :description  => entry.content.sanitize,
            :published_at => entry.published
        )

      end
    end
  end
end

然后你可以从cli / cron或其他任何地方调用它,例如:

rails runner -e development 'Entry.update_from_feed("feedname")'

这使用单独的rails实例(有点像rails console)在Rails应用程序的上下文中运行update_from_feed方法,但不会影响正在运行的Rails实例。

在这个示例中,有一个单独的模型,其中包含name和feed_urls,因此可以根据提供的名称查找url。

此代码不使用Feedjira检查更新的功能,因此可以使用dupe检查。 (This guthub issue表示要避免使用#update方法。

请注意,使用break会假定新条目始终添加到Feed的顶部。如果您不信任Feed,请将break if替换为unless。该网址可用作替代唯一ID。

编辑:

这是update_from_feed方法的一个版本,它利用了Feedjira处理多个Feed的能力:

def self.update_all
  feed_urls = Feed.pluck :feed_url
  feeds = Feedjira::Feed.fetch_and_parse(feed_urls)

  feed_urls.each do |feed_url|
    feed = Feed.find_by_feed_url(feed_url)
    add_entries(feeds[feed_url].entries, feed)
  end
end

pluck返回数组中指定列(在本例中为:feed_url)的所有行。同样,您可以将其更改为接受一组名称,从中查找要传递给feedjira的URL数组。

最后,如果你想要一个自循环方法,你可以包括:

def self.update_all_periodically(frequency = 15.minutes)
  loop do
    update_all_from_feed
    sleep frequency.to_i
  end
end

然后这个:

rails runner -e development 'Feed.update_all_periodically'

在您中断此过程之前不会返回,并会以默认频率或指定为可选参数的所有Feed更新。

如果您想在主Rails进程中异步运行更新,那么后台工作程序(如Sidekiq,Resque或DelayedJob)将执行...作业。 :)

答案 1 :(得分:0)

调度提取和解析这些提要可能非常困难和耗时,这意味着你绝对不能从Rails应用程序本身内部做到这一点。充其量,您应该使用“离线”脚本。

您还可以简单地依赖现有的API,例如Superfeedr及其rack middleware