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 empty_dirs = []
|
bgneal@665
|
31
|
bgneal@665
|
32 dls_dir = os.path.join(settings.MEDIA_ROOT, 'downloads')
|
bgneal@665
|
33 # find the set of all files in the downloads area
|
bgneal@665
|
34 for root, dirs, files in os.walk(dls_dir, followlinks=True):
|
bgneal@665
|
35 for name in files:
|
bgneal@665
|
36 orphans.add(unicode(os.path.join(root, name), 'utf-8'))
|
bgneal@665
|
37
|
bgneal@665
|
38 # check for empty directories
|
bgneal@665
|
39 if not len(dirs) and not len(files):
|
bgneal@665
|
40 empty_dirs.append(root)
|
bgneal@665
|
41
|
bgneal@665
|
42 # examine the pending downloads:
|
bgneal@665
|
43 for dl in PendingDownload.objects.iterator():
|
bgneal@665
|
44 try:
|
bgneal@665
|
45 orphans.remove(dl.file.path)
|
bgneal@665
|
46 except KeyError:
|
bgneal@665
|
47 missing_pending.append(dl)
|
bgneal@665
|
48
|
bgneal@665
|
49 # examine the downloads:
|
bgneal@665
|
50 for dl in Download.objects.iterator():
|
bgneal@665
|
51 try:
|
bgneal@665
|
52 orphans.remove(dl.file.path)
|
bgneal@665
|
53 except KeyError:
|
bgneal@665
|
54 missing_dls.append(dl)
|
bgneal@665
|
55
|
bgneal@665
|
56 if orphans:
|
bgneal@665
|
57 print "Orphan files:"
|
bgneal@665
|
58 for orphan in orphans:
|
bgneal@665
|
59 print orphan
|
bgneal@665
|
60
|
bgneal@665
|
61 if empty_dirs:
|
bgneal@665
|
62 print "Empty directories:"
|
bgneal@665
|
63 for d in empty_dirs:
|
bgneal@665
|
64 print d
|
bgneal@665
|
65
|
bgneal@665
|
66 if missing_pending:
|
bgneal@665
|
67 print "PendingDownloads with missing files:"
|
bgneal@665
|
68 for dl in missing_pending:
|
bgneal@665
|
69 print dl
|
bgneal@665
|
70
|
bgneal@665
|
71 if missing_dls:
|
bgneal@665
|
72 print "Downloads with missing files:"
|
bgneal@665
|
73 for dl in missing_dls:
|
bgneal@665
|
74 print dl
|
bgneal@665
|
75
|
bgneal@665
|
76 if delete:
|
bgneal@665
|
77 for path in orphans:
|
bgneal@665
|
78 print "Deleting: {}".format(path)
|
bgneal@665
|
79 os.remove(path)
|
bgneal@665
|
80
|
bgneal@665
|
81 for path in empty_dirs:
|
bgneal@665
|
82 print "Deleting: {}".format(path)
|
bgneal@665
|
83 os.removedirs(path)
|