update federation doc with the new artist credit object
This commit is contained in:
parent
e814b2fd01
commit
d2cbc3689b
|
@ -0,0 +1 @@
|
|||
update federation doc with the new artist credit object (#2335)
|
|
@ -99,6 +99,746 @@ Funkwhale considers a pod's service actor to be an authoritative source for acti
|
|||
|
||||
::::
|
||||
|
||||
## Supported activities
|
||||
|
||||
### Follow
|
||||
|
||||
A **follow** enables actors to access and retrieve content from other actors as soon as it updates.
|
||||
|
||||
::::{dropdown} Supported on
|
||||
|
||||
- [Library objects](#library)
|
||||
- [Actor](https://www.w3.org/TR/activitypub/#actors)
|
||||
|
||||
::::
|
||||
|
||||
#### Internal logic
|
||||
|
||||
When Funkwhale receives a follow on a [library object](#library), it performs one of the following actions depending on the library's visibility:
|
||||
|
||||
- Automatically accept: If the library is public, Funkwhale automatically accepts the follow activity. Funkwhale sends a notification to the owner of the library and an [`Accept`](#accept) activity to the actor who sent the follow
|
||||
- Accept request: If the library isn't public, Funkwhale sends a notification to the library owner. If the owner approves the request, Funkwhale sends an [`Accept`](#accept) activity to the actor who sent the follow
|
||||
|
||||
Funkwhale uses the library follow status to grant access to the actor who sent the follow request. If the library isn't public and the owner doesn't send an approval, the requesting actor can't access the library's content.
|
||||
|
||||
For User's actors the logic is the same but we use the privacy_level of the user instead of the public to automaically accept the Follow.
|
||||
|
||||
#### Checks
|
||||
|
||||
Funkwhale ensures the activity is being sent to the library's owner before handling it.
|
||||
|
||||
#### Example
|
||||
|
||||
In this example, **Alice** sends a follow activity for a [library object](#library) owned by **Bob**.
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{}
|
||||
],
|
||||
"type": "Follow",
|
||||
"id": "https://music.rocks/federation/actors/Alice#follows/99fc40d7-9bc8-4c4a-add1-f637339e1ded",
|
||||
"actor": "https://music.rocks/federation/actors/Alice",
|
||||
"to": ["https://awesome.music/federation/actors/Bob"],
|
||||
"object": "https://awesome.music/federation/music/libraries/dc702491-f6ce-441b-9da0-cecbed08bcc6"
|
||||
}
|
||||
```
|
||||
|
||||
#### Supported Activities
|
||||
|
||||
Activities sent to followings users (or to the world if the account is set to public) are :
|
||||
|
||||
- [Listen](#listen)
|
||||
- [Likes](#like)
|
||||
|
||||
### Accept
|
||||
|
||||
The `Accept` activity sends a positive response, such as confirming a [`Follow` activity](#follow).
|
||||
|
||||
::::{dropdown} Supported on
|
||||
|
||||
- `Activity` objects
|
||||
|
||||
::::
|
||||
|
||||
#### Internal logic
|
||||
|
||||
When Funkwhale receives an `Accept` activity related to a [`Follow`](#follow) activity, it marks the `Follow` as accepted in the database. If the `Follow` activity relates to a [`Library` object](#library), the requester receives future activities associated with the library. This includes [`Create`](#create), [`Audio`](#audio), and [`Delete`](#delete) activities. They can also browse and download the library's audio files. See the section on [Audio fetching on restricted libraries](./index.md#audio-fetching-on-restricted-libraries) for more details.
|
||||
|
||||
#### Checks
|
||||
|
||||
Funkwhale ensures the activity is sent by the library's owner before handling it.
|
||||
|
||||
#### Example
|
||||
|
||||
In this example, **Bob** accepts a follow request from **Alice**.
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{}
|
||||
],
|
||||
"type": "Accept",
|
||||
"id": "https://music.rocks/federation/actors/Alice#follows/99fc40d7-9bc8-4c4a-add1-f637339e1ded/accept",
|
||||
"to": ["https://music.rocks/federation/actors/Alice"],
|
||||
"actor": "https://awesome.music/federation/actors/Bob",
|
||||
"object": {
|
||||
"id": "https://music.rocks/federation/actors/Alice#follows/99fc40d7-9bc8-4c4a-add1-f637339e1ded",
|
||||
"type": "Follow",
|
||||
"actor": "https://music.rocks/federation/actors/Alice",
|
||||
"object": "https://awesome.music/federation/music/libraries/dc702491-f6ce-441b-9da0-cecbed08bcc6",
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### Undo
|
||||
|
||||
::::{dropdown} Supported on
|
||||
|
||||
- [`Follow` objects](#follow)
|
||||
|
||||
::::
|
||||
|
||||
#### Internal logic
|
||||
|
||||
When Funkwhale receives an `Undo` activity, it deletes the corresponding `Follow` from the database.
|
||||
|
||||
#### Checks
|
||||
|
||||
Funkwhale ensures the request actor is the same actor who sent the `Follow` activity before handling it.
|
||||
|
||||
#### Example
|
||||
|
||||
In this example, **Alice** notifies **Bob** that she's undoing her follow.
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{}
|
||||
],
|
||||
"type": "Undo",
|
||||
"id": "https://music.rocks/federation/actors/Alice#follows/99fc40d7-9bc8-4c4a-add1-f637339e1ded/accept",
|
||||
"to": ["https://awesome.music/federation/actors/Bob"],
|
||||
"actor": "https://music.rocks/federation/actors/Alice",
|
||||
"object": {
|
||||
"id": "https://music.rocks/federation/actors/Alice#follows/99fc40d7-9bc8-4c4a-add1-f637339e1ded",
|
||||
"type": "Follow",
|
||||
"actor": "https://music.rocks/federation/actors/Alice",
|
||||
"object": "https://awesome.music/federation/music/libraries/dc702491-f6ce-441b-9da0-cecbed08bcc6",
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### Create
|
||||
|
||||
::::{dropdown} Supported on
|
||||
|
||||
- [`Audio` objects](#audio)
|
||||
|
||||
::::
|
||||
|
||||
#### Internal logic
|
||||
|
||||
```{note}
|
||||
See [the `Audio` object reference](#audio) for details on the object's structure.
|
||||
```
|
||||
|
||||
When Funkwhale receives a `Create` activity with an [`Audio` object](#audio), it persists a local upload in the database. It then associates the upload to related library and track information. If no track matches the audio metadata, Funkwhale creates on using the `metadata` attribute in the object.
|
||||
|
||||
#### Checks
|
||||
|
||||
Funkwhale ensures the activity actor and library owner are the same before handling the activity. If the associated library has no local followers, Funkwhale discards the activity.
|
||||
|
||||
#### Example
|
||||
|
||||
In this example, **Bob** creates new content in his library and sends a message to its followers.
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{}
|
||||
],
|
||||
"to": [
|
||||
"https://awesome.music/federation/music/libraries/dc702491-f6ce-441b-9da0-cecbed08bcc6/followers"
|
||||
],
|
||||
"type": "Create",
|
||||
"actor": "https://awesome.music/federation/actors/Bob",
|
||||
"object": {}
|
||||
}
|
||||
```
|
||||
|
||||
### Update
|
||||
|
||||
::::{dropdown} Supported on
|
||||
|
||||
- [`Library` objects](#library)
|
||||
- [`Track` objects](#track)
|
||||
|
||||
::::
|
||||
|
||||
#### Internal logic
|
||||
|
||||
```{note}
|
||||
See [the `Track` object reference](#track) and [`Library` object reference](#library) for details on the object's structure.
|
||||
```
|
||||
|
||||
When Funkwhale receives an update associated with a [`Library`](#library) or [`Track`](#track) object, it attempts to update the corresponding object in its database.
|
||||
|
||||
#### Checks
|
||||
|
||||
Funkwhale performs different checks depending on the target of the update:
|
||||
|
||||
- For [`Library`](#library) objects, Funkwhale ensures the actor sending the message is the library owner
|
||||
- For [`Track`](#track) objects, Funkwhale ensures the actor sending the message **either**:
|
||||
- Matches the [`attributedTo`](./index.md#attributedto) property on the local copy of the object
|
||||
- Is the [service actor](./index.md#service-actor)
|
||||
|
||||
#### Example
|
||||
|
||||
In this example, **Bob** updates his library and sends a message to its followers.
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{}
|
||||
],
|
||||
"to": [
|
||||
"https://awesome.music/federation/music/libraries/dc702491-f6ce-441b-9da0-cecbed08bcc6/followers"
|
||||
],
|
||||
"type": "Update",
|
||||
"actor": "https://awesome.music/federation/actors/Bob",
|
||||
"object": {}
|
||||
}
|
||||
```
|
||||
|
||||
### Delete
|
||||
|
||||
::::{dropdown} Supported on
|
||||
|
||||
- [`Audio` objects](#audio)
|
||||
- [`Library` objects](#library)
|
||||
- [`Listen` activity](#listen)
|
||||
|
||||
::::
|
||||
|
||||
#### Internal logic
|
||||
|
||||
When Funkwhale receives a `Delete` activity, it deletes the associated object from the database.
|
||||
|
||||
#### Checks
|
||||
|
||||
Funkwhale ensures the actor initiating the activity is the owner of the associated object before handling it.
|
||||
|
||||
#### Example
|
||||
|
||||
::::{tab-set}
|
||||
|
||||
:::{tab-item} Library
|
||||
|
||||
In this example, **Bob** deletes a library and notifies its followers.
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{}
|
||||
],
|
||||
"type": "Delete",
|
||||
"to": [
|
||||
"https://awesome.music/federation/music/libraries/dc702491-f6ce-441b-9da0-cecbed08bcc6/followers"
|
||||
],
|
||||
"actor": "https://awesome.music/federation/actors/Bob",
|
||||
"object": {
|
||||
"type": "Library",
|
||||
"id": "https://awesome.music/federation/music/libraries/dc702491-f6ce-441b-9da0-cecbed08bcc6"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
:::{tab-item} Audio
|
||||
|
||||
In this example, **Bob** deletes three audio objects in a library and notifies the library's followers.
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{}
|
||||
],
|
||||
"type": "Delete",
|
||||
"to": [
|
||||
"https://awesome.music/federation/music/libraries/dc702491-f6ce-441b-9da0-cecbed08bcc6/followers"
|
||||
],
|
||||
"actor": "https://awesome.music/federation/actors/Bob",
|
||||
"object": {
|
||||
"type": "Audio",
|
||||
"id": [
|
||||
"https://awesome.music/federation/music/uploads/19420073-3572-48a9-8c6c-b385ee1b7905",
|
||||
"https://awesome.music/federation/music/uploads/11d99680-23c6-4f72-997a-073b980ab204",
|
||||
"https://awesome.music/federation/music/uploads/1efadc1c-a704-4b8a-a71a-b288b1d1f423"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
::::
|
||||
|
||||
### Like
|
||||
|
||||
We send the [Like](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-like) object with its type : this allow proper routing and avoid useless database and network queries.
|
||||
|
||||
::::{dropdown} Supported on
|
||||
|
||||
- [`Track` objects](#track)
|
||||
|
||||
::::
|
||||
|
||||
#### Example
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"type": "Like",
|
||||
"id": "https://burn.patriachy//7b54d361-c513-4756-a085-13f97573237b",
|
||||
""object": {
|
||||
"Type": "Track",
|
||||
"id": "https://Le_Rn.areRacists//aebd2be4-49a1-4ef5-aadf-27bff1001d4d",
|
||||
},
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
"https://funkwhale.audio/ns",
|
||||
{
|
||||
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
|
||||
"Hashtag": "as:Hashtag",
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
### Dislike
|
||||
|
||||
We send the [Dislike](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-dislike) object with its type : this allow proper routing and avoid useless database and network queries.
|
||||
|
||||
::::{dropdown} Supported on
|
||||
|
||||
- [`Track` objects](#track)
|
||||
|
||||
::::
|
||||
|
||||
#### Example
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"type": "Dislike",
|
||||
"id": "https://burn.patriachy//7b54d361-c513-4756-a085-13f97573237b",
|
||||
""object": {
|
||||
"Type": "Track",
|
||||
"id": "https://Le_Rn.areRacists//aebd2be4-49a1-4ef5-aadf-27bff1001d4d",
|
||||
},
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
"https://funkwhale.audio/ns",
|
||||
{
|
||||
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
|
||||
"Hashtag": "as:Hashtag",
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
### Listen
|
||||
|
||||
We send the [Listen](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-listen) object with its type : this allow proper routing and avoid useless database and network queries.
|
||||
|
||||
::::{dropdown} Supported on
|
||||
|
||||
- [`Track` objects](#track)
|
||||
|
||||
::::
|
||||
|
||||
#### Example
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"type": "Listen",
|
||||
"id": "https://makerichpeoplepay.forclimatechange//5355f8b7-bbcc-4285-9c13-d21748084cc1",
|
||||
"object": {
|
||||
"Type": "Track",
|
||||
"id": "https://Le_Rn.areRacists//aebd2be4-49a1-4ef5-aadf-27bff1001d4d",
|
||||
},
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
"https://funkwhale.audio/ns",
|
||||
{
|
||||
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
|
||||
"Hashtag": "as:Hashtag",
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
## Supported objects
|
||||
|
||||
### Artist
|
||||
|
||||
An `Artist` is a custom object used to store musical artist and podcast creator information.
|
||||
|
||||
#### Properties
|
||||
|
||||
```{list-table}
|
||||
:header-rows: 1
|
||||
|
||||
* - Property
|
||||
- Data type
|
||||
- Description
|
||||
* - `type`*
|
||||
- String
|
||||
- The object type (`Artist`)
|
||||
* - `id`*
|
||||
- String (URI)
|
||||
- A URI that identifies the artist over federation
|
||||
* - `name`*
|
||||
- String
|
||||
- The artist's name
|
||||
* - `published`*
|
||||
- Datetime
|
||||
- The date on which the artist was published over the federation
|
||||
* - `musicbrainzId`
|
||||
- String (UUID)
|
||||
- The Musicbrainz artist ID
|
||||
```
|
||||
|
||||
#### Example
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"type": "Artist",
|
||||
"id": "https://awesome.music/federation/music/artists/73c32807-a199-4682-8068-e967f734a320",
|
||||
"name": "Krav Boca",
|
||||
"published": "2018-04-08T12:19:05.920415+00:00",
|
||||
"musicbrainzId": "65f4f0c5-ef9e-490c-aee3-909e7ae6b2ab"
|
||||
}
|
||||
```
|
||||
|
||||
### ArtistCredit
|
||||
|
||||
An `ArtistCredit` is a custom object used to store information about how artists are credited in music objects. We followed [Musicbrainz data structure](https://musicbrainz.org/doc/Artist_Credits).
|
||||
|
||||
#### Properties
|
||||
|
||||
```{list-table}
|
||||
:header-rows: 1
|
||||
|
||||
* - Property
|
||||
- Data type
|
||||
- Description
|
||||
* - `type`*
|
||||
- String
|
||||
- The object type (`ArtistCredit`)
|
||||
* - `id`*
|
||||
- String (URI)
|
||||
- A URI that identifies the artist over federation
|
||||
* - `artist`*
|
||||
- [`Artist` object](#artist)
|
||||
- The credited Artist
|
||||
* - `credit`*
|
||||
- String
|
||||
- How the artist is credited in the object. Can differ from artist.name
|
||||
* - `joinphrase`
|
||||
- String
|
||||
- Concatenated after artist credit. Join the present ArtistCredit with the next one.
|
||||
* - `published`*
|
||||
- Datetime
|
||||
- The date on which the artist was published over the federation
|
||||
```
|
||||
|
||||
#### Example
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"type": "ArtistCredit",
|
||||
"id": "https://test.federation/federation/music/artistcredit/6dc0071c-0186-4f27-a234-fa5858774400",
|
||||
"artist": {
|
||||
"type": "Artist",
|
||||
"id": "https://white.info//6dc0071c-0186-4f27-a234-fa5858774400",
|
||||
"name": "Krav Boca",
|
||||
"published": "2024-12-22T21:54:46.391743+00:00",
|
||||
"musicbrainzId": "6dc0071c-0186-4f27-a234-fa5858774400",
|
||||
"attributedTo": None,
|
||||
"tag": [],
|
||||
"image": None,
|
||||
},
|
||||
"joinphrase": "feat. ",
|
||||
"credit": "Crav Boka",
|
||||
"index": None,
|
||||
"published": "2024-12-22T21:54:46.392309+00:00",
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Album
|
||||
|
||||
An `Album` is a custom object used to store album and podcast series information.
|
||||
|
||||
#### Properties
|
||||
|
||||
```{list-table}
|
||||
:header-rows: 1
|
||||
|
||||
* - Property
|
||||
- Data type
|
||||
- Description
|
||||
* - `type`*
|
||||
- String
|
||||
- The object type (`Album`)
|
||||
* - `id`*
|
||||
- String (URI)
|
||||
- A URI that identifies the album over federation
|
||||
* - `name`*
|
||||
- String
|
||||
- The album's title
|
||||
* - `artist_credit`
|
||||
- Array of strings
|
||||
- A list of [`ArtistCredit` objects](#artistcredit) associated with the albums
|
||||
* - `published`*
|
||||
- Datetime
|
||||
- The date on which the artist was published over the federation
|
||||
* - `released`
|
||||
- Datetime
|
||||
- The date on which the album was released
|
||||
* - `musicbrainzId`
|
||||
- String (UUID)
|
||||
- The Musicbrainz release ID
|
||||
* - `cover`
|
||||
- [`Link` object](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-link)
|
||||
- A `Link` object representing the album cover
|
||||
```
|
||||
|
||||
#### Example
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"type": "Album",
|
||||
"id": "https://awesome.music/federation/music/albums/69d488b5-fdf6-4803-b47c-9bb7098ea57e",
|
||||
"name": "Ride the Lightning",
|
||||
"released": "1984-01-01",
|
||||
"published": "2018-10-02T19:49:17.412546+00:00",
|
||||
"musicbrainzId": "589ff96d-0be8-3f82-bdd2-299592e51b40",
|
||||
"cover": {
|
||||
"href": "https://awesome.music/media/albums/covers/2018/10/02/b69d398b5-fdf6-4803-b47c-9bb7098ea57e.jpg",
|
||||
"type": "Link",
|
||||
"mediaType": "image/jpeg"
|
||||
},
|
||||
"artist_credit": [
|
||||
{}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Track
|
||||
|
||||
A `Track` is a custom object used to store track information.
|
||||
|
||||
#### Properties
|
||||
|
||||
```{list-table}
|
||||
:header-rows: 1
|
||||
|
||||
* - Property
|
||||
- Data type
|
||||
- Description
|
||||
* - `type`*
|
||||
- String
|
||||
- The object type (`Track`)
|
||||
* - `id`*
|
||||
- String (URI)
|
||||
- A URI that identifies the track over federation
|
||||
* - `name`*
|
||||
- String
|
||||
- The track title
|
||||
* - `position`*
|
||||
- Integer
|
||||
- The position of the track in the album
|
||||
* - `published`*
|
||||
- Datetime
|
||||
- The date on which the track was published over the federation
|
||||
* - `musicbrainzId`
|
||||
- String (UUID)
|
||||
- The Musicbrainz recording ID
|
||||
* - `album`
|
||||
- [`Album` object](#album)
|
||||
- The album that contains the track
|
||||
* - `artist_credit`
|
||||
- Array of strings
|
||||
- A list of [`ArtistCredit` objects](#artistcredit) associated with the track. This can differ from the album artists
|
||||
```
|
||||
|
||||
#### Example
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"type": "Track",
|
||||
"id": "https://awesome.music/federation/music/tracks/82ece296-6397-4e26-be90-bac5f9990240",
|
||||
"name": "Shock! Extinction de masse",
|
||||
"position": 3,
|
||||
"published": "2018-10-02T19:49:35.822537+00:00",
|
||||
"musicbrainzId": "771ab043-8821-44f9-b8e0-2733c3126c6d",
|
||||
"artist_credit": [
|
||||
{}
|
||||
],
|
||||
"album": {}
|
||||
}
|
||||
```
|
||||
|
||||
### Library
|
||||
|
||||
```{note}
|
||||
Crawling library pages requires authentication and an approved follow unless the library is public.
|
||||
```
|
||||
|
||||
A `Library` is a custom object used to store music collection information. It inherits its behavior and properties from ActivityPub's [`Actor`](https://www.w3.org/TR/activitypub/#actors) and [`Collection`](https://www.w3.org/TR/activitypub/#collections) objects.
|
||||
|
||||
#### Properties
|
||||
|
||||
```{list-table}
|
||||
:header-rows: 1
|
||||
|
||||
* - Property
|
||||
- Data type
|
||||
- Description
|
||||
* - `type`*
|
||||
- String
|
||||
- The object type (`Library`)
|
||||
* - `id`*
|
||||
- String (URI)
|
||||
- A URI that identifies the library over federation
|
||||
* - `name`*
|
||||
- String
|
||||
- The library's name
|
||||
* - `followers`*
|
||||
- String (URI)
|
||||
- The ID of the library's followers collection
|
||||
* - `totalItems`*
|
||||
- Integer
|
||||
- The number of [`Audio` objects](#audio) in the library
|
||||
* - `first`*
|
||||
- String (URI)
|
||||
- The URL of the library's first page
|
||||
* - `last`*
|
||||
- String (URI)
|
||||
- The URL of the library's last page
|
||||
* - `summary`
|
||||
- String
|
||||
- The library's description
|
||||
```
|
||||
|
||||
#### Example
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"type": "Library",
|
||||
"id": "https://awesome.music/federation/music/libraries/dc702491-f6ce-441b-9da0-cecbed08bcc6",
|
||||
"attributedTo": "https://awesome.music/federation/actors/Alice",
|
||||
"name": "My awesome library",
|
||||
"followers": "https://awesome.music/federation/music/libraries/dc702491-f6ce-441b-9da0-cecbed08bcc6/followers",
|
||||
"summary": "This library is for restricted use only",
|
||||
"totalItems": 4234,
|
||||
"first": "https://awesome.music/federation/music/libraries/dc702491-f6ce-441b-9da0-cecbed08bcc6?page=1",
|
||||
"last": "https://awesome.music/federation/music/libraries/dc702491-f6ce-441b-9da0-cecbed08bcc6?page=56",
|
||||
}
|
||||
```
|
||||
|
||||
### Audio
|
||||
|
||||
```{note}
|
||||
Accessing audio files requires authentication and an approved follow for the containing library unless the library is public.
|
||||
```
|
||||
|
||||
An `Audio` object is a custom object used to store upload information. It extends the [ActivityStreams Audio object](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-audio) with custom attributes.
|
||||
|
||||
#### Properties
|
||||
|
||||
```{list-table}
|
||||
:header-rows: 1
|
||||
|
||||
* - Property
|
||||
- Data type
|
||||
- Description
|
||||
* - `type`*
|
||||
- String
|
||||
- The object type (`Audio`)
|
||||
* - `id`*
|
||||
- String (URI)
|
||||
- A URI that identifies the audio over federation
|
||||
* - `name`*
|
||||
- String
|
||||
- A readable title for the order. Funkwhale concatenates the track name, album title, and artist name
|
||||
* - `size`*
|
||||
- Integer
|
||||
- The size of the audio in bytes
|
||||
* - `bitrate`*
|
||||
- Integer
|
||||
- The bitrate of the audio in bytes/s
|
||||
* - `duration`*
|
||||
- Integer
|
||||
- The duration of the audio in seconds
|
||||
* - `library`*
|
||||
- String (URI)
|
||||
- The ID of the audio's containing [`Library` object](#library)
|
||||
* - `published`*
|
||||
- Datetime
|
||||
- The date on which the audio was published over the federation
|
||||
* - `updated`*
|
||||
- Datetime
|
||||
- The date on which the audio was last updated over the federation
|
||||
* - `url`*
|
||||
- [`Link` object](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-link)
|
||||
- A `Link` object object containing the download location of the audio file
|
||||
* - `track`
|
||||
- [`Track` object](#track)
|
||||
- The track associated with the audio file
|
||||
```
|
||||
|
||||
#### Example
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"type": "Audio",
|
||||
"id": "https://awesome.music/federation/music/uploads/88f0bc20-d7fd-461d-a641-dd9ac485e096",
|
||||
"name": "Krav Boca - Mortem",
|
||||
"size": 8656581,
|
||||
"bitrate": 320000,
|
||||
"duration": 213,
|
||||
"library": "https://awesome.music/federation/music/libraries/dc702491-f6ce-441b-9da0-cecbed08bcc6",
|
||||
"updated": "2018-10-02T19:49:35.646372+00:00",
|
||||
"published": "2018-10-02T19:49:35.646359+00:00",
|
||||
"track": {},
|
||||
"url": {
|
||||
"href": "https://awesome.music/api/v1/listen/82ece296-6397-4e26-be90-bac5f9990240/?upload=88f0bc20-d7fd-461d-a641-dd9ac485e096",
|
||||
"type": "Link",
|
||||
"mediaType": "audio/mpeg"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Custom properties
|
||||
|
||||
### attributedTo
|
||||
|
|
|
@ -1,746 +0,0 @@
|
|||
# Activities and Objects
|
||||
|
||||
```{contents}
|
||||
:local:
|
||||
:depth: 2
|
||||
```
|
||||
|
||||
## Supported activities
|
||||
|
||||
### Follow
|
||||
|
||||
A **follow** enables actors to access and retrieve content from other actors as soon as it updates.
|
||||
|
||||
::::{dropdown} Supported on
|
||||
|
||||
- [Library objects](#library)
|
||||
- [Actor](https://www.w3.org/TR/activitypub/#actors)
|
||||
|
||||
::::
|
||||
|
||||
#### Internal logic
|
||||
|
||||
When Funkwhale receives a follow on a [library object](#library), it performs one of the following actions depending on the library's visibility:
|
||||
|
||||
- Automatically accept: If the library is public, Funkwhale automatically accepts the follow activity. Funkwhale sends a notification to the owner of the library and an [`Accept`](#accept) activity to the actor who sent the follow
|
||||
- Accept request: If the library isn't public, Funkwhale sends a notification to the library owner. If the owner approves the request, Funkwhale sends an [`Accept`](#accept) activity to the actor who sent the follow
|
||||
|
||||
Funkwhale uses the library follow status to grant access to the actor who sent the follow request. If the library isn't public and the owner doesn't send an approval, the requesting actor can't access the library's content.
|
||||
|
||||
For User's actors the logic is the same but we use the privacy_level of the user instead of the public to automaically accept the Follow.
|
||||
|
||||
#### Checks
|
||||
|
||||
Funkwhale ensures the activity is being sent to the library's owner before handling it.
|
||||
|
||||
#### Example
|
||||
|
||||
In this example, **Alice** sends a follow activity for a [library object](#library) owned by **Bob**.
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{}
|
||||
],
|
||||
"type": "Follow",
|
||||
"id": "https://music.rocks/federation/actors/Alice#follows/99fc40d7-9bc8-4c4a-add1-f637339e1ded",
|
||||
"actor": "https://music.rocks/federation/actors/Alice",
|
||||
"to": ["https://awesome.music/federation/actors/Bob"],
|
||||
"object": "https://awesome.music/federation/music/libraries/dc702491-f6ce-441b-9da0-cecbed08bcc6"
|
||||
}
|
||||
```
|
||||
|
||||
#### Supported Activities
|
||||
|
||||
Activities sent to followings users (or to the world if the account is set to public) are :
|
||||
|
||||
- [Listen](#listen)
|
||||
- [Likes](#like)
|
||||
|
||||
### Accept
|
||||
|
||||
The `Accept` activity sends a positive response, such as confirming a [`Follow` activity](#follow).
|
||||
|
||||
::::{dropdown} Supported on
|
||||
|
||||
- `Activity` objects
|
||||
|
||||
::::
|
||||
|
||||
#### Internal logic
|
||||
|
||||
When Funkwhale receives an `Accept` activity related to a [`Follow`](#follow) activity, it marks the `Follow` as accepted in the database. If the `Follow` activity relates to a [`Library` object](#library), the requester receives future activities associated with the library. This includes [`Create`](#create), [`Audio`](#audio), and [`Delete`](#delete) activities. They can also browse and download the library's audio files. See the section on [Audio fetching on restricted libraries](./index.md#audio-fetching-on-restricted-libraries) for more details.
|
||||
|
||||
#### Checks
|
||||
|
||||
Funkwhale ensures the activity is sent by the library's owner before handling it.
|
||||
|
||||
#### Example
|
||||
|
||||
In this example, **Bob** accepts a follow request from **Alice**.
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{}
|
||||
],
|
||||
"type": "Accept",
|
||||
"id": "https://music.rocks/federation/actors/Alice#follows/99fc40d7-9bc8-4c4a-add1-f637339e1ded/accept",
|
||||
"to": ["https://music.rocks/federation/actors/Alice"],
|
||||
"actor": "https://awesome.music/federation/actors/Bob",
|
||||
"object": {
|
||||
"id": "https://music.rocks/federation/actors/Alice#follows/99fc40d7-9bc8-4c4a-add1-f637339e1ded",
|
||||
"type": "Follow",
|
||||
"actor": "https://music.rocks/federation/actors/Alice",
|
||||
"object": "https://awesome.music/federation/music/libraries/dc702491-f6ce-441b-9da0-cecbed08bcc6",
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### Undo
|
||||
|
||||
::::{dropdown} Supported on
|
||||
|
||||
- [`Follow` objects](#follow)
|
||||
|
||||
::::
|
||||
|
||||
#### Internal logic
|
||||
|
||||
When Funkwhale receives an `Undo` activity, it deletes the corresponding `Follow` from the database.
|
||||
|
||||
#### Checks
|
||||
|
||||
Funkwhale ensures the request actor is the same actor who sent the `Follow` activity before handling it.
|
||||
|
||||
#### Example
|
||||
|
||||
In this example, **Alice** notifies **Bob** that she's undoing her follow.
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{}
|
||||
],
|
||||
"type": "Undo",
|
||||
"id": "https://music.rocks/federation/actors/Alice#follows/99fc40d7-9bc8-4c4a-add1-f637339e1ded/accept",
|
||||
"to": ["https://awesome.music/federation/actors/Bob"],
|
||||
"actor": "https://music.rocks/federation/actors/Alice",
|
||||
"object": {
|
||||
"id": "https://music.rocks/federation/actors/Alice#follows/99fc40d7-9bc8-4c4a-add1-f637339e1ded",
|
||||
"type": "Follow",
|
||||
"actor": "https://music.rocks/federation/actors/Alice",
|
||||
"object": "https://awesome.music/federation/music/libraries/dc702491-f6ce-441b-9da0-cecbed08bcc6",
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### Create
|
||||
|
||||
::::{dropdown} Supported on
|
||||
|
||||
- [`Audio` objects](#audio)
|
||||
|
||||
::::
|
||||
|
||||
#### Internal logic
|
||||
|
||||
```{note}
|
||||
See [the `Audio` object reference](#audio) for details on the object's structure.
|
||||
```
|
||||
|
||||
When Funkwhale receives a `Create` activity with an [`Audio` object](#audio), it persists a local upload in the database. It then associates the upload to related library and track information. If no track matches the audio metadata, Funkwhale creates on using the `metadata` attribute in the object.
|
||||
|
||||
#### Checks
|
||||
|
||||
Funkwhale ensures the activity actor and library owner are the same before handling the activity. If the associated library has no local followers, Funkwhale discards the activity.
|
||||
|
||||
#### Example
|
||||
|
||||
In this example, **Bob** creates new content in his library and sends a message to its followers.
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{}
|
||||
],
|
||||
"to": [
|
||||
"https://awesome.music/federation/music/libraries/dc702491-f6ce-441b-9da0-cecbed08bcc6/followers"
|
||||
],
|
||||
"type": "Create",
|
||||
"actor": "https://awesome.music/federation/actors/Bob",
|
||||
"object": {}
|
||||
}
|
||||
```
|
||||
|
||||
### Update
|
||||
|
||||
::::{dropdown} Supported on
|
||||
|
||||
- [`Library` objects](#library)
|
||||
- [`Track` objects](#track)
|
||||
|
||||
::::
|
||||
|
||||
#### Internal logic
|
||||
|
||||
```{note}
|
||||
See [the `Track` object reference](#track) and [`Library` object reference](#library) for details on the object's structure.
|
||||
```
|
||||
|
||||
When Funkwhale receives an update associated with a [`Library`](#library) or [`Track`](#track) object, it attempts to update the corresponding object in its database.
|
||||
|
||||
#### Checks
|
||||
|
||||
Funkwhale performs different checks depending on the target of the update:
|
||||
|
||||
- For [`Library`](#library) objects, Funkwhale ensures the actor sending the message is the library owner
|
||||
- For [`Track`](#track) objects, Funkwhale ensures the actor sending the message **either**:
|
||||
- Matches the [`attributedTo`](./index.md#attributedto) property on the local copy of the object
|
||||
- Is the [service actor](./index.md#service-actor)
|
||||
|
||||
#### Example
|
||||
|
||||
In this example, **Bob** updates his library and sends a message to its followers.
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{}
|
||||
],
|
||||
"to": [
|
||||
"https://awesome.music/federation/music/libraries/dc702491-f6ce-441b-9da0-cecbed08bcc6/followers"
|
||||
],
|
||||
"type": "Update",
|
||||
"actor": "https://awesome.music/federation/actors/Bob",
|
||||
"object": {}
|
||||
}
|
||||
```
|
||||
|
||||
### Delete
|
||||
|
||||
::::{dropdown} Supported on
|
||||
|
||||
- [`Audio` objects](#audio)
|
||||
- [`Library` objects](#library)
|
||||
- [`Listen` activity](#listen)
|
||||
|
||||
::::
|
||||
|
||||
#### Internal logic
|
||||
|
||||
When Funkwhale receives a `Delete` activity, it deletes the associated object from the database.
|
||||
|
||||
#### Checks
|
||||
|
||||
Funkwhale ensures the actor initiating the activity is the owner of the associated object before handling it.
|
||||
|
||||
#### Example
|
||||
|
||||
::::{tab-set}
|
||||
|
||||
:::{tab-item} Library
|
||||
|
||||
In this example, **Bob** deletes a library and notifies its followers.
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{}
|
||||
],
|
||||
"type": "Delete",
|
||||
"to": [
|
||||
"https://awesome.music/federation/music/libraries/dc702491-f6ce-441b-9da0-cecbed08bcc6/followers"
|
||||
],
|
||||
"actor": "https://awesome.music/federation/actors/Bob",
|
||||
"object": {
|
||||
"type": "Library",
|
||||
"id": "https://awesome.music/federation/music/libraries/dc702491-f6ce-441b-9da0-cecbed08bcc6"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
:::{tab-item} Audio
|
||||
|
||||
In this example, **Bob** deletes three audio objects in a library and notifies the library's followers.
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{}
|
||||
],
|
||||
"type": "Delete",
|
||||
"to": [
|
||||
"https://awesome.music/federation/music/libraries/dc702491-f6ce-441b-9da0-cecbed08bcc6/followers"
|
||||
],
|
||||
"actor": "https://awesome.music/federation/actors/Bob",
|
||||
"object": {
|
||||
"type": "Audio",
|
||||
"id": [
|
||||
"https://awesome.music/federation/music/uploads/19420073-3572-48a9-8c6c-b385ee1b7905",
|
||||
"https://awesome.music/federation/music/uploads/11d99680-23c6-4f72-997a-073b980ab204",
|
||||
"https://awesome.music/federation/music/uploads/1efadc1c-a704-4b8a-a71a-b288b1d1f423"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
::::
|
||||
|
||||
### Like
|
||||
|
||||
We send the [Like](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-like) object with its type : this allow proper routing and avoid useless database and network queries.
|
||||
|
||||
::::{dropdown} Supported on
|
||||
|
||||
- [`Track` objects](#track)
|
||||
|
||||
::::
|
||||
|
||||
#### Example
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"type": "Like",
|
||||
"id": "https://burn.patriachy//7b54d361-c513-4756-a085-13f97573237b",
|
||||
""object": {
|
||||
"Type": "Track",
|
||||
"id": "https://Le_Rn.areRacists//aebd2be4-49a1-4ef5-aadf-27bff1001d4d",
|
||||
},
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
"https://funkwhale.audio/ns",
|
||||
{
|
||||
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
|
||||
"Hashtag": "as:Hashtag",
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
### Dislike
|
||||
|
||||
We send the [Dislike](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-dislike) object with its type : this allow proper routing and avoid useless database and network queries.
|
||||
|
||||
::::{dropdown} Supported on
|
||||
|
||||
- [`Track` objects](#track)
|
||||
|
||||
::::
|
||||
|
||||
#### Example
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"type": "Dislike",
|
||||
"id": "https://burn.patriachy//7b54d361-c513-4756-a085-13f97573237b",
|
||||
""object": {
|
||||
"Type": "Track",
|
||||
"id": "https://Le_Rn.areRacists//aebd2be4-49a1-4ef5-aadf-27bff1001d4d",
|
||||
},
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
"https://funkwhale.audio/ns",
|
||||
{
|
||||
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
|
||||
"Hashtag": "as:Hashtag",
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
### Listen
|
||||
|
||||
We send the [Listen](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-listen) object with its type : this allow proper routing and avoid useless database and network queries.
|
||||
|
||||
::::{dropdown} Supported on
|
||||
|
||||
- [`Track` objects](#track)
|
||||
|
||||
::::
|
||||
|
||||
#### Example
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"type": "Listen",
|
||||
"id": "https://makerichpeoplepay.forclimatechange//5355f8b7-bbcc-4285-9c13-d21748084cc1",
|
||||
"object": {
|
||||
"Type": "Track",
|
||||
"id": "https://Le_Rn.areRacists//aebd2be4-49a1-4ef5-aadf-27bff1001d4d",
|
||||
},
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
"https://funkwhale.audio/ns",
|
||||
{
|
||||
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
|
||||
"Hashtag": "as:Hashtag",
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
## Supported objects
|
||||
|
||||
### Artist
|
||||
|
||||
An `Artist` is a custom object used to store musical artist and podcast creator information.
|
||||
|
||||
#### Properties
|
||||
|
||||
```{list-table}
|
||||
:header-rows: 1
|
||||
|
||||
* - Property
|
||||
- Data type
|
||||
- Description
|
||||
* - `type`*
|
||||
- String
|
||||
- The object type (`Artist`)
|
||||
* - `id`*
|
||||
- String (URI)
|
||||
- A URI that identifies the artist over federation
|
||||
* - `name`*
|
||||
- String
|
||||
- The artist's name
|
||||
* - `published`*
|
||||
- Datetime
|
||||
- The date on which the artist was published over the federation
|
||||
* - `musicbrainzId`
|
||||
- String (UUID)
|
||||
- The Musicbrainz artist ID
|
||||
```
|
||||
|
||||
#### Example
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"type": "Artist",
|
||||
"id": "https://awesome.music/federation/music/artists/73c32807-a199-4682-8068-e967f734a320",
|
||||
"name": "Krav Boca",
|
||||
"published": "2018-04-08T12:19:05.920415+00:00",
|
||||
"musicbrainzId": "65f4f0c5-ef9e-490c-aee3-909e7ae6b2ab"
|
||||
}
|
||||
```
|
||||
|
||||
### ArtistCredit
|
||||
|
||||
An `ArtistCredit` is a custom object used to store information about how artists are credited in music objects. We followed [Musicbrainz data structure](https://musicbrainz.org/doc/Artist_Credits).
|
||||
|
||||
#### Properties
|
||||
|
||||
```{list-table}
|
||||
:header-rows: 1
|
||||
|
||||
* - Property
|
||||
- Data type
|
||||
- Description
|
||||
* - `type`*
|
||||
- String
|
||||
- The object type (`ArtistCredit`)
|
||||
* - `id`*
|
||||
- String (URI)
|
||||
- A URI that identifies the artist over federation
|
||||
* - `artist`*
|
||||
- [`Artist` object](#artist)
|
||||
- The credited Artist
|
||||
* - `credit`*
|
||||
- String
|
||||
- How the artist is credited in the object. Can differ from artist.name
|
||||
* - `joinphrase`
|
||||
- String
|
||||
- Concatenated after artist credit. Join the present ArtistCredit with the next one.
|
||||
* - `published`*
|
||||
- Datetime
|
||||
- The date on which the artist was published over the federation
|
||||
```
|
||||
|
||||
#### Example
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"type": "ArtistCredit",
|
||||
"id": "https://test.federation/federation/music/artistcredit/6dc0071c-0186-4f27-a234-fa5858774400",
|
||||
"artist": {
|
||||
"type": "Artist",
|
||||
"id": "https://white.info//6dc0071c-0186-4f27-a234-fa5858774400",
|
||||
"name": "John Ross",
|
||||
"published": "2024-12-22T21:54:46.391743+00:00",
|
||||
"musicbrainzId": "6dc0071c-0186-4f27-a234-fa5858774400",
|
||||
"attributedTo": None,
|
||||
"tag": [],
|
||||
"image": None,
|
||||
},
|
||||
"joinphrase": "feat. ",
|
||||
"credit": "John Ross",
|
||||
"index": None,
|
||||
"published": "2024-12-22T21:54:46.392309+00:00",
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Album
|
||||
|
||||
An `Album` is a custom object used to store album and podcast series information.
|
||||
|
||||
#### Properties
|
||||
|
||||
```{list-table}
|
||||
:header-rows: 1
|
||||
|
||||
* - Property
|
||||
- Data type
|
||||
- Description
|
||||
* - `type`*
|
||||
- String
|
||||
- The object type (`Album`)
|
||||
* - `id`*
|
||||
- String (URI)
|
||||
- A URI that identifies the album over federation
|
||||
* - `name`*
|
||||
- String
|
||||
- The album's title
|
||||
* - `artist_credit`
|
||||
- Array of strings
|
||||
- A list of [`ArtistCredit` objects](#artistcredit) associated with the albums
|
||||
* - `published`*
|
||||
- Datetime
|
||||
- The date on which the artist was published over the federation
|
||||
* - `released`
|
||||
- Datetime
|
||||
- The date on which the album was released
|
||||
* - `musicbrainzId`
|
||||
- String (UUID)
|
||||
- The Musicbrainz release ID
|
||||
* - `cover`
|
||||
- [`Link` object](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-link)
|
||||
- A `Link` object representing the album cover
|
||||
```
|
||||
|
||||
#### Example
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"type": "Album",
|
||||
"id": "https://awesome.music/federation/music/albums/69d488b5-fdf6-4803-b47c-9bb7098ea57e",
|
||||
"name": "Ride the Lightning",
|
||||
"released": "1984-01-01",
|
||||
"published": "2018-10-02T19:49:17.412546+00:00",
|
||||
"musicbrainzId": "589ff96d-0be8-3f82-bdd2-299592e51b40",
|
||||
"cover": {
|
||||
"href": "https://awesome.music/media/albums/covers/2018/10/02/b69d398b5-fdf6-4803-b47c-9bb7098ea57e.jpg",
|
||||
"type": "Link",
|
||||
"mediaType": "image/jpeg"
|
||||
},
|
||||
"artist_credit": [
|
||||
{}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Track
|
||||
|
||||
A `Track` is a custom object used to store track information.
|
||||
|
||||
#### Properties
|
||||
|
||||
```{list-table}
|
||||
:header-rows: 1
|
||||
|
||||
* - Property
|
||||
- Data type
|
||||
- Description
|
||||
* - `type`*
|
||||
- String
|
||||
- The object type (`Track`)
|
||||
* - `id`*
|
||||
- String (URI)
|
||||
- A URI that identifies the track over federation
|
||||
* - `name`*
|
||||
- String
|
||||
- The track title
|
||||
* - `position`*
|
||||
- Integer
|
||||
- The position of the track in the album
|
||||
* - `published`*
|
||||
- Datetime
|
||||
- The date on which the track was published over the federation
|
||||
* - `musicbrainzId`
|
||||
- String (UUID)
|
||||
- The Musicbrainz recording ID
|
||||
* - `album`
|
||||
- [`Album` object](#album)
|
||||
- The album that contains the track
|
||||
* - `artist_credit`
|
||||
- Array of strings
|
||||
- A list of [`ArtistCredit` objects](#artistcredit) associated with the track. This can differ from the album artists
|
||||
```
|
||||
|
||||
#### Example
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"type": "Track",
|
||||
"id": "https://awesome.music/federation/music/tracks/82ece296-6397-4e26-be90-bac5f9990240",
|
||||
"name": "Shock! Extinction de masse",
|
||||
"position": 3,
|
||||
"published": "2018-10-02T19:49:35.822537+00:00",
|
||||
"musicbrainzId": "771ab043-8821-44f9-b8e0-2733c3126c6d",
|
||||
"artist_credit": [
|
||||
{}
|
||||
],
|
||||
"album": {}
|
||||
}
|
||||
```
|
||||
|
||||
### Library
|
||||
|
||||
```{note}
|
||||
Crawling library pages requires authentication and an approved follow unless the library is public.
|
||||
```
|
||||
|
||||
A `Library` is a custom object used to store music collection information. It inherits its behavior and properties from ActivityPub's [`Actor`](https://www.w3.org/TR/activitypub/#actors) and [`Collection`](https://www.w3.org/TR/activitypub/#collections) objects.
|
||||
|
||||
#### Properties
|
||||
|
||||
```{list-table}
|
||||
:header-rows: 1
|
||||
|
||||
* - Property
|
||||
- Data type
|
||||
- Description
|
||||
* - `type`*
|
||||
- String
|
||||
- The object type (`Library`)
|
||||
* - `id`*
|
||||
- String (URI)
|
||||
- A URI that identifies the library over federation
|
||||
* - `name`*
|
||||
- String
|
||||
- The library's name
|
||||
* - `followers`*
|
||||
- String (URI)
|
||||
- The ID of the library's followers collection
|
||||
* - `totalItems`*
|
||||
- Integer
|
||||
- The number of [`Audio` objects](#audio) in the library
|
||||
* - `first`*
|
||||
- String (URI)
|
||||
- The URL of the library's first page
|
||||
* - `last`*
|
||||
- String (URI)
|
||||
- The URL of the library's last page
|
||||
* - `summary`
|
||||
- String
|
||||
- The library's description
|
||||
```
|
||||
|
||||
#### Example
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"type": "Library",
|
||||
"id": "https://awesome.music/federation/music/libraries/dc702491-f6ce-441b-9da0-cecbed08bcc6",
|
||||
"attributedTo": "https://awesome.music/federation/actors/Alice",
|
||||
"name": "My awesome library",
|
||||
"followers": "https://awesome.music/federation/music/libraries/dc702491-f6ce-441b-9da0-cecbed08bcc6/followers",
|
||||
"summary": "This library is for restricted use only",
|
||||
"totalItems": 4234,
|
||||
"first": "https://awesome.music/federation/music/libraries/dc702491-f6ce-441b-9da0-cecbed08bcc6?page=1",
|
||||
"last": "https://awesome.music/federation/music/libraries/dc702491-f6ce-441b-9da0-cecbed08bcc6?page=56",
|
||||
}
|
||||
```
|
||||
|
||||
### Audio
|
||||
|
||||
```{note}
|
||||
Accessing audio files requires authentication and an approved follow for the containing library unless the library is public.
|
||||
```
|
||||
|
||||
An `Audio` object is a custom object used to store upload information. It extends the [ActivityStreams Audio object](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-audio) with custom attributes.
|
||||
|
||||
#### Properties
|
||||
|
||||
```{list-table}
|
||||
:header-rows: 1
|
||||
|
||||
* - Property
|
||||
- Data type
|
||||
- Description
|
||||
* - `type`*
|
||||
- String
|
||||
- The object type (`Audio`)
|
||||
* - `id`*
|
||||
- String (URI)
|
||||
- A URI that identifies the audio over federation
|
||||
* - `name`*
|
||||
- String
|
||||
- A readable title for the order. Funkwhale concatenates the track name, album title, and artist name
|
||||
* - `size`*
|
||||
- Integer
|
||||
- The size of the audio in bytes
|
||||
* - `bitrate`*
|
||||
- Integer
|
||||
- The bitrate of the audio in bytes/s
|
||||
* - `duration`*
|
||||
- Integer
|
||||
- The duration of the audio in seconds
|
||||
* - `library`*
|
||||
- String (URI)
|
||||
- The ID of the audio's containing [`Library` object](#library)
|
||||
* - `published`*
|
||||
- Datetime
|
||||
- The date on which the audio was published over the federation
|
||||
* - `updated`*
|
||||
- Datetime
|
||||
- The date on which the audio was last updated over the federation
|
||||
* - `url`*
|
||||
- [`Link` object](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-link)
|
||||
- A `Link` object object containing the download location of the audio file
|
||||
* - `track`
|
||||
- [`Track` object](#track)
|
||||
- The track associated with the audio file
|
||||
```
|
||||
|
||||
#### Example
|
||||
|
||||
```{code-block} json
|
||||
{
|
||||
"type": "Audio",
|
||||
"id": "https://awesome.music/federation/music/uploads/88f0bc20-d7fd-461d-a641-dd9ac485e096",
|
||||
"name": "Krav Boca - Mortem",
|
||||
"size": 8656581,
|
||||
"bitrate": 320000,
|
||||
"duration": 213,
|
||||
"library": "https://awesome.music/federation/music/libraries/dc702491-f6ce-441b-9da0-cecbed08bcc6",
|
||||
"updated": "2018-10-02T19:49:35.646372+00:00",
|
||||
"published": "2018-10-02T19:49:35.646359+00:00",
|
||||
"track": {},
|
||||
"url": {
|
||||
"href": "https://awesome.music/api/v1/listen/82ece296-6397-4e26-be90-bac5f9990240/?upload=88f0bc20-d7fd-461d-a641-dd9ac485e096",
|
||||
"type": "Link",
|
||||
"mediaType": "audio/mpeg"
|
||||
}
|
||||
}
|
||||
```
|
Loading…
Reference in New Issue