Skip to content

Commit 217985b

Browse files
marojenkacodingjoe
authored andcommitted
Add option to management command to ignore missing file (#191)
1 parent c898b88 commit 217985b

File tree

3 files changed

+70
-8
lines changed

3 files changed

+70
-8
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,12 @@ class AsyncImageModel(models.Model)
196196
You might want to add new variations to a field. That means you need to render new variations for missing fields.
197197
This can be accomplished using a management command.
198198
```bash
199-
python manage.py rendervariations 'app_name.model_name.field_name' [--replace]
199+
python manage.py rendervariations 'app_name.model_name.field_name' [--replace] [-i/--ignore-missing]
200200
```
201201
The `replace` option will replace all existing files.
202+
The `ignore-missing` option will suspend missing source file errors and keep
203+
rendering variations for other files. Othervise command will stop on first
204+
missing file.
202205

203206
### Multi processing
204207
Since version 2 stdImage supports multiprocessing.

stdimage/management/commands/rendervariations.py

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,16 @@ def add_arguments(self, parser):
2424
default=False,
2525
help='Replace existing files.')
2626

27+
parser.add_argument('-i', '--ignore-missing',
28+
action='store_true',
29+
dest='ignore_missing',
30+
default=False,
31+
help='Ignore missing source file error and '
32+
'skip render for that file')
33+
2734
def handle(self, *args, **options):
2835
replace = options.get('replace', False)
36+
ignore_missing = options.get('ignore_missing', False)
2937
routes = options.get('field_path', [])
3038
for route in routes:
3139
try:
@@ -48,10 +56,11 @@ def handle(self, *args, **options):
4856
images = queryset.values_list(field_name, flat=True).iterator()
4957
count = queryset.count()
5058

51-
self.render(field, images, count, replace, do_render)
59+
self.render(field, images, count, replace, ignore_missing,
60+
do_render)
5261

5362
@staticmethod
54-
def render(field, images, count, replace, do_render):
63+
def render(field, images, count, replace, ignore_missing, do_render):
5564
kwargs_list = (
5665
dict(
5766
file_name=file_name,
@@ -60,6 +69,7 @@ def render(field, images, count, replace, do_render):
6069
replace=replace,
6170
storage=field.storage.deconstruct()[0],
6271
field_class=field.attr_class,
72+
ignore_missing=ignore_missing,
6373
)
6474
for file_name in images
6575
)
@@ -77,9 +87,16 @@ def render(field, images, count, replace, do_render):
7787

7888
def render_field_variations(kwargs):
7989
kwargs['storage'] = get_storage_class(kwargs['storage'])()
90+
ignore_missing = kwargs.pop('ignore_missing')
8091
do_render = kwargs.pop('do_render')
81-
if callable(do_render):
82-
kwargs.pop('field_class')
83-
do_render = do_render(**kwargs)
84-
if do_render:
85-
render_variations(**kwargs)
92+
try:
93+
if callable(do_render):
94+
kwargs.pop('field_class')
95+
do_render = do_render(**kwargs)
96+
if do_render:
97+
render_variations(**kwargs)
98+
except FileNotFoundError as e:
99+
if not ignore_missing:
100+
raise CommandError(
101+
'Source file was not found, terminating. '
102+
'Use -i/--ignore-missing to skip this error.') from e

tests/test_commands.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,48 @@ def test_replace(self, image_upload_file):
8383
after = os.path.getmtime(file_path)
8484
assert before != after
8585

86+
def test_ignore_missing(self, image_upload_file):
87+
obj = ThumbnailModel.objects.create(image=image_upload_file)
88+
file_path = obj.image.path
89+
assert os.path.exists(file_path)
90+
os.remove(file_path)
91+
assert not os.path.exists(file_path)
92+
time.sleep(1)
93+
call_command(
94+
'rendervariations',
95+
'tests.ThumbnailModel.image',
96+
'--ignore-missing',
97+
replace=True,
98+
)
99+
100+
def test_short_ignore_missing(self, image_upload_file):
101+
obj = ThumbnailModel.objects.create(image=image_upload_file)
102+
file_path = obj.image.path
103+
assert os.path.exists(file_path)
104+
os.remove(file_path)
105+
assert not os.path.exists(file_path)
106+
time.sleep(1)
107+
call_command(
108+
'rendervariations',
109+
'tests.ThumbnailModel.image',
110+
'-i',
111+
replace=True,
112+
)
113+
114+
def test_no_ignore_missing(self, image_upload_file):
115+
obj = ThumbnailModel.objects.create(image=image_upload_file)
116+
file_path = obj.image.path
117+
assert os.path.exists(file_path)
118+
os.remove(file_path)
119+
assert not os.path.exists(file_path)
120+
time.sleep(1)
121+
with pytest.raises(CommandError):
122+
call_command(
123+
'rendervariations',
124+
'tests.ThumbnailModel.image',
125+
replace=True,
126+
)
127+
86128
def test_none_default_storage(self, image_upload_file):
87129
obj = MyStorageModel.customer_manager.create(
88130
image=image_upload_file

0 commit comments

Comments
 (0)