Merge branch 'master' into develop
This commit is contained in:
commit
07f0f32677
|
@ -101,7 +101,8 @@ you can create a symlink like this::
|
||||||
|
|
||||||
And import music from this share with this command::
|
And import music from this share with this command::
|
||||||
|
|
||||||
python api/manage.py import_files "/srv/funkwhale/data/music/nfsshare/**/*.ogg" --recursive --noinput --in-place
|
export LIBRARY_ID="<your_libary_id>"
|
||||||
|
python api/manage.py import_files $LIBRARY_ID "/srv/funkwhale/data/music/nfsshare/**/*.ogg" --recursive --noinput --in-place
|
||||||
|
|
||||||
On docker setups, it will require a bit more work, because while the ``/srv/funkwhale/data/music`` is mounted
|
On docker setups, it will require a bit more work, because while the ``/srv/funkwhale/data/music`` is mounted
|
||||||
in containers, symlinked directories are not.
|
in containers, symlinked directories are not.
|
||||||
|
|
|
@ -164,7 +164,7 @@ match what is described in :doc:`/installation/debian`:
|
||||||
# download more recent API files
|
# download more recent API files
|
||||||
sudo -u funkwhale curl -L -o "api-$FUNKWHALE_VERSION.zip" "https://dev.funkwhale.audio/funkwhale/funkwhale/-/jobs/artifacts/$FUNKWHALE_VERSION/download?job=build_api"
|
sudo -u funkwhale curl -L -o "api-$FUNKWHALE_VERSION.zip" "https://dev.funkwhale.audio/funkwhale/funkwhale/-/jobs/artifacts/$FUNKWHALE_VERSION/download?job=build_api"
|
||||||
sudo -u funkwhale unzip "api-$FUNKWHALE_VERSION.zip" -d extracted
|
sudo -u funkwhale unzip "api-$FUNKWHALE_VERSION.zip" -d extracted
|
||||||
sudo -u funkwhale rm -rf api/ && mv extracted/api .
|
sudo -u funkwhale rm -rf api/ && sudo -u funkwhale mv extracted/api .
|
||||||
sudo -u funkwhale rm -rf extracted
|
sudo -u funkwhale rm -rf extracted
|
||||||
|
|
||||||
# update os dependencies
|
# update os dependencies
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/bin/bash -eux
|
#!/bin/bash -eux
|
||||||
# Building sphinx and swagger docs
|
# Building sphinx and swagger docs
|
||||||
|
|
||||||
python -m sphinx . $BUILD_PATH
|
python -m sphinx . $BUILD_PATH
|
||||||
TARGET_PATH="$BUILD_PATH/swagger" ./build_swagger.sh
|
TARGET_PATH="$BUILD_PATH/swagger" ./build_swagger.sh
|
||||||
|
python ./get-releases-json.py > $BUILD_PATH/releases.json
|
||||||
|
|
|
@ -59,10 +59,10 @@ The reverse proxy
|
||||||
|
|
||||||
Funkwhale's API server should never be exposed directly to the internet, as we require
|
Funkwhale's API server should never be exposed directly to the internet, as we require
|
||||||
a reverse proxy (Apache or Nginx) for performance and security reasons. The reverse proxy
|
a reverse proxy (Apache or Nginx) for performance and security reasons. The reverse proxy
|
||||||
will receive client HTTP requests, and:
|
will receive client HTTP or HTTPS requests, and:
|
||||||
|
|
||||||
- Proxy them to the API server
|
- Proxy them to the API server
|
||||||
- Serve requested static files (Audio files, stylesheets, javascript, fonts...)
|
- Serve requested static files (audio files, stylesheets, javascript, fonts...)
|
||||||
|
|
||||||
The API server
|
The API server
|
||||||
--------------
|
--------------
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
import json
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
from distutils.version import StrictVersion
|
||||||
|
|
||||||
|
|
||||||
|
def get_versions():
|
||||||
|
|
||||||
|
output = subprocess.check_output(
|
||||||
|
["git", "tag", "-l", "--format=%(creatordate:iso-strict)|%(refname:short)"]
|
||||||
|
)
|
||||||
|
tags = []
|
||||||
|
|
||||||
|
for line in output.decode().splitlines():
|
||||||
|
try:
|
||||||
|
date, tag = line.split("|")
|
||||||
|
except (ValueError):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not date or not tag:
|
||||||
|
continue
|
||||||
|
|
||||||
|
tags.append({"id": tag, "date": date})
|
||||||
|
return sorted(tags, key=lambda tag: StrictVersion(tag["id"]), reverse=True)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
versions = get_versions()
|
||||||
|
data = {"count": len(versions), "releases": versions}
|
||||||
|
print(json.dumps(data))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
|
@ -199,6 +199,7 @@ Download the sample environment file:
|
||||||
|
|
||||||
cp /srv/funkwhale/deploy/env.prod.sample /srv/funkwhale/config/.env
|
cp /srv/funkwhale/deploy/env.prod.sample /srv/funkwhale/config/.env
|
||||||
|
|
||||||
|
|
||||||
Generate a secret key for Django::
|
Generate a secret key for Django::
|
||||||
|
|
||||||
openssl rand -base64 45
|
openssl rand -base64 45
|
||||||
|
@ -208,7 +209,8 @@ configuration options are mentioned at the top of the file.
|
||||||
|
|
||||||
.. code-block:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
nano /srv/funkwhale/api/.env
|
chmod 600 /srv/funkwhale/config/.env # reduce permissions on the .env file since it contains sensitive data
|
||||||
|
nano /srv/funkwhale/config/.env
|
||||||
|
|
||||||
Paste the secret key you generated earlier at the entry
|
Paste the secret key you generated earlier at the entry
|
||||||
``DJANGO_SECRET_KEY`` and populate the ``DATABASE_URL``
|
``DJANGO_SECRET_KEY`` and populate the ``DATABASE_URL``
|
||||||
|
|
|
@ -52,10 +52,15 @@ Create an env file to store a few important configuration options:
|
||||||
touch .env
|
touch .env
|
||||||
echo "FUNKWHALE_HOSTNAME=yourdomain.funkwhale" >> .env
|
echo "FUNKWHALE_HOSTNAME=yourdomain.funkwhale" >> .env
|
||||||
echo "FUNKWHALE_PROTOCOL=https" >> .env # or http
|
echo "FUNKWHALE_PROTOCOL=https" >> .env # or http
|
||||||
|
echo "NGINX_MAX_BODY_SIZE=100M" >> .env
|
||||||
|
echo "FUNKWHALE_API_IP=127.0.0.1" >> .env
|
||||||
|
echo "FUNKWHALE_API_PORT=5000" >> .env # or the container port you want to expose on the host
|
||||||
echo "DJANGO_SECRET_KEY=$(openssl rand -hex 45)" >> .env # generate and store a secure secret key for your instance
|
echo "DJANGO_SECRET_KEY=$(openssl rand -hex 45)" >> .env # generate and store a secure secret key for your instance
|
||||||
# Remove this if you expose the container directly on ports 80/443
|
# Remove this if you expose the container directly on ports 80/443
|
||||||
echo "NESTED_PROXY=1" >> .env
|
echo "NESTED_PROXY=1" >> .env
|
||||||
|
|
||||||
|
chmod 600 .env # reduce permissions on the .env file since it contains sensitive data
|
||||||
|
|
||||||
Then start the container:
|
Then start the container:
|
||||||
|
|
||||||
.. code-block:: shell
|
.. code-block:: shell
|
||||||
|
@ -179,8 +184,10 @@ Create your env file:
|
||||||
|
|
||||||
curl -L -o .env "https://dev.funkwhale.audio/funkwhale/funkwhale/raw/|version|/deploy/env.prod.sample"
|
curl -L -o .env "https://dev.funkwhale.audio/funkwhale/funkwhale/raw/|version|/deploy/env.prod.sample"
|
||||||
sed -i "s/FUNKWHALE_VERSION=latest/FUNKWHALE_VERSION=$FUNKWHALE_VERSION/" .env
|
sed -i "s/FUNKWHALE_VERSION=latest/FUNKWHALE_VERSION=$FUNKWHALE_VERSION/" .env
|
||||||
|
chmod 600 .env # reduce permissions on the .env file since it contains sensitive data
|
||||||
sudo nano .env
|
sudo nano .env
|
||||||
|
|
||||||
|
|
||||||
Ensure to edit it to match your needs (this file is heavily commented), in particular ``DJANGO_SECRET_KEY`` and ``FUNKWHALE_HOSTNAME``.
|
Ensure to edit it to match your needs (this file is heavily commented), in particular ``DJANGO_SECRET_KEY`` and ``FUNKWHALE_HOSTNAME``.
|
||||||
You should take a look at the `configuration reference <https://docs.funkwhale.audio/configuration.html#configuration-reference>`_ for more detailed information regarding each setting.
|
You should take a look at the `configuration reference <https://docs.funkwhale.audio/configuration.html#configuration-reference>`_ for more detailed information regarding each setting.
|
||||||
|
|
||||||
|
|
747
docs/swagger.yml
747
docs/swagger.yml
|
@ -1,6 +1,44 @@
|
||||||
|
# Undocumented endpoints:
|
||||||
|
# /api/v1/settings
|
||||||
|
# /api/v1/activity
|
||||||
|
# /api/v1/playlists
|
||||||
|
# /api/v1/playlist-tracks
|
||||||
|
# /api/v1/search
|
||||||
|
# /api/v1/radios
|
||||||
|
# /api/v1/history
|
||||||
|
|
||||||
openapi: "3.0.2"
|
openapi: "3.0.2"
|
||||||
info:
|
info:
|
||||||
description: "Documentation for [Funkwhale](https://funkwhale.audio) API. The API is **not** stable yet."
|
description: |
|
||||||
|
Interactive documentation for [Funkwhale](https://funkwhale.audio) API.
|
||||||
|
|
||||||
|
The API is **not** freezed yet, but we will document breaking changes in our changelog,
|
||||||
|
and try to avoid those as much as possible.
|
||||||
|
|
||||||
|
Usage
|
||||||
|
-----
|
||||||
|
|
||||||
|
Click on an endpoint name to inspect its properties, parameters and responses.
|
||||||
|
|
||||||
|
Use the "Try it out" button to send a real world payload to the endpoint and inspect
|
||||||
|
the corresponding response.
|
||||||
|
|
||||||
|
Authentication
|
||||||
|
--------------
|
||||||
|
|
||||||
|
To authenticate, use the `/token/` endpoint with a username and password, and copy/paste
|
||||||
|
the resulting JWT token in the `Authorize` modal. All subsequent requests made via the interactive
|
||||||
|
documentation will be authenticated.
|
||||||
|
|
||||||
|
If you keep the default server (https://demo.funkwhale.audio), the default username and password
|
||||||
|
couple is "demo" and "demo".
|
||||||
|
|
||||||
|
Resources
|
||||||
|
---------
|
||||||
|
|
||||||
|
For more targeted guides regarding API usage, and especially authentication, please
|
||||||
|
refer to [https://docs.funkwhale.audio/api.html](https://docs.funkwhale.audio/api.html)
|
||||||
|
|
||||||
version: "1.0.0"
|
version: "1.0.0"
|
||||||
title: "Funkwhale API"
|
title: "Funkwhale API"
|
||||||
|
|
||||||
|
@ -63,6 +101,18 @@ security:
|
||||||
- jwt: []
|
- jwt: []
|
||||||
- oauth2: []
|
- oauth2: []
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- name: Auth and security
|
||||||
|
description: Login, logout and authorization endpoints
|
||||||
|
- name: Library and metadata
|
||||||
|
description: Information and metadata about musical and audio entities (albums, tracks, artists, etc.)
|
||||||
|
- name: Uploads and audio content
|
||||||
|
description: Manipulation and uploading of audio files
|
||||||
|
externalDocs:
|
||||||
|
url: https://docs.funkwhale.audio/users/managing.html
|
||||||
|
- name: Content curation
|
||||||
|
description: Favorites, playlists, radios
|
||||||
|
|
||||||
paths:
|
paths:
|
||||||
/api/v1/oauth/apps/:
|
/api/v1/oauth/apps/:
|
||||||
post:
|
post:
|
||||||
|
@ -101,7 +151,8 @@ paths:
|
||||||
/api/v1/token/:
|
/api/v1/token/:
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
- "auth"
|
- "Auth and security"
|
||||||
|
summary: Get an API token
|
||||||
description:
|
description:
|
||||||
Obtain a JWT token you can use for authenticating your next requests.
|
Obtain a JWT token you can use for authenticating your next requests.
|
||||||
security: []
|
security: []
|
||||||
|
@ -124,11 +175,83 @@ paths:
|
||||||
type: "string"
|
type: "string"
|
||||||
example: "demo"
|
example: "demo"
|
||||||
|
|
||||||
|
/api/v1/auth/registration/:
|
||||||
|
post:
|
||||||
|
summary: Create an account
|
||||||
|
description: |
|
||||||
|
Register a new account on this instance. An invitation code will be required
|
||||||
|
if sign up is disabled.
|
||||||
|
tags:
|
||||||
|
- "Auth and security"
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: "object"
|
||||||
|
properties:
|
||||||
|
username:
|
||||||
|
type: "string"
|
||||||
|
example: "alice"
|
||||||
|
email:
|
||||||
|
type: "string"
|
||||||
|
format: "email"
|
||||||
|
invitation:
|
||||||
|
type: "string"
|
||||||
|
example: "INVITECODE"
|
||||||
|
required: false
|
||||||
|
description: An invitation code, required if signups are closed on the instance.
|
||||||
|
password1:
|
||||||
|
type: "string"
|
||||||
|
example: "passw0rd"
|
||||||
|
password2:
|
||||||
|
type: "string"
|
||||||
|
description: Must be identical to password1
|
||||||
|
example: "passw0rd"
|
||||||
|
responses:
|
||||||
|
201:
|
||||||
|
$ref: "#/responses/201"
|
||||||
|
/api/v1/auth/password/reset/:
|
||||||
|
post:
|
||||||
|
summary: Request a password reset
|
||||||
|
description: |
|
||||||
|
Request a password reset. An email with reset instructions will be sent to the provided email,
|
||||||
|
if it's associated with a user account.
|
||||||
|
tags:
|
||||||
|
- "Auth and security"
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: "object"
|
||||||
|
properties:
|
||||||
|
email:
|
||||||
|
type: "string"
|
||||||
|
format: "email"
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
$ref: "#/responses/200"
|
||||||
|
/api/v1/users/users/me/:
|
||||||
|
get:
|
||||||
|
summary: Retrive profile information
|
||||||
|
description: |
|
||||||
|
Retrieve profile informations of the current user
|
||||||
|
tags:
|
||||||
|
- "Auth and security"
|
||||||
|
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/definitions/Me"
|
||||||
|
|
||||||
/api/v1/artists/:
|
/api/v1/artists/:
|
||||||
get:
|
get:
|
||||||
summary: List artists
|
summary: List artists
|
||||||
tags:
|
tags:
|
||||||
- "artists"
|
- "Library and metadata"
|
||||||
security:
|
security:
|
||||||
- oauth2:
|
- oauth2:
|
||||||
- "read:libraries"
|
- "read:libraries"
|
||||||
|
@ -140,7 +263,6 @@ paths:
|
||||||
schema:
|
schema:
|
||||||
required: false
|
required: false
|
||||||
type: "string"
|
type: "string"
|
||||||
example: "carpenter"
|
|
||||||
- allOf:
|
- allOf:
|
||||||
- $ref: "#/parameters/Ordering"
|
- $ref: "#/parameters/Ordering"
|
||||||
- default: "-creation_date"
|
- default: "-creation_date"
|
||||||
|
@ -178,7 +300,7 @@ paths:
|
||||||
- oauth2:
|
- oauth2:
|
||||||
- "read:libraries"
|
- "read:libraries"
|
||||||
tags:
|
tags:
|
||||||
- "artists"
|
- "Library and metadata"
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
content:
|
content:
|
||||||
|
@ -202,8 +324,7 @@ paths:
|
||||||
- $ref: "#/parameters/PageSize"
|
- $ref: "#/parameters/PageSize"
|
||||||
|
|
||||||
tags:
|
tags:
|
||||||
- "artists"
|
- "Library and metadata"
|
||||||
- "libraries"
|
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
content:
|
content:
|
||||||
|
@ -220,7 +341,7 @@ paths:
|
||||||
get:
|
get:
|
||||||
summary: List albums
|
summary: List albums
|
||||||
tags:
|
tags:
|
||||||
- "albums"
|
- "Library and metadata"
|
||||||
|
|
||||||
security:
|
security:
|
||||||
- oauth2:
|
- oauth2:
|
||||||
|
@ -233,7 +354,6 @@ paths:
|
||||||
schema:
|
schema:
|
||||||
required: false
|
required: false
|
||||||
type: "string"
|
type: "string"
|
||||||
example: "carpenter"
|
|
||||||
- name: "artist"
|
- name: "artist"
|
||||||
in: "query"
|
in: "query"
|
||||||
default: null
|
default: null
|
||||||
|
@ -280,7 +400,7 @@ paths:
|
||||||
- oauth2:
|
- oauth2:
|
||||||
- "read:libraries"
|
- "read:libraries"
|
||||||
tags:
|
tags:
|
||||||
- "albums"
|
- "Library and metadata"
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
content:
|
content:
|
||||||
|
@ -305,8 +425,7 @@ paths:
|
||||||
- oauth2:
|
- oauth2:
|
||||||
- "read:libraries"
|
- "read:libraries"
|
||||||
tags:
|
tags:
|
||||||
- "albums"
|
- "Library and metadata"
|
||||||
- "libraries"
|
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
content:
|
content:
|
||||||
|
@ -323,7 +442,7 @@ paths:
|
||||||
get:
|
get:
|
||||||
summary: List tracks
|
summary: List tracks
|
||||||
tags:
|
tags:
|
||||||
- "tracks"
|
- "Library and metadata"
|
||||||
|
|
||||||
security:
|
security:
|
||||||
- oauth2:
|
- oauth2:
|
||||||
|
@ -336,7 +455,6 @@ paths:
|
||||||
schema:
|
schema:
|
||||||
required: false
|
required: false
|
||||||
type: "string"
|
type: "string"
|
||||||
example: "carpenter"
|
|
||||||
- name: "artist"
|
- name: "artist"
|
||||||
in: "query"
|
in: "query"
|
||||||
default: null
|
default: null
|
||||||
|
@ -345,6 +463,13 @@ paths:
|
||||||
required: false
|
required: false
|
||||||
type: "integer"
|
type: "integer"
|
||||||
format: "int64"
|
format: "int64"
|
||||||
|
- name: "favorites"
|
||||||
|
in: "query"
|
||||||
|
default: null
|
||||||
|
description: "filter/exclude tracks favorited by the current user"
|
||||||
|
schema:
|
||||||
|
required: false
|
||||||
|
type: "boolean"
|
||||||
- name: "album"
|
- name: "album"
|
||||||
in: "query"
|
in: "query"
|
||||||
default: null
|
default: null
|
||||||
|
@ -391,15 +516,15 @@ paths:
|
||||||
$ref: "#/definitions/Track"
|
$ref: "#/definitions/Track"
|
||||||
/api/v1/tracks/{id}/:
|
/api/v1/tracks/{id}/:
|
||||||
get:
|
get:
|
||||||
summary: Retrieve a single track
|
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: "#/parameters/ObjectId"
|
- $ref: "#/parameters/ObjectId"
|
||||||
|
summary: Retrieve a single track
|
||||||
|
|
||||||
security:
|
security:
|
||||||
- oauth2:
|
- oauth2:
|
||||||
- "read:libraries"
|
- "read:libraries"
|
||||||
tags:
|
tags:
|
||||||
- "tracks"
|
- "Library and metadata"
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
content:
|
content:
|
||||||
|
@ -423,8 +548,7 @@ paths:
|
||||||
- oauth2:
|
- oauth2:
|
||||||
- "read:libraries"
|
- "read:libraries"
|
||||||
tags:
|
tags:
|
||||||
- "tracks"
|
- "Library and metadata"
|
||||||
- "libraries"
|
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
content:
|
content:
|
||||||
|
@ -436,6 +560,66 @@ paths:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: "#/definitions/ResourceNotFound"
|
$ref: "#/definitions/ResourceNotFound"
|
||||||
|
/api/v1/listen/{uuid}/:
|
||||||
|
get:
|
||||||
|
summary: Download the audio file matching the given track uuid
|
||||||
|
description: |
|
||||||
|
Given a track uuid (and not ID), return the first found audio file
|
||||||
|
accessible by the user making the request.
|
||||||
|
|
||||||
|
In case of a remote upload, this endpoint will fetch the audio file from the remote
|
||||||
|
and cache it before sending the response.
|
||||||
|
|
||||||
|
parameters:
|
||||||
|
- name: uuid
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
description: Track uuid
|
||||||
|
schema:
|
||||||
|
type: "string"
|
||||||
|
format: "uuid"
|
||||||
|
- name: to
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
description: |
|
||||||
|
If specified, the endpoint will return a transcoded version of the original
|
||||||
|
audio file.
|
||||||
|
|
||||||
|
Since transcoding happens on the fly, it can significantly increase response time,
|
||||||
|
and it's recommended to request transcoding only for files that are not playable
|
||||||
|
by the client.
|
||||||
|
|
||||||
|
This endpoint support bytess-range requests.
|
||||||
|
schema:
|
||||||
|
$ref: "#/properties/transcode_options"
|
||||||
|
- name: upload
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
summary: An upload uuid
|
||||||
|
description: |
|
||||||
|
If specified, will return the audio for the given upload uuid.
|
||||||
|
|
||||||
|
This is useful for tracks that have multiple uploads available.
|
||||||
|
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- "Library and metadata"
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
content:
|
||||||
|
'*/*':
|
||||||
|
description: "Audio file, as binary data"
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: binary
|
||||||
|
404:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/definitions/ResourceNotFound"
|
||||||
|
|
||||||
/api/v1/licenses/:
|
/api/v1/licenses/:
|
||||||
get:
|
get:
|
||||||
|
@ -444,7 +628,7 @@ paths:
|
||||||
- oauth2:
|
- oauth2:
|
||||||
- "read:libraries"
|
- "read:libraries"
|
||||||
tags:
|
tags:
|
||||||
- "licenses"
|
- "Library and metadata"
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: "#/parameters/PageNumber"
|
- $ref: "#/parameters/PageNumber"
|
||||||
- $ref: "#/parameters/PageSize"
|
- $ref: "#/parameters/PageSize"
|
||||||
|
@ -478,7 +662,7 @@ paths:
|
||||||
example: cc0-1.0
|
example: cc0-1.0
|
||||||
|
|
||||||
tags:
|
tags:
|
||||||
- "licenses"
|
- "Library and metadata"
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
content:
|
content:
|
||||||
|
@ -491,6 +675,263 @@ paths:
|
||||||
schema:
|
schema:
|
||||||
$ref: "#/definitions/ResourceNotFound"
|
$ref: "#/definitions/ResourceNotFound"
|
||||||
|
|
||||||
|
/api/v1/libraries/:
|
||||||
|
get:
|
||||||
|
summary: List owned libraries
|
||||||
|
tags:
|
||||||
|
- "Uploads and audio content"
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/parameters/PageNumber"
|
||||||
|
- $ref: "#/parameters/PageSize"
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/definitions/ResultPage"
|
||||||
|
- type: "object"
|
||||||
|
properties:
|
||||||
|
results:
|
||||||
|
type: "array"
|
||||||
|
items:
|
||||||
|
$ref: "#/definitions/OwnedLibrary"
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- "Uploads and audio content"
|
||||||
|
description:
|
||||||
|
Create a new library
|
||||||
|
responses:
|
||||||
|
201:
|
||||||
|
$ref: "#/responses/201"
|
||||||
|
400:
|
||||||
|
$ref: "#/responses/400"
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/definitions/OwnedLibraryCreate"
|
||||||
|
|
||||||
|
/api/v1/libraries/{uuid}/:
|
||||||
|
parameters:
|
||||||
|
- name: uuid
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: "string"
|
||||||
|
format: "uuid"
|
||||||
|
get:
|
||||||
|
summary: Retrieve a library
|
||||||
|
tags:
|
||||||
|
- "Uploads and audio content"
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/definitions/OwnedLibrary"
|
||||||
|
post:
|
||||||
|
summary: Update a library
|
||||||
|
tags:
|
||||||
|
- "Uploads and audio content"
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/definitions/OwnedLibraryCreate"
|
||||||
|
responses:
|
||||||
|
201:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/definitions/OwnedLibrary"
|
||||||
|
delete:
|
||||||
|
summary: Delete a library and all associated uploads
|
||||||
|
description: |
|
||||||
|
This will delete the library, all associated uploads, follows, and broadcast
|
||||||
|
the event on the federation.
|
||||||
|
tags:
|
||||||
|
- "Uploads and audio content"
|
||||||
|
responses:
|
||||||
|
204:
|
||||||
|
$ref: "#/responses/204"
|
||||||
|
|
||||||
|
/api/v1/uploads/:
|
||||||
|
get:
|
||||||
|
summary: List owned uploads
|
||||||
|
tags:
|
||||||
|
- "Uploads and audio content"
|
||||||
|
parameters:
|
||||||
|
- name: "q"
|
||||||
|
in: "query"
|
||||||
|
default: null
|
||||||
|
description: "Search query used to filter uploads"
|
||||||
|
schema:
|
||||||
|
required: false
|
||||||
|
type: "string"
|
||||||
|
example: "Dire straits"
|
||||||
|
- $ref: "#/parameters/PageNumber"
|
||||||
|
- $ref: "#/parameters/PageSize"
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/definitions/ResultPage"
|
||||||
|
- type: "object"
|
||||||
|
properties:
|
||||||
|
results:
|
||||||
|
type: "array"
|
||||||
|
items:
|
||||||
|
$ref: "#/definitions/OwnedUpload"
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- "Uploads and audio content"
|
||||||
|
description:
|
||||||
|
Upload a new file in a library. The event will be broadcasted on federation,
|
||||||
|
according to the library visibility and followers.
|
||||||
|
responses:
|
||||||
|
201:
|
||||||
|
$ref: "#/responses/201"
|
||||||
|
400:
|
||||||
|
$ref: "#/responses/400"
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
multipart/form-data:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
library:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
description: "The library in which the audio should be stored"
|
||||||
|
import_reference:
|
||||||
|
type: string
|
||||||
|
example: "Import launched via API client on 04/19"
|
||||||
|
source:
|
||||||
|
type: string
|
||||||
|
example: "upload://filename.mp3"
|
||||||
|
audio_file:
|
||||||
|
type: string
|
||||||
|
format: binary
|
||||||
|
|
||||||
|
/api/v1/uploads/{uuid}/:
|
||||||
|
parameters:
|
||||||
|
- name: uuid
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: "string"
|
||||||
|
format: "uuid"
|
||||||
|
get:
|
||||||
|
summary: Retrieve an upload
|
||||||
|
tags:
|
||||||
|
- "Uploads and audio content"
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/definitions/OwnedUpload"
|
||||||
|
delete:
|
||||||
|
summary: Delete an upload
|
||||||
|
description: |
|
||||||
|
This will delete the upload from the server and broadcast the event
|
||||||
|
on the federation.
|
||||||
|
tags:
|
||||||
|
- "Uploads and audio content"
|
||||||
|
responses:
|
||||||
|
204:
|
||||||
|
$ref: "#/responses/204"
|
||||||
|
|
||||||
|
/api/v1/favorites/tracks/:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- "Content curation"
|
||||||
|
parameters:
|
||||||
|
- name: "q"
|
||||||
|
in: "query"
|
||||||
|
default: null
|
||||||
|
description: "Search query used to filter favorites"
|
||||||
|
schema:
|
||||||
|
required: false
|
||||||
|
type: "string"
|
||||||
|
- name: "user"
|
||||||
|
in: "query"
|
||||||
|
default: null
|
||||||
|
description: "Limit results to favorites belonging to the given user"
|
||||||
|
schema:
|
||||||
|
$ref: "#/parameters/ObjectId"
|
||||||
|
- $ref: "#/parameters/PageNumber"
|
||||||
|
- $ref: "#/parameters/PageSize"
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/definitions/ResultPage"
|
||||||
|
- type: "object"
|
||||||
|
properties:
|
||||||
|
results:
|
||||||
|
type: "array"
|
||||||
|
items:
|
||||||
|
$ref: "#/definitions/TrackFavorite"
|
||||||
|
post:
|
||||||
|
summary: Mark the given track as favorite
|
||||||
|
tags:
|
||||||
|
- "Content curation"
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: "object"
|
||||||
|
properties:
|
||||||
|
track:
|
||||||
|
type: "integer"
|
||||||
|
format: "int64"
|
||||||
|
example: 98
|
||||||
|
responses:
|
||||||
|
201:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: "object"
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: "integer"
|
||||||
|
format: "int64"
|
||||||
|
example: 876
|
||||||
|
track:
|
||||||
|
type: "integer"
|
||||||
|
format: "int64"
|
||||||
|
example: 98
|
||||||
|
creation_date:
|
||||||
|
$ref: "#/properties/creation_date"
|
||||||
|
/api/v1/favorites/tracks/remove/:
|
||||||
|
post:
|
||||||
|
summary: Remove the given track from favorites
|
||||||
|
tags:
|
||||||
|
- "Content curation"
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: "object"
|
||||||
|
properties:
|
||||||
|
track:
|
||||||
|
type: "integer"
|
||||||
|
format: "int64"
|
||||||
|
example: 98
|
||||||
|
responses:
|
||||||
|
204:
|
||||||
|
$ref: "#/responses/204"
|
||||||
|
|
||||||
parameters:
|
parameters:
|
||||||
ObjectId:
|
ObjectId:
|
||||||
|
@ -534,11 +975,67 @@ parameters:
|
||||||
required: false
|
required: false
|
||||||
type: "boolean"
|
type: "boolean"
|
||||||
|
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Success
|
||||||
|
201:
|
||||||
|
description: Successfully created
|
||||||
|
204:
|
||||||
|
description: Successfully deleted
|
||||||
|
400:
|
||||||
|
description: Bad request
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
mbid:
|
mbid:
|
||||||
type: "string"
|
type: "string"
|
||||||
formats: "uuid"
|
format: "uuid"
|
||||||
description: "A musicbrainz ID"
|
description: "A musicbrainz ID"
|
||||||
|
creation_date:
|
||||||
|
type: "string"
|
||||||
|
format: "date-time"
|
||||||
|
privacy_level:
|
||||||
|
type: string
|
||||||
|
example: "me"
|
||||||
|
description: |
|
||||||
|
* `me`: private
|
||||||
|
* `instance`: accessible by local users
|
||||||
|
* `everyone`: public (including over federation)
|
||||||
|
enum:
|
||||||
|
- "me"
|
||||||
|
- "instance"
|
||||||
|
- "everyone"
|
||||||
|
fid:
|
||||||
|
type: "string"
|
||||||
|
format: "uri"
|
||||||
|
description: "Federation ID"
|
||||||
|
example: "https://my.instance/federation/music/libraries/3fa85f64-5717-4562-b3fc-2c963f66afa6"
|
||||||
|
audio_mimetype:
|
||||||
|
type: string
|
||||||
|
example: "audio/ogg"
|
||||||
|
enum:
|
||||||
|
- "audio/ogg"
|
||||||
|
- "audio/mpeg"
|
||||||
|
- "audio/x-flac"
|
||||||
|
- "audio/flac"
|
||||||
|
import_status:
|
||||||
|
type: string
|
||||||
|
example: "finished"
|
||||||
|
enum:
|
||||||
|
- "pending"
|
||||||
|
- "finished"
|
||||||
|
- "errored"
|
||||||
|
- "skipped"
|
||||||
|
description: |
|
||||||
|
* `pending`: waiting to be processed by the server
|
||||||
|
* `finished`: successfully processed by the server
|
||||||
|
* `errored`: couldn't be processed by the server (e.g because of a tagging issue)
|
||||||
|
* `skipped`: processed by the server but skipped, because considered as a duplicate of an existing upload
|
||||||
|
|
||||||
|
transcode_options:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- "ogg"
|
||||||
|
- "mp3"
|
||||||
|
|
||||||
definitions:
|
definitions:
|
||||||
OAuthApplication:
|
OAuthApplication:
|
||||||
|
@ -926,23 +1423,215 @@ definitions:
|
||||||
example: 128000
|
example: 128000
|
||||||
description: "Bitrate of the file, in bytes/s"
|
description: "Bitrate of the file, in bytes/s"
|
||||||
mimetype:
|
mimetype:
|
||||||
type: string
|
$ref: "#/properties/audio_mimetype"
|
||||||
example: "audio/ogg"
|
|
||||||
enum:
|
|
||||||
- "audio/ogg"
|
|
||||||
- "audio/mpeg"
|
|
||||||
- "audio/x-flac"
|
|
||||||
- "audio/flac"
|
|
||||||
extension:
|
extension:
|
||||||
type: string
|
type: string
|
||||||
example: "ogg"
|
example: "ogg"
|
||||||
description: "File extension of the upload"
|
description: "File extension of the upload"
|
||||||
|
filename:
|
||||||
|
type: "string"
|
||||||
|
example: "Myfile.mp3"
|
||||||
listen_url:
|
listen_url:
|
||||||
type: "string"
|
type: "string"
|
||||||
format: "uri"
|
format: "uri"
|
||||||
description: "URL to stream the upload"
|
description: "URL to stream the upload"
|
||||||
|
|
||||||
|
OwnedLibraryCreate:
|
||||||
|
type: "object"
|
||||||
|
properties:
|
||||||
|
password:
|
||||||
|
type: "name"
|
||||||
|
example: "My new library"
|
||||||
|
description:
|
||||||
|
required: false
|
||||||
|
type: "string"
|
||||||
|
example: "Lots of interesting content"
|
||||||
|
privacy_level:
|
||||||
|
$ref: "#/properties/privacy_level"
|
||||||
|
|
||||||
|
OwnedLibrary:
|
||||||
|
type: "object"
|
||||||
|
properties:
|
||||||
|
uuid:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
fid:
|
||||||
|
$ref: "#/properties/fid"
|
||||||
|
name:
|
||||||
|
type: "string"
|
||||||
|
example: "My Creative Commons library"
|
||||||
|
description:
|
||||||
|
type: "string"
|
||||||
|
example: "All content is under CC-BY"
|
||||||
|
creation_date:
|
||||||
|
$ref: "#/properties/creation_date"
|
||||||
|
privacy_level:
|
||||||
|
$ref: "#/properties/privacy_level"
|
||||||
|
uploads_count:
|
||||||
|
type: "integer"
|
||||||
|
format: "int64"
|
||||||
|
example: 34
|
||||||
|
size:
|
||||||
|
type: "integer"
|
||||||
|
format: "int64"
|
||||||
|
example: 678917000
|
||||||
|
description: "Total size of uploads in the library, in bytes"
|
||||||
|
|
||||||
|
OwnedUpload:
|
||||||
|
type: "object"
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/definitions/Upload"
|
||||||
|
- type: "object"
|
||||||
|
properties:
|
||||||
|
import_status:
|
||||||
|
$ref: "#/properties/import_status"
|
||||||
|
track:
|
||||||
|
$ref: "#/definitions/Track"
|
||||||
|
library:
|
||||||
|
$ref: "#/definitions/OwnedLibrary"
|
||||||
|
source:
|
||||||
|
type: "string"
|
||||||
|
example: "upload://myfile.mp3"
|
||||||
|
import_reference:
|
||||||
|
type: "string"
|
||||||
|
example: "Import launched via web UI on 03/18"
|
||||||
|
TrackFavorite:
|
||||||
|
type: "object"
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: "integer"
|
||||||
|
format: "int64"
|
||||||
|
example: 876
|
||||||
|
track:
|
||||||
|
$ref: "#/definitions/Track"
|
||||||
|
user:
|
||||||
|
$ref: "#/definitions/User"
|
||||||
|
creation_date:
|
||||||
|
$ref: "#/properties/creation_date"
|
||||||
|
User:
|
||||||
|
type: "object"
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: "integer"
|
||||||
|
format: "int64"
|
||||||
|
example: 23
|
||||||
|
username:
|
||||||
|
type: "string"
|
||||||
|
example: "alice"
|
||||||
|
name:
|
||||||
|
type: "string"
|
||||||
|
example: "Alice Kingsley"
|
||||||
|
avatar:
|
||||||
|
$ref: "#/definitions/Avatar"
|
||||||
|
|
||||||
|
Me:
|
||||||
|
type: "object"
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/definitions/User"
|
||||||
|
- type: "object"
|
||||||
|
properties:
|
||||||
|
full_username:
|
||||||
|
type: "string"
|
||||||
|
description: Full username, for use on federation
|
||||||
|
example: "alice@yourdomain.com"
|
||||||
|
email:
|
||||||
|
type: "string"
|
||||||
|
format: "email"
|
||||||
|
description: Email address associated with the account
|
||||||
|
example: "alice@email.provider"
|
||||||
|
is_staff:
|
||||||
|
type: "boolean"
|
||||||
|
example: false
|
||||||
|
is_superuser:
|
||||||
|
type: "boolean"
|
||||||
|
example: false
|
||||||
|
date_joined:
|
||||||
|
type: "string"
|
||||||
|
format: "date-time"
|
||||||
|
privacy_level:
|
||||||
|
$ref: "#/properties/privacy_level"
|
||||||
|
description: Default privacy-level associated with the user account
|
||||||
|
quota_status:
|
||||||
|
$ref: "#/definitions/QuotaStatus"
|
||||||
|
permissions:
|
||||||
|
$ref: "#/definitions/Permissions"
|
||||||
|
Avatar:
|
||||||
|
type: "object"
|
||||||
|
properties:
|
||||||
|
original:
|
||||||
|
type: "string"
|
||||||
|
format: "uri"
|
||||||
|
description: "Original image URL"
|
||||||
|
example: "http://yourinstance/media/users/avatars/92/49/60/b3c-4736-43b3-bb5c-ed7a99ac6996.jpg"
|
||||||
|
square_crop:
|
||||||
|
type: "string"
|
||||||
|
format: "uri"
|
||||||
|
description: "400x400 thumbnail URL"
|
||||||
|
example: "http://yourinstance/media/__sized__/users/avatars/92/49/60/b3c-4736-43b3-bb5c-ed7a99ac6996-crop-c0-5__0-5-400x400-70.jpg"
|
||||||
|
small_square_crop:
|
||||||
|
type: "string"
|
||||||
|
format: "uri"
|
||||||
|
description: "50x50 thumbnail URL"
|
||||||
|
example: "http://yourinstance/media/__sized__/users/avatars/92/49/60/b3c-4736-43b3-bb5c-ed7a99ac6996-crop-c0-5__0-5-50x50-70.jpg"
|
||||||
|
medium_square_crop:
|
||||||
|
type: "string"
|
||||||
|
format: "uri"
|
||||||
|
description: "200x200 thumbnail URL"
|
||||||
|
example: "http://yourinstance/media/__sized__/users/avatars/92/49/60/b3c-4736-43b3-bb5c-ed7a99ac6996-crop-c0-5__0-5-200x200-70.jpg"
|
||||||
|
QuotaStatus:
|
||||||
|
type: "object"
|
||||||
|
properties:
|
||||||
|
max:
|
||||||
|
type: "integer"
|
||||||
|
format: "int64"
|
||||||
|
description: Storage space allocated to this user, in MB
|
||||||
|
example: 5000
|
||||||
|
remaining:
|
||||||
|
type: "integer"
|
||||||
|
format: "int64"
|
||||||
|
description: Remaining storage space for this user, in MB
|
||||||
|
example: 4600
|
||||||
|
current:
|
||||||
|
type: "integer"
|
||||||
|
format: "int64"
|
||||||
|
description: Storage space used by this user, in MB
|
||||||
|
example: 400
|
||||||
|
skipped:
|
||||||
|
type: "integer"
|
||||||
|
format: "int64"
|
||||||
|
description: Storage space occupied by uploads with "skipped" import status, in MB
|
||||||
|
example: 30
|
||||||
|
finished:
|
||||||
|
type: "integer"
|
||||||
|
format: "int64"
|
||||||
|
description: Storage space occupied by uploads with "finished" import status, in MB
|
||||||
|
example: 350
|
||||||
|
pending:
|
||||||
|
type: "integer"
|
||||||
|
format: "int64"
|
||||||
|
description: Storage space occupied by uploads with "pending" import status, in MB
|
||||||
|
example: 15
|
||||||
|
errored:
|
||||||
|
type: "integer"
|
||||||
|
format: "int64"
|
||||||
|
description: Storage space occupied by uploads with "errored" import status, in MB
|
||||||
|
example: 5
|
||||||
|
Permissions:
|
||||||
|
type: "object"
|
||||||
|
properties:
|
||||||
|
library:
|
||||||
|
type: "boolean"
|
||||||
|
example: false
|
||||||
|
description: A boolean indicating if the user can manage the instance library
|
||||||
|
moderation:
|
||||||
|
type: "boolean"
|
||||||
|
example: false
|
||||||
|
description: A boolean indicating if the user has moderation permission
|
||||||
|
settings:
|
||||||
|
type: "boolean"
|
||||||
|
example: false
|
||||||
|
description: A boolean indicating if the user can manage instance settings and users
|
||||||
|
|
||||||
ResourceNotFound:
|
ResourceNotFound:
|
||||||
type: "object"
|
type: "object"
|
||||||
properties:
|
properties:
|
||||||
|
|
|
@ -2,10 +2,10 @@ Creating a Funkwhale Account
|
||||||
============================
|
============================
|
||||||
|
|
||||||
Before you can start using Funkwhale, you will need to set up an account on an instance. While
|
Before you can start using Funkwhale, you will need to set up an account on an instance. While
|
||||||
some instances allow you to listen to public music anonymously, you will need to create account
|
some instances allow you to listen to public music anonymously, you will need to create an account
|
||||||
to benefit from the full Funkwhale experience.
|
to benefit from the full Funkwhale experience.
|
||||||
|
|
||||||
A list of instances along with other useful information such as version and enabled features can be found
|
A list of instances along with other useful informations such as version and enabled features can be found
|
||||||
`here <https://network.funkwhale.audio/dashboards/d/overview/network-overview>`_. Servers marked with
|
`here <https://network.funkwhale.audio/dashboards/d/overview/network-overview>`_. Servers marked with
|
||||||
"Open registrations" are available to sign up to.
|
"Open registrations" are available to sign up to.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue