discourse/app/controllers/list_controller.rb

199 lines
6.3 KiB
Ruby
Raw Normal View History

2013-02-05 14:16:51 -05:00
class ListController < ApplicationController
2013-12-23 18:50:36 -05:00
before_filter :ensure_logged_in, except: [:latest, :hot, :category, :top, :category_feed, :latest_feed, :hot_feed, :topics_by]
before_filter :set_category, only: [:category, :category_feed]
2013-02-05 14:16:51 -05:00
skip_before_filter :check_xhr
# Create our filters
2013-12-23 18:50:36 -05:00
Discourse.filters.each do |filter|
2013-02-07 10:45:24 -05:00
define_method(filter) do
list_opts = build_topic_list_options
user = list_target_user
list = TopicQuery.new(user, list_opts).public_send("list_#{filter}")
list.more_topics_url = construct_url_with(filter, list_opts)
2013-12-23 18:50:36 -05:00
if Discourse.anonymous_filters.include?(filter)
2013-10-11 12:35:12 -04:00
@description = SiteSetting.site_description
@rss = filter
end
2013-02-05 14:16:51 -05:00
respond(list)
2013-02-07 10:45:24 -05:00
end
2013-02-05 14:16:51 -05:00
end
2013-12-23 18:50:36 -05:00
Discourse.anonymous_filters.each do |filter|
2013-07-05 16:49:06 -04:00
define_method("#{filter}_feed") do
discourse_expires_in 1.minute
@title = "#{filter.capitalize} Topics"
@link = "#{Discourse.base_url}/#{filter}"
@description = I18n.t("rss_description.#{filter}")
@atom_link = "#{Discourse.base_url}/#{filter}.rss"
@topic_list = TopicQuery.new.public_send("list_#{filter}")
2013-12-23 18:50:36 -05:00
render 'list', formats: [:rss]
2013-07-05 16:49:06 -04:00
end
end
[:topics_by, :private_messages, :private_messages_sent, :private_messages_unread].each do |action|
define_method("#{action}") do
list_opts = build_topic_list_options
target_user = fetch_user_from_params
guardian.ensure_can_see_private_messages!(target_user.id) unless action == :topics_by
list = generate_list_for(action.to_s, target_user, list_opts)
url_prefix = "topics" unless action == :topics_by
url = construct_url_with(action, list_opts, url_prefix)
list.more_topics_url = url_for(url)
respond(list)
end
end
2013-02-05 14:16:51 -05:00
def category
2013-12-13 17:18:28 -05:00
category_response
end
def category_none
category_response(no_subcategories: true)
2013-02-05 14:16:51 -05:00
end
def category_feed
guardian.ensure_can_see!(@category)
discourse_expires_in 1.minute
@title = @category.name
@link = "#{Discourse.base_url}/category/#{@category.slug}"
@description = "#{I18n.t('topics_in_category', category: @category.name)} #{@category.description}"
@atom_link = "#{Discourse.base_url}/category/#{@category.slug}.rss"
@topic_list = TopicQuery.new.list_new_in_category(@category)
render 'list', formats: [:rss]
end
def popular_redirect
# We've renamed popular to latest. Use a redirect until we're sure we can
# safely remove this.
redirect_to latest_path, :status => 301
end
2013-12-23 18:50:36 -05:00
def top
top = generate_top_lists
2013-12-23 18:50:36 -05:00
respond_to do |format|
format.html do
@top = top
store_preloaded('top_list', MultiJson.dump(TopListSerializer.new(top, scope: guardian, root: false)))
render 'top'
end
format.json do
render json: MultiJson.dump(TopListSerializer.new(top, scope: guardian, root: false))
end
end
end
2013-02-05 14:16:51 -05:00
protected
2013-12-13 17:18:28 -05:00
def category_response(extra_opts=nil)
list_opts = build_topic_list_options
list_opts.merge!(extra_opts) if extra_opts
query = TopicQuery.new(current_user, list_opts)
list = query.list_latest
list.more_topics_url = construct_url_with(:latest, list_opts)
respond(list)
end
2013-02-05 14:16:51 -05:00
def respond(list)
2013-12-23 18:50:36 -05:00
discourse_expires_in 1.minute
2013-02-05 14:16:51 -05:00
list.draft_key = Draft::NEW_TOPIC
list.draft_sequence = DraftSequence.current(current_user, Draft::NEW_TOPIC)
2013-12-26 18:35:53 -05:00
list.draft = Draft.get(current_user, list.draft_key, list.draft_sequence) if current_user
2013-02-07 10:45:24 -05:00
2013-02-05 14:16:51 -05:00
respond_to do |format|
format.html do
2013-02-07 10:45:24 -05:00
@list = list
2013-02-05 14:16:51 -05:00
store_preloaded('topic_list', MultiJson.dump(TopicListSerializer.new(list, scope: guardian)))
render 'list'
end
format.json do
render_serialized(list, TopicListSerializer)
end
end
end
2013-02-07 10:45:24 -05:00
def next_page_params(opts=nil)
opts = opts || {}
route_params = { format: 'json', page: params[:page].to_i + 1 }
route_params[:sort_order] = opts[:sort_order] if opts[:sort_order].present?
route_params[:sort_descending] = opts[:sort_descending] if opts[:sort_descending].present?
route_params
2013-02-05 14:16:51 -05:00
end
private
def set_category
slug = params.fetch(:category)
2013-10-23 14:40:39 -04:00
parent_slug = params[:parent_category]
parent_category_id = nil
if parent_slug.present?
parent_category_id = Category.where(slug: parent_slug).pluck(:id).first ||
Category.where(id: parent_slug.to_i).pluck(:id).first
raise Discourse::NotFound.new if parent_category_id.blank?
end
@category = Category.where(slug: slug, parent_category_id: parent_category_id).includes(:featured_users).first ||
Category.where(id: slug.to_i, parent_category_id: parent_category_id).includes(:featured_users).first
end
def build_topic_list_options
# html format means we need to parse exclude category (aka filter) from the site options top menu
menu_items = SiteSetting.top_menu_items
menu_item = menu_items.select { |item| item.query_should_exclude_category?(action_name, params[:format]) }.first
# exclude_category = 1. from params / 2. parsed from top menu / 3. nil
2013-12-13 17:18:28 -05:00
result = {
page: params[:page],
topic_ids: param_to_integer_list(:topic_ids),
exclude_category: (params[:exclude_category] || menu_item.try(:filter)),
2013-11-11 19:35:57 -05:00
category: params[:category],
sort_order: params[:sort_order],
2013-12-13 17:18:28 -05:00
sort_descending: params[:sort_descending],
}
2013-12-13 17:18:28 -05:00
result[:no_subcategories] = true if params[:no_subcategories] == 'true'
result
end
def list_target_user
if params[:user_id] && guardian.is_staff?
User.find(params[:user_id].to_i)
else
current_user
end
end
def generate_list_for(action, target_user, opts)
TopicQuery.new(current_user, opts).send("list_#{action}", target_user)
end
def construct_url_with(action, opts, url_prefix=nil)
method = url_prefix.blank? ? "#{action}_path" : "#{url_prefix}_#{action}_path"
public_send(method, opts.merge(next_page_params(opts)))
end
2013-12-23 18:50:36 -05:00
def generate_top_lists
2013-12-23 18:50:36 -05:00
top = {}
topic_ids = Set.new
TopTopic.periods.each do |period|
options = {
per_page: SiteSetting.topics_per_period_in_summary,
except_topic_ids: topic_ids.to_a
}
list = TopicQuery.new(current_user, options).list_top_for(period)
2013-12-23 18:50:36 -05:00
topic_ids.merge(list.topic_ids)
top[period] = list
end
top
end
2013-02-05 14:16:51 -05:00
end