1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
import fnmatch
import os
from django.core.management.base import BaseCommand, CommandError
from compressor.conf import settings
from compressor.cache import cache, get_mtime, get_mtime_cachekey
class Command(BaseCommand):
help = "Add or remove all mtime values from the cache"
def add_arguments(self, parser):
parser.add_argument(
"-i",
"--ignore",
action="append",
default=[],
dest="ignore_patterns",
metavar="PATTERN",
help="Ignore files or directories matching this glob-style "
"pattern. Use multiple times to ignore more.",
),
parser.add_argument(
"--no-default-ignore",
action="store_false",
dest="use_default_ignore_patterns",
default=True,
help="Don't ignore the common private glob-style patterns 'CVS', "
"'.*' and '*~'.",
),
parser.add_argument(
"--follow-links",
dest="follow_links",
action="store_true",
help="Follow symlinks when traversing the COMPRESS_ROOT "
"(which defaults to STATIC_ROOT). Be aware that using this "
"can lead to infinite recursion if a link points to a parent "
"directory of itself.",
),
parser.add_argument(
"-c", "--clean", dest="clean", action="store_true", help="Remove all items"
),
parser.add_argument(
"-a", "--add", dest="add", action="store_true", help="Add all items"
),
def is_ignored(self, path):
"""
Return True or False depending on whether the ``path`` should be
ignored (if it matches any pattern in ``ignore_patterns``).
"""
for pattern in self.ignore_patterns:
if fnmatch.fnmatchcase(path, pattern):
return True
return False
def handle(self, **options):
ignore_patterns = options["ignore_patterns"]
if options["use_default_ignore_patterns"]:
ignore_patterns += ["CVS", ".*", "*~"]
options["ignore_patterns"] = ignore_patterns
self.ignore_patterns = ignore_patterns
if (options["add"] and options["clean"]) or (
not options["add"] and not options["clean"]
):
raise CommandError('Please specify either "--add" or "--clean"')
if not settings.COMPRESS_MTIME_DELAY:
raise CommandError(
"mtime caching is currently disabled. Please "
"set the COMPRESS_MTIME_DELAY setting to a number of seconds."
)
files_to_add = set()
keys_to_delete = set()
for root, dirs, files in os.walk(
settings.COMPRESS_ROOT, followlinks=options["follow_links"]
):
for dir_ in dirs:
if self.is_ignored(dir_):
dirs.remove(dir_)
for filename in files:
common = "".join(root.split(settings.COMPRESS_ROOT))
if common.startswith(os.sep):
common = common[len(os.sep) :]
if self.is_ignored(os.path.join(common, filename)):
continue
filename = os.path.join(root, filename)
keys_to_delete.add(get_mtime_cachekey(filename))
if options["add"]:
files_to_add.add(filename)
if keys_to_delete:
cache.delete_many(list(keys_to_delete))
self.stdout.write(
"Deleted mtimes of %d files from the cache." % len(keys_to_delete)
)
if files_to_add:
for filename in files_to_add:
get_mtime(filename)
self.stdout.write("Added mtimes of %d files to cache." % len(files_to_add))
|