2015-01-09 05:44:27 +08:00
|
|
|
require_dependency 'topic_list_responder'
|
|
|
|
|
2013-02-06 03:16:51 +08:00
|
|
|
class ListController < ApplicationController
|
2015-01-09 05:44:27 +08:00
|
|
|
include TopicListResponder
|
2013-02-06 03:16:51 +08:00
|
|
|
|
2014-01-18 06:52:06 +08:00
|
|
|
skip_before_filter :check_xhr
|
|
|
|
|
2015-09-03 02:25:18 +08:00
|
|
|
before_filter :set_category, only: [
|
2014-01-18 06:52:06 +08:00
|
|
|
# filtered topics lists
|
2015-09-03 02:25:18 +08:00
|
|
|
Discourse.filters.map { |f| :"category_#{f}" },
|
|
|
|
Discourse.filters.map { |f| :"category_none_#{f}" },
|
|
|
|
Discourse.filters.map { |f| :"parent_category_category_#{f}" },
|
|
|
|
Discourse.filters.map { |f| :"parent_category_category_none_#{f}" },
|
2014-02-03 23:08:00 +08:00
|
|
|
# top summaries
|
|
|
|
:category_top,
|
|
|
|
:category_none_top,
|
|
|
|
:parent_category_category_top,
|
2014-01-18 06:52:06 +08:00
|
|
|
# top pages (ie. with a period)
|
2015-09-03 02:25:18 +08:00
|
|
|
TopTopic.periods.map { |p| :"category_top_#{p}" },
|
|
|
|
TopTopic.periods.map { |p| :"category_none_top_#{p}" },
|
|
|
|
TopTopic.periods.map { |p| :"parent_category_category_top_#{p}" },
|
2014-01-18 06:52:06 +08:00
|
|
|
# category feeds
|
|
|
|
:category_feed,
|
|
|
|
].flatten
|
|
|
|
|
2014-01-14 08:02:14 +08:00
|
|
|
before_filter :ensure_logged_in, except: [
|
|
|
|
:topics_by,
|
|
|
|
# anonymous filters
|
2014-01-18 06:52:06 +08:00
|
|
|
Discourse.anonymous_filters,
|
2015-09-03 02:25:18 +08:00
|
|
|
Discourse.anonymous_filters.map { |f| "#{f}_feed" },
|
2014-04-05 01:05:40 +08:00
|
|
|
# anonymous categorized filters
|
2015-09-03 02:25:18 +08:00
|
|
|
Discourse.anonymous_filters.map { |f| :"category_#{f}" },
|
|
|
|
Discourse.anonymous_filters.map { |f| :"category_none_#{f}" },
|
|
|
|
Discourse.anonymous_filters.map { |f| :"parent_category_category_#{f}" },
|
|
|
|
Discourse.anonymous_filters.map { |f| :"parent_category_category_none_#{f}" },
|
2014-04-05 01:05:40 +08:00
|
|
|
# category feeds
|
|
|
|
:category_feed,
|
|
|
|
# top summaries
|
2014-01-18 06:52:06 +08:00
|
|
|
:top,
|
2014-04-05 01:05:40 +08:00
|
|
|
:category_top,
|
|
|
|
:category_none_top,
|
|
|
|
:parent_category_category_top,
|
|
|
|
# top pages (ie. with a period)
|
2015-09-03 02:25:18 +08:00
|
|
|
TopTopic.periods.map { |p| :"top_#{p}" },
|
|
|
|
TopTopic.periods.map { |p| :"category_top_#{p}" },
|
|
|
|
TopTopic.periods.map { |p| :"category_none_top_#{p}" },
|
|
|
|
TopTopic.periods.map { |p| :"parent_category_category_top_#{p}" },
|
2014-01-14 08:02:14 +08:00
|
|
|
].flatten
|
|
|
|
|
2013-02-06 03:16:51 +08:00
|
|
|
# Create our filters
|
2015-09-03 02:25:18 +08:00
|
|
|
Discourse.filters.each do |filter|
|
2014-01-18 06:52:06 +08:00
|
|
|
define_method(filter) do |options = nil|
|
2013-06-20 10:11:14 +08:00
|
|
|
list_opts = build_topic_list_options
|
2014-01-18 06:52:06 +08:00
|
|
|
list_opts.merge!(options) if options
|
2013-08-25 01:38:02 +08:00
|
|
|
user = list_target_user
|
2014-02-11 07:06:20 +08:00
|
|
|
|
|
|
|
if filter == :latest && params[:category].blank?
|
|
|
|
list_opts[:no_definitions] = true
|
|
|
|
end
|
|
|
|
|
2015-09-03 02:25:18 +08:00
|
|
|
if filter.to_s == current_homepage
|
|
|
|
list_opts.merge!(exclude_category_ids: get_excluded_category_ids(list_opts[:category]))
|
|
|
|
end
|
|
|
|
|
2013-08-22 07:18:54 +08:00
|
|
|
list = TopicQuery.new(user, list_opts).public_send("list_#{filter}")
|
2015-02-13 19:34:22 +08:00
|
|
|
list.more_topics_url = construct_url_with(:next, list_opts)
|
|
|
|
list.prev_topics_url = construct_url_with(:prev, list_opts)
|
2013-12-24 07:50:36 +08:00
|
|
|
if Discourse.anonymous_filters.include?(filter)
|
2013-10-12 00:35:12 +08:00
|
|
|
@description = SiteSetting.site_description
|
|
|
|
@rss = filter
|
2014-10-31 02:26:35 +08:00
|
|
|
|
2015-03-30 23:40:44 +08:00
|
|
|
# Note the first is the default and we don't add a title
|
2015-06-09 00:07:35 +08:00
|
|
|
if (filter.to_s != current_homepage) && use_crawler_layout?
|
2015-07-29 21:39:20 +08:00
|
|
|
filter_title = I18n.t("js.filters.#{filter.to_s}.title", count: 0)
|
2014-10-31 02:26:35 +08:00
|
|
|
if list_opts[:category]
|
|
|
|
@title = I18n.t('js.filters.with_category', filter: filter_title, category: Category.find(list_opts[:category]).name)
|
|
|
|
else
|
|
|
|
@title = I18n.t('js.filters.with_topics', filter: filter_title)
|
|
|
|
end
|
|
|
|
end
|
2013-10-12 00:35:12 +08:00
|
|
|
end
|
2014-10-31 02:26:35 +08:00
|
|
|
|
2015-01-09 05:44:27 +08:00
|
|
|
respond_with_list(list)
|
2013-02-07 23:45:24 +08:00
|
|
|
end
|
2014-01-18 06:52:06 +08:00
|
|
|
|
2014-02-03 23:08:00 +08:00
|
|
|
define_method("category_#{filter}") do
|
2015-02-25 23:16:45 +08:00
|
|
|
canonical_url "#{Discourse.base_url}#{@category.url}"
|
2015-09-03 02:25:18 +08:00
|
|
|
self.send(filter, category: @category.id)
|
2014-01-18 06:52:06 +08:00
|
|
|
end
|
|
|
|
|
2014-02-03 23:08:00 +08:00
|
|
|
define_method("category_none_#{filter}") do
|
2015-09-03 02:25:18 +08:00
|
|
|
self.send(filter, category: @category.id, no_subcategories: true)
|
2014-01-18 06:52:06 +08:00
|
|
|
end
|
2014-02-03 23:08:00 +08:00
|
|
|
|
|
|
|
define_method("parent_category_category_#{filter}") do
|
2015-02-25 23:16:45 +08:00
|
|
|
canonical_url "#{Discourse.base_url}#{@category.url}"
|
2015-09-03 02:25:18 +08:00
|
|
|
self.send(filter, category: @category.id)
|
2014-02-03 23:08:00 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
define_method("parent_category_category_none_#{filter}") do
|
2015-09-03 02:25:18 +08:00
|
|
|
self.send(filter, category: @category.id)
|
2013-07-06 04:49:06 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-10-19 21:21:17 +08: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
|
2015-02-13 19:34:22 +08:00
|
|
|
list.more_topics_url = url_for(construct_url_with(:next, list_opts, url_prefix))
|
|
|
|
list.prev_topics_url = url_for(construct_url_with(:prev, list_opts, url_prefix))
|
2015-01-09 05:44:27 +08:00
|
|
|
respond_with_list(list)
|
2013-10-19 21:21:17 +08:00
|
|
|
end
|
2013-08-31 00:32:05 +08:00
|
|
|
end
|
|
|
|
|
2015-09-03 02:25:18 +08:00
|
|
|
def latest_feed
|
|
|
|
discourse_expires_in 1.minute
|
|
|
|
|
|
|
|
@title = "#{SiteSetting.title} - #{I18n.t("rss_description.latest")}"
|
|
|
|
@link = "#{Discourse.base_url}/latest"
|
|
|
|
@atom_link = "#{Discourse.base_url}/latest.rss"
|
|
|
|
@description = I18n.t("rss_description.latest")
|
|
|
|
@topic_list = TopicQuery.new(nil, order: 'created').list_latest
|
|
|
|
|
|
|
|
render 'list', formats: [:rss]
|
|
|
|
end
|
|
|
|
|
2013-02-28 11:36:12 +08:00
|
|
|
def category_feed
|
|
|
|
guardian.ensure_can_see!(@category)
|
2013-10-16 13:39:18 +08:00
|
|
|
discourse_expires_in 1.minute
|
|
|
|
|
|
|
|
@title = @category.name
|
2015-02-05 15:52:28 +08:00
|
|
|
@link = "#{Discourse.base_url}#{@category.url}"
|
|
|
|
@atom_link = "#{Discourse.base_url}#{@category.url}.rss"
|
2015-09-03 02:25:18 +08:00
|
|
|
@description = "#{I18n.t('topics_in_category', category: @category.name)} #{@category.description}"
|
2013-10-16 13:39:18 +08:00
|
|
|
@topic_list = TopicQuery.new.list_new_in_category(@category)
|
2014-01-18 06:52:06 +08:00
|
|
|
|
2013-10-16 13:39:18 +08:00
|
|
|
render 'list', formats: [:rss]
|
2013-02-28 11:36:12 +08:00
|
|
|
end
|
2014-11-25 01:40:33 +08:00
|
|
|
|
2014-08-29 02:34:31 +08:00
|
|
|
def top(options=nil)
|
|
|
|
options ||= {}
|
|
|
|
period = ListController.best_period_for(current_user.try(:previous_visit_at), options[:category])
|
|
|
|
send("top_#{period}", options)
|
2013-12-24 07:50:36 +08:00
|
|
|
end
|
|
|
|
|
2014-02-03 23:08:00 +08:00
|
|
|
def category_top
|
2015-09-03 02:25:18 +08:00
|
|
|
top(category: @category.id)
|
2014-01-18 06:52:06 +08:00
|
|
|
end
|
|
|
|
|
2014-02-03 23:08:00 +08:00
|
|
|
def category_none_top
|
2015-09-03 02:25:18 +08:00
|
|
|
top(category: @category.id, no_subcategories: true)
|
2014-01-18 06:52:06 +08:00
|
|
|
end
|
|
|
|
|
2014-02-03 23:08:00 +08:00
|
|
|
def parent_category_category_top
|
2015-09-03 02:25:18 +08:00
|
|
|
top(category: @category.id)
|
2014-02-03 23:08:00 +08:00
|
|
|
end
|
|
|
|
|
2014-01-14 08:02:14 +08:00
|
|
|
TopTopic.periods.each do |period|
|
2014-01-18 06:52:06 +08: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
|
2015-09-03 02:25:18 +08:00
|
|
|
|
|
|
|
if "top".freeze == current_homepage
|
|
|
|
top_options.merge!(exclude_category_ids: get_excluded_category_ids(top_options[:category]))
|
|
|
|
end
|
|
|
|
|
2014-01-14 08:02:14 +08:00
|
|
|
user = list_target_user
|
2014-05-08 01:04:39 +08:00
|
|
|
list = TopicQuery.new(user, top_options).list_top_for(period)
|
2014-08-29 02:34:31 +08:00
|
|
|
list.for_period = period
|
2015-02-13 19:34:22 +08:00
|
|
|
list.more_topics_url = construct_url_with(:next, top_options)
|
|
|
|
list.prev_topics_url = construct_url_with(:prev, top_options)
|
2014-10-31 02:26:35 +08:00
|
|
|
|
|
|
|
if use_crawler_layout?
|
|
|
|
@title = I18n.t("js.filters.top.#{period}.title")
|
|
|
|
end
|
|
|
|
|
2015-01-09 05:44:27 +08:00
|
|
|
respond_with_list(list)
|
2014-01-14 08:02:14 +08:00
|
|
|
end
|
|
|
|
|
2014-02-03 23:08:00 +08:00
|
|
|
define_method("category_top_#{period}") do
|
2015-09-03 02:25:18 +08:00
|
|
|
self.send("top_#{period}", category: @category.id)
|
2014-01-18 06:52:06 +08:00
|
|
|
end
|
2013-02-06 03:16:51 +08:00
|
|
|
|
2014-02-03 23:08:00 +08:00
|
|
|
define_method("category_none_top_#{period}") do
|
2015-09-03 02:25:18 +08:00
|
|
|
self.send("top_#{period}", category: @category.id, no_subcategories: true)
|
2014-01-18 06:52:06 +08:00
|
|
|
end
|
2014-02-03 23:08:00 +08:00
|
|
|
|
2014-08-29 02:34:31 +08:00
|
|
|
define_method("parent_category_category_top_#{period}") do
|
2015-09-03 02:25:18 +08:00
|
|
|
self.send("top_#{period}", category: @category.id)
|
2014-02-03 23:08:00 +08:00
|
|
|
end
|
2013-12-14 06:18:28 +08:00
|
|
|
end
|
|
|
|
|
2014-01-18 06:52:06 +08:00
|
|
|
protected
|
|
|
|
|
2014-02-03 23:08:00 +08:00
|
|
|
def next_page_params(opts = nil)
|
2014-02-26 01:15:20 +08:00
|
|
|
page_params(opts).merge(page: params[:page].to_i + 1)
|
|
|
|
end
|
|
|
|
|
|
|
|
def prev_page_params(opts = nil)
|
2014-03-04 01:56:37 +08:00
|
|
|
pg = params[:page].to_i
|
|
|
|
if pg > 1
|
|
|
|
page_params(opts).merge(page: pg - 1)
|
|
|
|
else
|
|
|
|
page_params(opts).merge(page: nil)
|
|
|
|
end
|
2014-02-26 01:15:20 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def page_params(opts = nil)
|
2014-02-03 23:08:00 +08:00
|
|
|
opts ||= {}
|
2015-09-03 02:25:18 +08:00
|
|
|
route_params = { format: 'json' }
|
|
|
|
route_params[:category] = @category.slug_for_url if @category
|
2014-03-25 01:36:23 +08:00
|
|
|
route_params[:parent_category] = @category.parent_category.slug_for_url if @category && @category.parent_category
|
2015-09-03 02:25:18 +08:00
|
|
|
route_params[:order] = opts[:order] if opts[:order].present?
|
|
|
|
route_params[:ascending] = opts[:ascending] if opts[:ascending].present?
|
2013-11-15 01:35:18 +08:00
|
|
|
route_params
|
2013-02-06 03:16:51 +08:00
|
|
|
end
|
|
|
|
|
2013-06-20 10:11:14 +08:00
|
|
|
def set_category
|
2014-01-17 11:38:08 +08:00
|
|
|
slug_or_id = params.fetch(:category)
|
|
|
|
parent_slug_or_id = params[:parent_category]
|
2013-10-24 02:40:39 +08:00
|
|
|
|
|
|
|
parent_category_id = nil
|
2014-01-17 22:32:23 +08:00
|
|
|
if parent_slug_or_id.present?
|
2014-02-09 06:10:48 +08:00
|
|
|
parent_category_id = Category.query_parent_category(parent_slug_or_id)
|
2015-05-07 09:00:51 +08:00
|
|
|
raise Discourse::NotFound if parent_category_id.blank?
|
2013-10-24 02:40:39 +08:00
|
|
|
end
|
|
|
|
|
2014-02-09 06:10:48 +08:00
|
|
|
@category = Category.query_category(slug_or_id, parent_category_id)
|
2015-05-07 09:00:51 +08:00
|
|
|
raise Discourse::NotFound if !@category
|
2014-02-09 06:10:48 +08:00
|
|
|
|
2015-08-14 10:00:07 +08:00
|
|
|
@description_meta = @category.description_text
|
2014-02-06 04:33:52 +08:00
|
|
|
guardian.ensure_can_see!(@category)
|
2013-06-20 10:11:14 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def build_topic_list_options
|
2014-01-17 11:38:08 +08:00
|
|
|
options = {
|
2013-06-20 10:11:14 +08:00
|
|
|
page: params[:page],
|
|
|
|
topic_ids: param_to_integer_list(:topic_ids),
|
2015-09-03 02:25:18 +08:00
|
|
|
exclude_category_ids: params[:exclude_category_ids],
|
2013-11-12 08:35:57 +08:00
|
|
|
category: params[:category],
|
2014-04-17 00:05:54 +08:00
|
|
|
order: params[:order],
|
|
|
|
ascending: params[:ascending],
|
2014-06-05 21:30:24 +08:00
|
|
|
min_posts: params[:min_posts],
|
|
|
|
max_posts: params[:max_posts],
|
2014-05-15 22:31:45 +08:00
|
|
|
status: params[:status],
|
2015-01-07 15:20:10 +08:00
|
|
|
filter: params[:filter],
|
2014-07-17 07:29:09 +08:00
|
|
|
state: params[:state],
|
2015-06-22 16:09:08 +08:00
|
|
|
search: params[:search],
|
|
|
|
q: params[:q]
|
2013-06-20 10:11:14 +08:00
|
|
|
}
|
2014-01-17 11:38:08 +08:00
|
|
|
options[:no_subcategories] = true if params[:no_subcategories] == 'true'
|
2014-12-16 00:54:26 +08:00
|
|
|
options[:slow_platform] = true if slow_platform?
|
2014-01-17 11:38:08 +08:00
|
|
|
|
|
|
|
options
|
2013-06-20 10:11:14 +08:00
|
|
|
end
|
2013-08-25 01:38:02 +08: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 21:21:17 +08:00
|
|
|
|
|
|
|
def generate_list_for(action, target_user, opts)
|
2013-11-15 01:35:18 +08:00
|
|
|
TopicQuery.new(current_user, opts).send("list_#{action}", target_user)
|
2013-10-19 21:21:17 +08:00
|
|
|
end
|
|
|
|
|
2015-02-13 19:34:22 +08:00
|
|
|
def construct_url_with(action, opts, url_prefix = nil)
|
2014-02-03 23:08:00 +08:00
|
|
|
method = url_prefix.blank? ? "#{action_name}_path" : "#{url_prefix}_#{action_name}_path"
|
2015-02-13 19:34:22 +08:00
|
|
|
url = if action == :prev
|
|
|
|
public_send(method, opts.merge(prev_page_params(opts)))
|
|
|
|
else # :next
|
|
|
|
public_send(method, opts.merge(next_page_params(opts)))
|
|
|
|
end
|
|
|
|
url.sub('.json?','?')
|
2014-02-26 01:15:20 +08:00
|
|
|
end
|
|
|
|
|
2015-09-03 02:25:18 +08:00
|
|
|
def get_excluded_category_ids(current_category=nil)
|
|
|
|
exclude_category_ids = Category.where(suppress_from_homepage: true)
|
|
|
|
exclude_category_ids = exclude_category_ids.where.not(id: current_category) if current_category
|
|
|
|
exclude_category_ids.pluck(:id)
|
2013-12-24 07:50:36 +08:00
|
|
|
end
|
|
|
|
|
2014-05-14 17:49:50 +08:00
|
|
|
def self.best_period_for(previous_visit_at, category_id=nil)
|
|
|
|
best_periods_for(previous_visit_at).each do |period|
|
|
|
|
top_topics = TopTopic.where("#{period}_score > 0")
|
2015-09-03 02:25:18 +08:00
|
|
|
top_topics = top_topics.joins(:topic).where("topics.category_id = ?", category_id) if category_id
|
2014-05-14 17:49:50 +08:00
|
|
|
return period if top_topics.count >= SiteSetting.topics_per_period_in_top_page
|
2014-05-08 01:04:39 +08:00
|
|
|
end
|
|
|
|
# default period is yearly
|
|
|
|
:yearly
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.best_periods_for(date)
|
2014-01-16 08:36:32 +08:00
|
|
|
date ||= 1.year.ago
|
2014-05-08 01:04:39 +08:00
|
|
|
periods = []
|
2015-09-03 02:25:18 +08:00
|
|
|
periods << :daily if date > 8.days.ago
|
|
|
|
periods << :weekly if date > 35.days.ago
|
2014-05-08 01:04:39 +08:00
|
|
|
periods << :monthly if date > 180.days.ago
|
|
|
|
periods << :yearly
|
|
|
|
periods
|
2014-01-14 08:02:14 +08:00
|
|
|
end
|
|
|
|
|
2013-02-06 03:16:51 +08:00
|
|
|
end
|