annotate bio/management/commands/avatar_cleanup.py @ 1157:e4f2d6a4b401

Rework S3 connection logic for latest versions of Python 2.7. Had to make these changes for Ubuntu 16.04. Seems backward compatible with production.
author Brian Neal <bgneal@gmail.com>
date Thu, 19 Jan 2017 18:35:53 -0600
parents 644f69e1c1e1
children
rev   line source
bgneal@668 1 """avatar_cleanup - a management command to remove orphaned avatar files."""
bgneal@668 2
bgneal@668 3 from optparse import make_option
bgneal@668 4 import os
bgneal@668 5
bgneal@668 6 from django.core.management.base import NoArgsCommand
bgneal@668 7 from django.conf import settings
bgneal@668 8
bgneal@668 9 from bio.models import UserProfile
bgneal@668 10
bgneal@668 11
bgneal@668 12 class Command(NoArgsCommand):
bgneal@668 13 help = "Finds and optionally deletes orphan avatar files"
bgneal@668 14 option_list = NoArgsCommand.option_list + (
bgneal@668 15 make_option('--delete',
bgneal@668 16 action='store_true',
bgneal@668 17 dest='delete',
bgneal@668 18 default=False,
bgneal@668 19 help='Delete orphan files'),
bgneal@668 20 )
bgneal@668 21
bgneal@668 22 def handle_noargs(self, **options):
bgneal@668 23 """Find and optionally delete orphan avatar files."""
bgneal@668 24
bgneal@668 25 delete = options.get('delete', False)
bgneal@668 26
bgneal@668 27 orphans = set()
bgneal@668 28 missing = []
bgneal@668 29
bgneal@668 30 avatar_dir = os.path.join(settings.MEDIA_ROOT, settings.AVATAR_DIR)
bgneal@668 31 default_avatar = os.path.join(avatar_dir,
bgneal@668 32 settings.AVATAR_DEFAULT_URL.split('/')[-1])
bgneal@668 33
bgneal@668 34 # find the set of all files in the downloads area
bgneal@668 35 for root, dirs, files in os.walk(avatar_dir, followlinks=True):
bgneal@668 36 for name in files:
bgneal@668 37 orphans.add(unicode(os.path.join(root, name), 'utf-8'))
bgneal@668 38
bgneal@668 39 try:
bgneal@668 40 orphans.remove(default_avatar)
bgneal@668 41 except KeyError:
bgneal@668 42 self.stderr.write("Default avatar file missing! - {}\n".format(
bgneal@668 43 default_avatar))
bgneal@668 44
bgneal@668 45 # examine the UserProfile objects
bgneal@668 46 for profile in UserProfile.objects.iterator():
bgneal@668 47 if profile.avatar:
bgneal@668 48 try:
bgneal@668 49 orphans.remove(profile.avatar.path)
bgneal@668 50 except KeyError:
bgneal@668 51 missing.append(profile)
bgneal@668 52
bgneal@668 53 if orphans and delete:
bgneal@668 54 for path in orphans:
bgneal@668 55 self.stdout.write("Deleting: {}\n".format(path))
bgneal@668 56 os.remove(path)
bgneal@668 57 elif orphans:
bgneal@668 58 self.stdout.write("Orphan files:\n")
bgneal@668 59 for orphan in orphans:
bgneal@668 60 self.stdout.write("{}\n".format(orphan))
bgneal@668 61
bgneal@668 62 if missing:
bgneal@668 63 self.stdout.write("Users with missing avatar files:\n")
bgneal@668 64 for profile in missing:
bgneal@668 65 self.stdout.write("{}\n".format(profile.user.username))
bgneal@668 66
bgneal@668 67 empty_dirs = []
bgneal@668 68 # check for empty directories after deletions
bgneal@668 69 for root, dirs, files in os.walk(avatar_dir, followlinks=True):
bgneal@668 70 if not len(dirs) and not len(files):
bgneal@668 71 empty_dirs.append(root)
bgneal@668 72
bgneal@668 73 if empty_dirs and delete:
bgneal@668 74 for path in empty_dirs:
bgneal@668 75 self.stdout.write("Deleting empty dir: {}\n".format(path))
bgneal@668 76 os.removedirs(path)
bgneal@668 77 elif empty_dirs:
bgneal@668 78 self.stdout.write("Empty directories:\n")
bgneal@668 79 for d in empty_dirs:
bgneal@668 80 self.stdout.write("{}\n".format(d))