[Bf-extensions-cvs] [c03411a3] master: io_blend_utils: moved to contrib: T63750

meta-androcto noreply at git.blender.org
Thu Jul 4 12:16:06 CEST 2019


Commit: c03411a312a59b893adf46cc04d4a9b85262e407
Author: meta-androcto
Date:   Thu Jul 4 20:15:39 2019 +1000
Branches: master
https://developer.blender.org/rBACc03411a312a59b893adf46cc04d4a9b85262e407

io_blend_utils: moved to contrib: T63750

===================================================================

A	io_blend_utils/README.md
A	io_blend_utils/__init__.py
A	io_blend_utils/bl_utils/pipe_non_blocking.py
A	io_blend_utils/bl_utils/subprocess_helper.py
A	io_blend_utils/blend/blendfile.py
A	io_blend_utils/blend/blendfile_path_walker.py
A	io_blend_utils/blender_bam-unpacked.whl/bam/__init__.py
A	io_blend_utils/blender_bam-unpacked.whl/bam/__main__.py
A	io_blend_utils/blender_bam-unpacked.whl/bam/blend/__init__.py
A	io_blend_utils/blender_bam-unpacked.whl/bam/blend/blendfile.py
A	io_blend_utils/blender_bam-unpacked.whl/bam/blend/blendfile_copy.py
A	io_blend_utils/blender_bam-unpacked.whl/bam/blend/blendfile_pack.py
A	io_blend_utils/blender_bam-unpacked.whl/bam/blend/blendfile_pack_restore.py
A	io_blend_utils/blender_bam-unpacked.whl/bam/blend/blendfile_path_remap.py
A	io_blend_utils/blender_bam-unpacked.whl/bam/blend/blendfile_path_walker.py
A	io_blend_utils/blender_bam-unpacked.whl/bam/cli.py
A	io_blend_utils/blender_bam-unpacked.whl/bam/pack.py
A	io_blend_utils/blender_bam-unpacked.whl/bam/utils/__init__.py
A	io_blend_utils/blender_bam-unpacked.whl/bam/utils/system.py
A	io_blend_utils/install_whl.py
A	io_blend_utils/utils/system.py

===================================================================

diff --git a/io_blend_utils/README.md b/io_blend_utils/README.md
new file mode 100644
index 00000000..bfff16b9
--- /dev/null
+++ b/io_blend_utils/README.md
@@ -0,0 +1,37 @@
+Updating this module
+--------------------
+
+This module contains copies of files belonging to
+[BAM](https://pypi.python.org/pypi/blender-bam/). Fixes should be
+committed to BAM and then copied here, to keep versions in sync.
+
+
+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://pythonwheels.com/) file in
+BAM itself:
+
+    python3 setup.py bdist_wheel
+
+Since we do not want to have binaries in the addons repository, unpack this wheel to Blender
+by running:
+
+    python3 install_whl.py /path/to/blender-asset-manager/dist/blender_bam-xxx.whl
+
+This script also updates `__init__.py` to update the version number of the extracted
+wheel, and removes any pre-existing older versions of the BAM wheels.
+
+The version number and `.whl` extension are maintained in the directory name on purpose.
+This way it is clear that it is not a directory to import directly into Blender itself.
+Furthermore, I (Sybren) hope that it helps to get changes made in the addons repository
+back into the BAM repository.
+
+
+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
diff --git a/io_blend_utils/__init__.py b/io_blend_utils/__init__.py
new file mode 100644
index 00000000..9d102102
--- /dev/null
+++ b/io_blend_utils/__init__.py
@@ -0,0 +1,149 @@
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+# ***** END GPL LICENCE BLOCK *****
+
+bl_info = {
+    "name": "Blend File Utils",
+    "author": "Campbell Barton and Sybren A. Stüvel",
+    "version": (1, 1, 7),
+    "blender": (2, 76, 0),
+    "location": "File > External Data > Blend Utils",
+    "description": "Utility for packing blend files",
+    "warning": "",
+    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Import-Export/BlendFile_Utils",
+    "support": 'OFFICIAL',
+    "category": "Import-Export",
+}
+
+BAM_WHEEL_PATH = 'blender_bam-unpacked.whl'
+
+import logging
+
+import bpy
+from bpy.types import Operator
+from bpy_extras.io_utils import ExportHelper
+
+from .bl_utils.subprocess_helper import SubprocessHelper
+
+
+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"
+
+    # SubprocessHelper
+    report_interval = 0.25
+
+    temp_dir = None
+
+    @classmethod
+    def poll(cls, context):
+        return bpy.data.is_saved
+
+    def process_pre(self):
+        import tempfile
+
+        self.temp_dir = tempfile.TemporaryDirectory()
+
+        self.environ = {'PYTHONPATH': pythonpath()}
+        self.outfname = bpy.path.ensure_ext(self.filepath, ".zip")
+        self.command = (
+            bpy.app.binary_path_python,
+            '-m', 'bam.pack',
+            # file to pack
+            "--input", bpy.data.filepath,
+            # file to write
+            "--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 None:
+            return
+
+        try:
+            self.log.debug('Cleaning up temp dir %s', self.temp_dir)
+            self.temp_dir.cleanup()
+        except FileNotFoundError:
+            # This is expected, the directory was already removed by BAM.
+            pass
+        except Exception:
+            self.log.exception('Unable to clean up temp dir %s', self.temp_dir)
+
+        self.log.info('Written to %s', self.outfname)
+
+
+def menu_func(self, context):
+    layout = self.layout
+    layout.separator()
+    layout.operator(ExportBlendPack.bl_idname)
+
+
+classes = (
+    ExportBlendPack,
+)
+
+
+def pythonpath() -> str:
+    """Returns the value of a PYTHONPATH environment variable needed to run BAM from its wheel file.
+    """
+
+    import os
+    import pathlib
+
+    log = logging.getLogger('%s.pythonpath' % __name__)
+
+    # Find the wheel to run.
+    wheelpath = pathlib.Path(__file__).with_name(BAM_WHEEL_PATH)
+    if not wheelpath.exists():
+        raise EnvironmentError('Wheel %s does not exist!' % wheelpath)
+
+    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, str(wheelpath)))
+
+    return str(wheelpath)
+
+
+def register():
+    for cls in classes:
+        bpy.utils.register_class(cls)
+
+    bpy.types.TOPBAR_MT_file_external_data.append(menu_func)
+
+
+def unregister():
+    for cls in classes:
+        bpy.utils.unregister_class(cls)
+
+    bpy.types.TOPBAR_MT_file_external_data.remove(menu_func)
+
+
+if __name__ == "__main__":
+    register()
diff --git a/io_blend_utils/bl_utils/pipe_non_blocking.py b/io_blend_utils/bl_utils/pipe_non_blocking.py
new file mode 100644
index 00000000..ead0a738
--- /dev/null
+++ b/io_blend_utils/bl_utils/pipe_non_blocking.py
@@ -0,0 +1,100 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+"""
+Example use:
+
+    p = subprocess.Popen(
+            command,
+            stdout=subprocess.PIPE,
+            )
+
+    pipe_non_blocking_set(p.stdout.fileno())
+
+    try:
+        data = os.read(p.stdout.fileno(), 1)
+    except PortableBlockingIOError as ex:
+        if not pipe_non_blocking_is_error_blocking(ex):
+            raise ex
+"""
+
+
+__all__ = (
+    "pipe_non_blocking_set",
+    "pipe_non_blocking_is_error_blocking",
+    "PortableBlockingIOError",
+    )
+
+import os
+
+
+if os.name == "nt":
+    # MS-Windows Version
+    def pipe_non_blocking_set(fd):
+        # Constant could define globally but avoid polluting the name-space
+        # thanks to: http://stackoverflow.com/questions/34504970
+        import msvcrt
+
+        from ctypes import windll, byref, wintypes, WinError, POINTER
+        from ctypes.wintypes import HANDLE, DWORD, BOOL
+
+        LPDWORD = POINTER(DWORD)
+
+        PIPE_NOWAIT = wintypes.DWORD(0x00000001)
+
+        def pipe_no_wait(pipefd):
+            SetNamedPipeHandleState = windll.kernel32.SetNamedPipeHandleState
+            SetNamedPipeHandleState.argtypes = [HANDLE, LPDWORD, LPDWORD, LPDWORD]
+            SetNamedPipeHandleState.restype = BOOL
+
+            h = msvcrt.get_osfhandle(pipefd)
+
+            res = windll.kernel32.SetNamedPipeHandleState(h, byref(PIPE_NOWAIT), None, None)
+            if res == 0:
+                print(WinError())
+                return False
+            return True
+
+        return pipe_no_wait(fd)
+
+    def pipe_non_blocking_is_error_blocking(ex):
+        if not isinstance(ex, PortableBlockingIOError):
+            return False
+        from ctypes import GetLastError
+        ERROR_NO_DATA = 232
+
+        return (GetLastError() == ERROR_NO_DATA)
+
+    PortableBlockingIOError = OSError
+else:
+    # Posix Version
+    def pipe_non_blocking_set(fd):
+        import fcntl
+        fl = fcntl.fcntl(fd, fcntl.F_GETFL)
+        fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
+        return True
+
+    # only for compatibility with 'nt' version.
+    def pipe_non_blocking_is_error_blocking(ex):
+        if not isinstance(ex, PortableBlockingIOError):
+            return False
+        return True
+
+    PortableBlockingIOError = BlockingIOError
diff --git a/io_blend_utils/bl_utils/subprocess_helper.py b/io_blend_utils/bl_utils/subprocess_helper.py
new file mode 100644
index 00000000..f7750af7
--- /dev/null
+++ b/io_blend_utils/bl_utils/subprocess_helper.py
@@ -0,0 +1,188 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list