diff options
Diffstat (limited to 'app/services')
-rw-r--r-- | app/services/block_service.rb | 18 | ||||
-rw-r--r-- | app/services/fan_out_on_write_service.rb | 7 | ||||
-rw-r--r-- | app/services/favourite_service.rb | 2 | ||||
-rw-r--r-- | app/services/follow_remote_account_service.rb | 3 | ||||
-rw-r--r-- | app/services/follow_service.rb | 4 | ||||
-rw-r--r-- | app/services/notify_service.rb | 2 | ||||
-rw-r--r-- | app/services/post_status_service.rb | 13 | ||||
-rw-r--r-- | app/services/process_feed_service.rb | 2 | ||||
-rw-r--r-- | app/services/process_hashtags_service.rb | 2 | ||||
-rw-r--r-- | app/services/process_interaction_service.rb | 4 | ||||
-rw-r--r-- | app/services/pubsubhubbub/subscribe_service.rb | 13 | ||||
-rw-r--r-- | app/services/pubsubhubbub/unsubscribe_service.rb | 15 | ||||
-rw-r--r-- | app/services/reblog_service.rb | 2 | ||||
-rw-r--r-- | app/services/remove_status_service.rb | 5 | ||||
-rw-r--r-- | app/services/search_service.rb | 6 | ||||
-rw-r--r-- | app/services/unfollow_service.rb | 3 | ||||
-rw-r--r-- | app/services/update_remote_profile_service.rb | 26 |
17 files changed, 91 insertions, 36 deletions
diff --git a/app/services/block_service.rb b/app/services/block_service.rb index 388a592e0..6a032a5a1 100644 --- a/app/services/block_service.rb +++ b/app/services/block_service.rb @@ -6,19 +6,27 @@ class BlockService < BaseService UnfollowService.new.call(account, target_account) if account.following?(target_account) account.block!(target_account) - clear_mentions(account, target_account) + clear_timelines(account, target_account) + clear_notifications(account, target_account) end private - def clear_mentions(account, target_account) - timeline_key = FeedManager.instance.key(:mentions, account.id) + def clear_timelines(account, target_account) + mentions_key = FeedManager.instance.key(:mentions, account.id) + home_key = FeedManager.instance.key(:home, account.id) target_account.statuses.select('id').find_each do |status| - redis.zrem(timeline_key, status.id) + redis.zrem(mentions_key, status.id) + redis.zrem(home_key, status.id) end + end - FeedManager.instance.broadcast(account.id, type: 'block', id: target_account.id) + def clear_notifications(account, target_account) + Notification.where(account: account).joins(:follow).where(activity_type: 'Follow', follows: { account_id: target_account.id }).destroy_all + Notification.where(account: account).joins(mention: :status).where(activity_type: 'Mention', statuses: { account_id: target_account.id }).destroy_all + Notification.where(account: account).joins(:favourite).where(activity_type: 'Favourite', favourites: { account_id: target_account.id }).destroy_all + Notification.where(account: account).joins(:status).where(activity_type: 'Status', statuses: { account_id: target_account.id }).destroy_all end def redis diff --git a/app/services/fan_out_on_write_service.rb b/app/services/fan_out_on_write_service.rb index 78cb0b13f..40d8a0fee 100644 --- a/app/services/fan_out_on_write_service.rb +++ b/app/services/fan_out_on_write_service.rb @@ -24,7 +24,7 @@ class FanOutOnWriteService < BaseService def deliver_to_followers(status) Rails.logger.debug "Delivering status #{status.id} to followers" - status.account.followers.where(domain: nil).find_each do |follower| + status.account.followers.where(domain: nil).joins(:user).where('users.current_sign_in_at > ?', 14.days.ago).find_each do |follower| next if FeedManager.instance.filter?(:home, status, follower) FeedManager.instance.push(:home, follower, status) end @@ -41,14 +41,17 @@ class FanOutOnWriteService < BaseService end def deliver_to_hashtags(status) - Rails.logger.debug "Delivering status #{status.id} to hashtags" + return if status.reblog? || status.reply? + Rails.logger.debug "Delivering status #{status.id} to hashtags" status.tags.find_each do |tag| FeedManager.instance.broadcast("hashtag:#{tag.name}", type: 'update', id: status.id) end end def deliver_to_public(status) + return if status.reblog? || status.reply? + Rails.logger.debug "Delivering status #{status.id} to public timeline" FeedManager.instance.broadcast(:public, type: 'update', id: status.id) end diff --git a/app/services/favourite_service.rb b/app/services/favourite_service.rb index 781b03b40..2f280e03f 100644 --- a/app/services/favourite_service.rb +++ b/app/services/favourite_service.rb @@ -7,7 +7,9 @@ class FavouriteService < BaseService # @return [Favourite] def call(account, status) favourite = Favourite.create!(account: account, status: status) + HubPingWorker.perform_async(account.id) + Pubsubhubbub::DistributionWorker.perform_async(favourite.stream_entry.id) if status.local? NotifyService.new.call(status.account, favourite) diff --git a/app/services/follow_remote_account_service.rb b/app/services/follow_remote_account_service.rb index 37339d8ed..f640222b0 100644 --- a/app/services/follow_remote_account_service.rb +++ b/app/services/follow_remote_account_service.rb @@ -80,8 +80,7 @@ class FollowRemoteAccountService < BaseService end def get_profile(xml, account) - author = xml.at_xpath('/xmlns:feed/xmlns:author') || xml.at_xpath('/xmlns:feed').at_xpath('./dfrn:owner', dfrn: DFRN_NS) - update_remote_profile_service.call(author, account) + update_remote_profile_service.call(xml.at_xpath('/xmlns:feed'), account) end def update_remote_profile_service diff --git a/app/services/follow_service.rb b/app/services/follow_service.rb index cdae254bf..09fa295e3 100644 --- a/app/services/follow_service.rb +++ b/app/services/follow_service.rb @@ -19,7 +19,10 @@ class FollowService < BaseService end merge_into_timeline(target_account, source_account) + HubPingWorker.perform_async(source_account.id) + Pubsubhubbub::DistributionWorker.perform_async(follow.stream_entry.id) + follow end @@ -33,7 +36,6 @@ class FollowService < BaseService end FeedManager.instance.trim(:home, into_account.id) - FeedManager.instance.broadcast(into_account.id, type: 'merge') end def redis diff --git a/app/services/notify_service.rb b/app/services/notify_service.rb index 772adfb90..1efd326b0 100644 --- a/app/services/notify_service.rb +++ b/app/services/notify_service.rb @@ -36,6 +36,8 @@ class NotifyService < BaseService blocked = false blocked ||= @recipient.id == @notification.from_account.id blocked ||= @recipient.blocking?(@notification.from_account) + blocked ||= (@recipient.user.settings(:interactions).must_be_follower && !@notification.from_account.following?(@recipient)) + blocked ||= (@recipient.user.settings(:interactions).must_be_following && !@recipient.following?(@notification.from_account)) blocked ||= send("blocked_#{@notification.type}?") blocked end diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index cf824ff99..979a157e9 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -5,15 +5,20 @@ class PostStatusService < BaseService # @param [Account] account Account from which to post # @param [String] text Message # @param [Status] in_reply_to Optional status to reply to - # @param [Enumerable] media_ids Optional array of media IDs to attach + # @param [Hash] options + # @option [Boolean] :sensitive + # @option [Enumerable] :media_ids Optional array of media IDs to attach # @return [Status] - def call(account, text, in_reply_to = nil, media_ids = nil) - status = account.statuses.create!(text: text, thread: in_reply_to) - attach_media(status, media_ids) + def call(account, text, in_reply_to = nil, options = {}) + status = account.statuses.create!(text: text, thread: in_reply_to, sensitive: options[:sensitive]) + attach_media(status, options[:media_ids]) process_mentions_service.call(status) process_hashtags_service.call(status) + DistributionWorker.perform_async(status.id) HubPingWorker.perform_async(account.id) + Pubsubhubbub::DistributionWorker.perform_async(status.stream_entry.id) + status end diff --git a/app/services/process_feed_service.rb b/app/services/process_feed_service.rb index 1cd801b80..a7a4cb2b0 100644 --- a/app/services/process_feed_service.rb +++ b/app/services/process_feed_service.rb @@ -16,7 +16,7 @@ class ProcessFeedService < BaseService def update_author(xml, account) return if xml.at_xpath('/xmlns:feed').nil? - UpdateRemoteProfileService.new.call(xml.at_xpath('/xmlns:feed/xmlns:author'), account) + UpdateRemoteProfileService.new.call(xml.at_xpath('/xmlns:feed'), account, true) end def process_entries(xml, account) diff --git a/app/services/process_hashtags_service.rb b/app/services/process_hashtags_service.rb index 3bf3471ec..fa14c44da 100644 --- a/app/services/process_hashtags_service.rb +++ b/app/services/process_hashtags_service.rb @@ -4,7 +4,7 @@ class ProcessHashtagsService < BaseService def call(status, tags = []) tags = status.text.scan(Tag::HASHTAG_RE).map(&:first) if status.local? - tags.map(&:downcase).uniq.each do |tag| + tags.map { |str| str.mb_chars.downcase }.uniq.each do |tag| status.tags << Tag.where(name: tag).first_or_initialize(name: tag) end end diff --git a/app/services/process_interaction_service.rb b/app/services/process_interaction_service.rb index e7bb3c73b..6b2f6e2d2 100644 --- a/app/services/process_interaction_service.rb +++ b/app/services/process_interaction_service.rb @@ -26,7 +26,7 @@ class ProcessInteractionService < BaseService end if salmon.verify(envelope, account.keypair) - update_remote_profile_service.call(xml.at_xpath('/xmlns:entry/xmlns:author'), account) + update_remote_profile_service.call(xml.at_xpath('/xmlns:entry'), account, true) case verb(xml) when :follow @@ -74,7 +74,7 @@ class ProcessInteractionService < BaseService end def delete_post!(xml, account) - status = Status.find(activity_id(xml)) + status = Status.find(xml.at_xpath('//xmlns:id').content) return if status.nil? diff --git a/app/services/pubsubhubbub/subscribe_service.rb b/app/services/pubsubhubbub/subscribe_service.rb new file mode 100644 index 000000000..343376d77 --- /dev/null +++ b/app/services/pubsubhubbub/subscribe_service.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class Pubsubhubbub::SubscribeService < BaseService + def call(account, callback, secret, lease_seconds) + return ['Invalid topic URL', 422] if account.nil? + return ['Invalid callback URL', 422] unless !callback.blank? && callback =~ /\A#{URI.regexp(%w(http https))}\z/ + + subscription = Subscription.where(account: account, callback_url: callback).first_or_create!(account: account, callback_url: callback) + Pubsubhubbub::ConfirmationWorker.perform_async(subscription.id, 'subscribe', secret, lease_seconds) + + ['', 202] + end +end diff --git a/app/services/pubsubhubbub/unsubscribe_service.rb b/app/services/pubsubhubbub/unsubscribe_service.rb new file mode 100644 index 000000000..62459a0aa --- /dev/null +++ b/app/services/pubsubhubbub/unsubscribe_service.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class Pubsubhubbub::UnsubscribeService < BaseService + def call(account, callback) + return ['Invalid topic URL', 422] if account.nil? + + subscription = Subscription.where(account: account, callback_url: callback) + + unless subscription.nil? + Pubsubhubbub::ConfirmationWorker.perform_async(subscription.id, 'unsubscribe') + end + + ['', 202] + end +end diff --git a/app/services/reblog_service.rb b/app/services/reblog_service.rb index 6543d4ae7..39fdb4ea7 100644 --- a/app/services/reblog_service.rb +++ b/app/services/reblog_service.rb @@ -7,8 +7,10 @@ class ReblogService < BaseService # @return [Status] def call(account, reblogged_status) reblog = account.statuses.create!(reblog: reblogged_status, text: '') + DistributionWorker.perform_async(reblog.id) HubPingWorker.perform_async(account.id) + Pubsubhubbub::DistributionWorker.perform_async(reblog.stream_entry.id) if reblogged_status.local? NotifyService.new.call(reblogged_status.account, reblog) diff --git a/app/services/remove_status_service.rb b/app/services/remove_status_service.rb index 689abc97b..4e03661da 100644 --- a/app/services/remove_status_service.rb +++ b/app/services/remove_status_service.rb @@ -10,6 +10,11 @@ class RemoveStatusService < BaseService remove_from_public(status) status.destroy! + + if status.account.local? + HubPingWorker.perform_async(status.account.id) + Pubsubhubbub::DistributionWorker.perform_async(status.stream_entry.id) + end end private diff --git a/app/services/search_service.rb b/app/services/search_service.rb index c4cffda13..1ae1d5a80 100644 --- a/app/services/search_service.rb +++ b/app/services/search_service.rb @@ -2,9 +2,9 @@ class SearchService < BaseService def call(query, limit, resolve = false) - return if query.blank? + return if query.blank? || query.start_with?('#') - username, domain = query.split('@') + username, domain = query.gsub(/\A@/, '').split('@') results = if domain.nil? Account.search_for(username) @@ -12,7 +12,7 @@ class SearchService < BaseService Account.search_for("#{username} #{domain}") end - results = results.limit(limit).with_counters + results = results.limit(limit) if resolve && results.empty? && !domain.nil? results = [FollowRemoteAccountService.new.call("#{username}@#{domain}")] diff --git a/app/services/unfollow_service.rb b/app/services/unfollow_service.rb index b3386a99c..7973a3611 100644 --- a/app/services/unfollow_service.rb +++ b/app/services/unfollow_service.rb @@ -17,9 +17,8 @@ class UnfollowService < BaseService from_account.statuses.select('id').find_each do |status| redis.zrem(timeline_key, status.id) + redis.zremrangebyscore(timeline_key, status.id, status.id) end - - FeedManager.instance.broadcast(into_account.id, type: 'unmerge') end def redis diff --git a/app/services/update_remote_profile_service.rb b/app/services/update_remote_profile_service.rb index 2909ae12a..56b25816f 100644 --- a/app/services/update_remote_profile_service.rb +++ b/app/services/update_remote_profile_service.rb @@ -2,24 +2,24 @@ class UpdateRemoteProfileService < BaseService POCO_NS = 'http://portablecontacts.net/spec/1.0' + DFRN_NS = 'http://purl.org/macgirvin/dfrn/1.0' - def call(author_xml, account) - return if author_xml.nil? + def call(xml, account, resubscribe = false) + return if xml.nil? - account.display_name = if author_xml.at_xpath('./poco:displayName', poco: POCO_NS).nil? - account.username - else - author_xml.at_xpath('./poco:displayName', poco: POCO_NS).content - end + author_xml = xml.at_xpath('./xmlns:author') || xml.at_xpath('./dfrn:owner', dfrn: DFRN_NS) + hub_link = xml.at_xpath('./xmlns:link[@rel="hub"]') - unless author_xml.at_xpath('./poco:note').nil? - account.note = author_xml.at_xpath('./poco:note', poco: POCO_NS).content - end - - unless author_xml.at_xpath('./xmlns:link[@rel="avatar"]').nil? - account.avatar_remote_url = author_xml.at_xpath('./xmlns:link[@rel="avatar"]').attribute('href').value + unless author_xml.nil? + account.display_name = author_xml.at_xpath('./poco:displayName', poco: POCO_NS).content unless author_xml.at_xpath('./poco:displayName', poco: POCO_NS).nil? + account.note = author_xml.at_xpath('./poco:note', poco: POCO_NS).content unless author_xml.at_xpath('./poco:note').nil? + account.avatar_remote_url = author_xml.at_xpath('./xmlns:link[@rel="avatar"]')['href'] unless author_xml.at_xpath('./xmlns:link[@rel="avatar"]').nil? || author_xml.at_xpath('./xmlns:link[@rel="avatar"]')['href'].blank? end + old_hub_url = account.hub_url + account.hub_url = hub_link['href'] if !hub_link.nil? && !hub_link['href'].blank? && (hub_link['href'] != old_hub_url) account.save! + + SubscribeService.new.call(account) if resubscribe && (account.hub_url != old_hub_url) end end |