forked from fedi/mastodon
00c219aa45
If a poll contains empty options (which is apparently possible on Pleroma), it is created without them. However, the poll update code doesn't filter empty options, and thus: 1. Clear known votes, as it assumes the set of options has changed 2. Errors out because it tries adding empty options, which fails validation This commit fixes that by filtering them out the same way they are filtered out at poll creation time.
65 lines
1.6 KiB
Ruby
65 lines
1.6 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class ActivityPub::ProcessPollService < BaseService
|
|
include JsonLdHelper
|
|
|
|
def call(poll, json)
|
|
@json = json
|
|
|
|
return unless expected_type?
|
|
|
|
previous_expires_at = poll.expires_at
|
|
|
|
expires_at = begin
|
|
if @json['closed'].is_a?(String)
|
|
@json['closed']
|
|
elsif !@json['closed'].nil? && !@json['closed'].is_a?(FalseClass)
|
|
Time.now.utc
|
|
else
|
|
@json['endTime']
|
|
end
|
|
end
|
|
|
|
items = begin
|
|
if @json['anyOf'].is_a?(Array)
|
|
@json['anyOf']
|
|
else
|
|
@json['oneOf']
|
|
end
|
|
end
|
|
|
|
voters_count = @json['votersCount']
|
|
|
|
latest_options = items.map { |item| item['name'].presence || item['content'] }.compact
|
|
|
|
# If for some reasons the options were changed, it invalidates all previous
|
|
# votes, so we need to remove them
|
|
poll.votes.delete_all if latest_options != poll.options
|
|
|
|
begin
|
|
poll.update!(
|
|
last_fetched_at: Time.now.utc,
|
|
expires_at: expires_at,
|
|
options: latest_options,
|
|
cached_tallies: items.map { |item| item.dig('replies', 'totalItems') || 0 },
|
|
voters_count: voters_count
|
|
)
|
|
rescue ActiveRecord::StaleObjectError
|
|
poll.reload
|
|
retry
|
|
end
|
|
|
|
# If the poll had no expiration date set but now has, and people have voted,
|
|
# schedule a notification.
|
|
if previous_expires_at.nil? && poll.expires_at.present? && poll.votes.exists?
|
|
PollExpirationNotifyWorker.perform_at(poll.expires_at + 5.minutes, poll.id)
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def expected_type?
|
|
equals_or_includes_any?(@json['type'], %w(Question))
|
|
end
|
|
end
|