diff --git a/api/funkwhale_api/music/migrations/0066_remove_library_description_and_more.py b/api/funkwhale_api/music/migrations/0066_remove_library_description_and_more.py new file mode 100644 index 000000000..f1e5b36b7 --- /dev/null +++ b/api/funkwhale_api/music/migrations/0066_remove_library_description_and_more.py @@ -0,0 +1,21 @@ +# Generated by Django 4.2.9 on 2025-01-03 20:43 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("music", "0065_merge_20240911_1354"), + ("playlists", "0007_alter_playlist_actor_alter_playlisttrack_uuid_and_more"), + ] + + operations = [ + migrations.RemoveField( + model_name="library", + name="description", + ), + migrations.RemoveField( + model_name="library", + name="followers_url", + ), + ] diff --git a/api/funkwhale_api/music/migrations/0067_migrate_libraries_to_playlist.py b/api/funkwhale_api/music/migrations/0067_migrate_libraries_to_playlist.py new file mode 100644 index 000000000..63e026567 --- /dev/null +++ b/api/funkwhale_api/music/migrations/0067_migrate_libraries_to_playlist.py @@ -0,0 +1,108 @@ +# Generated by Django 4.2.9 on 2025-01-03 16:12 + +from django.db import migrations, models +from django.db import IntegrityError + +from funkwhale_api.federation import utils as federation_utils +from django.urls import reverse +import uuid + + +def insert_tracks_to_playlist(apps, playlist, uploads): + PlaylistTrack = apps.get_model("playlists", "PlaylistTrack") + plts = [ + PlaylistTrack( + creation_date=playlist.creation_date, + playlist=playlist, + track=upload.track, + index=0 + i, + uuid=(new_uuid := uuid.uuid4()), + fid=federation_utils.full_url( + reverse( + f"federation:music:playlists-detail", + kwargs={"uuid": new_uuid}, + ) + ), + ) + for i, upload in enumerate(uploads) + if upload.track + ] + + return PlaylistTrack.objects.bulk_create(plts) + + +def migrate_libraries_to_playlist(apps, schema_editor): + Playlist = apps.get_model("playlists", "Playlist") + Library = apps.get_model("music", "Library") + LibraryFollow = apps.get_model("federation", "LibraryFollow") + Follow = apps.get_model("federation", "Follow") + User = apps.get_model("users", "User") + Actor = apps.get_model("federation", "Actor") + + # library to playlist + for library in Library.objects.all(): + playlist = Playlist.objects.create( + name=library.name, + actor=library.actor, + creation_date=library.creation_date, + privacy_level=library.privacy_level, + uuid=(new_uuid := uuid.uuid4()), + fid=federation_utils.full_url( + reverse( + f"federation:music:playlists-detail", + kwargs={"uuid": new_uuid}, + ) + ), + ) + playlist.save() + + if library.uploads.all().exists(): + insert_tracks_to_playlist(apps, playlist, library.uploads.all()) + + # library follows to user follow + for lib_follow in LibraryFollow.objects.filter(target=library): + try: + Follow.objects.create( + uuid=lib_follow.uuid, + target=library.actor, + actor=lib_follow.actor, + approved=lib_follow.approved, + creation_date=lib_follow.creation_date, + modification_date=lib_follow.modification_date, + ) + except IntegrityError: + pass + + LibraryFollow.objects.all().delete() + + # migrate uploads to new library + for actor in Actor.objects.all(): + privacy_levels = ["me", "instance", "everyone"] + for privacy_level in privacy_levels: + build_in_lib = Library.objects.create( + actor=actor, + privacy_level=privacy_level, + name=privacy_level, + uuid=(new_uuid := uuid.uuid4()), + fid=federation_utils.full_url( + reverse( + f"federation:music:playlists-detail", + kwargs={"uuid": new_uuid}, + ) + ), + ) + for library in actor.libraries.filter(privacy_level=privacy_level): + library.uploads.all().update(library=build_in_lib) + if library.pk is not build_in_lib.pk: + library.delete() + + +class Migration(migrations.Migration): + dependencies = [ + ("music", "0066_remove_library_description_and_more"), + ] + operations = [ + migrations.RunPython( + migrate_libraries_to_playlist, reverse_code=migrations.RunPython.noop + ), + ]