kopia lustrzana https://dev.funkwhale.audio/funkwhale/funkwhale
146 wiersze
4.9 KiB
Python
146 wiersze
4.9 KiB
Python
from argparse import RawTextHelpFormatter
|
|
|
|
from django.core.management.base import BaseCommand
|
|
from django.core.management.base import CommandError
|
|
|
|
from django.db import transaction
|
|
|
|
from funkwhale_api.music import models, tasks
|
|
|
|
|
|
class Command(BaseCommand):
|
|
help = """
|
|
Remove tracks, albums and artists that are not associated with any file from the instance library:
|
|
|
|
- Tracks without uploads are deleted, if the --tracks flag is passed
|
|
- Albums without tracks are deleted, if the --albums flag is passed
|
|
- Artists without albums are deleted, if the --artists flag is passed
|
|
|
|
Tracks with associated favorites, playlists or listening won't be deleted
|
|
by default, unless you pass the corresponding --ignore-* flags.
|
|
|
|
"""
|
|
|
|
def create_parser(self, *args, **kwargs):
|
|
parser = super().create_parser(*args, **kwargs)
|
|
parser.formatter_class = RawTextHelpFormatter
|
|
return parser
|
|
|
|
def add_arguments(self, parser):
|
|
parser.add_argument(
|
|
"--no-dry-run",
|
|
action="store_false",
|
|
dest="dry_run",
|
|
default=True,
|
|
help="Disable dry run mode and apply pruning for real on the database",
|
|
)
|
|
parser.add_argument(
|
|
"--artists",
|
|
action="store_true",
|
|
dest="prune_artists",
|
|
default=False,
|
|
help="Prune artists without albums/tracks",
|
|
)
|
|
parser.add_argument(
|
|
"--albums",
|
|
action="store_true",
|
|
dest="prune_albums",
|
|
default=False,
|
|
help="Prune albums without tracks",
|
|
)
|
|
parser.add_argument(
|
|
"--tracks",
|
|
action="store_true",
|
|
dest="prune_tracks",
|
|
default=False,
|
|
help="Prune tracks without uploads",
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--ignore-favorites",
|
|
action="store_false",
|
|
dest="exclude_favorites",
|
|
default=True,
|
|
help="Allow favorited tracks to be pruned",
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--ignore-playlists",
|
|
action="store_false",
|
|
dest="exclude_playlists",
|
|
default=True,
|
|
help="Allow tracks included in playlists to be pruned",
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--ignore-listenings",
|
|
action="store_false",
|
|
dest="exclude_listenings",
|
|
default=True,
|
|
help="Allow tracks with listening history to be pruned",
|
|
)
|
|
|
|
@transaction.atomic
|
|
def handle(self, *args, **options):
|
|
if not any(
|
|
[options["prune_albums"], options["prune_tracks"], options["prune_artists"]]
|
|
):
|
|
raise CommandError(
|
|
"You need to provide at least one of the --tracks, --albums or --artists flags"
|
|
)
|
|
|
|
if options["dry_run"]:
|
|
self.stdout.write("Dry-run on, will not commit anything")
|
|
else:
|
|
self.stdout.write("Dry-run off, *pruning for real*")
|
|
self.stdout.write("")
|
|
if options["prune_tracks"]:
|
|
prunable = tasks.get_prunable_tracks(
|
|
exclude_favorites=options["exclude_favorites"],
|
|
exclude_playlists=options["exclude_playlists"],
|
|
exclude_listenings=options["exclude_listenings"],
|
|
)
|
|
pruned_total = prunable.count()
|
|
total = models.Track.objects.count()
|
|
if options["dry_run"]:
|
|
self.stdout.write(
|
|
"Would prune {}/{} tracks".format(pruned_total, total)
|
|
)
|
|
else:
|
|
self.stdout.write("Deleting {}/{} tracks…".format(pruned_total, total))
|
|
prunable.delete()
|
|
|
|
if options["prune_albums"]:
|
|
prunable = tasks.get_prunable_albums()
|
|
pruned_total = prunable.count()
|
|
total = models.Album.objects.count()
|
|
if options["dry_run"]:
|
|
self.stdout.write(
|
|
"Would prune {}/{} albums".format(pruned_total, total)
|
|
)
|
|
else:
|
|
self.stdout.write("Deleting {}/{} albums…".format(pruned_total, total))
|
|
prunable.delete()
|
|
|
|
if options["prune_artists"]:
|
|
prunable = tasks.get_prunable_artists()
|
|
pruned_total = prunable.count()
|
|
total = models.Artist.objects.count()
|
|
if options["dry_run"]:
|
|
self.stdout.write(
|
|
"Would prune {}/{} artists".format(pruned_total, total)
|
|
)
|
|
else:
|
|
self.stdout.write("Deleting {}/{} artists…".format(pruned_total, total))
|
|
prunable.delete()
|
|
|
|
self.stdout.write("")
|
|
if options["dry_run"]:
|
|
self.stdout.write(
|
|
"Nothing was pruned, rerun this command with --no-dry-run to apply the changes"
|
|
)
|
|
else:
|
|
self.stdout.write("Pruning completed!")
|
|
|
|
self.stdout.write("")
|