mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-25 21:32:15 +01:00
appAction works with versioning from database - app name is splitted by "_"
This commit is contained in:
parent
9ca3d61613
commit
e9b796e1d8
12 changed files with 337 additions and 299 deletions
|
|
@ -6,22 +6,15 @@ from ftrack_action_handler.appaction import AppAction
|
|||
from avalon import io, lib
|
||||
|
||||
|
||||
os.environ['AVALON_PROJECTS'] = 'tmp'
|
||||
io.install()
|
||||
projects = sorted(io.projects(), key=lambda x: x['name'])
|
||||
io.uninstall()
|
||||
|
||||
# Temporary
|
||||
s = ftrack_api.Session(
|
||||
server_url="https://pype.ftrackapp.com",
|
||||
api_key="4e01eda0-24b3-4451-8e01-70edc03286be",
|
||||
api_user="jakub.trllo"
|
||||
)
|
||||
|
||||
def register(session):
|
||||
|
||||
os.environ['AVALON_PROJECTS'] = 'tmp'
|
||||
io.install()
|
||||
projects = sorted(io.projects(), key=lambda x: x['name'])
|
||||
io.uninstall()
|
||||
|
||||
apps=[]
|
||||
actions = []
|
||||
icon = None
|
||||
|
||||
for project in projects:
|
||||
os.environ['AVALON_PROJECT'] = project['name']
|
||||
|
|
@ -29,16 +22,19 @@ def register(session):
|
|||
if app not in apps:
|
||||
apps.append(app)
|
||||
|
||||
# TODO get right icons
|
||||
for app in apps:
|
||||
name = app['name'].split("_")[0]
|
||||
variant = app['name'].split("_")[1]
|
||||
label = app['label']
|
||||
executable = toml.load(lib.which_app(app['name']))['executable']
|
||||
icon = None
|
||||
|
||||
if 'nuke' in app['name']:
|
||||
icon = "https://mbtskoudsalg.com/images/nuke-icon-png-2.png"
|
||||
label = "Nuke"
|
||||
elif 'maya' in app['name']:
|
||||
icon = "http://icons.iconarchive.com/icons/froyoshark/enkel/256/Maya-icon.png"
|
||||
else:
|
||||
icon = None
|
||||
label = "Autodesk Maya"
|
||||
|
||||
AppAction(session, app['label'], app['name'], icon).register()
|
||||
|
||||
session.event_hub.wait()
|
||||
|
||||
register(s)
|
||||
AppAction(session, label, name, executable, variant, icon).register()
|
||||
|
|
|
|||
257
pype/ftrack/actions/action_createCustomAttributes.py
Normal file
257
pype/ftrack/actions/action_createCustomAttributes.py
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
# :coding: utf-8
|
||||
# :copyright: Copyright (c) 2017 ftrack
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import json
|
||||
import ftrack_api
|
||||
from ftrack_action_handler.action import BaseAction
|
||||
|
||||
from avalon import io, inventory, lib
|
||||
from avalon.vendor import toml
|
||||
|
||||
class AvalonIdAttribute(BaseAction):
|
||||
'''Edit meta data action.'''
|
||||
|
||||
#: Action identifier.
|
||||
identifier = 'avalon.id.attribute'
|
||||
#: Action label.
|
||||
label = 'Create Avalon Attribute'
|
||||
#: Action description.
|
||||
description = 'Creates Avalon/Mongo ID for double check'
|
||||
|
||||
def validate_selection(self, session, entities):
|
||||
'''Return if *entities* is a valid selection.'''
|
||||
# if (len(entities) != 1):
|
||||
# # If entities contains more than one item return early since
|
||||
# # metadata cannot be edited for several entites at the same time.
|
||||
# return False
|
||||
# entity_type, entity_id = entities[0]
|
||||
# if (
|
||||
# entity_type not in session.types
|
||||
# ):
|
||||
# # Return False if the target entity does not have a metadata
|
||||
# # attribute.
|
||||
# return False
|
||||
pass
|
||||
return True
|
||||
|
||||
def discover(self, session, entities, event):
|
||||
'''Return True if action is valid.'''
|
||||
|
||||
self.logger.info('Got selection: {0}'.format(entities))
|
||||
return self.validate_selection(session, entities)
|
||||
|
||||
|
||||
def importToAvalon(self, session, entity):
|
||||
eLinks = []
|
||||
custAttrName = 'avalon_mongo_id'
|
||||
# TODO read from file, which data are in scope???
|
||||
# get needed info of entity and all parents
|
||||
for e in entity['link']:
|
||||
tmp = session.get(e['type'], e['id'])
|
||||
if e['name'].find(" ") == -1:
|
||||
name = e['name']
|
||||
else:
|
||||
name = e['name'].replace(" ", "-")
|
||||
print("Name of "+tmp.entity_type+" - "+e['name']+" was changed to "+name)
|
||||
|
||||
eLinks.append({"type": tmp.entity_type, "name": name, "ftrackId": tmp['id']})
|
||||
|
||||
entityProj = session.get(eLinks[0]['type'], eLinks[0]['ftrackId'])
|
||||
|
||||
# set AVALON_PROJECT env
|
||||
os.environ["AVALON_PROJECT"] = entityProj["full_name"]
|
||||
os.environ["AVALON_ASSET"] = entityProj['full_name']
|
||||
|
||||
# Get apps from Ftrack / TODO Exceptions?!!!
|
||||
apps = []
|
||||
for app in entityProj['custom_attributes']['applications']:
|
||||
try:
|
||||
label = toml.load(lib.which_app(app))['label']
|
||||
apps.append({'name':app, 'label':label})
|
||||
except Exception as e:
|
||||
print('Error with application {0} - {1}'.format(app, e))
|
||||
|
||||
# Set project Config
|
||||
config = {
|
||||
'schema': 'avalon-core:config-1.0',
|
||||
'tasks': [{'name': ''}],
|
||||
'apps': apps,
|
||||
'template': {'work': '','publish':''}
|
||||
}
|
||||
|
||||
# Set project template
|
||||
template = {"schema": "avalon-core:inventory-1.0"}
|
||||
|
||||
# --- Create project and assets in Avalon ---
|
||||
io.install()
|
||||
# If project don't exists -> <Create project> ELSE <Update Config>
|
||||
if (io.find_one(
|
||||
{'type': 'project', 'name': entityProj['full_name']}) is None):
|
||||
inventory.save(entityProj['full_name'], config, template)
|
||||
else:
|
||||
io.update_many({'type': 'project','name': entityProj['full_name']},
|
||||
{'$set':{'config':config}})
|
||||
|
||||
# Store info about project (FtrackId)
|
||||
io.update_many({'type': 'project','name': entityProj['full_name']},
|
||||
{'$set':{'data':{'ftrackId':entityProj['id'],'entityType':entityProj.entity_type}}})
|
||||
|
||||
# Store project Id
|
||||
projectId = io.find_one({"type": "project", "name": entityProj["full_name"]})["_id"]
|
||||
if custAttrName in entityProj['custom_attributes'] and entityProj['custom_attributes'][custAttrName] is '':
|
||||
entityProj['custom_attributes'][custAttrName] = str(projectId)
|
||||
|
||||
# If entity is Project or have only 1 entity kill action
|
||||
if (len(eLinks) > 1) and not (eLinks[-1]['type'] in ['Project']):
|
||||
|
||||
# TODO how to check if entity is Asset Library or AssetBuild?
|
||||
silo = 'Assets' if eLinks[-1]['type'] in ['AssetBuild', 'Library'] else 'Film'
|
||||
os.environ['AVALON_SILO'] = silo
|
||||
# Create Assets
|
||||
assets = []
|
||||
for i in range(1, len(eLinks)):
|
||||
assets.append(eLinks[i])
|
||||
|
||||
folderStruct = []
|
||||
parentId = None
|
||||
data = {'visualParent': parentId, 'parents': folderStruct,
|
||||
'tasks':None, 'ftrackId': None, 'entityType': None}
|
||||
|
||||
for asset in assets:
|
||||
os.environ['AVALON_ASSET'] = asset['name']
|
||||
data.update({'ftrackId': asset['ftrackId'], 'entityType': asset['type']})
|
||||
# Get tasks of each asset
|
||||
assetEnt = session.get('TypedContext', asset['ftrackId'])
|
||||
tasks = []
|
||||
for child in assetEnt['children']:
|
||||
if child.entity_type in ['Task']:
|
||||
tasks.append(child['name'])
|
||||
data.update({'tasks': tasks})
|
||||
|
||||
if (io.find_one({'type': 'asset', 'name': asset['name']}) is None):
|
||||
# Create asset in DB
|
||||
inventory.create_asset(asset['name'], silo, data, projectId)
|
||||
print("Asset "+asset['name']+" - created")
|
||||
else:
|
||||
io.update_many({'type': 'asset','name': asset['name']},
|
||||
{'$set':{'data':data}})
|
||||
# TODO check if is asset in same folder!!! ???? FEATURE FOR FUTURE
|
||||
print("Asset "+asset["name"]+" - already exist")
|
||||
|
||||
parentId = io.find_one({'type': 'asset', 'name': asset['name']})['_id']
|
||||
data.update({'visualParent': parentId, 'parents': folderStruct})
|
||||
folderStruct.append(asset['name'])
|
||||
|
||||
|
||||
# Set custom attribute to avalon/mongo id of entity (parentID is last)
|
||||
if custAttrName in entity['custom_attributes'] and entity['custom_attributes'][custAttrName] is '':
|
||||
entity['custom_attributes'][custAttrName] = str(parentId)
|
||||
|
||||
io.uninstall()
|
||||
|
||||
def launch(self, session, entities, event):
|
||||
# JOB SETTINGS
|
||||
userId = event['source']['user']['id']
|
||||
user = session.query('User where id is ' + userId).one()
|
||||
|
||||
job = session.create('Job', {
|
||||
'user': user,
|
||||
'status': 'running',
|
||||
'data': json.dumps({
|
||||
'description': 'Synch Ftrack to Avalon.'
|
||||
})
|
||||
})
|
||||
|
||||
try:
|
||||
print("action <" + self.__class__.__name__ + "> is running")
|
||||
#TODO It's better to have these env set, are they used anywhere?
|
||||
os.environ['AVALON_PROJECTS'] = "tmp"
|
||||
os.environ['AVALON_ASSET'] = "tmp"
|
||||
os.environ['AVALON_SILO'] = "tmp"
|
||||
importable = []
|
||||
|
||||
def getShotAsset(entity):
|
||||
if not (entity.entity_type in ['Task']):
|
||||
if entity not in importable:
|
||||
importable.append(entity)
|
||||
|
||||
if entity['children']:
|
||||
childrens = entity['children']
|
||||
for child in childrens:
|
||||
getShotAsset(child)
|
||||
|
||||
# get all entities separately
|
||||
for entity in entities:
|
||||
entity_type, entity_id = entity
|
||||
act_ent = session.get(entity_type, entity_id)
|
||||
getShotAsset(act_ent)
|
||||
|
||||
for e in importable:
|
||||
self.importToAvalon(session, e)
|
||||
|
||||
job['status'] = 'done'
|
||||
session.commit()
|
||||
|
||||
print('Synchronization to Avalon was successfull!')
|
||||
except Exception as e:
|
||||
job['status'] = 'failed'
|
||||
print('During synchronization to Avalon went something wrong!')
|
||||
print(e)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def register(session, **kw):
|
||||
'''Register plugin. Called when used as an plugin.'''
|
||||
|
||||
# Validate that session is an instance of ftrack_api.Session. If not,
|
||||
# assume that register is being called from an old or incompatible API and
|
||||
# return without doing anything.
|
||||
if not isinstance(session, ftrack_api.session.Session):
|
||||
return
|
||||
|
||||
action_handler = AvalonIdAttribute(session)
|
||||
action_handler.register()
|
||||
print("----- action - <" + action_handler.__class__.__name__ + "> - Has been registered -----")
|
||||
|
||||
|
||||
def main(arguments=None):
|
||||
'''Set up logging and register action.'''
|
||||
if arguments is None:
|
||||
arguments = []
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
# Allow setting of logging level from arguments.
|
||||
loggingLevels = {}
|
||||
for level in (
|
||||
logging.NOTSET, logging.DEBUG, logging.INFO, logging.WARNING,
|
||||
logging.ERROR, logging.CRITICAL
|
||||
):
|
||||
loggingLevels[logging.getLevelName(level).lower()] = level
|
||||
|
||||
parser.add_argument(
|
||||
'-v', '--verbosity',
|
||||
help='Set the logging output verbosity.',
|
||||
choices=loggingLevels.keys(),
|
||||
default='info'
|
||||
)
|
||||
namespace = parser.parse_args(arguments)
|
||||
|
||||
# Set up basic logging
|
||||
logging.basicConfig(level=loggingLevels[namespace.verbosity])
|
||||
|
||||
session = ftrack_api.Session()
|
||||
register(session)
|
||||
|
||||
# Wait for events
|
||||
logging.info(
|
||||
'Registered actions and listening for events. Use Ctrl-C to abort.'
|
||||
)
|
||||
session.event_hub.wait()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
raise SystemExit(main(sys.argv[1:]))
|
||||
|
|
@ -95,11 +95,8 @@ def main(arguments=None):
|
|||
# Set up basic logging
|
||||
logging.basicConfig(level=loggingLevels[namespace.verbosity])
|
||||
|
||||
session = ftrack_api.Session(
|
||||
server_url="https://pype.ftrackapp.com",
|
||||
api_key="4e01eda0-24b3-4451-8e01-70edc03286be",
|
||||
api_user="jakub.trllo"
|
||||
)
|
||||
session = ftrack_api.Session()
|
||||
|
||||
register(session)
|
||||
|
||||
# Wait for events
|
||||
|
|
|
|||
|
|
@ -1,154 +0,0 @@
|
|||
# :coding: utf-8
|
||||
# :copyright: Copyright (c) 2017 ftrack
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
import collections
|
||||
import os
|
||||
import json
|
||||
|
||||
import ftrack_api
|
||||
from ftrack_action_handler.action import BaseAction
|
||||
from avalon import io, inventory, schema
|
||||
from avalon.vendor import toml
|
||||
|
||||
|
||||
class TestAction(BaseAction):
|
||||
'''Edit meta data action.'''
|
||||
|
||||
#: Action identifier.
|
||||
identifier = 'test.action'
|
||||
|
||||
#: Action label.
|
||||
label = 'Test action'
|
||||
|
||||
#: Action description.
|
||||
description = 'Test action'
|
||||
|
||||
def validate_selection(self, session, entities):
|
||||
'''Return if *entities* is a valid selection.'''
|
||||
pass
|
||||
return True
|
||||
|
||||
def discover(self, session, entities, event):
|
||||
'''Return True if action is valid.'''
|
||||
|
||||
self.logger.info('Got selection: {0}'.format(entities))
|
||||
return self.validate_selection(session, entities)
|
||||
|
||||
def launch(self, session, entities, event):
|
||||
|
||||
def fromTop(index, max, inEnt):
|
||||
output=dict()
|
||||
entity = session.get(inEnt[index]['type'], inEnt[index]['id'])
|
||||
tasks=[]
|
||||
for e in entity['children']:
|
||||
if e.entity_type in ['Task']:
|
||||
tasks.append(e['name'])
|
||||
# Get info about all parents
|
||||
if index < max:
|
||||
output = {'name': entity['name'], 'tasks': tasks, 'childrens': fromTop(index+1, max, inEnt)}
|
||||
# Get info about all childrens
|
||||
else:
|
||||
childrens = []
|
||||
for e in entity['children']:
|
||||
if e.entity_type not in ['Task']:
|
||||
childrens.append(toBottom(e))
|
||||
output = {'name': entity['name'], 'tasks': tasks, 'childrens': childrens}
|
||||
return output
|
||||
|
||||
def toBottom(entity):
|
||||
tasks = []
|
||||
childrens = []
|
||||
# If entity have childrens do:
|
||||
if entity['children']:
|
||||
# Get all tasks
|
||||
for e in entity['children']:
|
||||
if e.entity_type in ['Task']:
|
||||
tasks.append(e['name'])
|
||||
# Get childrens of children
|
||||
for e in entity['children']:
|
||||
if e.entity_type not in ['Task']:
|
||||
childrens.append(toBottom(e))
|
||||
return {'name': entity['name'], 'tasks': tasks, 'childrens': childrens}
|
||||
|
||||
def project(proj):
|
||||
type = 'project'
|
||||
addProjectToDatabase()
|
||||
projId = getIdFromDb()
|
||||
if len(proj['childrens'] > 0):
|
||||
childrens = proj['childrens']
|
||||
test(childrens, None, projId)
|
||||
|
||||
def test(childrens, parentId, projId):
|
||||
type = 'asset'
|
||||
for child in childrens:
|
||||
silo = 'Assets' if child['type'] in ['AssetBuild', 'Library'] else 'Film'
|
||||
addtodatabase()
|
||||
newId = fromdatabase()
|
||||
if len(child['childrens']) > 0:
|
||||
test(child, newId, projId)
|
||||
|
||||
|
||||
for entity in entities:
|
||||
entity_type, entity_id = entity
|
||||
entity = session.get(entity_type, entity_id)
|
||||
max = len(entity['link']) - 1
|
||||
out = fromTop(0, max, entity['link'])
|
||||
print(100*"_")
|
||||
print(out)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def register(session, **kw):
|
||||
'''Register plugin. Called when used as an plugin.'''
|
||||
|
||||
if not isinstance(session, ftrack_api.session.Session):
|
||||
return
|
||||
|
||||
action_handler = TestAction(session)
|
||||
action_handler.register()
|
||||
|
||||
|
||||
def main(arguments=None):
|
||||
'''Set up logging and register action.'''
|
||||
if arguments is None:
|
||||
arguments = []
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
# Allow setting of logging level from arguments.
|
||||
loggingLevels = {}
|
||||
for level in (
|
||||
logging.NOTSET, logging.DEBUG, logging.INFO, logging.WARNING,
|
||||
logging.ERROR, logging.CRITICAL
|
||||
):
|
||||
loggingLevels[logging.getLevelName(level).lower()] = level
|
||||
|
||||
parser.add_argument(
|
||||
'-v', '--verbosity',
|
||||
help='Set the logging output verbosity.',
|
||||
choices=loggingLevels.keys(),
|
||||
default='info'
|
||||
)
|
||||
namespace = parser.parse_args(arguments)
|
||||
|
||||
# Set up basic logging
|
||||
logging.basicConfig(level=loggingLevels[namespace.verbosity])
|
||||
|
||||
session = ftrack_api.Session(
|
||||
server_url="https://pype.ftrackapp.com",
|
||||
api_key="4e01eda0-24b3-4451-8e01-70edc03286be",
|
||||
api_user="jakub.trllo"
|
||||
)
|
||||
register(session)
|
||||
|
||||
# Wait for events
|
||||
logging.info(
|
||||
'Registered actions and listening for events. Use Ctrl-C to abort.'
|
||||
)
|
||||
session.event_hub.wait()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
raise SystemExit(main(sys.argv[1:]))
|
||||
|
|
@ -90,8 +90,8 @@ class SyncToAvalon(BaseAction):
|
|||
# --- Create project and assets in Avalon ---
|
||||
io.install()
|
||||
# If project don't exists -> <Create project> ELSE <Update Config>
|
||||
if (io.find_one(
|
||||
{'type': 'project', 'name': entityProj['full_name']}) is None):
|
||||
if (io.find_one({'type': 'project',
|
||||
'name': entityProj['full_name']}) is None):
|
||||
inventory.save(entityProj['full_name'], config, template)
|
||||
else:
|
||||
io.update_many({'type': 'project','name': entityProj['full_name']},
|
||||
|
|
@ -245,10 +245,7 @@ def main(arguments=None):
|
|||
# Set up basic logging
|
||||
logging.basicConfig(level=loggingLevels[namespace.verbosity])
|
||||
|
||||
session = ftrack_api.Session(
|
||||
server_url="https://pype.ftrackapp.com",
|
||||
api_key="4e01eda0-24b3-4451-8e01-70edc03286be",
|
||||
)
|
||||
session = ftrack_api.Session()
|
||||
register(session)
|
||||
|
||||
# Wait for events
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ class TestAction(BaseAction):
|
|||
return self.validate_selection(session, entities)
|
||||
|
||||
def launch(self, session, entities, event):
|
||||
|
||||
|
||||
return True
|
||||
|
||||
|
||||
|
|
@ -76,11 +76,7 @@ def main(arguments=None):
|
|||
# Set up basic logging
|
||||
logging.basicConfig(level=loggingLevels[namespace.verbosity])
|
||||
|
||||
session = ftrack_api.Session(
|
||||
server_url="https://pype.ftrackapp.com",
|
||||
api_key="4e01eda0-24b3-4451-8e01-70edc03286be",
|
||||
api_user="jakub.trllo"
|
||||
)
|
||||
session = ftrack_api.Session()
|
||||
register(session)
|
||||
|
||||
# Wait for events
|
||||
|
|
|
|||
|
|
@ -1,30 +0,0 @@
|
|||
schema = "avalon-core:config-1.0"
|
||||
[[tasks]]
|
||||
name = "model"
|
||||
|
||||
[[tasks]]
|
||||
name = "render"
|
||||
|
||||
[[tasks]]
|
||||
name = "animate"
|
||||
|
||||
[[tasks]]
|
||||
name = "rig"
|
||||
|
||||
[[tasks]]
|
||||
name = "lookdev"
|
||||
|
||||
[[tasks]]
|
||||
name = "layout"
|
||||
|
||||
[[apps]]
|
||||
name = "maya2018"
|
||||
label = "Autodesk Maya 2018"
|
||||
|
||||
[[apps]]
|
||||
name = "nuke11"
|
||||
label = "The Foundry Nuke 11.0"
|
||||
|
||||
[template]
|
||||
work = "{root}/{project}/{silo}/{asset}/work/{task}/{app}"
|
||||
publish = "{root}/{project}/{silo}/{asset}/publish/{subset}/v{version:0>3}/{subset}.{representation}"
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
schema = "avalon-core:config-1.0"
|
||||
[[tasks]]
|
||||
name = "model"
|
||||
|
||||
[[tasks]]
|
||||
name = "render"
|
||||
|
||||
[[tasks]]
|
||||
name = "animate"
|
||||
|
||||
[[tasks]]
|
||||
name = "rig"
|
||||
|
||||
[[tasks]]
|
||||
name = "lookdev"
|
||||
|
||||
[[tasks]]
|
||||
name = "layout"
|
||||
|
||||
[[apps]]
|
||||
name = "maya2018"
|
||||
label = "Autodesk Maya 2018"
|
||||
|
||||
[[apps]]
|
||||
name = "nuke11"
|
||||
label = "The Foundry Nuke 11.0"
|
||||
|
||||
[template]
|
||||
work = "{root}/{project}/{silo}/{asset}/work/{task}/{app}"
|
||||
publish = "{root}/{project}/{silo}/{asset}/publish/{subset}/v{version:0>3}/{subset}.{representation}"
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
schema = "avalon-core:config-1.0"
|
||||
[[tasks]]
|
||||
name = "model"
|
||||
|
||||
[[tasks]]
|
||||
name = "render"
|
||||
|
||||
[[tasks]]
|
||||
name = "animate"
|
||||
|
||||
[[tasks]]
|
||||
name = "rig"
|
||||
|
||||
[[tasks]]
|
||||
name = "lookdev"
|
||||
|
||||
[[tasks]]
|
||||
name = "layout"
|
||||
|
||||
[[apps]]
|
||||
name = "maya2018"
|
||||
label = "Autodesk Maya 2018"
|
||||
|
||||
[[apps]]
|
||||
name = "nuke11"
|
||||
label = "The Foundry Nuke 11.0"
|
||||
|
||||
[template]
|
||||
work = "{root}/{project}/{asset}/work/{task}/{app}"
|
||||
publish = "{root}/{project}/{asset}/publish/{subset}/v{version:0>3}/{subset}.{representation}"
|
||||
44
pype/ftrack/actions/t.py
Normal file
44
pype/ftrack/actions/t.py
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
import model
|
||||
# model
|
||||
|
||||
name = model.data(index, "name")
|
||||
|
||||
# Get the action
|
||||
Action = next((a for a in self._registered_actions if a.name == name),
|
||||
None)
|
||||
assert Action, "No action found"
|
||||
action = Action()
|
||||
|
||||
# Run the action within current session
|
||||
self.log("Running action: %s" % name, level=INFO)
|
||||
popen = action.process(api.Session.copy())
|
||||
# Action might return popen that pipes stdout
|
||||
# in which case we listen for it.
|
||||
process = {}
|
||||
if popen and hasattr(popen, "stdout") and popen.stdout is not None:
|
||||
|
||||
class Thread(QtCore.QThread):
|
||||
messaged = Signal(str)
|
||||
|
||||
def run(self):
|
||||
for line in lib.stream(process["popen"].stdout):
|
||||
self.messaged.emit(line.rstrip())
|
||||
self.messaged.emit("%s killed." % process["name"])
|
||||
|
||||
thread = Thread()
|
||||
thread.messaged.connect(
|
||||
lambda line: terminal.log(line, terminal.INFO)
|
||||
)
|
||||
|
||||
process.update({
|
||||
"name": name,
|
||||
"action": action,
|
||||
"thread": thread,
|
||||
"popen": popen
|
||||
})
|
||||
|
||||
self._processes.append(process)
|
||||
|
||||
thread.start()
|
||||
|
||||
# return process
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
schema = "avalon-core:config-1.0"
|
||||
[[tasks]]
|
||||
name = ""
|
||||
|
||||
[[apps]]
|
||||
name = "maya2018"
|
||||
label = "Autodesk Maya 2018"
|
||||
|
||||
[[apps]]
|
||||
name = "nuke11"
|
||||
label = "The Foundry Nuke 11.0"
|
||||
|
||||
[template]
|
||||
work = ""
|
||||
17
pype/vendor/ftrack_action_handler/appaction.py
vendored
17
pype/vendor/ftrack_action_handler/appaction.py
vendored
|
|
@ -18,7 +18,7 @@ class AppAction(object):
|
|||
<icon> - icon in ftrack
|
||||
'''
|
||||
|
||||
def __init__(self, session, label, name, icon=None, variant=None, description=None):
|
||||
def __init__(self, session, label, name, executable, variant=None, icon=None, description=None):
|
||||
'''Expects a ftrack_api.Session instance'''
|
||||
|
||||
self.logger = logging.getLogger(
|
||||
|
|
@ -29,12 +29,15 @@ class AppAction(object):
|
|||
raise ValueError('Action missing label.')
|
||||
elif name is None:
|
||||
raise ValueError('Action missing identifier.')
|
||||
elif executable is None:
|
||||
raise ValueError('Action missing executable.')
|
||||
|
||||
self._session = session
|
||||
self.label = label
|
||||
self.identifier = name
|
||||
self.icon = icon
|
||||
self.executable = executable
|
||||
self.variant = variant
|
||||
self.icon = icon
|
||||
self.description = description
|
||||
|
||||
|
||||
|
|
@ -118,7 +121,7 @@ class AppAction(object):
|
|||
else:
|
||||
apps = []
|
||||
for app in project['config']['apps']:
|
||||
apps.append(app['name'])
|
||||
apps.append(app['name'].split("_")[0])
|
||||
|
||||
if self.identifier not in apps:
|
||||
return False
|
||||
|
|
@ -208,6 +211,10 @@ class AppAction(object):
|
|||
# TODO Delete this line
|
||||
print("Action - {0} ({1}) - just started".format(self.label, self.identifier))
|
||||
|
||||
# lib.launch(executable=self.executable,
|
||||
# args=["-u", "-m", "avalon.tools.projectmanager",
|
||||
# session['AVALON_PROJECT']])
|
||||
|
||||
# Get path to execute
|
||||
st_temp_path = os.environ['PYPE_STUDIO_TEMPLATES']
|
||||
os_plat = platform.system().lower()
|
||||
|
|
@ -218,11 +225,13 @@ class AppAction(object):
|
|||
execfile = None
|
||||
|
||||
for ext in os.environ["PATHEXT"].split(os.pathsep):
|
||||
fpath = os.path.join(path.strip('"'), self.identifier + ext)
|
||||
fpath = os.path.join(path.strip('"'), self.executable + ext)
|
||||
if os.path.isfile(fpath) and os.access(fpath, os.X_OK):
|
||||
execfile = fpath
|
||||
break
|
||||
|
||||
|
||||
|
||||
if execfile is not None:
|
||||
os.startfile(execfile)
|
||||
else:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue