feat(tools): added tool for copying textures to publish destination

This commit is contained in:
antirotor 2019-06-12 16:11:57 +02:00
parent d61ba75375
commit 11f29a551f
No known key found for this signature in database
GPG key ID: 8A29C663C672C2B7
2 changed files with 250 additions and 0 deletions

View file

@ -0,0 +1,88 @@
import os
import re
import copy
from avalon import io
from pprint import pprint
import pyblish.api
from avalon import api
texture_extensions = ['.tif', '.tiff', '.jpg', '.jpeg', '.tx', '.png', '.tga',
'.psd', '.dpx', '.hdr', '.hdri', '.exr', '.sxr', '.psb']
class CollectTextures(pyblish.api.ContextPlugin):
"""
Gather all texture files in working directory, traversing whole structure.
"""
order = pyblish.api.CollectorOrder
targets = ["texture"]
label = "Textures"
hosts = ["shell"]
def process(self, context):
if os.environ.get("PYPE_PUBLISH_PATHS"):
paths = os.environ["PYPE_PUBLISH_PATHS"].split(os.pathsep)
else:
cwd = context.get("workspaceDir", os.getcwd())
paths = [cwd]
textures = []
for path in paths:
for dir, subdir, files in os.walk(path):
textures.extend(
os.path.join(dir, x) for x in files
if os.path.splitext(x)[1].lower() in texture_extensions)
self.log.info("Got {} texture files.".format(len(textures)))
if len(textures) < 1:
raise RuntimeError("no textures found.")
asset_name = os.environ.get("AVALON_ASSET")
family = 'texture'
subset = 'Main'
project = io.find_one({'type': 'project'})
asset = io.find_one({
'type': 'asset',
'name': asset_name
})
context.data['project'] = project
context.data['asset'] = asset
for tex in textures:
self.log.info("Processing: {}".format(tex))
name, ext = os.path.splitext(tex)
simple_name = os.path.splitext(os.path.basename(tex))[0]
instance = context.create_instance(simple_name)
instance.data.update({
"subset": subset,
"asset": asset_name,
"label": simple_name,
"name": simple_name,
"family": family,
"families": [family, 'ftrack'],
})
instance.data['destination_list'] = list()
instance.data['representations'] = list()
instance.data['source'] = 'pype command'
texture_data = {}
texture_data['anatomy_template'] = 'texture'
texture_data["ext"] = ext
texture_data["label"] = simple_name
texture_data["name"] = "texture"
texture_data["stagingDir"] = os.path.dirname(tex)
texture_data["files"] = os.path.basename(tex)
texture_data["thumbnail"] = False
texture_data["preview"] = False
instance.data["representations"].append(texture_data)
self.log.info("collected instance: {}".format(instance.data))
self.log.info("All collected.")

View file

@ -0,0 +1,162 @@
import os
import re
import click
from avalon import io, api
from pprint import pprint
from pypeapp.lib.Terminal import Terminal
from pypeapp import Anatomy
import shutil
import speedcopy
t = Terminal()
texture_extensions = ['.tif', '.tiff', '.jpg', '.jpeg', '.tx', '.png', '.tga',
'.psd', '.dpx', '.hdr', '.hdri', '.exr', '.sxr', '.psb']
class TextureCopy:
def __init__(self):
if not io.Session:
io.install()
def _get_textures(self, path):
textures = []
for dir, subdir, files in os.walk(path):
textures.extend(
os.path.join(dir, x) for x in files
if os.path.splitext(x)[1].lower() in texture_extensions)
return textures
def _get_project(self, project_name):
project = io.find_one({
'type': 'project',
'name': project_name
})
return project
def _get_asset(self, asset_name):
asset = io.find_one({
'type': 'asset',
'name': asset_name
})
return asset
def _get_destination_path(self, asset, project):
root = api.registered_root()
PROJECT = api.Session["AVALON_PROJECT"]
hierarchy = ""
parents = asset['data']['parents']
if parents and len(parents) > 0:
hierarchy = os.path.join(*parents)
template_data = {"root": root,
"project": {"name": PROJECT,
"code": project['data']['code']},
"silo": asset['silo'],
"asset": asset['name'],
"family": 'texture',
"subset": 'Main',
"hierarchy": hierarchy}
anatomy = Anatomy()
anatomy_filled = os.path.normpath(
anatomy.format(template_data)['texture']['path'])
return anatomy_filled
def _get_version(self, path):
versions = [0]
dirs = [f.path for f in os.scandir(path) if f.is_dir()]
for d in dirs:
ver = re.search(r'^v(\d+)$',
os.path.basename(d),
flags=re.IGNORECASE)
if ver is not None:
versions.append(int(ver.group(1)))
return max(versions) + 1
def _copy_textures(self, textures, destination):
for tex in textures:
dst = os.path.join(destination,
os.path.basename(tex))
t.echo(" - Copy {} -> {}".format(tex, dst))
try:
speedcopy.copyfile(tex, dst)
except Exception as e:
t.echo("!!! Copying failed")
t.echo("!!! {}".format(e))
exit(1)
def process(self, asset, project, path):
"""
Process all textures found in path and copy them to asset under
project.
"""
t.echo(">>> Looking for textures ...")
textures = self._get_textures(path)
if len(textures) < 1:
t.echo("!!! no textures found.")
exit(1)
else:
t.echo(">>> Found {} textures ...".format(len(textures)))
project = self._get_project(project)
if not project:
t.echo("!!! Project name [ {} ] not found.".format(project))
exit(1)
asset = self._get_asset(asset)
if not project:
t.echo("!!! Asset [ {} ] not found in project".format(asset))
exit(1)
t.echo((">>> Project [ {} ] and "
"asset [ {} ] seems to be OK ...").format(project['name'],
asset['name']))
dst_path = self._get_destination_path(asset, project)
t.echo("--- Using [ {} ] as destination path".format(dst_path))
if not os.path.exists(dst_path):
try:
os.makedirs(dst_path)
except IOError as e:
t.echo("!!! Unable to create destination directory")
t.echo("!!! {}".format(e))
exit(1)
version = '%02d' % self._get_version(dst_path)
t.echo("--- Using version [ {} ]".format(version))
dst_path = os.path.join(dst_path, "v{}".format(version))
t.echo("--- Final destination path [ {} ]".format(dst_path))
try:
os.makedirs(dst_path)
except FileExistsError:
t.echo("!!! Somethings wrong, version directory already exists")
exit(1)
except IOError as e:
t.echo("!!! Cannot create version directory")
t.echo("!!! {}".format(e))
exit(1)
t.echo(">>> copying textures ...")
self._copy_textures(textures, dst_path)
t.echo(">>> done.")
t.echo("<<< terminating ...")
@click.command()
@click.option('--asset', required=True)
@click.option('--project', required=True)
@click.option('--path', required=True)
def texture_copy(asset, project, path):
t.echo("*** Running Texture tool ***")
t.echo(">>> Initializing avalon session ...")
os.environ["AVALON_PROJECT"] = project
os.environ["AVALON_ASSET"] = asset
os.environ["AVALON_SILO"] = ""
TextureCopy().process(asset, project, path)
if __name__ == '__main__':
texture_copy()