docs: Add NodeInfo 2.1 specification and schema
Part-of: <https://dev.funkwhale.audio/funkwhale/funkwhale/-/merge_requests/2499>
This commit is contained in:
		
							parent
							
								
									232ca0f050
								
							
						
					
					
						commit
						1b57d3e36e
					
				|  | @ -0,0 +1 @@ | ||||||
|  | Added NodeInfo 2.1 specification | ||||||
							
								
								
									
										10
									
								
								docs/conf.py
								
								
								
								
							
							
						
						
									
										10
									
								
								docs/conf.py
								
								
								
								
							|  | @ -69,13 +69,19 @@ templates_path = ["_templates"] | ||||||
| # You can specify multiple suffix as a list of string: | # You can specify multiple suffix as a list of string: | ||||||
| # | # | ||||||
| # source_suffix = ['.rst', '.md'] | # source_suffix = ['.rst', '.md'] | ||||||
| source_suffix = ".rst" | source_suffix = ".md" | ||||||
| 
 | 
 | ||||||
| # The root toctree document. | # The root toctree document. | ||||||
| root_doc = "index" | root_doc = "index" | ||||||
| 
 | 
 | ||||||
| # Enable colon fences | # Enable colon fences | ||||||
| myst_enable_extensions = ["colon_fence", "attrs_block"] | myst_enable_extensions = [ | ||||||
|  |     "colon_fence", | ||||||
|  |     "attrs_block", | ||||||
|  |     "tasklist", | ||||||
|  |     "fieldlist", | ||||||
|  |     "deflist", | ||||||
|  | ] | ||||||
| 
 | 
 | ||||||
| # Autogenerate anchors | # Autogenerate anchors | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -94,6 +94,17 @@ contributor/translation | ||||||
| 
 | 
 | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
|  | ```{toctree} | ||||||
|  | --- | ||||||
|  | maxdepth: 1 | ||||||
|  | caption: Specifications | ||||||
|  | hidden: true | ||||||
|  | --- | ||||||
|  | 
 | ||||||
|  | specs/nodeinfo21/index | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
| ```{toctree} | ```{toctree} | ||||||
| --- | --- | ||||||
| caption: Reference | caption: Reference | ||||||
|  |  | ||||||
|  | @ -0,0 +1,218 @@ | ||||||
|  | # NodeInfo 2.1 | ||||||
|  | 
 | ||||||
|  | {bdg-secondary}`In progress` | ||||||
|  | 
 | ||||||
|  | ## The issue | ||||||
|  | 
 | ||||||
|  | Servers need to communicate their capabilities in a network of communicating nodes to negotiate a common protocol. | ||||||
|  | 
 | ||||||
|  | ## Proposed solution | ||||||
|  | 
 | ||||||
|  | Use [NodeInfo](http://nodeinfo.diaspora.software), a well-defined standard for exactly this purpose that's widely used within the Fediverse. | ||||||
|  | 
 | ||||||
|  | ## Feature behavior | ||||||
|  | 
 | ||||||
|  | The NodeInfo endpoint is used to communicate the features and capabilities of a server. It presents details about: | ||||||
|  | 
 | ||||||
|  | - Implemented protocols | ||||||
|  | - Enabled features | ||||||
|  | - Usage statistics | ||||||
|  | - Content metadata | ||||||
|  | 
 | ||||||
|  | :::{seealso} | ||||||
|  | Read [the NodeInfo specification for more information](https://nodeinfo.diaspora.software/docson/index.html#/ns/schema/2.1#$$expand). | ||||||
|  | ::: | ||||||
|  | 
 | ||||||
|  | The NodeInfo endpoint must contain all mandatory elements listed in the specification. In addition to this, Funkwhale's implementation should list additional details about the instance. | ||||||
|  | 
 | ||||||
|  | `actorId` (URL) | ||||||
|  | : The URL of the pod service actor | ||||||
|  | 
 | ||||||
|  | `private` (Boolean) | ||||||
|  | : Whether the pod is private | ||||||
|  | 
 | ||||||
|  | `shortDescription` (String) | ||||||
|  | : A short description of the pod | ||||||
|  | 
 | ||||||
|  | `longDescription` (String) | ||||||
|  | : A longer description of the pod | ||||||
|  | 
 | ||||||
|  | `rules` (String) | ||||||
|  | : A collection of rules users of the pod must abide by | ||||||
|  | 
 | ||||||
|  | `contactEmail` (Email address) | ||||||
|  | : The email address of the pod administrator | ||||||
|  | 
 | ||||||
|  | `terms` (String) | ||||||
|  | : The terms of use associated with the pod | ||||||
|  | 
 | ||||||
|  | `nodeName`(String) | ||||||
|  | : The name of the pod | ||||||
|  | 
 | ||||||
|  | `banner` (URL) | ||||||
|  | : The URL of the banner image | ||||||
|  | 
 | ||||||
|  | `defaultUploadQuota` (Number) | ||||||
|  | : The default upload quota (in megabytes) allowed for new users | ||||||
|  | 
 | ||||||
|  | `library.federationEnabled` (Boolean) | ||||||
|  | : Whether federation is enabled | ||||||
|  | 
 | ||||||
|  | `library.anonymousCanListen` (Boolean) | ||||||
|  | : Whether public endpoints require authentication | ||||||
|  | 
 | ||||||
|  | `supportedUploadExtensions` (Array\<String\>) | ||||||
|  | : A list of file extensions enabled for upload | ||||||
|  | 
 | ||||||
|  | `allowlist.enabled` (Boolean) | ||||||
|  | : Whether the pod admin has enabled allow-listing | ||||||
|  | 
 | ||||||
|  | `allowlist.domains` (Array\<String\>) | ||||||
|  | : A list of allowed domains | ||||||
|  | 
 | ||||||
|  | `funkwhaleSupportMessageEnabled` (Boolean) | ||||||
|  | : Whether the admin has enabled the Funkwhale project support message | ||||||
|  | 
 | ||||||
|  | `instanceSupportMessage` (String) | ||||||
|  | : The support message associated with the instance | ||||||
|  | 
 | ||||||
|  | `content.top_music_categories` (Array\<Object\>) | ||||||
|  | : The top three music genres and the number of uploads tagged with them | ||||||
|  | 
 | ||||||
|  | `content.top_podcast_categories` (Array\<Object\>) | ||||||
|  | : The top three podcast categories and the number of uploads tagged with them | ||||||
|  | 
 | ||||||
|  | `instance_policy.moderation_policy` (String) | ||||||
|  | : The moderation policy of the pod | ||||||
|  | 
 | ||||||
|  | `instance_policy.terms_of_service` (String) | ||||||
|  | : The terms of service of the pod | ||||||
|  | 
 | ||||||
|  | `instance_policy.languages` (Array\<String\>) | ||||||
|  | : The languages spoken by the pod administrators | ||||||
|  | 
 | ||||||
|  | `instance_policy.location` (String) | ||||||
|  | : The country the pod is located in | ||||||
|  | 
 | ||||||
|  | `federation.follows_instances` (Number) | ||||||
|  | : The number of Funkwhale pods that the target pod follows | ||||||
|  | 
 | ||||||
|  | `federation.following_instances` (Number) | ||||||
|  | : The number of Funkwhale pods that publicly follow the target pod | ||||||
|  | 
 | ||||||
|  | `features` (Array\<String\>) | ||||||
|  | : A list of enabled features | ||||||
|  | 
 | ||||||
|  | ### Backend | ||||||
|  | 
 | ||||||
|  | A new NodeInfo endpoint will be created that sits alongside the existing `v1` endpoint for backwards-compatibility. | ||||||
|  | 
 | ||||||
|  | ```text | ||||||
|  | /api/v2/instance/nodeinfo/2.1 | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | This endpoint supports only `GET` requests and responds with the information outlined in the NodeInfo specification. | ||||||
|  | 
 | ||||||
|  | Example response: | ||||||
|  | 
 | ||||||
|  | ```json | ||||||
|  | { | ||||||
|  |   "version": "2.1", | ||||||
|  |   "software": { | ||||||
|  |     "name": "Funkwhale", | ||||||
|  |     "version": "1.4.0", | ||||||
|  |     "repository": "https://dev.funkwhale.audio/funkwhale/funkwhale", | ||||||
|  |     "homepage": "https://funkwhale.audio" | ||||||
|  |   }, | ||||||
|  |   "protocols": ["activitypub"], | ||||||
|  |   "services": { | ||||||
|  |     "inbound": ["atom1.0"], | ||||||
|  |     "outbound": ["atom1.0"] | ||||||
|  |   }, | ||||||
|  |   "openRegistrations": true, | ||||||
|  |   "usage": { | ||||||
|  |     "users": { | ||||||
|  |       "total": 0, | ||||||
|  |       "activeHalfYear": 0, | ||||||
|  |       "activeMonth": 0 | ||||||
|  |     }, | ||||||
|  |     "localPosts": 0, | ||||||
|  |     "localComments": 0 | ||||||
|  |   }, | ||||||
|  |   "metadata": { | ||||||
|  |     "actorId": "string", | ||||||
|  |     "private": false, | ||||||
|  |     "shortDescription": "string", | ||||||
|  |     "longDescription": "string", | ||||||
|  |     "rules": "string", | ||||||
|  |     "contactEmail": "user@example.com", | ||||||
|  |     "terms": "string", | ||||||
|  |     "nodeName": "string", | ||||||
|  |     "banner": "string", | ||||||
|  |     "defaultUploadQuota": 0, | ||||||
|  |     "library": { | ||||||
|  |       "federationEnabled": true, | ||||||
|  |       "anonymousCanListen": true | ||||||
|  |     }, | ||||||
|  |     "supportedUploadExtensions": ["string"], | ||||||
|  |     "allowList": { | ||||||
|  |       "enabled": true, | ||||||
|  |       "domains": ["string"] | ||||||
|  |     }, | ||||||
|  |     "funkwhaleSupportMessageEnabled": true, | ||||||
|  |     "instanceSupportMessage": "string", | ||||||
|  |     "instance_policy": { | ||||||
|  |       "moderation_policy": "string", | ||||||
|  |       "terms_of_service": "string", | ||||||
|  |       "languages": ["string"], | ||||||
|  |       "location": "string" | ||||||
|  |     }, | ||||||
|  |     "content": { | ||||||
|  |       "top_music_categories": [ | ||||||
|  |         { | ||||||
|  |           "rock": 1256 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "jazz": 604 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "classical": 308 | ||||||
|  |         } | ||||||
|  |       ], | ||||||
|  |       "top_podcast_categories": [ | ||||||
|  |         { | ||||||
|  |           "comedy": 12 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "politics": 4 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "nature": 1 | ||||||
|  |         } | ||||||
|  |       ], | ||||||
|  |       "federation": { | ||||||
|  |         "followed_instances": 0, | ||||||
|  |         "following_instances": 0 | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "features": ["channels", "podcasts", "collections", "audiobooks"] | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## Availability | ||||||
|  | 
 | ||||||
|  | - [ ] Admin panel | ||||||
|  | - [ ] App frontend | ||||||
|  | - [ ] CLI | ||||||
|  | - [x] API | ||||||
|  | 
 | ||||||
|  | ## Responsible parties | ||||||
|  | 
 | ||||||
|  | Since the actual endpoint is already standardized, Backend developers need only to agree on an implementation. The Frontend group needs to check to see if changing the location of `/.well-known/nodeinfo` has an impact on the web app. | ||||||
|  | 
 | ||||||
|  | The NodeInfo endpoint MUST be accompanied by a {download}`full OpenAPI schema file <schema.yml>` for ease of reference and implementation. | ||||||
|  | 
 | ||||||
|  | ## Open questions | ||||||
|  | 
 | ||||||
|  | - [ ] Does changing `/.well-known/nodeinfo` have any implications on the Frontend? | ||||||
|  | @ -0,0 +1,599 @@ | ||||||
|  | openapi: "3.0.3" | ||||||
|  | info: | ||||||
|  |   description: "Interactive documentation for [Funkwhale](https://funkwhale.audio) API." | ||||||
|  |   version: "2.0.0" | ||||||
|  |   title: "Funkwhale API" | ||||||
|  | 
 | ||||||
|  | servers: | ||||||
|  |   - url: "https://demo.funkwhale.audio" | ||||||
|  |     description: "Demo server" | ||||||
|  |   - url: "https://open.audio" | ||||||
|  |     description: "Real server with real content" | ||||||
|  |   - url: "https://{domain}" | ||||||
|  |     description: "Custom server" | ||||||
|  |     variables: | ||||||
|  |       domain: | ||||||
|  |         default: yourdomain | ||||||
|  |         description: "Your Funkwhale Domain" | ||||||
|  |       protocol: | ||||||
|  |         enum: | ||||||
|  |           - "http" | ||||||
|  |           - "https" | ||||||
|  |         default: "https" | ||||||
|  | tags: | ||||||
|  |   - name: Instance | ||||||
|  |     description: Information about the server | ||||||
|  |   - name: Content | ||||||
|  |     description: Information about content on the server | ||||||
|  | paths: | ||||||
|  |   /api/v2/instance/nodeinfo/2.1: | ||||||
|  |     get: | ||||||
|  |       tags: | ||||||
|  |         - Instance | ||||||
|  |       summary: Retrieve nodeinfo data | ||||||
|  |       description: Retrieve details about a Funkwhale server using the Nodeinfo standard | ||||||
|  |       operationId: getNodeinfo | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: Successful operation | ||||||
|  |           content: | ||||||
|  |             application/json: | ||||||
|  |               schema: | ||||||
|  |                 $ref: "#/components/schemas/Nodeinfo" | ||||||
|  |             application/xml: | ||||||
|  |               schema: | ||||||
|  |                 $ref: "#/components/schemas/Nodeinfo" | ||||||
|  |         "401": | ||||||
|  |           $ref: "#/components/responses/Unauthorized" | ||||||
|  |   /api/v2/tags/podcasts: | ||||||
|  |     get: | ||||||
|  |       tags: | ||||||
|  |         - Content | ||||||
|  |       summary: Retrieve podcast categories | ||||||
|  |       description: Retrieve a list of podcast categories and the number of uploads tagged with those categories | ||||||
|  |       operationId: getTagsPodcasts | ||||||
|  |       parameters: | ||||||
|  |         - name: q | ||||||
|  |           in: query | ||||||
|  |           required: false | ||||||
|  |           description: A free text field to filter category names | ||||||
|  |           schema: | ||||||
|  |             type: string | ||||||
|  |         - name: page | ||||||
|  |           in: query | ||||||
|  |           required: false | ||||||
|  |           description: The number of the result page you want to return | ||||||
|  |           schema: | ||||||
|  |             type: number | ||||||
|  |         - name: page_size | ||||||
|  |           in: query | ||||||
|  |           required: false | ||||||
|  |           description: The number of results to return on each page. Defaults to 50. | ||||||
|  |           schema: | ||||||
|  |             type: number | ||||||
|  |         - name: ordering | ||||||
|  |           in: query | ||||||
|  |           required: false | ||||||
|  |           description: | | ||||||
|  |             The order in which results are presented. Preface with `-` to return items in descending order. | ||||||
|  |           schema: | ||||||
|  |             type: string | ||||||
|  |             enum: | ||||||
|  |               - "name" | ||||||
|  |               - "creation_date" | ||||||
|  |               - "tagged_items" | ||||||
|  |               - "-name" | ||||||
|  |               - "-creation_date" | ||||||
|  |               - "-tagged_items" | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: Successful operation | ||||||
|  |           content: | ||||||
|  |             application/json: | ||||||
|  |               schema: | ||||||
|  |                 $ref: "#/components/schemas/Categories" | ||||||
|  |             application/xml: | ||||||
|  |               schema: | ||||||
|  |                 $ref: "#/components/schemas/Categories" | ||||||
|  |         "401": | ||||||
|  |           $ref: "#/components/responses/Unauthorized" | ||||||
|  |   /api/v2/tags/podcasts/{category}: | ||||||
|  |     get: | ||||||
|  |       tags: | ||||||
|  |         - Content | ||||||
|  |       summary: Retrieve podcast categories | ||||||
|  |       description: Retrieve a list of podcast categories and the number of uploads tagged with those categories | ||||||
|  |       operationId: getTagPodcasts | ||||||
|  |       parameters: | ||||||
|  |         - name: category | ||||||
|  |           in: path | ||||||
|  |           required: true | ||||||
|  |           description: The category you want to return information about | ||||||
|  |           schema: | ||||||
|  |             type: string | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: Successful operation | ||||||
|  |           content: | ||||||
|  |             application/json: | ||||||
|  |               schema: | ||||||
|  |                 $ref: "#/components/schemas/Category" | ||||||
|  |             application/xml: | ||||||
|  |               schema: | ||||||
|  |                 $ref: "#/components/schemas/Category" | ||||||
|  |         "401": | ||||||
|  |           $ref: "#/components/responses/Unauthorized" | ||||||
|  |   /api/v2/tags/music: | ||||||
|  |     get: | ||||||
|  |       tags: | ||||||
|  |         - Content | ||||||
|  |       summary: Retrieve music genres | ||||||
|  |       description: Retrieve a list of music genres and the number of uploads tagged with those categories | ||||||
|  |       operationId: getTagsMusic | ||||||
|  |       parameters: | ||||||
|  |         - name: q | ||||||
|  |           in: query | ||||||
|  |           required: false | ||||||
|  |           description: A free text field to filter genre names | ||||||
|  |           schema: | ||||||
|  |             type: string | ||||||
|  |         - name: page | ||||||
|  |           in: query | ||||||
|  |           required: false | ||||||
|  |           description: The number of the result page you want to return | ||||||
|  |           schema: | ||||||
|  |             type: number | ||||||
|  |         - name: page_size | ||||||
|  |           in: query | ||||||
|  |           required: false | ||||||
|  |           description: The number of results to return on each page. Defaults to 50. | ||||||
|  |           schema: | ||||||
|  |             type: number | ||||||
|  |         - name: ordering | ||||||
|  |           in: query | ||||||
|  |           required: false | ||||||
|  |           description: | | ||||||
|  |             The order in which results are presented. Preface with `-` to return items in descending order. | ||||||
|  |           schema: | ||||||
|  |             type: string | ||||||
|  |             enum: | ||||||
|  |               - "name" | ||||||
|  |               - "creation_date" | ||||||
|  |               - "tagged_items" | ||||||
|  |               - "-name" | ||||||
|  |               - "-creation_date" | ||||||
|  |               - "-tagged_items" | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: Successful operation | ||||||
|  |           content: | ||||||
|  |             application/json: | ||||||
|  |               schema: | ||||||
|  |                 $ref: "#/components/schemas/Genres" | ||||||
|  |             application/xml: | ||||||
|  |               schema: | ||||||
|  |                 $ref: "#/components/schemas/Genres" | ||||||
|  |         "401": | ||||||
|  |           $ref: "#/components/responses/Unauthorized" | ||||||
|  |   /api/v2/tags/music/{genre}: | ||||||
|  |     get: | ||||||
|  |       tags: | ||||||
|  |         - Content | ||||||
|  |       summary: Retrieve podcast categories | ||||||
|  |       description: Retrieve a list of podcast categories and the number of uploads tagged with those categories | ||||||
|  |       operationId: getTagMusic | ||||||
|  |       parameters: | ||||||
|  |         - name: genre | ||||||
|  |           in: path | ||||||
|  |           required: true | ||||||
|  |           description: The genre you want to return information about | ||||||
|  |           schema: | ||||||
|  |             type: string | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: Successful operation | ||||||
|  |           content: | ||||||
|  |             application/json: | ||||||
|  |               schema: | ||||||
|  |                 $ref: "#/components/schemas/Genre" | ||||||
|  |             application/xml: | ||||||
|  |               schema: | ||||||
|  |                 $ref: "#/components/schemas/Genre" | ||||||
|  |         "401": | ||||||
|  |           $ref: "#/components/responses/Unauthorized" | ||||||
|  | components: | ||||||
|  |   responses: | ||||||
|  |     Unauthorized: | ||||||
|  |       description: Unauthorized | ||||||
|  |       content: | ||||||
|  |         application/json: | ||||||
|  |           schema: | ||||||
|  |             $ref: "#/components/schemas/Error" | ||||||
|  |           example: | ||||||
|  |             code: 401 | ||||||
|  |             message: User not authorized | ||||||
|  |         application/xml: | ||||||
|  |           schema: | ||||||
|  |             $ref: "#/components/schemas/Error" | ||||||
|  |           example: | ||||||
|  |             code: 401 | ||||||
|  |             message: User not authorized | ||||||
|  |   schemas: | ||||||
|  |     Categories: | ||||||
|  |       type: object | ||||||
|  |       properties: | ||||||
|  |         total: | ||||||
|  |           type: number | ||||||
|  |         next: | ||||||
|  |           type: string | ||||||
|  |           format: url | ||||||
|  |         previous: | ||||||
|  |           type: string | ||||||
|  |           format: url | ||||||
|  |         results: | ||||||
|  |           type: array | ||||||
|  |           items: | ||||||
|  |             $ref: "#/components/schemas/Category" | ||||||
|  |       example: | ||||||
|  |         total: 5 | ||||||
|  |         next: https://demo.funkwhale.audio/api/v2/categories?page=2&page_size=2&q=crime | ||||||
|  |         previous: null | ||||||
|  |         results: | ||||||
|  |           - category: "True Crime" | ||||||
|  |             created_date: "2020-01-01T00:00:00.000Z" | ||||||
|  |             tagged_items: 5 | ||||||
|  |             results_page: "https://demo.funkwhale.audio/library/categories/True%20Crime" | ||||||
|  |           - category: "True Stories" | ||||||
|  |             created_date: "2023-12-15T23:32:52.000Z" | ||||||
|  |             tagged_items: 200 | ||||||
|  |             results_page: "https://demo.funkwhale.audio/library/categories/True%20Stories" | ||||||
|  |     Category: | ||||||
|  |       type: object | ||||||
|  |       properties: | ||||||
|  |         category: | ||||||
|  |           type: string | ||||||
|  |         created_date: | ||||||
|  |           type: string | ||||||
|  |           format: date-time | ||||||
|  |         tagged_items: | ||||||
|  |           type: number | ||||||
|  |         results_page: | ||||||
|  |           type: string | ||||||
|  |           format: url | ||||||
|  |       example: | ||||||
|  |         category: "True Crime" | ||||||
|  |         created_date: "2020-01-01T00:00:00.000Z" | ||||||
|  |         tagged_items: 5 | ||||||
|  |         results_page: "https://demo.funkwhale.audio/library/categories/True%20Crime" | ||||||
|  |     Genres: | ||||||
|  |       type: object | ||||||
|  |       properties: | ||||||
|  |         total: | ||||||
|  |           type: number | ||||||
|  |         next: | ||||||
|  |           type: string | ||||||
|  |           format: url | ||||||
|  |         previous: | ||||||
|  |           type: string | ||||||
|  |           format: url | ||||||
|  |         results: | ||||||
|  |           type: array | ||||||
|  |           items: | ||||||
|  |             $ref: "#/components/schemas/Genre" | ||||||
|  |       example: | ||||||
|  |         total: 5 | ||||||
|  |         next: https://demo.funkwhale.audio/api/v2/categories?page=2&page_size=2&q=rock | ||||||
|  |         previous: null | ||||||
|  |         results: | ||||||
|  |           - genre: "Acoustic Rock" | ||||||
|  |             created_date: "2020-01-01T00:00:00.000Z" | ||||||
|  |             tagged_items: 5 | ||||||
|  |             results_page: "https://demo.funkwhale.audio/library/categories/Acoustic%20Rock" | ||||||
|  |           - genre: "Surf Rock" | ||||||
|  |             created_date: "2023-12-15T23:32:52.000Z" | ||||||
|  |             tagged_items: 200 | ||||||
|  |             results_page: "https://demo.funkwhale.audio/library/categories/Surf%20Rock" | ||||||
|  |     Genre: | ||||||
|  |       type: object | ||||||
|  |       properties: | ||||||
|  |         genre: | ||||||
|  |           type: string | ||||||
|  |         created_date: | ||||||
|  |           type: string | ||||||
|  |           format: date-time | ||||||
|  |         tagged_items: | ||||||
|  |           type: number | ||||||
|  |         results_page: | ||||||
|  |           type: string | ||||||
|  |           format: url | ||||||
|  |       example: | ||||||
|  |         genre: "Acoustic Rock" | ||||||
|  |         created_date: "2020-01-01T00:00:00.000Z" | ||||||
|  |         tagged_items: 5 | ||||||
|  |         results_page: "https://demo.funkwhale.audio/library/categories/Acoustic%20Rock" | ||||||
|  |     Nodeinfo: | ||||||
|  |       type: object | ||||||
|  |       required: | ||||||
|  |         - version | ||||||
|  |         - software | ||||||
|  |         - protocols | ||||||
|  |         - services | ||||||
|  |         - openRegistrations | ||||||
|  |         - usage | ||||||
|  |         - metadata | ||||||
|  |       properties: | ||||||
|  |         version: | ||||||
|  |           type: string | ||||||
|  |           enum: | ||||||
|  |             - "2.1" | ||||||
|  |         software: | ||||||
|  |           type: object | ||||||
|  |           required: | ||||||
|  |             - name | ||||||
|  |             - version | ||||||
|  |           properties: | ||||||
|  |             name: | ||||||
|  |               type: string | ||||||
|  |               enum: | ||||||
|  |                 - "Funkwhale" | ||||||
|  |             version: | ||||||
|  |               type: string | ||||||
|  |               example: "1.4.0" | ||||||
|  |             repository: | ||||||
|  |               type: string | ||||||
|  |               format: url | ||||||
|  |               enum: | ||||||
|  |                 - "https://dev.funkwhale.audio/funkwhale/funkwhale" | ||||||
|  |             homepage: | ||||||
|  |               type: string | ||||||
|  |               format: url | ||||||
|  |               enum: | ||||||
|  |                 - "https://funkwhale.audio" | ||||||
|  |         protocols: | ||||||
|  |           type: array | ||||||
|  |           minItems: 1 | ||||||
|  |           items: | ||||||
|  |             type: string | ||||||
|  |             enum: | ||||||
|  |               - "activitypub" | ||||||
|  |               - "buddycloud" | ||||||
|  |               - "dfrn" | ||||||
|  |               - "diaspora" | ||||||
|  |               - "libertree" | ||||||
|  |               - "ostatus" | ||||||
|  |               - "pumpio" | ||||||
|  |               - "tent" | ||||||
|  |               - "xmpp" | ||||||
|  |               - "zot" | ||||||
|  |           example: | ||||||
|  |             - "activitypub" | ||||||
|  |         services: | ||||||
|  |           type: object | ||||||
|  |           required: | ||||||
|  |             - inbound | ||||||
|  |             - outbound | ||||||
|  |           properties: | ||||||
|  |             inbound: | ||||||
|  |               type: array | ||||||
|  |               items: | ||||||
|  |                 type: string | ||||||
|  |                 enum: | ||||||
|  |                   - "atom1.0" | ||||||
|  |                   - "gnusocial" | ||||||
|  |                   - "imap" | ||||||
|  |                   - "pnut" | ||||||
|  |                   - "pop3" | ||||||
|  |                   - "pumpio" | ||||||
|  |                   - "rss2.0" | ||||||
|  |                   - "twitter" | ||||||
|  |             outbound: | ||||||
|  |               type: array | ||||||
|  |               items: | ||||||
|  |                 type: string | ||||||
|  |                 enum: | ||||||
|  |                   - "atom1.0" | ||||||
|  |                   - "blogger" | ||||||
|  |                   - "buddycloud" | ||||||
|  |                   - "diaspora" | ||||||
|  |                   - "dreamwidth" | ||||||
|  |                   - "drupal" | ||||||
|  |                   - "facebook" | ||||||
|  |                   - "friendica" | ||||||
|  |                   - "gnusocial" | ||||||
|  |                   - "google" | ||||||
|  |                   - "insanejournal" | ||||||
|  |                   - "libertree" | ||||||
|  |                   - "linkedin" | ||||||
|  |                   - "livejournal" | ||||||
|  |                   - "mediagoblin" | ||||||
|  |                   - "myspace" | ||||||
|  |                   - "pinterest" | ||||||
|  |                   - "pnut" | ||||||
|  |                   - "posterous" | ||||||
|  |                   - "pumpio" | ||||||
|  |                   - "redmatrix" | ||||||
|  |                   - "rss2.0" | ||||||
|  |                   - "smtp" | ||||||
|  |                   - "tent" | ||||||
|  |                   - "tumblr" | ||||||
|  |                   - "twitter" | ||||||
|  |                   - "wordpress" | ||||||
|  |                   - "xmpp" | ||||||
|  |         openRegistrations: | ||||||
|  |           type: boolean | ||||||
|  |         usage: | ||||||
|  |           type: object | ||||||
|  |           required: | ||||||
|  |             - users | ||||||
|  |           properties: | ||||||
|  |             users: | ||||||
|  |               type: object | ||||||
|  |               properties: | ||||||
|  |                 total: | ||||||
|  |                   type: integer | ||||||
|  |                   minimum: 0 | ||||||
|  |                 activeHalfYear: | ||||||
|  |                   type: integer | ||||||
|  |                   minimum: 0 | ||||||
|  |                 activeMonth: | ||||||
|  |                   type: integer | ||||||
|  |                   minimum: 0 | ||||||
|  |             localPosts: | ||||||
|  |               type: integer | ||||||
|  |               minimum: 0 | ||||||
|  |             localComments: | ||||||
|  |               type: integer | ||||||
|  |               minimum: 0 | ||||||
|  |         metadata: | ||||||
|  |           type: object | ||||||
|  |           properties: | ||||||
|  |             actorId: | ||||||
|  |               type: string | ||||||
|  |               format: url | ||||||
|  |             private: | ||||||
|  |               type: boolean | ||||||
|  |             shortDescription: | ||||||
|  |               type: string | ||||||
|  |             longDescription: | ||||||
|  |               type: string | ||||||
|  |             rules: | ||||||
|  |               type: string | ||||||
|  |             contactEmail: | ||||||
|  |               type: string | ||||||
|  |               format: email | ||||||
|  |             terms: | ||||||
|  |               type: string | ||||||
|  |             nodeName: | ||||||
|  |               type: string | ||||||
|  |             banner: | ||||||
|  |               type: string | ||||||
|  |               format: url | ||||||
|  |             defaultUploadQuota: | ||||||
|  |               type: integer | ||||||
|  |             library: | ||||||
|  |               type: object | ||||||
|  |               properties: | ||||||
|  |                 federationEnabled: | ||||||
|  |                   type: boolean | ||||||
|  |                 anonymousCanListen: | ||||||
|  |                   type: boolean | ||||||
|  |             supportedUploadExtensions: | ||||||
|  |               type: array | ||||||
|  |               items: | ||||||
|  |                 type: string | ||||||
|  |             allowList: | ||||||
|  |               type: object | ||||||
|  |               properties: | ||||||
|  |                 enabled: | ||||||
|  |                   type: boolean | ||||||
|  |                 domains: | ||||||
|  |                   type: array | ||||||
|  |                   items: | ||||||
|  |                     type: string | ||||||
|  |             funkwhaleSupportMessageEnabled: | ||||||
|  |               type: boolean | ||||||
|  |             instanceSupportMessage: | ||||||
|  |               type: string | ||||||
|  |             instance_policy: | ||||||
|  |               type: object | ||||||
|  |               properties: | ||||||
|  |                 moderation_policy: | ||||||
|  |                   type: string | ||||||
|  |                   format: url | ||||||
|  |                 terms_of_service: | ||||||
|  |                   type: string | ||||||
|  |                   format: url | ||||||
|  |                 languages: | ||||||
|  |                   type: array | ||||||
|  |                   items: | ||||||
|  |                     type: string | ||||||
|  |                 location: | ||||||
|  |                   type: string | ||||||
|  |             content: | ||||||
|  |               type: object | ||||||
|  |               properties: | ||||||
|  |                 top_music_categories: | ||||||
|  |                   type: array | ||||||
|  |                   items: | ||||||
|  |                     type: object | ||||||
|  |                     additionalProperties: | ||||||
|  |                       type: integer | ||||||
|  |                   example: | ||||||
|  |                     - "rock": 1256 | ||||||
|  |                     - "jazz": 604 | ||||||
|  |                     - "classical": 308 | ||||||
|  |                 top_podcast_categories: | ||||||
|  |                   type: array | ||||||
|  |                   items: | ||||||
|  |                     type: object | ||||||
|  |                     additionalProperties: | ||||||
|  |                       type: integer | ||||||
|  |                   example: | ||||||
|  |                     - "comedy": 12 | ||||||
|  |                     - "politics": 4 | ||||||
|  |                     - "nature": 1 | ||||||
|  |                 federation: | ||||||
|  |                   type: object | ||||||
|  |                   properties: | ||||||
|  |                     followed_instances: | ||||||
|  |                       type: integer | ||||||
|  |                     following_instances: | ||||||
|  |                       type: integer | ||||||
|  |             features: | ||||||
|  |               type: array | ||||||
|  |               items: | ||||||
|  |                 type: string | ||||||
|  |               example: | ||||||
|  |                 - "channels" | ||||||
|  |                 - "podcasts" | ||||||
|  |                 - "collections" | ||||||
|  |                 - "audiobooks" | ||||||
|  |     Error: | ||||||
|  |       type: object | ||||||
|  |       properties: | ||||||
|  |         code: | ||||||
|  |           type: string | ||||||
|  |         message: | ||||||
|  |           type: string | ||||||
|  |       required: | ||||||
|  |         - code | ||||||
|  |         - message | ||||||
|  |   securitySchemes: | ||||||
|  |     oauth2: | ||||||
|  |       type: oauth2 | ||||||
|  |       description: This API uses OAuth 2 with the Authorization Code flow. You can register an app using the /oauth/apps/ endpoint. | ||||||
|  |       flows: | ||||||
|  |         authorizationCode: | ||||||
|  |           authorizationUrl: /authorize | ||||||
|  |           tokenUrl: /api/v1/oauth/token/ | ||||||
|  |           refreshUrl: /api/v1/oauth/token/ | ||||||
|  |           scopes: | ||||||
|  |             "read": "Read-only access to all user data" | ||||||
|  |             "write": "Write-only access on all user data" | ||||||
|  |             "read:edits": "Read-only access to edits" | ||||||
|  |             "write:edits": "Write-only access to edits" | ||||||
|  |             "read:favorites": "Read-only access to favorites" | ||||||
|  |             "write:favorites": "Write-only access to favorits" | ||||||
|  |             "read:filters": "Read-only to to content filters" | ||||||
|  |             "write:filters": "Write-only access to content-filters" | ||||||
|  |             "read:follows": "Read-only to follows" | ||||||
|  |             "write:follows": "Write-only access to follows" | ||||||
|  |             "read:libraries": "Read-only access to library and uploads" | ||||||
|  |             "write:libraries": "Write-only access to libraries" | ||||||
|  |             "read:listenings": "Read-only access to listening history" | ||||||
|  |             "write:listenings": "Write-only access to listening history" | ||||||
|  |             "read:notifications": "Read-only access to notifications" | ||||||
|  |             "write:notifications": "Write-only access to notifications" | ||||||
|  |             "read:playlists": "Read-only access to playlists" | ||||||
|  |             "write:playlists": "Write-only access to playlists" | ||||||
|  |             "read:profile": "Read-only access to profile data" | ||||||
|  |             "write:profile": "Write-only access to profile data" | ||||||
|  |             "read:radios": "Read-only access to radios" | ||||||
|  |             "write:radios": "Write-only access to radios" | ||||||
|  |             "read:reports": "Read-only access to reports" | ||||||
|  |             "write:reports": "Write-only access to reports" | ||||||
|  |             "read:security": "Read-only access security settings" | ||||||
|  |             "write:security": "write-only access security settings" | ||||||
|  | 
 | ||||||
|  | security: | ||||||
|  |   - oauth2: [] | ||||||
		Loading…
	
		Reference in New Issue
	
	 Ciarán Ainsworth
						Ciarán Ainsworth