optional delayed publishing of roars for proofreading

staging
multiple creatures 2019-07-29 14:26:41 -05:00
parent 02729ab3ae
commit 74290d4eb3
10 changed files with 82 additions and 6 deletions

View File

@ -54,6 +54,7 @@ class Settings::PreferencesController < Settings::BaseController
:setting_hide_public_outbox,
:setting_max_public_history,
:setting_roar_lifespan,
:setting_delayed_roars,
:setting_default_privacy,
:setting_default_sensitive,

View File

@ -38,6 +38,7 @@ class UserSettingsDecorator
user.settings['larger_emoji'] = larger_emoji_preference if change?('setting_larger_emoji')
user.settings['max_public_history'] = max_public_history_preference if change?('setting_max_public_history')
user.settings['roar_lifespan'] = roar_lifespan_preference if change?('setting_roar_lifespan')
user.settings['delayed_roars'] = delayed_roars_preference if change?('setting_delayed_roars')
user.settings['notification_emails'] = merged_notification_emails if change?('notification_emails')
user.settings['interactions'] = merged_interactions if change?('interactions')
@ -135,6 +136,10 @@ class UserSettingsDecorator
settings['setting_roar_lifespan']
end
def delayed_roars_preference
settings['setting_delayed_roars']
end
def merged_notification_emails
user.settings['notification_emails'].merge coerced_settings('notification_emails').to_h
end

View File

@ -130,6 +130,7 @@ class Account < ApplicationRecord
:always_local_only?,
:max_public_history,
:roar_lifespan,
:delayed_roars?,
:hides_public_profile?,
:hides_public_outbox?,

View File

@ -126,6 +126,7 @@ class User < ApplicationRecord
:hide_public_outbox,
:max_public_history,
:roar_lifespan,
:delayed_roars,
:auto_play_gif,
:default_sensitive,
@ -304,6 +305,10 @@ class User < ApplicationRecord
@_roar_lifespan ||= (settings.roar_lifespan || 0)
end
def delayed_roars?
@delayed_roars ||= (settings.delayed_roars || false)
end
def defaults_to_local_only?
@defaults_to_local_only ||= (settings.default_local || false)
end

View File

@ -3,10 +3,11 @@
class FanOutOnWriteService < BaseService
# Push a status into home and mentions feeds
# @param [Status] status
def call(status)
def call(status, delayed = false)
raise Mastodon::RaceConditionError if status.visibility.nil?
deliver_to_self(status) if status.account.local?
return if delayed
render_anonymous_payload(status)

View File

@ -32,6 +32,7 @@ class PostStatusService < BaseService
# @option [String] :delete_after
# @option [Boolean] :nocrawl Optional skip link card generation
# @option [Boolean] :nomentions Optional skip mention processing
# @option [Boolean] :delayed Optional publishing delay of 30 secs
# @option [Hash] :poll Optional poll to attach
# @option [Enumerable] :media_ids Optional array of media IDs to attach
# @option [Doorkeeper::Application] :application
@ -57,8 +58,23 @@ class PostStatusService < BaseService
schedule_status!
else
return unless process_status!
postprocess_status!
bump_potential_friendship!
if @options[:delayed] || @account&.user&.delayed_roars?
delay_until = Time.now.utc + 30.seconds
opts = {
visibility: @visibility,
federate: @options[:federate],
distribute: @options[:distribute],
nocrawl: @options[:nocrawl],
nomentions: @options[:nomentions],
delete_after: @delete_after.nil? ? nil : @delete_after + 30.seconds,
}.compact
PostStatusWorker.perform_at(delay_until, @status.id, opts)
DistributionWorker.perform_async(@status.id, delayed = true) unless @options[:distribute] == false
else
postprocess_status!
bump_potential_friendship!
end
end
redis.setex(idempotency_key, 3_600, @status.id) if idempotency_given?
@ -149,7 +165,7 @@ class PostStatusService < BaseService
return false if @status.destroyed?
process_hashtags_service.call(@status, @tags, @preloaded_tags)
process_mentions_service.call(@status) unless @options[:nomentions]
process_mentions_service.call(@status) unless @delayed || @options[:nomentions]
return true
end

View File

@ -31,6 +31,9 @@
= f.input :setting_always_local, as: :boolean, wrapper: :with_label
= f.input :setting_default_sensitive, as: :boolean, wrapper: :with_label
.fields-group
= f.input :setting_delayed_roars, as: :boolean, wrapper: :with_label
%hr#settings_other/
.fields-group

View File

@ -3,10 +3,10 @@
class DistributionWorker
include Sidekiq::Worker
def perform(status_id)
def perform(status_id, delayed = false)
RedisLock.acquire(redis: Redis.current, key: "distribute:#{status_id}") do |lock|
if lock.acquired?
FanOutOnWriteService.new.call(Status.find(status_id))
FanOutOnWriteService.new.call(Status.find(status_id), delayed)
else
raise Mastodon::RaceConditionError
end

View File

@ -0,0 +1,43 @@
# frozen_string_literal: true
class PostStatusWorker
include Sidekiq::Worker
sidekiq_options unique: :until_executed
def perform(status_id, options = {})
status = Status.find(status_id)
return false if status.destroyed?
if options[:visibility]
status.visibility = options[:visibility]
status.save!
end
process_mentions_service.call(status) unless options[:nomentions]
LinkCrawlWorker.perform_async(status.id) unless options[:nocrawl] || status.spoiler_text?
DistributionWorker.perform_async(status.id) unless options[:distribute] == false
unless status.local_only? || options[:distribute] == false || options[:federate] == false
ActivityPub::DistributionWorker.perform_async(status.id)
end
PollExpirationNotifyWorker.perform_at(status.poll.expires_at, status.poll.id) if status.poll
status.delete_after = options[:delete_after] if options[:delete_after]
return true if !status.reply? || status.account.id == status.in_reply_to_account_id
ActivityTracker.increment('activity:interactions')
return if status.account.following?(status.in_reply_to_account_id)
PotentialFriendshipTracker.record(status.account.id, status.in_reply_to_account_id, :reply)
true
rescue ActiveRecord::RecordNotFound, ActiveRecord::RecordInvalid
true
end
def process_mentions_service
ProcessMentionsService.new
end
end

View File

@ -118,6 +118,7 @@ en:
setting_default_language: Posting language
setting_default_privacy: Post privacy
setting_roar_lifespan: Auto-delete new roars after
setting_delayed_roars: Delayed publishing of roars for proofreading (30 secs)
setting_default_local: Default to Monsterpit-only roars (in Glitch flavour)
setting_always_local: Don't send your roars outside Monsterpit
setting_rawr_federated: Show raw world timeline (may contain offensive content!)