docs: fix spelling errors (pre-commit)
This commit is contained in:
parent
bdd02cf2fa
commit
054a9e54f5
|
@ -0,0 +1,12 @@
|
||||||
|
followings
|
||||||
|
inforce
|
||||||
|
keypair
|
||||||
|
nam
|
||||||
|
nd
|
||||||
|
readby
|
||||||
|
serie
|
||||||
|
upto
|
||||||
|
|
||||||
|
# Names
|
||||||
|
nin
|
||||||
|
noe
|
86
CHANGELOG
86
CHANGELOG
|
@ -401,7 +401,7 @@ Due to a bug in our CI Pipeline frontend artifacts are not available at
|
||||||
https://dev.funkwhale.audio/funkwhale/funkwhale/builds/artifacts/1.2.0/download?job=build_front as they would usually.
|
https://dev.funkwhale.audio/funkwhale/funkwhale/builds/artifacts/1.2.0/download?job=build_front as they would usually.
|
||||||
Please use this URL to get your frontend build: https://dev.funkwhale.audio/funkwhale/funkwhale/-/jobs/81069/artifacts/download
|
Please use this URL to get your frontend build: https://dev.funkwhale.audio/funkwhale/funkwhale/-/jobs/81069/artifacts/download
|
||||||
|
|
||||||
If you are running the All-in-One-Container since a longer time, you probably need to manually migrate your database information. If thats the case, you will get a message like this:
|
If you are running the All-in-One-Container since a longer time, you probably need to manually migrate your database information. If that's the case, you will get a message like this:
|
||||||
|
|
||||||
`DETAIL: The data directory was initialized by PostgreSQL version 11, which is not compatible with this version 13.5.`
|
`DETAIL: The data directory was initialized by PostgreSQL version 11, which is not compatible with this version 13.5.`
|
||||||
|
|
||||||
|
@ -409,7 +409,7 @@ Make sure the Funkwhale version is set to `1.1.4` in `docker-compose.yml`. Now y
|
||||||
|
|
||||||
`docker-compose exec -T funkwhale pg_dump -c -U funkwhale > "db.dump"`
|
`docker-compose exec -T funkwhale pg_dump -c -U funkwhale > "db.dump"`
|
||||||
|
|
||||||
Now you can update the Funkwhale version in `docker-compose.yml` to `1.2.0`. Additionally you should save your `data` directory, eg by running `mv data data.bak && mkdir data`. Stop Funkwhale and start it again with the new version, by using `docker-compose down && docker-compose up -d`. This will initialize a fresh DB and applies all migrations. Now you can restore your database with the following command: `cat db.dump | docker-compose exec -T funkwhale psql -U funkwhale`. Thats it, enjoy!
|
Now you can update the Funkwhale version in `docker-compose.yml` to `1.2.0`. Additionally you should save your `data` directory, eg by running `mv data data.bak && mkdir data`. Stop Funkwhale and start it again with the new version, by using `docker-compose down && docker-compose up -d`. This will initialize a fresh DB and applies all migrations. Now you can restore your database with the following command: `cat db.dump | docker-compose exec -T funkwhale psql -U funkwhale`. That's it, enjoy!
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
|
|
||||||
|
@ -446,7 +446,7 @@ Bugfixes:
|
||||||
- Fix showing too long radio descriptions (#1556)
|
- Fix showing too long radio descriptions (#1556)
|
||||||
- Fix X-Frame-Options HTTP header for embed and force it to SAMEORIGIN value for other pages (fix #1022)
|
- Fix X-Frame-Options HTTP header for embed and force it to SAMEORIGIN value for other pages (fix #1022)
|
||||||
- Fix before last track starts playing when last track removed (#1485)
|
- Fix before last track starts playing when last track removed (#1485)
|
||||||
- Fix delete account button is not disalbed when missing password (#1591)
|
- Fix delete account button is not disabled when missing password (#1591)
|
||||||
- Fix omputed properties already defined in components data (#1649)
|
- Fix omputed properties already defined in components data (#1649)
|
||||||
- Fix the all in one docker image building process, related to #1503
|
- Fix the all in one docker image building process, related to #1503
|
||||||
- Fix crash in album moderation interface when missing cover (#1474)
|
- Fix crash in album moderation interface when missing cover (#1474)
|
||||||
|
@ -458,7 +458,7 @@ Bugfixes:
|
||||||
- Sanitize remote tracks' saving locations with slashes on their names (#1435)
|
- Sanitize remote tracks' saving locations with slashes on their names (#1435)
|
||||||
- Show embed option for channel tracks (#1278)
|
- Show embed option for channel tracks (#1278)
|
||||||
- Store volume in logarithmic scale and convert when setting it to audio (fixes #1543)
|
- Store volume in logarithmic scale and convert when setting it to audio (fixes #1543)
|
||||||
- Use global Howler volume instead of setting it separatly for each track (fixes #1542)
|
- Use global Howler volume instead of setting it separately for each track (fixes #1542)
|
||||||
|
|
||||||
|
|
||||||
Documentation:
|
Documentation:
|
||||||
|
@ -916,7 +916,7 @@ Features:
|
||||||
- Allow users to hide compilation artists on the artist search page (#1053)
|
- Allow users to hide compilation artists on the artist search page (#1053)
|
||||||
- Can now launch server import from the UI (#1105)
|
- Can now launch server import from the UI (#1105)
|
||||||
- Dedicated, advanced search page (#370)
|
- Dedicated, advanced search page (#370)
|
||||||
- Persist theme and language settings accross sessions (#996)
|
- Persist theme and language settings across sessions (#996)
|
||||||
|
|
||||||
|
|
||||||
Enhancements:
|
Enhancements:
|
||||||
|
@ -1008,13 +1008,13 @@ Enhancements:
|
||||||
|
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
|
|
||||||
- Fix embedded player not working on channel serie/album (#1175)
|
- Fix embedded player not working on channel series/album (#1175)
|
||||||
- Fixed broken mimetype detection during import (#1165)
|
- Fixed broken mimetype detection during import (#1165)
|
||||||
- Fixed crash when loading recent albums via Subsonic (#1158)
|
- Fixed crash when loading recent albums via Subsonic (#1158)
|
||||||
- Fixed crash with null help text in admin (#1161)
|
- Fixed crash with null help text in admin (#1161)
|
||||||
- Fixed invalid metadata when importing multi-artists tracks/albums (#1104)
|
- Fixed invalid metadata when importing multi-artists tracks/albums (#1104)
|
||||||
- Fixed player crash when using Funkwhale as a PWA (#1157)
|
- Fixed player crash when using Funkwhale as a PWA (#1157)
|
||||||
- Fixed wrong covert art displaying in some situations (#1138)
|
- Fixed wrong convert art displaying in some situations (#1138)
|
||||||
- Make channel card updated times more humanly readable, add internationalization (#1089)
|
- Make channel card updated times more humanly readable, add internationalization (#1089)
|
||||||
|
|
||||||
Contributors to this release (development, documentation, reviews):
|
Contributors to this release (development, documentation, reviews):
|
||||||
|
@ -1041,7 +1041,7 @@ Enhancements:
|
||||||
- Fix HTML <title> not including instance name in some situations (#1107)
|
- Fix HTML <title> not including instance name in some situations (#1107)
|
||||||
- Make URL-building logic more resilient against reverse proxy misconfiguration (#1085)
|
- Make URL-building logic more resilient against reverse proxy misconfiguration (#1085)
|
||||||
- Removed unused masonry dependency (#1112)
|
- Removed unused masonry dependency (#1112)
|
||||||
- Support for specifying itunes:email and itunes:name in channels for compatibiliy with third-party platforms (#1154)
|
- Support for specifying itunes:email and itunes:name in channels for compatibility with third-party platforms (#1154)
|
||||||
- Updated the /api/v1/libraries endpoint to support listing public libraries from other users/pods (#1151)
|
- Updated the /api/v1/libraries endpoint to support listing public libraries from other users/pods (#1151)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1234,7 +1234,7 @@ Upgrade from Postgres 10 to 11 [manual action required, docker all-in-one only]
|
||||||
|
|
||||||
With our upgrade to Alpine 3.10, the ``funkwhale/all-in-one`` image now includes PostgreSQL 11.
|
With our upgrade to Alpine 3.10, the ``funkwhale/all-in-one`` image now includes PostgreSQL 11.
|
||||||
|
|
||||||
In order to update to Funkwhale 0.21, you will first need to uprade Funkwhale's PostgreSQL database, following the steps below::
|
In order to update to Funkwhale 0.21, you will first need to upgrade Funkwhale's PostgreSQL database, following the steps below::
|
||||||
|
|
||||||
# open a shell as the Funkwhale user
|
# open a shell as the Funkwhale user
|
||||||
sudo -u funkwhale -H bash
|
sudo -u funkwhale -H bash
|
||||||
|
@ -1611,7 +1611,7 @@ Then reload the configuration change with ``sudo systemctl daemon-reload`` and `
|
||||||
Content-Security-Policy and additional security headers [manual action suggested]
|
Content-Security-Policy and additional security headers [manual action suggested]
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
To improve the security and reduce the attack surface in case of a successfull exploit, we suggest
|
To improve the security and reduce the attack surface in case of a successful exploit, we suggest
|
||||||
you add the following Content-Security-Policy to your nginx configuration.
|
you add the following Content-Security-Policy to your nginx configuration.
|
||||||
|
|
||||||
..note::
|
..note::
|
||||||
|
@ -1664,7 +1664,7 @@ Then reload nginx with ``systemctl reload nginx``.
|
||||||
# Simply copy-paste the /front/ location, but replace the following lines:
|
# Simply copy-paste the /front/ location, but replace the following lines:
|
||||||
location /front/embed.html {
|
location /front/embed.html {
|
||||||
add_header X-Frame-Options "ALLOW";
|
add_header X-Frame-Options "ALLOW";
|
||||||
alias /frontent/embed.html;
|
alias /frontend/embed.html;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1676,7 +1676,7 @@ Rate limiting
|
||||||
With this release, rate-limiting on the API is enabled by default, with high enough limits to ensure
|
With this release, rate-limiting on the API is enabled by default, with high enough limits to ensure
|
||||||
regular users of the app aren't affected. Requests beyond allowed limits are answered with a 429 HTTP error.
|
regular users of the app aren't affected. Requests beyond allowed limits are answered with a 429 HTTP error.
|
||||||
|
|
||||||
For anonymous requests, the limit is applied to the IP adress of the client, and for authenticated requests, the limit
|
For anonymous requests, the limit is applied to the IP address of the client, and for authenticated requests, the limit
|
||||||
is applied to the corresponding user account. By default, anonymous requests get a lower limit than authenticated requests.
|
is applied to the corresponding user account. By default, anonymous requests get a lower limit than authenticated requests.
|
||||||
|
|
||||||
You can disable the rate-limiting feature by adding `THROTTLING_ENABLED=false` to your ``.env`` file and restarting the
|
You can disable the rate-limiting feature by adding `THROTTLING_ENABLED=false` to your ``.env`` file and restarting the
|
||||||
|
@ -1825,7 +1825,7 @@ Bugfixes:
|
||||||
- Use ASCII filename before upload to S3 to avoid playback issues (#847)
|
- Use ASCII filename before upload to S3 to avoid playback issues (#847)
|
||||||
|
|
||||||
|
|
||||||
Contributors to this release (commiters and reviewers):
|
Contributors to this release (committers and reviewers):
|
||||||
|
|
||||||
- Ciarán Ainsworth
|
- Ciarán Ainsworth
|
||||||
- Creak
|
- Creak
|
||||||
|
@ -1986,7 +1986,7 @@ Enhancements:
|
||||||
- Expose an instance-level actor (service@domain) in nodeinfo endpoint (#689)
|
- Expose an instance-level actor (service@domain) in nodeinfo endpoint (#689)
|
||||||
- Improved readability of logo (#385)
|
- Improved readability of logo (#385)
|
||||||
- Keep persistent connections to the database instead of recreating a new one for each request
|
- Keep persistent connections to the database instead of recreating a new one for each request
|
||||||
- Labels for privacy levels are now consistently grabbed from a common source instead of being hardcoded everytime they are needed.
|
- Labels for privacy levels are now consistently grabbed from a common source instead of being hardcoded every time they are needed.
|
||||||
- Merged artist/album buttons with title text on artist and album pages (#725)
|
- Merged artist/album buttons with title text on artist and album pages (#725)
|
||||||
- Now honor maxBitrate parameter in Subsonic API (#802)
|
- Now honor maxBitrate parameter in Subsonic API (#802)
|
||||||
- Preload next track in queue (#572)
|
- Preload next track in queue (#572)
|
||||||
|
@ -2008,7 +2008,7 @@ Bugfixes:
|
||||||
- Do not consider tracks as duplicates during import if they have different positions (#740)
|
- Do not consider tracks as duplicates during import if they have different positions (#740)
|
||||||
- Ensure all our ActivityPub fetches are authenticated (#758)
|
- Ensure all our ActivityPub fetches are authenticated (#758)
|
||||||
- Ensure correct track duration and playable status when browsing radios (#812)
|
- Ensure correct track duration and playable status when browsing radios (#812)
|
||||||
- Fixed alignement/size issue with some buttons (#702)
|
- Fixed alignment/size issue with some buttons (#702)
|
||||||
- Fixed an encoding issue with instance name on about page (#828)
|
- Fixed an encoding issue with instance name on about page (#828)
|
||||||
- Fixed cover not showing in queue/player when playing tracks from "albums" tab (#795)
|
- Fixed cover not showing in queue/player when playing tracks from "albums" tab (#795)
|
||||||
- Fixed crashing upload processing on invalid date format (#718)
|
- Fixed crashing upload processing on invalid date format (#718)
|
||||||
|
@ -2028,7 +2028,7 @@ Documentation:
|
||||||
|
|
||||||
- Document how to use Redis over unix sockets (#770)
|
- Document how to use Redis over unix sockets (#770)
|
||||||
|
|
||||||
Contributors to this release (commiters and translators):
|
Contributors to this release (committers and translators):
|
||||||
|
|
||||||
- Ale London
|
- Ale London
|
||||||
- Alexander
|
- Alexander
|
||||||
|
@ -2090,7 +2090,7 @@ Enhancements:
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
|
|
||||||
- Avoid mixed content when deploying mono-container behind HTTPS proxy (thetarkus/docker-funkwhale#19)
|
- Avoid mixed content when deploying mono-container behind HTTPS proxy (thetarkus/docker-funkwhale#19)
|
||||||
- Display new notifications immediatly on notifications page (#729)
|
- Display new notifications immediately on notifications page (#729)
|
||||||
- Ensure cover art from uploaded files is picked up properly on existing albums (#757)
|
- Ensure cover art from uploaded files is picked up properly on existing albums (#757)
|
||||||
- Fixed a crash when federating a track with unspecified position
|
- Fixed a crash when federating a track with unspecified position
|
||||||
- Fixed broken Activity and Actor modules in django admin (#767)
|
- Fixed broken Activity and Actor modules in django admin (#767)
|
||||||
|
@ -2232,7 +2232,7 @@ Bugfixes:
|
||||||
- Fix transcoding of in-place imported tracks (#688)
|
- Fix transcoding of in-place imported tracks (#688)
|
||||||
- Fixed celery worker defaulting to development settings instead of production
|
- Fixed celery worker defaulting to development settings instead of production
|
||||||
- Fixed crashing Django admin when loading track detail page (#666)
|
- Fixed crashing Django admin when loading track detail page (#666)
|
||||||
- Fixed list icon alignement on landing page (#668)
|
- Fixed list icon alignment on landing page (#668)
|
||||||
- Fixed overescaping issue in notifications and album page (#676)
|
- Fixed overescaping issue in notifications and album page (#676)
|
||||||
- Fixed wrong number of affected elements in bulk action modal (#683)
|
- Fixed wrong number of affected elements in bulk action modal (#683)
|
||||||
- Fixed wrong URL in documentation for funkwhale_proxy.conf file when deploying using Docker
|
- Fixed wrong URL in documentation for funkwhale_proxy.conf file when deploying using Docker
|
||||||
|
@ -2257,7 +2257,7 @@ Many thanks to the dozens of people that contributed to this release: translator
|
||||||
bug hunters, admins and backers. You made it possible!
|
bug hunters, admins and backers. You made it possible!
|
||||||
|
|
||||||
Upgrade instructions are available at
|
Upgrade instructions are available at
|
||||||
https://docs.funkwhale.audio/admin/upgrading.html, ensure you also execute the intructions
|
https://docs.funkwhale.audio/admin/upgrading.html, ensure you also execute the instructions
|
||||||
marked with ``[manual action required]`` and ``[manual action suggested]``.
|
marked with ``[manual action required]`` and ``[manual action suggested]``.
|
||||||
|
|
||||||
See ``Full changelog`` below for an exhaustive list of changes!
|
See ``Full changelog`` below for an exhaustive list of changes!
|
||||||
|
@ -2477,7 +2477,7 @@ Enhancements:
|
||||||
- Load env file in config/.env automatically to avoid sourcing it by hand (#626)
|
- Load env file in config/.env automatically to avoid sourcing it by hand (#626)
|
||||||
- More resilient date parsing during audio import, will not crash anymore on
|
- More resilient date parsing during audio import, will not crash anymore on
|
||||||
invalid dates (#622)
|
invalid dates (#622)
|
||||||
- Now start radios immediatly, skipping any existing tracks in queue (#585)
|
- Now start radios immediately, skipping any existing tracks in queue (#585)
|
||||||
- Officially support connecting to a password protected redis server, with
|
- Officially support connecting to a password protected redis server, with
|
||||||
the redis://:password@localhost:6379/0 scheme (#640)
|
the redis://:password@localhost:6379/0 scheme (#640)
|
||||||
- Performance improvement when fetching favorites, down to a single, small http request
|
- Performance improvement when fetching favorites, down to a single, small http request
|
||||||
|
@ -2505,11 +2505,11 @@ Bugfixes:
|
||||||
- Allow opus file upload (#598)
|
- Allow opus file upload (#598)
|
||||||
- Do not display "view on MusicBrainz" button if we miss the mbid (#422)
|
- Do not display "view on MusicBrainz" button if we miss the mbid (#422)
|
||||||
- Do not try to create unaccent extension if it's already present (#663)
|
- Do not try to create unaccent extension if it's already present (#663)
|
||||||
- Ensure admin links in sidebar are displayed for users with relavant permissions, and only them (#597)
|
- Ensure admin links in sidebar are displayed for users with relevant permissions, and only them (#597)
|
||||||
- Fix broken websocket connexion under Chrome browser (#589)
|
- Fix broken websocket connection under Chrome browser (#589)
|
||||||
- Fix play button not starting playback with empty queue (#632)
|
- Fix play button not starting playback with empty queue (#632)
|
||||||
- Fixed a styling inconsistency on about page when instance description was missing (#659)
|
- Fixed a styling inconsistency on about page when instance description was missing (#659)
|
||||||
- Fixed a UI discrepency in playlist tracks count (#647)
|
- Fixed a UI discrepancy in playlist tracks count (#647)
|
||||||
- Fixed greyed tracks in radio builder and detail page (#637)
|
- Fixed greyed tracks in radio builder and detail page (#637)
|
||||||
- Fixed inconsistencies in subsonic error responses (#616)
|
- Fixed inconsistencies in subsonic error responses (#616)
|
||||||
- Fixed incorrect icon for "next track" in player control (#613)
|
- Fixed incorrect icon for "next track" in player control (#613)
|
||||||
|
@ -2517,7 +2517,7 @@ Bugfixes:
|
||||||
- Fixed missing track count on various library cards (#581)
|
- Fixed missing track count on various library cards (#581)
|
||||||
- Fixed skipped track when appending multiple tracks to the queue under certain conditions (#209)
|
- Fixed skipped track when appending multiple tracks to the queue under certain conditions (#209)
|
||||||
- Fixed wrong album/track count on artist page (#599)
|
- Fixed wrong album/track count on artist page (#599)
|
||||||
- Hide unplayable/emtpy playlists in "Browse playlist" pages (#424)
|
- Hide unplayable/empty playlists in "Browse playlist" pages (#424)
|
||||||
- Initial UI render using correct language from browser (#644)
|
- Initial UI render using correct language from browser (#644)
|
||||||
- Invalid URI for reverse proxy websocket with apache (#617)
|
- Invalid URI for reverse proxy websocket with apache (#617)
|
||||||
- Properly encode Wikipedia and lyrics search urls (#470)
|
- Properly encode Wikipedia and lyrics search urls (#470)
|
||||||
|
@ -2566,7 +2566,7 @@ Bugfixes:
|
||||||
or adding tracks to queue (#464)
|
or adding tracks to queue (#464)
|
||||||
- Fix broken icons in playlist editor (#515)
|
- Fix broken icons in playlist editor (#515)
|
||||||
- Fixed a few untranslated strings (#559)
|
- Fixed a few untranslated strings (#559)
|
||||||
- Fixed splitted album when importing from federation (#346)
|
- Fixed split album when importing from federation (#346)
|
||||||
- Fixed toggle mute in volume bar does not restore previous volume level (#514)
|
- Fixed toggle mute in volume bar does not restore previous volume level (#514)
|
||||||
- Fixed wrong env file URL and display bugs in deployment documentation (#520)
|
- Fixed wrong env file URL and display bugs in deployment documentation (#520)
|
||||||
- Fixed wrong title in PlayButton (#435)
|
- Fixed wrong title in PlayButton (#435)
|
||||||
|
@ -2841,7 +2841,7 @@ Features:
|
||||||
|
|
||||||
- Complete redesign of the library home and playlist pages (#284)
|
- Complete redesign of the library home and playlist pages (#284)
|
||||||
- Expose ActivityPub actors for users (#317)
|
- Expose ActivityPub actors for users (#317)
|
||||||
- Implemented a basic but functionnal Github-like search on federated tracks
|
- Implemented a basic but functional Github-like search on federated tracks
|
||||||
list (#344)
|
list (#344)
|
||||||
- Internationalized interface as well as translations for Arabic, French,
|
- Internationalized interface as well as translations for Arabic, French,
|
||||||
Esperanto, Italian, Occitan, Polish, Portuguese and Swedish (#161, #167)
|
Esperanto, Italian, Occitan, Polish, Portuguese and Swedish (#161, #167)
|
||||||
|
@ -3002,7 +3002,7 @@ This is the type of query you can run:
|
||||||
- ``artist:"System of a Down" domain:instance.funkwhale`` search for results where artist name equals "System of a Down" and inside "instance.funkwhale" library
|
- ``artist:"System of a Down" domain:instance.funkwhale`` search for results where artist name equals "System of a Down" and inside "instance.funkwhale" library
|
||||||
|
|
||||||
|
|
||||||
Ensure MEDIA_ROOT, STATIC_ROOT and MUSIC_DIRECTORY_* are set explicitely [Manual action required]
|
Ensure MEDIA_ROOT, STATIC_ROOT and MUSIC_DIRECTORY_* are set explicitly [Manual action required]
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
In our default .env file, MEDIA_ROOT and STATIC_ROOT were commented by default, causing
|
In our default .env file, MEDIA_ROOT and STATIC_ROOT were commented by default, causing
|
||||||
|
@ -3122,10 +3122,10 @@ Invitations generation and management requires the "settings" permission.
|
||||||
Removed front-end and back-end coupling
|
Removed front-end and back-end coupling
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Eventhough Funkwhale's front-end has always been a Single Page Application,
|
Even though Funkwhale's front-end has always been a Single Page Application,
|
||||||
talking to an API, it was only able to talk to an API on the same domain.
|
talking to an API, it was only able to talk to an API on the same domain.
|
||||||
|
|
||||||
There was no real technical justification behind this (only lazyness), and it was
|
There was no real technical justification behind this (only laziness), and it was
|
||||||
also blocking interesting use cases:
|
also blocking interesting use cases:
|
||||||
|
|
||||||
- Use multiple customized versions of the front-end with the same instance
|
- Use multiple customized versions of the front-end with the same instance
|
||||||
|
@ -3168,7 +3168,7 @@ Bugfixes:
|
||||||
- Ensure radios can only be edited and deleted by their owners (#311)
|
- Ensure radios can only be edited and deleted by their owners (#311)
|
||||||
- Fixed admin menu not showing after login (#245)
|
- Fixed admin menu not showing after login (#245)
|
||||||
- Fixed broken pagination in Subsonic API (#295)
|
- Fixed broken pagination in Subsonic API (#295)
|
||||||
- Fixed duplicated websocket connexion on timeline (#287)
|
- Fixed duplicated websocket connection on timeline (#287)
|
||||||
|
|
||||||
|
|
||||||
Documentation:
|
Documentation:
|
||||||
|
@ -3404,7 +3404,7 @@ Bugfixes:
|
||||||
(#106)
|
(#106)
|
||||||
- Fixed a few broken translations strings (#227)
|
- Fixed a few broken translations strings (#227)
|
||||||
- Fixed broken ordering in front-end lists (#179)
|
- Fixed broken ordering in front-end lists (#179)
|
||||||
- Fixed ignored page_size paremeter on artist and favorites list (#240)
|
- Fixed ignored page_size parameter on artist and favorites list (#240)
|
||||||
- Read ID3Tag Tracknumber from TRCK (#220)
|
- Read ID3Tag Tracknumber from TRCK (#220)
|
||||||
- We now fetch album covers regardless of the import methods (#231)
|
- We now fetch album covers regardless of the import methods (#231)
|
||||||
|
|
||||||
|
@ -3426,7 +3426,7 @@ This is the first bit of an ongoing work that will span several releases, to
|
||||||
bring more powerful library management features to Funkwhale. This iteration
|
bring more powerful library management features to Funkwhale. This iteration
|
||||||
includes a basic file management interface where users with the "library"
|
includes a basic file management interface where users with the "library"
|
||||||
permission can list and search available files, order them using
|
permission can list and search available files, order them using
|
||||||
various criterias (size, bitrate, duration...) and delete them.
|
various criteria (size, bitrate, duration...) and delete them.
|
||||||
|
|
||||||
New "upload" permission
|
New "upload" permission
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -3534,10 +3534,10 @@ tend to be a lot bigger than other files, you may want to increase the
|
||||||
``client_max_body_size`` value in your Nginx configuration if you plan
|
``client_max_body_size`` value in your Nginx configuration if you plan
|
||||||
to upload flac files.
|
to upload flac files.
|
||||||
|
|
||||||
Missing subsonic configuration bloc in vhost files
|
Missing subsonic configuration block in vhost files
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Because of a missing bloc in the sample Nginx and Apache configurations,
|
Because of a missing block in the sample Nginx and Apache configurations,
|
||||||
instances that were deployed after the 0.13 release are likely to be unable
|
instances that were deployed after the 0.13 release are likely to be unable
|
||||||
to answer to Subsonic clients (the missing bits were properly documented
|
to answer to Subsonic clients (the missing bits were properly documented
|
||||||
in the changelog).
|
in the changelog).
|
||||||
|
@ -3620,7 +3620,7 @@ additional information about audio files:
|
||||||
- Duration
|
- Duration
|
||||||
|
|
||||||
This change is not retroactive, meaning already imported files will lack those
|
This change is not retroactive, meaning already imported files will lack those
|
||||||
informations. The interface and API should work as before in such case, however,
|
information. The interface and API should work as before in such case, however,
|
||||||
we offer a command to deal with legacy files and populate the missing values.
|
we offer a command to deal with legacy files and populate the missing values.
|
||||||
|
|
||||||
On docker setups:
|
On docker setups:
|
||||||
|
@ -3724,7 +3724,7 @@ Most advanced Subsonic clients support offline caching of music files,
|
||||||
playlist management and search, which makes them well-suited for nomadic use.
|
playlist management and search, which makes them well-suited for nomadic use.
|
||||||
|
|
||||||
Please see `our list of supported apps <https://funkwhale.audio/en_US/apps>`_
|
Please see `our list of supported apps <https://funkwhale.audio/en_US/apps>`_
|
||||||
for more informations about supported clients and user instructions.
|
for more information about supported clients and user instructions.
|
||||||
|
|
||||||
At the instance-level, the Subsonic API is enabled by default, but require
|
At the instance-level, the Subsonic API is enabled by default, but require
|
||||||
and additional endpoint to be added in you reverse-proxy configuration.
|
and additional endpoint to be added in you reverse-proxy configuration.
|
||||||
|
@ -3907,7 +3907,7 @@ of emails:
|
||||||
- Password reset emails, enabling user to reset their password without an admin's intervention
|
- Password reset emails, enabling user to reset their password without an admin's intervention
|
||||||
|
|
||||||
Email sending is disabled by default, as it requires additional configuration.
|
Email sending is disabled by default, as it requires additional configuration.
|
||||||
In this mode, emails are simply outputed on stdout.
|
In this mode, emails are simply outputted on stdout.
|
||||||
|
|
||||||
If you want to actually send those emails to your users, you should edit your
|
If you want to actually send those emails to your users, you should edit your
|
||||||
.env file and tweak the ``EMAIL_CONFIG`` variable. See :data:`EMAIL_CONFIG <config.settings.common.EMAIL_CONFIG>`
|
.env file and tweak the ``EMAIL_CONFIG`` variable. See :data:`EMAIL_CONFIG <config.settings.common.EMAIL_CONFIG>`
|
||||||
|
@ -4046,7 +4046,7 @@ This is for real this time, and includes:
|
||||||
|
|
||||||
- Following other Funkwhale libraries
|
- Following other Funkwhale libraries
|
||||||
- Importing tracks from remote libraries (tracks are hotlinked, and only cached for a short amount of time)
|
- Importing tracks from remote libraries (tracks are hotlinked, and only cached for a short amount of time)
|
||||||
- Searching accross federated catalogs
|
- Searching across federated catalogs
|
||||||
|
|
||||||
Note that by default, federation is opt-in, on a per-instance basis:
|
Note that by default, federation is opt-in, on a per-instance basis:
|
||||||
instances will request access to your catalog, and you can accept or refuse
|
instances will request access to your catalog, and you can accept or refuse
|
||||||
|
@ -4196,7 +4196,7 @@ Bugfixes:
|
||||||
- Fixed broken import request admin (#115)
|
- Fixed broken import request admin (#115)
|
||||||
- Fixed forced redirection to login event with
|
- Fixed forced redirection to login event with
|
||||||
API_AUTHENTICATION_REQUIRED=False (#119)
|
API_AUTHENTICATION_REQUIRED=False (#119)
|
||||||
- Fixed position not being reseted properly when playing the same track
|
- Fixed position not being reset properly when playing the same track
|
||||||
multiple times in a row
|
multiple times in a row
|
||||||
- Fixed synchronized start/stop radio buttons for all custom radios (#103)
|
- Fixed synchronized start/stop radio buttons for all custom radios (#103)
|
||||||
- Fixed typo and missing icon on homepage (#96)
|
- Fixed typo and missing icon on homepage (#96)
|
||||||
|
@ -4269,7 +4269,7 @@ To prepare for new realtime features and enable websocket support in Funkwhale,
|
||||||
we are now using django-channels and daphne to serve HTTP and websocket traffic.
|
we are now using django-channels and daphne to serve HTTP and websocket traffic.
|
||||||
|
|
||||||
This replaces gunicorn and the switch should be easy assuming you
|
This replaces gunicorn and the switch should be easy assuming you
|
||||||
follow the upgrade process described bellow.
|
follow the upgrade process described below.
|
||||||
|
|
||||||
If you are using docker, please remove the command instruction inside the
|
If you are using docker, please remove the command instruction inside the
|
||||||
api service, as the up-to-date command is now included directly in the image
|
api service, as the up-to-date command is now included directly in the image
|
||||||
|
@ -4400,7 +4400,7 @@ Basic transcoding is now available to/from the following formats : ogg and mp3.
|
||||||
|
|
||||||
This relies internally on FFMPEG and can put some load on your server.
|
This relies internally on FFMPEG and can put some load on your server.
|
||||||
It's definitely recommended you setup some caching for the transcoded files
|
It's definitely recommended you setup some caching for the transcoded files
|
||||||
at your webserver level. Check the the exemple nginx file at deploy/nginx.conf
|
at your webserver level. Check the the example nginx file at deploy/nginx.conf
|
||||||
for an implementation.
|
for an implementation.
|
||||||
|
|
||||||
On the frontend, usage of transcoding should be transparent in the player.
|
On the frontend, usage of transcoding should be transparent in the player.
|
||||||
|
@ -4454,7 +4454,7 @@ an import is made.
|
||||||
0.3.1
|
0.3.1
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
- Revamped all import logic, everything is more tested and consistend
|
- Revamped all import logic, everything is more tested and consistent
|
||||||
- Can now use Acoustid in file imports to automatically grab metadata from musicbrainz
|
- Can now use Acoustid in file imports to automatically grab metadata from musicbrainz
|
||||||
- Brand new file import wizard
|
- Brand new file import wizard
|
||||||
|
|
||||||
|
@ -4513,7 +4513,7 @@ Tech:
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
|
|
||||||
- Models: now store relese group mbid on Album model (#7)
|
- Models: now store release group mbid on Album model (#7)
|
||||||
- Models: now bind import job to track files (#44)
|
- Models: now bind import job to track files (#44)
|
||||||
|
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
|
|
|
@ -5,7 +5,7 @@ set -e
|
||||||
# environment variables just to support cookiecutter out of the box. That makes no sense, so this little entrypoint
|
# environment variables just to support cookiecutter out of the box. That makes no sense, so this little entrypoint
|
||||||
# does all this for us.
|
# does all this for us.
|
||||||
if [ -z "$DATABASE_URL" ]; then
|
if [ -z "$DATABASE_URL" ]; then
|
||||||
# the official postgres image uses 'postgres' as default user if not set explictly.
|
# the official postgres image uses 'postgres' as default user if not set explicitly.
|
||||||
if [ -z "$POSTGRES_ENV_POSTGRES_USER" ]; then
|
if [ -z "$POSTGRES_ENV_POSTGRES_USER" ]; then
|
||||||
export POSTGRES_ENV_POSTGRES_USER=postgres
|
export POSTGRES_ENV_POSTGRES_USER=postgres
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -81,7 +81,7 @@ Path to a .env file to load
|
||||||
"""
|
"""
|
||||||
if env_file:
|
if env_file:
|
||||||
logger.info("Loading specified env file at %s", env_file)
|
logger.info("Loading specified env file at %s", env_file)
|
||||||
# we have an explicitely specified env file
|
# we have an explicitly specified env file
|
||||||
# so we try to load and it fail loudly if it does not exist
|
# so we try to load and it fail loudly if it does not exist
|
||||||
env.read_env(env_file)
|
env.read_env(env_file)
|
||||||
else:
|
else:
|
||||||
|
@ -493,7 +493,7 @@ bucket.
|
||||||
|
|
||||||
ACLs and bucket policies are distinct concepts, and some storage
|
ACLs and bucket policies are distinct concepts, and some storage
|
||||||
providers (ie Linode, Scaleway) will always apply the most restrictive between
|
providers (ie Linode, Scaleway) will always apply the most restrictive between
|
||||||
a bucket's ACL and policy, meaning a default private ACL will supercede
|
a bucket's ACL and policy, meaning a default private ACL will supersede
|
||||||
a relaxed bucket policy.
|
a relaxed bucket policy.
|
||||||
|
|
||||||
If present, the value should be a valid canned ACL.
|
If present, the value should be a valid canned ACL.
|
||||||
|
@ -1258,7 +1258,7 @@ able to read this directory.
|
||||||
Don’t insert a slash at the end of this path.
|
Don’t insert a slash at the end of this path.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# When this is set to default=True, we need to reenable migration music/0042
|
# When this is set to default=True, we need to re-enable migration music/0042
|
||||||
# to ensure data is populated correctly on existing pods
|
# to ensure data is populated correctly on existing pods
|
||||||
MUSIC_USE_DENORMALIZATION = env.bool("MUSIC_USE_DENORMALIZATION", default=True)
|
MUSIC_USE_DENORMALIZATION = env.bool("MUSIC_USE_DENORMALIZATION", default=True)
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ QUERY_REGEX = re.compile(r'(((?P<key>\w+):)?(?P<value>"[^"]+"|[\S]+))')
|
||||||
def parse_query(query):
|
def parse_query(query):
|
||||||
"""
|
"""
|
||||||
Given a search query such as "hello is:issue status:opened",
|
Given a search query such as "hello is:issue status:opened",
|
||||||
returns a list of dictionnaries discribing each query token
|
returns a list of dictionaries describing each query token
|
||||||
"""
|
"""
|
||||||
matches = [m.groupdict() for m in QUERY_REGEX.finditer(query.lower())]
|
matches = [m.groupdict() for m in QUERY_REGEX.finditer(query.lower())]
|
||||||
for m in matches:
|
for m in matches:
|
||||||
|
@ -25,7 +25,7 @@ def normalize_query(
|
||||||
findterms=re.compile(r'"([^"]+)"|(\S+)').findall,
|
findterms=re.compile(r'"([^"]+)"|(\S+)').findall,
|
||||||
normspace=re.compile(r"\s{2,}").sub,
|
normspace=re.compile(r"\s{2,}").sub,
|
||||||
):
|
):
|
||||||
"""Splits the query string in invidual keywords, getting rid of unecessary spaces
|
"""Splits the query string in individual keywords, getting rid of unnecessary spaces
|
||||||
and grouping quoted words together.
|
and grouping quoted words together.
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
|
|
@ -138,7 +138,7 @@ def chunk_queryset(source_qs, chunk_size):
|
||||||
|
|
||||||
def join_url(start, end):
|
def join_url(start, end):
|
||||||
if end.startswith("http://") or end.startswith("https://"):
|
if end.startswith("http://") or end.startswith("https://"):
|
||||||
# alread a full URL, joining makes no sense
|
# already a full URL, joining makes no sense
|
||||||
return end
|
return end
|
||||||
if start.endswith("/") and end.startswith("/"):
|
if start.endswith("/") and end.startswith("/"):
|
||||||
return start + end[1:]
|
return start + end[1:]
|
||||||
|
|
|
@ -97,7 +97,7 @@ class FileValidator:
|
||||||
"MIME type '%(mimetype)s' is not valid. Allowed types are: %(allowed_mimetypes)s."
|
"MIME type '%(mimetype)s' is not valid. Allowed types are: %(allowed_mimetypes)s."
|
||||||
)
|
)
|
||||||
min_size_message = _(
|
min_size_message = _(
|
||||||
"The current file %(size)s, which is too small. The minumum file size is %(allowed_size)s."
|
"The current file %(size)s, which is too small. The minimum file size is %(allowed_size)s."
|
||||||
)
|
)
|
||||||
max_size_message = _(
|
max_size_message = _(
|
||||||
"The current file %(size)s, which is too large. The maximum file size is %(allowed_size)s."
|
"The current file %(size)s, which is too large. The maximum file size is %(allowed_size)s."
|
||||||
|
|
|
@ -59,7 +59,7 @@ def submit_scrobble_v1(session, scrobble_time, track, session_key, scrobble_url)
|
||||||
else:
|
else:
|
||||||
raise ScrobblerException(response.text)
|
raise ScrobblerException(response.text)
|
||||||
|
|
||||||
PLUGIN["logger"].debug("Scrobble successfull!")
|
PLUGIN["logger"].debug("Scrobble successful!")
|
||||||
|
|
||||||
|
|
||||||
def submit_now_playing_v1(session, track, session_key, now_playing_url):
|
def submit_now_playing_v1(session, track, session_key, now_playing_url):
|
||||||
|
@ -75,7 +75,7 @@ def submit_now_playing_v1(session, track, session_key, now_playing_url):
|
||||||
else:
|
else:
|
||||||
raise ScrobblerException(response.text)
|
raise ScrobblerException(response.text)
|
||||||
|
|
||||||
PLUGIN["logger"].debug("Now playing successfull!")
|
PLUGIN["logger"].debug("Now playing successful!")
|
||||||
|
|
||||||
|
|
||||||
def get_scrobble_payload(track, date, suffix="[0]"):
|
def get_scrobble_payload(track, date, suffix="[0]"):
|
||||||
|
|
|
@ -424,7 +424,7 @@ def is_allowed_url(url, allowed_domains):
|
||||||
def prepare_deliveries_and_inbox_items(recipient_list, type, allowed_domains=None):
|
def prepare_deliveries_and_inbox_items(recipient_list, type, allowed_domains=None):
|
||||||
"""
|
"""
|
||||||
Given a list of recipients (
|
Given a list of recipients (
|
||||||
either actor instances, public adresses, a dictionnary with a "type" and "target"
|
either actor instances, public addresses, a dictionary with a "type" and "target"
|
||||||
keys for followers collections)
|
keys for followers collections)
|
||||||
returns a list of deliveries, alist of inbox_items and a list
|
returns a list of deliveries, alist of inbox_items and a list
|
||||||
of urls to persist in the activity in place of the initial recipient list.
|
of urls to persist in the activity in place of the initial recipient list.
|
||||||
|
|
|
@ -96,7 +96,7 @@ async def fetch_many(*ids, references=None):
|
||||||
"""
|
"""
|
||||||
Given a list of object ids, will fetch the remote
|
Given a list of object ids, will fetch the remote
|
||||||
representations for those objects, expand them
|
representations for those objects, expand them
|
||||||
and return a dictionnary with id as the key and expanded document as the values
|
and return a dictionary with id as the key and expanded document as the values
|
||||||
"""
|
"""
|
||||||
ids = set(ids)
|
ids = set(ids)
|
||||||
results = references if references is not None else {}
|
results = references if references is not None else {}
|
||||||
|
@ -122,7 +122,7 @@ DEFAULT_PREPARE_CONFIG = {
|
||||||
|
|
||||||
def dereference(value, references):
|
def dereference(value, references):
|
||||||
"""
|
"""
|
||||||
Given a payload and a dictonary containing ids and objects, will replace
|
Given a payload and a dictionary containing ids and objects, will replace
|
||||||
all the matching objects in the payload by the one in the references dictionary.
|
all the matching objects in the payload by the one in the references dictionary.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -166,10 +166,10 @@ def get_value(value, keep=None, attr=None):
|
||||||
def prepare_for_serializer(payload, config, fallbacks={}):
|
def prepare_for_serializer(payload, config, fallbacks={}):
|
||||||
"""
|
"""
|
||||||
Json-ld payloads, as returned by expand are quite complex to handle, because
|
Json-ld payloads, as returned by expand are quite complex to handle, because
|
||||||
every attr is basically a list of dictionnaries. To make code simpler,
|
every attr is basically a list of dictionaries. To make code simpler,
|
||||||
we use this function to clean the payload a little bit, base on the config object.
|
we use this function to clean the payload a little bit, base on the config object.
|
||||||
|
|
||||||
Config is a dictionnary, with keys being serializer field names, and values
|
Config is a dictionary, with keys being serializer field names, and values
|
||||||
being dictionaries describing how to handle this field.
|
being dictionaries describing how to handle this field.
|
||||||
"""
|
"""
|
||||||
final_payload = {}
|
final_payload = {}
|
||||||
|
|
|
@ -30,7 +30,7 @@ MODELS = [
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = """
|
help = """
|
||||||
Find and replace wrong protocal/domain in local federation ids.
|
Find and replace wrong protocol/domain in local federation ids.
|
||||||
|
|
||||||
Use with caution and only if you know what you are doing.
|
Use with caution and only if you know what you are doing.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -328,7 +328,7 @@ def fetch(fetch_obj):
|
||||||
auth = None
|
auth = None
|
||||||
try:
|
try:
|
||||||
if url.startswith("webfinger://"):
|
if url.startswith("webfinger://"):
|
||||||
# we first grab the correpsonding webfinger representation
|
# we first grab the corresponding webfinger representation
|
||||||
# to get the ActivityPub actor ID
|
# to get the ActivityPub actor ID
|
||||||
webfinger_data = webfinger.get_resource(
|
webfinger_data = webfinger.get_resource(
|
||||||
"acct:" + url.replace("webfinger://", "")
|
"acct:" + url.replace("webfinger://", "")
|
||||||
|
@ -552,8 +552,8 @@ def fetch_collection(url, max_pages, channel, is_page=False):
|
||||||
"total": 0,
|
"total": 0,
|
||||||
}
|
}
|
||||||
if is_page:
|
if is_page:
|
||||||
# starting immediatly from a page, no need to fetch the wrapping collection
|
# starting immediately from a page, no need to fetch the wrapping collection
|
||||||
logger.debug("Fetch collection page immediatly at %s", url)
|
logger.debug("Fetch collection page immediately at %s", url)
|
||||||
results["next_page"] = url
|
results["next_page"] = url
|
||||||
else:
|
else:
|
||||||
logger.debug("Fetching collection object at %s", url)
|
logger.debug("Fetching collection object at %s", url)
|
||||||
|
@ -644,7 +644,7 @@ def check_single_remote_instance_availability(domain):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.info(
|
logger.info(
|
||||||
f"Domain {domain.name} could not be reached because of the following error : {e}. \
|
f"Domain {domain.name} could not be reached because of the following error : {e}. \
|
||||||
Setting domain as unreacheable."
|
Setting domain as unreachable."
|
||||||
)
|
)
|
||||||
domain.reachable = False
|
domain.reachable = False
|
||||||
domain.save()
|
domain.save()
|
||||||
|
@ -657,7 +657,7 @@ def check_single_remote_instance_availability(domain):
|
||||||
return domain.reachable
|
return domain.reachable
|
||||||
else:
|
else:
|
||||||
logger.info(
|
logger.info(
|
||||||
f"Domain {domain.name} is not reacheable at the moment. Setting domain as unreacheable."
|
f"Domain {domain.name} is not reachable at the moment. Setting domain as unreachable."
|
||||||
)
|
)
|
||||||
domain.reachable = False
|
domain.reachable = False
|
||||||
domain.save()
|
domain.save()
|
||||||
|
|
|
@ -16,7 +16,7 @@ class AllowListEnabled(types.BooleanPreference):
|
||||||
section = moderation
|
section = moderation
|
||||||
name = "allow_list_enabled"
|
name = "allow_list_enabled"
|
||||||
verbose_name = "Enable allow-listing"
|
verbose_name = "Enable allow-listing"
|
||||||
help_text = "If enabled, only interactions with explicitely allowed domains will be authorized."
|
help_text = "If enabled, only interactions with explicitly allowed domains will be authorized."
|
||||||
default = False
|
default = False
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@ class Command(BaseCommand):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if not dry_run:
|
if not dry_run:
|
||||||
self.stdout.write("[mimetypes] commiting...")
|
self.stdout.write("[mimetypes] committing...")
|
||||||
qs.update(mimetype=mimetype)
|
qs.update(mimetype=mimetype)
|
||||||
|
|
||||||
def fix_file_data(self, dry_run, **kwargs):
|
def fix_file_data(self, dry_run, **kwargs):
|
||||||
|
|
|
@ -63,5 +63,5 @@ class Command(BaseCommand):
|
||||||
actor_ids=actor_ids,
|
actor_ids=actor_ids,
|
||||||
upload_and_track_ids=[],
|
upload_and_track_ids=[],
|
||||||
)
|
)
|
||||||
print("Commiting changes…")
|
print("Committing changes…")
|
||||||
TrackActor.objects.bulk_create(objs, batch_size=5000, ignore_conflicts=True)
|
TrackActor.objects.bulk_create(objs, batch_size=5000, ignore_conflicts=True)
|
||||||
|
|
|
@ -742,7 +742,7 @@ class Upload(models.Model):
|
||||||
default=empty_dict, max_length=50000, encoder=DjangoJSONEncoder, blank=True
|
default=empty_dict, max_length=50000, encoder=DjangoJSONEncoder, blank=True
|
||||||
)
|
)
|
||||||
import_date = models.DateTimeField(null=True, blank=True)
|
import_date = models.DateTimeField(null=True, blank=True)
|
||||||
# optionnal metadata provided during import
|
# optional metadata provided during import
|
||||||
import_metadata = JSONField(
|
import_metadata = JSONField(
|
||||||
default=empty_dict, max_length=50000, encoder=DjangoJSONEncoder, blank=True
|
default=empty_dict, max_length=50000, encoder=DjangoJSONEncoder, blank=True
|
||||||
)
|
)
|
||||||
|
@ -754,7 +754,7 @@ class Upload(models.Model):
|
||||||
# in the same import
|
# in the same import
|
||||||
import_reference = models.CharField(max_length=50, default=get_import_reference)
|
import_reference = models.CharField(max_length=50, default=get_import_reference)
|
||||||
|
|
||||||
# optionnal metadata about import results (error messages, etc.)
|
# optional metadata about import results (error messages, etc.)
|
||||||
import_details = JSONField(
|
import_details = JSONField(
|
||||||
default=empty_dict, max_length=50000, encoder=DjangoJSONEncoder, blank=True
|
default=empty_dict, max_length=50000, encoder=DjangoJSONEncoder, blank=True
|
||||||
)
|
)
|
||||||
|
|
|
@ -811,7 +811,7 @@ def albums_set_tags_from_tracks(ids=None, dry_run=False):
|
||||||
)
|
)
|
||||||
logger.info("Found automatic tags for %s albums…", len(data))
|
logger.info("Found automatic tags for %s albums…", len(data))
|
||||||
if dry_run:
|
if dry_run:
|
||||||
logger.info("Running in dry-run mode, not commiting")
|
logger.info("Running in dry-run mode, not committing")
|
||||||
return
|
return
|
||||||
|
|
||||||
tags_tasks.add_tags_batch(
|
tags_tasks.add_tags_batch(
|
||||||
|
@ -836,7 +836,7 @@ def artists_set_tags_from_tracks(ids=None, dry_run=False):
|
||||||
)
|
)
|
||||||
logger.info("Found automatic tags for %s artists…", len(data))
|
logger.info("Found automatic tags for %s artists…", len(data))
|
||||||
if dry_run:
|
if dry_run:
|
||||||
logger.info("Running in dry-run mode, not commiting")
|
logger.info("Running in dry-run mode, not committing")
|
||||||
return
|
return
|
||||||
|
|
||||||
tags_tasks.add_tags_batch(
|
tags_tasks.add_tags_batch(
|
||||||
|
|
|
@ -517,7 +517,7 @@ def should_transcode(upload, format, max_bitrate=None):
|
||||||
# upload should have a mimetype, otherwise we cannot transcode
|
# upload should have a mimetype, otherwise we cannot transcode
|
||||||
format_need_transcoding = False
|
format_need_transcoding = False
|
||||||
elif upload.mimetype == utils.EXTENSION_TO_MIMETYPE[format]:
|
elif upload.mimetype == utils.EXTENSION_TO_MIMETYPE[format]:
|
||||||
# requested format sould be different than upload mimetype, otherwise
|
# requested format should be different than upload mimetype, otherwise
|
||||||
# there is no need to transcode
|
# there is no need to transcode
|
||||||
format_need_transcoding = False
|
format_need_transcoding = False
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ class DeleteAccountMutationSerializer(mutations.MutationSerializer):
|
||||||
if not obj.is_local or not obj.user:
|
if not obj.is_local or not obj.user:
|
||||||
raise mutations.serializers.ValidationError("Cannot delete this account")
|
raise mutations.serializers.ValidationError("Cannot delete this account")
|
||||||
|
|
||||||
# delete oauth apps / reset all passwords immediatly
|
# delete oauth apps / reset all passwords immediately
|
||||||
obj.user.set_unusable_password()
|
obj.user.set_unusable_password()
|
||||||
obj.user.subsonic_api_token = None
|
obj.user.subsonic_api_token = None
|
||||||
# force logout
|
# force logout
|
||||||
|
|
|
@ -20,7 +20,7 @@ function usage_message()
|
||||||
echo -e "\thelp\t\tPrint this help"
|
echo -e "\thelp\t\tPrint this help"
|
||||||
echo -e "\n\tCommands that require superuser permission:"
|
echo -e "\n\tCommands that require superuser permission:"
|
||||||
echo -e "\tinstall\t\tInstall packages defined on ${OS_REQUIREMENTS_FILENAME} file. Note: This\n\t\t\t does not upgrade the packages already installed for new\n\t\t\t versions, even if new version is available in the repository."
|
echo -e "\tinstall\t\tInstall packages defined on ${OS_REQUIREMENTS_FILENAME} file. Note: This\n\t\t\t does not upgrade the packages already installed for new\n\t\t\t versions, even if new version is available in the repository."
|
||||||
echo -e "\tupgrade\t\tSame that install, but upgrate the already installed packages,\n\t\t\t if new version is available."
|
echo -e "\tupgrade\t\tSame that install, but upgrade the already installed packages,\n\t\t\t if new version is available."
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ if __name__ == "__main__":
|
||||||
# we're doing this here since otherwise, missing environment
|
# we're doing this here since otherwise, missing environment
|
||||||
# files in settings result in AttributeError being raised, generating
|
# files in settings result in AttributeError being raised, generating
|
||||||
# a cryptic django.core.exceptions.AppRegistryNotReady error.
|
# a cryptic django.core.exceptions.AppRegistryNotReady error.
|
||||||
# To prevent that, we explicitely load settings here before anything
|
# To prevent that, we explicitly load settings here before anything
|
||||||
# else, so we fail fast with a relevant error. See #140 for more details.
|
# else, so we fail fast with a relevant error. See #140 for more details.
|
||||||
django.setup()
|
django.setup()
|
||||||
|
|
||||||
|
|
|
@ -100,7 +100,7 @@ def local_cache():
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def factories(db):
|
def factories(db):
|
||||||
"""
|
"""
|
||||||
Returns a dictionnary containing all registered factories with keys such as
|
Returns a dictionary containing all registered factories with keys such as
|
||||||
users.User or music.Track
|
users.User or music.Track
|
||||||
"""
|
"""
|
||||||
from funkwhale_api import factories
|
from funkwhale_api import factories
|
||||||
|
@ -117,7 +117,7 @@ def factories(db):
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def nodb_factories():
|
def nodb_factories():
|
||||||
"""
|
"""
|
||||||
Returns a dictionnary containing all registered factories with a build strategy
|
Returns a dictionary containing all registered factories with a build strategy
|
||||||
that does not require access to the database
|
that does not require access to the database
|
||||||
"""
|
"""
|
||||||
from funkwhale_api import factories
|
from funkwhale_api import factories
|
||||||
|
|
|
@ -153,11 +153,11 @@ def test_import_track_with_different_artist_than_release(factories, mocker):
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"extention,mimetype", [("ogg", "audio/ogg"), ("mp3", "audio/mpeg")]
|
"extension,mimetype", [("ogg", "audio/ogg"), ("mp3", "audio/mpeg")]
|
||||||
)
|
)
|
||||||
def test_audio_track_mime_type(extention, mimetype, factories):
|
def test_audio_track_mime_type(extension, mimetype, factories):
|
||||||
|
|
||||||
name = ".".join(["test", extention])
|
name = ".".join(["test", extension])
|
||||||
path = os.path.join(DATA_DIR, name)
|
path = os.path.join(DATA_DIR, name)
|
||||||
upload = factories["music.Upload"](audio_file__from_path=path, mimetype=None)
|
upload = factories["music.Upload"](audio_file__from_path=path, mimetype=None)
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,7 @@ def test_can_use_radio_session_to_filter_choices(factories):
|
||||||
for i in range(10):
|
for i in range(10):
|
||||||
radio.pick(filter_playable=False)
|
radio.pick(filter_playable=False)
|
||||||
|
|
||||||
# ensure 10 differents tracks have been suggested
|
# ensure 10 different tracks have been suggested
|
||||||
tracks_id = [
|
tracks_id = [
|
||||||
session_track.track.pk for session_track in session.session_tracks.all()
|
session_track.track.pk for session_track in session.session_tracks.all()
|
||||||
]
|
]
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Fixed upload form VUE erros (#1738) (1738)
|
Fixed upload form VUE errors (#1738) (1738)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Allow arbritrary length names for artists, albums and tracks
|
Allow arbitrary length names for artists, albums and tracks
|
||||||
|
|
|
@ -16,7 +16,7 @@ curl -L -o /srv/funkwhale/docker-compose.yml "https://dev.funkwhale.audio/funkwh
|
||||||
Docker's resolver <https://docs.funkwhale.audio/admin/external-storages.html#no-resolver-found>`_, you can mount your
|
Docker's resolver <https://docs.funkwhale.audio/admin/external-storages.html#no-resolver-found>`_, you can mount your
|
||||||
custom nginx configuration into the container. Uncomment the commented volumes in the `nginx` section of your `docker-compose.yml`.
|
custom nginx configuration into the container. Uncomment the commented volumes in the `nginx` section of your `docker-compose.yml`.
|
||||||
Additionally you need to update the paths in `nginx/funkwhale.template`.
|
Additionally you need to update the paths in `nginx/funkwhale.template`.
|
||||||
Replace all occurances of `/funkwhale` by `/usr/share/nginx/html`.
|
Replace all occurrences of `/funkwhale` by `/usr/share/nginx/html`.
|
||||||
This loads the templates from your `nginx` folder and overrides the template files in the Docker container.
|
This loads the templates from your `nginx` folder and overrides the template files in the Docker container.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Fix conent form autofocus despite `autofocus` prop being set to `false` (#1924)
|
Fix content form autofocus despite `autofocus` prop being set to `false` (#1924)
|
||||||
|
|
|
@ -48,7 +48,7 @@ sudo ENV_FILE=/srv/funkwhale-demo/.env ./setup.sh
|
||||||
|
|
||||||
## Automate
|
## Automate
|
||||||
|
|
||||||
You'll probaby want to reset the demo every now and then. You can do that
|
You'll probably want to reset the demo every now and then. You can do that
|
||||||
using a cronjob:
|
using a cronjob:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -55,7 +55,7 @@ type: String
|
||||||
value: cn=admin,dc=domain,dc=com
|
value: cn=admin,dc=domain,dc=com
|
||||||
---
|
---
|
||||||
|
|
||||||
LDAP user {abbr}`DN (Distinguised Name)` to bind on so you can perform searches.
|
LDAP user {abbr}`DN (Distinguished Name)` to bind on so you can perform searches.
|
||||||
```
|
```
|
||||||
|
|
||||||
```{py:data} LDAP_BIND_PASSWORD
|
```{py:data} LDAP_BIND_PASSWORD
|
||||||
|
@ -64,7 +64,7 @@ type: String
|
||||||
value: bindpassword
|
value: bindpassword
|
||||||
---
|
---
|
||||||
|
|
||||||
LDAP user password for bind {abbr}`DN (Distinguised Name)`.
|
LDAP user password for bind {abbr}`DN (Distinguished Name)`.
|
||||||
```
|
```
|
||||||
|
|
||||||
```{py:data} LDAP_SEARCH_FILTER
|
```{py:data} LDAP_SEARCH_FILTER
|
||||||
|
@ -91,7 +91,7 @@ type: String
|
||||||
value: dc=domain,dc=com
|
value: dc=domain,dc=com
|
||||||
---
|
---
|
||||||
|
|
||||||
The LDAP search root {abbr}`DN (Distinguised Name)`. Supports several entries in a comma-delimited list.
|
The LDAP search root {abbr}`DN (Distinguished Name)`. Supports several entries in a comma-delimited list.
|
||||||
```
|
```
|
||||||
|
|
||||||
```{py:data} LDAP_USER_ATTR_MAP
|
```{py:data} LDAP_USER_ATTR_MAP
|
||||||
|
@ -126,7 +126,7 @@ type: String
|
||||||
value: ou=groups,dc=domain,dc=com
|
value: ou=groups,dc=domain,dc=com
|
||||||
---
|
---
|
||||||
|
|
||||||
The LDAP group search root {abbr}`DN (Distinguised Name)`. This needs to be set to `True` to enable group features.
|
The LDAP group search root {abbr}`DN (Distinguished Name)`. This needs to be set to `True` to enable group features.
|
||||||
```
|
```
|
||||||
|
|
||||||
```{py:data} LDAP_GROUP_FILTER
|
```{py:data} LDAP_GROUP_FILTER
|
||||||
|
|
|
@ -177,7 +177,7 @@ You need to initialize the postgres container on your {term}`destination server`
|
||||||
|
|
||||||
## 5. Check your DNS settings
|
## 5. Check your DNS settings
|
||||||
|
|
||||||
Before you start Funkwhale on your {term}`destination server`, check your DNS changes have propogated. Once your hostname is pointing to your {term}`destination server's <destination server>` IP address, proceed to the next step.
|
Before you start Funkwhale on your {term}`destination server`, check your DNS changes have propagated. Once your hostname is pointing to your {term}`destination server's <destination server>` IP address, proceed to the next step.
|
||||||
|
|
||||||
## 6. Start your new Funkwhale installation
|
## 6. Start your new Funkwhale installation
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ docker-compose run --rm api python manage.py create_library username1 --name="Li
|
||||||
Created library Library 1 for user username1 with UUID 436da05b-8cb1-4a4d-b870-4a3b235d8517
|
Created library Library 1 for user username1 with UUID 436da05b-8cb1-4a4d-b870-4a3b235d8517
|
||||||
```
|
```
|
||||||
|
|
||||||
### Create a new library wth no name or privacy level
|
### Create a new library with no name or privacy level
|
||||||
|
|
||||||
You can create a library using only a username. The script substitutes default values for the library name and privacy level.
|
You can create a library using only a username. The script substitutes default values for the library name and privacy level.
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ Actor:
|
||||||
fid:
|
fid:
|
||||||
type: string
|
type: string
|
||||||
format: uri
|
format: uri
|
||||||
description: "The actor Federation ID (unique accross federation)"
|
description: "The actor Federation ID (unique across federation)"
|
||||||
uuid:
|
uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
|
@ -131,7 +131,7 @@ BaseArtist:
|
||||||
fid:
|
fid:
|
||||||
type: string
|
type: string
|
||||||
format: uri
|
format: uri
|
||||||
description: "The artist Federation ID (unique accross federation)"
|
description: "The artist Federation ID (unique across federation)"
|
||||||
name:
|
name:
|
||||||
type: "string"
|
type: "string"
|
||||||
example: "System of a Down"
|
example: "System of a Down"
|
||||||
|
@ -140,7 +140,7 @@ BaseArtist:
|
||||||
format: "date-time"
|
format: "date-time"
|
||||||
is_local:
|
is_local:
|
||||||
type: "boolean"
|
type: "boolean"
|
||||||
description: "Indicates if the object was initally created locally or on another server"
|
description: "Indicates if the object was initially created locally or on another server"
|
||||||
|
|
||||||
Artist:
|
Artist:
|
||||||
type: "object"
|
type: "object"
|
||||||
|
@ -177,7 +177,7 @@ BaseAlbum:
|
||||||
fid:
|
fid:
|
||||||
type: string
|
type: string
|
||||||
format: uri
|
format: uri
|
||||||
description: "The album Federation ID (unique accross federation)"
|
description: "The album Federation ID (unique across federation)"
|
||||||
artist:
|
artist:
|
||||||
type: "integer"
|
type: "integer"
|
||||||
format: "int64"
|
format: "int64"
|
||||||
|
@ -198,7 +198,7 @@ BaseAlbum:
|
||||||
$ref: "#/Attachment"
|
$ref: "#/Attachment"
|
||||||
is_local:
|
is_local:
|
||||||
type: "boolean"
|
type: "boolean"
|
||||||
description: "Indicates if the object was initally created locally or on another server"
|
description: "Indicates if the object was initially created locally or on another server"
|
||||||
|
|
||||||
Album:
|
Album:
|
||||||
type: "object"
|
type: "object"
|
||||||
|
@ -332,7 +332,7 @@ Library:
|
||||||
fid:
|
fid:
|
||||||
type: string
|
type: string
|
||||||
format: uri
|
format: uri
|
||||||
description: "The library Federation ID (unique accross federation)"
|
description: "The library Federation ID (unique across federation)"
|
||||||
uuid:
|
uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
|
@ -427,7 +427,7 @@ BaseTrack:
|
||||||
fid:
|
fid:
|
||||||
type: string
|
type: string
|
||||||
format: uri
|
format: uri
|
||||||
description: "The track Federation ID (unique accross federation)"
|
description: "The track Federation ID (unique across federation)"
|
||||||
artist:
|
artist:
|
||||||
type: "integer"
|
type: "integer"
|
||||||
format: "int64"
|
format: "int64"
|
||||||
|
@ -462,7 +462,7 @@ BaseTrack:
|
||||||
example: "cc-by-nc-nd-4.0"
|
example: "cc-by-nc-nd-4.0"
|
||||||
is_local:
|
is_local:
|
||||||
type: "boolean"
|
type: "boolean"
|
||||||
description: "Indicates if the object was initally created locally or on another server"
|
description: "Indicates if the object was initially created locally or on another server"
|
||||||
|
|
||||||
AlbumTrack:
|
AlbumTrack:
|
||||||
type: "object"
|
type: "object"
|
||||||
|
@ -557,7 +557,7 @@ Upload:
|
||||||
description: "URL to stream the upload"
|
description: "URL to stream the upload"
|
||||||
is_local:
|
is_local:
|
||||||
type: "boolean"
|
type: "boolean"
|
||||||
description: "Indicates if the object was initally created locally or on another server"
|
description: "Indicates if the object was initially created locally or on another server"
|
||||||
|
|
||||||
OwnedLibraryCreate:
|
OwnedLibraryCreate:
|
||||||
type: "object"
|
type: "object"
|
||||||
|
|
|
@ -92,7 +92,7 @@ tags:
|
||||||
|
|
||||||
content_category:
|
content_category:
|
||||||
type: "string"
|
type: "string"
|
||||||
description: Used to what kind of content is published in a chanel
|
description: Used to what kind of content is published in a channel
|
||||||
enum:
|
enum:
|
||||||
- music
|
- music
|
||||||
- podcast
|
- podcast
|
||||||
|
|
|
@ -38,7 +38,7 @@ When creating an application you need to define the [**scopes**](https://www.rfc
|
||||||
- `read:<scope>`: grants read-only access to the resource
|
- `read:<scope>`: grants read-only access to the resource
|
||||||
- `write:<scope>`: grants write-only access to the resource
|
- `write:<scope>`: grants write-only access to the resource
|
||||||
|
|
||||||
`read` rights are required to fetch information using a `GET` request. All other actions (`POST`, `PATCH`, `PUT`, and `DELETE`) require `write` priviliges. You may give an application **both** `read` and `write` access to any scope.
|
`read` rights are required to fetch information using a `GET` request. All other actions (`POST`, `PATCH`, `PUT`, and `DELETE`) require `write` privileges. You may give an application **both** `read` and `write` access to any scope.
|
||||||
|
|
||||||
```{list-table}
|
```{list-table}
|
||||||
:header-rows: 1
|
:header-rows: 1
|
||||||
|
|
|
@ -39,7 +39,7 @@ If you want to make changes to the frontend, you can use Vite to run a developme
|
||||||
yarn i18n-compile
|
yarn i18n-compile
|
||||||
```
|
```
|
||||||
|
|
||||||
5. Launch the devlopment server:
|
5. Launch the development server:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
yarn dev
|
yarn dev
|
||||||
|
|
|
@ -6228,7 +6228,7 @@ msgid ""
|
||||||
"This new permission is helpful if you want to give upload/import rights "
|
"This new permission is helpful if you want to give upload/import rights "
|
||||||
"to some users, but don't want them to be able to manage the library as a "
|
"to some users, but don't want them to be able to manage the library as a "
|
||||||
"whole: although there are no controls yet for managing library in the "
|
"whole: although there are no controls yet for managing library in the "
|
||||||
"fron-end, subsequent release will introduce management interfaces for "
|
"front-end, subsequent release will introduce management interfaces for "
|
||||||
"artists, files, etc."
|
"artists, files, etc."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -6225,7 +6225,7 @@ msgid ""
|
||||||
"This new permission is helpful if you want to give upload/import rights "
|
"This new permission is helpful if you want to give upload/import rights "
|
||||||
"to some users, but don't want them to be able to manage the library as a "
|
"to some users, but don't want them to be able to manage the library as a "
|
||||||
"whole: although there are no controls yet for managing library in the "
|
"whole: although there are no controls yet for managing library in the "
|
||||||
"fron-end, subsequent release will introduce management interfaces for "
|
"front-end, subsequent release will introduce management interfaces for "
|
||||||
"artists, files, etc."
|
"artists, files, etc."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -6225,7 +6225,7 @@ msgid ""
|
||||||
"This new permission is helpful if you want to give upload/import rights "
|
"This new permission is helpful if you want to give upload/import rights "
|
||||||
"to some users, but don't want them to be able to manage the library as a "
|
"to some users, but don't want them to be able to manage the library as a "
|
||||||
"whole: although there are no controls yet for managing library in the "
|
"whole: although there are no controls yet for managing library in the "
|
||||||
"fron-end, subsequent release will introduce management interfaces for "
|
"front-end, subsequent release will introduce management interfaces for "
|
||||||
"artists, files, etc."
|
"artists, files, etc."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -5406,7 +5406,7 @@ msgid "New \"upload\" permission"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../../../CHANGELOG:3375
|
#: ../../../CHANGELOG:3375
|
||||||
msgid "This new permission is helpful if you want to give upload/import rights to some users, but don't want them to be able to manage the library as a whole: although there are no controls yet for managing library in the fron-end, subsequent release will introduce management interfaces for artists, files, etc."
|
msgid "This new permission is helpful if you want to give upload/import rights to some users, but don't want them to be able to manage the library as a whole: although there are no controls yet for managing library in the front-end, subsequent release will introduce management interfaces for artists, files, etc."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../../../CHANGELOG:3381
|
#: ../../../CHANGELOG:3381
|
||||||
|
|
|
@ -257,9 +257,9 @@ paths:
|
||||||
$ref: "#/components/responses/200"
|
$ref: "#/components/responses/200"
|
||||||
/api/v1/users/me/:
|
/api/v1/users/me/:
|
||||||
get:
|
get:
|
||||||
summary: Retrive profile information
|
summary: Retrieve profile information
|
||||||
description: |
|
description: |
|
||||||
Retrieve profile informations of the current user
|
Retrieve profile information of the current user
|
||||||
tags:
|
tags:
|
||||||
- "Auth and security"
|
- "Auth and security"
|
||||||
|
|
||||||
|
@ -322,7 +322,7 @@ paths:
|
||||||
|
|
||||||
/api/v1/rate-limit/:
|
/api/v1/rate-limit/:
|
||||||
get:
|
get:
|
||||||
summary: Retrive rate-limit information and current usage status
|
summary: Retrieve rate-limit information and current usage status
|
||||||
tags:
|
tags:
|
||||||
- "Auth and security"
|
- "Auth and security"
|
||||||
|
|
||||||
|
@ -1658,7 +1658,7 @@ paths:
|
||||||
type: boolean
|
type: boolean
|
||||||
default: false
|
default: false
|
||||||
description: |
|
description: |
|
||||||
Wether to raise an error when the same track is added
|
Whether to raise an error when the same track is added
|
||||||
multiple time in the playlist
|
multiple time in the playlist
|
||||||
responses:
|
responses:
|
||||||
201:
|
201:
|
||||||
|
|
|
@ -53,7 +53,7 @@ This guide shows you how to tag your content with MusicBrainz Picard.
|
||||||
Used if no license found in the `License` tag.
|
Used if no license found in the `License` tag.
|
||||||
- `CC-BY 3.0: http://creativecommons.org/licenses/cc-by/3.0/`
|
- `CC-BY 3.0: http://creativecommons.org/licenses/cc-by/3.0/`
|
||||||
* - `Pictures`
|
* - `Pictures`
|
||||||
- The first embeded picture found is used as the album cover.
|
- The first embedded picture found is used as the album cover.
|
||||||
-
|
-
|
||||||
* - `MusicBrainz Recording ID`
|
* - `MusicBrainz Recording ID`
|
||||||
- The MusicBrainz ID for the recording.
|
- The MusicBrainz ID for the recording.
|
||||||
|
|
|
@ -7930,7 +7930,7 @@ msgstr ""
|
||||||
|
|
||||||
#: src/components/auth/LoginForm.vue:49
|
#: src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -8502,7 +8502,7 @@ msgstr ""
|
||||||
|
|
||||||
#: front/src/components/auth/LoginForm.vue:49
|
#: front/src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -8221,7 +8221,7 @@ msgstr "Es tancarà la sessió d’aquest compte i hauràs d’iniciar sessió a
|
||||||
#: front/src/components/auth/LoginForm.vue:49
|
#: front/src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr "Es redirigirà a <strong>%{ url }</strong>"
|
msgstr "Es redirigirà a <strong>%{ url }</strong>"
|
||||||
|
|
||||||
|
|
|
@ -8391,7 +8391,7 @@ msgstr "Budete odhlášeni z tohoto sezení a musíte se přihlásit znovu"
|
||||||
#: front/src/components/auth/LoginForm.vue:49
|
#: front/src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr "Budete přesměrováni na <strong>%{ url }</strong>"
|
msgstr "Budete přesměrováni na <strong>%{ url }</strong>"
|
||||||
|
|
||||||
|
|
|
@ -8098,7 +8098,7 @@ msgstr "Du wirst von dieser Sitzung abgemeldet und du musst dich mit deinem neue
|
||||||
|
|
||||||
#: front/src/components/auth/LoginForm.vue:49
|
#: front/src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr "Du wirst zur Authentifizierung zu %{ url } weitergeleitet."
|
msgstr "Du wirst zur Authentifizierung zu %{ url } weitergeleitet."
|
||||||
|
|
||||||
|
|
|
@ -8105,7 +8105,7 @@ msgstr ""
|
||||||
|
|
||||||
#: front/src/components/auth/LoginForm.vue:49
|
#: front/src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -8254,7 +8254,7 @@ msgstr ""
|
||||||
|
|
||||||
#: front/src/components/auth/LoginForm.vue:49
|
#: front/src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr "You will be redirected to %{ domain } to authenticate."
|
msgstr "You will be redirected to %{ domain } to authenticate."
|
||||||
|
|
||||||
|
|
|
@ -8407,7 +8407,7 @@ msgstr "Vi estos elŝaluta el tiu seanco kaj devus ensaluti denove"
|
||||||
|
|
||||||
#: front/src/components/auth/LoginForm.vue:49
|
#: front/src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -8376,7 +8376,7 @@ msgstr "Se cerrará esta sesión y tendrás que reiniciar sesión con la nueva c
|
||||||
|
|
||||||
#: front/src/components/auth/LoginForm.vue:49
|
#: front/src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -8068,7 +8068,7 @@ msgstr "Saio hau amaituko zaizu eta berriarekin hasi beharko duzu"
|
||||||
|
|
||||||
#: front/src/components/auth/LoginForm.vue:49
|
#: front/src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr "%{ domain } domeinura birbideratua izango zara baimentzeko."
|
msgstr "%{ domain } domeinura birbideratua izango zara baimentzeko."
|
||||||
|
|
||||||
|
|
|
@ -8065,7 +8065,7 @@ msgstr ""
|
||||||
|
|
||||||
#: front/src/components/auth/LoginForm.vue:49
|
#: front/src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -8135,7 +8135,7 @@ msgstr "Vous allez être déconnecté⋅e de cette session et vous devrez vous c
|
||||||
|
|
||||||
#: front/src/components/auth/LoginForm.vue:49
|
#: front/src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr "Vous allez être redirigé·e vers %{ domain } pour vous authentifier."
|
msgstr "Vous allez être redirigé·e vers %{ domain } pour vous authentifier."
|
||||||
|
|
||||||
|
|
|
@ -7904,7 +7904,7 @@ msgid "You will be logged out from this session and have to log in with the new
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: front/src/components/auth/LoginForm.vue:49 src/components/auth/LoginForm.vue:2
|
#: front/src/components/auth/LoginForm.vue:49 src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -8098,7 +8098,7 @@ msgstr "Pecharemos esta sesión e deberás acceder co novo"
|
||||||
|
|
||||||
#: front/src/components/auth/LoginForm.vue:49
|
#: front/src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr "Ímoste redirixir a %{ domain } para autenticarte."
|
msgstr "Ímoste redirixir a %{ domain } para autenticarte."
|
||||||
|
|
||||||
|
|
|
@ -8119,7 +8119,7 @@ msgstr ""
|
||||||
|
|
||||||
#: front/src/components/auth/LoginForm.vue:49
|
#: front/src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -7903,7 +7903,7 @@ msgid "You will be logged out from this session and have to log in with the new
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: front/src/components/auth/LoginForm.vue:49 src/components/auth/LoginForm.vue:2
|
#: front/src/components/auth/LoginForm.vue:49 src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -8102,7 +8102,7 @@ msgstr "Sarai disconnesso da questa sessione e dovrai accedere con una nuova"
|
||||||
|
|
||||||
#: front/src/components/auth/LoginForm.vue:49
|
#: front/src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr "Sarai reindirizzato su %{ domain } per autenticarti."
|
msgstr "Sarai reindirizzato su %{ domain } per autenticarti."
|
||||||
|
|
||||||
|
|
|
@ -8075,7 +8075,7 @@ msgstr "このセッションからログアウトされ、新しくログイン
|
||||||
|
|
||||||
#: front/src/components/auth/LoginForm.vue:49
|
#: front/src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr "認証のために%{ domain }にリダイレクトされます。"
|
msgstr "認証のために%{ domain }にリダイレクトされます。"
|
||||||
|
|
||||||
|
|
|
@ -8144,7 +8144,7 @@ msgstr ""
|
||||||
|
|
||||||
#: front/src/components/auth/LoginForm.vue:49
|
#: front/src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -8041,7 +8041,7 @@ msgstr ""
|
||||||
|
|
||||||
#: front/src/components/auth/LoginForm.vue:49
|
#: front/src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -8094,7 +8094,7 @@ msgstr ""
|
||||||
|
|
||||||
#: front/src/components/auth/LoginForm.vue:49
|
#: front/src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -8565,7 +8565,7 @@ msgstr "Du vil bli logget ut av denne økta, og må logge inn i den nye"
|
||||||
|
|
||||||
#: front/src/components/auth/LoginForm.vue:49
|
#: front/src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -8217,7 +8217,7 @@ msgstr "Je wordt uitgelogd uit deze sessie moet inloggen op de nieuwe"
|
||||||
|
|
||||||
#: front/src/components/auth/LoginForm.vue:49
|
#: front/src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr "Je wordt doorgestuurd naar %{ domain } om te authenticeren."
|
msgstr "Je wordt doorgestuurd naar %{ domain } om te authenticeren."
|
||||||
|
|
||||||
|
|
|
@ -8060,7 +8060,7 @@ msgstr ""
|
||||||
|
|
||||||
#: front/src/components/auth/LoginForm.vue:49
|
#: front/src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -8100,7 +8100,7 @@ msgstr "Sètz per èsser desconnectat d’aquesta session e vos caldrà vos conn
|
||||||
|
|
||||||
#: front/src/components/auth/LoginForm.vue:49
|
#: front/src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr "Seretz mandat a <strong>%{ url }</strong>."
|
msgstr "Seretz mandat a <strong>%{ url }</strong>."
|
||||||
|
|
||||||
|
|
|
@ -8098,7 +8098,7 @@ msgstr "Zostaniesz wylogowany i będziesz musiał zalogować się nowym hasłem"
|
||||||
|
|
||||||
#: front/src/components/auth/LoginForm.vue:49
|
#: front/src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr "Zostaniesz przekierowany do %{ domain } w celu uwierzytelnienia."
|
msgstr "Zostaniesz przekierowany do %{ domain } w celu uwierzytelnienia."
|
||||||
|
|
||||||
|
|
|
@ -8213,7 +8213,7 @@ msgstr "Você sairá desta conta e precisará entrar novamente"
|
||||||
#: front/src/components/auth/LoginForm.vue:49
|
#: front/src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr "Você será redirecionado para <strong>%{ url }</strong>"
|
msgstr "Você será redirecionado para <strong>%{ url }</strong>"
|
||||||
|
|
||||||
|
|
|
@ -8411,7 +8411,7 @@ msgstr "Você será desconectado desta sessão e precisará fazer login com o no
|
||||||
|
|
||||||
#: front/src/components/auth/LoginForm.vue:49
|
#: front/src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -8097,7 +8097,7 @@ msgstr "Вы будете отключены от этого сеанса и В
|
||||||
|
|
||||||
#: front/src/components/auth/LoginForm.vue:49
|
#: front/src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr "Вы будете перенаправлены на %{ domain } для входа."
|
msgstr "Вы будете перенаправлены на %{ domain } для входа."
|
||||||
|
|
||||||
|
|
|
@ -8060,7 +8060,7 @@ msgstr ""
|
||||||
|
|
||||||
#: front/src/components/auth/LoginForm.vue:49
|
#: front/src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -8749,7 +8749,7 @@ msgstr "Du kommer att loggas ut från den här sessionen och måste logga in med
|
||||||
|
|
||||||
#: front/src/components/auth/LoginForm.vue:49
|
#: front/src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -7904,7 +7904,7 @@ msgid "You will be logged out from this session and have to log in with the new
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: front/src/components/auth/LoginForm.vue:49 src/components/auth/LoginForm.vue:2
|
#: front/src/components/auth/LoginForm.vue:49 src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -8040,7 +8040,7 @@ msgstr "您将立刻被登出,需要重新登录"
|
||||||
|
|
||||||
#: front/src/components/auth/LoginForm.vue:49
|
#: front/src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr "您将会被跳转到 %{ domain } 以授权登录。"
|
msgstr "您将会被跳转到 %{ domain } 以授权登录。"
|
||||||
|
|
||||||
|
|
|
@ -8063,7 +8063,7 @@ msgstr ""
|
||||||
|
|
||||||
#: front/src/components/auth/LoginForm.vue:49
|
#: front/src/components/auth/LoginForm.vue:49
|
||||||
#: src/components/auth/LoginForm.vue:2
|
#: src/components/auth/LoginForm.vue:2
|
||||||
msgctxt "Contant/Auth/Paragraph"
|
msgctxt "Content/Auth/Paragraph"
|
||||||
msgid "You will be redirected to %{ domain } to authenticate."
|
msgid "You will be redirected to %{ domain } to authenticate."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@
|
||||||
// NOTE: Filter out repeating and unplayable media types
|
// NOTE: Filter out repeating and unplayable media types
|
||||||
.filter(({ mimetype }, index, array) => array.findIndex((upload) => upload.mimetype === mimetype) === index)
|
.filter(({ mimetype }, index, array) => array.findIndex((upload) => upload.mimetype === mimetype) === index)
|
||||||
.filter(({ mimetype }) => ['probably', 'maybe'].includes(audio.element?.canPlayType(mimetype)))
|
.filter(({ mimetype }) => ['probably', 'maybe'].includes(audio.element?.canPlayType(mimetype)))
|
||||||
// NOTE: For backwards compatibilty, prepend the baseUrl if listen_url starts with a slash
|
// NOTE: For backwards compatibility, prepend the baseUrl if listen_url starts with a slash
|
||||||
.map(source => ({
|
.map(source => ({
|
||||||
...source,
|
...source,
|
||||||
listen_url: source.listen_url[0] === '/'
|
listen_url: source.listen_url[0] === '/'
|
||||||
|
|
|
@ -217,7 +217,7 @@ Given the previous config, the following style sheet:
|
||||||
|
|
||||||
.. code-block:: css
|
.. code-block:: css
|
||||||
|
|
||||||
.unsed.variation {
|
.unused.variation {
|
||||||
color: yellow;
|
color: yellow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -837,7 +837,7 @@ def set_vars(component_name, rules):
|
||||||
|
|
||||||
for rule in rules:
|
for rule in rules:
|
||||||
if rule["lines"][0].startswith("@media"):
|
if rule["lines"][0].startswith("@media"):
|
||||||
# manual handling of media queries, becaues our parser is really
|
# manual handling of media queries, because our parser is really
|
||||||
# simplistic
|
# simplistic
|
||||||
internal_rules = rules_from_media_query(rule)
|
internal_rules = rules_from_media_query(rule)
|
||||||
internal_rules = set_vars(component_name, internal_rules)
|
internal_rules = set_vars(component_name, internal_rules)
|
||||||
|
|
|
@ -103,7 +103,7 @@ onMounted(() => {
|
||||||
|
|
||||||
const openMenu = () => {
|
const openMenu = () => {
|
||||||
// little magic to ensure the menu is always visible in the viewport
|
// little magic to ensure the menu is always visible in the viewport
|
||||||
// By default, try to diplay it on the right if there is enough room
|
// By default, try to display it on the right if there is enough room
|
||||||
const menu = dropdown.value.find('.menu')
|
const menu = dropdown.value.find('.menu')
|
||||||
const viewportOffset = menu.get(0)?.getBoundingClientRect() ?? { right: 0, left: 0 }
|
const viewportOffset = menu.get(0)?.getBoundingClientRect() ?? { right: 0, left: 0 }
|
||||||
const viewportWidth = document.documentElement.clientWidth
|
const viewportWidth = document.documentElement.clientWidth
|
||||||
|
|
|
@ -115,7 +115,7 @@ const fetchData = async () => {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get('tracks/', { params })
|
const response = await axios.get('tracks/', { params })
|
||||||
|
|
||||||
// TODO (wvffle): Fetch continously?
|
// TODO (wvffle): Fetch continuously?
|
||||||
fetchDataUrl.value = response.data.next
|
fetchDataUrl.value = response.data.next
|
||||||
additionalTracks.value = response.data.results
|
additionalTracks.value = response.data.results
|
||||||
totalTracks.value = response.data.count
|
totalTracks.value = response.data.count
|
||||||
|
|
|
@ -137,7 +137,7 @@ const submit = async () => {
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<p>
|
<p>
|
||||||
<translate
|
<translate
|
||||||
translate-context="Contant/Auth/Paragraph"
|
translate-context="Content/Auth/Paragraph"
|
||||||
:translate-params="{domain: $store.getters['instance/domain']}"
|
:translate-params="{domain: $store.getters['instance/domain']}"
|
||||||
>
|
>
|
||||||
You will be redirected to %{ domain } to authenticate.
|
You will be redirected to %{ domain } to authenticate.
|
||||||
|
|
|
@ -961,7 +961,7 @@ fetchOwnedApps()
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
<translate translate-context="Popup/Settings/Paragraph">
|
<translate translate-context="Popup/Settings/Paragraph">
|
||||||
This is irreversible and will permanently remove your data from our servers. You will we immediatly logged out.
|
This is irreversible and will permanently remove your data from our servers. You will we immediately logged out.
|
||||||
</translate>
|
</translate>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -98,7 +98,7 @@ const toggleCheck = (event: MouseEvent, id: string, index: number) => {
|
||||||
selectAll.value = false
|
selectAll.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add inbetween ids to the list of affected ids
|
// Add in between ids to the list of affected ids
|
||||||
if (event.shiftKey && lastCheckedIndex.value !== -1) {
|
if (event.shiftKey && lastCheckedIndex.value !== -1) {
|
||||||
const boundaries = [index, lastCheckedIndex.value].sort((a, b) => a - b)
|
const boundaries = [index, lastCheckedIndex.value].sort((a, b) => a - b)
|
||||||
for (const object of props.objectsData.results.slice(boundaries[0], boundaries[1] + 1)) {
|
for (const object of props.objectsData.results.slice(boundaries[0], boundaries[1] + 1)) {
|
||||||
|
|
|
@ -67,7 +67,7 @@ const targets = reactive({
|
||||||
|
|
||||||
const fetchTargets = async () => {
|
const fetchTargets = async () => {
|
||||||
// we request target data via the API so we can display previous state
|
// we request target data via the API so we can display previous state
|
||||||
// additionnal data next to the edit card
|
// additional data next to the edit card
|
||||||
type Config = { url: string, ids: number[] }
|
type Config = { url: string, ids: number[] }
|
||||||
const typesAndIds: Record<Targets, Config> = {
|
const typesAndIds: Record<Targets, Config> = {
|
||||||
artist: { url: 'artists/', ids: [] },
|
artist: { url: 'artists/', ids: [] },
|
||||||
|
|
|
@ -43,7 +43,7 @@ export const usePlayer = createGlobalState(() => {
|
||||||
sound.pause()
|
sound.pause()
|
||||||
})
|
})
|
||||||
|
|
||||||
// Create first track when we initalize the page
|
// Create first track when we initialize the page
|
||||||
// NOTE: We want to have it called only once, hence we're using createGlobalState
|
// NOTE: We want to have it called only once, hence we're using createGlobalState
|
||||||
const initializeFirstTrack = createGlobalState(() => tryOnMounted(() => {
|
const initializeFirstTrack = createGlobalState(() => tryOnMounted(() => {
|
||||||
const { initialize } = useTracks()
|
const { initialize } = useTracks()
|
||||||
|
|
|
@ -16,7 +16,7 @@ async function useErrorHandler (error: Error | BackendError, eventId?: string):
|
||||||
? 'Unexpected API error'
|
? 'Unexpected API error'
|
||||||
: 'Unexpected error'
|
: 'Unexpected error'
|
||||||
|
|
||||||
let content = $pgettext('App/Message/Paragraph', 'An unexpected error occured.')
|
let content = $pgettext('App/Message/Paragraph', 'An unexpected error occurred.')
|
||||||
|
|
||||||
if ('backendErrors' in error) {
|
if ('backendErrors' in error) {
|
||||||
logger.error(title, error, error.backendErrors)
|
logger.error(title, error, error.backendErrors)
|
||||||
|
@ -35,7 +35,7 @@ async function useErrorHandler (error: Error | BackendError, eventId?: string):
|
||||||
|
|
||||||
const { get } = useCookies()
|
const { get } = useCookies()
|
||||||
if (get(COOKIE) === 'yes') {
|
if (get(COOKIE) === 'yes') {
|
||||||
content = $pgettext('App/Message/Paragraph', 'An unexpected error occured. <br><sub>To help us understand why it happened, please attach a detailed description of what you did that has triggered the error.</sub>')
|
content = $pgettext('App/Message/Paragraph', 'An unexpected error occurred. <br><sub>To help us understand why it happened, please attach a detailed description of what you did that has triggered the error.</sub>')
|
||||||
const user = store.state.auth.authenticated
|
const user = store.state.auth.authenticated
|
||||||
? {
|
? {
|
||||||
name: store.state.auth.username,
|
name: store.state.auth.username,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@use "./_vars" as *;
|
@use "./_vars" as *;
|
||||||
|
|
||||||
// not in vars because not meant to be overriden
|
// not in vars because not meant to be overridden
|
||||||
$desktop-sidebar-width: 275px;
|
$desktop-sidebar-width: 275px;
|
||||||
$widedesktop-sidebar-width: 275px;
|
$widedesktop-sidebar-width: 275px;
|
||||||
$bottom-player-height: 4rem;
|
$bottom-player-height: 4rem;
|
||||||
|
|
|
@ -85,7 +85,7 @@ const updateObj = async (attr: string) => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await axios.patch(`manage/library/libraries/${props.id}/`, params)
|
await axios.patch(`manage/library/libraries/${props.id}/`, params)
|
||||||
logger.info(`${attr} was updated succcessfully to ${params[attr]}`)
|
logger.info(`${attr} was updated successfully to ${params[attr]}`)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`Error while setting ${attr} to ${params[attr]}`, error)
|
logger.error(`Error while setting ${attr} to ${params[attr]}`, error)
|
||||||
// TODO (wvffle): Use error handler with custom msg
|
// TODO (wvffle): Use error handler with custom msg
|
||||||
|
|
|
@ -127,7 +127,7 @@ const updateUser = async (attr: string, toNull = false) => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await axios.patch(`manage/users/users/${object.value.user.id}/`, params)
|
await axios.patch(`manage/users/users/${object.value.user.id}/`, params)
|
||||||
logger.info(`${attr} was updated succcessfully to ${newValue}`)
|
logger.info(`${attr} was updated successfully to ${newValue}`)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`Error while setting ${attr} to ${newValue}`, error)
|
logger.error(`Error while setting ${attr} to ${newValue}`, error)
|
||||||
// TODO: Use error handler
|
// TODO: Use error handler
|
||||||
|
|
|
@ -65,3 +65,7 @@ force-exclude = "(api/.*/migrations/.*)" # pre-commit pass files as args
|
||||||
profile = "black"
|
profile = "black"
|
||||||
extend_skip_glob = ["api/*/migrations/*"]
|
extend_skip_glob = ["api/*/migrations/*"]
|
||||||
known_first_party = ["funkwhale_api", "config"]
|
known_first_party = ["funkwhale_api", "config"]
|
||||||
|
|
||||||
|
[tool.codespell]
|
||||||
|
ignore-words = ".codespellignore"
|
||||||
|
skip = "*.po,*.pot,*.lock,api/funkwhale_api/common/locales.py"
|
||||||
|
|
|
@ -30,7 +30,7 @@ if __name__ == "__main__":
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description="""
|
description="""
|
||||||
Exit with code 0 if the given version matches the latest one
|
Exit with code 0 if the given version matches the latest one
|
||||||
fron the list of releases found in releases_json. Primary use
|
from the list of releases found in releases_json. Primary use
|
||||||
is to check whether the current version can be safely pushed
|
is to check whether the current version can be safely pushed
|
||||||
as the latest one on the docker Hub.
|
as the latest one on the docker Hub.
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue