Merge commit 'b9f59ebcc68e9da0a7158741a1a2ef3564e1321e' into merging-upstream
This commit is contained in:
@ -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'])
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -14,14 +14,22 @@ class OStatus::Activity::Creation < OStatus::Activity::Base
|
||||
return result if result.first.present?
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
[@status, true]
|
||||
end
|
||||
|
||||
def process_status
|
||||
Rails.logger.debug "Creating remote status #{id}"
|
||||
|
||||
# Return early if status already exists in db
|
||||
status = find_status(id)
|
||||
|
||||
return [status, false] unless status.nil?
|
||||
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
73
app/lib/ostatus/tag_manager.rb
Normal file
73
app/lib/ostatus/tag_manager.rb
Normal file
@ -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
|
@ -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?
|
||||
|
||||
|
Reference in New Issue
Block a user