annotate downloads/management/commands/dlorphan.py @ 1163:44e55e4317f8

Merge with mainline.
author Brian Neal <bgneal@gmail.com>
date Tue, 07 Mar 2017 19:47:18 -0600
parents 264b08bce8b8
children
rev   line source
bgneal@665 1 """dlorphan - a management command to remove orphaned downloads files."""
bgneal@665 2
bgneal@665 3 from optparse import make_option
bgneal@665 4 import os
bgneal@665 5
bgneal@665 6 from django.core.management.base import NoArgsCommand
bgneal@665 7 from django.conf import settings
bgneal@665 8
bgneal@665 9 from downloads.models import Download, PendingDownload
bgneal@665 10
bgneal@665 11
bgneal@665 12 class Command(NoArgsCommand):
bgneal@665 13 help = "Finds and optionally deletes orphan downloads files"
bgneal@665 14 option_list = NoArgsCommand.option_list + (
bgneal@665 15 make_option('--delete',
bgneal@665 16 action='store_true',
bgneal@665 17 dest='delete',
bgneal@665 18 default=False,
bgneal@665 19 help='Delete orphan files'),
bgneal@665 20 )
bgneal@665 21
bgneal@665 22 def handle_noargs(self, **options):
bgneal@665 23 """Find and optionally delete orphan downloads files."""
bgneal@665 24
bgneal@665 25 delete = options.get('delete', False)
bgneal@665 26
bgneal@665 27 orphans = set()
bgneal@665 28 missing_pending = []
bgneal@665 29 missing_dls = []
bgneal@665 30
bgneal@665 31 dls_dir = os.path.join(settings.MEDIA_ROOT, 'downloads')
bgneal@665 32 # find the set of all files in the downloads area
bgneal@665 33 for root, dirs, files in os.walk(dls_dir, followlinks=True):
bgneal@665 34 for name in files:
bgneal@665 35 orphans.add(unicode(os.path.join(root, name), 'utf-8'))
bgneal@665 36
bgneal@665 37 # examine the pending downloads:
bgneal@665 38 for dl in PendingDownload.objects.iterator():
bgneal@665 39 try:
bgneal@665 40 orphans.remove(dl.file.path)
bgneal@665 41 except KeyError:
bgneal@665 42 missing_pending.append(dl)
bgneal@665 43
bgneal@665 44 # examine the downloads:
bgneal@665 45 for dl in Download.objects.iterator():
bgneal@665 46 try:
bgneal@665 47 orphans.remove(dl.file.path)
bgneal@665 48 except KeyError:
bgneal@665 49 missing_dls.append(dl)
bgneal@665 50
bgneal@667 51 if orphans and delete:
bgneal@667 52 for path in orphans:
bgneal@667 53 self.stdout.write("Deleting: {}\n".format(path))
bgneal@667 54 os.remove(path)
bgneal@667 55 elif orphans:
bgneal@667 56 self.stdout.write("Orphan files:\n")
bgneal@665 57 for orphan in orphans:
bgneal@667 58 self.stdout.write("{}\n".format(orphan))
bgneal@665 59
bgneal@665 60 if missing_pending:
bgneal@667 61 self.stdout.write("PendingDownloads with missing files:\n")
bgneal@665 62 for dl in missing_pending:
bgneal@667 63 self.stdout.write("{}\n".format(dl))
bgneal@665 64
bgneal@665 65 if missing_dls:
bgneal@667 66 self.stdout.write("Downloads with missing files:\n")
bgneal@665 67 for dl in missing_dls:
bgneal@667 68 self.stdout.write("{}\n".format(dl))
bgneal@665 69
bgneal@667 70 empty_dirs = []
bgneal@667 71 # check for empty directories after deletions
bgneal@667 72 for root, dirs, files in os.walk(dls_dir, followlinks=True):
bgneal@667 73 if not len(dirs) and not len(files):
bgneal@667 74 empty_dirs.append(root)
bgneal@665 75
bgneal@667 76 if empty_dirs and delete:
bgneal@665 77 for path in empty_dirs:
bgneal@667 78 self.stdout.write("Deleting empty dir: {}\n".format(path))
bgneal@665 79 os.removedirs(path)
bgneal@667 80 elif empty_dirs:
bgneal@667 81 self.stdout.write("Empty directories:\n")
bgneal@667 82 for d in empty_dirs:
bgneal@667 83 self.stdout.write("{}\n".format(d))