add private rss feeds for logged-out users by passing a token

create a random rss_token for each user and append it to the rss
urls.  when adding the user-specific feed url to a feed reader, the
user's tag filters will be applied before generating the rss view,
giving the same list of stories that the user sees while logged in.
This commit is contained in:
joshua stein 2012-09-18 10:38:03 -05:00
parent 7c8db7269d
commit b2315a5728
4 changed files with 45 additions and 6 deletions

View file

@ -1,19 +1,29 @@
class HomeController < ApplicationController
STORIES_PER_PAGE = 25
# for rss feeds, load the user's tag filters if a token is passed
before_filter :find_user_from_rss_token, :only => [ :index, :newest ]
def index
@stories = find_stories_for_user_and_tag_and_newest_and_by_user(@user,
nil, false, nil)
@rss_link ||= "<link rel=\"alternate\" type=\"application/rss+xml\" " <<
"title=\"RSS 2.0\" href=\"/rss\" />"
"title=\"RSS 2.0\" href=\"/rss" <<
(@user ? "?token=#{@user.rss_token}" : "") << "\" />"
@heading = @title = ""
@cur_url = "/"
respond_to do |format|
format.html { render :action => "index" }
format.rss { render :action => "rss", :layout => false }
format.rss {
if @user && params[:token].present?
@title = "Private feed for #{@user.username}"
end
render :action => "rss", :layout => false
}
end
end
@ -25,13 +35,20 @@ class HomeController < ApplicationController
@cur_url = "/newest"
@rss_link = "<link rel=\"alternate\" type=\"application/rss+xml\" " <<
"title=\"RSS 2.0 - Newest Items\" href=\"/newest.rss\" />"
"title=\"RSS 2.0 - Newest Items\" href=\"/newest.rss" <<
(@user ? "?token=#{@user.rss_token}" : "") << "\" />"
@newest = true
respond_to do |format|
format.html { render :action => "index" }
format.rss { render :action => "rss", :layout => false }
format.rss {
if @user && params[:token].present?
@title += " - Private feed for #{@user.username}"
end
render :action => "rss", :layout => false
}
end
end
@ -168,4 +185,10 @@ private
[ stories, show_more ]
end
def find_user_from_rss_token
if !@user && request[:format] == "rss" && params[:token].to_s.present?
@user = User.find_by_rss_token(params[:token])
end
end
end

View file

@ -28,7 +28,7 @@ class User < ActiveRecord::Base
:pushover_mentions
before_save :check_session_token
after_create :create_default_tag_filters
after_create :create_default_tag_filters, :create_rss_token
def check_session_token
if self.session_token.blank?
@ -45,6 +45,12 @@ class User < ActiveRecord::Base
end
end
def create_rss_token
if self.rss_token.blank?
self.rss_token = Utils.random_str(60)
end
end
def unread_message_count
Keystore.value_for("user:#{self.id}:unread_messages").to_i
end

View file

@ -0,0 +1,9 @@
class PrivateRssFeed < ActiveRecord::Migration
def up
add_column :users, :rss_token, :string
end
def down
remove_column :users, :rss_token
end
end

View file

@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20120910172514) do
ActiveRecord::Schema.define(:version => 20120918152116) do
create_table "comments", :force => true do |t|
t.datetime "created_at", :null => false
@ -139,6 +139,7 @@ ActiveRecord::Schema.define(:version => 20120910172514) do
t.boolean "is_moderator", :default => false
t.boolean "email_mentions", :default => false
t.boolean "pushover_mentions", :default => false
t.string "rss_token"
end
add_index "users", ["session_token"], :name => "session_hash", :unique => true