Skip to content

Commit

Permalink
io_blend_utils: ship BAM as wheel file, running BAM-pack from that
Browse files Browse the repository at this point in the history
Previously we had a copy of BAM's blendfile_pack.py shipped with Blender.
Updating that was cumbersome, as changes in one copy would have to be
manually ported to the other. This is now resolved by not bundling
blendfile_pack.py at all, but to include BAM as wheel file. This wheel
file can be produced by running "python3 setup.py bdist_wheel" in the BAM
source directory, and can be bundled with Blender without further
modification.

Blender looks for a file "blender_bam-*.whl" in the io_blend_utils
directory, and loads the (alphabetically) last version. Even though there
should be only one wheel file bundled, things won't break when there happen
to be more, and Blender should pick up on the latest version (given simple
versioning schemes).
  • Loading branch information
sybrenstuvel committed Jan 17, 2017
1 parent a746a84 commit 415c234
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 623 deletions.
25 changes: 25 additions & 0 deletions io_blend_utils/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Bundling BAM with Blender
-------------------------

Blender is bundled with a version of [BAM](https://pypi.python.org/pypi/blender-bam/).
To update this version, first build a new `wheel <http:https://pythonwheels.com/>`_ file in
BAM itself:

python3 setup.py bdist_wheel

Then copy this wheel to Blender:

cp dist/blender_bam-xxx.whl /path/to/blender/release/scripts/addons/io_blend_utils/

Remove old wheels that are still in `/path/to/blender/release/scripts/addons/io_blend_utils/`
before committing.


Running bam-pack from the wheel
-------------------------------

This is the way that Blender runs bam-pack:

PYTHONPATH=./path/to/blender_bam-xxx.whl python3 -m bam.pack

52 changes: 41 additions & 11 deletions io_blend_utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,18 @@

bl_info = {
"name": "Blend File Utils",
"author": "Campbell Barton",
"version": (0, 1),
"author": "Campbell Barton and Sybren A. Stüvel",
"version": (1, 0),
"blender": (2, 76, 0),
"location": "File > External Data > Blend Utils",
"description": "Utility for packing blend files",
"warning": "",
"wiki_url": "http:https://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Import-Export/BlendFile_Utils",
"support": 'OFFICIAL',
"category": "Import-Export",
}
}

import logging

import bpy
from bpy.types import Operator
Expand All @@ -41,6 +42,7 @@ class ExportBlendPack(Operator, ExportHelper, SubprocessHelper):
"""Packs a blend file and all its dependencies into an archive for easy redistribution"""
bl_idname = "export_blend.pack"
bl_label = "Pack Blend to Archive"
log = logging.getLogger('%s.ExportBlendPack' % __name__)

# ExportHelper
filename_ext = ".zip"
Expand All @@ -55,22 +57,26 @@ def poll(cls, context):
return bpy.data.is_saved

def process_pre(self):
import os
import tempfile

self.temp_dir = tempfile.TemporaryDirectory()

filepath_blend = bpy.data.filepath

self.environ = {'PYTHONPATH': pythonpath()}
self.outfname = bpy.path.ensure_ext(self.filepath, ".zip")
self.command = (
bpy.app.binary_path_python,
os.path.join(os.path.dirname(__file__), "blendfile_pack.py"),
'-m', 'bam.pack',
# file to pack
"--input", filepath_blend,
"--input", bpy.data.filepath,
# file to write
"--output", bpy.path.ensure_ext(self.filepath, ".zip"),
"--output", self.outfname,
"--temp", self.temp_dir.name,
)
)

if self.log.isEnabledFor(logging.INFO):
import shlex
cmd_to_log = ' '.join(shlex.quote(s) for s in self.command)
self.log.info('Executing %s', cmd_to_log)

def process_post(self, returncode):
if self.temp_dir is not None:
Expand All @@ -79,6 +85,7 @@ def process_post(self, returncode):
except:
import traceback
traceback.print_exc()
self.log.info('Written to %s', self.outfname)


def menu_func(self, context):
Expand All @@ -89,7 +96,30 @@ def menu_func(self, context):

classes = (
ExportBlendPack,
)
)


def pythonpath() -> str:
"""Returns the value of a PYTHONPATH environment variable needed to run BAM from its wheel file.
"""

import os.path
import glob

log = logging.getLogger('%s.pythonpath' % __name__)

# Find the wheel to run.
my_dir = os.path.abspath(os.path.dirname(__file__))
wheelpaths = glob.glob(os.path.join(my_dir, 'blender_bam-*.whl'))
wheelpath = sorted(wheelpaths)[-1] # use the last version we find, should be only one.
log.info('Using wheel file %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


def register():
Expand Down
17 changes: 17 additions & 0 deletions io_blend_utils/bl_utils/subprocess_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
Defines an operator mix-in to use for non-blocking command line access.
"""


class SubprocessHelper:
"""
Mix-in class for operators to run commands in a non-blocking way.
Expand All @@ -39,8 +40,18 @@ class SubprocessHelper:
``process_post(returncode)``:
Callback that runs when the process has ende.
returncode is -1 if the process was terminated.
Subclass may define:
``environment``:
Dict of environment variables exposed to the subprocess.
Contrary to the subprocess.Popen(env=...) parameter, this
dict is and not used to replace the existing environment
entirely, but is just used to update it.
"""

environ = {}
command = ()

@staticmethod
def _non_blocking_readlines(f, chunk=64):
"""
Expand Down Expand Up @@ -138,14 +149,20 @@ def modal(self, context, event):

def execute(self, context):
import subprocess
import os
import copy

self.process_pre()

env = copy.deepcopy(os.environ)
env.update(self.environ)

try:
p = subprocess.Popen(
self.command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=env,
)
except FileNotFoundError as ex:
# Command not found
Expand Down
Binary file added io_blend_utils/blender_bam-1.1.1-py3-none-any.whl
Binary file not shown.
Loading

0 comments on commit 415c234

Please sign in to comment.