ayon-core/pype/plugins/global/publish/cleanup.py
2020-10-14 16:22:20 +02:00

141 lines
4.6 KiB
Python

# -*- coding: utf-8 -*-
"""Cleanup leftover files from publish."""
import os
import shutil
import pyblish.api
import re
class CleanUp(pyblish.api.InstancePlugin):
"""Cleans up the staging directory after a successful publish.
This will also clean published renders and delete their parent directories.
"""
order = pyblish.api.IntegratorOrder + 10
label = "Clean Up"
exclude_families = ["clip"]
optional = True
active = True
# Presets
paterns = None # list of regex paterns
remove_temp_renders = True
def process(self, instance):
"""Plugin entry point."""
# Get the errored instances
failed = []
for result in instance.context.data["results"]:
if (result["error"] is not None and result["instance"] is not None
and result["instance"] not in failed):
failed.append(result["instance"])
assert instance not in failed, (
"Result of '{}' instance were not success".format(
instance.data["name"]
)
)
if self.remove_temp_renders:
self.log.info("Cleaning renders new...")
self.clean_renders(instance)
if [ef for ef in self.exclude_families
if instance.data["family"] in ef]:
return
import tempfile
temp_root = tempfile.gettempdir()
staging_dir = instance.data.get("stagingDir", None)
if not staging_dir:
self.log.info("Staging dir not set.")
return
if not os.path.normpath(staging_dir).startswith(temp_root):
self.log.info("Skipping cleanup. Staging directory is not in the "
"temp folder: %s" % staging_dir)
return
if not os.path.exists(staging_dir):
self.log.info("No staging directory found: %s" % staging_dir)
return
self.log.info("Removing staging directory {}".format(staging_dir))
shutil.rmtree(staging_dir)
def clean_renders(self, instance):
transfers = instance.data.get("transfers", list())
current_families = instance.data.get("families", list())
instance_family = instance.data.get("family", None)
dirnames = []
transfers_dirs = []
for src, dest in transfers:
# fix path inconsistency
src = os.path.normpath(src)
dest = os.path.normpath(dest)
# add src dir into clearing dir paths (regex paterns)
transfers_dirs.append(os.path.dirname(src))
# add dest dir into clearing dir paths (regex paterns)
transfers_dirs.append(os.path.dirname(dest))
if os.path.normpath(src) != os.path.normpath(dest):
if instance_family == 'render' or 'render' in current_families:
self.log.info("Removing src: `{}`...".format(src))
try:
os.remove(src)
except PermissionError:
self.log.warning("Insufficient permission to delete {}".format(src))
continue
# add dir for cleanup
dirnames.append(os.path.dirname(src))
# clean by regex paterns
# make unique set
transfers_dirs = set(transfers_dirs)
self.log.debug("__ transfers_dirs: `{}`".format(transfers_dirs))
self.log.debug("__ self.paterns: `{}`".format(self.paterns))
if self.paterns:
files = list()
# get list of all available content of dirs
for _dir in transfers_dirs:
if not os.path.exists(_dir):
continue
files.extend([
os.path.join(_dir, f)
for f in os.listdir(_dir)])
self.log.debug("__ files: `{}`".format(files))
# remove all files which match regex patern
for f in files:
for p in self.paterns:
patern = re.compile(p)
if not patern.findall(f):
continue
if not os.path.exists(f):
continue
self.log.info("Removing file by regex: `{}`".format(f))
os.remove(f)
# add dir for cleanup
dirnames.append(os.path.dirname(f))
# make unique set
cleanup_dirs = set(dirnames)
# clean dirs which are empty
for dir in cleanup_dirs:
try:
os.rmdir(dir)
except OSError:
# directory is not empty, skipping
continue