diff --git a/api/funkwhale_api/music/models.py b/api/funkwhale_api/music/models.py index 02c4f4434b29ca509f83b2a58723e156b486b02d..0992c2519ac14db9ad232195c148e6592b65aa5a 100644 --- a/api/funkwhale_api/music/models.py +++ b/api/funkwhale_api/music/models.py @@ -178,12 +178,13 @@ class ArtistQuerySet(common_models.LocalFromFidQuerySet, models.QuerySet): return self.annotate(is_playable_by_actor=subquery) def playable_by(self, actor, include=True): - tracks = Track.objects.playable_by(actor, include) - matches = self.filter(tracks__in=tracks).values_list("pk") + query = get_viewable_by_query(actor, "tracks__uploads__library") & models.Q( + tracks__uploads__import_status="finished" + ) if include: - return self.filter(pk__in=matches) + return self.filter(query) else: - return self.exclude(pk__in=matches) + return self.exclude(query) class Artist(APIModelMixin): @@ -262,12 +263,13 @@ class AlbumQuerySet(common_models.LocalFromFidQuerySet, models.QuerySet): return self.annotate(is_playable_by_actor=subquery) def playable_by(self, actor, include=True): - tracks = Track.objects.playable_by(actor, include) - matches = self.filter(tracks__in=tracks).values_list("pk") + query = get_viewable_by_query(actor, "tracks__uploads__library") & models.Q( + tracks__uploads__import_status="finished" + ) if include: - return self.filter(pk__in=matches) + return self.filter(query) else: - return self.exclude(pk__in=matches) + return self.exclude(query) def with_prefetched_tracks_and_playable_uploads(self, actor): tracks = Track.objects.with_playable_uploads(actor) @@ -418,12 +420,13 @@ class TrackQuerySet(common_models.LocalFromFidQuerySet, models.QuerySet): return self.annotate(is_playable_by_actor=subquery) def playable_by(self, actor, include=True): - files = Upload.objects.playable_by(actor, include) - matches = self.filter(uploads__in=files).values_list("pk") + query = get_viewable_by_query(actor, "uploads__library") & models.Q( + uploads__import_status="finished" + ) if include: - return self.filter(pk__in=matches) + return self.filter(query) else: - return self.exclude(pk__in=matches) + return self.exclude(query) def with_playable_uploads(self, actor): uploads = Upload.objects.playable_by(actor).select_related("track") @@ -598,11 +601,10 @@ class Track(APIModelMixin): class UploadQuerySet(common_models.NullsLastQuerySet): def playable_by(self, actor, include=True): - libraries = Library.objects.viewable_by(actor) - + query = get_viewable_by_query(actor, "library") if include: - return self.filter(library__in=libraries, import_status="finished") - return self.exclude(library__in=libraries, import_status="finished") + return self.filter(query, import_status="finished") + return self.exclude(query, import_status="finished") def local(self, include=True): return self.exclude(library__actor__user__isnull=include) @@ -1025,6 +1027,37 @@ LIBRARY_PRIVACY_LEVEL_CHOICES = [ ] +def prefixed_query(path, **kwargs): + if not path: + return models.Q(**kwargs) + + prefixed_kwargs = { + "{}__{}".format(path, key): value for key, value in kwargs.items() + } + return models.Q(**prefixed_kwargs) + + +def get_viewable_by_query(actor, path=None): + from funkwhale_api.federation.models import LibraryFollow + + if actor is None: + return prefixed_query(path, privacy_level="everyone") + + me_query = prefixed_query(path, privacy_level="me", actor=actor) + instance_query = prefixed_query( + path, privacy_level="instance", actor__domain=actor.domain + ) + followed_libraries = LibraryFollow.objects.filter( + actor=actor, approved=True + ).values_list("target", flat=True) + return ( + me_query + | instance_query + | prefixed_query(path, privacy_level="everyone") + | prefixed_query(path, pk__in=followed_libraries) + ) + + class LibraryQuerySet(models.QuerySet): def with_follows(self, actor): return self.prefetch_related( @@ -1036,22 +1069,7 @@ class LibraryQuerySet(models.QuerySet): ) def viewable_by(self, actor): - from funkwhale_api.federation.models import LibraryFollow - - if actor is None: - return Library.objects.filter(privacy_level="everyone") - - me_query = models.Q(privacy_level="me", actor=actor) - instance_query = models.Q(privacy_level="instance", actor__domain=actor.domain) - followed_libraries = LibraryFollow.objects.filter( - actor=actor, approved=True - ).values_list("target", flat=True) - return Library.objects.filter( - me_query - | instance_query - | models.Q(privacy_level="everyone") - | models.Q(pk__in=followed_libraries) - ) + return self.filter(get_viewable_by_query(actor)) class Library(federation_models.FederationMixin): diff --git a/api/tests/music/test_models.perf.yml b/api/tests/music/test_models.perf.yml index 6530cc0e5cfa8a1471af7bd9b5578fd081dda56d..36d633f18b1228c1fd9257d8c43948e99dce3466 100755 --- a/api/tests/music/test_models.perf.yml +++ b/api/tests/music/test_models.perf.yml @@ -1,50 +1,38 @@ test_album_playable_by_anonymous: -- db: 'SELECT ... FROM "music_album" WHERE "music_album"."id" IN (SELECT Y0."id" FROM "music_album" Y0 INNER JOIN "music_track" Y1 ON (Y0."id" = Y1."album_id") WHERE Y1."id" IN (SELECT X0."id" FROM "music_track" X0 WHERE X0."id" IN (SELECT W0."id" FROM "music_track" W0 INNER JOIN "music_upload" W1 ON (W0."id" = W1."track_id") WHERE W1."id" IN (SELECT V0."id" FROM "music_upload" V0 WHERE (V0."import_status" = # AND V0."library_id" IN (SELECT U0."id" FROM "music_library" U0 WHERE U0."privacy_level" = #)))))) ORDER BY "music_album"."creation_date" DESC' +- db: 'SELECT ... FROM "music_album" INNER JOIN "music_track" ON ("music_album"."id" = "music_track"."album_id") INNER JOIN "music_upload" ON ("music_track"."id" = "music_upload"."track_id") INNER JOIN "music_library" ON ("music_upload"."library_id" = "music_library"."id") WHERE ("music_library"."privacy_level" = # AND "music_upload"."import_status" = #) ORDER BY "music_album"."creation_date" DESC' test_album_playable_by_anonymous.2: -- db: 'SELECT ... FROM "music_album" WHERE "music_album"."id" IN (SELECT Y0."id" FROM "music_album" Y0 INNER JOIN "music_track" Y1 ON (Y0."id" = Y1."album_id") WHERE Y1."id" IN (SELECT X0."id" FROM "music_track" X0 WHERE X0."id" IN (SELECT W0."id" FROM "music_track" W0 INNER JOIN "music_upload" W1 ON (W0."id" = W1."track_id") WHERE W1."id" IN (SELECT V0."id" FROM "music_upload" V0 WHERE (V0."import_status" = # AND V0."library_id" IN (SELECT U0."id" FROM "music_library" U0 WHERE U0."privacy_level" = #)))))) ORDER BY "music_album"."creation_date" DESC' +- db: 'SELECT ... FROM "music_album" INNER JOIN "music_track" ON ("music_album"."id" = "music_track"."album_id") INNER JOIN "music_upload" ON ("music_track"."id" = "music_upload"."track_id") INNER JOIN "music_library" ON ("music_upload"."library_id" = "music_library"."id") WHERE ("music_library"."privacy_level" = # AND "music_upload"."import_status" = #) ORDER BY "music_album"."creation_date" DESC' test_album_playable_by_correct_actor: -- db: 'SELECT ... FROM "music_album" WHERE "music_album"."id" IN (SELECT Z0."id" FROM "music_album" Z0 INNER JOIN "music_track" Z1 ON (Z0."id" = Z1."album_id") WHERE Z1."id" IN (SELECT Y0."id" FROM "music_track" Y0 WHERE Y0."id" IN (SELECT X0."id" FROM "music_track" X0 INNER JOIN "music_upload" X1 ON (X0."id" = X1."track_id") WHERE X1."id" IN (SELECT W0."id" FROM "music_upload" W0 WHERE (W0."import_status" = # AND W0."library_id" IN (SELECT V0."id" FROM "music_library" V0 INNER JOIN "federation_actor" V1 ON (V0."actor_id" = V1."id") WHERE ((V0."actor_id" = # AND V0."privacy_level" = #) OR (V1."domain_id" = # AND V0."privacy_level" = #) OR V0."privacy_level" = # OR V0."id" IN (SELECT U0."target_id" FROM "federation_libraryfollow" U0 WHERE (U0."actor_id" = # AND U0."approved" = true))))))))) ORDER BY "music_album"."creation_date" DESC' -test_album_playable_by_correct_actor.2: -- db: 'SELECT ... FROM "music_album" WHERE "music_album"."id" IN (SELECT Z0."id" FROM "music_album" Z0 INNER JOIN "music_track" Z1 ON (Z0."id" = Z1."album_id") WHERE Z1."id" IN (SELECT Y0."id" FROM "music_track" Y0 WHERE Y0."id" IN (SELECT X0."id" FROM "music_track" X0 INNER JOIN "music_upload" X1 ON (X0."id" = X1."track_id") WHERE X1."id" IN (SELECT W0."id" FROM "music_upload" W0 WHERE (W0."import_status" = # AND W0."library_id" IN (SELECT V0."id" FROM "music_library" V0 INNER JOIN "federation_actor" V1 ON (V0."actor_id" = V1."id") WHERE ((V0."actor_id" = # AND V0."privacy_level" = #) OR (V1."domain_id" = # AND V0."privacy_level" = #) OR V0."privacy_level" = # OR V0."id" IN (SELECT U0."target_id" FROM "federation_libraryfollow" U0 WHERE (U0."actor_id" = # AND U0."approved" = true))))))))) ORDER BY "music_album"."creation_date" DESC' +- db: 'SELECT ... FROM "music_album" INNER JOIN "music_track" ON ("music_album"."id" = "music_track"."album_id") INNER JOIN "music_upload" ON ("music_track"."id" = "music_upload"."track_id") INNER JOIN "music_library" ON ("music_upload"."library_id" = "music_library"."id") INNER JOIN "federation_actor" ON ("music_library"."actor_id" = "federation_actor"."id") WHERE ((("music_library"."actor_id" = # AND "music_library"."privacy_level" = #) OR ("federation_actor"."domain_id" = # AND "music_library"."privacy_level" = #) OR "music_library"."privacy_level" = # OR "music_upload"."library_id" IN (SELECT U0."target_id" FROM "federation_libraryfollow" U0 WHERE (U0."actor_id" = # AND U0."approved" = true))) AND "music_upload"."import_status" = #) ORDER BY "music_album"."creation_date" DESC' test_album_playable_by_instance_actor: -- db: 'SELECT ... FROM "music_album" WHERE "music_album"."id" IN (SELECT Z0."id" FROM "music_album" Z0 INNER JOIN "music_track" Z1 ON (Z0."id" = Z1."album_id") WHERE Z1."id" IN (SELECT Y0."id" FROM "music_track" Y0 WHERE Y0."id" IN (SELECT X0."id" FROM "music_track" X0 INNER JOIN "music_upload" X1 ON (X0."id" = X1."track_id") WHERE X1."id" IN (SELECT W0."id" FROM "music_upload" W0 WHERE (W0."import_status" = # AND W0."library_id" IN (SELECT V0."id" FROM "music_library" V0 INNER JOIN "federation_actor" V1 ON (V0."actor_id" = V1."id") WHERE ((V0."actor_id" = # AND V0."privacy_level" = #) OR (V1."domain_id" = # AND V0."privacy_level" = #) OR V0."privacy_level" = # OR V0."id" IN (SELECT U0."target_id" FROM "federation_libraryfollow" U0 WHERE (U0."actor_id" = # AND U0."approved" = true))))))))) ORDER BY "music_album"."creation_date" DESC' -test_album_playable_by_instance_actor.2: -- db: 'SELECT ... FROM "music_album" WHERE "music_album"."id" IN (SELECT Z0."id" FROM "music_album" Z0 INNER JOIN "music_track" Z1 ON (Z0."id" = Z1."album_id") WHERE Z1."id" IN (SELECT Y0."id" FROM "music_track" Y0 WHERE Y0."id" IN (SELECT X0."id" FROM "music_track" X0 INNER JOIN "music_upload" X1 ON (X0."id" = X1."track_id") WHERE X1."id" IN (SELECT W0."id" FROM "music_upload" W0 WHERE (W0."import_status" = # AND W0."library_id" IN (SELECT V0."id" FROM "music_library" V0 INNER JOIN "federation_actor" V1 ON (V0."actor_id" = V1."id") WHERE ((V0."actor_id" = # AND V0."privacy_level" = #) OR (V1."domain_id" = # AND V0."privacy_level" = #) OR V0."privacy_level" = # OR V0."id" IN (SELECT U0."target_id" FROM "federation_libraryfollow" U0 WHERE (U0."actor_id" = # AND U0."approved" = true))))))))) ORDER BY "music_album"."creation_date" DESC' +- db: 'SELECT ... FROM "music_album" INNER JOIN "music_track" ON ("music_album"."id" = "music_track"."album_id") INNER JOIN "music_upload" ON ("music_track"."id" = "music_upload"."track_id") INNER JOIN "music_library" ON ("music_upload"."library_id" = "music_library"."id") INNER JOIN "federation_actor" ON ("music_library"."actor_id" = "federation_actor"."id") WHERE ((("music_library"."actor_id" = # AND "music_library"."privacy_level" = #) OR ("federation_actor"."domain_id" = # AND "music_library"."privacy_level" = #) OR "music_library"."privacy_level" = # OR "music_upload"."library_id" IN (SELECT U0."target_id" FROM "federation_libraryfollow" U0 WHERE (U0."actor_id" = # AND U0."approved" = true))) AND "music_upload"."import_status" = #) ORDER BY "music_album"."creation_date" DESC' test_artist_playable_by_anonymous: -- db: 'SELECT ... FROM "music_artist" WHERE "music_artist"."id" IN (SELECT Y0."id" FROM "music_artist" Y0 INNER JOIN "music_track" Y1 ON (Y0."id" = Y1."artist_id") WHERE Y1."id" IN (SELECT X0."id" FROM "music_track" X0 WHERE X0."id" IN (SELECT W0."id" FROM "music_track" W0 INNER JOIN "music_upload" W1 ON (W0."id" = W1."track_id") WHERE W1."id" IN (SELECT V0."id" FROM "music_upload" V0 WHERE (V0."import_status" = # AND V0."library_id" IN (SELECT U0."id" FROM "music_library" U0 WHERE U0."privacy_level" = #)))))) ORDER BY "music_artist"."creation_date" DESC' -test_artist_playable_by_anonymous.2: -- db: 'SELECT ... FROM "music_artist" WHERE "music_artist"."id" IN (SELECT Y0."id" FROM "music_artist" Y0 INNER JOIN "music_track" Y1 ON (Y0."id" = Y1."artist_id") WHERE Y1."id" IN (SELECT X0."id" FROM "music_track" X0 WHERE X0."id" IN (SELECT W0."id" FROM "music_track" W0 INNER JOIN "music_upload" W1 ON (W0."id" = W1."track_id") WHERE W1."id" IN (SELECT V0."id" FROM "music_upload" V0 WHERE (V0."import_status" = # AND V0."library_id" IN (SELECT U0."id" FROM "music_library" U0 WHERE U0."privacy_level" = #)))))) ORDER BY "music_artist"."creation_date" DESC' +- db: 'SELECT ... FROM "music_artist" INNER JOIN "music_track" ON ("music_artist"."id" = "music_track"."artist_id") INNER JOIN "music_upload" ON ("music_track"."id" = "music_upload"."track_id") INNER JOIN "music_library" ON ("music_upload"."library_id" = "music_library"."id") WHERE ("music_library"."privacy_level" = # AND "music_upload"."import_status" = #) ORDER BY "music_artist"."creation_date" DESC' test_artist_playable_by_correct_actor: -- db: 'SELECT ... FROM "music_artist" WHERE "music_artist"."id" IN (SELECT Z0."id" FROM "music_artist" Z0 INNER JOIN "music_track" Z1 ON (Z0."id" = Z1."artist_id") WHERE Z1."id" IN (SELECT Y0."id" FROM "music_track" Y0 WHERE Y0."id" IN (SELECT X0."id" FROM "music_track" X0 INNER JOIN "music_upload" X1 ON (X0."id" = X1."track_id") WHERE X1."id" IN (SELECT W0."id" FROM "music_upload" W0 WHERE (W0."import_status" = # AND W0."library_id" IN (SELECT V0."id" FROM "music_library" V0 INNER JOIN "federation_actor" V1 ON (V0."actor_id" = V1."id") WHERE ((V0."actor_id" = # AND V0."privacy_level" = #) OR (V1."domain_id" = # AND V0."privacy_level" = #) OR V0."privacy_level" = # OR V0."id" IN (SELECT U0."target_id" FROM "federation_libraryfollow" U0 WHERE (U0."actor_id" = # AND U0."approved" = true))))))))) ORDER BY "music_artist"."creation_date" DESC' +- db: 'SELECT ... FROM "music_artist" INNER JOIN "music_track" ON ("music_artist"."id" = "music_track"."artist_id") INNER JOIN "music_upload" ON ("music_track"."id" = "music_upload"."track_id") INNER JOIN "music_library" ON ("music_upload"."library_id" = "music_library"."id") INNER JOIN "federation_actor" ON ("music_library"."actor_id" = "federation_actor"."id") WHERE ((("music_library"."actor_id" = # AND "music_library"."privacy_level" = #) OR ("federation_actor"."domain_id" = # AND "music_library"."privacy_level" = #) OR "music_library"."privacy_level" = # OR "music_upload"."library_id" IN (SELECT U0."target_id" FROM "federation_libraryfollow" U0 WHERE (U0."actor_id" = # AND U0."approved" = true))) AND "music_upload"."import_status" = #) ORDER BY "music_artist"."creation_date" DESC' test_artist_playable_by_instance_actor: -- db: 'SELECT ... FROM "music_artist" WHERE "music_artist"."id" IN (SELECT Z0."id" FROM "music_artist" Z0 INNER JOIN "music_track" Z1 ON (Z0."id" = Z1."artist_id") WHERE Z1."id" IN (SELECT Y0."id" FROM "music_track" Y0 WHERE Y0."id" IN (SELECT X0."id" FROM "music_track" X0 INNER JOIN "music_upload" X1 ON (X0."id" = X1."track_id") WHERE X1."id" IN (SELECT W0."id" FROM "music_upload" W0 WHERE (W0."import_status" = # AND W0."library_id" IN (SELECT V0."id" FROM "music_library" V0 INNER JOIN "federation_actor" V1 ON (V0."actor_id" = V1."id") WHERE ((V0."actor_id" = # AND V0."privacy_level" = #) OR (V1."domain_id" = # AND V0."privacy_level" = #) OR V0."privacy_level" = # OR V0."id" IN (SELECT U0."target_id" FROM "federation_libraryfollow" U0 WHERE (U0."actor_id" = # AND U0."approved" = true))))))))) ORDER BY "music_artist"."creation_date" DESC' +- db: 'SELECT ... FROM "music_artist" INNER JOIN "music_track" ON ("music_artist"."id" = "music_track"."artist_id") INNER JOIN "music_upload" ON ("music_track"."id" = "music_upload"."track_id") INNER JOIN "music_library" ON ("music_upload"."library_id" = "music_library"."id") INNER JOIN "federation_actor" ON ("music_library"."actor_id" = "federation_actor"."id") WHERE ((("music_library"."actor_id" = # AND "music_library"."privacy_level" = #) OR ("federation_actor"."domain_id" = # AND "music_library"."privacy_level" = #) OR "music_library"."privacy_level" = # OR "music_upload"."library_id" IN (SELECT U0."target_id" FROM "federation_libraryfollow" U0 WHERE (U0."actor_id" = # AND U0."approved" = true))) AND "music_upload"."import_status" = #) ORDER BY "music_artist"."creation_date" DESC' test_artist_playable_by_instance_actor.2: -- db: 'SELECT ... FROM "music_artist" WHERE "music_artist"."id" IN (SELECT Z0."id" FROM "music_artist" Z0 INNER JOIN "music_track" Z1 ON (Z0."id" = Z1."artist_id") WHERE Z1."id" IN (SELECT Y0."id" FROM "music_track" Y0 WHERE Y0."id" IN (SELECT X0."id" FROM "music_track" X0 INNER JOIN "music_upload" X1 ON (X0."id" = X1."track_id") WHERE X1."id" IN (SELECT W0."id" FROM "music_upload" W0 WHERE (W0."import_status" = # AND W0."library_id" IN (SELECT V0."id" FROM "music_library" V0 INNER JOIN "federation_actor" V1 ON (V0."actor_id" = V1."id") WHERE ((V0."actor_id" = # AND V0."privacy_level" = #) OR (V1."domain_id" = # AND V0."privacy_level" = #) OR V0."privacy_level" = # OR V0."id" IN (SELECT U0."target_id" FROM "federation_libraryfollow" U0 WHERE (U0."actor_id" = # AND U0."approved" = true))))))))) ORDER BY "music_artist"."creation_date" DESC' +- db: 'SELECT ... FROM "music_artist" INNER JOIN "music_track" ON ("music_artist"."id" = "music_track"."artist_id") INNER JOIN "music_upload" ON ("music_track"."id" = "music_upload"."track_id") INNER JOIN "music_library" ON ("music_upload"."library_id" = "music_library"."id") INNER JOIN "federation_actor" ON ("music_library"."actor_id" = "federation_actor"."id") WHERE ((("music_library"."actor_id" = # AND "music_library"."privacy_level" = #) OR ("federation_actor"."domain_id" = # AND "music_library"."privacy_level" = #) OR "music_library"."privacy_level" = # OR "music_upload"."library_id" IN (SELECT U0."target_id" FROM "federation_libraryfollow" U0 WHERE (U0."actor_id" = # AND U0."approved" = true))) AND "music_upload"."import_status" = #) ORDER BY "music_artist"."creation_date" DESC' test_playable_by_anonymous: -- db: 'SELECT ... FROM "music_upload" WHERE ("music_upload"."library_id" = # AND "music_upload"."import_status" = # AND "music_upload"."library_id" IN (SELECT U0."id" FROM "music_library" U0 WHERE U0."privacy_level" = #))' -test_playable_by_anonymous.2: -- db: 'SELECT ... FROM "music_upload" WHERE ("music_upload"."library_id" = # AND "music_upload"."import_status" = # AND "music_upload"."library_id" IN (SELECT U0."id" FROM "music_library" U0 WHERE U0."privacy_level" = #))' +- db: 'SELECT ... FROM "music_upload" INNER JOIN "music_library" ON ("music_upload"."library_id" = "music_library"."id") WHERE ("music_upload"."library_id" = # AND "music_library"."privacy_level" = # AND "music_upload"."import_status" = #)' test_playable_by_correct_actor: -- db: 'SELECT ... FROM "music_upload" WHERE ("music_upload"."library_id" = # AND "music_upload"."import_status" = # AND "music_upload"."library_id" IN (SELECT V0."id" FROM "music_library" V0 INNER JOIN "federation_actor" V1 ON (V0."actor_id" = V1."id") WHERE ((V0."actor_id" = # AND V0."privacy_level" = #) OR (V1."domain_id" = # AND V0."privacy_level" = #) OR V0."privacy_level" = # OR V0."id" IN (SELECT U0."target_id" FROM "federation_libraryfollow" U0 WHERE (U0."actor_id" = # AND U0."approved" = true)))))' +- db: 'SELECT ... FROM "music_upload" INNER JOIN "music_library" ON ("music_upload"."library_id" = "music_library"."id") INNER JOIN "federation_actor" ON ("music_library"."actor_id" = "federation_actor"."id") WHERE ("music_upload"."library_id" = # AND (("music_library"."actor_id" = # AND "music_library"."privacy_level" = #) OR ("federation_actor"."domain_id" = # AND "music_library"."privacy_level" = #) OR "music_library"."privacy_level" = # OR "music_upload"."library_id" IN (SELECT U0."target_id" FROM "federation_libraryfollow" U0 WHERE (U0."actor_id" = # AND U0."approved" = true))) AND "music_upload"."import_status" = #)' +test_playable_by_correct_actor.2: +- db: 'SELECT ... FROM "music_upload" INNER JOIN "music_library" ON ("music_upload"."library_id" = "music_library"."id") INNER JOIN "federation_actor" ON ("music_library"."actor_id" = "federation_actor"."id") WHERE ("music_upload"."library_id" = # AND (("music_library"."actor_id" = # AND "music_library"."privacy_level" = #) OR ("federation_actor"."domain_id" = # AND "music_library"."privacy_level" = #) OR "music_library"."privacy_level" = # OR "music_upload"."library_id" IN (SELECT U0."target_id" FROM "federation_libraryfollow" U0 WHERE (U0."actor_id" = # AND U0."approved" = true))) AND "music_upload"."import_status" = #)' test_playable_by_correct_status: -- db: 'SELECT ... FROM "music_upload" WHERE ("music_upload"."library_id" = # AND "music_upload"."import_status" = # AND "music_upload"."library_id" IN (SELECT U0."id" FROM "music_library" U0 WHERE U0."privacy_level" = #))' -test_playable_by_correct_status.2: -- db: 'SELECT ... FROM "music_upload" WHERE ("music_upload"."library_id" = # AND "music_upload"."import_status" = # AND "music_upload"."library_id" IN (SELECT U0."id" FROM "music_library" U0 WHERE U0."privacy_level" = #))' +- db: 'SELECT ... FROM "music_upload" INNER JOIN "music_library" ON ("music_upload"."library_id" = "music_library"."id") WHERE ("music_upload"."library_id" = # AND "music_library"."privacy_level" = # AND "music_upload"."import_status" = #)' test_playable_by_follower: -- db: 'SELECT ... FROM "music_upload" WHERE ("music_upload"."library_id" = # AND "music_upload"."import_status" = # AND "music_upload"."library_id" IN (SELECT V0."id" FROM "music_library" V0 INNER JOIN "federation_actor" V1 ON (V0."actor_id" = V1."id") WHERE ((V0."actor_id" = # AND V0."privacy_level" = #) OR (V1."domain_id" = # AND V0."privacy_level" = #) OR V0."privacy_level" = # OR V0."id" IN (SELECT U0."target_id" FROM "federation_libraryfollow" U0 WHERE (U0."actor_id" = # AND U0."approved" = true)))))' +- db: 'SELECT ... FROM "music_upload" INNER JOIN "music_library" ON ("music_upload"."library_id" = "music_library"."id") INNER JOIN "federation_actor" ON ("music_library"."actor_id" = "federation_actor"."id") WHERE ("music_upload"."library_id" = # AND (("music_library"."actor_id" = # AND "music_library"."privacy_level" = #) OR ("federation_actor"."domain_id" = # AND "music_library"."privacy_level" = #) OR "music_library"."privacy_level" = # OR "music_upload"."library_id" IN (SELECT U0."target_id" FROM "federation_libraryfollow" U0 WHERE (U0."actor_id" = # AND U0."approved" = true))) AND "music_upload"."import_status" = #)' test_playable_by_instance_actor: -- db: 'SELECT ... FROM "music_upload" WHERE ("music_upload"."library_id" = # AND "music_upload"."import_status" = # AND "music_upload"."library_id" IN (SELECT V0."id" FROM "music_library" V0 INNER JOIN "federation_actor" V1 ON (V0."actor_id" = V1."id") WHERE ((V0."actor_id" = # AND V0."privacy_level" = #) OR (V1."domain_id" = # AND V0."privacy_level" = #) OR V0."privacy_level" = # OR V0."id" IN (SELECT U0."target_id" FROM "federation_libraryfollow" U0 WHERE (U0."actor_id" = # AND U0."approved" = true)))))' +- db: 'SELECT ... FROM "music_upload" INNER JOIN "music_library" ON ("music_upload"."library_id" = "music_library"."id") INNER JOIN "federation_actor" ON ("music_library"."actor_id" = "federation_actor"."id") WHERE ("music_upload"."library_id" = # AND (("music_library"."actor_id" = # AND "music_library"."privacy_level" = #) OR ("federation_actor"."domain_id" = # AND "music_library"."privacy_level" = #) OR "music_library"."privacy_level" = # OR "music_upload"."library_id" IN (SELECT U0."target_id" FROM "federation_libraryfollow" U0 WHERE (U0."actor_id" = # AND U0."approved" = true))) AND "music_upload"."import_status" = #)' test_playable_by_instance_actor.2: -- db: 'SELECT ... FROM "music_upload" WHERE ("music_upload"."library_id" = # AND "music_upload"."import_status" = # AND "music_upload"."library_id" IN (SELECT V0."id" FROM "music_library" V0 INNER JOIN "federation_actor" V1 ON (V0."actor_id" = V1."id") WHERE ((V0."actor_id" = # AND V0."privacy_level" = #) OR (V1."domain_id" = # AND V0."privacy_level" = #) OR V0."privacy_level" = # OR V0."id" IN (SELECT U0."target_id" FROM "federation_libraryfollow" U0 WHERE (U0."actor_id" = # AND U0."approved" = true)))))' +- db: 'SELECT ... FROM "music_upload" INNER JOIN "music_library" ON ("music_upload"."library_id" = "music_library"."id") INNER JOIN "federation_actor" ON ("music_library"."actor_id" = "federation_actor"."id") WHERE ("music_upload"."library_id" = # AND (("music_library"."actor_id" = # AND "music_library"."privacy_level" = #) OR ("federation_actor"."domain_id" = # AND "music_library"."privacy_level" = #) OR "music_library"."privacy_level" = # OR "music_upload"."library_id" IN (SELECT U0."target_id" FROM "federation_libraryfollow" U0 WHERE (U0."actor_id" = # AND U0."approved" = true))) AND "music_upload"."import_status" = #)' test_track_playable_by_anonymous: -- db: 'SELECT ... FROM "music_track" LEFT OUTER JOIN "music_album" ON ("music_track"."album_id" = "music_album"."id") WHERE "music_track"."id" IN (SELECT W0."id" FROM "music_track" W0 INNER JOIN "music_upload" W1 ON (W0."id" = W1."track_id") WHERE W1."id" IN (SELECT V0."id" FROM "music_upload" V0 WHERE (V0."import_status" = # AND V0."library_id" IN (SELECT U0."id" FROM "music_library" U0 WHERE U0."privacy_level" = #)))) ORDER BY "music_album"."creation_date" DESC, "music_track"."disc_number" ASC, "music_track"."position" ASC' -test_track_playable_by_anonymous.2: -- db: 'SELECT ... FROM "music_track" LEFT OUTER JOIN "music_album" ON ("music_track"."album_id" = "music_album"."id") WHERE "music_track"."id" IN (SELECT W0."id" FROM "music_track" W0 INNER JOIN "music_upload" W1 ON (W0."id" = W1."track_id") WHERE W1."id" IN (SELECT V0."id" FROM "music_upload" V0 WHERE (V0."import_status" = # AND V0."library_id" IN (SELECT U0."id" FROM "music_library" U0 WHERE U0."privacy_level" = #)))) ORDER BY "music_album"."creation_date" DESC, "music_track"."disc_number" ASC, "music_track"."position" ASC' -test_track_playable_by_anonymous.3: -- db: 'SELECT ... FROM "music_track" LEFT OUTER JOIN "music_album" ON ("music_track"."album_id" = "music_album"."id") WHERE "music_track"."id" IN (SELECT W0."id" FROM "music_track" W0 INNER JOIN "music_upload" W1 ON (W0."id" = W1."track_id") WHERE W1."id" IN (SELECT V0."id" FROM "music_upload" V0 WHERE (V0."import_status" = # AND V0."library_id" IN (SELECT U0."id" FROM "music_library" U0 WHERE U0."privacy_level" = #)))) ORDER BY "music_album"."creation_date" DESC, "music_track"."disc_number" ASC, "music_track"."position" ASC' +- db: 'SELECT ... FROM "music_track" INNER JOIN "music_upload" ON ("music_track"."id" = "music_upload"."track_id") INNER JOIN "music_library" ON ("music_upload"."library_id" = "music_library"."id") LEFT OUTER JOIN "music_album" ON ("music_track"."album_id" = "music_album"."id") WHERE ("music_library"."privacy_level" = # AND "music_upload"."import_status" = #) ORDER BY "music_album"."creation_date" DESC, "music_track"."disc_number" ASC, "music_track"."position" ASC' test_track_playable_by_correct_actor: -- db: 'SELECT ... FROM "music_track" LEFT OUTER JOIN "music_album" ON ("music_track"."album_id" = "music_album"."id") WHERE "music_track"."id" IN (SELECT X0."id" FROM "music_track" X0 INNER JOIN "music_upload" X1 ON (X0."id" = X1."track_id") WHERE X1."id" IN (SELECT W0."id" FROM "music_upload" W0 WHERE (W0."import_status" = # AND W0."library_id" IN (SELECT V0."id" FROM "music_library" V0 INNER JOIN "federation_actor" V1 ON (V0."actor_id" = V1."id") WHERE ((V0."actor_id" = # AND V0."privacy_level" = #) OR (V1."domain_id" = # AND V0."privacy_level" = #) OR V0."privacy_level" = # OR V0."id" IN (SELECT U0."target_id" FROM "federation_libraryfollow" U0 WHERE (U0."actor_id" = # AND U0."approved" = true))))))) ORDER BY "music_album"."creation_date" DESC, "music_track"."disc_number" ASC, "music_track"."position" ASC' +- db: 'SELECT ... FROM "music_track" INNER JOIN "music_upload" ON ("music_track"."id" = "music_upload"."track_id") INNER JOIN "music_library" ON ("music_upload"."library_id" = "music_library"."id") INNER JOIN "federation_actor" ON ("music_library"."actor_id" = "federation_actor"."id") LEFT OUTER JOIN "music_album" ON ("music_track"."album_id" = "music_album"."id") WHERE ((("music_library"."actor_id" = # AND "music_library"."privacy_level" = #) OR ("federation_actor"."domain_id" = # AND "music_library"."privacy_level" = #) OR "music_library"."privacy_level" = # OR "music_upload"."library_id" IN (SELECT U0."target_id" FROM "federation_libraryfollow" U0 WHERE (U0."actor_id" = # AND U0."approved" = true))) AND "music_upload"."import_status" = #) ORDER BY "music_album"."creation_date" DESC, "music_track"."disc_number" ASC, "music_track"."position" ASC' test_track_playable_by_instance_actor: -- db: 'SELECT ... FROM "music_track" LEFT OUTER JOIN "music_album" ON ("music_track"."album_id" = "music_album"."id") WHERE "music_track"."id" IN (SELECT X0."id" FROM "music_track" X0 INNER JOIN "music_upload" X1 ON (X0."id" = X1."track_id") WHERE X1."id" IN (SELECT W0."id" FROM "music_upload" W0 WHERE (W0."import_status" = # AND W0."library_id" IN (SELECT V0."id" FROM "music_library" V0 INNER JOIN "federation_actor" V1 ON (V0."actor_id" = V1."id") WHERE ((V0."actor_id" = # AND V0."privacy_level" = #) OR (V1."domain_id" = # AND V0."privacy_level" = #) OR V0."privacy_level" = # OR V0."id" IN (SELECT U0."target_id" FROM "federation_libraryfollow" U0 WHERE (U0."actor_id" = # AND U0."approved" = true))))))) ORDER BY "music_album"."creation_date" DESC, "music_track"."disc_number" ASC, "music_track"."position" ASC' +- db: 'SELECT ... FROM "music_track" INNER JOIN "music_upload" ON ("music_track"."id" = "music_upload"."track_id") INNER JOIN "music_library" ON ("music_upload"."library_id" = "music_library"."id") INNER JOIN "federation_actor" ON ("music_library"."actor_id" = "federation_actor"."id") LEFT OUTER JOIN "music_album" ON ("music_track"."album_id" = "music_album"."id") WHERE ((("music_library"."actor_id" = # AND "music_library"."privacy_level" = #) OR ("federation_actor"."domain_id" = # AND "music_library"."privacy_level" = #) OR "music_library"."privacy_level" = # OR "music_upload"."library_id" IN (SELECT U0."target_id" FROM "federation_libraryfollow" U0 WHERE (U0."actor_id" = # AND U0."approved" = true))) AND "music_upload"."import_status" = #) ORDER BY "music_album"."creation_date" DESC, "music_track"."disc_number" ASC, "music_track"."position" ASC' test_track_playable_by_instance_actor.2: -- db: 'SELECT ... FROM "music_track" LEFT OUTER JOIN "music_album" ON ("music_track"."album_id" = "music_album"."id") WHERE "music_track"."id" IN (SELECT X0."id" FROM "music_track" X0 INNER JOIN "music_upload" X1 ON (X0."id" = X1."track_id") WHERE X1."id" IN (SELECT W0."id" FROM "music_upload" W0 WHERE (W0."import_status" = # AND W0."library_id" IN (SELECT V0."id" FROM "music_library" V0 INNER JOIN "federation_actor" V1 ON (V0."actor_id" = V1."id") WHERE ((V0."actor_id" = # AND V0."privacy_level" = #) OR (V1."domain_id" = # AND V0."privacy_level" = #) OR V0."privacy_level" = # OR V0."id" IN (SELECT U0."target_id" FROM "federation_libraryfollow" U0 WHERE (U0."actor_id" = # AND U0."approved" = true))))))) ORDER BY "music_album"."creation_date" DESC, "music_track"."disc_number" ASC, "music_track"."position" ASC' +- db: 'SELECT ... FROM "music_track" INNER JOIN "music_upload" ON ("music_track"."id" = "music_upload"."track_id") INNER JOIN "music_library" ON ("music_upload"."library_id" = "music_library"."id") INNER JOIN "federation_actor" ON ("music_library"."actor_id" = "federation_actor"."id") LEFT OUTER JOIN "music_album" ON ("music_track"."album_id" = "music_album"."id") WHERE ((("music_library"."actor_id" = # AND "music_library"."privacy_level" = #) OR ("federation_actor"."domain_id" = # AND "music_library"."privacy_level" = #) OR "music_library"."privacy_level" = # OR "music_upload"."library_id" IN (SELECT U0."target_id" FROM "federation_libraryfollow" U0 WHERE (U0."actor_id" = # AND U0."approved" = true))) AND "music_upload"."import_status" = #) ORDER BY "music_album"."creation_date" DESC, "music_track"."disc_number" ASC, "music_track"."position" ASC'