From e38a1bee120386ad2b0cdcf00c3756c9a2cf2d8f Mon Sep 17 00:00:00 2001 From: Aaron Mueller Date: Sun, 8 Apr 2012 04:04:37 +0200 Subject: [PATCH] Rudimentary feed fetching and display --- app/controllers/feeds_controller.rb | 9 + app/models/feed.rb | 48 +++- app/models/item.rb | 18 ++ app/views/feeds/index.html.erb | 5 + app/views/feeds/show.html.erb | 7 + app/views/layouts/application.html.erb | 2 + config/routes.rb | 1 + db/migrate/20120407165240_create_items.rb | 2 +- db/migrate/20120407180851_add_error_field.rb | 9 + db/schema.rb | 13 +- public/index.html | 241 ------------------- 11 files changed, 104 insertions(+), 251 deletions(-) create mode 100644 app/views/feeds/index.html.erb create mode 100644 app/views/feeds/show.html.erb create mode 100644 db/migrate/20120407180851_add_error_field.rb delete mode 100644 public/index.html diff --git a/app/controllers/feeds_controller.rb b/app/controllers/feeds_controller.rb index cce59f0..35bc7bb 100644 --- a/app/controllers/feeds_controller.rb +++ b/app/controllers/feeds_controller.rb @@ -1,2 +1,11 @@ class FeedsController < ApplicationController + # Show all feeds + def index + @feeds = Feed.all + end + + # Show a single feed + def show + @items = Feed.find(params[:id]).items + end end diff --git a/app/models/feed.rb b/app/models/feed.rb index 1948d20..24d1203 100644 --- a/app/models/feed.rb +++ b/app/models/feed.rb @@ -1,8 +1,50 @@ +require "pp" class Feed < ActiveRecord::Base - has_many :items + has_many :items validates_uniqueness_of :url - validates_presence_of :title - scope :recent, order(:published, :asc).limit(10) + default_scope where(:has_errors => false) + scope :with_error, unscoped.where(:has_errors => true) + + def fetch! + Feedzirra::Feed.fetch_and_parse(url, + :on_success => lambda do |url, feed| + feed.entries.each do |entry| + unless Item.exists?(:url => entry.url) + entry.sanitize! + items << Item.create_from_feed_entry!(entry) + end + end + by_url(url).update_attribute(:has_errors, false) + end, + :on_failure => lambda do |url, response_code, response_header, response_body| + by_url(url).update_attribute(:has_errors, true) + end + ) + end + + def self.import(url, *params) + Feedzirra::Feed.fetch_and_parse(url, + :on_success => lambda do |url, feed| + Feed.create!(:url => feed.feed_url, :title => feed.title).fetch! + end, + :on_failure => lambda do |url, response_code, response_header, response_body| + if params.first.include?(:force) + Feed.create!(:url => url, :has_errors => true) + end + end + ) + end + + def self.update_all! + Feed.all.each do |feed| + feed.fetch! + end + end + + private + def by_url(feed_url) + Feed.where(:url => feed_url).first + end end diff --git a/app/models/item.rb b/app/models/item.rb index 0561bcd..6eddd62 100644 --- a/app/models/item.rb +++ b/app/models/item.rb @@ -3,4 +3,22 @@ class Item < ActiveRecord::Base validates_presence_of :title, :author, :content validates_uniqueness_of :url + + default_scope order("published_at DESC") + scope :recent, limit(10) + + def self.create_from_feed_entry!(feed_entry) + feed_entry.sanitize! + self.create!( + :title => feed_entry.title, + :url => feed_entry.url, + :author => feed_entry.author, + :published_at => feed_entry.published, + :content => feed_entry.content + ) + end + + def <=>(other) + self.published_at <=> other.published_at + end end diff --git a/app/views/feeds/index.html.erb b/app/views/feeds/index.html.erb new file mode 100644 index 0000000..d0e11f8 --- /dev/null +++ b/app/views/feeds/index.html.erb @@ -0,0 +1,5 @@ + diff --git a/app/views/feeds/show.html.erb b/app/views/feeds/show.html.erb new file mode 100644 index 0000000..e115467 --- /dev/null +++ b/app/views/feeds/show.html.erb @@ -0,0 +1,7 @@ +<% @items.each do |item| %> +
+

<%= raw(item.title) %>

+ <%= time_ago_in_words(item.published_at) %> by <%= item.author %> +

<%= raw(item.content) %>

+
+<% end %> diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 16f791c..17aeb21 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -8,6 +8,8 @@ + + <%= yield %> diff --git a/config/routes.rb b/config/routes.rb index 0a61362..41181a6 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -12,6 +12,7 @@ FeedFu::Application.routes.draw do # Sample resource route (maps HTTP verbs to controller actions automatically): # resources :products + resources :feeds # Sample resource route with options: # resources :products do diff --git a/db/migrate/20120407165240_create_items.rb b/db/migrate/20120407165240_create_items.rb index 08a2068..03b2832 100644 --- a/db/migrate/20120407165240_create_items.rb +++ b/db/migrate/20120407165240_create_items.rb @@ -5,7 +5,7 @@ class CreateItems < ActiveRecord::Migration t.string :url t.string :author t.text :content - t.time :published + t.datetime :published_at t.references :feed diff --git a/db/migrate/20120407180851_add_error_field.rb b/db/migrate/20120407180851_add_error_field.rb new file mode 100644 index 0000000..d1d0cb5 --- /dev/null +++ b/db/migrate/20120407180851_add_error_field.rb @@ -0,0 +1,9 @@ +class AddErrorField < ActiveRecord::Migration + def up + add_column :feeds, :has_errors, :boolean, :default => false + end + + def down + remove_column :feeds, :has_errors + end +end diff --git a/db/schema.rb b/db/schema.rb index 1bc3161..a316a28 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,13 +11,14 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20120407165240) do +ActiveRecord::Schema.define(:version => 20120407180851) do create_table "feeds", :force => true do |t| t.string "url" t.string "title" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.boolean "has_errors", :default => false end create_table "items", :force => true do |t| @@ -25,10 +26,10 @@ ActiveRecord::Schema.define(:version => 20120407165240) do t.string "url" t.string "author" t.text "content" - t.time "published" + t.datetime "published_at" t.integer "feed_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end end diff --git a/public/index.html b/public/index.html deleted file mode 100644 index a1d5099..0000000 --- a/public/index.html +++ /dev/null @@ -1,241 +0,0 @@ - - - - Ruby on Rails: Welcome aboard - - - - -
- - -
- - - - -
-

Getting started

-

Here’s how to get rolling:

- -
    -
  1. -

    Use rails generate to create your models and controllers

    -

    To see all available options, run it without parameters.

    -
  2. - -
  3. -

    Set up a default route and remove public/index.html

    -

    Routes are set up in config/routes.rb.

    -
  4. - -
  5. -

    Create your database

    -

    Run rake db:create to create your database. If you're not using SQLite (the default), edit config/database.yml with your username and password.

    -
  6. -
-
-
- - -
- -