From 3ae34ecfd4801ce5db475df96ae3349ef29b0b57 Mon Sep 17 00:00:00 2001 From: Petitminion Date: Tue, 3 Jun 2025 16:45:02 +0200 Subject: [PATCH] enhancement(backend):trigger plugins download on third_party metadata fetch --- api/funkwhale_api/federation/tasks.py | 32 +++++++++++++++++++++++++-- docs/specs/fetch-third-party/index.md | 17 ++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 docs/specs/fetch-third-party/index.md diff --git a/api/funkwhale_api/federation/tasks.py b/api/funkwhale_api/federation/tasks.py index d9d73607e..d8694fe5c 100644 --- a/api/funkwhale_api/federation/tasks.py +++ b/api/funkwhale_api/federation/tasks.py @@ -7,6 +7,7 @@ from urllib.parse import urlparse import requests from django.conf import settings +from django.contrib.contenttypes.models import ContentType from django.core.cache import cache from django.db import transaction from django.db.models import F, Q @@ -15,6 +16,7 @@ from django.utils import timezone from dynamic_preferences.registries import global_preferences_registry from requests.exceptions import RequestException +from config import plugins from funkwhale_api import musicbrainz from funkwhale_api.audio import models as audio_models from funkwhale_api.common import models as common_models @@ -461,6 +463,31 @@ def fetch(fetch_obj): ) +def trigger_third_party_upload_hook(fetch): + if fetch.status == "finished" and fetch.object: + if fetch.object_content_type == ContentType.objects.get_for_model( + music_models.Track + ): + if not music_models.Track.objects.filter(pk=fetch.object.pk).playable_by( + fetch.actor + ): + plugins.trigger_hook( + plugins.TRIGGER_THIRD_PARTY_UPLOAD, + track=fetch.object, + ) + if fetch.object_content_type == ContentType.objects.get_for_model( + music_models.Album + ): + for track in fetch.object.tracks.all(): + if not music_models.Track.objects.filter( + pk=fetch.object.pk + ).playable_by(fetch.actor): + plugins.trigger_hook( + plugins.TRIGGER_THIRD_PARTY_UPLOAD, + track=track, + ) + + def musicbrainz_type_handler(fetch): url = fetch.url path_parts = urlparse(url).path.strip("/").split("/") @@ -590,10 +617,11 @@ def third_party_fetch(fetch_obj): fetch_obj.object = obj fetch_obj.status = "finished" fetch_obj.fetch_date = timezone.now() - # to do : trigger third party download ? - return fetch_obj.save( + trigger_third_party_upload_hook(fetch_obj) + fetch_obj.save( update_fields=["fetch_date", "status", "object_id", "object_content_type"] ) + return fetch_obj class PreserveSomeDataCollector(Collector): diff --git a/docs/specs/fetch-third-party/index.md b/docs/specs/fetch-third-party/index.md new file mode 100644 index 000000000..d69d6a7dd --- /dev/null +++ b/docs/specs/fetch-third-party/index.md @@ -0,0 +1,17 @@ +# Collections + +## The issue + +Has a user I want to be able to get metadata from third party services (to add them to my favorites or to a playlist) + +## Solution + +paste the track or release url into the search bar. Funkwhale will get the mmetadata and create the objects in db. First implementation with Musicbrainz : + +- track : https://musicbrainz.org/release/{mbid} +- release : https://musicbrainz.org/recording/{mbid} + +## Implementation + +third_party_fetch in federation.tasks +musicbrainz.serializers