diff options
author | Ondřej Hruška <ondra@ondrovo.com> | 2017-09-28 09:18:35 +0200 |
---|---|---|
committer | Ondřej Hruška <ondra@ondrovo.com> | 2017-09-28 09:18:35 +0200 |
commit | 83bda6c1a813c5aeb131b18a0500fed0c07fa9c2 (patch) | |
tree | 32f197901b4b16ea7f94de682fee6cdc44686045 /app/lib | |
parent | fcf0d2078ea813e0dd318fa154d620018e7b7bcf (diff) | |
parent | b9f59ebcc68e9da0a7158741a1a2ef3564e1321e (diff) |
Merge commit 'b9f59ebcc68e9da0a7158741a1a2ef3564e1321e' into merging-upstream
Diffstat (limited to 'app/lib')
-rw-r--r-- | app/lib/activitypub/activity/announce.rb | 2 | ||||
-rw-r--r-- | app/lib/activitypub/activity/create.rb | 14 | ||||
-rw-r--r-- | app/lib/activitypub/tag_manager.rb | 4 | ||||
-rw-r--r-- | app/lib/emoji.rb | 40 | ||||
-rw-r--r-- | app/lib/formatter.rb | 10 | ||||
-rw-r--r-- | app/lib/ostatus/activity/base.rb | 18 | ||||
-rw-r--r-- | app/lib/ostatus/activity/creation.rb | 54 | ||||
-rw-r--r-- | app/lib/ostatus/activity/share.rb | 2 | ||||
-rw-r--r-- | app/lib/ostatus/atom_serializer.rb | 106 | ||||
-rw-r--r-- | app/lib/ostatus/tag_manager.rb | 73 | ||||
-rw-r--r-- | app/lib/tag_manager.rb | 67 |
11 files changed, 192 insertions, 198 deletions
diff --git a/app/lib/activitypub/activity/announce.rb b/app/lib/activitypub/activity/announce.rb index 556f91235..4516454e1 100644 --- a/app/lib/activitypub/activity/announce.rb +++ b/app/lib/activitypub/activity/announce.rb @@ -25,6 +25,8 @@ class ActivityPub::Activity::Announce < ActivityPub::Activity def fetch_remote_original_status if object_uri.start_with?('http') + return if ActivityPub::TagManager.instance.local_uri?(object_uri) + ActivityPub::FetchRemoteStatusService.new.call(object_uri) elsif @object['url'].present? ::FetchRemoteStatusService.new.call(@object['url']) diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index 41f2b0bad..4e19b3096 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -68,6 +68,8 @@ class ActivityPub::Activity::Create < ActivityPub::Activity end def process_hashtag(tag, status) + return if tag['name'].blank? + hashtag = tag['name'].gsub(/\A#/, '').mb_chars.downcase hashtag = Tag.where(name: hashtag).first_or_initialize(name: hashtag) @@ -75,6 +77,8 @@ class ActivityPub::Activity::Create < ActivityPub::Activity end def process_mention(tag, status) + return if tag['href'].blank? + account = account_from_uri(tag['href']) account = FetchRemoteAccountService.new.call(tag['href']) if account.nil? return if account.nil? @@ -82,6 +86,8 @@ class ActivityPub::Activity::Create < ActivityPub::Activity end def process_emoji(tag, _status) + return if tag['name'].blank? || tag['href'].blank? + shortcode = tag['name'].delete(':') emoji = CustomEmoji.find_by(shortcode: shortcode, domain: @account.domain) @@ -96,7 +102,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity return unless @object['attachment'].is_a?(Array) @object['attachment'].each do |attachment| - next if unsupported_media_type?(attachment['mediaType']) + next if unsupported_media_type?(attachment['mediaType']) || attachment['url'].blank? href = Addressable::URI.parse(attachment['url']).normalize.to_s media_attachment = MediaAttachment.create(status: status, account: status.account, remote_url: href) @@ -106,6 +112,8 @@ class ActivityPub::Activity::Create < ActivityPub::Activity media_attachment.file_remote_url = href media_attachment.save end + rescue Addressable::URI::InvalidURIError => e + Rails.logger.debug e end def resolve_thread(status) @@ -115,8 +123,8 @@ class ActivityPub::Activity::Create < ActivityPub::Activity def conversation_from_uri(uri) return nil if uri.nil? - return Conversation.find_by(id: TagManager.instance.unique_tag_to_local_id(uri, 'Conversation')) if TagManager.instance.local_id?(uri) - Conversation.find_by(uri: uri) || Conversation.create!(uri: uri) + return Conversation.find_by(id: OStatus::TagManager.instance.unique_tag_to_local_id(uri, 'Conversation')) if OStatus::TagManager.instance.local_id?(uri) + Conversation.find_by(uri: uri) || Conversation.create(uri: uri) end def visibility_from_audience diff --git a/app/lib/activitypub/tag_manager.rb b/app/lib/activitypub/tag_manager.rb index 1b4e271db..4ec3b8c56 100644 --- a/app/lib/activitypub/tag_manager.rb +++ b/app/lib/activitypub/tag_manager.rb @@ -98,8 +98,8 @@ class ActivityPub::TagManager else StatusFinder.new(uri).status end - elsif ::TagManager.instance.local_id?(uri) - klass.find_by(id: ::TagManager.instance.unique_tag_to_local_id(uri, klass.to_s)) + elsif OStatus::TagManager.instance.local_id?(uri) + klass.find_by(id: OStatus::TagManager.instance.unique_tag_to_local_id(uri, klass.to_s)) else klass.find_by(uri: uri.split('#').first) end diff --git a/app/lib/emoji.rb b/app/lib/emoji.rb deleted file mode 100644 index 45b7f53de..000000000 --- a/app/lib/emoji.rb +++ /dev/null @@ -1,40 +0,0 @@ -# frozen_string_literal: true - -require 'singleton' - -class Emoji - include Singleton - - def initialize - data = Oj.load(File.open(Rails.root.join('lib', 'assets', 'emoji.json'))) - - @map = {} - - data.each do |_, emoji| - keys = [emoji['shortname']] + emoji['aliases'] - unicode = codepoint_to_unicode(emoji['unicode']) - - keys.each do |key| - @map[key] = unicode - end - end - end - - def unicode(shortcode) - @map[shortcode] - end - - def names - @map.keys - end - - private - - def codepoint_to_unicode(codepoint) - if codepoint.include?('-') - codepoint.split('-').map(&:hex).pack('U*') - else - [codepoint.hex].pack('U') - end - end -end diff --git a/app/lib/formatter.rb b/app/lib/formatter.rb index 29fea27de..42cd72990 100644 --- a/app/lib/formatter.rb +++ b/app/lib/formatter.rb @@ -22,7 +22,7 @@ class Formatter unless status.local? html = reformat(raw_content) html = encode_custom_emojis(html, status.emojis) if options[:custom_emojify] - return html + return html.html_safe # rubocop:disable Rails/OutputSafety end linkable_accounts = status.mentions.map(&:account) @@ -39,7 +39,7 @@ class Formatter end def reformat(html) - sanitize(html, Sanitize::Config::MASTODON_STRICT).html_safe # rubocop:disable Rails/OutputSafety + sanitize(html, Sanitize::Config::MASTODON_STRICT) end def plaintext(status) @@ -63,6 +63,12 @@ class Formatter Sanitize.fragment(html, config) end + def format_spoiler(status) + html = encode(status.spoiler_text) + html = encode_custom_emojis(html, status.emojis) + html.html_safe # rubocop:disable Rails/OutputSafety + end + private def encode(html) diff --git a/app/lib/ostatus/activity/base.rb b/app/lib/ostatus/activity/base.rb index 1dc7abee3..039381397 100644 --- a/app/lib/ostatus/activity/base.rb +++ b/app/lib/ostatus/activity/base.rb @@ -11,30 +11,30 @@ class OStatus::Activity::Base end def verb - 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 def type - raw = @xml.at_xpath('./activity:object-type', activity: TagManager::AS_XMLNS).content - TagManager::TYPES.key(raw) + raw = @xml.at_xpath('./activity:object-type', activity: OStatus::TagManager::AS_XMLNS).content + OStatus::TagManager::TYPES.key(raw) rescue :activity end def id - @xml.at_xpath('./xmlns:id', xmlns: TagManager::XMLNS).content + @xml.at_xpath('./xmlns:id', xmlns: OStatus::TagManager::XMLNS).content end def url - link = @xml.xpath('./xmlns:link[@rel="alternate"]', xmlns: TagManager::XMLNS).find { |link_candidate| link_candidate['type'] == 'text/html' } + link = @xml.xpath('./xmlns:link[@rel="alternate"]', xmlns: OStatus::TagManager::XMLNS).find { |link_candidate| link_candidate['type'] == 'text/html' } link.nil? ? nil : link['href'] end def activitypub_uri - link = @xml.xpath('./xmlns:link[@rel="alternate"]', xmlns: TagManager::XMLNS).find { |link_candidate| ['application/activity+json', 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'].include?(link_candidate['type']) } + link = @xml.xpath('./xmlns:link[@rel="alternate"]', xmlns: OStatus::TagManager::XMLNS).find { |link_candidate| ['application/activity+json', 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'].include?(link_candidate['type']) } link.nil? ? nil : link['href'] end @@ -45,8 +45,8 @@ class OStatus::Activity::Base private def find_status(uri) - if TagManager.instance.local_id?(uri) - local_id = TagManager.instance.unique_tag_to_local_id(uri, 'Status') + if OStatus::TagManager.instance.local_id?(uri) + local_id = OStatus::TagManager.instance.unique_tag_to_local_id(uri, 'Status') return Status.find_by(id: local_id) elsif ActivityPub::TagManager.instance.local_uri?(uri) local_id = ActivityPub::TagManager.instance.uri_to_local_id(uri) diff --git a/app/lib/ostatus/activity/creation.rb b/app/lib/ostatus/activity/creation.rb index d3f1629c4..2687776f9 100644 --- a/app/lib/ostatus/activity/creation.rb +++ b/app/lib/ostatus/activity/creation.rb @@ -14,14 +14,22 @@ class OStatus::Activity::Creation < OStatus::Activity::Base return result if result.first.present? end - Rails.logger.debug "Creating remote status #{id}" - - # Return early if status already exists in db - status = find_status(id) + RedisLock.acquire(lock_options) do |lock| + if lock.acquired? + # Return early if status already exists in db + @status = find_status(id) + return [@status, false] unless @status.nil? + @status = process_status + end + end - return [status, false] unless status.nil? + [@status, true] + end + def process_status + Rails.logger.debug "Creating remote status #{id}" cached_reblog = reblog + status = nil ApplicationRecord.transaction do status = Status.create!( @@ -55,7 +63,7 @@ class OStatus::Activity::Creation < OStatus::Activity::Base LinkCrawlWorker.perform_async(status.id) unless status.spoiler_text? DistributionWorker.perform_async(status.id) - [status, true] + status end def perform_via_activitypub @@ -63,42 +71,42 @@ class OStatus::Activity::Creation < OStatus::Activity::Base end def content - @xml.at_xpath('./xmlns:content', xmlns: TagManager::XMLNS).content + @xml.at_xpath('./xmlns:content', xmlns: OStatus::TagManager::XMLNS).content end def content_language - @xml.at_xpath('./xmlns:content', xmlns: TagManager::XMLNS)['xml:lang']&.presence || 'en' + @xml.at_xpath('./xmlns:content', xmlns: OStatus::TagManager::XMLNS)['xml:lang']&.presence || 'en' end def content_warning - @xml.at_xpath('./xmlns:summary', xmlns: TagManager::XMLNS)&.content || '' + @xml.at_xpath('./xmlns:summary', xmlns: OStatus::TagManager::XMLNS)&.content || '' end def visibility_scope - @xml.at_xpath('./mastodon:scope', mastodon: TagManager::MTDN_XMLNS)&.content&.to_sym || :public + @xml.at_xpath('./mastodon:scope', mastodon: OStatus::TagManager::MTDN_XMLNS)&.content&.to_sym || :public end def published - @xml.at_xpath('./xmlns:published', xmlns: TagManager::XMLNS).content + @xml.at_xpath('./xmlns:published', xmlns: OStatus::TagManager::XMLNS).content end def thread? - !@xml.at_xpath('./thr:in-reply-to', thr: TagManager::THR_XMLNS).nil? + !@xml.at_xpath('./thr:in-reply-to', thr: OStatus::TagManager::THR_XMLNS).nil? end def thread - thr = @xml.at_xpath('./thr:in-reply-to', thr: TagManager::THR_XMLNS) + thr = @xml.at_xpath('./thr:in-reply-to', thr: OStatus::TagManager::THR_XMLNS) [thr['ref'], thr['href']] end private def find_or_create_conversation - uri = @xml.at_xpath('./ostatus:conversation', ostatus: TagManager::OS_XMLNS)&.attribute('ref')&.content + uri = @xml.at_xpath('./ostatus:conversation', ostatus: OStatus::TagManager::OS_XMLNS)&.attribute('ref')&.content return if uri.nil? - if TagManager.instance.local_id?(uri) - local_id = TagManager.instance.unique_tag_to_local_id(uri, 'Conversation') + if OStatus::TagManager.instance.local_id?(uri) + local_id = OStatus::TagManager.instance.unique_tag_to_local_id(uri, 'Conversation') return Conversation.find_by(id: local_id) end @@ -108,8 +116,8 @@ class OStatus::Activity::Creation < OStatus::Activity::Base def save_mentions(parent) processed_account_ids = [] - @xml.xpath('./xmlns:link[@rel="mentioned"]', xmlns: TagManager::XMLNS).each do |link| - next if [TagManager::TYPES[:group], TagManager::TYPES[:collection]].include? link['ostatus:object-type'] + @xml.xpath('./xmlns:link[@rel="mentioned"]', xmlns: OStatus::TagManager::XMLNS).each do |link| + next if [OStatus::TagManager::TYPES[:group], OStatus::TagManager::TYPES[:collection]].include? link['ostatus:object-type'] mentioned_account = account_from_href(link['href']) @@ -123,14 +131,14 @@ class OStatus::Activity::Creation < OStatus::Activity::Base end def save_hashtags(parent) - tags = @xml.xpath('./xmlns:category', xmlns: TagManager::XMLNS).map { |category| category['term'] }.select(&:present?) + tags = @xml.xpath('./xmlns:category', xmlns: OStatus::TagManager::XMLNS).map { |category| category['term'] }.select(&:present?) ProcessHashtagsService.new.call(parent, tags) end def save_media(parent) do_not_download = DomainBlock.find_by(domain: parent.account.domain)&.reject_media? - @xml.xpath('./xmlns:link[@rel="enclosure"]', xmlns: TagManager::XMLNS).each do |link| + @xml.xpath('./xmlns:link[@rel="enclosure"]', xmlns: OStatus::TagManager::XMLNS).each do |link| next unless link['href'] media = MediaAttachment.where(status: parent, remote_url: link['href']).first_or_initialize(account: parent.account, status: parent, remote_url: link['href']) @@ -156,7 +164,7 @@ class OStatus::Activity::Creation < OStatus::Activity::Base return if do_not_download - @xml.xpath('./xmlns:link[@rel="emoji"]', xmlns: TagManager::XMLNS).each do |link| + @xml.xpath('./xmlns:link[@rel="emoji"]', xmlns: OStatus::TagManager::XMLNS).each do |link| next unless link['href'] && link['name'] shortcode = link['name'].delete(':') @@ -179,4 +187,8 @@ class OStatus::Activity::Creation < OStatus::Activity::Base Account.where(uri: href).or(Account.where(url: href)).first || FetchRemoteAccountService.new.call(href) end end + + def lock_options + { redis: Redis.current, key: "create:#{id}" } + end end diff --git a/app/lib/ostatus/activity/share.rb b/app/lib/ostatus/activity/share.rb index 290008021..5ca601415 100644 --- a/app/lib/ostatus/activity/share.rb +++ b/app/lib/ostatus/activity/share.rb @@ -10,7 +10,7 @@ class OStatus::Activity::Share < OStatus::Activity::Creation end def object - @xml.at_xpath('.//activity:object', activity: TagManager::AS_XMLNS) + @xml.at_xpath('.//activity:object', activity: OStatus::TagManager::AS_XMLNS) end private diff --git a/app/lib/ostatus/atom_serializer.rb b/app/lib/ostatus/atom_serializer.rb index a6a5cb0c4..a1ac11a51 100644 --- a/app/lib/ostatus/atom_serializer.rb +++ b/app/lib/ostatus/atom_serializer.rb @@ -15,10 +15,10 @@ class OStatus::AtomSerializer def author(account) author = Ox::Element.new('author') - uri = TagManager.instance.uri_for(account) + uri = OStatus::TagManager.instance.uri_for(account) append_element(author, 'id', uri) - append_element(author, 'activity:object-type', TagManager::TYPES[:person]) + append_element(author, 'activity:object-type', OStatus::TagManager::TYPES[:person]) append_element(author, 'uri', uri) append_element(author, 'name', account.username) append_element(author, 'email', account.local? ? account.local_username_and_domain : account.acct) @@ -65,15 +65,15 @@ class OStatus::AtomSerializer add_namespaces(entry) if root - append_element(entry, 'id', TagManager.instance.uri_for(stream_entry.status)) + append_element(entry, 'id', OStatus::TagManager.instance.uri_for(stream_entry.status)) append_element(entry, 'published', stream_entry.created_at.iso8601) append_element(entry, 'updated', stream_entry.updated_at.iso8601) append_element(entry, 'title', stream_entry&.status&.title || "#{stream_entry.account.acct} deleted status") entry << author(stream_entry.account) if root - append_element(entry, 'activity:object-type', TagManager::TYPES[stream_entry.object_type]) - append_element(entry, 'activity:verb', TagManager::VERBS[stream_entry.verb]) + append_element(entry, 'activity:object-type', OStatus::TagManager::TYPES[stream_entry.object_type]) + append_element(entry, 'activity:verb', OStatus::TagManager::VERBS[stream_entry.verb]) entry << object(stream_entry.target) if stream_entry.targeted? @@ -88,7 +88,7 @@ class OStatus::AtomSerializer append_element(entry, 'link', nil, rel: :alternate, type: 'text/html', href: TagManager.instance.url_for(stream_entry.status)) append_element(entry, 'link', nil, rel: :self, type: 'application/atom+xml', href: account_stream_entry_url(stream_entry.account, stream_entry, format: 'atom')) - append_element(entry, 'thr:in-reply-to', nil, ref: TagManager.instance.uri_for(stream_entry.thread), href: TagManager.instance.url_for(stream_entry.thread)) if stream_entry.threaded? + append_element(entry, 'thr:in-reply-to', nil, ref: OStatus::TagManager.instance.uri_for(stream_entry.thread), href: TagManager.instance.url_for(stream_entry.thread)) if stream_entry.threaded? append_element(entry, 'ostatus:conversation', nil, ref: conversation_uri(stream_entry.status.conversation)) unless stream_entry&.status&.conversation_id.nil? entry @@ -97,20 +97,20 @@ class OStatus::AtomSerializer def object(status) object = Ox::Element.new('activity:object') - append_element(object, 'id', TagManager.instance.uri_for(status)) + append_element(object, 'id', OStatus::TagManager.instance.uri_for(status)) append_element(object, 'published', status.created_at.iso8601) append_element(object, 'updated', status.updated_at.iso8601) append_element(object, 'title', status.title) object << author(status.account) - append_element(object, 'activity:object-type', TagManager::TYPES[status.object_type]) - append_element(object, 'activity:verb', TagManager::VERBS[status.verb]) + append_element(object, 'activity:object-type', OStatus::TagManager::TYPES[status.object_type]) + append_element(object, 'activity:verb', OStatus::TagManager::VERBS[status.verb]) serialize_status_attributes(object, status) append_element(object, 'link', nil, rel: :alternate, type: 'text/html', href: TagManager.instance.url_for(status)) - append_element(object, 'thr:in-reply-to', nil, ref: TagManager.instance.uri_for(status.thread), href: TagManager.instance.url_for(status.thread)) unless status.thread.nil? + append_element(object, 'thr:in-reply-to', nil, ref: OStatus::TagManager.instance.uri_for(status.thread), href: TagManager.instance.url_for(status.thread)) unless status.thread.nil? append_element(object, 'ostatus:conversation', nil, ref: conversation_uri(status.conversation)) unless status.conversation_id.nil? object @@ -122,14 +122,14 @@ class OStatus::AtomSerializer description = "#{follow.account.acct} started following #{follow.target_account.acct}" - append_element(entry, 'id', TagManager.instance.unique_tag(follow.created_at, follow.id, 'Follow')) + append_element(entry, 'id', OStatus::TagManager.instance.unique_tag(follow.created_at, follow.id, 'Follow')) append_element(entry, 'title', description) append_element(entry, 'content', description, type: :html) entry << author(follow.account) - append_element(entry, 'activity:object-type', TagManager::TYPES[:activity]) - append_element(entry, 'activity:verb', TagManager::VERBS[:follow]) + append_element(entry, 'activity:object-type', OStatus::TagManager::TYPES[:activity]) + append_element(entry, 'activity:verb', OStatus::TagManager::VERBS[:follow]) object = author(follow.target_account) object.value = 'activity:object' @@ -142,13 +142,13 @@ class OStatus::AtomSerializer entry = Ox::Element.new('entry') add_namespaces(entry) - append_element(entry, 'id', TagManager.instance.unique_tag(follow_request.created_at, follow_request.id, 'FollowRequest')) + append_element(entry, 'id', OStatus::TagManager.instance.unique_tag(follow_request.created_at, follow_request.id, 'FollowRequest')) append_element(entry, 'title', "#{follow_request.account.acct} requested to follow #{follow_request.target_account.acct}") entry << author(follow_request.account) - append_element(entry, 'activity:object-type', TagManager::TYPES[:activity]) - append_element(entry, 'activity:verb', TagManager::VERBS[:request_friend]) + append_element(entry, 'activity:object-type', OStatus::TagManager::TYPES[:activity]) + append_element(entry, 'activity:verb', OStatus::TagManager::VERBS[:request_friend]) object = author(follow_request.target_account) object.value = 'activity:object' @@ -161,19 +161,19 @@ class OStatus::AtomSerializer entry = Ox::Element.new('entry') add_namespaces(entry) - append_element(entry, 'id', TagManager.instance.unique_tag(Time.now.utc, follow_request.id, 'FollowRequest')) + append_element(entry, 'id', OStatus::TagManager.instance.unique_tag(Time.now.utc, follow_request.id, 'FollowRequest')) append_element(entry, 'title', "#{follow_request.target_account.acct} authorizes follow request by #{follow_request.account.acct}") entry << author(follow_request.target_account) - append_element(entry, 'activity:object-type', TagManager::TYPES[:activity]) - append_element(entry, 'activity:verb', TagManager::VERBS[:authorize]) + append_element(entry, 'activity:object-type', OStatus::TagManager::TYPES[:activity]) + append_element(entry, 'activity:verb', OStatus::TagManager::VERBS[:authorize]) object = Ox::Element.new('activity:object') object << author(follow_request.account) - append_element(object, 'activity:object-type', TagManager::TYPES[:activity]) - append_element(object, 'activity:verb', TagManager::VERBS[:request_friend]) + append_element(object, 'activity:object-type', OStatus::TagManager::TYPES[:activity]) + append_element(object, 'activity:verb', OStatus::TagManager::VERBS[:request_friend]) inner_object = author(follow_request.target_account) inner_object.value = 'activity:object' @@ -187,19 +187,19 @@ class OStatus::AtomSerializer entry = Ox::Element.new('entry') add_namespaces(entry) - append_element(entry, 'id', TagManager.instance.unique_tag(Time.now.utc, follow_request.id, 'FollowRequest')) + append_element(entry, 'id', OStatus::TagManager.instance.unique_tag(Time.now.utc, follow_request.id, 'FollowRequest')) append_element(entry, 'title', "#{follow_request.target_account.acct} rejects follow request by #{follow_request.account.acct}") entry << author(follow_request.target_account) - append_element(entry, 'activity:object-type', TagManager::TYPES[:activity]) - append_element(entry, 'activity:verb', TagManager::VERBS[:reject]) + append_element(entry, 'activity:object-type', OStatus::TagManager::TYPES[:activity]) + append_element(entry, 'activity:verb', OStatus::TagManager::VERBS[:reject]) object = Ox::Element.new('activity:object') object << author(follow_request.account) - append_element(object, 'activity:object-type', TagManager::TYPES[:activity]) - append_element(object, 'activity:verb', TagManager::VERBS[:request_friend]) + append_element(object, 'activity:object-type', OStatus::TagManager::TYPES[:activity]) + append_element(object, 'activity:verb', OStatus::TagManager::VERBS[:request_friend]) inner_object = author(follow_request.target_account) inner_object.value = 'activity:object' @@ -215,14 +215,14 @@ class OStatus::AtomSerializer description = "#{follow.account.acct} is no longer following #{follow.target_account.acct}" - append_element(entry, 'id', TagManager.instance.unique_tag(Time.now.utc, follow.id, 'Follow')) + append_element(entry, 'id', OStatus::TagManager.instance.unique_tag(Time.now.utc, follow.id, 'Follow')) append_element(entry, 'title', description) append_element(entry, 'content', description, type: :html) entry << author(follow.account) - append_element(entry, 'activity:object-type', TagManager::TYPES[:activity]) - append_element(entry, 'activity:verb', TagManager::VERBS[:unfollow]) + append_element(entry, 'activity:object-type', OStatus::TagManager::TYPES[:activity]) + append_element(entry, 'activity:verb', OStatus::TagManager::VERBS[:unfollow]) object = author(follow.target_account) object.value = 'activity:object' @@ -237,13 +237,13 @@ class OStatus::AtomSerializer description = "#{block.account.acct} no longer wishes to interact with #{block.target_account.acct}" - append_element(entry, 'id', TagManager.instance.unique_tag(Time.now.utc, block.id, 'Block')) + append_element(entry, 'id', OStatus::TagManager.instance.unique_tag(Time.now.utc, block.id, 'Block')) append_element(entry, 'title', description) entry << author(block.account) - append_element(entry, 'activity:object-type', TagManager::TYPES[:activity]) - append_element(entry, 'activity:verb', TagManager::VERBS[:block]) + append_element(entry, 'activity:object-type', OStatus::TagManager::TYPES[:activity]) + append_element(entry, 'activity:verb', OStatus::TagManager::VERBS[:block]) object = author(block.target_account) object.value = 'activity:object' @@ -258,13 +258,13 @@ class OStatus::AtomSerializer description = "#{block.account.acct} no longer blocks #{block.target_account.acct}" - append_element(entry, 'id', TagManager.instance.unique_tag(Time.now.utc, block.id, 'Block')) + append_element(entry, 'id', OStatus::TagManager.instance.unique_tag(Time.now.utc, block.id, 'Block')) append_element(entry, 'title', description) entry << author(block.account) - append_element(entry, 'activity:object-type', TagManager::TYPES[:activity]) - append_element(entry, 'activity:verb', TagManager::VERBS[:unblock]) + append_element(entry, 'activity:object-type', OStatus::TagManager::TYPES[:activity]) + append_element(entry, 'activity:verb', OStatus::TagManager::VERBS[:unblock]) object = author(block.target_account) object.value = 'activity:object' @@ -279,18 +279,18 @@ class OStatus::AtomSerializer description = "#{favourite.account.acct} favourited a status by #{favourite.status.account.acct}" - append_element(entry, 'id', TagManager.instance.unique_tag(favourite.created_at, favourite.id, 'Favourite')) + append_element(entry, 'id', OStatus::TagManager.instance.unique_tag(favourite.created_at, favourite.id, 'Favourite')) append_element(entry, 'title', description) append_element(entry, 'content', description, type: :html) entry << author(favourite.account) - append_element(entry, 'activity:object-type', TagManager::TYPES[:activity]) - append_element(entry, 'activity:verb', TagManager::VERBS[:favorite]) + append_element(entry, 'activity:object-type', OStatus::TagManager::TYPES[:activity]) + append_element(entry, 'activity:verb', OStatus::TagManager::VERBS[:favorite]) entry << object(favourite.status) - append_element(entry, 'thr:in-reply-to', nil, ref: TagManager.instance.uri_for(favourite.status), href: TagManager.instance.url_for(favourite.status)) + append_element(entry, 'thr:in-reply-to', nil, ref: OStatus::TagManager.instance.uri_for(favourite.status), href: TagManager.instance.url_for(favourite.status)) entry end @@ -301,18 +301,18 @@ class OStatus::AtomSerializer description = "#{favourite.account.acct} no longer favourites a status by #{favourite.status.account.acct}" - append_element(entry, 'id', TagManager.instance.unique_tag(Time.now.utc, favourite.id, 'Favourite')) + append_element(entry, 'id', OStatus::TagManager.instance.unique_tag(Time.now.utc, favourite.id, 'Favourite')) append_element(entry, 'title', description) append_element(entry, 'content', description, type: :html) entry << author(favourite.account) - append_element(entry, 'activity:object-type', TagManager::TYPES[:activity]) - append_element(entry, 'activity:verb', TagManager::VERBS[:unfavorite]) + append_element(entry, 'activity:object-type', OStatus::TagManager::TYPES[:activity]) + append_element(entry, 'activity:verb', OStatus::TagManager::VERBS[:unfavorite]) entry << object(favourite.status) - append_element(entry, 'thr:in-reply-to', nil, ref: TagManager.instance.uri_for(favourite.status), href: TagManager.instance.url_for(favourite.status)) + append_element(entry, 'thr:in-reply-to', nil, ref: OStatus::TagManager.instance.uri_for(favourite.status), href: TagManager.instance.url_for(favourite.status)) entry end @@ -332,17 +332,17 @@ class OStatus::AtomSerializer def conversation_uri(conversation) return conversation.uri if conversation.uri? - TagManager.instance.unique_tag(conversation.created_at, conversation.id, 'Conversation') + OStatus::TagManager.instance.unique_tag(conversation.created_at, conversation.id, 'Conversation') end def add_namespaces(parent) - parent['xmlns'] = TagManager::XMLNS - parent['xmlns:thr'] = TagManager::THR_XMLNS - parent['xmlns:activity'] = TagManager::AS_XMLNS - parent['xmlns:poco'] = TagManager::POCO_XMLNS - parent['xmlns:media'] = TagManager::MEDIA_XMLNS - parent['xmlns:ostatus'] = TagManager::OS_XMLNS - parent['xmlns:mastodon'] = TagManager::MTDN_XMLNS + parent['xmlns'] = OStatus::TagManager::XMLNS + parent['xmlns:thr'] = OStatus::TagManager::THR_XMLNS + parent['xmlns:activity'] = OStatus::TagManager::AS_XMLNS + parent['xmlns:poco'] = OStatus::TagManager::POCO_XMLNS + parent['xmlns:media'] = OStatus::TagManager::MEDIA_XMLNS + parent['xmlns:ostatus'] = OStatus::TagManager::OS_XMLNS + parent['xmlns:mastodon'] = OStatus::TagManager::MTDN_XMLNS end def serialize_status_attributes(entry, status) @@ -352,10 +352,10 @@ class OStatus::AtomSerializer append_element(entry, 'content', Formatter.instance.format(status).to_str, type: 'html', 'xml:lang': status.language) status.mentions.each do |mentioned| - append_element(entry, 'link', nil, rel: :mentioned, 'ostatus:object-type': TagManager::TYPES[:person], href: TagManager.instance.uri_for(mentioned.account)) + append_element(entry, 'link', nil, rel: :mentioned, 'ostatus:object-type': OStatus::TagManager::TYPES[:person], href: OStatus::TagManager.instance.uri_for(mentioned.account)) end - append_element(entry, 'link', nil, rel: :mentioned, 'ostatus:object-type': TagManager::TYPES[:collection], href: TagManager::COLLECTIONS[:public]) if status.public_visibility? + append_element(entry, 'link', nil, rel: :mentioned, 'ostatus:object-type': OStatus::TagManager::TYPES[:collection], href: OStatus::TagManager::COLLECTIONS[:public]) if status.public_visibility? status.tags.each do |tag| append_element(entry, 'category', nil, term: tag.name) diff --git a/app/lib/ostatus/tag_manager.rb b/app/lib/ostatus/tag_manager.rb new file mode 100644 index 000000000..4f4501312 --- /dev/null +++ b/app/lib/ostatus/tag_manager.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true + +class OStatus::TagManager + include Singleton + include RoutingHelper + + VERBS = { + post: 'http://activitystrea.ms/schema/1.0/post', + share: 'http://activitystrea.ms/schema/1.0/share', + favorite: 'http://activitystrea.ms/schema/1.0/favorite', + unfavorite: 'http://activitystrea.ms/schema/1.0/unfavorite', + delete: 'http://activitystrea.ms/schema/1.0/delete', + follow: 'http://activitystrea.ms/schema/1.0/follow', + request_friend: 'http://activitystrea.ms/schema/1.0/request-friend', + authorize: 'http://activitystrea.ms/schema/1.0/authorize', + reject: 'http://activitystrea.ms/schema/1.0/reject', + unfollow: 'http://ostatus.org/schema/1.0/unfollow', + block: 'http://mastodon.social/schema/1.0/block', + unblock: 'http://mastodon.social/schema/1.0/unblock', + }.freeze + + TYPES = { + activity: 'http://activitystrea.ms/schema/1.0/activity', + note: 'http://activitystrea.ms/schema/1.0/note', + comment: 'http://activitystrea.ms/schema/1.0/comment', + person: 'http://activitystrea.ms/schema/1.0/person', + collection: 'http://activitystrea.ms/schema/1.0/collection', + group: 'http://activitystrea.ms/schema/1.0/group', + }.freeze + + COLLECTIONS = { + public: 'http://activityschema.org/collection/public', + }.freeze + + XMLNS = 'http://www.w3.org/2005/Atom' + MEDIA_XMLNS = 'http://purl.org/syndication/atommedia' + AS_XMLNS = 'http://activitystrea.ms/spec/1.0/' + THR_XMLNS = 'http://purl.org/syndication/thread/1.0' + POCO_XMLNS = 'http://portablecontacts.net/spec/1.0' + DFRN_XMLNS = 'http://purl.org/macgirvin/dfrn/1.0' + OS_XMLNS = 'http://ostatus.org/schema/1.0' + MTDN_XMLNS = 'http://mastodon.social/schema/1.0' + + def unique_tag(date, id, type) + "tag:#{Rails.configuration.x.local_domain},#{date.strftime('%Y-%m-%d')}:objectId=#{id}:objectType=#{type}" + end + + def unique_tag_to_local_id(tag, expected_type) + return nil unless local_id?(tag) + + if ActivityPub::TagManager.instance.local_uri?(tag) + ActivityPub::TagManager.instance.uri_to_local_id(tag) + else + matches = Regexp.new("objectId=([\\d]+):objectType=#{expected_type}").match(tag) + return matches[1] unless matches.nil? + end + end + + def local_id?(id) + id.start_with?("tag:#{Rails.configuration.x.local_domain}") || ActivityPub::TagManager.instance.local_uri?(id) + end + + def uri_for(target) + return target.uri if target.respond_to?(:local?) && !target.local? + + case target.object_type + when :person + account_url(target) + when :note, :comment, :activity + target.uri || unique_tag(target.created_at, target.id, 'Status') + end + end +end diff --git a/app/lib/tag_manager.rb b/app/lib/tag_manager.rb index 1d0a24e42..fb364cb98 100644 --- a/app/lib/tag_manager.rb +++ b/app/lib/tag_manager.rb @@ -6,62 +6,6 @@ class TagManager include Singleton include RoutingHelper - VERBS = { - post: 'http://activitystrea.ms/schema/1.0/post', - share: 'http://activitystrea.ms/schema/1.0/share', - favorite: 'http://activitystrea.ms/schema/1.0/favorite', - unfavorite: 'http://activitystrea.ms/schema/1.0/unfavorite', - delete: 'http://activitystrea.ms/schema/1.0/delete', - follow: 'http://activitystrea.ms/schema/1.0/follow', - request_friend: 'http://activitystrea.ms/schema/1.0/request-friend', - authorize: 'http://activitystrea.ms/schema/1.0/authorize', - reject: 'http://activitystrea.ms/schema/1.0/reject', - unfollow: 'http://ostatus.org/schema/1.0/unfollow', - block: 'http://mastodon.social/schema/1.0/block', - unblock: 'http://mastodon.social/schema/1.0/unblock', - }.freeze - - TYPES = { - activity: 'http://activitystrea.ms/schema/1.0/activity', - note: 'http://activitystrea.ms/schema/1.0/note', - comment: 'http://activitystrea.ms/schema/1.0/comment', - person: 'http://activitystrea.ms/schema/1.0/person', - collection: 'http://activitystrea.ms/schema/1.0/collection', - group: 'http://activitystrea.ms/schema/1.0/group', - }.freeze - - COLLECTIONS = { - public: 'http://activityschema.org/collection/public', - }.freeze - - XMLNS = 'http://www.w3.org/2005/Atom' - MEDIA_XMLNS = 'http://purl.org/syndication/atommedia' - AS_XMLNS = 'http://activitystrea.ms/spec/1.0/' - THR_XMLNS = 'http://purl.org/syndication/thread/1.0' - POCO_XMLNS = 'http://portablecontacts.net/spec/1.0' - DFRN_XMLNS = 'http://purl.org/macgirvin/dfrn/1.0' - OS_XMLNS = 'http://ostatus.org/schema/1.0' - MTDN_XMLNS = 'http://mastodon.social/schema/1.0' - - def unique_tag(date, id, type) - "tag:#{Rails.configuration.x.local_domain},#{date.strftime('%Y-%m-%d')}:objectId=#{id}:objectType=#{type}" - end - - def unique_tag_to_local_id(tag, expected_type) - return nil unless local_id?(tag) - - if ActivityPub::TagManager.instance.local_uri?(tag) - ActivityPub::TagManager.instance.uri_to_local_id(tag) - else - matches = Regexp.new("objectId=([\\d]+):objectType=#{expected_type}").match(tag) - return matches[1] unless matches.nil? - end - end - - def local_id?(id) - id.start_with?("tag:#{Rails.configuration.x.local_domain}") || ActivityPub::TagManager.instance.local_uri?(id) - end - def web_domain?(domain) domain.nil? || domain.gsub(/[\/]/, '').casecmp(Rails.configuration.x.web_domain).zero? end @@ -90,17 +34,6 @@ class TagManager TagManager.instance.web_domain?(domain) end - def uri_for(target) - return target.uri if target.respond_to?(:local?) && !target.local? - - case target.object_type - when :person - account_url(target) - when :note, :comment, :activity - target.uri || unique_tag(target.created_at, target.id, 'Status') - end - end - def url_for(target) return target.url if target.respond_to?(:local?) && !target.local? |