Ignore compressed statics.
[redakcja.git] / apps / sorl / thumbnail / management / commands / thumbnail_cleanup.py
1 import os
2 import re
3 from django.db import models
4 from django.conf import settings
5 from django.core.management.base import NoArgsCommand
6 from sorl.thumbnail.main import get_thumbnail_setting
7
8
9 try:
10     set
11 except NameError:
12     from sets import Set as set     # For Python 2.3
13
14 thumb_re = re.compile(r'^%s(.*)_\d{1,}x\d{1,}_[-\w]*q([1-9]\d?|100)\.jpg' %
15                       get_thumbnail_setting('PREFIX'))
16
17
18 def get_thumbnail_path(path):
19     basedir = get_thumbnail_setting('BASEDIR')
20     subdir = get_thumbnail_setting('SUBDIR')
21     return os.path.join(basedir, path, subdir)
22
23
24 def clean_up():
25     paths = set()
26     for app in models.get_apps():
27         model_list = models.get_models(app)
28         for model in model_list:
29             for field in model._meta.fields:
30                 if isinstance(field, models.ImageField):
31                     #TODO: take care of date formatted and callable upload_to.
32                     if (not callable(field.upload_to) and
33                             field.upload_to.find("%") == -1):
34                         paths = paths.union((field.upload_to,))
35     paths = list(paths)
36     for path in paths:
37         thumbnail_path = get_thumbnail_path(path)
38         try:
39             file_list = os.listdir(os.path.join(settings.MEDIA_ROOT,
40                                                 thumbnail_path))
41         except OSError:
42             continue # Dir doesn't exists, no thumbnails here.
43         for fn in file_list:
44             m = thumb_re.match(fn)
45             if m:
46                 # Due to that the naming of thumbnails replaces the dot before
47                 # extension with an underscore we have 2 possibilities for the
48                 # original filename. If either present we do not delete
49                 # suspected thumbnail.
50                 # org_fn is the expected original filename w/o extension
51                 # org_fn_alt is the expected original filename with extension
52                 org_fn = m.group(1)
53                 org_fn_exists = os.path.isfile(
54                             os.path.join(settings.MEDIA_ROOT, path, org_fn))
55
56                 usc_pos = org_fn.rfind("_")
57                 if usc_pos != -1:
58                     org_fn_alt = "%s.%s" % (org_fn[0:usc_pos],
59                                             org_fn[usc_pos+1:])
60                     org_fn_alt_exists = os.path.isfile(
61                         os.path.join(settings.MEDIA_ROOT, path, org_fn_alt))
62                 else:
63                     org_fn_alt_exists = False
64                 if not org_fn_exists and not org_fn_alt_exists:
65                     del_me = os.path.join(settings.MEDIA_ROOT,
66                                           thumbnail_path, fn)
67                     os.remove(del_me)
68
69
70 class Command(NoArgsCommand):
71     help = "Deletes thumbnails that no longer have an original file."
72     requires_model_validation = False
73
74     def handle_noargs(self, **options):
75         clean_up()