diff options
author | beatrix <beatrix.bitrot@gmail.com> | 2017-09-28 21:48:28 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-09-28 21:48:28 -0400 |
commit | c027a7bd4d7b5af21f4b201d656f7251fa3606a1 (patch) | |
tree | ce2c2327b26358c26cb899ea918988af373ca6d6 /app/services | |
parent | 210e6776fce016666ecfd248b2208c487f3440f9 (diff) | |
parent | 53f829dfa8bc376041a442dc84c22aa1cbfcb9d0 (diff) |
Merge pull request #157 from glitch-soc/merging-upstream
ABRACA-HRRRRRRRRRRRNGGGGGGGHHH!!!!!!!!!!!!!!!!!!!
Diffstat (limited to 'app/services')
-rw-r--r-- | app/services/activitypub/fetch_remote_status_service.rb | 2 | ||||
-rw-r--r-- | app/services/activitypub/process_account_service.rb | 78 | ||||
-rw-r--r-- | app/services/activitypub/process_collection_service.rb | 4 | ||||
-rw-r--r-- | app/services/batched_remove_status_service.rb | 4 | ||||
-rw-r--r-- | app/services/block_domain_service.rb | 9 | ||||
-rw-r--r-- | app/services/concerns/author_extractor.rb | 6 | ||||
-rw-r--r-- | app/services/fetch_link_card_service.rb | 43 | ||||
-rw-r--r-- | app/services/fetch_remote_account_service.rb | 2 | ||||
-rw-r--r-- | app/services/fetch_remote_status_service.rb | 2 | ||||
-rw-r--r-- | app/services/post_status_service.rb | 6 | ||||
-rw-r--r-- | app/services/process_feed_service.rb | 2 | ||||
-rw-r--r-- | app/services/process_interaction_service.rb | 16 | ||||
-rw-r--r-- | app/services/process_mentions_service.rb | 2 | ||||
-rw-r--r-- | app/services/remove_status_service.rb | 13 | ||||
-rw-r--r-- | app/services/resolve_remote_account_service.rb | 1 | ||||
-rw-r--r-- | app/services/verify_salmon_service.rb | 2 |
16 files changed, 134 insertions, 58 deletions
diff --git a/app/services/activitypub/fetch_remote_status_service.rb b/app/services/activitypub/fetch_remote_status_service.rb index 68ca58d62..a95931afe 100644 --- a/app/services/activitypub/fetch_remote_status_service.rb +++ b/app/services/activitypub/fetch_remote_status_service.rb @@ -17,6 +17,8 @@ class ActivityPub::FetchRemoteStatusService < BaseService actor = ActivityPub::TagManager.instance.uri_to_resource(actor_id, Account) actor = ActivityPub::FetchRemoteAccountService.new.call(actor_id) if actor.nil? + return if actor.suspended? + ActivityPub::Activity.factory(activity, actor).perform end diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb index b54e447ad..811209537 100644 --- a/app/services/activitypub/process_account_service.rb +++ b/app/services/activitypub/process_account_service.rb @@ -12,12 +12,21 @@ class ActivityPub::ProcessAccountService < BaseService @uri = @json['id'] @username = username @domain = domain - @account = Account.find_by(uri: @uri) @collections = {} - create_account if @account.nil? - upgrade_account if @account.ostatus? - update_account + RedisLock.acquire(lock_options) do |lock| + if lock.acquired? + @account = Account.find_by(uri: @uri) + @old_public_key = @account&.public_key + @old_protocol = @account&.protocol + + create_account if @account.nil? + update_account + end + end + + after_protocol_change! if protocol_changed? + after_key_change! if key_changed? @account rescue Oj::ParseError @@ -35,33 +44,46 @@ class ActivityPub::ProcessAccountService < BaseService @account.suspended = true if auto_suspend? @account.silenced = true if auto_silence? @account.private_key = nil - @account.save! end def update_account @account.last_webfingered_at = Time.now.utc @account.protocol = :activitypub - @account.inbox_url = @json['inbox'] || '' - @account.outbox_url = @json['outbox'] || '' - @account.shared_inbox_url = (@json['endpoints'].is_a?(Hash) ? @json['endpoints']['sharedInbox'] : @json['sharedInbox']) || '' - @account.followers_url = @json['followers'] || '' - @account.url = url || @uri - @account.display_name = @json['name'] || '' - @account.note = @json['summary'] || '' - @account.avatar_remote_url = image_url('icon') unless skip_download? - @account.header_remote_url = image_url('image') unless skip_download? - @account.public_key = public_key || '' - @account.locked = @json['manuallyApprovesFollowers'] || false - @account.statuses_count = outbox_total_items if outbox_total_items.present? - @account.following_count = following_total_items if following_total_items.present? - @account.followers_count = followers_total_items if followers_total_items.present? + + set_immediate_attributes! + set_fetchable_attributes! + @account.save_with_optional_media! end - def upgrade_account + def set_immediate_attributes! + @account.inbox_url = @json['inbox'] || '' + @account.outbox_url = @json['outbox'] || '' + @account.shared_inbox_url = (@json['endpoints'].is_a?(Hash) ? @json['endpoints']['sharedInbox'] : @json['sharedInbox']) || '' + @account.followers_url = @json['followers'] || '' + @account.url = url || @uri + @account.display_name = @json['name'] || '' + @account.note = @json['summary'] || '' + @account.locked = @json['manuallyApprovesFollowers'] || false + end + + def set_fetchable_attributes! + @account.avatar_remote_url = image_url('icon') unless skip_download? + @account.header_remote_url = image_url('image') unless skip_download? + @account.public_key = public_key || '' + @account.statuses_count = outbox_total_items if outbox_total_items.present? + @account.following_count = following_total_items if following_total_items.present? + @account.followers_count = followers_total_items if followers_total_items.present? + end + + def after_protocol_change! ActivityPub::PostUpgradeWorker.perform_async(@account.domain) end + def after_key_change! + RefollowWorker.perform_async(@account.id) + end + def image_url(key) value = first_of_value(@json[key]) @@ -120,15 +142,27 @@ class ActivityPub::ProcessAccountService < BaseService end def auto_suspend? - domain_block && domain_block.suspend? + domain_block&.suspend? end def auto_silence? - domain_block && domain_block.silence? + domain_block&.silence? end def domain_block return @domain_block if defined?(@domain_block) @domain_block = DomainBlock.find_by(domain: @domain) end + + def key_changed? + !@old_public_key.nil? && @old_public_key != @account.public_key + end + + def protocol_changed? + !@old_protocol.nil? && @old_protocol != @account.protocol + end + + def lock_options + { redis: Redis.current, key: "process_account:#{@uri}" } + end end diff --git a/app/services/activitypub/process_collection_service.rb b/app/services/activitypub/process_collection_service.rb index bc04c50ba..59cb65c65 100644 --- a/app/services/activitypub/process_collection_service.rb +++ b/app/services/activitypub/process_collection_service.rb @@ -7,9 +7,9 @@ class ActivityPub::ProcessCollectionService < BaseService @account = account @json = Oj.load(body, mode: :strict) - return if @account.suspended? || !supported_context? - + return unless supported_context? return if different_actor? && verify_account!.nil? + return if @account.suspended? || @account.local? case @json['type'] when 'Collection', 'CollectionPage' diff --git a/app/services/batched_remove_status_service.rb b/app/services/batched_remove_status_service.rb index 86eaa5735..2fd623922 100644 --- a/app/services/batched_remove_status_service.rb +++ b/app/services/batched_remove_status_service.rb @@ -18,7 +18,7 @@ class BatchedRemoveStatusService < BaseService @stream_entry_batches = [] @salmon_batches = [] @activity_json_batches = [] - @json_payloads = statuses.map { |s| [s.id, Oj.dump(event: :delete, payload: s.id)] }.to_h + @json_payloads = statuses.map { |s| [s.id, Oj.dump(event: :delete, payload: s.id.to_s)] }.to_h @activity_json = {} @activity_xml = {} @@ -84,6 +84,8 @@ class BatchedRemoveStatusService < BaseService end def unpush_from_public_timelines(status) + return unless status.public_visibility? + payload = @json_payloads[status.id] redis.pipelined do diff --git a/app/services/block_domain_service.rb b/app/services/block_domain_service.rb index 1473bc841..eefdc0dbf 100644 --- a/app/services/block_domain_service.rb +++ b/app/services/block_domain_service.rb @@ -26,6 +26,7 @@ class BlockDomainService < BaseService def clear_media! clear_account_images clear_account_attachments + clear_emojos end def suspend_accounts! @@ -51,6 +52,10 @@ class BlockDomainService < BaseService end end + def clear_emojos + emojis_from_blocked_domains.destroy_all + end + def blocked_domain domain_block.domain end @@ -62,4 +67,8 @@ class BlockDomainService < BaseService def media_from_blocked_domain MediaAttachment.joins(:account).merge(blocked_domain_accounts).reorder(nil) end + + def emojis_from_blocked_domains + CustomEmoji.where(domain: blocked_domain) + end end diff --git a/app/services/concerns/author_extractor.rb b/app/services/concerns/author_extractor.rb index 867d6dc25..c2366188a 100644 --- a/app/services/concerns/author_extractor.rb +++ b/app/services/concerns/author_extractor.rb @@ -5,12 +5,12 @@ module AuthorExtractor return nil if xml.nil? # Try <email> for acct - acct = xml.at_xpath('./xmlns:author/xmlns:email', xmlns: TagManager::XMLNS)&.content + acct = xml.at_xpath('./xmlns:author/xmlns:email', xmlns: OStatus::TagManager::XMLNS)&.content # Try <name> + <uri> if acct.blank? - username = xml.at_xpath('./xmlns:author/xmlns:name', xmlns: TagManager::XMLNS)&.content - uri = xml.at_xpath('./xmlns:author/xmlns:uri', xmlns: TagManager::XMLNS)&.content + username = xml.at_xpath('./xmlns:author/xmlns:name', xmlns: OStatus::TagManager::XMLNS)&.content + uri = xml.at_xpath('./xmlns:author/xmlns:uri', xmlns: OStatus::TagManager::XMLNS)&.content return nil if username.blank? || uri.blank? diff --git a/app/services/fetch_link_card_service.rb b/app/services/fetch_link_card_service.rb index c38e9e7df..4acbfae7a 100644 --- a/app/services/fetch_link_card_service.rb +++ b/app/services/fetch_link_card_service.rb @@ -1,7 +1,15 @@ # frozen_string_literal: true class FetchLinkCardService < BaseService - URL_PATTERN = %r{https?://\S+} + URL_PATTERN = %r{ + ( # $1 URL + (https?:\/\/)? # $2 Protocol (optional) + (#{Twitter::Regex[:valid_domain]}) # $3 Domain(s) + (?::(#{Twitter::Regex[:valid_port_number]}))? # $4 Port number (optional) + (/#{Twitter::Regex[:valid_url_path]}*)? # $5 URL Path and anchor + (\?#{Twitter::Regex[:valid_url_query_chars]}*#{Twitter::Regex[:valid_url_query_ending_chars]})? # $6 Query String + ) + }iox def call(status) @status = status @@ -14,11 +22,11 @@ class FetchLinkCardService < BaseService RedisLock.acquire(lock_options) do |lock| if lock.acquired? @card = PreviewCard.find_by(url: @url) - process_url if @card.nil? + process_url if @card.nil? || @card.updated_at <= 2.weeks.ago end end - attach_card unless @card.nil? + attach_card if @card&.persisted? rescue HTTP::ConnectionError, OpenSSL::SSL::SSLError nil end @@ -26,8 +34,8 @@ class FetchLinkCardService < BaseService private def process_url - @card = PreviewCard.new(url: @url) - res = Request.new(:head, @url).perform + @card ||= PreviewCard.new(url: @url) + res = Request.new(:head, @url).perform return if res.code != 200 || res.mime_type != 'text/html' @@ -40,7 +48,7 @@ class FetchLinkCardService < BaseService def parse_urls if @status.local? - urls = @status.text.match(URL_PATTERN).to_a.map { |uri| Addressable::URI.parse(uri).normalize } + urls = @status.text.scan(URL_PATTERN).map { |array| Addressable::URI.parse(array[0]).normalize } else html = Nokogiri::HTML(@status.text) links = html.css('a') @@ -106,12 +114,25 @@ class FetchLinkCardService < BaseService guess = detector.detect(html, response.charset) page = Nokogiri::HTML(html, nil, guess&.fetch(:encoding)) - @card.type = :link - @card.title = meta_property(page, 'og:title') || page.at_xpath('//title')&.content || '' - @card.description = meta_property(page, 'og:description') || meta_property(page, 'description') || '' - @card.image_remote_url = meta_property(page, 'og:image') if meta_property(page, 'og:image') + if meta_property(page, 'twitter:player') + @card.type = :video + @card.width = meta_property(page, 'twitter:player:width') || 0 + @card.height = meta_property(page, 'twitter:player:height') || 0 + @card.html = content_tag(:iframe, nil, src: meta_property(page, 'twitter:player'), + width: @card.width, + height: @card.height, + allowtransparency: 'true', + scrolling: 'no', + frameborder: '0') + else + @card.type = :link + @card.image_remote_url = meta_property(page, 'og:image') if meta_property(page, 'og:image') + end + + @card.title = meta_property(page, 'og:title').presence || page.at_xpath('//title')&.content || '' + @card.description = meta_property(page, 'og:description').presence || meta_property(page, 'description') || '' - return if @card.title.blank? + return if @card.title.blank? && @card.html.blank? @card.save_with_optional_image! end diff --git a/app/services/fetch_remote_account_service.rb b/app/services/fetch_remote_account_service.rb index 7c618a0b0..bd98e70d1 100644 --- a/app/services/fetch_remote_account_service.rb +++ b/app/services/fetch_remote_account_service.rb @@ -25,7 +25,7 @@ class FetchRemoteAccountService < BaseService xml = Nokogiri::XML(body) xml.encoding = 'utf-8' - account = author_from_xml(xml.at_xpath('/xmlns:feed', xmlns: TagManager::XMLNS), false) + account = author_from_xml(xml.at_xpath('/xmlns:feed', xmlns: OStatus::TagManager::XMLNS), false) UpdateRemoteProfileService.new.call(xml, account) unless account.nil? diff --git a/app/services/fetch_remote_status_service.rb b/app/services/fetch_remote_status_service.rb index 18af18059..1b90854c4 100644 --- a/app/services/fetch_remote_status_service.rb +++ b/app/services/fetch_remote_status_service.rb @@ -27,7 +27,7 @@ class FetchRemoteStatusService < BaseService xml = Nokogiri::XML(body) xml.encoding = 'utf-8' - account = author_from_xml(xml.at_xpath('/xmlns:entry', xmlns: TagManager::XMLNS)) + account = author_from_xml(xml.at_xpath('/xmlns:entry', xmlns: OStatus::TagManager::XMLNS)) domain = Addressable::URI.parse(url).normalized_host return nil unless !account.nil? && confirmed_domain?(domain, account) diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index e5b0fe438..d1b8f42c7 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -28,7 +28,7 @@ class PostStatusService < BaseService sensitive: options[:sensitive], spoiler_text: options[:spoiler_text] || '', visibility: options[:visibility] || account.user&.setting_default_privacy, - language: detect_language_for(text, account), + language: LanguageDetector.instance.detect(text, account), application: options[:application]) attach_media(status, media) @@ -73,10 +73,6 @@ class PostStatusService < BaseService media.update(status_id: status.id) end - def detect_language_for(text, account) - LanguageDetector.new(text, account).to_iso_s - end - def process_mentions_service @process_mentions_service ||= ProcessMentionsService.new end diff --git a/app/services/process_feed_service.rb b/app/services/process_feed_service.rb index 31191a818..2a5f1e2bc 100644 --- a/app/services/process_feed_service.rb +++ b/app/services/process_feed_service.rb @@ -16,7 +16,7 @@ class ProcessFeedService < BaseService end def process_entries(xml, account) - xml.xpath('//xmlns:entry', xmlns: TagManager::XMLNS).reverse_each.map { |entry| process_entry(entry, account) }.compact + xml.xpath('//xmlns:entry', xmlns: OStatus::TagManager::XMLNS).reverse_each.map { |entry| process_entry(entry, account) }.compact end def process_entry(xml, account) diff --git a/app/services/process_interaction_service.rb b/app/services/process_interaction_service.rb index d04e926e7..1fca3832b 100644 --- a/app/services/process_interaction_service.rb +++ b/app/services/process_interaction_service.rb @@ -13,7 +13,7 @@ class ProcessInteractionService < BaseService xml = Nokogiri::XML(body) xml.encoding = 'utf-8' - account = author_from_xml(xml.at_xpath('/xmlns:entry', xmlns: TagManager::XMLNS)) + account = author_from_xml(xml.at_xpath('/xmlns:entry', xmlns: OStatus::TagManager::XMLNS)) return if account.nil? || account.suspended? @@ -54,13 +54,13 @@ class ProcessInteractionService < BaseService private def mentions_account?(xml, account) - xml.xpath('/xmlns:entry/xmlns:link[@rel="mentioned"]', xmlns: TagManager::XMLNS).each { |mention_link| return true if [TagManager.instance.uri_for(account), TagManager.instance.url_for(account)].include?(mention_link.attribute('href').value) } + xml.xpath('/xmlns:entry/xmlns:link[@rel="mentioned"]', xmlns: OStatus::TagManager::XMLNS).each { |mention_link| return true if [OStatus::TagManager.instance.uri_for(account), OStatus::TagManager.instance.url_for(account)].include?(mention_link.attribute('href').value) } false end def verb(xml) - raw = xml.at_xpath('//activity:verb', activity: TagManager::AS_XMLNS).content - TagManager::VERBS.key(raw) + raw = xml.at_xpath('//activity:verb', activity: OStatus::TagManager::AS_XMLNS).content + OStatus::TagManager::VERBS.key(raw) rescue :post end @@ -104,7 +104,7 @@ class ProcessInteractionService < BaseService end def delete_post!(xml, account) - status = Status.find(xml.at_xpath('//xmlns:id', xmlns: TagManager::XMLNS).content) + status = Status.find(xml.at_xpath('//xmlns:id', xmlns: OStatus::TagManager::XMLNS).content) return if status.nil? @@ -137,12 +137,12 @@ class ProcessInteractionService < BaseService def status(xml) uri = activity_id(xml) - return nil unless TagManager.instance.local_id?(uri) - Status.find(TagManager.instance.unique_tag_to_local_id(uri, 'Status')) + return nil unless OStatus::TagManager.instance.local_id?(uri) + Status.find(OStatus::TagManager.instance.unique_tag_to_local_id(uri, 'Status')) end def activity_id(xml) - xml.at_xpath('//activity:object', activity: TagManager::AS_XMLNS).at_xpath('./xmlns:id', xmlns: TagManager::XMLNS).content + xml.at_xpath('//activity:object', activity: OStatus::TagManager::AS_XMLNS).at_xpath('./xmlns:id', xmlns: OStatus::TagManager::XMLNS).content end def salmon diff --git a/app/services/process_mentions_service.rb b/app/services/process_mentions_service.rb index f123bf869..1c3eea369 100644 --- a/app/services/process_mentions_service.rb +++ b/app/services/process_mentions_service.rb @@ -39,7 +39,7 @@ class ProcessMentionsService < BaseService if mentioned_account.local? NotifyService.new.call(mentioned_account, mention) - elsif mentioned_account.ostatus? && (Rails.configuration.x.use_ostatus_privacy || !status.stream_entry.hidden?) + elsif mentioned_account.ostatus? && !status.stream_entry.hidden? NotificationWorker.perform_async(stream_entry_to_xml(status.stream_entry), status.account_id, mentioned_account.id) elsif mentioned_account.activitypub? ActivityPub::DeliveryWorker.perform_async(build_json(mention.status), mention.status.account_id, mentioned_account.inbox_url) diff --git a/app/services/remove_status_service.rb b/app/services/remove_status_service.rb index 83fc77043..14f24908c 100644 --- a/app/services/remove_status_service.rb +++ b/app/services/remove_status_service.rb @@ -4,7 +4,7 @@ class RemoveStatusService < BaseService include StreamEntryRenderer def call(status) - @payload = Oj.dump(event: :delete, payload: status.id) + @payload = Oj.dump(event: :delete, payload: status.id.to_s) @status = status @account = status.account @tags = status.tags.pluck(:name).to_a @@ -14,6 +14,7 @@ class RemoveStatusService < BaseService remove_from_self if status.account.local? remove_from_followers + remove_from_affected remove_reblogs remove_from_hashtags remove_from_public @@ -38,6 +39,12 @@ class RemoveStatusService < BaseService end end + def remove_from_affected + @mentions.map(&:account).select(&:local?).each do |account| + Redis.current.publish("timeline:#{account.id}", @payload) + end + end + def remove_from_remote_affected # People who got mentioned in the status, or who # reblogged it from someone else might not follow @@ -105,6 +112,8 @@ class RemoveStatusService < BaseService end def remove_from_hashtags + return unless @status.public_visibility? + @tags.each do |hashtag| Redis.current.publish("timeline:hashtag:#{hashtag}", @payload) Redis.current.publish("timeline:hashtag:#{hashtag}:local", @payload) if @status.local? @@ -112,6 +121,8 @@ class RemoveStatusService < BaseService end def remove_from_public + return unless @status.public_visibility? + Redis.current.publish('timeline:public', @payload) Redis.current.publish('timeline:public:local', @payload) if @status.local? end diff --git a/app/services/resolve_remote_account_service.rb b/app/services/resolve_remote_account_service.rb index 7031c98f5..57c80fc82 100644 --- a/app/services/resolve_remote_account_service.rb +++ b/app/services/resolve_remote_account_service.rb @@ -80,6 +80,7 @@ class ResolveRemoteAccountService < BaseService def activitypub_ready? !@webfinger.link('self').nil? && ['application/activity+json', 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'].include?(@webfinger.link('self').type) && + !actor_json.nil? && actor_json['inbox'].present? end diff --git a/app/services/verify_salmon_service.rb b/app/services/verify_salmon_service.rb index cd674837d..205b35d8b 100644 --- a/app/services/verify_salmon_service.rb +++ b/app/services/verify_salmon_service.rb @@ -9,7 +9,7 @@ class VerifySalmonService < BaseService xml = Nokogiri::XML(body) xml.encoding = 'utf-8' - account = author_from_xml(xml.at_xpath('/xmlns:entry', xmlns: TagManager::XMLNS)) + account = author_from_xml(xml.at_xpath('/xmlns:entry', xmlns: OStatus::TagManager::XMLNS)) if account.nil? false |