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 @@
+
+ <% @feeds.each do |feed| %>
+ - <%= link_to feed.title, feed_path(feed) %>
+ <% end %>
+
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:
-
-
- -
-
Use rails generate
to create your models and controllers
- To see all available options, run it without parameters.
-
-
- -
-
Set up a default route and remove public/index.html
- Routes are set up in config/routes.rb.
-
-
- -
-
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.
-
-
-
-
-
-
-
-
-