mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
Merge pull request #223 from pypeclub/feature/ftrack_cleanup_part_2
Feature/ftrack cleanup part 2
This commit is contained in:
commit
391aef5ba8
30 changed files with 72 additions and 1250 deletions
|
|
@ -1,7 +1,7 @@
|
|||
import os
|
||||
import toml
|
||||
import time
|
||||
from pype.modules.ftrack import AppAction
|
||||
from pype.modules.ftrack.lib import AppAction
|
||||
from avalon import lib
|
||||
from pype.api import Logger
|
||||
from pype.lib import get_all_avalon_projects
|
||||
|
|
@ -72,7 +72,7 @@ def register(session, plugins_presets={}):
|
|||
for app in apps:
|
||||
try:
|
||||
registerApp(app, session, plugins_presets)
|
||||
if app_counter%5 == 0:
|
||||
if app_counter % 5 == 0:
|
||||
time.sleep(0.1)
|
||||
app_counter += 1
|
||||
except Exception as exc:
|
||||
|
|
|
|||
|
|
@ -1,284 +0,0 @@
|
|||
import os
|
||||
|
||||
import ftrack_api
|
||||
from pype.modules.ftrack import BaseAction
|
||||
from pype.modules.ftrack.lib.io_nonsingleton import DbConnector
|
||||
|
||||
|
||||
class AttributesRemapper(BaseAction):
|
||||
'''Edit meta data action.'''
|
||||
|
||||
ignore_me = True
|
||||
#: Action identifier.
|
||||
identifier = 'attributes.remapper'
|
||||
#: Action label.
|
||||
label = "Pype Doctor"
|
||||
variant = '- Attributes Remapper'
|
||||
#: Action description.
|
||||
description = 'Remaps attributes in avalon DB'
|
||||
|
||||
#: roles that are allowed to register this action
|
||||
role_list = ["Pypeclub", "Administrator"]
|
||||
icon = '{}/ftrack/action_icons/PypeDoctor.svg'.format(
|
||||
os.environ.get('PYPE_STATICS_SERVER', '')
|
||||
)
|
||||
|
||||
db_con = DbConnector()
|
||||
keys_to_change = {
|
||||
"fstart": "frameStart",
|
||||
"startFrame": "frameStart",
|
||||
"edit_in": "frameStart",
|
||||
|
||||
"fend": "frameEnd",
|
||||
"endFrame": "frameEnd",
|
||||
"edit_out": "frameEnd",
|
||||
|
||||
"handle_start": "handleStart",
|
||||
"handle_end": "handleEnd",
|
||||
"handles": ["handleEnd", "handleStart"],
|
||||
|
||||
"frameRate": "fps",
|
||||
"framerate": "fps",
|
||||
"resolution_width": "resolutionWidth",
|
||||
"resolution_height": "resolutionHeight",
|
||||
"pixel_aspect": "pixelAspect"
|
||||
}
|
||||
|
||||
def discover(self, session, entities, event):
|
||||
''' Validation '''
|
||||
|
||||
return True
|
||||
|
||||
def interface(self, session, entities, event):
|
||||
if event['data'].get('values', {}):
|
||||
return
|
||||
|
||||
title = 'Select Projects where attributes should be remapped'
|
||||
|
||||
items = []
|
||||
|
||||
selection_enum = {
|
||||
'label': 'Process type',
|
||||
'type': 'enumerator',
|
||||
'name': 'process_type',
|
||||
'data': [
|
||||
{
|
||||
'label': 'Selection',
|
||||
'value': 'selection'
|
||||
}, {
|
||||
'label': 'Inverted selection',
|
||||
'value': 'except'
|
||||
}
|
||||
],
|
||||
'value': 'selection'
|
||||
}
|
||||
selection_label = {
|
||||
'type': 'label',
|
||||
'value': (
|
||||
'Selection based variants:<br/>'
|
||||
'- `Selection` - '
|
||||
'NOTHING is processed when nothing is selected<br/>'
|
||||
'- `Inverted selection` - '
|
||||
'ALL Projects are processed when nothing is selected'
|
||||
)
|
||||
}
|
||||
|
||||
items.append(selection_enum)
|
||||
items.append(selection_label)
|
||||
|
||||
item_splitter = {'type': 'label', 'value': '---'}
|
||||
|
||||
all_projects = session.query('Project').all()
|
||||
for project in all_projects:
|
||||
item_label = {
|
||||
'type': 'label',
|
||||
'value': '{} (<i>{}</i>)'.format(
|
||||
project['full_name'], project['name']
|
||||
)
|
||||
}
|
||||
item = {
|
||||
'name': project['id'],
|
||||
'type': 'boolean',
|
||||
'value': False
|
||||
}
|
||||
if len(items) > 0:
|
||||
items.append(item_splitter)
|
||||
items.append(item_label)
|
||||
items.append(item)
|
||||
|
||||
if len(items) == 0:
|
||||
return {
|
||||
'success': False,
|
||||
'message': 'Didn\'t found any projects'
|
||||
}
|
||||
else:
|
||||
return {
|
||||
'items': items,
|
||||
'title': title
|
||||
}
|
||||
|
||||
def launch(self, session, entities, event):
|
||||
if 'values' not in event['data']:
|
||||
return
|
||||
|
||||
values = event['data']['values']
|
||||
process_type = values.pop('process_type')
|
||||
|
||||
selection = True
|
||||
if process_type == 'except':
|
||||
selection = False
|
||||
|
||||
interface_messages = {}
|
||||
|
||||
projects_to_update = []
|
||||
for project_id, update_bool in values.items():
|
||||
if not update_bool and selection:
|
||||
continue
|
||||
|
||||
if update_bool and not selection:
|
||||
continue
|
||||
|
||||
project = session.query(
|
||||
'Project where id is "{}"'.format(project_id)
|
||||
).one()
|
||||
projects_to_update.append(project)
|
||||
|
||||
if not projects_to_update:
|
||||
self.log.debug('Nothing to update')
|
||||
return {
|
||||
'success': True,
|
||||
'message': 'Nothing to update'
|
||||
}
|
||||
|
||||
|
||||
self.db_con.install()
|
||||
|
||||
relevant_types = ["project", "asset", "version"]
|
||||
|
||||
for ft_project in projects_to_update:
|
||||
self.log.debug(
|
||||
"Processing project \"{}\"".format(ft_project["full_name"])
|
||||
)
|
||||
|
||||
self.db_con.Session["AVALON_PROJECT"] = ft_project["full_name"]
|
||||
project = self.db_con.find_one({'type': 'project'})
|
||||
if not project:
|
||||
key = "Projects not synchronized to db"
|
||||
if key not in interface_messages:
|
||||
interface_messages[key] = []
|
||||
interface_messages[key].append(ft_project["full_name"])
|
||||
continue
|
||||
|
||||
# Get all entities in project collection from MongoDB
|
||||
_entities = self.db_con.find({})
|
||||
for _entity in _entities:
|
||||
ent_t = _entity.get("type", "*unknown type")
|
||||
name = _entity.get("name", "*unknown name")
|
||||
|
||||
self.log.debug(
|
||||
"- {} ({})".format(name, ent_t)
|
||||
)
|
||||
|
||||
# Skip types that do not store keys to change
|
||||
if ent_t.lower() not in relevant_types:
|
||||
self.log.debug("-- skipping - type is not relevant")
|
||||
continue
|
||||
|
||||
# Get data which will change
|
||||
updating_data = {}
|
||||
source_data = _entity["data"]
|
||||
|
||||
for key_from, key_to in self.keys_to_change.items():
|
||||
# continue if final key already exists
|
||||
if type(key_to) == list:
|
||||
for key in key_to:
|
||||
# continue if final key was set in update_data
|
||||
if key in updating_data:
|
||||
continue
|
||||
|
||||
# continue if source key not exist or value is None
|
||||
value = source_data.get(key_from)
|
||||
if value is None:
|
||||
continue
|
||||
|
||||
self.log.debug(
|
||||
"-- changing key {} to {}".format(
|
||||
key_from,
|
||||
key
|
||||
)
|
||||
)
|
||||
|
||||
updating_data[key] = value
|
||||
else:
|
||||
if key_to in source_data:
|
||||
continue
|
||||
|
||||
# continue if final key was set in update_data
|
||||
if key_to in updating_data:
|
||||
continue
|
||||
|
||||
# continue if source key not exist or value is None
|
||||
value = source_data.get(key_from)
|
||||
if value is None:
|
||||
continue
|
||||
|
||||
self.log.debug(
|
||||
"-- changing key {} to {}".format(key_from, key_to)
|
||||
)
|
||||
updating_data[key_to] = value
|
||||
|
||||
# Pop out old keys from entity
|
||||
is_obsolete = False
|
||||
for key in self.keys_to_change:
|
||||
if key not in source_data:
|
||||
continue
|
||||
is_obsolete = True
|
||||
source_data.pop(key)
|
||||
|
||||
# continue if there is nothing to change
|
||||
if not is_obsolete and not updating_data:
|
||||
self.log.debug("-- nothing to change")
|
||||
continue
|
||||
|
||||
source_data.update(updating_data)
|
||||
|
||||
self.db_con.update_many(
|
||||
{"_id": _entity["_id"]},
|
||||
{"$set": {"data": source_data}}
|
||||
)
|
||||
|
||||
self.db_con.uninstall()
|
||||
|
||||
if interface_messages:
|
||||
self.show_interface_from_dict(
|
||||
messages=interface_messages,
|
||||
title="Errors during remapping attributes",
|
||||
event=event
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
def show_interface_from_dict(self, event, messages, title=""):
|
||||
items = []
|
||||
|
||||
for key, value in messages.items():
|
||||
if not value:
|
||||
continue
|
||||
subtitle = {'type': 'label', 'value': '# {}'.format(key)}
|
||||
items.append(subtitle)
|
||||
if isinstance(value, list):
|
||||
for item in value:
|
||||
message = {
|
||||
'type': 'label', 'value': '<p>{}</p>'.format(item)
|
||||
}
|
||||
items.append(message)
|
||||
else:
|
||||
message = {'type': 'label', 'value': '<p>{}</p>'.format(value)}
|
||||
items.append(message)
|
||||
|
||||
self.show_interface(items=items, title=title, event=event)
|
||||
|
||||
def register(session, plugins_presets={}):
|
||||
'''Register plugin. Called when used as an plugin.'''
|
||||
|
||||
AttributesRemapper(session, plugins_presets).register()
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
import os
|
||||
import collections
|
||||
import ftrack_api
|
||||
from pype.modules.ftrack import BaseAction
|
||||
from pype.modules.ftrack.lib import BaseAction, statics_icon
|
||||
from pype.modules.ftrack.lib.avalon_sync import get_avalon_attr
|
||||
|
||||
|
||||
|
|
@ -11,9 +10,7 @@ class CleanHierarchicalAttrsAction(BaseAction):
|
|||
variant = "- Clean hierarchical custom attributes"
|
||||
description = "Unset empty hierarchical attribute values."
|
||||
role_list = ["Pypeclub", "Administrator", "Project Manager"]
|
||||
icon = "{}/ftrack/action_icons/PypeAdmin.svg".format(
|
||||
os.environ.get("PYPE_STATICS_SERVER", "")
|
||||
)
|
||||
icon = statics_icon("ftrack", "action_icons", "PypeAdmin.svg")
|
||||
|
||||
all_project_entities_query = (
|
||||
"select id, name, parent_id, link"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from pype.modules.ftrack import BaseAction
|
||||
from pype.modules.ftrack.lib import BaseAction
|
||||
try:
|
||||
from functools import cmp_to_key
|
||||
except Exception:
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
import subprocess
|
||||
import ftrack_api
|
||||
from pype.modules.ftrack import BaseAction
|
||||
from pype.modules.ftrack.lib import BaseAction, statics_icon
|
||||
|
||||
|
||||
class ComponentOpen(BaseAction):
|
||||
|
|
@ -15,9 +12,7 @@ class ComponentOpen(BaseAction):
|
|||
# Action label
|
||||
label = 'Open File'
|
||||
# Action icon
|
||||
icon = '{}/ftrack/action_icons/ComponentOpen.svg'.format(
|
||||
os.environ.get('PYPE_STATICS_SERVER', '')
|
||||
)
|
||||
icon = statics_icon("ftrack", "action_icons", "ComponentOpen.svg")
|
||||
|
||||
def discover(self, session, entities, event):
|
||||
''' Validation '''
|
||||
|
|
@ -69,42 +64,3 @@ def register(session, plugins_presets={}):
|
|||
'''Register action. Called when used as an event plugin.'''
|
||||
|
||||
ComponentOpen(session, plugins_presets).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()
|
||||
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:]))
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
import os
|
||||
import collections
|
||||
import json
|
||||
import arrow
|
||||
import ftrack_api
|
||||
from pype.modules.ftrack import BaseAction
|
||||
from pype.modules.ftrack.lib import BaseAction, statics_icon
|
||||
from pype.modules.ftrack.lib.avalon_sync import CustAttrIdKey
|
||||
from pype.api import config
|
||||
|
||||
|
|
@ -114,9 +113,7 @@ class CustomAttributes(BaseAction):
|
|||
description = 'Creates Avalon/Mongo ID for double check'
|
||||
#: roles that are allowed to register this action
|
||||
role_list = ['Pypeclub', 'Administrator']
|
||||
icon = '{}/ftrack/action_icons/PypeAdmin.svg'.format(
|
||||
os.environ.get('PYPE_STATICS_SERVER', '')
|
||||
)
|
||||
icon = statics_icon("ftrack", "action_icons", "PypeAdmin.svg")
|
||||
|
||||
required_keys = ['key', 'label', 'type']
|
||||
type_posibilities = [
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import os
|
||||
from pype.modules.ftrack import BaseAction
|
||||
from pype.modules.ftrack.lib import BaseAction, statics_icon
|
||||
from avalon import lib as avalonlib
|
||||
from pype.api import config, Anatomy
|
||||
|
||||
|
|
@ -7,9 +7,7 @@ from pype.api import config, Anatomy
|
|||
class CreateFolders(BaseAction):
|
||||
identifier = "create.folders"
|
||||
label = "Create Folders"
|
||||
icon = "{}/ftrack/action_icons/CreateFolders.svg".format(
|
||||
os.environ.get("PYPE_STATICS_SERVER", "")
|
||||
)
|
||||
icon = statics_icon("ftrack", "action_icons", "CreateFolders.svg")
|
||||
|
||||
def discover(self, session, entities, event):
|
||||
if len(entities) != 1:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import os
|
||||
import re
|
||||
|
||||
from pype.modules.ftrack import BaseAction
|
||||
from pype.modules.ftrack.lib import BaseAction, statics_icon
|
||||
from pype.api import config, Anatomy
|
||||
|
||||
|
||||
|
|
@ -52,9 +52,7 @@ class CreateProjectFolders(BaseAction):
|
|||
label = "Create Project Structure"
|
||||
description = "Creates folder structure"
|
||||
role_list = ["Pypeclub", "Administrator", "Project Manager"]
|
||||
icon = "{}/ftrack/action_icons/CreateProjectFolders.svg".format(
|
||||
os.environ.get("PYPE_STATICS_SERVER", "")
|
||||
)
|
||||
icon = statics_icon("ftrack", "action_icons", "CreateProjectFolders.svg")
|
||||
|
||||
pattern_array = re.compile(r"\[.*\]")
|
||||
pattern_ftrack = re.compile(r".*\[[.]*ftrack[.]*")
|
||||
|
|
|
|||
|
|
@ -1,336 +0,0 @@
|
|||
import os
|
||||
import sys
|
||||
import json
|
||||
import argparse
|
||||
import logging
|
||||
|
||||
import ftrack_api
|
||||
from pype.modules.ftrack import BaseAction
|
||||
|
||||
|
||||
class CustomAttributeDoctor(BaseAction):
|
||||
|
||||
ignore_me = True
|
||||
#: Action identifier.
|
||||
identifier = 'custom.attributes.doctor'
|
||||
#: Action label.
|
||||
label = "Pype Doctor"
|
||||
variant = '- Custom Attributes Doctor'
|
||||
#: Action description.
|
||||
description = (
|
||||
'Fix hierarchical custom attributes mainly handles, fstart'
|
||||
' and fend'
|
||||
)
|
||||
|
||||
icon = '{}/ftrack/action_icons/PypeDoctor.svg'.format(
|
||||
os.environ.get('PYPE_STATICS_SERVER', '')
|
||||
)
|
||||
hierarchical_ca = ['handleStart', 'handleEnd', 'frameStart', 'frameEnd']
|
||||
hierarchical_alternatives = {
|
||||
'handleStart': 'handles',
|
||||
'handleEnd': 'handles',
|
||||
"frameStart": "fstart",
|
||||
"frameEnd": "fend"
|
||||
}
|
||||
|
||||
# Roles for new custom attributes
|
||||
read_roles = ['ALL',]
|
||||
write_roles = ['ALL',]
|
||||
|
||||
data_ca = {
|
||||
'handleStart': {
|
||||
'label': 'Frame handles start',
|
||||
'type': 'number',
|
||||
'config': json.dumps({'isdecimal': False})
|
||||
},
|
||||
'handleEnd': {
|
||||
'label': 'Frame handles end',
|
||||
'type': 'number',
|
||||
'config': json.dumps({'isdecimal': False})
|
||||
},
|
||||
'frameStart': {
|
||||
'label': 'Frame start',
|
||||
'type': 'number',
|
||||
'config': json.dumps({'isdecimal': False})
|
||||
},
|
||||
'frameEnd': {
|
||||
'label': 'Frame end',
|
||||
'type': 'number',
|
||||
'config': json.dumps({'isdecimal': False})
|
||||
}
|
||||
}
|
||||
|
||||
def discover(self, session, entities, event):
|
||||
''' Validation '''
|
||||
|
||||
return True
|
||||
|
||||
def interface(self, session, entities, event):
|
||||
if event['data'].get('values', {}):
|
||||
return
|
||||
|
||||
title = 'Select Project to fix Custom attributes'
|
||||
|
||||
items = []
|
||||
item_splitter = {'type': 'label', 'value': '---'}
|
||||
|
||||
all_projects = session.query('Project').all()
|
||||
for project in all_projects:
|
||||
item_label = {
|
||||
'type': 'label',
|
||||
'value': '{} (<i>{}</i>)'.format(
|
||||
project['full_name'], project['name']
|
||||
)
|
||||
}
|
||||
item = {
|
||||
'name': project['id'],
|
||||
'type': 'boolean',
|
||||
'value': False
|
||||
}
|
||||
if len(items) > 0:
|
||||
items.append(item_splitter)
|
||||
items.append(item_label)
|
||||
items.append(item)
|
||||
|
||||
if len(items) == 0:
|
||||
return {
|
||||
'success': False,
|
||||
'message': 'Didn\'t found any projects'
|
||||
}
|
||||
else:
|
||||
return {
|
||||
'items': items,
|
||||
'title': title
|
||||
}
|
||||
|
||||
def launch(self, session, entities, event):
|
||||
if 'values' not in event['data']:
|
||||
return
|
||||
|
||||
values = event['data']['values']
|
||||
projects_to_update = []
|
||||
for project_id, update_bool in values.items():
|
||||
if not update_bool:
|
||||
continue
|
||||
|
||||
project = session.query(
|
||||
'Project where id is "{}"'.format(project_id)
|
||||
).one()
|
||||
projects_to_update.append(project)
|
||||
|
||||
if not projects_to_update:
|
||||
self.log.debug('Nothing to update')
|
||||
return {
|
||||
'success': True,
|
||||
'message': 'Nothing to update'
|
||||
}
|
||||
|
||||
self.security_roles = {}
|
||||
self.to_process = {}
|
||||
# self.curent_default_values = {}
|
||||
existing_attrs = session.query('CustomAttributeConfiguration').all()
|
||||
self.prepare_custom_attributes(existing_attrs)
|
||||
|
||||
self.projects_data = {}
|
||||
for project in projects_to_update:
|
||||
self.process_data(project)
|
||||
|
||||
return True
|
||||
|
||||
def process_data(self, entity):
|
||||
cust_attrs = entity.get('custom_attributes')
|
||||
if not cust_attrs:
|
||||
return
|
||||
for dst_key, src_key in self.to_process.items():
|
||||
if src_key in cust_attrs:
|
||||
value = cust_attrs[src_key]
|
||||
entity['custom_attributes'][dst_key] = value
|
||||
self.session.commit()
|
||||
|
||||
for child in entity.get('children', []):
|
||||
self.process_data(child)
|
||||
|
||||
def prepare_custom_attributes(self, existing_attrs):
|
||||
to_process = {}
|
||||
to_create = []
|
||||
all_keys = {attr['key']: attr for attr in existing_attrs}
|
||||
for key in self.hierarchical_ca:
|
||||
if key not in all_keys:
|
||||
self.log.debug(
|
||||
'Custom attribute "{}" does not exist at all'.format(key)
|
||||
)
|
||||
to_create.append(key)
|
||||
if key in self.hierarchical_alternatives:
|
||||
alt_key = self.hierarchical_alternatives[key]
|
||||
if alt_key in all_keys:
|
||||
self.log.debug((
|
||||
'Custom attribute "{}" will use values from "{}"'
|
||||
).format(key, alt_key))
|
||||
|
||||
to_process[key] = alt_key
|
||||
|
||||
obj = all_keys[alt_key]
|
||||
# if alt_key not in self.curent_default_values:
|
||||
# self.curent_default_values[alt_key] = obj['default']
|
||||
obj['default'] = None
|
||||
self.session.commit()
|
||||
|
||||
else:
|
||||
obj = all_keys[key]
|
||||
new_key = key + '_old'
|
||||
|
||||
if obj['is_hierarchical']:
|
||||
if new_key not in all_keys:
|
||||
self.log.info((
|
||||
'Custom attribute "{}" is already hierarchical'
|
||||
' and can\'t find old one'
|
||||
).format(key)
|
||||
)
|
||||
continue
|
||||
|
||||
to_process[key] = new_key
|
||||
continue
|
||||
|
||||
# default_value = obj['default']
|
||||
# if new_key not in self.curent_default_values:
|
||||
# self.curent_default_values[new_key] = default_value
|
||||
|
||||
obj['key'] = new_key
|
||||
obj['label'] = obj['label'] + '(old)'
|
||||
obj['default'] = None
|
||||
|
||||
self.session.commit()
|
||||
|
||||
to_create.append(key)
|
||||
to_process[key] = new_key
|
||||
|
||||
self.to_process = to_process
|
||||
for key in to_create:
|
||||
data = {
|
||||
'key': key,
|
||||
'entity_type': 'show',
|
||||
'is_hierarchical': True,
|
||||
'default': None
|
||||
}
|
||||
for _key, _value in self.data_ca.get(key, {}).items():
|
||||
if _key == 'type':
|
||||
_value = self.session.query((
|
||||
'CustomAttributeType where name is "{}"'
|
||||
).format(_value)).first()
|
||||
|
||||
data[_key] = _value
|
||||
|
||||
avalon_group = self.session.query(
|
||||
'CustomAttributeGroup where name is "avalon"'
|
||||
).first()
|
||||
if avalon_group:
|
||||
data['group'] = avalon_group
|
||||
|
||||
read_roles = self.get_security_role(self.read_roles)
|
||||
write_roles = self.get_security_role(self.write_roles)
|
||||
data['read_security_roles'] = read_roles
|
||||
data['write_security_roles'] = write_roles
|
||||
|
||||
self.session.create('CustomAttributeConfiguration', data)
|
||||
self.session.commit()
|
||||
|
||||
# def return_back_defaults(self):
|
||||
# existing_attrs = self.session.query(
|
||||
# 'CustomAttributeConfiguration'
|
||||
# ).all()
|
||||
#
|
||||
# for attr_key, default in self.curent_default_values.items():
|
||||
# for attr in existing_attrs:
|
||||
# if attr['key'] != attr_key:
|
||||
# continue
|
||||
# attr['default'] = default
|
||||
# self.session.commit()
|
||||
# break
|
||||
|
||||
def get_security_role(self, security_roles):
|
||||
roles = []
|
||||
if len(security_roles) == 0 or security_roles[0] == 'ALL':
|
||||
roles = self.get_role_ALL()
|
||||
elif security_roles[0] == 'except':
|
||||
excepts = security_roles[1:]
|
||||
all = self.get_role_ALL()
|
||||
for role in all:
|
||||
if role['name'] not in excepts:
|
||||
roles.append(role)
|
||||
if role['name'] not in self.security_roles:
|
||||
self.security_roles[role['name']] = role
|
||||
else:
|
||||
for role_name in security_roles:
|
||||
if role_name in self.security_roles:
|
||||
roles.append(self.security_roles[role_name])
|
||||
continue
|
||||
|
||||
try:
|
||||
query = 'SecurityRole where name is "{}"'.format(role_name)
|
||||
role = self.session.query(query).one()
|
||||
self.security_roles[role_name] = role
|
||||
roles.append(role)
|
||||
except Exception:
|
||||
self.log.warning(
|
||||
'Securit role "{}" does not exist'.format(role_name)
|
||||
)
|
||||
continue
|
||||
|
||||
return roles
|
||||
|
||||
def get_role_ALL(self):
|
||||
role_name = 'ALL'
|
||||
if role_name in self.security_roles:
|
||||
all_roles = self.security_roles[role_name]
|
||||
else:
|
||||
all_roles = self.session.query('SecurityRole').all()
|
||||
self.security_roles[role_name] = all_roles
|
||||
for role in all_roles:
|
||||
if role['name'] not in self.security_roles:
|
||||
self.security_roles[role['name']] = role
|
||||
return all_roles
|
||||
|
||||
|
||||
def register(session, plugins_presets={}):
|
||||
'''Register plugin. Called when used as an plugin.'''
|
||||
|
||||
CustomAttributeDoctor(session, plugins_presets).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()
|
||||
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:]))
|
||||
|
|
@ -1,11 +1,10 @@
|
|||
import os
|
||||
import collections
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
from queue import Queue
|
||||
|
||||
from bson.objectid import ObjectId
|
||||
from pype.modules.ftrack import BaseAction
|
||||
from pype.modules.ftrack.lib import BaseAction, statics_icon
|
||||
from pype.modules.ftrack.lib.io_nonsingleton import DbConnector
|
||||
|
||||
|
||||
|
|
@ -18,9 +17,7 @@ class DeleteAssetSubset(BaseAction):
|
|||
label = "Delete Asset/Subsets"
|
||||
#: Action description.
|
||||
description = "Removes from Avalon with all childs and asset from Ftrack"
|
||||
icon = "{}/ftrack/action_icons/DeleteAsset.svg".format(
|
||||
os.environ.get("PYPE_STATICS_SERVER", "")
|
||||
)
|
||||
icon = statics_icon("ftrack", "action_icons", "DeleteAsset.svg")
|
||||
#: roles that are allowed to register this action
|
||||
role_list = ["Pypeclub", "Administrator", "Project Manager"]
|
||||
#: Db connection
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import uuid
|
|||
import clique
|
||||
from pymongo import UpdateOne
|
||||
|
||||
from pype.modules.ftrack import BaseAction
|
||||
from pype.modules.ftrack.lib import BaseAction, statics_icon
|
||||
from pype.modules.ftrack.lib.io_nonsingleton import DbConnector
|
||||
from pype.api import Anatomy
|
||||
|
||||
|
|
@ -22,9 +22,7 @@ class DeleteOldVersions(BaseAction):
|
|||
" archived with only lates versions."
|
||||
)
|
||||
role_list = ["Pypeclub", "Project Manager", "Administrator"]
|
||||
icon = "{}/ftrack/action_icons/PypeAdmin.svg".format(
|
||||
os.environ.get("PYPE_STATICS_SERVER", "")
|
||||
)
|
||||
icon = statics_icon("ftrack", "action_icons", "PypeAdmin.svg")
|
||||
|
||||
dbcon = DbConnector()
|
||||
|
||||
|
|
|
|||
|
|
@ -8,11 +8,11 @@ from bson.objectid import ObjectId
|
|||
|
||||
from avalon import pipeline
|
||||
from avalon.vendor import filelink
|
||||
from avalon.tools.libraryloader.io_nonsingleton import DbConnector
|
||||
|
||||
from pype.api import Anatomy
|
||||
from pype.modules.ftrack import BaseAction
|
||||
from pype.modules.ftrack.lib import BaseAction, statics_icon
|
||||
from pype.modules.ftrack.lib.avalon_sync import CustAttrIdKey
|
||||
from pype.modules.ftrack.lib.io_nonsingleton import DbConnector
|
||||
|
||||
|
||||
class Delivery(BaseAction):
|
||||
|
|
@ -21,9 +21,7 @@ class Delivery(BaseAction):
|
|||
label = "Delivery"
|
||||
description = "Deliver data to client"
|
||||
role_list = ["Pypeclub", "Administrator", "Project manager"]
|
||||
icon = "{}/ftrack/action_icons/Delivery.svg".format(
|
||||
os.environ.get("PYPE_STATICS_SERVER", "")
|
||||
)
|
||||
icon = statics_icon("ftrack", "action_icons", "Delivery.svg")
|
||||
|
||||
db_con = DbConnector()
|
||||
|
||||
|
|
@ -508,6 +506,7 @@ class Delivery(BaseAction):
|
|||
"message": "Delivery Finished"
|
||||
}
|
||||
|
||||
|
||||
def register(session, plugins_presets={}):
|
||||
'''Register plugin. Called when used as an plugin.'''
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
import os
|
||||
import sys
|
||||
import json
|
||||
import logging
|
||||
import subprocess
|
||||
from operator import itemgetter
|
||||
import ftrack_api
|
||||
from pype.modules.ftrack import BaseAction
|
||||
from pype.modules.ftrack.lib import BaseAction, statics_icon
|
||||
from pype.api import Logger, config
|
||||
|
||||
log = Logger().get_logger(__name__)
|
||||
|
|
@ -16,9 +15,8 @@ class DJVViewAction(BaseAction):
|
|||
identifier = "djvview-launch-action"
|
||||
label = "DJV View"
|
||||
description = "DJV View Launcher"
|
||||
icon = '{}/app_icons/djvView.png'.format(
|
||||
os.environ.get('PYPE_STATICS_SERVER', '')
|
||||
)
|
||||
icon = statics_icon("app_icons", "djvView.png")
|
||||
|
||||
type = 'Application'
|
||||
|
||||
def __init__(self, session, plugins_presets):
|
||||
|
|
|
|||
|
|
@ -1,11 +1,5 @@
|
|||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
import json
|
||||
|
||||
import ftrack_api
|
||||
from pype.modules.ftrack import BaseAction
|
||||
from pype.modules.ftrack.lib import BaseAction, statics_icon
|
||||
|
||||
|
||||
class JobKiller(BaseAction):
|
||||
|
|
@ -20,9 +14,7 @@ class JobKiller(BaseAction):
|
|||
description = 'Killing selected running jobs'
|
||||
#: roles that are allowed to register this action
|
||||
role_list = ['Pypeclub', 'Administrator']
|
||||
icon = '{}/ftrack/action_icons/PypeAdmin.svg'.format(
|
||||
os.environ.get('PYPE_STATICS_SERVER', '')
|
||||
)
|
||||
icon = statics_icon("ftrack", "action_icons", "PypeAdmin.svg")
|
||||
|
||||
def discover(self, session, entities, event):
|
||||
''' Validation '''
|
||||
|
|
@ -124,43 +116,3 @@ def register(session, plugins_presets={}):
|
|||
'''Register plugin. Called when used as an plugin.'''
|
||||
|
||||
JobKiller(session, plugins_presets).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()
|
||||
|
||||
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:]))
|
||||
|
|
|
|||
|
|
@ -1,10 +1,4 @@
|
|||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
import ftrack_api
|
||||
|
||||
from pype.modules.ftrack import BaseAction
|
||||
from pype.modules.ftrack.lib import BaseAction, statics_icon
|
||||
|
||||
|
||||
class MultipleNotes(BaseAction):
|
||||
|
|
@ -16,9 +10,7 @@ class MultipleNotes(BaseAction):
|
|||
label = 'Multiple Notes'
|
||||
#: Action description.
|
||||
description = 'Add same note to multiple Asset Versions'
|
||||
icon = '{}/ftrack/action_icons/MultipleNotes.svg'.format(
|
||||
os.environ.get('PYPE_STATICS_SERVER', '')
|
||||
)
|
||||
icon = statics_icon("ftrack", "action_icons", "MultipleNotes.svg")
|
||||
|
||||
def discover(self, session, entities, event):
|
||||
''' Validation '''
|
||||
|
|
@ -116,42 +108,3 @@ def register(session, plugins_presets={}):
|
|||
'''Register plugin. Called when used as an plugin.'''
|
||||
|
||||
MultipleNotes(session, plugins_presets).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()
|
||||
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:]))
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import os
|
||||
import json
|
||||
|
||||
from pype.modules.ftrack import BaseAction
|
||||
from pype.modules.ftrack.lib import BaseAction, statics_icon
|
||||
from pype.api import config, Anatomy, project_overrides_dir_path
|
||||
from pype.modules.ftrack.lib.avalon_sync import get_avalon_attr
|
||||
|
||||
|
|
@ -17,9 +17,7 @@ class PrepareProject(BaseAction):
|
|||
description = 'Set basic attributes on the project'
|
||||
#: roles that are allowed to register this action
|
||||
role_list = ["Pypeclub", "Administrator", "Project manager"]
|
||||
icon = '{}/ftrack/action_icons/PrepareProject.svg'.format(
|
||||
os.environ.get('PYPE_STATICS_SERVER', '')
|
||||
)
|
||||
icon = statics_icon("ftrack", "action_icons", "PrepareProject.svg")
|
||||
|
||||
# Key to store info about trigerring create folder structure
|
||||
create_project_structure_key = "create_folder_structure"
|
||||
|
|
|
|||
|
|
@ -1,17 +1,13 @@
|
|||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import logging
|
||||
import traceback
|
||||
import json
|
||||
|
||||
from pype.api import Logger, config
|
||||
from pype.modules.ftrack import BaseAction
|
||||
from pype.api import config
|
||||
from pype.modules.ftrack.lib import BaseAction, statics_icon
|
||||
import ftrack_api
|
||||
from avalon import io, api
|
||||
|
||||
log = Logger().get_logger(__name__)
|
||||
|
||||
|
||||
class RVAction(BaseAction):
|
||||
""" Launch RV action """
|
||||
|
|
@ -19,9 +15,8 @@ class RVAction(BaseAction):
|
|||
identifier = "rv.launch.action"
|
||||
label = "rv"
|
||||
description = "rv Launcher"
|
||||
icon = '{}/ftrack/action_icons/RV.png'.format(
|
||||
os.environ.get('PYPE_STATICS_SERVER', '')
|
||||
)
|
||||
icon = statics_icon("ftrack", "action_icons", "RV.png")
|
||||
|
||||
type = 'Application'
|
||||
|
||||
def __init__(self, session, plugins_presets):
|
||||
|
|
@ -144,7 +139,7 @@ class RVAction(BaseAction):
|
|||
try:
|
||||
items = self.get_interface_items(session, entities)
|
||||
except Exception:
|
||||
log.error(traceback.format_exc())
|
||||
self.log.error(traceback.format_exc())
|
||||
job["status"] = "failed"
|
||||
else:
|
||||
job["status"] = "done"
|
||||
|
|
@ -238,7 +233,7 @@ class RVAction(BaseAction):
|
|||
try:
|
||||
paths = self.get_file_paths(session, event)
|
||||
except Exception:
|
||||
log.error(traceback.format_exc())
|
||||
self.log.error(traceback.format_exc())
|
||||
job["status"] = "failed"
|
||||
else:
|
||||
job["status"] = "done"
|
||||
|
|
@ -254,7 +249,7 @@ class RVAction(BaseAction):
|
|||
|
||||
args.extend(paths)
|
||||
|
||||
log.info("Running rv: {}".format(args))
|
||||
self.log.info("Running rv: {}".format(args))
|
||||
|
||||
subprocess.Popen(args)
|
||||
|
||||
|
|
@ -332,43 +327,3 @@ def register(session, plugins_presets={}):
|
|||
"""Register hooks."""
|
||||
|
||||
RVAction(session, plugins_presets).register()
|
||||
|
||||
|
||||
def main(arguments=None):
|
||||
'''Set up logging and register action.'''
|
||||
if arguments is None:
|
||||
arguments = []
|
||||
|
||||
import argparse
|
||||
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:]))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import os
|
||||
from operator import itemgetter
|
||||
from pype.modules.ftrack import BaseAction
|
||||
from pype.modules.ftrack.lib import BaseAction, statics_icon
|
||||
|
||||
|
||||
class SeedDebugProject(BaseAction):
|
||||
|
|
@ -16,9 +16,7 @@ class SeedDebugProject(BaseAction):
|
|||
priority = 100
|
||||
#: roles that are allowed to register this action
|
||||
role_list = ["Pypeclub"]
|
||||
icon = "{}/ftrack/action_icons/SeedProject.svg".format(
|
||||
os.environ.get("PYPE_STATICS_SERVER", "")
|
||||
)
|
||||
icon = statics_icon("ftrack", "action_icons", "SeedProject.svg")
|
||||
|
||||
# Asset names which will be created in `Assets` entity
|
||||
assets = [
|
||||
|
|
@ -429,6 +427,7 @@ class SeedDebugProject(BaseAction):
|
|||
self.session.commit()
|
||||
return True
|
||||
|
||||
|
||||
def register(session, plugins_presets={}):
|
||||
'''Register plugin. Called when used as an plugin.'''
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import ftrack_api
|
||||
from pype.modules.ftrack import BaseAction
|
||||
from pype.modules.ftrack.lib import BaseAction
|
||||
|
||||
|
||||
class StartTimer(BaseAction):
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import errno
|
|||
import json
|
||||
|
||||
from bson.objectid import ObjectId
|
||||
from pype.modules.ftrack import BaseAction
|
||||
from pype.modules.ftrack.lib import BaseAction, statics_icon
|
||||
from pype.api import Anatomy
|
||||
from pype.modules.ftrack.lib.io_nonsingleton import DbConnector
|
||||
|
||||
|
|
@ -22,10 +22,7 @@ class StoreThumbnailsToAvalon(BaseAction):
|
|||
description = 'Test action'
|
||||
# roles that are allowed to register this action
|
||||
role_list = ["Pypeclub", "Administrator", "Project Manager"]
|
||||
|
||||
icon = '{}/ftrack/action_icons/PypeAdmin.svg'.format(
|
||||
os.environ.get('PYPE_STATICS_SERVER', '')
|
||||
)
|
||||
icon = statics_icon("ftrack", "action_icons", "PypeAdmin.svg")
|
||||
|
||||
thumbnail_key = "AVALON_THUMBNAIL_ROOT"
|
||||
db_con = DbConnector()
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
import os
|
||||
import time
|
||||
import traceback
|
||||
|
||||
from pype.modules.ftrack import BaseAction
|
||||
from pype.modules.ftrack.lib import BaseAction, statics_icon
|
||||
from pype.modules.ftrack.lib.avalon_sync import SyncEntitiesFactory
|
||||
|
||||
|
||||
|
|
@ -43,9 +42,7 @@ class SyncToAvalonLocal(BaseAction):
|
|||
priority = 200
|
||||
#: roles that are allowed to register this action
|
||||
role_list = ["Pypeclub"]
|
||||
icon = '{}/ftrack/action_icons/PypeAdmin.svg'.format(
|
||||
os.environ.get('PYPE_STATICS_SERVER', '')
|
||||
)
|
||||
icon = statics_icon("ftrack", "action_icons", "PypeAdmin.svg")
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
|
|
|||
|
|
@ -1,37 +1,19 @@
|
|||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
import collections
|
||||
import json
|
||||
import re
|
||||
|
||||
import ftrack_api
|
||||
from avalon import io, inventory, schema
|
||||
from pype.modules.ftrack import BaseAction
|
||||
from pype.modules.ftrack.lib import BaseAction, statics_icon
|
||||
|
||||
|
||||
class TestAction(BaseAction):
|
||||
'''Edit meta data action.'''
|
||||
"""Action for testing purpose or as base for new actions."""
|
||||
|
||||
ignore_me = True
|
||||
#: Action identifier.
|
||||
|
||||
identifier = 'test.action'
|
||||
#: Action label.
|
||||
label = 'Test action'
|
||||
#: Action description.
|
||||
description = 'Test action'
|
||||
#: priority
|
||||
priority = 10000
|
||||
#: roles that are allowed to register this action
|
||||
role_list = ['Pypeclub']
|
||||
icon = '{}/ftrack/action_icons/TestAction.svg'.format(
|
||||
os.environ.get('PYPE_STATICS_SERVER', '')
|
||||
)
|
||||
icon = statics_icon("ftrack", "action_icons", "TestAction.svg")
|
||||
|
||||
def discover(self, session, entities, event):
|
||||
''' Validation '''
|
||||
|
||||
return True
|
||||
|
||||
def launch(self, session, entities, event):
|
||||
|
|
@ -41,45 +23,4 @@ class TestAction(BaseAction):
|
|||
|
||||
|
||||
def register(session, plugins_presets={}):
|
||||
'''Register plugin. Called when used as an plugin.'''
|
||||
|
||||
TestAction(session, plugins_presets).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()
|
||||
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:]))
|
||||
|
|
|
|||
|
|
@ -1,11 +1,5 @@
|
|||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
import json
|
||||
|
||||
import ftrack_api
|
||||
from pype.modules.ftrack import BaseAction
|
||||
from pype.modules.ftrack.lib import BaseAction, statics_icon
|
||||
|
||||
|
||||
class ThumbToChildren(BaseAction):
|
||||
|
|
@ -18,9 +12,7 @@ class ThumbToChildren(BaseAction):
|
|||
# Action variant
|
||||
variant = " to Children"
|
||||
# Action icon
|
||||
icon = '{}/ftrack/action_icons/Thumbnail.svg'.format(
|
||||
os.environ.get('PYPE_STATICS_SERVER', '')
|
||||
)
|
||||
icon = statics_icon("ftrack", "action_icons", "Thumbnail.svg")
|
||||
|
||||
def discover(self, session, entities, event):
|
||||
''' Validation '''
|
||||
|
|
@ -71,42 +63,3 @@ def register(session, plugins_presets={}):
|
|||
'''Register action. Called when used as an event plugin.'''
|
||||
|
||||
ThumbToChildren(session, plugins_presets).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()
|
||||
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:]))
|
||||
|
|
|
|||
|
|
@ -1,10 +1,5 @@
|
|||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
import json
|
||||
import ftrack_api
|
||||
from pype.modules.ftrack import BaseAction
|
||||
from pype.modules.ftrack.lib import BaseAction, statics_icon
|
||||
|
||||
|
||||
class ThumbToParent(BaseAction):
|
||||
|
|
@ -17,9 +12,7 @@ class ThumbToParent(BaseAction):
|
|||
# Action variant
|
||||
variant = " to Parent"
|
||||
# Action icon
|
||||
icon = '{}/ftrack/action_icons/Thumbnail.svg'.format(
|
||||
os.environ.get('PYPE_STATICS_SERVER', '')
|
||||
)
|
||||
icon = statics_icon("ftrack", "action_icons", "Thumbnail.svg")
|
||||
|
||||
def discover(self, session, entities, event):
|
||||
'''Return action config if triggered on asset versions.'''
|
||||
|
|
@ -93,42 +86,3 @@ def register(session, plugins_presets={}):
|
|||
'''Register action. Called when used as an event plugin.'''
|
||||
|
||||
ThumbToParent(session, plugins_presets).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()
|
||||
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:]))
|
||||
|
|
|
|||
|
|
@ -1,189 +0,0 @@
|
|||
import os
|
||||
|
||||
from pype.modules.ftrack import BaseAction
|
||||
from pype.modules.ftrack.lib.io_nonsingleton import DbConnector
|
||||
|
||||
|
||||
class PypeUpdateFromV2_2_0(BaseAction):
|
||||
"""This action is to remove silo field from database and changes asset
|
||||
schema to newer version
|
||||
|
||||
WARNING: it is NOT for situations when you want to switch from avalon-core
|
||||
to Pype's avalon-core!!!
|
||||
|
||||
"""
|
||||
#: Action identifier.
|
||||
identifier = "silos.doctor"
|
||||
#: Action label.
|
||||
label = "Pype Update"
|
||||
variant = "- v2.2.0 to v2.3.0 or higher"
|
||||
#: Action description.
|
||||
description = "Use when Pype was updated from v2.2.0 to v2.3.0 or higher"
|
||||
|
||||
#: roles that are allowed to register this action
|
||||
role_list = ["Pypeclub", "Administrator"]
|
||||
icon = "{}/ftrack/action_icons/PypeUpdate.svg".format(
|
||||
os.environ.get("PYPE_STATICS_SERVER", "")
|
||||
)
|
||||
# connector to MongoDB (Avalon mongo)
|
||||
db_con = DbConnector()
|
||||
|
||||
def discover(self, session, entities, event):
|
||||
""" Validation """
|
||||
if len(entities) != 1:
|
||||
return False
|
||||
|
||||
if entities[0].entity_type.lower() != "project":
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def interface(self, session, entities, event):
|
||||
if event['data'].get('values', {}):
|
||||
return
|
||||
|
||||
items = []
|
||||
item_splitter = {'type': 'label', 'value': '---'}
|
||||
title = "Updated Pype from v 2.2.0 to v2.3.0 or higher"
|
||||
|
||||
items.append({
|
||||
"type": "label",
|
||||
"value": (
|
||||
"NOTE: This doctor action should be used ONLY when Pype"
|
||||
" was updated from v2.2.0 to v2.3.0 or higher.<br><br><br>"
|
||||
)
|
||||
})
|
||||
|
||||
items.append({
|
||||
"type": "label",
|
||||
"value": (
|
||||
"Select if want to process <b>all synchronized projects</b>"
|
||||
" or <b>selection</b>."
|
||||
)
|
||||
})
|
||||
|
||||
items.append({
|
||||
"type": "enumerator",
|
||||
"name": "__process_all__",
|
||||
"data": [{
|
||||
"label": "All synchronized projects",
|
||||
"value": True
|
||||
}, {
|
||||
"label": "Selection",
|
||||
"value": False
|
||||
}],
|
||||
"value": False
|
||||
})
|
||||
|
||||
items.append({
|
||||
"type": "label",
|
||||
"value": (
|
||||
"<br/><br/><h2>Synchronized projects:</h2>"
|
||||
"<i>(ignore if <strong>\"ALL projects\"</strong> selected)</i>"
|
||||
)
|
||||
})
|
||||
|
||||
self.log.debug("Getting all Ftrack projects")
|
||||
# Get all Ftrack projects
|
||||
all_ftrack_projects = [
|
||||
project["full_name"] for project in session.query("Project").all()
|
||||
]
|
||||
|
||||
self.log.debug("Getting Avalon projects that are also in the Ftrack")
|
||||
# Get Avalon projects that are in Ftrack
|
||||
self.db_con.install()
|
||||
possible_projects = [
|
||||
project["name"] for project in self.db_con.projects()
|
||||
if project["name"] in all_ftrack_projects
|
||||
]
|
||||
|
||||
for project in possible_projects:
|
||||
item_label = {
|
||||
"type": "label",
|
||||
"value": project
|
||||
}
|
||||
item = {
|
||||
"label": "- process",
|
||||
"name": project,
|
||||
"type": 'boolean',
|
||||
"value": False
|
||||
}
|
||||
items.append(item_splitter)
|
||||
items.append(item_label)
|
||||
items.append(item)
|
||||
|
||||
if len(possible_projects) == 0:
|
||||
return {
|
||||
"success": False,
|
||||
"message": (
|
||||
"Nothing to process."
|
||||
" There are not projects synchronized to avalon."
|
||||
)
|
||||
}
|
||||
else:
|
||||
return {
|
||||
"items": items,
|
||||
"title": title
|
||||
}
|
||||
|
||||
def launch(self, session, entities, event):
|
||||
if 'values' not in event['data']:
|
||||
return
|
||||
|
||||
projects_selection = {
|
||||
True: [],
|
||||
False: []
|
||||
}
|
||||
process_all = None
|
||||
|
||||
values = event['data']['values']
|
||||
for key, value in values.items():
|
||||
if key == "__process_all__":
|
||||
process_all = value
|
||||
continue
|
||||
|
||||
projects_selection[value].append(key)
|
||||
|
||||
# Skip if process_all value is not boolean
|
||||
# - may happen when user delete string line in combobox
|
||||
if not isinstance(process_all, bool):
|
||||
self.log.warning(
|
||||
"Nothing was processed. User didn't select if want to process"
|
||||
" selection or all projects!"
|
||||
)
|
||||
return {
|
||||
"success": False,
|
||||
"message": (
|
||||
"Nothing was processed. You must select if want to process"
|
||||
" \"selection\" or \"all projects\"!"
|
||||
)
|
||||
}
|
||||
|
||||
projects_to_process = projects_selection[True]
|
||||
if process_all:
|
||||
projects_to_process.extend(projects_selection[False])
|
||||
|
||||
self.db_con.install()
|
||||
for project in projects_to_process:
|
||||
self.log.debug("Processing project \"{}\"".format(project))
|
||||
self.db_con.Session["AVALON_PROJECT"] = project
|
||||
|
||||
self.log.debug("- Unsetting silos on assets")
|
||||
self.db_con.update_many(
|
||||
{"type": "asset"},
|
||||
{"$unset": {"silo": ""}}
|
||||
)
|
||||
|
||||
self.log.debug("- setting schema of assets to v.3")
|
||||
self.db_con.update_many(
|
||||
{"type": "asset"},
|
||||
{"$set": {"schema": "avalon-core:asset-3.0"}}
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def register(session, plugins_presets={}):
|
||||
"""Register plugin. Called when used as an plugin."""
|
||||
|
||||
PypeUpdateFromV2_2_0(session, plugins_presets).register()
|
||||
|
|
@ -1,23 +1,15 @@
|
|||
import os
|
||||
from pype.modules.ftrack import BaseAction
|
||||
from pype.modules.ftrack.lib import BaseAction, statics_icon
|
||||
|
||||
|
||||
class ActionAskWhereIRun(BaseAction):
|
||||
""" Sometimes user forget where pipeline with his credentials is running.
|
||||
- this action triggers `ActionShowWhereIRun`
|
||||
"""
|
||||
# Action is ignored by default
|
||||
ignore_me = True
|
||||
#: Action identifier.
|
||||
identifier = 'ask.where.i.run'
|
||||
#: Action label.
|
||||
label = 'Ask where I run'
|
||||
#: Action description.
|
||||
description = 'Triggers PC info where user have running Pype'
|
||||
#: Action icon
|
||||
icon = '{}/ftrack/action_icons/ActionAskWhereIRun.svg'.format(
|
||||
os.environ.get('PYPE_STATICS_SERVER', '')
|
||||
)
|
||||
icon = statics_icon("ftrack", "action_icons", "ActionAskWhereIRun.svg")
|
||||
|
||||
def discover(self, session, entities, event):
|
||||
""" Hide by default - Should be enabled only if you want to run.
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
import platform
|
||||
import socket
|
||||
import getpass
|
||||
import ftrack_api
|
||||
from pype.modules.ftrack import BaseAction
|
||||
from pype.modules.ftrack.lib import BaseAction
|
||||
|
||||
|
||||
class ActionShowWhereIRun(BaseAction):
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from . import avalon_sync
|
|||
from . import credentials
|
||||
from .ftrack_base_handler import BaseHandler
|
||||
from .ftrack_event_handler import BaseEvent
|
||||
from .ftrack_action_handler import BaseAction
|
||||
from .ftrack_action_handler import BaseAction, statics_icon
|
||||
from .ftrack_app_handler import AppAction
|
||||
|
||||
__all__ = [
|
||||
|
|
@ -11,5 +11,6 @@ __all__ = [
|
|||
"BaseHandler",
|
||||
"BaseEvent",
|
||||
"BaseAction",
|
||||
"statics_icon",
|
||||
"AppAction"
|
||||
]
|
||||
|
|
|
|||
|
|
@ -5,27 +5,20 @@ Copy of io module in avalon-core.
|
|||
- In this case not working as singleton with api.Session!
|
||||
"""
|
||||
|
||||
import os
|
||||
import time
|
||||
import errno
|
||||
import shutil
|
||||
import logging
|
||||
import tempfile
|
||||
import functools
|
||||
import contextlib
|
||||
import atexit
|
||||
|
||||
import requests
|
||||
|
||||
# Third-party dependencies
|
||||
import pymongo
|
||||
from pymongo.client_session import ClientSession
|
||||
|
||||
|
||||
class NotActiveTable(Exception):
|
||||
def __init__(self, *args, **kwargs):
|
||||
msg = "Active table is not set. (This is bug)"
|
||||
if not (args or kwargs):
|
||||
args = (default_message,)
|
||||
args = [msg]
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
|
||||
|
|
@ -120,7 +113,7 @@ class DbConnector:
|
|||
else:
|
||||
raise IOError(
|
||||
"ERROR: Couldn't connect to %s in "
|
||||
"less than %.3f ms" % (self._mongo_url, timeout)
|
||||
"less than %.3f ms" % (self._mongo_url, self.timeout)
|
||||
)
|
||||
|
||||
self.log.info("Connected to %s, delay %.3f s" % (
|
||||
|
|
|
|||
|
|
@ -1,6 +1,14 @@
|
|||
import os
|
||||
from .ftrack_base_handler import BaseHandler
|
||||
|
||||
|
||||
def statics_icon(*icon_statics_file_parts):
|
||||
statics_server = os.environ.get("PYPE_STATICS_SERVER")
|
||||
if not statics_server:
|
||||
return None
|
||||
return "/".join((statics_server, *icon_statics_file_parts))
|
||||
|
||||
|
||||
class BaseAction(BaseHandler):
|
||||
'''Custom Action base class
|
||||
|
||||
|
|
@ -177,7 +185,9 @@ class BaseAction(BaseHandler):
|
|||
else:
|
||||
for key in ('success', 'message'):
|
||||
if key not in result:
|
||||
raise KeyError('Missing required key: {0}.'.format(key))
|
||||
raise KeyError(
|
||||
"Missing required key: {0}.".format(key)
|
||||
)
|
||||
return result
|
||||
|
||||
self.log.warning((
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue