diff --git a/api/funkwhale_api/music/fake_data.py b/api/funkwhale_api/music/fake_data.py index 9f74c1f72..add7b4c58 100644 --- a/api/funkwhale_api/music/fake_data.py +++ b/api/funkwhale_api/music/fake_data.py @@ -68,6 +68,7 @@ def create_data(super_user_name=None): playlist = playlist_factories.PlaylistFactory( name="playlist test public", privacy_level="everyone", + local=True if super_user else False, actor=(super_user.actor if super_user else federation_factories.ActorFactory()), ) playlist_factories.PlaylistTrackFactory(playlist=playlist, track=upload.track) diff --git a/api/funkwhale_api/music/migrations/0061_migrate_libraries_to_playlist.py b/api/funkwhale_api/music/migrations/0061_migrate_libraries_to_playlist.py index b2028da99..6d0da91ea 100644 --- a/api/funkwhale_api/music/migrations/0061_migrate_libraries_to_playlist.py +++ b/api/funkwhale_api/music/migrations/0061_migrate_libraries_to_playlist.py @@ -74,13 +74,15 @@ def migrate_libraries_to_playlist(apps, schema_editor): creation_date=library.creation_date, privacy_level=library.privacy_level, description=library.description, - uuid=(new_uuid := uuid.uuid4()), - fid=federation_utils.full_url( - reverse( - "federation:music:playlists-detail", - kwargs={"uuid": new_uuid}, - ) - ), + defaults={ + "uuid": (new_uuid := uuid.uuid4()), + "fid": federation_utils.full_url( + reverse( + "federation:music:playlists-detail", + kwargs={"uuid": new_uuid}, + ) + ), + }, ) playlist.save() @@ -104,22 +106,30 @@ def migrate_libraries_to_playlist(apps, schema_editor): # migrate uploads to new built-in libraries for actor in Actor.objects.all(): - if not federation_utils.is_local(actor.fid) or actor.name == "service": + if ( + not federation_utils.is_local(actor.fid) + or actor.name == "service" + or hasattr(actor, "channel") + ): continue privacy_levels = ["me", "instance", "everyone"] for privacy_level in privacy_levels: - build_in_lib, created = Library.objects.get_or_create( + build_in_lib, created = Library.objects.filter( + channel__isnull=True + ).get_or_create( actor=actor, privacy_level=privacy_level, name=privacy_level, - uuid=(new_uuid := uuid.uuid4()), - fid=federation_utils.full_url( - reverse( - "federation:music:libraries-detail", - kwargs={"uuid": new_uuid}, - ) - ), + defaults={ + "uuid": (new_uuid := uuid.uuid4()), + "fid": federation_utils.full_url( + reverse( + "federation:music:libraries-detail", + kwargs={"uuid": new_uuid}, + ) + ), + }, ) for library in actor.libraries.filter(privacy_level=privacy_level): library.uploads.all().update(library=build_in_lib) @@ -141,15 +151,34 @@ def check_succefull_migration(apps, schema_editor): Playlist = apps.get_model("playlists", "Playlist") for actor in Actor.objects.all(): - not_build_in_libs = len(actor.playlists.all()) + len( - actor.libraries.filter(channel__isnull=False) + not_build_in_libs = ( + actor.playlists.count() + + actor.libraries.filter(channel__isnull=False).count() ) - if len(actor.libraries.all()) - 3 != not_build_in_libs: + actor_playlist_lib = actor.playlists.filter(library__isnull=False).count() + + if actor.playlists.count() != actor_playlist_lib: raise Exception( - "Incoherent library database state, check for errors in log and share them to the funkwhale team. Migration was abordted to prevent data loss" + f"Incoherent playlist database state : all playlists do not have lib or too many libs\ + actor_playlist_lib = {actor_playlist_lib} actor.playlists.count()={actor.playlists.count()}" + ) + + if actor.name == "service" or not federation_utils.is_local(actor.fid): + continue + + elif actor.libraries.count() - 3 != not_build_in_libs or ( + hasattr(actor, "channel") and actor.libraries.count() > 1 + ): + raise Exception( + f"Incoherent library database state, check for errors in log and share them to the funkwhale team. Migration was abordted to prevent data loss.\ + actor libs = {actor.libraries.count()} and acto not built-in lib = {not_build_in_libs} \ + and acto pl ={actor.playlists.count()} and not channel lib = {actor.libraries.filter(channel__isnull=False).count()} \ + and {actor.name} actor_playlist_lib {actor_playlist_lib}" ) for playlist in Playlist.objects.all(): - if playlist.library.privacy_level != "me": + if not federation_utils.is_local(playlist.fid): + continue + elif playlist.library.privacy_level != "me": raise Exception( "Incoherent playlist database state, check for errors in log and share them to the funkwhale team. Migration was abordted to prevent data loss" )