Merge branch 'master' into glitch-soc/merge-upstream

Conflicts:
- app/models/status.rb
- db/schema.rb

Both conflicts are caused by us having extra database columns.
This commit is contained in:
Thibaut Girka
2019-03-05 19:23:16 +01:00
64 changed files with 1251 additions and 33 deletions
@@ -0,0 +1,52 @@
# frozen_string_literal: true
class ActivityPub::FetchRemotePollService < BaseService
include JsonLdHelper
def call(poll, on_behalf_of = nil)
@json = fetch_resource(poll.status.uri, true, on_behalf_of)
return unless supported_context? && expected_type?
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
latest_options = items.map { |item| item['name'].presence || item['content'] }
# 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
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 }
)
end
private
def supported_context?
super(@json)
end
def expected_type?
equals_or_includes_any?(@json['type'], %w(Question))
end
end
@@ -36,9 +36,7 @@ class ActivityPub::FetchRepliesService < BaseService
return collection_or_uri if collection_or_uri.is_a?(Hash)
return unless @allow_synchronous_requests
return if invalid_origin?(collection_or_uri)
collection = fetch_resource_without_id_validation(collection_or_uri)
raise Mastodon::UnexpectedResponseError if collection.nil?
collection
fetch_resource_without_id_validation(collection_or_uri, nil, true)
end
def filtered_replies
+10 -1
View File
@@ -15,6 +15,7 @@ class PostStatusService < BaseService
# @option [String] :spoiler_text
# @option [String] :language
# @option [String] :scheduled_at
# @option [Hash] :poll Optional poll to attach
# @option [Enumerable] :media_ids Optional array of media IDs to attach
# @option [Doorkeeper::Application] :application
# @option [String] :idempotency Optional idempotency key
@@ -28,6 +29,7 @@ class PostStatusService < BaseService
return idempotency_duplicate if idempotency_given? && idempotency_duplicate?
validate_media!
validate_poll!
preprocess_attributes!
if scheduled?
@@ -98,13 +100,19 @@ class PostStatusService < BaseService
def validate_media!
return if @options[:media_ids].blank? || !@options[:media_ids].is_a?(Enumerable)
raise Mastodon::ValidationError, I18n.t('media_attachments.validations.too_many') if @options[:media_ids].size > 4
raise Mastodon::ValidationError, I18n.t('media_attachments.validations.too_many') if @options[:media_ids].size > 4 || @options[:poll].present?
@media = @account.media_attachments.where(status_id: nil).where(id: @options[:media_ids].take(4).map(&:to_i))
raise Mastodon::ValidationError, I18n.t('media_attachments.validations.images_and_video') if @media.size > 1 && @media.find(&:video?)
end
def validate_poll!
return if @options[:poll].blank?
@poll = @account.polls.new(@options[:poll])
end
def language_from_option(str)
ISO_639.find(str)&.alpha2
end
@@ -157,6 +165,7 @@ class PostStatusService < BaseService
text: @text,
media_attachments: @media || [],
thread: @in_reply_to,
owned_poll: @poll,
sensitive: (@options[:sensitive].nil? ? @account.user&.setting_default_sensitive : @options[:sensitive]) || @options[:spoiler_text].present?,
spoiler_text: @options[:spoiler_text] || '',
visibility: @visibility,
+1 -1
View File
@@ -20,7 +20,7 @@ class ResolveURLService < BaseService
def process_url
if equals_or_includes_any?(type, %w(Application Group Organization Person Service))
FetchRemoteAccountService.new.call(atom_url, body, protocol)
elsif equals_or_includes_any?(type, %w(Note Article Image Video Page))
elsif equals_or_includes_any?(type, %w(Note Article Image Video Page Question))
FetchRemoteStatusService.new.call(atom_url, body, protocol)
end
end
+1 -1
View File
@@ -84,7 +84,7 @@ class SuspendAccountService < BaseService
@account.locked = false
@account.display_name = ''
@account.note = ''
@account.fields = {}
@account.fields = []
@account.statuses_count = 0
@account.followers_count = 0
@account.following_count = 0
+40
View File
@@ -0,0 +1,40 @@
# frozen_string_literal: true
class VoteService < BaseService
include Authorization
def call(account, poll, choices)
authorize_with account, poll, :vote?
@account = account
@poll = poll
@choices = choices
@votes = []
ApplicationRecord.transaction do
@choices.each do |choice|
@votes << @poll.votes.create!(account: @account, choice: choice)
end
end
return if @poll.account.local?
@votes.each do |vote|
ActivityPub::DeliveryWorker.perform_async(
build_json(vote),
@account.id,
@poll.account.inbox_url
)
end
end
private
def build_json(vote)
ActiveModelSerializers::SerializableResource.new(
vote,
serializer: ActivityPub::VoteSerializer,
adapter: ActivityPub::Adapter
).to_json
end
end