Skip to content

Commit

Permalink
Add option to management command to ignore missing file (#191)
Browse files Browse the repository at this point in the history
  • Loading branch information
marojenka authored and codingjoe committed May 15, 2018
1 parent c898b88 commit 217985b
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 8 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,12 @@ class AsyncImageModel(models.Model)
You might want to add new variations to a field. That means you need to render new variations for missing fields.
This can be accomplished using a management command.
```bash
python manage.py rendervariations 'app_name.model_name.field_name' [--replace]
python manage.py rendervariations 'app_name.model_name.field_name' [--replace] [-i/--ignore-missing]
```
The `replace` option will replace all existing files.
The `ignore-missing` option will suspend missing source file errors and keep
rendering variations for other files. Othervise command will stop on first
missing file.

### Multi processing
Since version 2 stdImage supports multiprocessing.
Expand Down
31 changes: 24 additions & 7 deletions stdimage/management/commands/rendervariations.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,16 @@ def add_arguments(self, parser):
default=False,
help='Replace existing files.')

parser.add_argument('-i', '--ignore-missing',
action='store_true',
dest='ignore_missing',
default=False,
help='Ignore missing source file error and '
'skip render for that file')

def handle(self, *args, **options):
replace = options.get('replace', False)
ignore_missing = options.get('ignore_missing', False)
routes = options.get('field_path', [])
for route in routes:
try:
Expand All @@ -48,10 +56,11 @@ def handle(self, *args, **options):
images = queryset.values_list(field_name, flat=True).iterator()
count = queryset.count()

self.render(field, images, count, replace, do_render)
self.render(field, images, count, replace, ignore_missing,
do_render)

@staticmethod
def render(field, images, count, replace, do_render):
def render(field, images, count, replace, ignore_missing, do_render):
kwargs_list = (
dict(
file_name=file_name,
Expand All @@ -60,6 +69,7 @@ def render(field, images, count, replace, do_render):
replace=replace,
storage=field.storage.deconstruct()[0],
field_class=field.attr_class,
ignore_missing=ignore_missing,
)
for file_name in images
)
Expand All @@ -77,9 +87,16 @@ def render(field, images, count, replace, do_render):

def render_field_variations(kwargs):
kwargs['storage'] = get_storage_class(kwargs['storage'])()
ignore_missing = kwargs.pop('ignore_missing')
do_render = kwargs.pop('do_render')
if callable(do_render):
kwargs.pop('field_class')
do_render = do_render(**kwargs)
if do_render:
render_variations(**kwargs)
try:
if callable(do_render):
kwargs.pop('field_class')
do_render = do_render(**kwargs)
if do_render:
render_variations(**kwargs)
except FileNotFoundError as e:
if not ignore_missing:
raise CommandError(
'Source file was not found, terminating. '
'Use -i/--ignore-missing to skip this error.') from e
42 changes: 42 additions & 0 deletions tests/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,48 @@ def test_replace(self, image_upload_file):
after = os.path.getmtime(file_path)
assert before != after

def test_ignore_missing(self, image_upload_file):
obj = ThumbnailModel.objects.create(image=image_upload_file)
file_path = obj.image.path
assert os.path.exists(file_path)
os.remove(file_path)
assert not os.path.exists(file_path)
time.sleep(1)
call_command(
'rendervariations',
'tests.ThumbnailModel.image',
'--ignore-missing',
replace=True,
)

def test_short_ignore_missing(self, image_upload_file):
obj = ThumbnailModel.objects.create(image=image_upload_file)
file_path = obj.image.path
assert os.path.exists(file_path)
os.remove(file_path)
assert not os.path.exists(file_path)
time.sleep(1)
call_command(
'rendervariations',
'tests.ThumbnailModel.image',
'-i',
replace=True,
)

def test_no_ignore_missing(self, image_upload_file):
obj = ThumbnailModel.objects.create(image=image_upload_file)
file_path = obj.image.path
assert os.path.exists(file_path)
os.remove(file_path)
assert not os.path.exists(file_path)
time.sleep(1)
with pytest.raises(CommandError):
call_command(
'rendervariations',
'tests.ThumbnailModel.image',
replace=True,
)

def test_none_default_storage(self, image_upload_file):
obj = MyStorageModel.customer_manager.create(
image=image_upload_file
Expand Down

0 comments on commit 217985b

Please sign in to comment.