2021-10-18 15:54:04 +02:00
|
|
|
"""shutil-like functionality while compressing blendfiles on the fly."""
|
|
|
|
|
|
|
|
import gzip
|
|
|
|
import logging
|
|
|
|
import pathlib
|
|
|
|
import shutil
|
|
|
|
|
2023-01-10 11:41:55 +01:00
|
|
|
from blender_asset_tracer.blendfile import magic_compression
|
|
|
|
|
2021-10-18 15:54:04 +02:00
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
# Arbitrarily chosen block size, in bytes.
|
2023-01-10 11:41:55 +01:00
|
|
|
BLOCK_SIZE = 256 * 2**10
|
2021-10-18 15:54:04 +02:00
|
|
|
|
|
|
|
|
|
|
|
def move(src: pathlib.Path, dest: pathlib.Path):
|
|
|
|
"""Move a file from src to dest, gzip-compressing if not compressed yet.
|
|
|
|
|
|
|
|
Only compresses files ending in .blend; others are moved as-is.
|
|
|
|
"""
|
2023-01-10 11:41:55 +01:00
|
|
|
my_log = log.getChild("move")
|
|
|
|
my_log.debug("Moving %s to %s", src, dest)
|
2021-10-18 15:54:04 +02:00
|
|
|
|
2023-01-10 11:41:55 +01:00
|
|
|
if src.suffix.lower() == ".blend":
|
2021-10-18 15:54:04 +02:00
|
|
|
_move_or_copy(src, dest, my_log, source_must_remain=False)
|
|
|
|
else:
|
|
|
|
shutil.move(str(src), str(dest))
|
|
|
|
|
|
|
|
|
|
|
|
def copy(src: pathlib.Path, dest: pathlib.Path):
|
|
|
|
"""Copy a file from src to dest, gzip-compressing if not compressed yet.
|
|
|
|
|
|
|
|
Only compresses files ending in .blend; others are copied as-is.
|
|
|
|
"""
|
2023-01-10 11:41:55 +01:00
|
|
|
my_log = log.getChild("copy")
|
|
|
|
my_log.debug("Copying %s to %s", src, dest)
|
2021-10-18 15:54:04 +02:00
|
|
|
|
2023-01-10 11:41:55 +01:00
|
|
|
if src.suffix.lower() == ".blend":
|
2021-10-18 15:54:04 +02:00
|
|
|
_move_or_copy(src, dest, my_log, source_must_remain=True)
|
|
|
|
else:
|
|
|
|
shutil.copy2(str(src), str(dest))
|
|
|
|
|
|
|
|
|
2023-01-10 11:41:55 +01:00
|
|
|
def _move_or_copy(
|
|
|
|
src: pathlib.Path,
|
|
|
|
dest: pathlib.Path,
|
|
|
|
my_log: logging.Logger,
|
|
|
|
*,
|
|
|
|
source_must_remain: bool
|
|
|
|
):
|
2021-10-18 15:54:04 +02:00
|
|
|
"""Either move or copy a file, gzip-compressing if not compressed yet.
|
|
|
|
|
|
|
|
:param src: File to copy/move.
|
|
|
|
:param dest: Path to copy/move to.
|
|
|
|
:source_must_remain: True to copy, False to move.
|
|
|
|
:my_log: Logger to use for logging.
|
|
|
|
"""
|
2023-01-10 11:41:55 +01:00
|
|
|
srcfile = src.open("rb")
|
2021-10-18 15:54:04 +02:00
|
|
|
try:
|
2023-01-10 11:41:55 +01:00
|
|
|
comp_type = magic_compression.find_compression_type(srcfile)
|
|
|
|
if comp_type != magic_compression.Compression.NONE:
|
|
|
|
# Either already compressed or not a blend file.
|
|
|
|
# Either way we shouldn't attempt compressing this file.
|
2021-10-18 15:54:04 +02:00
|
|
|
srcfile.close()
|
2023-01-10 11:41:55 +01:00
|
|
|
my_log.debug("Source file %s is compressed already", src)
|
2021-10-18 15:54:04 +02:00
|
|
|
if source_must_remain:
|
|
|
|
shutil.copy2(str(src), str(dest))
|
|
|
|
else:
|
|
|
|
shutil.move(str(src), str(dest))
|
|
|
|
return
|
|
|
|
|
2023-01-10 11:41:55 +01:00
|
|
|
my_log.debug("Compressing %s on the fly while copying to %s", src, dest)
|
|
|
|
srcfile.seek(0)
|
|
|
|
with gzip.open(str(dest), mode="wb") as destfile:
|
2021-10-18 15:54:04 +02:00
|
|
|
shutil.copyfileobj(srcfile, destfile, BLOCK_SIZE)
|
|
|
|
|
|
|
|
srcfile.close()
|
|
|
|
if not source_must_remain:
|
2023-01-10 11:41:55 +01:00
|
|
|
my_log.debug("Deleting source file %s", src)
|
2021-10-18 15:54:04 +02:00
|
|
|
src.unlink()
|
|
|
|
finally:
|
|
|
|
if not srcfile.closed:
|
|
|
|
srcfile.close()
|