diaspora/lib/evil_query.rb
Benjamin Neff a4c26b7464
Exclude ignored people from followed tags when building stream-relation
This improves the main stream when you have less or inactive contacts
and ignored an active person that posts many posts with tags. When the
person is only removed after collecting all post ids, you don't see
posts with tags from other people.
2017-07-23 23:33:43 +02:00

122 lines
3.2 KiB
Ruby

module EvilQuery
class Base
include Diaspora::Logging
def fetch_ids!(relation, id_column)
#the relation should be ordered and limited by here
@class.connection.select_values(id_sql(relation, id_column))
end
def id_sql(relation, id_column)
@class.connection.unprepared_statement { relation.select(id_column).to_sql }
end
end
class Participation < Base
def initialize(user)
@user = user
@class = Post
end
def posts
author_id = @user.person_id
Post.joins("LEFT OUTER JOIN participations ON participations.target_id = posts.id AND " \
"participations.target_type = 'Post'")
.where(::Participation.arel_table[:author_id].eq(author_id).or(Post.arel_table[:author_id].eq(author_id)))
.order("posts.interacted_at DESC")
.distinct
end
end
class LikedPosts < Base
def initialize(user)
@user = user
end
def posts
Post.liked_by(@user.person)
end
end
class CommentedPosts < Base
def initialize(user)
@user = user
end
def posts
Post.commented_by(@user.person)
end
end
class MultiStream < Base
def initialize(user, order, max_time, include_spotlight)
@user = user
@class = Post
@order = order
@max_time = max_time
@include_spotlight = include_spotlight
end
def make_relation!
logger.debug("[EVIL-QUERY] make_relation!")
post_ids = aspects_post_ids! + ids!(followed_tags_posts!) + ids!(mentioned_posts)
post_ids += ids!(community_spotlight_posts!) if @include_spotlight
Post.where(:id => post_ids)
end
def aspects_post_ids!
logger.debug("[EVIL-QUERY] aspect_post_ids!")
@user.visible_shareable_ids(Post, limit: 15, order: "#{@order} DESC", max_time: @max_time, all_aspects?: true)
end
def followed_tags_posts!
logger.debug("[EVIL-QUERY] followed_tags_posts!")
StatusMessage.public_tag_stream(@user.followed_tag_ids).excluding_hidden_content(@user)
end
def mentioned_posts
logger.debug("[EVIL-QUERY] mentioned_posts")
StatusMessage.where_person_is_mentioned(@user.person)
end
def community_spotlight_posts!
Post.all_public.where(:author_id => fetch_ids!(Person.community_spotlight, 'people.id'))
end
def ids!(query)
fetch_ids!(query.for_a_stream(@max_time, @order), 'posts.id')
end
end
class VisibleShareableById < Base
def initialize(user, klass, key, id, conditions={})
@querent = user
@class = klass
@key = key
@id = id
@conditions = conditions
end
def post!
#small optimization - is this optimal order??
querent_has_visibility.first || querent_is_author.first || public_post.first
end
protected
def querent_has_visibility
@class.where(@key => @id).joins(:share_visibilities)
.where(share_visibilities: {user_id: @querent.id})
.where(@conditions)
.select(@class.table_name + ".*")
end
def querent_is_author
@class.where(@key => @id, :author_id => @querent.person.id).where(@conditions)
end
def public_post
@class.where(@key => @id, :public => true).where(@conditions)
end
end
end