app/controllers/home_controller.rb
class HomeController < ApplicationController
before_action :require_user, only: %i(subscriptions nearby)
def home
if current_user
redirect_to '/dashboard'
else
@projects = Tag.where('term_data.name IN (?)', 'project:featured').first&.nodes
&.sample(3) # random sampling
@title = I18n.t('home_controller.science_community')
render template: 'home/home'
end
end
# route for seeing the front page even if you are logged in
def front
@projects = Tag.where('term_data.name IN (?)', 'project:featured').first&.nodes
&.sample(3) # random sampling
@title = I18n.t('home_controller.environmental_investigation')
render template: 'home/home'
@unpaginated = true
end
# used in front and home methods only
def blog
@notes = Node.where(status: 1, type: 'note')
.includes(:revision, :tag)
.references(:term_data, :node_revisions)
.where('term_data.name = ?', 'blog')
.order('created DESC')
.paginate(page: params[:page], per_page: 8)
end
def dashboard
redirect_to '/research'
end
def dashboard_v2
@title = I18n.t('dashboard._header.dashboard')
# The new dashboard displays the blog and topics list
if current_user
@blog = Tag.find_nodes_by_type('blog', 'note', 1).limit(1).first
# Tags without the blog tag and everything tag to avoid double display
exclude_tids = Tag.where(name: %w(blog everything)).pluck(:tid)
@pagy, @tag_subscriptions = pagy(
TagSelection
.select('tag_selections.tid, term_data.name')
.where(user_id: current_user.id, following: true)
.where.not(tid: exclude_tids)
.joins("INNER JOIN term_data ON tag_selections.tid = term_data.tid")
.order("term_data.activity_timestamp DESC")
)
@trending_tags = trending
render template: 'dashboard_v2/dashboard'
else
redirect_to '/research'
end
end
def research
@note_count = Node.select(%i(created type status))
.where(type: 'note', status: 1, created: Time.now.to_i - 1.weeks.to_i..Time.now.to_i)
.count(:all)
@wiki_count = Revision.select(:timestamp)
.where(timestamp: Time.now.to_i - 1.weeks.to_i..Time.now.to_i)
.size
if current_user
@user_note_count = Node.where(type: 'note', status: 1, uid: current_user.uid).size
@activity, @blog, @notes, @wikis, @revisions, @comments, @answer_comments = activity
render template: 'dashboard/dashboard'
else
@activity, @blog, @notes, @wikis, @revisions, @comments, @answer_comments = activity
render template: 'dashboard/dashboard'
@title = I18n.t('home_controller.community_research')
end
end
private
def activity
blog = Tag.find_nodes_by_type('blog', 'note', 1).first
# remove "classroom" postings; also switch to an EXCEPT operator in sql, see https://github.com/publiclab/plots2/issues/375
hidden_nids = Node.hidden_response_node_ids
notes = Node.where(type: 'note')
.includes(:revision)
.references(:node_revision)
.where('node.nid NOT IN (?)', hidden_nids + [0]) # in case hidden_nids is empty
.order('node_revisions.timestamp DESC')
.page(params[:page])
notes = notes.where('node.nid != (?)', blog.nid) if blog
comments = Comment.joins(:node, :user)
.includes(:node)
.order('timestamp DESC')
.where('timestamp - node.created > ?', 86_400) # don't report edits within 1 day of page creation
.where('node.status = ?', 1)
.page(params[:page])
.group(['title', 'comments.cid']) # ONLY_FULL_GROUP_BY, issue #3120
if logged_in_as(%w(moderator admin))
notes = notes.where('(node.status = 1 OR node.status = 3)')
comments = comments.where('comments.status = 1')
elsif current_user
coauthor_nids = Node.joins(:node_tag)
.joins('LEFT OUTER JOIN term_data ON term_data.tid = community_tags.tid')
.select('node.*, term_data.*, community_tags.*')
.where(type: 'note', status: 3)
.where('term_data.name = (?)', "with:#{current_user.username}")
.collect(&:nid)
notes = notes.where('(node.nid IN (?) OR node.status = 1 OR ((node.status = 3 OR node.status = 4) AND node.uid = ?))', coauthor_nids, current_user.uid)
comments = comments.where('comments.status = 1 OR (comments.status = 4 AND comments.uid = ?)', current_user.uid)
else
notes = notes.where('node.status = 1')
comments = comments.where('comments.status = 1')
end
notes = notes.to_a # ensure it can be serialized for caching
# include revisions, then mix with new pages:
wikis = Node.where(type: 'page', status: 1)
.order('nid DESC')
.limit(10)
revisions = Revision.joins(:node)
.includes(:node)
.order('timestamp DESC')
.where('type = (?)', 'page')
.where('node.status = 1')
.where('node_revisions.status = 1')
.where('timestamp - node.created > ?', 300) # don't report edits within 5 mins of page creation
.limit(10)
.group(['node.title', 'node.nid', 'node_revisions.vid']) # ONLY_FULL_GROUP_BY, issue #3120
# group by day: http://stackoverflow.com/questions/5970938/group-by-day-from-timestamp
revisions = revisions.group('DATE(FROM_UNIXTIME(timestamp))') if Rails.env == 'production'
revisions = revisions.to_a # ensure it can be serialized for caching
wikis += revisions
wikis = wikis.sort_by(&:created_at).reverse
# group by day: http://stackoverflow.com/questions/5970938/group-by-day-from-timestamp
comments = comments.group('DATE(FROM_UNIXTIME(timestamp))') if Rails.env == 'production'
comments = comments.to_a # ensure it can be serialized for caching
activity = (notes + wikis + comments).sort_by(&:created_at).reverse
[activity, blog, notes, wikis, revisions, comments]
end
def trending
# Trending tags exculding subscriptions and tag first time poster tag
# The first time poster tag is not useful in search
exclude_tids = @tag_subscriptions.pluck(:tid)
exclude_tids << Tag.where(name: %w(everything first-time-poster)).pluck(:tid)
exclude_tids.flatten!.uniq
Tag.trending.where('term_data.name NOT LIKE (?)', '%:%').where.not(tid: exclude_tids)
end
end