diff --git a/CHANGELOG.md b/CHANGELOG.md index 48594a9..10cc186 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ # Blender Cloud changelog +## Version 1.7.2 (in development) + +- Fixed compatibility with Blender 2.78c. + + ## Version 1.7.1 (2017-06-13) - Fixed asyncio issues on Windows diff --git a/blender_cloud/blender.py b/blender_cloud/blender.py index 5b4fc46..f6a7b81 100644 --- a/blender_cloud/blender.py +++ b/blender_cloud/blender.py @@ -461,16 +461,7 @@ class BlenderCloudPreferences(AddonPreferences): path_box.prop(self, 'flamenco_job_output_path', text='') props = path_box.operator('flamenco.explore_file_path', text='', icon='DISK_DRIVE') props.path = self.flamenco_job_output_path - - show_warning = bool(self.flamenco_exclude_filter and - not bam_interface.bam_supports_exclude_option()) - job_output_box.alert = show_warning - job_output_box.prop(self, 'flamenco_exclude_filter', - icon='ERROR' if show_warning else 'NONE') - if show_warning: - job_output_box.label( - text='Warning, the exclusion filter requires a newer version of Blender!') - job_output_box.alert = False + job_output_box.prop(self, 'flamenco_exclude_filter') prop_split = job_output_box.split(0.32, align=True) prop_split.label('Strip Components:') diff --git a/blender_cloud/flamenco/bam_interface.py b/blender_cloud/flamenco/bam_interface.py index a75f50b..7d4737f 100644 --- a/blender_cloud/flamenco/bam_interface.py +++ b/blender_cloud/flamenco/bam_interface.py @@ -1,6 +1,5 @@ """BAM packing interface for Flamenco.""" -import functools import logging from pathlib import Path import typing @@ -15,26 +14,26 @@ class CommandExecutionError(Exception): pass -if 'bam_supports_exclude_option' in locals(): - locals()['bam_supports_exclude_option'].cache_clear() +def wheel_pythonpath_278() -> str: + """Returns the value of a PYTHONPATH environment variable needed to run BAM from its wheel file. - -@functools.lru_cache(maxsize=1) -def bam_supports_exclude_option() -> bool: - """Returns True if the version of BAM bundled with Blender supports --exclude. - - This feature was added to BAM 1.1.7, so we can do a simple version check. + Workaround for Blender 2.78c not having io_blend_utils.pythonpath() """ - try: - import io_blend_utils - except ImportError: - # If this happens, BAM won't work at all. However, this function can be called from - # the GUI; by being a bit careful while importing, we avoid breaking Blender's GUI. - log.exception('Error importing io_blend_utils module.') - return False + import os + from ..wheels import wheel_filename - return io_blend_utils.bl_info['version'] >= (1, 1, 7) + # Find the wheel to run. + wheelpath = wheel_filename('blender_bam') + + log.info('Using wheel %s to run BAM-Pack', wheelpath) + + # Update the PYTHONPATH to include that wheel. + existing_pypath = os.environ.get('PYTHONPATH', '') + if existing_pypath: + return os.pathsep.join((existing_pypath, wheelpath)) + + return wheelpath async def bam_copy(base_blendfile: Path, target_blendfile: Path, @@ -66,18 +65,20 @@ async def bam_copy(base_blendfile: Path, target_blendfile: Path, ] if exclusion_filter: - if bam_supports_exclude_option(): - args.extend(['--exclude', exclusion_filter]) - else: - log.warning('Your version of Blender does not support the exclusion filter, ' - 'copying all files.') + args.extend(['--exclude', exclusion_filter]) cmd_to_log = ' '.join(shlex.quote(s) for s in args) log.info('Executing %s', cmd_to_log) + # Workaround for Blender 2.78c not having io_blend_utils.pythonpath() + if hasattr(io_blend_utils, 'pythonpath'): + pythonpath = io_blend_utils.pythonpath() + else: + pythonpath = wheel_pythonpath_278() + proc = await asyncio.create_subprocess_exec( *args, - env={'PYTHONPATH': io_blend_utils.pythonpath()}, + env={'PYTHONPATH': pythonpath}, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, diff --git a/blender_cloud/wheels/__init__.py b/blender_cloud/wheels/__init__.py index 0edf4c9..24f01d3 100644 --- a/blender_cloud/wheels/__init__.py +++ b/blender_cloud/wheels/__init__.py @@ -44,6 +44,12 @@ def load_wheel(module_name, fname_prefix): module_name, module.__file__, fname_prefix) return + sys.path.append(wheel_filename(fname_prefix)) + module = __import__(module_name) + log.debug('Loaded %s from %s', module_name, module.__file__) + + +def wheel_filename(fname_prefix: str) -> str: path_pattern = os.path.join(my_dir, '%s*.whl' % fname_prefix) wheels = glob.glob(path_pattern) if not wheels: @@ -51,9 +57,7 @@ def load_wheel(module_name, fname_prefix): # If there are multiple wheels that match, load the latest one. wheels.sort() - sys.path.append(wheels[-1]) - module = __import__(module_name) - log.debug('Loaded %s from %s', module_name, module.__file__) + return wheels[-1] def load_wheels(): diff --git a/requirements.txt b/requirements.txt index b06f529..bd3d179 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,6 +3,7 @@ lockfile==0.12.2 pillarsdk==1.6.1 wheel==0.29.0 +blender-bam==1.1.7 # Secondary requirements: cffi==1.6.0 diff --git a/setup.py b/setup.py index 9a972e0..fc6c06f 100755 --- a/setup.py +++ b/setup.py @@ -101,6 +101,11 @@ class BuildWheels(Command): log.info('Downloading Pillar Python SDK wheel') self.download_wheel(requirements['pillarsdk']) + # Download BAM from pypi. This is required for compatibility with Blender 2.78. + if not list(self.wheels_path.glob('blender_bam*.whl')): + log.info('Downloading BAM wheel') + self.download_wheel(requirements['blender-bam']) + # Build CacheControl. if not list(self.wheels_path.glob('CacheControl*.whl')): log.info('Building CacheControl in %s', self.cachecontrol_path)