From 249dd85ec3e0d36f6d87de4f4d424060142d01ba Mon Sep 17 00:00:00 2001
From: joshua stein
Date: Mon, 5 Aug 2013 02:16:33 -0500
Subject: [PATCH] allow non-logged-in users to define tag filters
when not logged in, store the filters in a long-lasting cookie and
do not cache the home page
for that one guy on hacker news that complained about lobste.rs not
having this
---
app/controllers/application_controller.rb | 8 +++++
app/controllers/filters_controller.rb | 44 ++++++++++++++---------
app/controllers/home_controller.rb | 8 +++--
app/models/tag.rb | 2 +-
app/views/filters/index.html.erb | 8 +++++
app/views/layouts/application.html.erb | 5 ++-
6 files changed, 52 insertions(+), 23 deletions(-)
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 6389191..ac763bb 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -5,6 +5,8 @@ class ApplicationController < ActionController::Base
TRAFFIC_DECREMENTER = 0.15
+ TAG_FILTER_COOKIE = :tag_filters
+
def authenticate_user
if session[:u]
@user = User.find_by_session_token(session[:u].to_s)
@@ -55,6 +57,12 @@ class ApplicationController < ActionController::Base
end
end
+ @_tags_filtered = nil
+ def tags_filtered_by_cookie
+ @_tags_filtered ||= cookies[TAG_FILTER_COOKIE].to_s.split(",").map{|t|
+ Tag.find_by_tag(t) }.reject{|tf| !tf }
+ end
+
def user_is_spider?
!!request.env["HTTP_USER_AGENT"].to_s.match(/Googlebot/)
end
diff --git a/app/controllers/filters_controller.rb b/app/controllers/filters_controller.rb
index b81d3d7..cb5939b 100644
--- a/app/controllers/filters_controller.rb
+++ b/app/controllers/filters_controller.rb
@@ -1,11 +1,19 @@
class FiltersController < ApplicationController
- before_filter :require_logged_in_user
+ before_filter :authenticate_user
def index
@cur_url = "/filters"
@title = "Filtered Tags"
- @filtered_tags = @user.tag_filters.reload
+ if @user
+ @filtered_tags = @user.tag_filters.reload
+ else
+ @filtered_tags = tags_filtered_by_cookie.map{|t|
+ tf = TagFilter.new
+ tf.tag = t
+ tf
+ }
+ end
render :action => "index"
end
@@ -20,22 +28,26 @@ class FiltersController < ApplicationController
end
end
- @user.tag_filters(:include => :tag).each do |tf|
- if tf.tag && new_filters.include?(tf.tag.tag)
- new_filters.reject!{|t| t == tf.tag.tag }
- else
- tf.destroy
+ if @user
+ @user.tag_filters(:include => :tag).each do |tf|
+ if tf.tag && new_filters.include?(tf.tag.tag)
+ new_filters.reject!{|t| t == tf.tag.tag }
+ else
+ tf.destroy
+ end
end
+
+ new_filters.each do |t|
+ tf = TagFilter.new
+ tf.user_id = @user.id
+ tf.tag_id = Tag.find_by_tag(t).id
+ tf.save!
+ end
+ else
+ cookies.permanent[TAG_FILTER_COOKIE] = new_filters.join(",")
end
- new_filters.each do |t|
- tf = TagFilter.new
- tf.user_id = @user.id
- tf.tag_id = Tag.find_by_tag(t).id
- tf.save
- end
-
- flash.now[:success] = "Your filters have been updated."
- index
+ flash[:success] = "Your filters have been updated."
+ return redirect_to "/filters"
end
end
diff --git a/app/controllers/home_controller.rb b/app/controllers/home_controller.rb
index d6ee903..c4b3c20 100644
--- a/app/controllers/home_controller.rb
+++ b/app/controllers/home_controller.rb
@@ -96,8 +96,9 @@ private
@page = params[:page].to_i
end
- # guest views have caching, but don't bother for logged-in users (or dev)
- if Rails.env == "development" || user
+ # guest views have caching, but don't bother for logged-in users or dev or
+ # when the user has tag filters
+ if Rails.env == "development" || user || tags_filtered_by_cookie.any?
stories, @show_more =
_find_stories_for_user_and_tag_and_newest_and_by_user(user, tag,
newest, by_user)
@@ -129,7 +130,8 @@ private
filtered_tag_ids = @user.tag_filters.map{|tf| tf.tag_id }
else
# for logged-out users, filter defaults
- filtered_tag_ids = Tag.where(:filtered_by_default => true).map{|t| t.id }
+ filtered_tag_ids = Tag.where(:filtered_by_default => true).
+ map{|t| t.id } + tags_filtered_by_cookie.map{|t| t.id }
end
if tag
diff --git a/app/models/tag.rb b/app/models/tag.rb
index 1410616..3bc36d7 100644
--- a/app/models/tag.rb
+++ b/app/models/tag.rb
@@ -5,7 +5,7 @@ class Tag < ActiveRecord::Base
attr_accessor :filtered_count
scope :accessible_to, ->(user) do
- user.is_admin?? all : where(:privileged => false)
+ user && user.is_admin?? all : where(:privileged => false)
end
def self.all_with_filtered_counts_for(user)
diff --git a/app/views/filters/index.html.erb b/app/views/filters/index.html.erb
index c730680..f867a0c 100644
--- a/app/views/filters/index.html.erb
+++ b/app/views/filters/index.html.erb
@@ -8,6 +8,14 @@
check them below.
+ <% if !@user %>
+
+ Since you are not logged in, your filters will be stored in a long-lasting
+ browser cookie. To permanently store your tag filters and have them work
+ across browsers, login to your account.
+
+ <% end %>
+
<%= form_tag "/filters", :method => :post do %>
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index d26fd12..2354a93 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -66,10 +66,9 @@