-
Notifications
You must be signed in to change notification settings - Fork 317
/
__init__.py
127 lines (111 loc) · 4.39 KB
/
__init__.py
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import os
import re
from easy_thumbnails.conf import settings
re_thumbnail_file = re.compile(r'(?P<source_filename>.+)_(?P<x>\d+)x(?P<y>\d+)'
r'(?:_(?P<options>\w+))?_q(?P<quality>\d+)'
r'(?:.[^.]+)?$')
def all_thumbnails(path, recursive=True, prefix=None, subdir=None):
"""
Return a dictionary referencing all files which match the thumbnail format.
Each key is a source image filename, relative to path.
Each value is a list of dictionaries as explained in `thumbnails_for_file`.
"""
if prefix is None:
prefix = settings.THUMBNAIL_PREFIX
if subdir is None:
subdir = settings.THUMBNAIL_SUBDIR
thumbnail_files = {}
if not path.endswith('/'):
path = '%s/' % path
len_path = len(path)
if recursive:
all = os.walk(path)
else:
files = []
for file in os.listdir(path):
if os.path.isfile(os.path.join(path, file)):
files.append(file)
all = [(path, [], files)]
for dir_, subdirs, files in all:
rel_dir = dir_[len_path:]
for file in files:
thumb = re_thumbnail_file.match(file)
if not thumb:
continue
d = thumb.groupdict()
source_filename = d.pop('source_filename')
if prefix:
source_path, source_filename = os.path.split(source_filename)
if not source_filename.startswith(prefix):
continue
source_filename = os.path.join(
source_path, source_filename[len(prefix):])
d['options'] = d['options'] and d['options'].split('_') or []
if subdir and rel_dir.endswith(subdir):
rel_dir = rel_dir[:-len(subdir)]
# Corner-case bug: if the filename didn't have an extension but did
# have an underscore, the last underscore will get converted to a
# '.'.
m = re.match(r'(.*)_(.*)', source_filename)
if m:
source_filename = '%s.%s' % m.groups()
filename = os.path.join(rel_dir, source_filename)
thumbnail_file = thumbnail_files.setdefault(filename, [])
d['filename'] = os.path.join(dir_, file)
thumbnail_file.append(d)
return thumbnail_files
def thumbnails_for_file(relative_source_path, root=None, basedir=None,
subdir=None, prefix=None):
"""
Return a list of dictionaries, one for each thumbnail belonging to the
source image.
The following list explains each key of the dictionary:
`filename` -- absolute thumbnail path
`x` and `y` -- the size of the thumbnail
`options` -- list of options for this thumbnail
`quality` -- quality setting for this thumbnail
"""
if root is None:
root = settings.MEDIA_ROOT
if prefix is None:
prefix = settings.THUMBNAIL_PREFIX
if subdir is None:
subdir = settings.THUMBNAIL_SUBDIR
if basedir is None:
basedir = settings.THUMBNAIL_BASEDIR
source_dir, filename = os.path.split(relative_source_path)
thumbs_path = os.path.join(root, basedir, source_dir, subdir)
if not os.path.isdir(thumbs_path):
return []
files = all_thumbnails(thumbs_path, recursive=False, prefix=prefix,
subdir='')
return files.get(filename, [])
def delete_thumbnails(relative_source_path, root=None, basedir=None,
subdir=None, prefix=None):
"""
Delete all thumbnails for a source image.
"""
thumbs = thumbnails_for_file(relative_source_path, root, basedir, subdir,
prefix)
return _delete_using_thumbs_list(thumbs)
def _delete_using_thumbs_list(thumbs):
deleted = 0
for thumb_dict in thumbs:
filename = thumb_dict['filename']
try:
os.remove(filename)
except:
pass
else:
deleted += 1
return deleted
def delete_all_thumbnails(path, recursive=True):
"""
Delete all files within a path which match the thumbnails pattern.
By default, matching files from all sub-directories are also removed. To
only remove from the path directory, set recursive=False.
"""
total = 0
for thumbs in all_thumbnails(path, recursive=recursive).values():
total += _delete_using_thumbs_list(thumbs)
return total