annotate downloads/management/commands/dlorphan.py @ 887:9a15f7c27526

Actually save model object upon change. This commit was tested on the comments model. Additional logging added. Added check for Markdown image references. Added TODOs after observing behavior on comments.
author Brian Neal <bgneal@gmail.com>
date Tue, 03 Feb 2015 21:09:44 -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))