Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #12 from shelr/comments_feed

add atom feed for comments on record and dashboard
  • Loading branch information...
commit 4cb399ba18f155fc1cf3d9417e380e1764420078 2 parents 949c71b + 6130c62
@antono antono authored
View
33 app/controllers/home_controller.rb
@@ -1,5 +1,5 @@
class HomeController < ApplicationController
- respond_to :html, :xml
+ respond_to :html, :xml, :atom
def landing
if logged_in? && current_user.comments_for_records.any?
@@ -15,10 +15,35 @@ def opensearch
end
def dashboard
- if logged_in?
- @comments = CommentDecorator.decorate(current_user.comments_for_records(params[:page]))
+ # format atom
+ if request.format == 'atom'
+ # key present => find user by key
+ if params[:key].present?
+ @user = User.where(atom_key: params[:key]).first
+
+ # user with given key found => render atom bulilder
+ if @user.present?
+ @comments = CommentDecorator.decorate(@user.comments_for_records.reverse)
+ # user with given key not found => render blank body
+ else
+ render text: ''
+ end
+ # no key => render blank body
+ else
+ render text: ''
+ end
+ # format html
else
- redirect_to records_path
+ # user logged in => render fetch comments, render dashboard
+ if logged_in?
+ page = params[:page] || 1
+ comments = current_user.comments_for_records
+ comments = Kaminari.paginate_array(comments).page(page).per(20)
+ @comments = CommentDecorator.decorate(comments)
+ # user not logged in => redirect to records
+ else
+ redirect_to records_path
+ end
end
end
end
View
4 app/helpers/application_helper.rb
@@ -10,4 +10,8 @@ def controller_and_action_class_names
def active_if(regex)
'active' if request.env['PATH_INFO'] =~ regex
end
+
+ def comment_url(comment)
+ record_url(comment.model.commentable, anchor: dom_id(comment))
+ end
end
View
20 app/models/user.rb
@@ -1,4 +1,5 @@
require 'digest/md5'
+require 'securerandom'
class User
@@ -17,6 +18,7 @@ class User
field :google_oauth2_uid, type: String, unique: true, allow_nil: true
field :open_id_name, type: String, unique: false
field :open_id_uid, type: String, unique: true, allow_nil: true
+ field :atom_key, type: String, unique: true, allow_nil: true
field :website, type: String
field :bitcoin, type: String
field :about, type: String
@@ -56,9 +58,23 @@ def maybe_assign_nickname_placeholder
self.nickname = 'noname' if nickname.blank?
end
- def comments_for_records(page = 1)
+ def comments_for_records
comments = records.map(&:comments).flatten.compact.sort! { |a, b| b.updated_at <=> a.updated_at }
- Kaminari.paginate_array(comments).page(page).per(20)
end
+ def atom_key
+ if read_attribute(:atom_key).blank?
+ hex_size = 16
+ _atom_key = SecureRandom.hex(hex_size)
+
+ while User.where(atom_key: _atom_key).present?
+ _atom_key = SecureRandom.hex(hex_size)
+ end
+
+ self.atom_key = _atom_key
+ save
+ end
+
+ read_attribute(:atom_key)
+ end
end
View
20 app/views/home/dashboard.atom.builder
@@ -0,0 +1,20 @@
+atom_feed :language => 'en-US' do |feed|
+ feed.title "Shelr.tv - new activity for #{@user.nickname}"
+ feed.updated @comments.last.updated_at
+
+ @comments.each do |comment|
+ feed.entry(comment) do |entry|
+ entry.url comment_url(comment)
+ entry.title "Comment from #{comment.user.nickname} for \"#{comment.commentable.title}\""
+ entry.content comment.body, :type => 'html'
+
+ # the strftime is needed to work with Google Reader.
+ entry.updated(comment.updated_at.strftime("%Y-%m-%dT%H:%M:%SZ"))
+
+ entry.author do |author|
+ author.name comment.user.nickname
+ author.url user_url(comment.user)
+ end
+ end
+ end
+end
View
4 app/views/layouts/application.html.haml
@@ -12,6 +12,10 @@
= javascript_include_tag 'application'
= csrf_meta_tag
= auto_discovery_link_tag :atom, "/records.atom", title: 'Shelr.tv - new records'
+ - if logged_in?
+ = auto_discovery_link_tag :atom,
+ dashboard_url(key: current_user.atom_key, format: :atom),
+ title: "Shelr.tv - new activity for #{current_user.nickname}"
= yield :head
= yield :meta
View
20 app/views/records/show.atom.builder
@@ -0,0 +1,20 @@
+atom_feed :language => 'en-US' do |feed|
+ feed.title "Shelr.tv - new comments for \"#{@record.title}\""
+ feed.updated @record.comments.last.updated_at
+
+ @record.comments.each do |comment|
+ feed.entry(comment) do |entry|
+ entry.url comment_url(comment)
+ entry.title "Comment from #{comment.user.nickname}"
+ entry.content comment.body, :type => 'html'
+
+ # the strftime is needed to work with Google Reader.
+ entry.updated(comment.updated_at.strftime("%Y-%m-%dT%H:%M:%SZ"))
+
+ entry.author do |author|
+ author.name comment.user.nickname
+ author.url user_url(comment.user)
+ end
+ end
+ end
+end
View
3  app/views/records/show.html.haml
@@ -1,3 +1,6 @@
+- content_for :head do
+ = auto_discovery_link_tag(:atom, record_url(@record, format: :atom), {:title => "Shelr.tv - new comments for \"#{@record.title}\""})
+
- content_for :title do
= @record.title
View
47 spec/controllers/home_controller_spec.rb
@@ -15,4 +15,51 @@
assigns(:records).should_not be_blank
end
end
+
+ describe 'GET dashboard' do
+ let(:user) { build(:user) }
+
+ context 'when format is html' do
+ before { subject.stub(:current_user).and_return(user) }
+
+ it 'should fetch all comments' do
+ comments = []
+ user.should_receive(:comments_for_records).and_return(comments)
+ get :dashboard
+ end
+
+ it 'should paginate comments' do
+ comments = []
+ paginated_comments = []
+ paginated_comments.stub_chain(:page, :per)
+ user.should_receive(:comments_for_records).and_return(comments)
+ Kaminari.should_receive(:paginate_array).with(comments).and_return(paginated_comments)
+ get :dashboard
+ end
+ end
+
+ context 'when format is atom' do
+ it 'should render blank body if no key is specified' do
+ get :dashboard, format: 'atom'
+ response.body.should be_blank
+ end
+
+ it 'should render blank body if no user with specified key' do
+ get :dashboard, format: 'atom', key: 'some_non_existing_key'
+ response.body.should be_blank
+ end
+
+ it 'should assign comments for user' do
+ record = create(:record, user: user)
+ 2.times { create(:comment, commentable: record) }
+ get :dashboard, format: 'atom', key: user.atom_key
+ assigns(:comments).should have(2).item
+ end
+
+ it 'should assign user' do
+ get :dashboard, format: 'atom', key: user.atom_key
+ assigns(:user).should eql(user)
+ end
+ end
+ end
end
View
15 spec/controllers/records_controller_spec.rb
@@ -107,6 +107,21 @@
get :show, id: record.id.to_s, format: 'json'
end
end
+
+ context "when format is atom" do
+ let(:user) { create :user }
+ let(:record) { create :record }
+
+ it "add record to assigns" do
+ get :show, id: record.id.to_s, format: 'atom'
+ assigns[:record].model.should eql(record)
+ end
+
+ it "should render show.atom.builder" do
+ get :show, id: record.id.to_s, format: 'atom'
+ response.should render_template :show
+ end
+ end
end
describe "POST create" do
View
10 spec/models/user_spec.rb
@@ -84,12 +84,12 @@
comments.reverse.should == subject.comments_for_records
end
+ end
- it "should add methods to array for kaminari" do
- commentable = create(:record, user: subject)
- commentable.comments << create(:comment)
- comments = subject.comments_for_records
- comments.should respond_to(:current_page)
+ describe "#atom_key" do
+ it "should generate new key if key does not exists" do
+ subject.atom_key = nil
+ subject.atom_key.should_not be_nil
end
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.