diff --git a/flamenco_worker/commands.py b/flamenco_worker/commands.py index c95ff082b2a76c2a14697a1aafc4c20c7cc969d0..0b7d19bd4ff321041622d12830f4e8b90c40ba48 100644 --- a/flamenco_worker/commands.py +++ b/flamenco_worker/commands.py @@ -740,19 +740,37 @@ class BlenderRenderCommand(AbstractSubprocessCommand): return super().validate(settings) async def execute(self, settings: Settings): - cmd = self._build_blender_cmd(settings) + cmd = await self._build_blender_cmd(settings) await self.worker.register_task_update(activity='Starting Blender') await self.subprocess(cmd) - def _build_blender_cmd(self, settings): + async def _build_blender_cmd(self, settings): + filepath = settings['filepath'] + cmd = settings['blender_cmd'][:] cmd += [ '--enable-autoexec', '-noaudio', '--background', - settings['filepath'], + filepath, ] + + # See if there is an override file to load. + try: + index = filepath.lower().rindex('.blend') + except ValueError: + # No '.blend' in the filepath. Weird. + pass + else: + override_filepath = filepath[:index] + '-overrides.py' + if Path(override_filepath).exists(): + msg = f'Override file found in {override_filepath}' + self._log.info(msg) + await self.worker.register_log(msg) + + cmd.extend(['--python', override_filepath]) + if settings.get('python_expr'): cmd.extend(['--python-expr', settings['python_expr']]) if settings.get('render_output'): @@ -855,8 +873,8 @@ class BlenderRenderProgressiveCommand(BlenderRenderCommand): if cycles_chunk < 1: return '"cycles_chunk" must be a positive integer' - def _build_blender_cmd(self, settings): - cmd = super()._build_blender_cmd(settings) + async def _build_blender_cmd(self, settings): + cmd = await super()._build_blender_cmd(settings) return cmd + [ '--', @@ -970,7 +988,7 @@ class BlenderRenderAudioCommand(BlenderRenderCommand): if err: return err - def _build_blender_cmd(self, settings: Settings) -> typing.List[str]: + async def _build_blender_cmd(self, settings: Settings) -> typing.List[str]: frame_start = settings.get('frame_start') frame_end = settings.get('frame_end') render_output = settings.get('render_output') diff --git a/tests/test_commands_blender_render.py b/tests/test_commands_blender_render.py index caa1a560bd1ddb1b051a8b6948076766888ab43d..cf4362317a976ad7593e0941acec8995802e2595 100644 --- a/tests/test_commands_blender_render.py +++ b/tests/test_commands_blender_render.py @@ -1,5 +1,6 @@ from pathlib import Path import subprocess +import tempfile from unittest import mock from unittest.mock import patch @@ -152,3 +153,44 @@ class BlenderRenderTest(AbstractCommandTest): stdout=subprocess.PIPE, stderr=subprocess.STDOUT, ) + + def test_cli_args_override_file(self): + """Test that an override file next to the blend file is recognised.""" + from tests.mock_responses import CoroMock + + with tempfile.TemporaryDirectory() as tempdir: + temppath = Path(tempdir) + + blendpath = temppath / 'thefile.blend' + blendpath.touch() + override = temppath / 'thefile-overrides.py' + override.touch() + + settings = { + # Point blender_cmd to this file so that we're sure it exists. + 'blender_cmd': __file__, + 'chunk_size': 100, + 'frames': '1..2', + 'format': 'JPEG', + 'filepath': str(blendpath), + } + + cse = CoroMock(...) + cse.coro.return_value.wait = CoroMock(return_value=0) + cse.coro.return_value.pid = 47 + with patch('asyncio.create_subprocess_exec', new=cse) as mock_cse: + self.loop.run_until_complete(self.cmd.run(settings)) + + mock_cse.assert_called_once_with( + __file__, + '--enable-autoexec', + '-noaudio', + '--background', + str(blendpath), + '--python', str(override), + '--render-format', 'JPEG', + '--render-frame', '1..2', + stdin=subprocess.DEVNULL, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + )