from django.core.management.base import CommandError, NoArgsCommand from django.conf import settings from adim.models import AnObj import os import sys from optparse import make_option class Command(NoArgsCommand): help = 'Remove image files not used by an Annotable Object' option_list = NoArgsCommand.option_list + ( make_option('--noinput', action='store_false', dest='interactive', default=True, help="Do NOT prompt the user for input of any kind."), make_option('-n', '--dry-run', action='store_true', dest='dry_run', default=False, help="Do everything except modify the filesystem."), ) def __init__(self, *args, **kwargs): super(NoArgsCommand, self).__init__(*args, **kwargs) self.dry_run = False self.interactive = True self.verbosity = 1 def set_options(self, **options): """ Set instance variables based on an options dict """ self.interactive = options['interactive'] self.dry_run = options['dry_run'] self.verbosity = int(options['verbosity']) if self.interactive else 0 def handle_noargs(self, **options): self.set_options(**options) anobj_uuid_list = AnObj.objects.all().values_list('uuid', flat=True) images_path = os.path.join(settings.MEDIA_ROOT, 'ao_images') files_to_remove = [] for root, dirs, files in os.walk(unicode(images_path)): files_to_remove.extend(os.path.join(root, f) for f in files if f[:32] not in anobj_uuid_list) if len(files_to_remove) == 0: if self.verbosity >= 1: print "No files to remove." sys.exit(0) if self.verbosity >= 1: print "List of files to be deleted: " print "---------------------------" print "\n".join(f.replace(settings.MEDIA_ROOT, ' .') for f in files_to_remove) print "\n" message = "Continue and delete {} files ? [yes/NO] ".format(len(files_to_remove)) if self.interactive and raw_input(message) != 'yes': raise CommandError("Removing unused files cancelled.") if not self.dry_run: for f in files_to_remove: try: os.unlink(f) except OSError: if self.verbosity >= 1: print "# Unable to delete file {}\n -> {}".format(f, sys.exc_info()[1][1]) if self.verbosity >= 1: print "Done."