From 055ae44aef1199f4babdea82ba60c43c0cfdb701 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Schieli?= Date: Sun, 11 Oct 2020 16:14:58 +0200 Subject: [PATCH 1/3] Allow genre tags to be updated when rescanning files in-place --- api/funkwhale_api/music/tasks.py | 2 ++ api/tests/music/test_tasks.py | 4 ++++ changes/changelog.d/1246.enhancement | 1 + docs/admin/importing-music.rst | 1 + 4 files changed, 8 insertions(+) create mode 100644 changes/changelog.d/1246.enhancement diff --git a/api/funkwhale_api/music/tasks.py b/api/funkwhale_api/music/tasks.py index fa8e69591..b01f68e5f 100644 --- a/api/funkwhale_api/music/tasks.py +++ b/api/funkwhale_api/music/tasks.py @@ -937,6 +937,8 @@ def update_track_metadata(audio_metadata, track): if obj_updated_fields: obj.save(update_fields=obj_updated_fields) + tags_models.set_tags(track, *new_data.get("tags", [])) + if track.album and "album" in new_data and new_data["album"].get("cover_data"): common_utils.attach_file( track.album, "attachment_cover", new_data["album"].get("cover_data") diff --git a/api/tests/music/test_tasks.py b/api/tests/music/test_tasks.py index 573f04f1f..414bf95e7 100644 --- a/api/tests/music/test_tasks.py +++ b/api/tests/music/test_tasks.py @@ -1364,6 +1364,7 @@ def test_update_track_metadata(factories): "license": "Dummy license: http://creativecommons.org/licenses/by-sa/4.0/", "copyright": "Someone", "comment": "hello there", + "genre": "classical", } tasks.update_track_metadata(metadata.FakeMetadata(data), track) @@ -1382,6 +1383,9 @@ def test_update_track_metadata(factories): assert str(track.artist.mbid) == data["musicbrainz_artistid"] assert track.album.artist.name == "Edvard Grieg" assert str(track.album.artist.mbid) == "013c8e5b-d72a-4cd3-8dee-6c64d6125823" + assert sorted(track.tagged_items.values_list("tag__name", flat=True)) == [ + "classical" + ] def test_fs_import_not_pending(factories): diff --git a/changes/changelog.d/1246.enhancement b/changes/changelog.d/1246.enhancement new file mode 100644 index 000000000..10edbfb23 --- /dev/null +++ b/changes/changelog.d/1246.enhancement @@ -0,0 +1 @@ +Allow genre tags to be updated when rescanning files in-place (#1246) diff --git a/docs/admin/importing-music.rst b/docs/admin/importing-music.rst index 4cd71c2f9..f75a6133e 100644 --- a/docs/admin/importing-music.rst +++ b/docs/admin/importing-music.rst @@ -145,6 +145,7 @@ Funkwhale will pick up the new title. The following fields can be updated this w - Track title - Track position and disc number - Track license and copyright +- Track genre - Album cover - Album title - Album mbid From 7ee8e02b297e5cfa36a93a1d4378d2be1e5243e3 Mon Sep 17 00:00:00 2001 From: Kuba Orlik Date: Thu, 22 Oct 2020 15:06:28 +0200 Subject: [PATCH 2/3] Fix feed formatting so it passes w3c validation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Feeds generated by Funkwhale do not pass validation with the [w3c validator](https://validator.w3.org/feed/check.cgi?url=https%3A%2F%2Fpodcast.midline.pl%2Fapi%2Fv1%2Fchannels%2FMidline%2Frss). This commit addresses the problems identified during validation: 1. The `isPermalink` is not recognized -> changed it to `isPermaLink` (capital "L") 2. `itunes:summary` and `itunes:subtitle` are 256 characters after truncating, but the maximum is 255. The truncating function trims the text to 255 chars, but then adds `…`, so the text is one character too long 3. The tags within `itunes:keywords` are now separated with commas instead of spaces (https://validator.w3.org/feed/docs/warning/InvalidKeywords.html) --- api/funkwhale_api/audio/serializers.py | 8 ++++---- api/funkwhale_api/users/adapters.py | 3 +++ api/requirements/base.txt | 2 +- api/tests/audio/test_serializers.py | 6 +++--- changes/changelog.d/1250.bugfix | 1 + 5 files changed, 12 insertions(+), 8 deletions(-) create mode 100644 changes/changelog.d/1250.bugfix diff --git a/api/funkwhale_api/audio/serializers.py b/api/funkwhale_api/audio/serializers.py index fd57ed374..e15325d8c 100644 --- a/api/funkwhale_api/audio/serializers.py +++ b/api/funkwhale_api/audio/serializers.py @@ -818,7 +818,7 @@ def rss_serialize_item(upload): data = { "title": [{"value": upload.track.title}], "itunes:title": [{"value": upload.track.title}], - "guid": [{"cdata_value": str(upload.uuid), "isPermalink": "false"}], + "guid": [{"cdata_value": str(upload.uuid), "isPermaLink": "false"}], "pubDate": [{"value": rfc822_date(upload.creation_date)}], "itunes:duration": [{"value": rss_duration(upload.duration)}], "itunes:explicit": [{"value": "no"}], @@ -841,7 +841,7 @@ def rss_serialize_item(upload): ], } if upload.track.description: - data["itunes:subtitle"] = [{"value": upload.track.description.truncate(255)}] + data["itunes:subtitle"] = [{"value": upload.track.description.truncate(254)}] data["itunes:summary"] = [{"cdata_value": upload.track.description.rendered}] data["description"] = [{"value": upload.track.description.as_plain_text}] @@ -853,7 +853,7 @@ def rss_serialize_item(upload): tagged_items = getattr(upload.track, "_prefetched_tagged_items", []) if tagged_items: data["itunes:keywords"] = [ - {"value": " ".join([ti.tag.name for ti in tagged_items])} + {"value": ",".join([ti.tag.name for ti in tagged_items])} ] return data @@ -903,7 +903,7 @@ def rss_serialize_channel(channel): data["itunes:category"] = [node] if channel.artist.description: - data["itunes:subtitle"] = [{"value": channel.artist.description.truncate(255)}] + data["itunes:subtitle"] = [{"value": channel.artist.description.truncate(254)}] data["itunes:summary"] = [{"cdata_value": channel.artist.description.rendered}] data["description"] = [{"value": channel.artist.description.as_plain_text}] diff --git a/api/funkwhale_api/users/adapters.py b/api/funkwhale_api/users/adapters.py index e52892bd9..436ed2d77 100644 --- a/api/funkwhale_api/users/adapters.py +++ b/api/funkwhale_api/users/adapters.py @@ -26,6 +26,9 @@ class FunkwhaleAccountAdapter(DefaultAccountAdapter): def get_login_redirect_url(self, request): return "noop" + def get_signup_redirect_url(self, request): + return "noop" + def add_message(self, *args, **kwargs): # disable message sending return diff --git a/api/requirements/base.txt b/api/requirements/base.txt index 602ec8f46..0b6234d8a 100644 --- a/api/requirements/base.txt +++ b/api/requirements/base.txt @@ -6,7 +6,7 @@ django-environ~=0.4 # Images Pillow~=7.0 -django-allauth~=0.42 +django-allauth~=0.42.0 psycopg2-binary~=2.8 diff --git a/api/tests/audio/test_serializers.py b/api/tests/audio/test_serializers.py index fbcd28a1a..5f0c1226f 100644 --- a/api/tests/audio/test_serializers.py +++ b/api/tests/audio/test_serializers.py @@ -300,13 +300,13 @@ def test_rss_item_serializer(factories): expected = { "title": [{"value": upload.track.title}], "itunes:title": [{"value": upload.track.title}], - "itunes:subtitle": [{"value": description.truncate(255)}], + "itunes:subtitle": [{"value": description.truncate(254)}], "itunes:summary": [{"cdata_value": description.rendered}], "description": [{"value": description.as_plain_text}], - "guid": [{"cdata_value": str(upload.uuid), "isPermalink": "false"}], + "guid": [{"cdata_value": str(upload.uuid), "isPermaLink": "false"}], "pubDate": [{"value": serializers.rfc822_date(upload.creation_date)}], "itunes:duration": [{"value": serializers.rss_duration(upload.duration)}], - "itunes:keywords": [{"value": "pop rock"}], + "itunes:keywords": [{"value": "pop,rock"}], "itunes:explicit": [{"value": "no"}], "itunes:episodeType": [{"value": "full"}], "itunes:season": [{"value": upload.track.disc_number}], diff --git a/changes/changelog.d/1250.bugfix b/changes/changelog.d/1250.bugfix new file mode 100644 index 000000000..4d4cbddf2 --- /dev/null +++ b/changes/changelog.d/1250.bugfix @@ -0,0 +1 @@ +Make the generated RSS feed more conformant with w3c specification (#1250) From 61233a2119a230ca973794f927a33ec7fe9933d0 Mon Sep 17 00:00:00 2001 From: Agate Date: Sun, 25 Oct 2020 18:49:06 +0100 Subject: [PATCH 3/3] Fixed requirements specifications --- api/requirements/base.txt | 84 +++++++++++++++++++------------------- api/requirements/local.txt | 16 ++++---- api/requirements/test.txt | 18 ++++---- 3 files changed, 59 insertions(+), 59 deletions(-) diff --git a/api/requirements/base.txt b/api/requirements/base.txt index 0b6234d8a..3a3d61d92 100644 --- a/api/requirements/base.txt +++ b/api/requirements/base.txt @@ -1,74 +1,74 @@ django~=3.0.8 setuptools>=49 # Configuration -django-environ~=0.4 +django-environ~=0.4.0 # Images -Pillow~=7.0 +Pillow~=7.0.0 django-allauth~=0.42.0 -psycopg2-binary~=2.8 +psycopg2-binary~=2.8.0 # Time zones support pytz==2020.1 # Redis support -django-redis~=4.12 -redis~=3.5 -kombu~=4.6 +django-redis~=4.12.0 +redis~=3.5.0 +kombu~=4.6.0 -celery~=4.4 +celery~=4.4.0 # Your custom requirements go here -django-cors-headers~=3.4 +django-cors-headers~=3.4.0 musicbrainzngs~=0.7.1 -djangorestframework~=3.11 -djangorestframework-jwt~=1.11 +djangorestframework~=3.11.0 +djangorestframework-jwt~=1.11.0 arrow~=0.15.5 -persisting-theory~=0.2 -django-versatileimagefield~=2.0 -django-filter~=2.3 -django-rest-auth~=0.9 -ipython~=7.10 -mutagen~=1.45 +persisting-theory~=0.2.0 +django-versatileimagefield~=2.0.0 +django-filter~=2.3.0 +django-rest-auth~=0.9.0 +ipython~=7.10.0 +mutagen~=1.45.0 -pymemoize~=1.0 +pymemoize~=1.0.0 django-dynamic-preferences~=1.10 -raven~=6.10 -python-magic~=0.4 -channels~=2.4 -channels_redis~=3.0 -uvicorn[standard]~=0.12 -gunicorn~=20.0 +raven~=6.10.0 +python-magic~=0.4.0 +channels~=2.4.0 +channels_redis~=3.0.0 +uvicorn[standard]~=0.12.0 +gunicorn~=20.0.0 -cryptography~=2.9 +cryptography~=2.9.0 # requests-http-signature==0.0.3 # clone until the branch is merged and released upstream git+https://github.com/EliotBerriot/requests-http-signature.git@signature-header-support -django-cleanup~=5.0 -requests~=2.24 -pyOpenSSL~=19.1 +django-cleanup~=5.0.0 +requests~=2.24.0 +pyOpenSSL~=19.1.0 # for LDAP authentication -python-ldap~=3.3 -django-auth-ldap~=2.2 +python-ldap~=3.3.0 +django-auth-ldap~=2.2.0 -pydub~=0.24 -pyld~=1.0 -aiohttp~=3.6 +pydub~=0.24.0 +pyld~=1.0.0 +aiohttp~=3.6.0 -django-oauth-toolkit~=1.3 -django-storages~=1.9 -boto3~=1.14 -unicode-slugify~=0.1 -django-cacheops~=5.0 +django-oauth-toolkit~=1.3.0 +django-storages~=1.9.0 +boto3~=1.14.0 +unicode-slugify~=0.1.0 +django-cacheops~=5.0.0 -click~=7.1 -service_identity~=18.1 -markdown~=3.2 -bleach~=3.1 +click~=7.1.0 +service_identity~=18.1.0 +markdown~=3.2.0 +bleach~=3.1.0 feedparser==6.0.0b3 -watchdog~=0.10 +watchdog~=0.10.0 diff --git a/api/requirements/local.txt b/api/requirements/local.txt index f1525516e..b2e86b23c 100644 --- a/api/requirements/local.txt +++ b/api/requirements/local.txt @@ -1,20 +1,20 @@ # Local development dependencies go here -coverage~=4.5 -django_coverage_plugin~=1.6 -factory_boy~=2.11 +coverage~=4.5.0 +django_coverage_plugin~=1.6.0 +factory_boy~=2.11.0 # django-debug-toolbar that works with Django 1.5+ -django-debug-toolbar~=2.2 +django-debug-toolbar~=2.2.0 # improved REPL -ipdb~=0.11 -prompt_toolkit~=2.0 +ipdb~=0.11.0 +prompt_toolkit~=2.0.0 black==19.10b0 #profiling -asynctest~=0.12 -aioresponses~=0.6 +asynctest~=0.12.0 +aioresponses~=0.6.0 #line_profiler<3 #https://github.com/dmclain/django-debug-toolbar-line-profiler/archive/master.zip #django-silk diff --git a/api/requirements/test.txt b/api/requirements/test.txt index dacc8217c..134814510 100644 --- a/api/requirements/test.txt +++ b/api/requirements/test.txt @@ -1,12 +1,12 @@ # Test dependencies go here. -flake8~=3.8 -pytest~=6.0 -pytest-cov~=2.10 -pytest-django~=3.9 -pytest-env~=0.6 -pytest-mock~=3.2 -pytest-randomly~=3.4 -pytest-sugar~=0.9 -requests-mock~=1.8 +flake8~=3.8.0 +pytest~=6.0.0 +pytest-cov~=2.10.0 +pytest-django~=3.9.0 +pytest-env~=0.6.0 +pytest-mock~=3.2.0 +pytest-randomly~=3.4.0 +pytest-sugar~=0.9.0 +requests-mock~=1.8.0 #pytest-profiling<1.4