2013-02-05 14:16:51 -05:00
|
|
|
class ListController < ApplicationController
|
|
|
|
|
2014-01-17 17:52:06 -05:00
|
|
|
skip_before_filter :check_xhr
|
|
|
|
|
|
|
|
@@categories = [
|
|
|
|
# filtered topics lists
|
|
|
|
Discourse.filters.map { |f| "#{f}_category".to_sym },
|
|
|
|
Discourse.filters.map { |f| "#{f}_category_none".to_sym },
|
|
|
|
# top summary
|
|
|
|
:top_category,
|
|
|
|
:top_category_none,
|
|
|
|
# top pages (ie. with a period)
|
|
|
|
TopTopic.periods.map { |p| "top_#{p}_category".to_sym },
|
|
|
|
TopTopic.periods.map { |p| "top_#{p}_category_none".to_sym },
|
|
|
|
# category feeds
|
|
|
|
:category_feed,
|
|
|
|
].flatten
|
|
|
|
|
|
|
|
before_filter :set_category, only: @@categories
|
|
|
|
|
2014-01-13 19:02:14 -05:00
|
|
|
before_filter :ensure_logged_in, except: [
|
|
|
|
:topics_by,
|
|
|
|
# anonymous filters
|
2014-01-17 17:52:06 -05:00
|
|
|
Discourse.anonymous_filters,
|
|
|
|
Discourse.anonymous_filters.map { |f| "#{f}_feed".to_sym },
|
|
|
|
# categories
|
|
|
|
@@categories,
|
2014-01-13 19:02:14 -05:00
|
|
|
# top
|
2014-01-17 17:52:06 -05:00
|
|
|
:top,
|
|
|
|
TopTopic.periods.map { |p| "top_#{p}".to_sym }
|
2014-01-13 19:02:14 -05:00
|
|
|
].flatten
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
# Create our filters
|
2013-12-23 18:50:36 -05:00
|
|
|
Discourse.filters.each do |filter|
|
2014-01-17 17:52:06 -05:00
|
|
|
define_method(filter) do |options = nil|
|
2013-06-19 22:11:14 -04:00
|
|
|
list_opts = build_topic_list_options
|
2014-01-17 17:52:06 -05:00
|
|
|
list_opts.merge!(options) if options
|
2013-08-24 13:38:02 -04:00
|
|
|
user = list_target_user
|
2013-08-21 19:18:54 -04:00
|
|
|
list = TopicQuery.new(user, list_opts).public_send("list_#{filter}")
|
2013-10-19 09:21:17 -04:00
|
|
|
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
|
2014-01-17 17:52:06 -05:00
|
|
|
|
|
|
|
define_method("#{filter}_category") do
|
|
|
|
self.send(filter, { category: @category.id })
|
|
|
|
end
|
|
|
|
|
|
|
|
define_method("#{filter}_category_none") do
|
|
|
|
self.send(filter, { category: @category.id, no_subcategories: true })
|
|
|
|
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
|
2013-10-16 01:39:18 -04:00
|
|
|
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"
|
2013-10-22 10:30:25 -04:00
|
|
|
@topic_list = TopicQuery.new.public_send("list_#{filter}")
|
2013-12-23 18:50:36 -05:00
|
|
|
|
2013-10-16 01:39:18 -04:00
|
|
|
render 'list', formats: [:rss]
|
2013-07-05 16:49:06 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-10-19 09:21:17 -04:00
|
|
|
[: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
|
2013-08-30 12:32:05 -04:00
|
|
|
end
|
|
|
|
|
2013-02-27 22:36:12 -05:00
|
|
|
def category_feed
|
|
|
|
guardian.ensure_can_see!(@category)
|
2013-10-16 01:39:18 -04:00
|
|
|
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)
|
2014-01-17 17:52:06 -05:00
|
|
|
|
2013-10-16 01:39:18 -04:00
|
|
|
render 'list', formats: [:rss]
|
2013-02-27 22:36:12 -05:00
|
|
|
end
|
|
|
|
|
2013-03-27 16:17:49 -04:00
|
|
|
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
|
|
|
|
|
2014-01-17 17:52:06 -05:00
|
|
|
def top(options = nil)
|
2014-01-13 19:02:14 -05:00
|
|
|
discourse_expires_in 1.minute
|
|
|
|
|
2014-01-17 17:52:06 -05:00
|
|
|
top_options = build_topic_list_options
|
|
|
|
top_options.merge!(options) if options
|
|
|
|
|
|
|
|
top = generate_top_lists(top_options)
|
2013-12-23 18:50:36 -05:00
|
|
|
|
|
|
|
respond_to do |format|
|
|
|
|
format.html do
|
|
|
|
@top = top
|
2014-01-13 19:02:14 -05:00
|
|
|
store_preloaded('top_lists', MultiJson.dump(TopListSerializer.new(top, scope: guardian, root: false)))
|
2013-12-23 18:50:36 -05:00
|
|
|
render 'top'
|
|
|
|
end
|
|
|
|
format.json do
|
|
|
|
render json: MultiJson.dump(TopListSerializer.new(top, scope: guardian, root: false))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-01-17 17:52:06 -05:00
|
|
|
def top_category
|
|
|
|
options = { category: @category.id }
|
|
|
|
top(options)
|
|
|
|
end
|
|
|
|
|
|
|
|
def top_category_none
|
|
|
|
options = { category: @category.id, no_subcategories: true }
|
|
|
|
top(options)
|
|
|
|
end
|
|
|
|
|
2014-01-13 19:02:14 -05:00
|
|
|
TopTopic.periods.each do |period|
|
2014-01-17 17:52:06 -05:00
|
|
|
define_method("top_#{period}") do |options = nil|
|
|
|
|
top_options = build_topic_list_options
|
|
|
|
top_options.merge!(options) if options
|
|
|
|
top_options[:per_page] = SiteSetting.topics_per_period_in_top_page
|
2014-01-13 19:02:14 -05:00
|
|
|
user = list_target_user
|
2014-01-17 17:52:06 -05:00
|
|
|
list = TopicQuery.new(user, top_options).public_send("list_top_#{period}")
|
|
|
|
list.more_topics_url = construct_url_with(period, top_options, "top")
|
2014-01-13 19:02:14 -05:00
|
|
|
respond(list)
|
|
|
|
end
|
|
|
|
|
2014-01-17 17:52:06 -05:00
|
|
|
define_method("top_#{period}_category") do
|
|
|
|
self.send("top_#{period}", { category: @category.id })
|
|
|
|
end
|
2013-02-05 14:16:51 -05:00
|
|
|
|
2014-01-17 17:52:06 -05:00
|
|
|
define_method("top_#{period}_category_none") do
|
|
|
|
self.send("top_#{period}", { category: @category.id, no_subcategories: true })
|
|
|
|
end
|
2013-12-13 17:18:28 -05:00
|
|
|
end
|
|
|
|
|
2014-01-17 17:52:06 -05:00
|
|
|
protected
|
|
|
|
|
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
|
|
|
|
2013-11-14 12:35:18 -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
|
|
|
|
|
2013-06-19 22:11:14 -04:00
|
|
|
private
|
|
|
|
|
|
|
|
def set_category
|
2014-01-16 22:38:08 -05:00
|
|
|
slug_or_id = params.fetch(:category)
|
|
|
|
parent_slug_or_id = params[:parent_category]
|
2013-10-23 14:40:39 -04:00
|
|
|
|
|
|
|
parent_category_id = nil
|
2014-01-17 09:32:23 -05:00
|
|
|
if parent_slug_or_id.present?
|
2014-01-16 22:38:08 -05:00
|
|
|
parent_category_id = Category.where(slug: parent_slug_or_id).pluck(:id).first ||
|
|
|
|
Category.where(id: parent_slug_or_id.to_i).pluck(:id).first
|
2013-10-23 14:40:39 -04:00
|
|
|
raise Discourse::NotFound.new if parent_category_id.blank?
|
|
|
|
end
|
|
|
|
|
2014-01-16 22:38:08 -05:00
|
|
|
@category = Category.where(slug: slug_or_id, parent_category_id: parent_category_id).includes(:featured_users).first ||
|
|
|
|
Category.where(id: slug_or_id.to_i, parent_category_id: parent_category_id).includes(:featured_users).first
|
2014-01-17 17:52:06 -05:00
|
|
|
|
|
|
|
raise Discourse::NotFound.new if @category.blank?
|
2013-06-19 22:11:14 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def build_topic_list_options
|
|
|
|
menu_items = SiteSetting.top_menu_items
|
2014-01-31 08:36:00 -05:00
|
|
|
menu_item = menu_items.select { |item| item.query_should_exclude_category?(action_name) }.first
|
2014-01-31 11:33:04 -05:00
|
|
|
menu_item = nil if menu_item.try(:filter).try(:parameterize) == params[:category]
|
2013-06-19 22:11:14 -04:00
|
|
|
|
|
|
|
# exclude_category = 1. from params / 2. parsed from top menu / 3. nil
|
2014-01-16 22:38:08 -05:00
|
|
|
options = {
|
2013-06-19 22:11:14 -04:00
|
|
|
page: params[:page],
|
|
|
|
topic_ids: param_to_integer_list(:topic_ids),
|
2013-10-24 06:05:06 -04:00
|
|
|
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],
|
2014-01-12 22:40:21 -05:00
|
|
|
status: params[:status]
|
2013-06-19 22:11:14 -04:00
|
|
|
}
|
2014-01-16 22:38:08 -05:00
|
|
|
options[:no_subcategories] = true if params[:no_subcategories] == 'true'
|
|
|
|
|
|
|
|
options
|
2013-06-19 22:11:14 -04:00
|
|
|
end
|
2013-08-24 13:38:02 -04:00
|
|
|
|
|
|
|
def list_target_user
|
|
|
|
if params[:user_id] && guardian.is_staff?
|
|
|
|
User.find(params[:user_id].to_i)
|
|
|
|
else
|
|
|
|
current_user
|
|
|
|
end
|
|
|
|
end
|
2013-10-19 09:21:17 -04:00
|
|
|
|
|
|
|
def generate_list_for(action, target_user, opts)
|
2013-11-14 12:35:18 -05:00
|
|
|
TopicQuery.new(current_user, opts).send("list_#{action}", target_user)
|
2013-10-19 09:21:17 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def construct_url_with(action, opts, url_prefix=nil)
|
|
|
|
method = url_prefix.blank? ? "#{action}_path" : "#{url_prefix}_#{action}_path"
|
2013-11-14 12:35:18 -05:00
|
|
|
public_send(method, opts.merge(next_page_params(opts)))
|
2013-10-19 09:21:17 -04:00
|
|
|
end
|
2013-12-23 18:50:36 -05:00
|
|
|
|
2014-01-15 18:49:58 -05:00
|
|
|
def generate_top_lists(options)
|
2013-12-23 18:50:36 -05:00
|
|
|
top = {}
|
2014-01-15 18:49:58 -05:00
|
|
|
options[:per_page] = SiteSetting.topics_per_period_in_top_summary
|
2014-01-13 19:02:14 -05:00
|
|
|
topic_query = TopicQuery.new(current_user, options)
|
2014-01-15 15:45:28 -05:00
|
|
|
|
|
|
|
if current_user.present?
|
2014-01-15 19:36:32 -05:00
|
|
|
periods = [best_period_for(current_user.previous_visit_at)]
|
2014-01-15 15:45:28 -05:00
|
|
|
else
|
|
|
|
periods = TopTopic.periods
|
|
|
|
end
|
2014-01-13 19:02:14 -05:00
|
|
|
|
|
|
|
periods.each { |period| top[period] = topic_query.list_top_for(period) }
|
2013-12-23 18:50:36 -05:00
|
|
|
|
|
|
|
top
|
|
|
|
end
|
|
|
|
|
2014-01-15 15:45:28 -05:00
|
|
|
def best_period_for(date)
|
2014-01-15 19:36:32 -05:00
|
|
|
date ||= 1.year.ago
|
2014-01-15 15:45:28 -05:00
|
|
|
return :yearly if date < 180.days.ago
|
|
|
|
return :monthly if date < 35.days.ago
|
|
|
|
return :weekly if date < 8.days.ago
|
|
|
|
:daily
|
2014-01-13 19:02:14 -05:00
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|