From 3f3932cff165a7b13be08f5f08de5097cd8a2d2c Mon Sep 17 00:00:00 2001 From: Toke Jepsen Date: Wed, 21 Aug 2019 14:29:25 +0100 Subject: [PATCH 01/13] Enable "Force Copy" option. In cases where hardlinking is not an option (cloud syncing), copying is the only option. --- pype/plugins/maya/create/create_look.py | 3 +++ pype/plugins/maya/publish/extract_look.py | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/pype/plugins/maya/create/create_look.py b/pype/plugins/maya/create/create_look.py index 299fbafe02..49fd376db0 100644 --- a/pype/plugins/maya/create/create_look.py +++ b/pype/plugins/maya/create/create_look.py @@ -18,3 +18,6 @@ class CreateLook(avalon.maya.Creator): # Whether to automatically convert the textures to .tx upon publish. self.data["maketx"] = True + + # Enable users to force a copy. + self.data["forceCopy"] = False diff --git a/pype/plugins/maya/publish/extract_look.py b/pype/plugins/maya/publish/extract_look.py index f883f98412..c6ddd135d7 100644 --- a/pype/plugins/maya/publish/extract_look.py +++ b/pype/plugins/maya/publish/extract_look.py @@ -203,6 +203,11 @@ class ExtractLook(pype.api.Extractor): destination = self.resource_destination( instance, source, do_maketx ) + + # Force copy is specified. + if instance.data.get("forceCopy", False): + mode = COPY + if mode == COPY: transfers.append((source, destination)) elif mode == HARDLINK: From 049e9ba7169651dd2778933cf0dbfd06280b0735 Mon Sep 17 00:00:00 2001 From: Toke Jepsen Date: Wed, 21 Aug 2019 16:43:54 +0100 Subject: [PATCH 02/13] Validate knobs to studio presets. --- .../nuke/publish/validate_write_knobs.py | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 pype/plugins/nuke/publish/validate_write_knobs.py diff --git a/pype/plugins/nuke/publish/validate_write_knobs.py b/pype/plugins/nuke/publish/validate_write_knobs.py new file mode 100644 index 0000000000..a7a96002ca --- /dev/null +++ b/pype/plugins/nuke/publish/validate_write_knobs.py @@ -0,0 +1,88 @@ +import nuke + +import pyblish.api +import pype.api + + +class ValidateNukeWriteKnobs(pyblish.api.ContextPlugin): + """Ensure knobs are consistent. + + Knobs to validate and their values comes from the + "nuke/knobs.json" preset, which needs this structure: + { + "family": { + "knob_name": knob_value + } + } + """ + + order = pyblish.api.ValidatorOrder + label = "Knobs" + hosts = ["nuke"] + actions = [pype.api.RepairContextAction] + optional = True + + def process(self, context): + # Check for preset existence. + if not context.data["presets"]["nuke"].get("knobs"): + return + + invalid = self.get_invalid(context, compute=True) + if invalid: + raise RuntimeError( + "Found knobs with invalid values: {}".format(invalid) + ) + + @classmethod + def get_invalid(cls, context, compute=False): + invalid = context.data.get("invalid_knobs", []) + if compute: + invalid = cls.get_invalid_knobs(context) + + return invalid + + @classmethod + def get_invalid_knobs(cls, context): + presets = context.data["presets"]["nuke"]["knobs"] + invalid_knobs = [] + for instance in context: + # Filter publisable instances. + if not instance.data["publish"]: + continue + + # Filter families. + families = [instance.data["family"]] + families += instance.data.get("families", []) + families = list(set(families) & set(presets.keys())) + if not families: + continue + + # Get all knobs to validate. + knobs = {} + for family in families: + for preset in presets[family]: + knobs.update({preset: presets[family][preset]}) + + # Get invalid knobs. + nodes = nuke.allNodes() + for node in nodes: + for knob in node.knobs(): + if knob in knobs.keys(): + expected = knobs[knob] + if node[knob].value() != expected: + invalid_knobs.append( + { + "knob": node[knob], + "expected": expected, + "current": node[knob].value() + } + ) + + context.data["invalid_knobs"] = invalid_knobs + return invalid_knobs + + @classmethod + def repair(cls, instance): + invalid = cls.get_invalid(instance) + for data in invalid: + data["knob"].setValue(data["expected"]) From 5dcffac49145c3ca578007b4217818a0631d0926 Mon Sep 17 00:00:00 2001 From: Toke Jepsen Date: Sun, 3 Nov 2019 18:43:22 +0000 Subject: [PATCH 03/13] Validate knobs inside write group. --- pype/plugins/nuke/publish/validate_write_knobs.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pype/plugins/nuke/publish/validate_write_knobs.py b/pype/plugins/nuke/publish/validate_write_knobs.py index a7a96002ca..eb9342abcc 100644 --- a/pype/plugins/nuke/publish/validate_write_knobs.py +++ b/pype/plugins/nuke/publish/validate_write_knobs.py @@ -64,7 +64,16 @@ class ValidateNukeWriteKnobs(pyblish.api.ContextPlugin): knobs.update({preset: presets[family][preset]}) # Get invalid knobs. - nodes = nuke.allNodes() + nodes = [] + + for node in nuke.allNodes(): + nodes.append(node) + if node.Class() == "Group": + node.begin() + for i in nuke.allNodes(): + nodes.append(i) + node.end() + for node in nodes: for knob in node.knobs(): if knob in knobs.keys(): From 73886c5079ce3b9df6d77ad5bc3abd0938fd8c8c Mon Sep 17 00:00:00 2001 From: Toke Jepsen Date: Sun, 3 Nov 2019 18:43:57 +0000 Subject: [PATCH 04/13] Bugfix for string based knobs. --- pype/plugins/nuke/publish/validate_write_knobs.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pype/plugins/nuke/publish/validate_write_knobs.py b/pype/plugins/nuke/publish/validate_write_knobs.py index eb9342abcc..072ffd4b17 100644 --- a/pype/plugins/nuke/publish/validate_write_knobs.py +++ b/pype/plugins/nuke/publish/validate_write_knobs.py @@ -94,4 +94,8 @@ class ValidateNukeWriteKnobs(pyblish.api.ContextPlugin): def repair(cls, instance): invalid = cls.get_invalid(instance) for data in invalid: + if isinstance(data["expected"], unicode): + data["knob"].setValue(str(data["expected"])) + continue + data["knob"].setValue(data["expected"]) From 67e90896383a16396c8ec9054dccc208031d129a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 15 Nov 2019 14:19:00 +0100 Subject: [PATCH 05/13] added while loop so more than one status may be tried and rollback is called on session if change failed --- pype/ftrack/lib/ftrack_app_handler.py | 35 +++++++++++++++++++++------ 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/pype/ftrack/lib/ftrack_app_handler.py b/pype/ftrack/lib/ftrack_app_handler.py index dbb38a3247..9dc735987d 100644 --- a/pype/ftrack/lib/ftrack_app_handler.py +++ b/pype/ftrack/lib/ftrack_app_handler.py @@ -345,25 +345,44 @@ class AppAction(BaseHandler): statuses = presets['status_update'] actual_status = entity['status']['name'].lower() - next_status_name = None - for key, value in statuses.items(): - if actual_status in value or '_any_' in value: - if key != '_ignore_': - next_status_name = key + already_tested = [] + ent_path = "/".join( + [ent["name"] for ent in entity['link']] + ) + while True: + next_status_name = None + for key, value in statuses.items(): + if key in already_tested: + continue + if actual_status in value or '_any_' in value: + if key != '_ignore_': + next_status_name = key + already_tested.append(key) + break + already_tested.append(key) + + if next_status_name is None: break - if next_status_name is not None: try: query = 'Status where name is "{}"'.format( next_status_name ) status = session.query(query).one() + entity['status'] = status session.commit() + self.log.debug("Changing status to \"{}\" <{}>".format( + next_status_name, ent_path + )) + break + except Exception: + session.rollback() msg = ( - 'Status "{}" in presets wasn\'t found on Ftrack' - ).format(next_status_name) + 'Status "{}" in presets wasn\'t found' + ' on Ftrack entity type "{}"' + ).format(next_status_name, entity.entity_type) self.log.warning(msg) # Set origin avalon environments From e66a3e1b382715b976e51b7260390dd44b938615 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 15 Nov 2019 14:25:13 +0100 Subject: [PATCH 06/13] added more necessary rollbacks --- pype/ftrack/events/event_thumbnail_updates.py | 5 ++++- pype/ftrack/events/event_version_to_task_statuses.py | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pype/ftrack/events/event_thumbnail_updates.py b/pype/ftrack/events/event_thumbnail_updates.py index a74aad6bd9..15aa57152d 100644 --- a/pype/ftrack/events/event_thumbnail_updates.py +++ b/pype/ftrack/events/event_thumbnail_updates.py @@ -49,7 +49,10 @@ class ThumbnailEvents(BaseEvent): self.log.info(msg) - session.commit() + try: + session.commit() + except Exception: + session.rollback() def register(session, plugins_presets): diff --git a/pype/ftrack/events/event_version_to_task_statuses.py b/pype/ftrack/events/event_version_to_task_statuses.py index 66a55c0cf7..d3e90d22de 100644 --- a/pype/ftrack/events/event_version_to_task_statuses.py +++ b/pype/ftrack/events/event_version_to_task_statuses.py @@ -64,6 +64,7 @@ class VersionToTaskStatus(BaseEvent): except Exception as e: self.log.warning('!!! [ {} ] status couldnt be set:\ [ {} ]'.format(path, e)) + session.rollback() else: self.log.info('>>> [ {} ] updated to [ {} ]'.format( path, task_status['name'])) From 38198124e4b54ca574bcd9e6edc9650891073cf9 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 15 Nov 2019 14:36:37 +0100 Subject: [PATCH 07/13] removed unnecesary commit --- pype/ftrack/events/event_version_to_task_statuses.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pype/ftrack/events/event_version_to_task_statuses.py b/pype/ftrack/events/event_version_to_task_statuses.py index d3e90d22de..a31342250f 100644 --- a/pype/ftrack/events/event_version_to_task_statuses.py +++ b/pype/ftrack/events/event_version_to_task_statuses.py @@ -6,7 +6,6 @@ class VersionToTaskStatus(BaseEvent): def launch(self, session, event): '''Propagates status from version to task when changed''' - session.commit() # start of event procedure ---------------------------------- for entity in event['data'].get('entities', []): From 246072f39ff8f78b7fe5f5f4f0160de847a2b651 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 15 Nov 2019 16:28:57 +0100 Subject: [PATCH 08/13] use logging traceback print instead of traceback module --- pype/ftrack/ftrack_server/sub_event_processor.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pype/ftrack/ftrack_server/sub_event_processor.py b/pype/ftrack/ftrack_server/sub_event_processor.py index 01fa64fdd0..6ada787223 100644 --- a/pype/ftrack/ftrack_server/sub_event_processor.py +++ b/pype/ftrack/ftrack_server/sub_event_processor.py @@ -30,8 +30,7 @@ def main(args): server.run_server(session) except Exception as exc: - import traceback - traceback.print_tb(exc.__traceback__) + log.error("Event server crashed. See traceback below", exc_info=True) finally: log.debug("First closing socket") From 562c5a8e69f5174187f37beb56770da87e645fb8 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 15 Nov 2019 16:30:42 +0100 Subject: [PATCH 09/13] added trigger event method to base handler --- pype/ftrack/lib/ftrack_base_handler.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/pype/ftrack/lib/ftrack_base_handler.py b/pype/ftrack/lib/ftrack_base_handler.py index 13e1cae9a9..95894ef782 100644 --- a/pype/ftrack/lib/ftrack_base_handler.py +++ b/pype/ftrack/lib/ftrack_base_handler.py @@ -593,3 +593,24 @@ class BaseHandler(object): self.log.debug( "Action \"{}\" Triggered successfully".format(action_name) ) + + def trigger_event( + self, topic, event_data={}, session=None, source=None, + event=None, on_error="ignore" + ): + if session is None: + session = self.session + + if not source and event: + source = event.get("source") + # Create and trigger event + event = fa_session.ftrack_api.event.base.Event( + topic=topic, + data=event_data, + source=source + ) + session.event_hub.publish(event, on_error=on_error) + + self.log.debug(( + "Publishing event: {}" + ).format(str(event.__dict__))) From 6acbd7c799a3da58e612a9085f7e1e3428bf563d Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 19 Nov 2019 18:09:46 +0100 Subject: [PATCH 10/13] first version of seed action for project entities seeding --- pype/ftrack/actions/action_seed.py | 307 ++++++++++++++++++++++++ res/ftrack/action_icons/SeedProject.svg | 89 +++++++ 2 files changed, 396 insertions(+) create mode 100644 pype/ftrack/actions/action_seed.py create mode 100644 res/ftrack/action_icons/SeedProject.svg diff --git a/pype/ftrack/actions/action_seed.py b/pype/ftrack/actions/action_seed.py new file mode 100644 index 0000000000..f69e2b1514 --- /dev/null +++ b/pype/ftrack/actions/action_seed.py @@ -0,0 +1,307 @@ +from operator import itemgetter +from pype.ftrack import BaseAction + + +class SeedDebugProject(BaseAction): + '''Edit meta data action.''' + + #: Action identifier. + identifier = "seed.debug.project" + #: Action label. + label = "SeedDebugProject" + #: Action description. + description = "Description" + #: priority + priority = 100 + #: roles that are allowed to register this action + role_list = ["Pypeclub"] + # icon = "{}/ftrack/action_icons/TestAction.svg".format( + # os.environ.get("PYPE_STATICS_SERVER", "") + # ) + + # Asset names which will be created in `Assets` entity + assets = [ + "Addax", "Alpaca", "Ant", "Antelope", "Aye", "Badger", "Bear", "Bee", + "Beetle", "Bluebird", "Bongo", "Bontebok", "Butterflie", "Caiman", + "Capuchin", "Capybara", "Cat", "Caterpillar", "Coyote", "Crocodile", + "Cuckoo", "Deer", "Dragonfly", "Duck", "Eagle", "Egret", "Elephant", + "Falcon", "Fossa", "Fox", "Gazelle", "Gecko", "Gerbil", + "GiantArmadillo", "Gibbon", "Giraffe", "Goose", "Gorilla", + "Grasshoper", "Hare", "Hawk", "Hedgehog", "Heron", "Hog", + "Hummingbird", "Hyena", "Chameleon", "Cheetah", "Iguana", "Jackal", + "Jaguar", "Kingfisher", "Kinglet", "Kite", "Komodo", "Lemur", + "Leopard", "Lion", "Lizard", "Macaw", "Malachite", "Mandrill", + "Mantis", "Marmoset", "Meadowlark", "Meerkat", "Mockingbird", + "Mongoose", "Monkey", "Nyal", "Ocelot", "Okapi", "Oribi", "Oriole", + "Otter", "Owl", "Panda", "Parrot", "Pelican", "Pig", "Porcupine", + "Reedbuck", "Rhinocero", "Sandpiper", "Servil", "Skink", "Sloth", + "Snake", "Spider", "Squirrel", "Sunbird", "Swallow", "Swift", "Tiger", + "Sylph", "Tanager", "Vulture", "Warthog", "Waterbuck", "Woodpecker", + "Zebra" + ] + + # Tasks which will be created for Assets + asset_tasks = [ + "Modeling", "Lookdev", "Rigging" + ] + # Tasks which will be created for Shots + shot_tasks = [ + "Animation", "Lighting", "Compositing", "FX" + ] + + # Define how much assets will be created(each will be created once if None) + # - you can enter more or less then assets mentioned in assets + asset_count = None + # Define how much sequences will be created + seq_count = 5 + # Define how much shots will be created for each sequence + shots_count = 10 + + existing_projects = None + new_project_item = "< New Project >" + + def discover(self, session, entities, event): + ''' Validation ''' + return True + + def interface(self, session, entities, event): + if event["data"].get("values", {}): + return + + title = "Select Project where you want to create seed data" + + items = [] + item_splitter = {"type": "label", "value": "---"} + + description_label = { + "type": "label", + "value": ( + "WARNING: Action does NOT check if entities already exist !!!" + ) + } + items.append(description_label) + + all_projects = session.query("select full_name from Project").all() + self.existing_projects = [proj["full_name"] for proj in all_projects] + projects_items = [ + {"label": proj, "value": proj} for proj in self.existing_projects + ] + + data_items = [] + + data_items.append({ + "label": self.new_project_item, + "value": self.new_project_item + }) + data_items.extend(sorted( + projects_items, + key=itemgetter("label"), + reverse=False + )) + projects_item = { + "label": "Choose Project", + "type": "enumerator", + "name": "project_name", + "data": data_items, + "value": self.new_project_item + } + items.append(projects_item) + items.append(item_splitter) + + note_label = { + "type": "label", + "value": ( + "

NOTE: Enter project name and choose schema if you " + "chose `\"< New Project >\"`(code is optional)

" + ) + } + items.append(note_label) + items.append({ + "label": "Project name", + "name": "new_project_name", + "type": "text", + "value": "" + }) + + project_schemas = [ + sch["name"] for sch in self.session.query("ProjectSchema").all() + ] + schemas_item = { + "label": "Choose Schema", + "type": "enumerator", + "name": "new_schema_name", + "data": [ + {"label": sch, "value": sch} for sch in project_schemas + ], + "value": project_schemas[0] + } + items.append(schemas_item) + + items.append({ + "label": "*Project code", + "name": "new_project_code", + "type": "text", + "value": "", + "empty_text": "Optional..." + }) + + return { + "items": items, + "title": title + } + + def launch(self, session, in_entities, event): + if "values" not in event["data"]: + return + + # THIS IS THE PROJECT PART + values = event["data"]["values"] + selected_project = values["project_name"] + if selected_project == self.new_project_item: + project_name = values["new_project_name"] + if project_name in self.existing_projects: + msg = "Project \"{}\" already exist".format(project_name) + self.log.error(msg) + return {"success": False, "message": msg} + + project_code = values["new_project_code"] + project_schema_name = values["new_schema_name"] + if not project_code: + project_code = project_name + project_code = project_code.lower().replace(" ", "_").strip() + _project = session.query( + "Project where name is \"{}\"".format(project_code) + ).first() + if _project: + msg = "Project with code \"{}\" already exist".format( + project_code + ) + self.log.error(msg) + return {"success": False, "message": msg} + + project_schema = session.query( + "ProjectSchema where name is \"{}\"".format( + project_schema_name + ) + ).one() + # Create the project with the chosen schema. + self.log.debug(( + "*** Creating Project: name <{}>, code <{}>, schema <{}>" + ).format(project_name, project_code, project_schema_name)) + project = session.create("Project", { + "name": project_code, + "full_name": project_name, + "project_schema": project_schema + }) + session.commit() + + else: + project = session.query("Project where full_name is \"{}\"".format( + selected_project + )).one() + project_schema = project["project_schema"] + self.log.debug(( + "*** Using Project: name <{}>, code <{}>, schema <{}>" + ).format( + project["full_name"], project["name"], project_schema["name"] + )) + + # THIS IS THE MAGIC PART + task_types = {} + for _type in project_schema["_task_type_schema"]["types"]: + if _type["name"] not in task_types: + task_types[_type["name"]] = _type + self.task_types = task_types + + self.create_assets(project) + self.create_shots(project) + + return True + + def create_assets(self, project): + self.log.debug("*** Creating assets:") + + asset_count = self.asset_count + if asset_count is None: + asset_count = len(self.assets) + + main_entity = self.session.create("Folder", { + "name": "Assets", + "parent": project + }) + self.log.debug("- Assets") + available_assets = len(self.assets) + repetitive_times = ( + int(asset_count / available_assets) + + (asset_count % available_assets > 0) + ) + created_assets = 0 + for _asset_name in self.assets: + if created_assets >= asset_count: + break + for asset_num in range(1, repetitive_times + 1): + if created_assets >= asset_count: + break + asset_name = "%s_%02d" % (_asset_name, asset_num) + asset = self.session.create("AssetBuild", { + "name": asset_name, + "parent": main_entity + }) + created_assets += 1 + self.log.debug("- Assets/{}".format(asset_name)) + + for task_name in self.asset_tasks: + self.session.create("Task", { + "name": task_name, + "parent": asset, + "type": self.task_types[task_name] + }) + self.log.debug("- Assets/{}/{}".format( + asset_name, task_name + )) + + self.log.debug("*** Commiting Assets") + self.session.commit() + + def create_shots(self, project): + self.log.debug("*** Creating shots:") + main_entity = self.session.create("Folder", { + "name": "Shots", + "parent": project + }) + self.log.debug("- Shots") + + for seq_num in range(1, self.seq_count+1): + seq_name = "sq%03d" % seq_num + seq = self.session.create("Sequence", { + "name": seq_name, + "parent": main_entity + }) + self.log.debug("- Shots/{}".format(seq_name)) + + for shot_num in range(1, self.shots_count+1): + shot_name = "%ssh%04d" % (seq_name, (shot_num*10)) + shot = self.session.create("Shot", { + "name": shot_name, + "parent": seq + }) + self.log.debug("- Shots/{}/{}".format(seq_name, shot_name)) + + for task_name in self.shot_tasks: + self.session.create("Task", { + "name": task_name, + "parent": shot, + "type": self.task_types[task_name] + }) + self.log.debug("- Shots/{}/{}/{}".format( + seq_name, shot_name, task_name + )) + + self.log.debug("*** Commiting Shots") + self.session.commit() + + +def register(session, plugins_presets={}): + '''Register plugin. Called when used as an plugin.''' + + SeedDebugProject(session, plugins_presets).register() diff --git a/res/ftrack/action_icons/SeedProject.svg b/res/ftrack/action_icons/SeedProject.svg new file mode 100644 index 0000000000..19ab22e411 --- /dev/null +++ b/res/ftrack/action_icons/SeedProject.svg @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + From 9e74d086709c7bc7513a6ef1782f03cc2f274391 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 19 Nov 2019 18:14:19 +0100 Subject: [PATCH 11/13] added icon --- pype/ftrack/actions/action_seed.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pype/ftrack/actions/action_seed.py b/pype/ftrack/actions/action_seed.py index f69e2b1514..fd23b399dc 100644 --- a/pype/ftrack/actions/action_seed.py +++ b/pype/ftrack/actions/action_seed.py @@ -1,3 +1,4 @@ +import os from operator import itemgetter from pype.ftrack import BaseAction @@ -15,9 +16,9 @@ class SeedDebugProject(BaseAction): priority = 100 #: 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 = "{}/ftrack/action_icons/SeedProject.svg".format( + os.environ.get("PYPE_STATICS_SERVER", "") + ) # Asset names which will be created in `Assets` entity assets = [ From 81dbc9a17ebb23c7059c267dd06138a6be91eb65 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 19 Nov 2019 18:33:38 +0100 Subject: [PATCH 12/13] user can change number of created instances --- pype/ftrack/actions/action_seed.py | 47 ++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/pype/ftrack/actions/action_seed.py b/pype/ftrack/actions/action_seed.py index fd23b399dc..e4b47c4e6a 100644 --- a/pype/ftrack/actions/action_seed.py +++ b/pype/ftrack/actions/action_seed.py @@ -50,13 +50,10 @@ class SeedDebugProject(BaseAction): "Animation", "Lighting", "Compositing", "FX" ] - # Define how much assets will be created(each will be created once if None) - # - you can enter more or less then assets mentioned in assets - asset_count = None # Define how much sequences will be created - seq_count = 5 + default_seq_count = 5 # Define how much shots will be created for each sequence - shots_count = 10 + default_shots_count = 10 existing_projects = None new_project_item = "< New Project >" @@ -109,6 +106,26 @@ class SeedDebugProject(BaseAction): items.append(projects_item) items.append(item_splitter) + items.append({ + "label": "Number of assets", + "type": "number", + "name": "asset_count", + "value": len(self.assets) + }) + items.append({ + "label": "Number of sequences", + "type": "number", + "name": "seq_count", + "value": self.default_seq_count + }) + items.append({ + "label": "Number of shots", + "type": "number", + "name": "shots_count", + "value": self.default_shots_count + }) + items.append(item_splitter) + note_label = { "type": "label", "value": ( @@ -214,18 +231,18 @@ class SeedDebugProject(BaseAction): task_types[_type["name"]] = _type self.task_types = task_types - self.create_assets(project) - self.create_shots(project) + asset_count = values.get("asset_count") or len(self.assets) + seq_count = values.get("seq_count") or self.default_seq_count + shots_count = values.get("shots_count") or self.default_shots_count + + self.create_assets(project, asset_count) + self.create_shots(project, seq_count, shots_count) return True - def create_assets(self, project): + def create_assets(self, project, asset_count): self.log.debug("*** Creating assets:") - asset_count = self.asset_count - if asset_count is None: - asset_count = len(self.assets) - main_entity = self.session.create("Folder", { "name": "Assets", "parent": project @@ -264,7 +281,7 @@ class SeedDebugProject(BaseAction): self.log.debug("*** Commiting Assets") self.session.commit() - def create_shots(self, project): + def create_shots(self, project, seq_count, shots_count): self.log.debug("*** Creating shots:") main_entity = self.session.create("Folder", { "name": "Shots", @@ -272,7 +289,7 @@ class SeedDebugProject(BaseAction): }) self.log.debug("- Shots") - for seq_num in range(1, self.seq_count+1): + for seq_num in range(1, seq_count+1): seq_name = "sq%03d" % seq_num seq = self.session.create("Sequence", { "name": seq_name, @@ -280,7 +297,7 @@ class SeedDebugProject(BaseAction): }) self.log.debug("- Shots/{}".format(seq_name)) - for shot_num in range(1, self.shots_count+1): + for shot_num in range(1, shots_count+1): shot_name = "%ssh%04d" % (seq_name, (shot_num*10)) shot = self.session.create("Shot", { "name": shot_name, From 413dfc6a03e815573ff87277d6e35e967bdfde1f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 19 Nov 2019 18:33:51 +0100 Subject: [PATCH 13/13] added current project to project list --- pype/ftrack/actions/action_seed.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/pype/ftrack/actions/action_seed.py b/pype/ftrack/actions/action_seed.py index e4b47c4e6a..cf0a4b0445 100644 --- a/pype/ftrack/actions/action_seed.py +++ b/pype/ftrack/actions/action_seed.py @@ -57,6 +57,7 @@ class SeedDebugProject(BaseAction): existing_projects = None new_project_item = "< New Project >" + current_project_item = "< Current Project >" def discover(self, session, entities, event): ''' Validation ''' @@ -91,6 +92,12 @@ class SeedDebugProject(BaseAction): "label": self.new_project_item, "value": self.new_project_item }) + + data_items.append({ + "label": self.current_project_item, + "value": self.current_project_item + }) + data_items.extend(sorted( projects_items, key=itemgetter("label"), @@ -101,7 +108,7 @@ class SeedDebugProject(BaseAction): "type": "enumerator", "name": "project_name", "data": data_items, - "value": self.new_project_item + "value": self.current_project_item } items.append(projects_item) items.append(item_splitter) @@ -213,6 +220,21 @@ class SeedDebugProject(BaseAction): }) session.commit() + elif selected_project == self.current_project_item: + entity = in_entities[0] + if entity.entity_type.lower() == "project": + project = entity + else: + if "project" in entity: + project = entity["project"] + else: + project = entity["parent"]["project"] + project_schema = project["project_schema"] + self.log.debug(( + "*** Using Project: name <{}>, code <{}>, schema <{}>" + ).format( + project["full_name"], project["name"], project_schema["name"] + )) else: project = session.query("Project where full_name is \"{}\"".format( selected_project