Commits (9)
......@@ -184,7 +184,9 @@ test_api:
when: always
reports:
junit: api/report.xml
cobertura: api/coverage.xml
coverage_report:
coverage_format: cobertura
path: api/coverage.xml
test_front:
interruptible: true
......
......@@ -670,17 +670,31 @@ class SubsonicViewSet(viewsets.GenericViewSet):
def create_playlist(self, request, *args, **kwargs):
data = request.GET or request.POST
name = data.get("name", "")
if not name:
createPlaylist = True
playListId = data.get("playlistId", "")
if name and playListId:
return response.Response(
{
"error": {
"code": 10,
"message": "Playlist ID or name must be specified.",
"message": "You can only supply either a playlistId or name, not both.",
}
}
)
playlist = request.user.playlists.create(name=name)
if playListId:
playlist = request.user.playlists.get(pk=playListId)
createPlaylist = False
if not name and not playlist:
return response.Response(
{
"error": {
"code": 10,
"message": "A valid playlist ID or name must be specified.",
}
}
)
if createPlaylist:
playlist = request.user.playlists.create(name=name)
ids = []
for i in data.getlist("songId"):
try:
......
......@@ -708,6 +708,26 @@ def test_create_playlist(f, db, logged_in_api_client, factories):
}
@pytest.mark.parametrize("f", ["json"])
def test_create_playlist_with_update(f, db, logged_in_api_client, factories):
url = reverse("api:subsonic-create_playlist")
assert url.endswith("createPlaylist") is True
playlist = factories["playlists.Playlist"](user=logged_in_api_client.user)
factories["playlists.PlaylistTrack"](index=0, playlist=playlist)
track1 = factories["music.Track"]()
track2 = factories["music.Track"]()
response = logged_in_api_client.get(
url, {"f": f, "playlistId": playlist.pk, "songId": [track1.pk, track2.pk]}
)
playlist.refresh_from_db()
assert response.status_code == 200
assert playlist.playlist_tracks.count() == 3
qs = playlist.__class__.objects.with_tracks_count()
assert response.data == {
"playlist": serializers.get_playlist_detail_data(qs.first())
}
@pytest.mark.parametrize("f", ["json"])
def test_get_music_folders(f, db, logged_in_api_client, factories):
url = reverse("api:subsonic-get_music_folders")
......
Fixes subsonic createPlaylist's endpoint doesn't update playlist (#1263) (1263)
Fix login form focusing reset password link instead of next input (#1373)
Channel overview was displaying foreign tracks (#1773) (1773)
Fixed missing album contextual menu (#1791) (1791)
Replaced references to #funkwhale-troubleshooting with #funkwhale-support
......@@ -30,7 +30,7 @@ issue tracker.
.. note::
To get detailed log messages, set the environment variable ``LOGLEVEL=debug``.
To get detailed log messages, set the environment variable ``LOGLEVEL=debug``.
If you are using the docker setup you can configure this in the ``.env`` file.
Backend issues
......@@ -141,7 +141,7 @@ Report an issue or get help
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Well be more than happy to help you to debug installation and configuration issues. The main channel
for receiving support about your Funkwhale installation is the `#funkwhale-troubleshooting:matrix.org <https://matrix.to/#/#funkwhale-troubleshooting:matrix.org>`_ Matrix channel.
for receiving support about your Funkwhale installation is the `#funkwhale-support:matrix.org <https://matrix.to/#/#funkwhale-support:matrix.org>`_ Matrix channel.
Before asking for help, we'd really appreciate if you took the time to go through this document and try to diagnose the problem yourself. But if you don't find
anything relevant or don't have the time, we'll be there for you!
......
......@@ -8,7 +8,7 @@ python-versions = "*"
[[package]]
name = "asgiref"
version = "3.5.1"
version = "3.5.2"
description = "ASGI specs, helper code, and adapters"
category = "main"
optional = false
......@@ -30,11 +30,11 @@ pytz = ">=2015.7"
[[package]]
name = "certifi"
version = "2021.10.8"
version = "2022.5.18.1"
description = "Python package for providing Mozilla's CA Bundle."
category = "main"
optional = false
python-versions = "*"
python-versions = ">=3.6"
[[package]]
name = "charset-normalizer"
......@@ -57,7 +57,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[[package]]
name = "django"
version = "4.0.4"
version = "4.0.5"
description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design."
category = "main"
optional = false
......@@ -220,7 +220,7 @@ python-versions = ">=3.6"
[[package]]
name = "pyparsing"
version = "3.0.8"
version = "3.0.9"
description = "pyparsing module - Classes and methods to define and execute parsing grammars"
category = "main"
optional = false
......@@ -247,20 +247,20 @@ python-versions = ">=3.6"
[[package]]
name = "requests"
version = "2.27.1"
version = "2.28.0"
description = "Python HTTP for Humans."
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
python-versions = ">=3.7, <4"
[package.dependencies]
certifi = ">=2017.4.17"
charset-normalizer = {version = ">=2.0.0,<2.1.0", markers = "python_version >= \"3\""}
idna = {version = ">=2.5,<4", markers = "python_version >= \"3\""}
charset-normalizer = ">=2.0.0,<2.1.0"
idna = ">=2.5,<4"
urllib3 = ">=1.21.1,<1.27"
[package.extras]
socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"]
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"]
[[package]]
......@@ -457,7 +457,7 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
[metadata]
lock-version = "1.1"
python-versions = "^3.10"
content-hash = "1253741b33c5dbaecb1434b76c232f33a932685d71e48d4f18e713b688b946ba"
content-hash = "4d911e1b8540d66be185320c0727c43e8e4178e75bbbef631fc691841797adbe"
[metadata.files]
alabaster = [
......@@ -465,16 +465,16 @@ alabaster = [
{file = "alabaster-0.7.12.tar.gz", hash = "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"},
]
asgiref = [
{file = "asgiref-3.5.1-py3-none-any.whl", hash = "sha256:45a429524fba18aba9d512498b19d220c4d628e75b40cf5c627524dbaebc5cc1"},
{file = "asgiref-3.5.1.tar.gz", hash = "sha256:fddeea3c53fa99d0cdb613c3941cc6e52d822491fc2753fba25768fb5bf4e865"},
{file = "asgiref-3.5.2-py3-none-any.whl", hash = "sha256:1d2880b792ae8757289136f1db2b7b99100ce959b2aa57fd69dab783d05afac4"},
{file = "asgiref-3.5.2.tar.gz", hash = "sha256:4a29362a6acebe09bf1d6640db38c1dc3d9217c68e6f9f6204d72667fc19a424"},
]
babel = [
{file = "Babel-2.10.1-py3-none-any.whl", hash = "sha256:3f349e85ad3154559ac4930c3918247d319f21910d5ce4b25d439ed8693b98d2"},
{file = "Babel-2.10.1.tar.gz", hash = "sha256:98aeaca086133efb3e1e2aad0396987490c8425929ddbcfe0550184fdc54cd13"},
]
certifi = [
{file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"},
{file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"},
{file = "certifi-2022.5.18.1-py3-none-any.whl", hash = "sha256:f1d53542ee8cbedbe2118b5686372fb33c297fcd6379b050cca0ef13a597382a"},
{file = "certifi-2022.5.18.1.tar.gz", hash = "sha256:9c5705e395cd70084351dd8ad5c41e65655e08ce46f2ec9cf6c2c08390f71eb7"},
]
charset-normalizer = [
{file = "charset-normalizer-2.0.12.tar.gz", hash = "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597"},
......@@ -485,8 +485,8 @@ colorama = [
{file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
]
django = [
{file = "Django-4.0.4-py3-none-any.whl", hash = "sha256:07c8638e7a7f548dc0acaaa7825d84b7bd42b10e8d22268b3d572946f1e9b687"},
{file = "Django-4.0.4.tar.gz", hash = "sha256:4e8177858524417563cc0430f29ea249946d831eacb0068a1455686587df40b5"},
{file = "Django-4.0.5-py3-none-any.whl", hash = "sha256:502ae42b6ab1b612c933fb50d5ff850facf858a4c212f76946ecd8ea5b3bf2d9"},
{file = "Django-4.0.5.tar.gz", hash = "sha256:f7431a5de7277966f3785557c3928433347d998c1e6459324501378a291e5aab"},
]
django-environ = [
{file = "django-environ-0.8.1.tar.gz", hash = "sha256:6f0bc902b43891656b20486938cba0861dc62892784a44919170719572a534cb"},
......@@ -575,8 +575,8 @@ pygments = [
{file = "Pygments-2.12.0.tar.gz", hash = "sha256:5eb116118f9612ff1ee89ac96437bb6b49e8f04d8a13b514ba26f620208e26eb"},
]
pyparsing = [
{file = "pyparsing-3.0.8-py3-none-any.whl", hash = "sha256:ef7b523f6356f763771559412c0d7134753f037822dad1b16945b7b846f7ad06"},
{file = "pyparsing-3.0.8.tar.gz", hash = "sha256:7bf433498c016c4314268d95df76c81b842a4cb2b276fa3312cfb1e1d85f6954"},
{file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"},
{file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"},
]
pytz = [
{file = "pytz-2022.1-py2.py3-none-any.whl", hash = "sha256:e68985985296d9a66a881eb3193b0906246245294a881e7c8afe623866ac6a5c"},
......@@ -618,8 +618,8 @@ pyyaml = [
{file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"},
]
requests = [
{file = "requests-2.27.1-py2.py3-none-any.whl", hash = "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"},
{file = "requests-2.27.1.tar.gz", hash = "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61"},
{file = "requests-2.28.0-py3-none-any.whl", hash = "sha256:bc7861137fbce630f17b03d3ad02ad0bf978c844f3536d0edda6499dafce2b6f"},
{file = "requests-2.28.0.tar.gz", hash = "sha256:d568723a7ebd25875d8d1eaf5dfa068cd2fc8194b2e483d7b1f7c81918dbec6b"},
]
snowballstemmer = [
{file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"},
......
......@@ -10,7 +10,7 @@ python = "^3.10"
Sphinx = "4.4.0"
sphinx-rtd-theme = "1.0.0"
django-environ = "0.8.1"
Django = "==4.0.4"
Django = "==4.0.5"
myst-parser = "==0.17.2"
sphinx-panels = "0.6.0"
sphinx-multiversion = "0.2.4"
......
......@@ -34,7 +34,7 @@
"text-clipper": "1.3.0",
"vue": "2.6.14",
"vue-gettext": "2.1.12",
"vue-lazyload": "1.3.3",
"vue-lazyload": "1.3.4",
"vue-plyr": "5.1.3",
"vue-router": "3.0.7",
"vue-upload-component": "2.8.22",
......
......@@ -36,6 +36,7 @@
:total="count"
:page="page"
:paginate-by="limit"
:filters="filters"
@page-changed="updatePage"
/>
<template v-if="!isLoading && objects.length === 0">
......
......@@ -54,7 +54,10 @@
<div class="field">
<label for="password-field">
<translate translate-context="*/*/*">Password</translate> |
<router-link :to="{name: 'auth.password-reset', query: {email: credentials.username}}">
<router-link
tabindex="1"
:to="{name: 'auth.password-reset', query: {email: credentials.username}}"
>
<translate translate-context="*/Login/*/Verb">Reset your password</translate>
</router-link>
</label>
......
......@@ -77,7 +77,7 @@
{{ labels.forum }}
</a>
<a
href="https://matrix.to/#/#funkwhale-troubleshooting:matrix.org"
href="https://matrix.to/#/#funkwhale-support:matrix.org"
class="item"
target="_blank"
>
......
......@@ -292,7 +292,7 @@ export default {
return this.object.tracks_count
},
isChannel () {
return this.object.artist.channel !== null
return !!this.object.artist.channel
},
isSerie () {
return this.object.artist.content_category === 'podcast'
......
This source diff could not be displayed because it is too large. You can view the blob instead.