Filter Duplicate Boosts
Filter Duplicate Boosts | |
---|---|
Description | Prevent duplicated boosts in public timelines like in home timelines |
Part Of | Mastodon/Hacking |
Contributors | Jonny |
Has Git Repository | https://github.com/NeuromatchAcademy/mastodon |
Completion Status | Stub |
Active Status | Inactive |
Problem
People like boosts in local timeline, but don't like seeing the same boost a zillion times.
Public feeds work differently than home feeds:
- Public feeds use a public_feed model that is a scoped database query
def get(limit, max_id = nil, since_id = nil, min_id = nil)
scope = public_scope
scope.merge!(without_local_only_scope) unless allow_local_only?
scope.merge!(without_replies_scope) unless with_replies?
scope.merge!(without_reblogs_scope) unless with_reblogs?
scope.merge!(local_only_scope) if local_only?
scope.merge!(remote_only_scope) if remote_only?
scope.merge!(account_filters_scope) if account?
scope.merge!(media_only_scope) if media_only?
scope.merge!(language_scope) if account&.chosen_languages.present?
scope.cache_ids.to_a_paginated_by_id(limit, max_id: max_id, since_id: since_id, min_id: min_id)
end
- Home feeds use a feed_manager class that inserts posts into a persistent list, which applies the boost filter at the time of that insertion:
def add_to_feed(timeline_type, account_id, status, aggregate_reblogs: true)
timeline_key = key(timeline_type, account_id)
reblog_key = key(timeline_type, account_id, 'reblogs')
if status.reblog? && (aggregate_reblogs.nil? || aggregate_reblogs)
# If the original status or a reblog of it is within
# REBLOG_FALLOFF statuses from the top, do not re-insert it into
# the feed
rank = redis.zrevrank(timeline_key, status.reblog_of_id)
return false if !rank.nil? && rank < FeedManager::REBLOG_FALLOFF
# The ordered set at `reblog_key` holds statuses which have a reblog
# in the top `REBLOG_FALLOFF` statuses of the timeline
if redis.zadd(reblog_key, status.id, status.reblog_of_id, nx: true)
# This is not something we've already seen reblogged, so we
# can just add it to the feed (and note that we're reblogging it).
redis.zadd(timeline_key, status.id, status.id)
else
# Another reblog of the same status was already in the
# REBLOG_FALLOFF most recent statuses, so we note that this
# is an "extra" reblog, by storing it in reblog_set_key.
reblog_set_key = key(timeline_type, account_id, "reblogs:#{status.reblog_of_id}")
redis.sadd(reblog_set_key, status.id)
return false
end
else
# A reblog may reach earlier than the original status because of the
# delay of the worker delivering the original status, the late addition
# by merging timelines, and other reasons.
# If such a reblog already exists, just do not re-insert it into the feed.
return false unless redis.zscore(reblog_key, status.id).nil?
redis.zadd(timeline_key, status.id, status.id)
end
true
end
Options
- Model - Make some tricky scope that can filter repeated boosts in the existing public_feed model
- Controller - Filter repeated boosts from the cached feed when serving the public_feed endpoint
- Frontend - Filter repeated boosts in the web UI (but wouldn't work on apps, which is bad)