From 7d7fede5b2df3f8ba5177b73fceaa478a6a5eb9b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 9 Jun 2015 03:08:18 +1000 Subject: [PATCH] Support context manager for opening blend file --- bam/__init__.py | 2 +- bam/blend/blendfile.py | 6 ++ bam/blend/blendfile_path_walker.py | 100 ++++++++++++++--------------- 3 files changed, 57 insertions(+), 51 deletions(-) diff --git a/bam/__init__.py b/bam/__init__.py index 260cb8b..619a557 100644 --- a/bam/__init__.py +++ b/bam/__init__.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- import sys -__version__ = "0.0.4.7" +__version__ = "0.0.4.8" def main(argv=sys.argv): from .cli import main diff --git a/bam/blend/blendfile.py b/bam/blend/blendfile.py index 3a1b0a3..d171140 100644 --- a/bam/blend/blendfile.py +++ b/bam/blend/blendfile.py @@ -145,6 +145,12 @@ class BlendFile: # cache (could lazy init, incase we never use?) self.block_from_offset = {block.addr_old: block for block in self.blocks if block.code != b'ENDB'} + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + self.close() + def find_blocks_from_code(self, code): assert(type(code) == bytes) if code not in self.code_index: diff --git a/bam/blend/blendfile_path_walker.py b/bam/blend/blendfile_path_walker.py index b38728d..c286966 100644 --- a/bam/blend/blendfile_path_walker.py +++ b/bam/blend/blendfile_path_walker.py @@ -396,62 +396,62 @@ class FilePath: extra_info = rootdir, os.path.basename(filepath) from bam.blend import blendfile - blend = blendfile.open_blend(filepath_tmp, "rb" if readonly else "r+b") + with blendfile.open_blend(filepath_tmp, "rb" if readonly else "r+b") as blend: - for code in blend.code_index.keys(): - # handle library blocks as special case - if ((len(code) != 2) or - (code in { - # libraries handled below - b'LI', - b'ID', - # unneeded - b'WM', - b'SN', # bScreen - })): + for code in blend.code_index.keys(): + # handle library blocks as special case + if ((len(code) != 2) or + (code in { + # libraries handled below + b'LI', + b'ID', + # unneeded + b'WM', + b'SN', # bScreen + })): - continue + continue - # if VERBOSE: - # print(" Scanning", code) + # if VERBOSE: + # print(" Scanning", code) - for block in iter_blocks_id(code): + for block in iter_blocks_id(code): + yield from FilePath.from_block(block, basedir, extra_info, level) + + # print("A:", expand_addr_visit) + # print("B:", block_codes) + if VERBOSE: + log_deps.info("%s%s" % (indent_str, set_as_str(expand_addr_visit))) + + if recursive: + + if expand_codes_idlib is None: + expand_codes_idlib = {} + for block in blend.find_blocks_from_code(b'ID'): + expand_codes_idlib.setdefault(block[b'lib'], set()).add(block[b'name']) + + # look into libraries + lib_all = [] + + for lib_id, lib_block_codes in sorted(expand_codes_idlib.items()): + lib = blend.find_block_from_offset(lib_id) + lib_path = lib[b'name'] + + # get all data needed to read the blend files here (it will be freed!) + # lib is an address at the moment, we only use as a way to group + + lib_all.append((lib_path, lib_block_codes)) + # import IPython; IPython.embed() + + # ensure we expand indirect linked libs + if block_codes_idlib is not None: + block_codes_idlib.add(lib_path) + + # do this after, incase we mangle names above + for block in iter_blocks_idlib(): yield from FilePath.from_block(block, basedir, extra_info, level) + del blend - # print("A:", expand_addr_visit) - # print("B:", block_codes) - if VERBOSE: - log_deps.info("%s%s" % (indent_str, set_as_str(expand_addr_visit))) - - if recursive: - - if expand_codes_idlib is None: - expand_codes_idlib = {} - for block in blend.find_blocks_from_code(b'ID'): - expand_codes_idlib.setdefault(block[b'lib'], set()).add(block[b'name']) - - # look into libraries - lib_all = [] - - for lib_id, lib_block_codes in sorted(expand_codes_idlib.items()): - lib = blend.find_block_from_offset(lib_id) - lib_path = lib[b'name'] - - # get all data needed to read the blend files here (it will be freed!) - # lib is an address at the moment, we only use as a way to group - - lib_all.append((lib_path, lib_block_codes)) - # import IPython; IPython.embed() - - # ensure we expand indirect linked libs - if block_codes_idlib is not None: - block_codes_idlib.add(lib_path) - - # do this after, incase we mangle names above - for block in iter_blocks_idlib(): - yield from FilePath.from_block(block, basedir, extra_info, level) - - blend.close() # ---------------- # Handle Recursive