diff options
author | Spencer Alves <impiaaa@gmail.com> | 2018-05-31 21:33:16 -0700 |
---|---|---|
committer | Spencer Alves <impiaaa@gmail.com> | 2018-05-31 21:33:16 -0700 |
commit | 7d2e6429c27c5ddc8ef3d2366c44329092e07f77 (patch) | |
tree | 7cfd2035f69616a369b2f3762ce9cefe61c2bd22 /app/services | |
parent | f2ff167c1a8df9b2521d33fcca15b8d5c67c50b1 (diff) | |
parent | e396fbfe3bf4d2a404e78e73cff1a609dd0a9bfb (diff) |
Merge branch 'glitch' into thread-icon
Diffstat (limited to 'app/services')
-rw-r--r-- | app/services/activitypub/fetch_remote_status_service.rb | 5 | ||||
-rw-r--r-- | app/services/activitypub/process_account_service.rb | 13 | ||||
-rw-r--r-- | app/services/activitypub/process_collection_service.rb | 3 | ||||
-rw-r--r-- | app/services/batched_remove_status_service.rb | 5 | ||||
-rw-r--r-- | app/services/fan_out_on_write_service.rb | 12 | ||||
-rw-r--r-- | app/services/fetch_link_card_service.rb | 4 | ||||
-rw-r--r-- | app/services/notify_service.rb | 21 | ||||
-rw-r--r-- | app/services/post_status_service.rb | 10 | ||||
-rw-r--r-- | app/services/process_hashtags_service.rb | 6 | ||||
-rw-r--r-- | app/services/remove_status_service.rb | 8 | ||||
-rw-r--r-- | app/services/resolve_account_service.rb | 2 | ||||
-rw-r--r-- | app/services/update_remote_profile_service.rb | 12 |
12 files changed, 75 insertions, 26 deletions
diff --git a/app/services/activitypub/fetch_remote_status_service.rb b/app/services/activitypub/fetch_remote_status_service.rb index 930fbad1f..2b447abb3 100644 --- a/app/services/activitypub/fetch_remote_status_service.rb +++ b/app/services/activitypub/fetch_remote_status_service.rb @@ -4,9 +4,9 @@ class ActivityPub::FetchRemoteStatusService < BaseService include JsonLdHelper # Should be called when uri has already been checked for locality - def call(uri, id: true, prefetched_body: nil) + def call(uri, id: true, prefetched_body: nil, on_behalf_of: nil) @json = if prefetched_body.nil? - fetch_resource(uri, id) + fetch_resource(uri, id, on_behalf_of) else body_to_json(prefetched_body) end @@ -34,6 +34,7 @@ class ActivityPub::FetchRemoteStatusService < BaseService end def trustworthy_attribution?(uri, attributed_to) + return false if uri.nil? || attributed_to.nil? Addressable::URI.parse(uri).normalized_host.casecmp(Addressable::URI.parse(attributed_to).normalized_host).zero? end diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb index f67ebb443..453253db4 100644 --- a/app/services/activitypub/process_account_service.rb +++ b/app/services/activitypub/process_account_service.rb @@ -23,6 +23,8 @@ class ActivityPub::ProcessAccountService < BaseService create_account if @account.nil? update_account process_tags + else + raise Mastodon::RaceConditionError end end @@ -44,7 +46,6 @@ class ActivityPub::ProcessAccountService < BaseService @account.protocol = :activitypub @account.username = @username @account.domain = @domain - @account.uri = @uri @account.suspended = true if auto_suspend? @account.silenced = true if auto_silence? @account.private_key = nil @@ -67,10 +68,12 @@ class ActivityPub::ProcessAccountService < BaseService @account.followers_url = @json['followers'] || '' @account.featured_collection_url = @json['featured'] || '' @account.url = url || @uri + @account.uri = @uri @account.display_name = @json['name'] || '' @account.note = @json['summary'] || '' @account.locked = @json['manuallyApprovesFollowers'] || false @account.fields = property_values || {} + @account.actor_type = actor_type end def set_fetchable_attributes! @@ -95,6 +98,14 @@ class ActivityPub::ProcessAccountService < BaseService ActivityPub::SynchronizeFeaturedCollectionWorker.perform_async(@account.id) end + def actor_type + if @json['type'].is_a?(Array) + @json['type'].find { |type| ActivityPub::FetchRemoteAccountService::SUPPORTED_TYPES.include?(type) } + else + @json['type'] + end + end + def image_url(key) value = first_of_value(@json[key]) diff --git a/app/services/activitypub/process_collection_service.rb b/app/services/activitypub/process_collection_service.rb index eb93329e9..79cdca297 100644 --- a/app/services/activitypub/process_collection_service.rb +++ b/app/services/activitypub/process_collection_service.rb @@ -45,5 +45,8 @@ class ActivityPub::ProcessCollectionService < BaseService def verify_account! @account = ActivityPub::LinkedDataSignature.new(@json).verify_account! + rescue JSON::LD::JsonLdError => e + Rails.logger.debug "Could not verify LD-Signature for #{value_or_id(@json['actor'])}: #{e.message}" + nil end end diff --git a/app/services/batched_remove_status_service.rb b/app/services/batched_remove_status_service.rb index cb65a2256..ace51a1fc 100644 --- a/app/services/batched_remove_status_service.rb +++ b/app/services/batched_remove_status_service.rb @@ -81,6 +81,11 @@ class BatchedRemoveStatusService < BaseService redis.publish('timeline:public', payload) redis.publish('timeline:public:local', payload) if status.local? + if status.media_attachments.any? + redis.publish('timeline:public:media', payload) + redis.publish('timeline:public:local:media', payload) if status.local? + end + @tags[status.id].each do |hashtag| redis.publish("timeline:hashtag:#{hashtag}", payload) redis.publish("timeline:hashtag:#{hashtag}:local", payload) if status.local? diff --git a/app/services/fan_out_on_write_service.rb b/app/services/fan_out_on_write_service.rb index 510b80c82..8b3630229 100644 --- a/app/services/fan_out_on_write_service.rb +++ b/app/services/fan_out_on_write_service.rb @@ -25,6 +25,7 @@ class FanOutOnWriteService < BaseService return if status.reply? && status.in_reply_to_account_id != status.account_id deliver_to_public(status) + deliver_to_media(status) if status.media_attachments.any? end private @@ -37,7 +38,7 @@ class FanOutOnWriteService < BaseService def deliver_to_followers(status) Rails.logger.debug "Delivering status #{status.id} to followers" - status.account.followers.where(domain: nil).joins(:user).where('users.current_sign_in_at > ?', 14.days.ago).select(:id).reorder(nil).find_in_batches do |followers| + status.account.followers.where(domain: nil).joins(:user).where('users.current_sign_in_at > ?', User::ACTIVE_DURATION.ago).select(:id).reorder(nil).find_in_batches do |followers| FeedInsertWorker.push_bulk(followers) do |follower| [status.id, follower.id, :home] end @@ -47,7 +48,7 @@ class FanOutOnWriteService < BaseService def deliver_to_lists(status) Rails.logger.debug "Delivering status #{status.id} to lists" - status.account.lists.joins(account: :user).where('users.current_sign_in_at > ?', 14.days.ago).select(:id).reorder(nil).find_in_batches do |lists| + status.account.lists.joins(account: :user).where('users.current_sign_in_at > ?', User::ACTIVE_DURATION.ago).select(:id).reorder(nil).find_in_batches do |lists| FeedInsertWorker.push_bulk(lists) do |list| [status.id, list.id, :list] end @@ -85,6 +86,13 @@ class FanOutOnWriteService < BaseService Redis.current.publish('timeline:public:local', @payload) if status.local? end + def deliver_to_media(status) + Rails.logger.debug "Delivering status #{status.id} to media timeline" + + Redis.current.publish('timeline:public:media', @payload) + Redis.current.publish('timeline:public:local:media', @payload) if status.local? + end + def deliver_to_direct_timelines(status) Rails.logger.debug "Delivering status #{status.id} to direct timelines" diff --git a/app/services/fetch_link_card_service.rb b/app/services/fetch_link_card_service.rb index 77d4aa538..86d0f9971 100644 --- a/app/services/fetch_link_card_service.rb +++ b/app/services/fetch_link_card_service.rb @@ -23,11 +23,13 @@ class FetchLinkCardService < BaseService if lock.acquired? @card = PreviewCard.find_by(url: @url) process_url if @card.nil? || @card.updated_at <= 2.weeks.ago + else + raise Mastodon::RaceConditionError end end attach_card if @card&.persisted? - rescue HTTP::Error, Addressable::URI::InvalidURIError => e + rescue HTTP::Error, Addressable::URI::InvalidURIError, Mastodon::LengthValidationError => e Rails.logger.debug "Error fetching link #{@url}: #{e}" nil end diff --git a/app/services/notify_service.rb b/app/services/notify_service.rb index ba086449c..6490d2735 100644 --- a/app/services/notify_service.rb +++ b/app/services/notify_service.rb @@ -9,6 +9,7 @@ class NotifyService < BaseService return if recipient.user.nil? || blocked? create_notification + push_notification if @notification.browserable? send_email if email_enabled? rescue ActiveRecord::RecordInvalid return @@ -101,25 +102,27 @@ class NotifyService < BaseService def create_notification @notification.save! - return unless @notification.browserable? + end + + def push_notification + return if @notification.activity.nil? + Redis.current.publish("timeline:#{@recipient.id}", Oj.dump(event: :notification, payload: InlineRenderer.render(@notification, @recipient, :notification))) send_push_notifications end def send_push_notifications - # HACK: Can be caused by quickly unfavouriting a status, since creating - # a favourite and creating a notification are not wrapped in a transaction. - return if @notification.activity.nil? - - sessions_with_subscriptions = @recipient.user.session_activations.where.not(web_push_subscription: nil) - sessions_with_subscriptions_ids = sessions_with_subscriptions.select { |session| session.web_push_subscription.pushable? @notification }.map(&:id) + subscriptions_ids = ::Web::PushSubscription.where(user_id: @recipient.user.id) + .select { |subscription| subscription.pushable?(@notification) } + .map(&:id) - WebPushNotificationWorker.push_bulk(sessions_with_subscriptions_ids) do |session_activation_id| - [session_activation_id, @notification.id] + ::Web::PushNotificationWorker.push_bulk(subscriptions_ids) do |subscription_id| + [subscription_id, @notification.id] end end def send_email + return if @notification.activity.nil? NotificationMailer.public_send(@notification.type, @recipient, @notification).deliver_later end diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index fe03c044c..b1d5bd3a7 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -22,7 +22,7 @@ class PostStatusService < BaseService media = validate_media!(options[:media_ids]) status = nil text = options.delete(:spoiler_text) if text.blank? && options[:spoiler_text].present? - text = '.' if text.blank? && !media.empty? + text = '.' if text.blank? && media.present? ApplicationRecord.transaction do status = account.statuses.create!(text: text, @@ -31,12 +31,12 @@ class PostStatusService < BaseService sensitive: (options[:sensitive].nil? ? account.user&.setting_default_sensitive : options[:sensitive]), spoiler_text: options[:spoiler_text] || '', visibility: options[:visibility] || account.user&.setting_default_privacy, - language: LanguageDetector.instance.detect(text, account), + language: language_from_option(options[:language]) || LanguageDetector.instance.detect(text, account), application: options[:application]) end - process_mentions_service.call(status) process_hashtags_service.call(status) + process_mentions_service.call(status) LinkCrawlWorker.perform_async(status.id) unless status.spoiler_text? DistributionWorker.perform_async(status.id) @@ -68,6 +68,10 @@ class PostStatusService < BaseService media end + def language_from_option(str) + ISO_639.find(str)&.alpha2 + end + def process_mentions_service ProcessMentionsService.new end diff --git a/app/services/process_hashtags_service.rb b/app/services/process_hashtags_service.rb index 5b45c865f..0695922b8 100644 --- a/app/services/process_hashtags_service.rb +++ b/app/services/process_hashtags_service.rb @@ -4,8 +4,10 @@ class ProcessHashtagsService < BaseService def call(status, tags = []) tags = Extractor.extract_hashtags(status.text) if status.local? - tags.map { |str| str.mb_chars.downcase }.uniq(&:to_s).each do |tag| - status.tags << Tag.where(name: tag).first_or_initialize(name: tag) + tags.map { |str| str.mb_chars.downcase }.uniq(&:to_s).each do |name| + tag = Tag.where(name: name).first_or_create(name: name) + status.tags << tag + TrendingTags.record_use!(tag, status.account, status.created_at) end end end diff --git a/app/services/remove_status_service.rb b/app/services/remove_status_service.rb index e164c03ab..8c3e18444 100644 --- a/app/services/remove_status_service.rb +++ b/app/services/remove_status_service.rb @@ -20,6 +20,7 @@ class RemoveStatusService < BaseService remove_reblogs remove_from_hashtags remove_from_public + remove_from_media if status.media_attachments.any? remove_from_direct if status.direct_visibility? @status.destroy! @@ -131,6 +132,13 @@ class RemoveStatusService < BaseService Redis.current.publish('timeline:public:local', @payload) if @status.local? end + def remove_from_media + return unless @status.public_visibility? + + Redis.current.publish('timeline:public:media', @payload) + Redis.current.publish('timeline:public:local:media', @payload) if @status.local? + end + def remove_from_direct @mentions.each do |mention| Redis.current.publish("timeline:direct:#{mention.account.id}", @payload) if mention.account.local? diff --git a/app/services/resolve_account_service.rb b/app/services/resolve_account_service.rb index de8d1151d..4323e7f06 100644 --- a/app/services/resolve_account_service.rb +++ b/app/services/resolve_account_service.rb @@ -49,6 +49,8 @@ class ResolveAccountService < BaseService else handle_ostatus end + else + raise Mastodon::RaceConditionError end end diff --git a/app/services/update_remote_profile_service.rb b/app/services/update_remote_profile_service.rb index aca1185de..68d36addf 100644 --- a/app/services/update_remote_profile_service.rb +++ b/app/services/update_remote_profile_service.rb @@ -41,24 +41,24 @@ class UpdateRemoteProfileService < BaseService account.header.destroy end - save_emojis(account) if remote_profile.emojis.present? + save_emojis if remote_profile.emojis.present? end end - def save_emojis(parent) - do_not_download = DomainBlock.find_by(domain: parent.account.domain)&.reject_media? + def save_emojis + do_not_download = DomainBlock.find_by(domain: account.domain)&.reject_media? return if do_not_download - remote_account.emojis.each do |link| + remote_profile.emojis.each do |link| next unless link['href'] && link['name'] shortcode = link['name'].delete(':') - emoji = CustomEmoji.find_by(shortcode: shortcode, domain: parent.account.domain) + emoji = CustomEmoji.find_by(shortcode: shortcode, domain: account.domain) next unless emoji.nil? - emoji = CustomEmoji.new(shortcode: shortcode, domain: parent.account.domain) + emoji = CustomEmoji.new(shortcode: shortcode, domain: account.domain) emoji.image_remote_url = link['href'] emoji.save end |