Improve ActivityPub representations (#3844)
* Improve webfinger templates and make tests more flexible * Clean up AS2 representation of actor * Refactor outbox * Create activities representation * Add representations of followers/following collections, do not redirect /users/:username route if format is empty * Remove unused translations * ActivityPub endpoint for single statuses, add ActivityPub::TagManager for better URL/URI generation * Add ActivityPub::TagManager#to * Represent all attachments as Document instead of Image/Video specifically (Because for remote ones we may not know for sure) Add mentions and hashtags representation to AP notes * Add AP-resolvable hashtag URIs * Use ActiveModelSerializers for ActivityPub * Clean up unused translations * Separate route for object and activity * Adjust cc/to matrices * Add to/cc to activities, ensure announce activity embeds target status and not the wrapper status, add "id" to all collections
This commit is contained in:
parent
3fbf1bf35a
commit
8c45cd0e36
61 changed files with 443 additions and 725 deletions
|
@ -1,9 +0,0 @@
|
|||
extends 'activitypub/types/person.activitystreams2.rabl'
|
||||
|
||||
object @account
|
||||
|
||||
attributes display_name: :name, username: :preferredUsername, note: :summary
|
||||
|
||||
node(:icon) { |account| full_asset_url(account.avatar.url(:original)) }
|
||||
node(:image) { |account| full_asset_url(account.header.url(:original)) }
|
||||
node(:outbox) { |account| api_activitypub_outbox_url(account.id) }
|
|
@ -1 +0,0 @@
|
|||
node(:'@context') { 'https://www.w3.org/ns/activitystreams' }
|
|
@ -1,3 +0,0 @@
|
|||
extends 'activitypub/base.activitystreams2.rabl'
|
||||
|
||||
node(:id) { request.original_url }
|
|
@ -1,3 +0,0 @@
|
|||
extends 'activitypub/intransient.activitystreams2.rabl'
|
||||
|
||||
node(:type) { 'Announce' }
|
|
@ -1,3 +0,0 @@
|
|||
extends 'activitypub/intransient.activitystreams2.rabl'
|
||||
|
||||
node(:type) { 'Collection' }
|
|
@ -1,3 +0,0 @@
|
|||
extends 'activitypub/intransient.activitystreams2.rabl'
|
||||
|
||||
node(:type) { 'Create' }
|
|
@ -1,3 +0,0 @@
|
|||
extends 'activitypub/intransient.activitystreams2.rabl'
|
||||
|
||||
node(:type) { 'Note' }
|
|
@ -1,3 +0,0 @@
|
|||
extends 'activitypub/types/collection.activitystreams2.rabl'
|
||||
|
||||
node(:type) { 'OrderedCollection' }
|
|
@ -1,3 +0,0 @@
|
|||
extends 'activitypub/types/ordered_collection.activitystreams2.rabl'
|
||||
|
||||
node(:type) { 'OrderedCollectionPage' }
|
|
@ -1,3 +0,0 @@
|
|||
extends 'activitypub/intransient.activitystreams2.rabl'
|
||||
|
||||
node(:type) { 'Person' }
|
|
@ -1,4 +0,0 @@
|
|||
object @status
|
||||
|
||||
node(:actor) { |status| TagManager.instance.url_for(status.account) }
|
||||
node(:published) { |status| status.created_at.to_time.xmlschema }
|
|
@ -1,8 +0,0 @@
|
|||
extends 'activitypub/types/announce.activitystreams2.rabl'
|
||||
extends 'api/activitypub/activities/_show_status.activitystreams2.rabl'
|
||||
|
||||
object @status
|
||||
|
||||
node(:name) { |status| t('activitypub.activity.announce.name', account_name: account_name(status.account)) }
|
||||
node(:url) { |status| TagManager.instance.url_for(status) }
|
||||
node(:object) { |status| api_activitypub_status_url(status.reblog_of_id) }
|
|
@ -1,8 +0,0 @@
|
|||
extends 'activitypub/types/create.activitystreams2.rabl'
|
||||
extends 'api/activitypub/activities/_show_status.activitystreams2.rabl'
|
||||
|
||||
object @status
|
||||
|
||||
node(:name) { |status| t('activitypub.activity.create.name', account_name: account_name(status.account)) }
|
||||
node(:url) { |status| TagManager.instance.url_for(status) }
|
||||
node(:object) { |status| api_activitypub_note_url(status) }
|
|
@ -1,11 +0,0 @@
|
|||
extends 'activitypub/types/note.activitystreams2.rabl'
|
||||
|
||||
object @status
|
||||
|
||||
attributes :content
|
||||
|
||||
node(:name) { |status| status.content }
|
||||
node(:url) { |status| TagManager.instance.url_for(status) }
|
||||
node(:attributedTo) { |status| TagManager.instance.url_for(status.account) }
|
||||
node(:inReplyTo) { |status| api_activitypub_note_url(status.thread) } if @status.thread
|
||||
node(:published) { |status| status.created_at.to_time.xmlschema }
|
|
@ -1,12 +0,0 @@
|
|||
extends 'activitypub/types/ordered_collection.activitystreams2.rabl'
|
||||
|
||||
object @account
|
||||
|
||||
node(:totalItems) { @statuses.count }
|
||||
node(:current) { @first_page_url } if @first_page_url
|
||||
node(:first) { @first_page_url } if @first_page_url
|
||||
node(:last) { @last_page_url } if @last_page_url
|
||||
|
||||
node(:name) { |account| t('activitypub.outbox.name', account_name: account_name(account)) }
|
||||
node(:summary) { |account| t('activitypub.outbox.summary', account_name: account_name(account)) }
|
||||
node(:updated) { |account| (@statuses.empty? ? account.created_at.to_time : @statuses.first.updated_at.to_time).xmlschema }
|
|
@ -1,16 +0,0 @@
|
|||
extends 'activitypub/types/ordered_collection_page.activitystreams2.rabl'
|
||||
|
||||
object @account
|
||||
|
||||
node(:items) do
|
||||
@statuses.map { |status| api_activitypub_status_url(status) }
|
||||
end
|
||||
|
||||
node(:next) { @next_page_url } if @next_page_url
|
||||
node(:prev) { @prev_page_url } if @prev_page_url
|
||||
node(:current) { @first_page_url } if @first_page_url
|
||||
node(:first) { @first_page_url } if @first_page_url
|
||||
node(:last) { @last_page_url } if @last_page_url
|
||||
node(:partOf) { @part_of_url } if @part_of_url
|
||||
|
||||
node(:updated) { |account| (@statuses.empty? ? account.created_at.to_time : @statuses.first.updated_at.to_time).xmlschema }
|
|
@ -3,14 +3,14 @@ object @account
|
|||
node(:subject) { @canonical_account_uri }
|
||||
|
||||
node(:aliases) do
|
||||
[TagManager.instance.url_for(@account), TagManager.instance.uri_for(@account)]
|
||||
[short_account_url(@account), account_url(@account)]
|
||||
end
|
||||
|
||||
node(:links) do
|
||||
[
|
||||
{ rel: 'http://webfinger.net/rel/profile-page', type: 'text/html', href: TagManager.instance.url_for(@account) },
|
||||
{ rel: 'http://webfinger.net/rel/profile-page', type: 'text/html', href: account_url(@account) },
|
||||
{ rel: 'http://schemas.google.com/g/2010#updates-from', type: 'application/atom+xml', href: account_url(@account, format: 'atom') },
|
||||
{ rel: 'self', type: 'application/activity+json', href: TagManager.instance.url_for(@account) },
|
||||
{ rel: 'self', type: 'application/activity+json', href: account_url(@account) },
|
||||
{ rel: 'salmon', href: api_salmon_url(@account.id) },
|
||||
{ rel: 'magic-public-key', href: "data:application/magic-public-key,#{@magic_key}" },
|
||||
{ rel: 'http://ostatus.org/schema/1.0/subscribe', template: "#{authorize_follow_url}?acct={uri}" },
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
Nokogiri::XML::Builder.new do |xml|
|
||||
xml.XRD(xmlns: 'http://docs.oasis-open.org/ns/xri/xrd-1.0') do
|
||||
xml.Subject @canonical_account_uri
|
||||
xml.Alias TagManager.instance.url_for(@account)
|
||||
xml.Alias TagManager.instance.uri_for(@account)
|
||||
xml.Alias short_account_url(@account)
|
||||
xml.Alias account_url(@account)
|
||||
xml.Link(rel: 'http://webfinger.net/rel/profile-page', type: 'text/html', href: TagManager.instance.url_for(@account))
|
||||
xml.Link(rel: 'http://schemas.google.com/g/2010#updates-from', type: 'application/atom+xml', href: account_url(@account, format: 'atom'))
|
||||
xml.Link(rel: 'self', type: 'application/activity+json', href: account_url(@account))
|
||||
xml.Link(rel: 'salmon', href: api_salmon_url(@account.id))
|
||||
xml.Link(rel: 'magic-public-key', href: "data:application/magic-public-key,#{@magic_key}")
|
||||
xml.Link(rel: 'http://ostatus.org/schema/1.0/subscribe', template: "#{authorize_follow_url}?acct={uri}")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue