From 20d66ffec5b9d529d691913cfa018822322c9f5e Mon Sep 17 00:00:00 2001 From: Eliot Berriot Date: Tue, 29 Jan 2019 14:36:35 +0100 Subject: [PATCH 1/6] Fixed styling issue in changelog --- CHANGELOG | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index a0446517f..9cc7df63e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -18,7 +18,7 @@ https://docs.funkwhale.audio/index.html Fix Gzip compression to avoid BREACH exploit [security] [manual action required] --------------------------------------------------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ In the 0.18 release, we've enabled Gzip compression by default for various content types, including HTML and JSON. Unfortunately, enabling Gzip compression @@ -62,7 +62,7 @@ For convenience, you can also replace the whole setting with the following snipp Many thanks to @jibec for the report! Fix Apache configuration file for 0.18 [manual action required] ----------------------------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The way front is served has changed since 0.18. The Apache configuration can't serve 0.18 properly, leading to blank screens. From 5857ad638e80ebc04c597264e45ffabe93747414 Mon Sep 17 00:00:00 2001 From: Eliot Berriot Date: Tue, 29 Jan 2019 17:16:39 +0100 Subject: [PATCH 2/6] Api docs --- docs/swagger.yml | 663 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 635 insertions(+), 28 deletions(-) diff --git a/docs/swagger.yml b/docs/swagger.yml index 71c74e442..5b277f0e0 100644 --- a/docs/swagger.yml +++ b/docs/swagger.yml @@ -1,4 +1,4 @@ -openapi: "3.0" +openapi: "3.0.0" info: description: "Documentation for [Funkwhale](https://funkwhale.audio) API. The API is **not** stable yet." version: "1.0.0" @@ -7,6 +7,8 @@ info: servers: - url: https://demo.funkwhale.audio/api/v1 description: Demo server + - url: https://open.audio/api/v1 + description: Open Audio - url: https://node1.funkwhale.test/api/v1 description: Node 1 (local) @@ -50,47 +52,471 @@ paths: /artists/: get: + summary: List artists tags: - "artists" parameters: - name: "q" in: "query" + default: null description: "Search query used to filter artists" schema: required: false type: "string" example: "carpenter" - - name: "listenable" - in: "query" - description: "Filter/exclude artists with listenable tracks" - schema: - required: false - type: "boolean" + - allOf: + - $ref: "#/parameters/Ordering" + - default: "-creation_date" + schema: + required: false + type: "string" + example: "creation_date" + enum: + - creation_date + - id + - name + - $ref: "#/parameters/Playable" + - $ref: "#/parameters/PageNumber" + - $ref: "#/parameters/PageSize" + responses: 200: content: application/json: schema: - type: "object" - properties: - count: - $ref: "#/properties/resultsCount" - results: - type: "array" - items: - $ref: "#/definitions/ArtistWithAlbums" + allOf: + - $ref: "#/definitions/ResultPage" + - type: "object" + properties: + results: + type: "array" + items: + $ref: "#/definitions/Artist" + /artists/{id}/: + get: + summary: Retrieve a single artist + parameters: + - $ref: "#/parameters/ObjectId" + + tags: + - "artists" + responses: + 200: + content: + application/json: + schema: + $ref: "#/definitions/Artist" + 404: + content: + application/json: + schema: + $ref: "#/definitions/ResourceNotFound" + /artists/{id}/libraries/: + get: + summary: List available user libraries containing work from this artist + parameters: + - $ref: "#/parameters/ObjectId" + - $ref: "#/parameters/PageNumber" + - $ref: "#/parameters/PageSize" + + tags: + - "artists" + - "libraries" + responses: + 200: + content: + application/json: + schema: + $ref: "#/definitions/LibraryPage" + 404: + content: + application/json: + schema: + $ref: "#/definitions/ResourceNotFound" + + /albums/: + get: + summary: List albums + tags: + - "albums" + parameters: + - name: "q" + in: "query" + default: null + description: "Search query used to filter albums" + schema: + required: false + type: "string" + example: "carpenter" + - name: "artist" + in: "query" + default: null + description: "Only include albums by the requested artist" + schema: + required: false + type: "integer" + format: "int64" + - allOf: + - $ref: "#/parameters/Ordering" + - default: "-creation_date" + schema: + required: false + type: "string" + example: "creation_date" + enum: + - creation_date + - release_date + - title + - $ref: "#/parameters/Playable" + - $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/Album" + /albums/{id}/: + get: + summary: Retrieve a single album + parameters: + - $ref: "#/parameters/ObjectId" + + tags: + - "albums" + responses: + 200: + content: + application/json: + schema: + $ref: "#/definitions/Album" + 404: + content: + application/json: + schema: + $ref: "#/definitions/ResourceNotFound" + + /albums/{id}/libraries/: + get: + summary: List available user libraries containing tracks from this album + parameters: + - $ref: "#/parameters/ObjectId" + - $ref: "#/parameters/PageNumber" + - $ref: "#/parameters/PageSize" + + tags: + - "albums" + - "libraries" + responses: + 200: + content: + application/json: + schema: + $ref: "#/definitions/LibraryPage" + 404: + content: + application/json: + schema: + $ref: "#/definitions/ResourceNotFound" + + /tracks/: + get: + summary: List tracks + tags: + - "tracks" + parameters: + - name: "q" + in: "query" + default: null + description: "Search query used to filter tracks" + schema: + required: false + type: "string" + example: "carpenter" + - name: "artist" + in: "query" + default: null + description: "Only include tracks by the requested artist" + schema: + required: false + type: "integer" + format: "int64" + - name: "album" + in: "query" + default: null + description: "Only include tracks from the requested album" + schema: + required: false + type: "integer" + format: "int64" + - name: "license" + in: "query" + description: "Only include tracks with the given license" + default: null + schema: + example: "cc-by-sa-4.0" + required: false + type: "string" + - allOf: + - $ref: "#/parameters/Ordering" + - default: "-creation_date" + schema: + required: false + type: "string" + example: "creation_date" + enum: + - creation_date + - release_date + - title + - $ref: "#/parameters/Playable" + - $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/Track" + /tracks/{id}/: + get: + summary: Retrieve a single track + parameters: + - $ref: "#/parameters/ObjectId" + + tags: + - "tracks" + responses: + 200: + content: + application/json: + schema: + $ref: "#/definitions/Track" + 404: + content: + application/json: + schema: + $ref: "#/definitions/ResourceNotFound" + + /tracks/{id}/libraries/: + get: + summary: List available user libraries containing given track + parameters: + - $ref: "#/parameters/ObjectId" + - $ref: "#/parameters/PageNumber" + - $ref: "#/parameters/PageSize" + + tags: + - "tracks" + - "libraries" + responses: + 200: + content: + application/json: + schema: + $ref: "#/definitions/LibraryPage" + 404: + content: + application/json: + schema: + $ref: "#/definitions/ResourceNotFound" + + /licenses/: + get: + summary: List licenses + tags: + - "licenses" + 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/License" + + /licenses/{code}/: + get: + summary: Retrieve a single license + parameters: + - name: code + in: path + description: License code + required: true + schema: + type: string + example: cc0-1.0 + + tags: + - "licenses" + responses: + 200: + content: + application/json: + schema: + $ref: "#/definitions/License" + 404: + content: + application/json: + schema: + $ref: "#/definitions/ResourceNotFound" + + +parameters: + ObjectId: + name: id + in: path + description: Object ID + required: true + schema: + type: integer + format: int64 + Ordering: + name: "ordering" + in: "query" + description: "Ordering for the results, prefix with - for DESC ordering" + + PageNumber: + in: query + name: page + schema: + type: "integer" + format: "int64" + example: 1 + default: 1 + minimum: 1 + PageSize: + in: query + name: page_size + schema: + type: "integer" + format: "int64" + example: 16 + default: 25 + minimum: 1 + maximum: 25 + Playable: + name: "playable" + in: "query" + default: null + description: "Filter/exclude resources with playable tracks" + schema: + required: false + type: "boolean" -properties: - resultsCount: - type: "integer" - format: "int64" - description: "The total number of resources matching the request" mbid: type: "string" formats: "uuid" description: "A musicbrainz ID" + definitions: - Artist: + ResultPage: + type: "object" + properties: + count: + type: "integer" + format: "int64" + example: 42 + description: "The total number of results (all pages included)" + next: + type: "string" + format: "uri" + description: "Link to the next page of results" + previous: + type: "string" + format: "uri" + description: "Link to the previous page of results" + + + Image: + type: "object" + properties: + original: + type: "string" + description: "URL to the original image" + example: "https://mydomain/media/albums/covers/ec2c53aeaac6.jpg" + small_square_crop: + type: "string" + description: "URL to a small, squared thumbnail of the image" + example: "https://mydomain/media/__sized__/albums/covers/ec2c53aeaac6-crop-c0-5__0-5-50x50-70.jpg" + + medium_square_crop: + type: "string" + description: "URL to a medium, squared thumbnail of the image" + example: "https://mydomain/media/__sized__/albums/covers/ec2c53aeaac6-crop-c0-5__0-5-200x200-70.jpg" + + square_crop: + type: "string" + description: "URL to a large, squared thumbnail of the image" + example: "https://mydomain/media/__sized__/albums/covers/ec2c53aeaac6-crop-c0-5__0-5-400x400-70.jpg" + + Actor: + type: object + description: "A federation/ ActivityPub actor" + properties: + fid: + type: string + format: uri + description: "The actor Federation ID (unique accross federation)" + uuid: + type: string + format: uuid + description: "Local ID of the library" + creation_date: + type: "string" + format: "date-time" + preferred_username: + type: "string" + example: "alice" + name: + type: string + example: "Alice Unicorn" + last_fetch_date: + type: "string" + format: "date-time" + description: "Last time the actor profile was fetched on its origin server" + domain: + type: "string" + format: "hostname" + example: "open.audio" + type: + type: "string" + example: "Person" + enum: + - Person + - Application + - Group + - Organization + manually_approves_followers: + type: "boolean" + full_username: + type: string + example: "alice@open.audio" + + BaseArtist: type: "object" properties: mbid: @@ -106,10 +532,10 @@ definitions: creation_date: type: "string" format: "date-time" - ArtistWithAlbums: + Artist: type: "object" allOf: - - $ref: "#/definitions/Artist" + - $ref: "#/definitions/BaseArtist" - type: "object" properties: albums: @@ -117,7 +543,7 @@ definitions: items: $ref: "#/definitions/ArtistAlbum" - Album: + BaseAlbum: type: "object" properties: mbid: @@ -142,19 +568,112 @@ definitions: required: false format: "date" example: "2001-01-01" + is_playable: + type: "boolean" + cover: + $ref: "#/definitions/Image" + + Album: + type: "object" + allOf: + - $ref: "#/definitions/BaseAlbum" + - type: "object" + properties: + tracks: + type: "array" + items: + $ref: "#/definitions/AlbumTrack" ArtistAlbum: type: "object" allOf: - - $ref: "#/definitions/Album" + - $ref: "#/definitions/BaseAlbum" - type: "object" properties: tracks_count: type: "integer" format: "int64" example: 16 + Library: + type: "object" + properties: + fid: + type: string + format: uri + description: "The library Federation ID (unique accross federation)" + uuid: + type: string + format: uuid + description: "Local ID of the library" + name: + type: string + example: "My awesome library" + description: + type: string + nullable: true + example: "This library contains all the stuff I love!" + uploads_count: + type: "integer" + format: "int64" + example: 687 + privacy_level: + type: string + example: "me" + enum: + - "me" + - "instance" + - "everyone" + actor: + $ref: "#/definitions/Actor" + LibraryPage: + allOf: + - $ref: "#/definitions/ResultPage" + - type: "object" + properties: + results: + type: "array" + items: + $ref: "#/definitions/Library" - Track: + License: + type: "object" + properties: + id: + type: string + format: uri + example: http://creativecommons.org/publicdomain/zero/1.0/ + description: "The license ID" + url: + type: string + format: uri + example: http://creativecommons.org/publicdomain/zero/1.0/ + description: "The license url (can be different than the ID)" + code: + type: string + description: "A unique code to identify the license" + example: cc0-1.0 + redistribute: + type: boolean + example: true + description: "Does the license allow free redistribution?" + derivative: + type: boolean + example: true + description: "Does the license allow the creation of derivative work?" + commercial: + type: boolean + example: true + description: "Does the license allow commercial use?" + attribution: + type: boolean + example: false + description: "Does the license requires crediting the author?" + copyleft: + type: boolean + example: false + description: "Does the license enforce a similar license of derivative work?" + + BaseTrack: type: "object" properties: mbid: @@ -181,6 +700,94 @@ definitions: type: "number" minimum: 1 example: 1 - creation_date: + disc_number: + required: false + type: "number" + minimum: 1 + example: 1 + listen_url: type: "string" - format: "date-time" + format: "uri" + description: "URL to stream the track" + copyright: + type: "string" + example: "Creative Commons Attribution-NonCommercial-NoDerivatives 4.0: http://creativecommons.org/licenses/by-nc-nd/4.0/" + description: "Copyright information as extracted from upload tags" + license: + type: "string" + description: "Identifier of the license that is linked to the track" + example: "cc-by-nc-nd-4.0" + + AlbumTrack: + type: "object" + allOf: + - $ref: "#/definitions/BaseTrack" + - type: "object" + properties: + artist: + $ref: "#/definitions/BaseArtist" + uploads: + type: "array" + description: "List of uploads associated with this track" + items: + $ref: "#/definitions/Upload" + Track: + type: "object" + allOf: + - $ref: "#/definitions/BaseTrack" + - type: "object" + properties: + album: + $ref: "#/definitions/Album" + artist: + $ref: "#/definitions/BaseArtist" + uploads: + type: "array" + description: "List of uploads associated with this track" + items: + $ref: "#/definitions/Upload" + Upload: + type: "object" + properties: + uuid: + type: string + format: uuid + size: + type: "integer" + format: "int64" + example: 278987000 + description: "Size of the file, in bytes" + duration: + type: "integer" + format: "int64" + example: 184 + description: "Duration of the audio, in seconds" + bitrate: + type: "integer" + format: "int64" + example: 128000 + description: "Bitrate of the file, in bytes/s" + mimetype: + type: string + example: "audio/ogg" + enum: + - "audio/ogg" + - "audio/mpeg" + - "audio/x-flac" + - "audio/flac" + extension: + type: string + example: "ogg" + description: "File extension of the upload" + + listen_url: + type: "string" + format: "uri" + description: "URL to stream the upload" + + ResourceNotFound: + type: "object" + properties: + detail: + type: "string" + example: "Not found." From c73ce96f4d2a794629593980deae9ca1a6b77629 Mon Sep 17 00:00:00 2001 From: Eliot Berriot Date: Tue, 29 Jan 2019 17:33:44 +0100 Subject: [PATCH 3/6] Enabled custom domain to use with the swagger API --- docs/swagger.yml | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/docs/swagger.yml b/docs/swagger.yml index 5b277f0e0..be32d91a6 100644 --- a/docs/swagger.yml +++ b/docs/swagger.yml @@ -7,10 +7,17 @@ info: servers: - url: https://demo.funkwhale.audio/api/v1 description: Demo server - - url: https://open.audio/api/v1 - description: Open Audio - - url: https://node1.funkwhale.test/api/v1 - description: Node 1 (local) + - url: https://{domain}/api/v1 + description: Custom server + variables: + domain: + default: yourdomain + description: Your Funkwhale Domain + protocol: + enum: + - 'http' + - 'https' + default: 'https' components: securitySchemes: From 2f100ab9a756aee36cfb61413d5a8bbe47df96eb Mon Sep 17 00:00:00 2001 From: Eliot Berriot Date: Tue, 29 Jan 2019 17:46:37 +0100 Subject: [PATCH 4/6] Fixed a bad reference in swagger docs --- docs/swagger.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/swagger.yml b/docs/swagger.yml index be32d91a6..de809242d 100644 --- a/docs/swagger.yml +++ b/docs/swagger.yml @@ -434,6 +434,7 @@ parameters: required: false type: "boolean" +properties: mbid: type: "string" formats: "uuid" From 741199c55109c35d76a40db0dd0484fe89033177 Mon Sep 17 00:00:00 2001 From: Eliot Berriot Date: Thu, 7 Feb 2019 16:17:51 +0100 Subject: [PATCH 5/6] Fix #697: Downgraded channels dependency to 2.1.6 to fix denied uploads --- api/requirements/base.txt | 3 ++- changes/changelog.d/697.bugfix | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 changes/changelog.d/697.bugfix diff --git a/api/requirements/base.txt b/api/requirements/base.txt index b05be4bff..c2fc95a6f 100644 --- a/api/requirements/base.txt +++ b/api/requirements/base.txt @@ -49,7 +49,8 @@ django-dynamic-preferences>=1.7,<1.8 raven>=6.5,<7 python-magic==0.4.15 ffmpeg-python==0.1.10 -channels>=2.1,<2.2 +# XXX: until https://github.com/django/channels/issues/1240 is fixed +channels==2.1.6 channels_redis>=2.3,<2.4 daphne>=2.2,<2.3 diff --git a/changes/changelog.d/697.bugfix b/changes/changelog.d/697.bugfix new file mode 100644 index 000000000..66fe1ee9a --- /dev/null +++ b/changes/changelog.d/697.bugfix @@ -0,0 +1 @@ +Downgraded channels dependency to 2.1.6 to fix denied uploads (#697) From c15b4381bb01a5ad19f3ee55b355876e249fc4d9 Mon Sep 17 00:00:00 2001 From: Eliot Berriot Date: Thu, 7 Feb 2019 16:23:14 +0100 Subject: [PATCH 6/6] Fix #696: Embed component name that could lead to issue when developping on OSX --- changes/changelog.d/696.bugfix | 1 + front/src/{Embed.vue => EmbedFrame.vue} | 0 front/src/embed.js | 6 +++--- 3 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 changes/changelog.d/696.bugfix rename front/src/{Embed.vue => EmbedFrame.vue} (100%) diff --git a/changes/changelog.d/696.bugfix b/changes/changelog.d/696.bugfix new file mode 100644 index 000000000..22a1c6aa4 --- /dev/null +++ b/changes/changelog.d/696.bugfix @@ -0,0 +1 @@ +Fixed Embed component name that could lead to issue when developping on OSX (#696) diff --git a/front/src/Embed.vue b/front/src/EmbedFrame.vue similarity index 100% rename from front/src/Embed.vue rename to front/src/EmbedFrame.vue diff --git a/front/src/embed.js b/front/src/embed.js index 6de3ca187..5a924a9b1 100644 --- a/front/src/embed.js +++ b/front/src/embed.js @@ -1,6 +1,6 @@ import Vue from 'vue' -import Embed from './Embed' +import EmbedFrame from './EmbedFrame' import VuePlyr from 'vue-plyr' Vue.use(VuePlyr) @@ -10,6 +10,6 @@ Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', - template: '', - components: { Embed } + template: '', + components: { EmbedFrame } })