Add cli command to prune non mbid content from db (#2083)
This commit is contained in:
parent
ac74380986
commit
4364d82b0b
|
@ -0,0 +1,61 @@
|
||||||
|
from django.core.management.base import BaseCommand
|
||||||
|
from django.db import transaction
|
||||||
|
|
||||||
|
from funkwhale_api.music import models
|
||||||
|
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
help = """Deletes any tracks not tagged with a MusicBrainz ID from the database. By default, any tracks that
|
||||||
|
have been favorited by a user or added to a playlist are preserved."""
|
||||||
|
|
||||||
|
def add_arguments(self, parser):
|
||||||
|
parser.add_argument(
|
||||||
|
"--no-dry-run",
|
||||||
|
action="store_true",
|
||||||
|
dest="no_dry_run",
|
||||||
|
default=True,
|
||||||
|
help="Disable dry run mode and apply pruning for real on the database",
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"--include-playlist-content",
|
||||||
|
action="store_true",
|
||||||
|
dest="include_playlist_content",
|
||||||
|
default=False,
|
||||||
|
help="Allow tracks included in playlists to be pruned",
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"--include-favorites-content",
|
||||||
|
action="store_true",
|
||||||
|
dest="include_favorited_content",
|
||||||
|
default=False,
|
||||||
|
help="Allow favorited tracks to be pruned",
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"--include-listened-content",
|
||||||
|
action="store_true",
|
||||||
|
dest="include_listened_content",
|
||||||
|
default=False,
|
||||||
|
help="Allow tracks with listening history to be pruned",
|
||||||
|
)
|
||||||
|
|
||||||
|
@transaction.atomic
|
||||||
|
def handle(self, *args, **options):
|
||||||
|
tracks = models.Track.objects.filter(mbid__isnull=True)
|
||||||
|
if not options["include_favorited_content"]:
|
||||||
|
tracks = tracks.filter(track_favorites__isnull=True)
|
||||||
|
if not options["include_playlist_content"]:
|
||||||
|
tracks = tracks.filter(playlist_tracks__isnull=True)
|
||||||
|
if not options["include_listened_content"]:
|
||||||
|
tracks = tracks.filter(listenings__isnull=True)
|
||||||
|
|
||||||
|
pruned_total = tracks.count()
|
||||||
|
total = models.Track.objects.count()
|
||||||
|
|
||||||
|
if options["no_dry_run"]:
|
||||||
|
self.stdout.write(f"Deleting {pruned_total}/{total} tracks…")
|
||||||
|
tracks.delete()
|
||||||
|
else:
|
||||||
|
self.stdout.write(f"Would prune {pruned_total}/{total} tracks")
|
|
@ -7,6 +7,7 @@ from funkwhale_api.music.management.commands import (
|
||||||
check_inplace_files,
|
check_inplace_files,
|
||||||
fix_uploads,
|
fix_uploads,
|
||||||
prune_library,
|
prune_library,
|
||||||
|
prune_non_mbid_content,
|
||||||
)
|
)
|
||||||
|
|
||||||
DATA_DIR = os.path.dirname(os.path.abspath(__file__))
|
DATA_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
@ -204,3 +205,45 @@ def test_check_inplace_files_no_dry_run(factories, tmpfile):
|
||||||
|
|
||||||
for u in not_prunable:
|
for u in not_prunable:
|
||||||
u.refresh_from_db()
|
u.refresh_from_db()
|
||||||
|
|
||||||
|
|
||||||
|
def test_prune_non_mbid_content(factories):
|
||||||
|
prunable = factories["music.Track"](mbid=None)
|
||||||
|
|
||||||
|
track = factories["music.Track"](mbid=None)
|
||||||
|
factories["playlists.PlaylistTrack"](track=track)
|
||||||
|
not_prunable = [factories["music.Track"](), track]
|
||||||
|
c = prune_non_mbid_content.Command()
|
||||||
|
options = {
|
||||||
|
"include_playlist_content": False,
|
||||||
|
"include_listened_content": False,
|
||||||
|
"include_favorited_content": True,
|
||||||
|
"no_dry_run": True,
|
||||||
|
}
|
||||||
|
c.handle(**options)
|
||||||
|
|
||||||
|
with pytest.raises(prunable.DoesNotExist):
|
||||||
|
prunable.refresh_from_db()
|
||||||
|
|
||||||
|
for t in not_prunable:
|
||||||
|
t.refresh_from_db()
|
||||||
|
|
||||||
|
track = factories["music.Track"](mbid=None)
|
||||||
|
factories["playlists.PlaylistTrack"](track=track)
|
||||||
|
prunable = [factories["music.Track"](mbid=None), track]
|
||||||
|
|
||||||
|
not_prunable = [factories["music.Track"]()]
|
||||||
|
options = {
|
||||||
|
"include_playlist_content": True,
|
||||||
|
"include_listened_content": False,
|
||||||
|
"include_favorited_content": False,
|
||||||
|
"no_dry_run": True,
|
||||||
|
}
|
||||||
|
c.handle(**options)
|
||||||
|
|
||||||
|
for t in prunable:
|
||||||
|
with pytest.raises(t.DoesNotExist):
|
||||||
|
t.refresh_from_db()
|
||||||
|
|
||||||
|
for t in not_prunable:
|
||||||
|
t.refresh_from_db()
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Add cli command to prune non mbid content from db (#2083)
|
Loading…
Reference in New Issue