Sybren A. Stüvel 08f538d8c8 File I/O improvements
- Tracer now iterates over blocks in disk order.
- Packer copies files per directory, in a separate thread.
- Packer only copies files if they don't exist yet.
- Packer also copies file permissions.
2018-03-08 12:33:15 +01:00

49 lines
1.5 KiB
Python

import logging
import pathlib
import typing
from blender_asset_tracer import blendfile, bpathlib
from . import result, blocks2assets, file2blocks
log = logging.getLogger(__name__)
codes_to_skip = {
# These blocks never have external assets:
b'ID', b'WM', b'SN',
# These blocks are skipped for now, until we have proof they point to
# assets otherwise missed:
b'GR', b'WO', b'BR', b'LS',
}
def deps(bfilepath: pathlib.Path) -> typing.Iterator[result.BlockUsage]:
"""Open the blend file and report its dependencies.
:param bfilepath: File to open.
"""
bfile = blendfile.open_cached(bfilepath)
# Sort the asset-holding blocks so that we can iterate over them
# in disk order, which is slightly faster than random order.
ahb = asset_holding_blocks(file2blocks.iter_blocks(bfile))
for block in sorted(ahb):
yield from blocks2assets.iter_assets(block)
def asset_holding_blocks(blocks: typing.Iterable[blendfile.BlendFileBlock]) \
-> typing.Iterator[blendfile.BlendFileBlock]:
"""Generator, yield data blocks that could reference external assets."""
for block in blocks:
assert isinstance(block, blendfile.BlendFileBlock)
code = block.code
# The longer codes are either arbitrary data or data blocks that
# don't refer to external assets. The former data blocks will be
# visited when we hit the two-letter datablocks that use them.
if len(code) > 2 or code in codes_to_skip:
continue
yield block