def test_no_primary(self): """ Ensures error is raised if there are no primary available. """ self.mockgun.update("PipelineConfiguration", self.pipeline_configuration.get_shotgun_id(), {"code": "Secondary"}) with self.assertRaisesRegex( TankInitError, "does not have a Primary pipeline configuration!"): sgtk.sgtk_from_path(self.project_root)
def test_no_primary(self): """ Ensures error is raised if there are no primary available. """ self.mockgun.update( "PipelineConfiguration", self.pipeline_configuration.get_shotgun_id(), {"code": "Secondary"} ) with self.assertRaisesRegex( TankInitError, "does not have a Primary pipeline configuration!" ): sgtk.sgtk_from_path(self.project_root)
def test_multiple_primaries(self): """ Ensures that a site-level primary is not considered for a shared-core for a project. """ self.mockgun.create( "PipelineConfiguration", { "code": "Primary", "mac_path": "/a/b/c", "windows_path": "C:\\b\\a", "linux_path": "/a/b/c" }) sgtk.sgtk_from_path(self.project_root) sgtk.sgtk_from_entity(self.project["type"], self.project["id"])
def test_no_path(self): """ Ensures error is raised if the primary has no path set. """ self.mockgun.update( "PipelineConfiguration", self.pipeline_configuration.get_shotgun_id(), {"windows_path": None, "linux_path": None, "mac_path": None} ) # We do not support site-wide pipeline configurations from shared cores. with self.assertRaisesRegexp( TankInitError, "cannot be instantiated because it does not have an absolute path" ): sgtk.sgtk_from_path(self.project_root)
def __init__(self, app): """ """ QtGui.QWidget.__init__(self) self.app = app # debug(self.app, method = 'MainUI.__init__', message = 'Running app...', verbose = False) self.context = self.app.context ## To get the step # debug(app = self.app, method = 'MainUI.__init__', message = 'context: %s' % self.context, verbose = False) if self.context.step['name'] == 'Blocking': self.tk = sgtk.sgtk_from_path("T:/software/bubblebathbay") ################### UI LOAD / BUILD NOW ## Now build the UI self.mainLayout = QtGui.QVBoxLayout(self) ## Setup the layout and buttons self.buttonLayout = QtGui.QHBoxLayout() self.shotBasedSBoardButton = QtGui.QPushButton('Fetch StoryBoard') self.shotBasedSBoardButton.clicked.connect(self._singleShotSBoard) ## Add the buttons to their layout widget self.buttonLayout.addWidget(self.shotBasedSBoardButton) self.mainLayout.addLayout(self.buttonLayout) self.mainLayout.addStretch(1) self.resize(300, 20)
def powerwall(self, entity_type, entity_ids): # this message will be displayed to the user self.engine.log_info("Open with VARJO Script Requested") chosen_file = self.shotgun.find_one(entity_type, [["id", "is", entity_ids[0]]], ["path", "task", "entity"]) tk = sgtk.sgtk_from_path(chosen_file["path"]["local_path_windows"]) context = tk.context_from_path( chosen_file["path"]["local_path_windows"]) software_launcher = sgtk.platform.create_engine_launcher( tk, context, "tk-vred") software_versions = software_launcher.scan_software() launch_info = software_launcher.prepare_launch( software_versions[-1].path, "") env = os.environ.copy() for k in launch_info.environment: env[k] = launch_info.environment[k] subprocess.Popen([ launch_info.path, launch_info.args, chosen_file["path"]["local_path_windows"], '-postpython', 'setDisplayMode(VR_DISPLAY_VARJO)' ], env=env) self.engine.log_info("Open with VARJO Script Launched")
def augmented(self, entity_type, entity_ids): # this message will be displayed to the user self.engine.log_info("Augmented Script Requested") chosen_file = self.shotgun.find_one(entity_type, [["id", "is", entity_ids[0]]], ["path", "task", "entity"]) tk = sgtk.sgtk_from_path(chosen_file["path"]["local_path_windows"]) context = tk.context_from_path( chosen_file["path"]["local_path_windows"]) software_launcher = sgtk.platform.create_engine_launcher( tk, context, "tk-vred") software_versions = software_launcher.scan_software() launch_info = software_launcher.prepare_launch( software_versions[-1].path, "") env = os.environ.copy() for k in launch_info.environment: env[k] = launch_info.environment[k] subprocess.Popen([ launch_info.path, launch_info.args, chosen_file["path"]["local_path_windows"], '-postpython', 'load(\'//10.146.20.210/Demo/VRED/Augmented/SRG_Augmented_V9.vpb\')' ], env=env) self.engine.log_info("Augmented Script Launched")
def refresh_engine(engine_name, prev_context, menu_name): """ Refresh the current engine """ current_engine = sgtk.platform.current_engine() if not current_engine: # If we don't have an engine for some reason then we don't have # anything to do. return document = _active_document() if not document: # There is no active document so we leave the engine in it's current # state. return # determine the tk instance and ctx to use: tk = current_engine.sgtk # loading a scene file new_path = document.fileName().abspath() # this file could be in another project altogether, so create a new # API instance. try: tk = sgtk.sgtk_from_path(new_path) except sgtk.TankError, e: logging.warning("Shotgun: Engine cannot be started: %s" % e) # build disabled menu create_sgtk_disabled_menu(menu_name) return
def collaboration(self, entity_type, entity_ids): # this message will be displayed to the user self.engine.log_info("Tiguan Collab Script Requested") chosen_file = self.shotgun.find_one(entity_type, [["id", "is", entity_ids[0]]], ["path", "task", "entity"]) tk = sgtk.sgtk_from_path(chosen_file["path"]["local_path_windows"]) context = tk.context_from_path( chosen_file["path"]["local_path_windows"]) software_launcher = sgtk.platform.create_engine_launcher( tk, context, "tk-vred") software_versions = software_launcher.scan_software() launch_info = software_launcher.prepare_launch( software_versions[-1].path, "") env = os.environ.copy() for k in launch_info.environment: env[k] = launch_info.environment[k] subprocess.Popen([ launch_info.path, launch_info.args, chosen_file["path"]["local_path_windows"], '-postpython', 'load(\'//10.146.20.210/Demo/VRED/Collaboration/Collab_2019_2_VW_Tiguan_35_VARJO.vpb\')' ], env=env) filepath = 'C:/Batch/DEMO4_ps.bat' subprocess.Popen(filepath, shell=True, stdout=subprocess.PIPE) self.engine.log_info("Tiguan Collab Script Launched")
def __sgtk_on_save_callback(): """ Callback that fires every time a file is saved. Carefully manage exceptions here so that a bug in Tank never interrupts the normal workflows in Nuke. """ # get the new file name file_name = nuke.root().name() try: # this file could be in another project altogether, so create a new Tank # API instance. try: tk = sgtk.sgtk_from_path(file_name) except sgtk.TankError as e: __create_tank_disabled_menu(e) return # try to get current ctx and inherit its values if possible curr_ctx = None curr_engine = sgtk.platform.current_engine() if curr_engine: curr_ctx = curr_engine.context # and now extract a new context based on the file new_ctx = tk.context_from_path(file_name, curr_ctx) # now restart the engine with the new context __engine_refresh(new_ctx) except Exception: __create_tank_error_menu()
def publishingSubProc(winpath, vpath, vcode, eventID, linkType, linkID, taskID): # Get toolkit engine (sgtk) of the project sys.path.append('%s/install/core/python' % winpath) import sgtk sys.path.remove('%s/install/core/python' % winpath) #f, filename, desc = imp.find_module('sgtk', ['%s/install/core/python/' % winpath]) #sgtk = imp.load_module('sgtk', f, filename, desc) # Publish the version # Get toolkit tk = sgtk.sgtk_from_path(vpath) tk.synchronize_filesystem_structure() # Set context ctx = tk.context_from_entity(linkType,linkID) #print(ctx) # Construct path to facilis, this is where the renders have to be copied to and needs to be put in the publish # Get the template to the rendered frames version_path_template = tk.templates['maya_render_shot_version'] # Get field data from vpath with the use of the template fields = version_path_template.get_fields(vpath.replace("\\","/")) # Get the template location of where to copy the frames to publish_path_template = tk.templates['maya_render_shot_publish'] # Apply the field data to the "publish" template and remove the file name because we only need the destination directory for copying purposes facilis_dir_path = publish_path_template.parent.apply_fields(fields) # Apply the field data to the entire template as well, for publishing after the file copying publish_location = publish_path_template.apply_fields(fields) # Check if path to copy to exists, if not -> create it # @TODO: what if the folder exists and has files in it, overwrite? abort? if not os.path.exists(facilis_dir_path): os.makedirs(facilis_dir_path) # Start copy and rename loop for frame in glob.glob(vpath.replace("#", "?")): # First, copy the file to the new destination, this is the easy part #print(frame) #print(facilis_dir_path) shutil.copy(frame, facilis_dir_path) # Second, rename the file to fit the publish template # To do that first we get the name of the file we just copied and append it to the path we copied to. # That way we get the complete path + file name so we know what to rename and where it is located old_file = os.path.split(frame)[1] rename_from_file = os.path.join(facilis_dir_path, old_file) # Next get the fields from the version template, this is done here because only now the file has the frame number in its name # Unlike before where it was just #### fields = version_path_template.get_fields(frame) # Apply the fields to the publishing template to figure out to what to rename the file rename_to_file = publish_path_template.apply_fields(fields) # Do the actual renaming if the file names don't match if rename_from_file != rename_to_file: os.rename(rename_from_file, rename_to_file) # Register the publish published_entity = sgtk.util.register_publish(tk, ctx, publish_location, vcode, fields['version'], published_file_type='Rendered Image', version_entity={"type":"Version", "id":eventID}, task={"type":"Task", "id":taskID}) return published_entity
def run_app(self): """ Callback from when the menu is clicked. """ context = self.context ## To get the step debug(app = self, method = 'run_app', message = 'Context Step...\n%s' % context.step['name'], verbose = False) if context.step['name'] == 'Surface': ## Tell the artist to be patient... eg not genY inprogressBar = pbui.ProgressBarUI(title = 'Building Asset Shaders:') inprogressBar.show() inprogressBar.updateProgress(percent = 5, doingWhat = 'Processing scene info...') ## Instantiate the API tk = sgtk.sgtk_from_path("T:/software/bubblebathbay") debug(app = self, method = 'run_app', message = 'API instanced...\n%s' % tk, verbose = False) debug(app = self, method = 'run_app', message = 'RebuildLIBSHD launched...', verbose = False) ## Now process XML debug(app = self, method = 'processTemplates', message = 'Looking for LIB assets to rebuild now', verbose = False) shd.reconnectLIBSHD(rootGrp = 'geo_hrc', freshImport = False) inprogressBar.updateProgress(percent = 100, doingWhat = 'COMPLETE...') inprogressBar.close() inprogressBar = None else: cmds.warning('Not a valid SRF context step. Try making sure you are in a valid Surfacing step launched from shotgun.')
def start_engine(data): """ Start the tk-desktop engine given a data dictionary like the one passed to the launch_python hook. """ sys.path.append(data["core_python_path"]) # make sure we don't inherit the GUI's pipeline configuration os.environ["TANK_CURRENT_PC"] = data["config_path"] import sgtk sgtk.util.append_path_to_env_var("PYTHONPATH", data["core_python_path"]) # If the core supports the shotgun_authentication module and the pickle has # a current user, we have to set the authenticated user. if hasattr(sgtk, "set_authenticated_user"): # Retrieve the currently authenticated user for this process. from tank_vendor.shotgun_authentication import ShotgunAuthenticator user = ShotgunAuthenticator(sgtk.util.CoreDefaultsManager()).get_default_user() sgtk.set_authenticated_user(user) tk = sgtk.sgtk_from_path(data["config_path"]) tk._desktop_data = data["proxy_data"] ctx = tk.context_from_entity("Project", data["project"]["id"]) return sgtk.platform.start_engine("tk-desktop", tk, ctx)
def test_project_path_lookup_local_mode(self): """ Check that a sgtk init works for this path """ # By setting the TANK_CURRENT_PC, we emulate the behaviour # of a local API running. Push this variable old_tank_current_pc = None if "TANK_CURRENT_PC" in os.environ: old_tank_current_pc = os.environ["TANK_CURRENT_PC"] os.environ["TANK_CURRENT_PC"] = self.pipeline_config_root probe_path = {} probe_path["win32"] = "C:\\temp\\foo\\bar\\test.ma" probe_path["darwin"] = "/tmp/foo/bar/test.ma" probe_path["linux2"] = "/tmp/foo/bar/test.ma" test_path = probe_path[sgsix.platform] test_path_dir = os.path.dirname(test_path) if not os.path.exists(test_path_dir): os.makedirs(test_path_dir) self.assertIsInstance(sgtk.sgtk_from_path(test_path), Tank) # and pop the modification if old_tank_current_pc is None: del os.environ["TANK_CURRENT_PC"] else: os.environ["TANK_CURRENT_PC"] = old_tank_current_pc
def _publishAudio(self): """ Function to add the publish a maya audio file both making a maya file with an audio node and publishing this to shotgun as a version """ for key, var in self.fileBoxes.items(): if var: if key.isChecked(): ## Work out what we need for the creation of the ma file ## and the publish for shotgun self.pathToWav = var if sys.platform == 'win32': self.publishPath = var.replace('/publish/wav', '/publish/maya').replace('.wav', '.ma').replace('/', '\\') self.localPath = self.publishPath.split('I:')[-1] self.localPathMac = self.publishPath.replace('I:', '/_projects') self.fileName = str(key.text()).replace('.wav', '.ma') self.wavName = str(key.text()) self.wavSGName = str(key.text().replace('_AUD', '').split('.')[0]) self.version_number = int(str(key.text()).split('.')[-2].split('v')[-1]) ## Now register the publish with Shotgun ## First find the audio on shotgun for processing. self.exists = self.sgsrv.find_one('CustomEntity03', filters = [["code", "is", self.wavSGName]], fields=['code', 'tasks', 'id']) if not self.exists: print '%s has no shotgun entry! You should make sure this has been processed correctly before proceeding!!' % self.wavName else: ## now publish tk = sgtk.sgtk_from_path("I:/lsapipeline/") ctx = tk.context_from_path(self.publishPath) ## For existing check ## CHECK FOR EXISTING PUBLISH WITH THE SAME VERSION NUMBER!!!! findExisting = self.sgsrv.find_one('PublishedFile', filters = [["code", "is", self.wavSGName]], fields=['code', 'id', 'version_number', 'created_at', 'entity']) if findExisting: if findExisting['version_number'] == self.version_number: print 'A PUBLISHED FILE FOR THIS VERSION ALREADY EXISTS SKIPPING! VERSION UP OR DELETE EXISTING SHOTGUN PUBLISH ENTRIES IF YOU NEED TO YOU SHOULDNT BUT YOU MIGHT!' ## WRITE THE MA ## Now write the ma file we are going to publish with the audio node created. ## Note this will delete and re-make any ma files with the same name in the folder if they exist self._writeMaFile(self.fileName, self.pathToWav, self.wavName, self.publishPath) else:## This is a new version number ## WRITE THE MA ## Now write the ma file we are going to publish with the audio node created. ## Note this will delete and re-make any ma files with the same name in the folder if they exist self._writeMaFile(self.fileName, self.pathToWav, self.wavName, self.publishPath) self._createPublish(publishPath = self.publishPath, fileName = self.fileName, pathToWav = self.pathToWav, wavName = self.wavName, version_number = self.version_number, localPath = self.localPath, localPathMac = self.localPathMac, wavSGName = self.wavSGName, ctx = ctx) else:## nothing already exists so build a fresh publish ## WRITE THE MA ## Now write the ma file we are going to publish with the audio node created. ## Note this will delete and re-make any ma files with the same name in the folder if they exist self._writeMaFile(self.fileName, self.pathToWav, self.wavName, self.publishPath) self._createPublish(publishPath = self.publishPath, fileName = self.fileName, pathToWav = self.pathToWav, wavName = self.wavName, version_number = self.version_number, localPath = self.localPath, localPathMac = self.localPathMac, wavSGName = self.wavSGName, ctx = ctx) print 'Complete' self.goButton.setText('COMPLETE.. click to run again') self.goButton.setStyleSheet('QPushButton {background-color: green; border: 2px solid 1 ; border-radius: 6px;}') self.repaint()
def test_no_path(self): """ Ensures error is raised if the primary has no path set. """ self.mockgun.update( "PipelineConfiguration", self.pipeline_configuration.get_shotgun_id(), {"windows_path": None, "linux_path": None, "mac_path": None} ) # We do not support site-wide pipeline configurations from shared cores. with self.assertRaisesRegex( TankInitError, "cannot be instantiated because it is a distributed config. " "To launch this kind of configuration, use the Bootstrap API instead." ): sgtk.sgtk_from_path(self.project_root)
def get_entity_by_project_name(self, project_name): default_root_path = atk_globals.PROJECTS_DRIVE project_root_path = os.path.join(default_root_path, project_name) tk = sgtk.sgtk_from_path(project_root_path) result = tk.entity_from_path(project_root_path) return result
def _create_render_prefix(self): """ create a token to place in the renderSetup filename prefix """ path = cmds.file(query=True, sceneName=True) tk = sgtk.sgtk_from_path(path) work_template = tk.template_from_path(path) curr_fields = work_template.get_fields(path) eng = sgtk.platform.current_engine() # entity name with space-to-dash conversion entity = eng.context.entity.get('name') entity = entity.replace(" ", "-") # task name task = eng.context.task.get('name') # version number version = "v" + str(curr_fields.get('version')).zfill(3) # internal Maya key for layer name layer = "<RenderLayer>" name_token = "%s_%s_%s_%s" % (entity, task, layer, version) cmds.setAttr("defaultRenderGlobals.imageFilePrefix", "<RenderLayer>/" + name_token, type="string")
def __init__(self): self.tk = sgtk.sgtk_from_path('T:/software/lsapipeline') fields = ['image', 'code', 'id', 'description'] projectId = 113 databasePath = 'T:/software/lsapipeline/install/apps/tk-custom-workfiles/python/tk_custom_workfiles/database/' self.getAssetList(projectId, fields, databasePath) self.getShotList(projectId, fields, databasePath)
def _move_data(path): """ Rename directory to backup name, if backup currently exists replace it. """ if path and os.path.exists(path): dirname, basename = os.path.split(path) new_basename = "%s.old" % basename backup_path = os.path.join(dirname, new_basename) if os.path.exists(backup_path): shutil.rmtree(backup_path) try: os.rename(path, backup_path) except WindowsError: # On windows intermittent problems with sqlite db file occur tk = sgtk.sgtk_from_path(path) pc = path_cache.PathCache(tk) db_path = pc._get_path_cache_location() if os.path.exists(db_path): print 'Removing db %s' % db_path # Importing pdb allows the deletion of the sqlite db sometimes... import pdb # try multiple times, waiting longer in between for count in range(5): try: os.remove(db_path) break except WindowsError: time.sleep(count*2) os.rename(path, backup_path)
def get_tk_from_project_id(self, project_id): """ Get the tank instance given the project ID. This is useful when you have to deal with files from library project :param project_id: Id of the project you want to get the tank instance for :return: An instance of :class`sgtk.Sgtk` """ # first of all, we need to determine if the file we're trying to import lives in the current project or in # another one in_current_project = project_id == self.context.project["id"] if in_current_project: return self.sgtk # if the file we're trying to import lives in another project, we need to access the configuration used by this # project in order to get the right configuration settings else: pc_local_path = self.__get_pipeline_configuration_local_path( project_id) if not pc_local_path: self.logger.warning( "Couldn't get tank instance for project {}.".format( project_id)) return None return sgtk.sgtk_from_path(pc_local_path)
def test_multiple_primaries(self): """ Ensures that a site-level primary is not considered for a shared-core for a project. """ self.mockgun.create( "PipelineConfiguration", { "code": "Primary", "mac_path": "/a/b/c", "windows_path": "C:\\b\\a", "linux_path": "/a/b/c" } ) sgtk.sgtk_from_path(self.project_root) sgtk.sgtk_from_entity(self.project["type"], self.project["id"])
def _move_data(path): """ Rename directory to backup name, if backup currently exists replace it. """ if path and os.path.exists(path): dirname, basename = os.path.split(path) new_basename = "%s.old" % basename backup_path = os.path.join(dirname, new_basename) if os.path.exists(backup_path): shutil.rmtree(backup_path) try: os.rename(path, backup_path) except WindowsError: # On windows intermittent problems with sqlite db file occur tk = sgtk.sgtk_from_path(path) pc = path_cache.PathCache(tk) db_path = pc._get_path_cache_location() if os.path.exists(db_path): print('Removing db %s' % db_path) # Importing pdb allows the deletion of the sqlite db sometimes... import pdb # noqa # try multiple times, waiting longer in between for count in range(5): try: os.remove(db_path) break except WindowsError: time.sleep(count * 2) os.rename(path, backup_path)
def test_project_path_lookup_local_mode(self): """ Check that a sgtk init works for this path """ # By setting the TANK_CURRENT_PC, we emulate the behaviour # of a local API running. Push this variable old_tank_current_pc = None if "TANK_CURRENT_PC" in os.environ: old_tank_current_pc = os.environ["TANK_CURRENT_PC"] os.environ["TANK_CURRENT_PC"] = self.pipeline_config_root probe_path = {} probe_path["win32"] = "C:\\temp\\foo\\bar\\test.ma" probe_path["darwin"] = "/tmp/foo/bar/test.ma" probe_path["linux2"] = "/tmp/foo/bar/test.ma" test_path = probe_path[sys.platform] test_path_dir = os.path.dirname(test_path) if not os.path.exists(test_path_dir): os.makedirs(test_path_dir) self.assertIsInstance(sgtk.sgtk_from_path(test_path), Tank) # and pop the modification if old_tank_current_pc is None: del os.environ["TANK_CURRENT_PC"] else: os.environ["TANK_CURRENT_PC"] = old_tank_current_pc
def getTank(): if _platform == "win32": ProjectPath= "W:\WG\Shotgun_Configs\RTS_Master" elif _platform == "linux" or _platform == "linux2": ProjectPath="/srv/projects/rts/WG/Shotgun_Configs/RTS_Master" else: ProjectPath= "W:/WG/Shotgun_Configs/RTS_Master" return sgtk.sgtk_from_path(ProjectPath)
def _get_shotgun_fields_from_file_name_(): import sgtk libUtilities.pyLog.info('Getting info from Shotgun') path = pm.sceneName() tk = sgtk.sgtk_from_path(path) template_obj = tk.template_from_path(path) fields = template_obj.get_fields(path) return template_obj, fields, tk
def test_no_path(self): """ Ensures error is raised if the primary has no path set. """ self.mockgun.update("PipelineConfiguration", self.pipeline_configuration.get_shotgun_id(), { "windows_path": None, "linux_path": None, "mac_path": None }) # We do not support site-wide pipeline configurations from shared cores. with self.assertRaisesRegex( TankInitError, "cannot be instantiated because it is a distributed config. " "To launch this kind of configuration, use the Bootstrap API instead." ): sgtk.sgtk_from_path(self.project_root)
def run_app(self): """ Callback from when the menu is clicked. """ ## Tell the artist to be patient... eg not genY cmds.headsUpMessage("Building shotCam...", time = 1) inprogressBar = pbui.ProgressBarUI(title = 'Building Shotcam:') inprogressBar.show() ## Instantiate the API tk = sgtk.sgtk_from_path("T:/software/bubblebathbay") debug(app = self, method = 'run_app', message = 'API instanced...\n%s' % tk, verbose = False) debug(app = self, method = 'run_app', message = 'Fetch Shot Assets launched...', verbose = False) context = self.context ## To get the step debug(app = self, method = 'run_app', message = 'Context Step...\n%s' % context.step['name'], verbose = False) if context.step['name'] == 'Anm' or context.step['name'] == 'Blocking': inprogressBar.updateProgress(percent = 10, doingWhat = 'processing scene info...') cmds.cycleCheck(e = 1) ## Build an entity type to get some values from. entity = self.context.entity ## returns {'type': 'Shot', 'name': 'ep100_sh010', 'id': 1166} debug(app = self, method = 'run_app', message = 'entity... %s' % entity, verbose = False) ## Set the template to the maya publish folder shot_root_template = tk.templates[self.get_setting('shot_root_template')] debug(app = self, method = 'run_app', message = 'shot_root_template...\n%s' % shot_root_template, verbose = False) ## Now build the camera shotName = entity['name'] cameraName = '%s_shotCam' % shotName if self.doesAssetAlreadyExistInScene(cameraName): inprogressBar.updateProgress(percent = 100, doingWhat = 'Camera found...') inprogressBar.close() cmds.warning("Scene currently has a valid shotCamera in it! Aborting ...") QtGui.QMessageBox.information(None, "Scene currently has a valid shotCamera in it! Aborting ...") raise tank.TankError("Scene currently has a valid shotCamera in it! Aborting ...") else: inprogressBar.updateProgress(percent = 50, doingWhat = 'Building camera...') cmds.camera() cmds.rename('camera1', cameraName) self.tagShotCam(cameraName) ## Now set the default camera stuff up settings._setCameraDefaults(cameraName) settings._createCamGate(cameraName) ## Now set the renderGlobals up width = self.get_setting('movie_width') height = self.get_setting('movie_height') inprogressBar.updateProgress(percent = 90, doingWhat = 'Setting render globals...') settings._setRenderGlobals(width = width, height = height, animation = True) inprogressBar.updateProgress(percent = 100, doingWhat = 'Finished...') inprogressBar.close() cmds.headsUpMessage("shotCam built successfully...", time = 1) else: cmds.headsUpMessage("Current context is not a valid Shot context. Please make sure you are under a valid shotgun Shot context!", time = 2) cmds.warning("Current context is not a valid Shot context. Please make sure you are under a valid shotgun Shot context!") QtGui.QMessageBox.information(None, "Current context is not a valid Shot context. Please make sure you are under a valid shotgun Shot context!") raise tank.TankError("Current context is not a valid Shot context. Please make sure you are under a valid shotgun Shot context!")
def main(): """ Do stuff """ global logger # Initialize logging log_handler = init_logging() # Initialize user credentials init_user_credentials() # Create an API instance tk = sgtk.sgtk_from_path( sgtk.pipelineconfig_utils.get_config_install_location()) # attach our logger to the tank instance # this will be detected by the shotgun and shell engines and used. tk.log = logger # If we're opening a new file, get context from cwd ctx = tk.context_from_path(os.getcwd()) # Cannot launch engine if running in site mode if tk.pipeline_configuration.is_site_configuration(): logger.info( "Running using site configuration. Skipping filesystem update.") else: if tk.pipeline_configuration.get_shotgun_path_cache_enabled(): tk.synchronize_filesystem_structure() # Get the appropriate entity ctx_entity = ctx.task or ctx.entity or ctx.project # Run filesystem creation if ctx_entity: tk.create_filesystem_structure(ctx_entity.get("type"), ctx_entity.get("id"), app_name) try: engine = sgtk.platform.start_engine("tk-shell", tk, ctx) except Exception as e: logger.error("Could not start engine: %s" % str(e)) if os.environ.get("DD_DEBUG"): import pdb pdb.post_mortem() raise try: return engine.execute_command("Publish...", []) except Exception as e: logger.error("Could not start app: %s" % str(e)) if os.environ.get("DD_DEBUG"): import pdb pdb.post_mortem() raise
def __init__(self, projectPath = None, sgtk = None): if sgtk != None: self.tk = sgtk return if projectPath != None: self.projectPath = projectPath self.tk = sgtk.sgtk_from_path(self.projectPath) print 'Initialize Done.'
def sgwi(): """ Shotgun with authentification""" import sgtk from tank_vendor.shotgun_authentication import ShotgunAuthenticator cdm = sgtk.util.CoreDefaultsManager() authenticator = ShotgunAuthenticator(cdm) user = authenticator.create_script_user(api_script="Toolkit",api_key="cdeb3545052b2afeec449c43deda7c857558a067658b52033ce489d0789d6aff") sgtk.set_authenticated_user(user) return sgtk.sgtk_from_path(cf.get_primary_data_root())
def getDataFolder(): targetPath = getFileName() tk = sgtk.sgtk_from_path(targetPath) print targetPath splitPath = targetPath.split("/") print splitPath name = getAssetName() target = "%s/%s/%s/%s/%s/data/" %(splitPath[0],splitPath[1],splitPath[2],splitPath[3],name) return target
def test_09_cache_yaml(self): """ Runs tank cache_yaml on the project. """ # Strip the test folder, as it contains yaml files which the cache_yaml # command will try to cache. The problem with those files is that some # of them are purposefully corrupted so they will crash the caching. shutil.rmtree( os.path.join(self.pipeline_location, "install", "core", "tests")) self.run_tank_cmd(self.pipeline_location, "cache_yaml") yaml_cache.g_yaml_cache = yaml_cache.YamlCache() self.assertEqual(yaml_cache.g_yaml_cache.get_cached_items(), []) # This should trigger a load of the cache. sgtk.sgtk_from_path(self.pipeline_location) self.assertNotEqual(yaml_cache.g_yaml_cache.get_cached_items(), []) # Extract all the file names from the cache, but strip the pipeline location from the paths. items = set([ item.path.replace(self.pipeline_location, "") for item in yaml_cache.g_yaml_cache.get_cached_items() ]) expected_items = set([ path.replace("/", os.path.sep) for path in [ "/config/core/core_api.yml", "/config/core/install_location.yml", "/config/core/pipeline_configuration.yml", "/config/core/roots.yml", "/config/core/shotgun.yml", "/config/env/project.yml", # Do not check for versions of bundles pulled from the appstore as they will change # over time. "/install/core/info.yml", ] ]) self.assertTrue( expected_items.issubset(items), "{0} should be a subset of {1}".format(sorted(expected_items), sorted(items)), )
def sgtk_on_load_callback(): try: # If we have opened a file then we should check if automatic context switching is enabled and change if possible engine = sgtk.platform.current_engine() file_name = nuke.root().name() if file_name != "Root" and engine is not None and engine.get_setting( "automatic_context_switch"): # We have a current script, and we have an engine and the current environment is set to # automatic context switch, so we should attempt to change the context to suit the file that is open. try: # todo: do we need to create a new tk object, instead should we just check the context gets created correctly? tk = sgtk.sgtk_from_path(file_name) except sgtk.TankError as e: __create_tank_disabled_menu(e) return # try to get current ctx and inherit its values if possible curr_ctx = None if sgtk.platform.current_engine(): curr_ctx = sgtk.platform.current_engine().context new_ctx = tk.context_from_path(file_name, curr_ctx) # Now switch to the context appropriate for the file __engine_refresh(new_ctx) elif file_name != "Root" and engine is None: # we have no engine, this maybe because the integration disabled itself, due to a non Toolkit file being # opened, prior to this new file. We must create a sgtk instance from the script path. try: tk = sgtk.sgtk_from_path(file_name) except sgtk.TankError as e: __create_tank_disabled_menu(e) return new_ctx = tk.context_from_path(file_name) # Now switch to the context appropriate for the file __engine_refresh(new_ctx) except Exception: __create_tank_error_menu()
def test_project_path_lookup(self): """ Check that a sgtk init works for this path """ # only run this test on windows if sys.platform == "win32": # probe a path inside of project test_path = "%s\\%s\\toolkit_test_path" % (self.STORAGE_ROOT, self.PROJECT_NAME) if not os.path.exists(test_path): os.makedirs(test_path) self.assertIsInstance(sgtk.sgtk_from_path(test_path), Tank)
def set_publish_info(): try: import sgtk except: shotgunErrorBox = libPySide.QCriticalBox() shotgunErrorBox.setText("Shotgun toolkit not loaded") shotgunErrorBox.setWindowTitle("Shotgun Module") shotgunErrorBox.exec_() return # # Evaluate the path path = pm.sceneName() # # # Get the toolkit tk = sgtk.sgtk_from_path(path) # # Get the nuke published area nukePublishFolderTemplate = tk.templates['shot_publish_area_nuke'] # # Deconstruct the maya scene mayaTemplate = tk.template_from_path(path) fields = mayaTemplate.get_fields(path) nukePublishFolder = nukePublishFolderTemplate.apply_fields(fields) # publishNukeFile = [fileName for fileName in libFile.listfiles(nukePublishFolder) if fileName.endswith(".nk")] currentPublishedNuke = libFile.search_pattern_in_folder(".nk", nukePublishFolder) # # increments the version fields["version"] = len(publishNukeFile) + 1 # Get the maya scene file mayaPublishFolderTemplate = tk.templates['maya_shot_render_folder'] mayaPublishVersion = "v%s" % str(fields["version"]).zfill(3) mayaPublishVersionFolder = mayaPublishFolderTemplate.apply_fields(fields) mayaShotTemplate = tk.templates['shot_publish_area_maya'] mayaProjectFolder = mayaShotTemplate.apply_fields(fields) mayaFileName = "%s_%s" % (fields['Shot'], mayaPublishVersion) renderer = pm.PyNode("defaultRenderGlobals") renderer.currentRenderer.set("vray") # Setup Vray _set_vray_() vraySettings = pm.PyNode("vraySettings") vraySettings.fileNamePrefix.set(mayaFileName) info = {"jobName": mayaFileName, "imagesFolder": mayaPublishVersionFolder, "projectFolder": mayaProjectFolder } # Set the meta data set_render_meta_data(vraySettings, tk) return info
def update(self, items): """ Perform replacements given a number of scene items passed from the app. Once a selection has been performed in the main UI and the user clicks the update button, this method is called. The items parameter is a list of dictionaries on the same form as was generated by the scan_scene hook above. The path key now holds the that each node should be updated *to* rather than the current path. """ engine = self.parent.engine scene_path = cmds.file(q=True, sn=True) tk = sgtk.sgtk_from_path(scene_path) substance_publish_template = "substancepainter_asset_textures_path_publish" template_obj = tk.templates[substance_publish_template] context = engine.context step_id = context.step.get('id') uv_step = 136 for i in items: node = i["node"] node_type = i["type"] new_path = i["path"] #\\3par\ibrix01\shotgun\shotgun_work\tdprojects\assets\Environment\table\TXT\publish\substancepainter\textures\table_textures_v004 if node_type == "reference": # maya reference engine.log_debug("Maya Reference %s: Updating to version %s" % (node, new_path)) rn = pm.system.FileReference(node) rn.replaceWith(new_path) elif node_type == "file": # file texture node engine.log_debug("File Texture %s: Updating to version %s" % (node, new_path)) file_name = cmds.getAttr("%s.fileTextureName" % node) folder_name = '' substance_file_name = '' if "/publish/substancepainter/" in file_name: folder_name, substance_file_name = os.path.split(file_name) sub_template = tk.template_from_path(folder_name) if sub_template == template_obj: new_path += '\\%s' % substance_file_name cmds.setAttr("%s.fileTextureName" % node, new_path, type="string")
def _import_script(self, new_script_path): """ Import contents of the given file into the scene. :param path: Path to file. :param sg_publish_data: Shotgun data dictionary with all the standard publish fields. """ # first we look at the current read nodes in the scene (they've been updated to their latest version already) preloaded_nodes = nuke.allNodes('Read') # We import the new nodes into the scene # if not os.path.exists(new_path): # raise Exception("File not found on disk - '%s'" % new_path) nuke.nodePaste(new_script_path) node = nuke.toNode('Published Data') node['text'].setValue(new_script_path) # Compare the new nodes with the old ones and delete the duplicates new_nodes = [item for item in nuke.allNodes('Read') if item not in preloaded_nodes] # Initialise the tank tk = sgtk.sgtk_from_path(new_script_path) # Get the maya render template maya_render_template = tk.templates["maya_shot_render"] cleanup_list = [] # Iterate through all the node for new_node in new_nodes: new_path = new_node['file'].value() # Is it a published render if maya_render_template.validate(new_path): new_fields = maya_render_template.get_fields(new_path) # Iterate through all the pre loaded node for old_node in preloaded_nodes: old_path = old_node['file'].value() # Is it a published node if maya_render_template.validate(old_path): old_fields = maya_render_template.get_fields(old_path) # Compare the fields if (new_fields['Shot'] == old_fields['Shot'] and new_fields['render_layer'] == old_fields['render_layer'] and new_fields['version'] > old_fields['version']): old_node["file"].setValue(new_path) cleanup_list.append(new_node) self.color_updated_read_node(old_node) #Delete any redundents nodes for node in list(set(cleanup_list)): nuke.delete(node )
def refresh_engine(engine_name, prev_context, menu_name): """ refresh the current engine """ logger.debug("Refreshing the engine, previous context: '%r'", prev_context) current_engine = sgtk.platform.current_engine() if not current_engine: # If we don't have an engine for some reason then we don't have # anything to do. logger.debug( "No currently initialized engine found; aborting the refresh of the engine" ) return # Get the path of the current open Maya scene file. new_path = maya_scene_path() if new_path is None: # This is a File->New call, so we just leave the engine in the current # context and move on. logger.debug("New file call, aborting the refresh of the engine.") return # this file could be in another project altogether, so create a new # API instance. try: tk = sgtk.sgtk_from_path(new_path) logger.debug("Extracted sgtk instance: '%r' from path: '%r'", tk, new_path) except sgtk.TankError as e: logger.exception("Could not execute sgtk_from_path('%s')" % new_path) OpenMaya.MGlobal.displayInfo("Shotgun: Engine cannot be started: %s" % e) # build disabled menu create_sgtk_disabled_menu(menu_name) return # shotgun menu may have been removed, so add it back in if its not already there. current_engine.create_shotgun_menu() # now remove the shotgun disabled menu if it exists. remove_sgtk_disabled_menu() # and construct the new context for this path: ctx = tk.context_from_path(new_path, prev_context) logger.debug( "Given the path: '%s' the following context was extracted: '%r'", new_path, ctx) if ctx != sgtk.platform.current_engine().context: logger.debug("Changing the context to '%r", ctx) current_engine.change_context(ctx)
def sgtk_on_load_callback(): try: # If we have opened a file then we should check if automatic context switching is enabled and change if possible engine = sgtk.platform.current_engine() file_name = nuke.root().name() if file_name != "Root" and engine is not None and engine.get_setting("automatic_context_switch"): # We have a current script, and we have an engine and the current environment is set to # automatic context switch, so we should attempt to change the context to suit the file that is open. try: # todo: do we need to create a new tk object, instead should we just check the context gets created correctly? tk = sgtk.sgtk_from_path(file_name) except sgtk.TankError as e: __create_tank_disabled_menu(e) return # try to get current ctx and inherit its values if possible curr_ctx = None if sgtk.platform.current_engine(): curr_ctx = sgtk.platform.current_engine().context new_ctx = tk.context_from_path(file_name, curr_ctx) # Now switch to the context appropriate for the file __engine_refresh(new_ctx) elif file_name != "Root" and engine is None: # we have no engine, this maybe because the integration disabled itself, due to a non Toolkit file being # opened, prior to this new file. We must create a sgtk instance from the script path. try: tk = sgtk.sgtk_from_path(file_name) except sgtk.TankError as e: __create_tank_disabled_menu(e) return new_ctx = tk.context_from_path(file_name) # Now switch to the context appropriate for the file __engine_refresh(new_ctx) except Exception: __create_tank_error_menu()
def _create_namespace_(self): """Only create a namespace if referencing a asset in to shot scene""" scenename = pm.sceneName() self.parent.log_info("SceneName:%s"%scenename) # Has the scene been saved if scenename: # Check to see if is a shot or asset tk = sgtk.sgtk_from_path(scenename) template_obj = tk.template_from_path(scenename) # Return the vale return template_obj.get_fields(scenename).has_key("Shot") else: # Due to fact the scene has not been saved, we use namespace just in case it is shot return True
def start_sg_nuke_engime(work_area_path): """ Initialize Shotgun Toolkit from the given context path and start the engine. For more info check: https://support.shotgunsoftware.com/entries/95440797#Render%20Farm%20Integration%201 returns: Nuke SGTK Instance """ tk = sgtk.sgtk_from_path(work_area_path) tk.synchronize_filesystem_structure() ctx = tk.context_from_path(work_area_path) # Attempt to start the engine for this context engine = sgtk.platform.start_engine('tk-nuke', tk, ctx) log.info('Shotgun Toolkit Nuke engine was initialized.') return engine
def __loadMissingSgtk(cls): """ Load missing sgtk engine. This is necessary to be able to run sgtk on the farm. The reason for that is because sgtk modifies the environment variables that were used to launch nuke from sgtk desktop. Therefore, context, engine (etc). Don't get available on the farm (or anywhere that tries to run nuke with those environments). This solution was based on: https://github.com/shotgunsoftware/tk-nuke-writenode/wiki/Documentation """ # we need that for the authentication if 'TANK_NUKE_ENGINE_INIT_CONTEXT' not in os.environ: return # initialize tk-nuke engine: # Determine the work area path that will be used to # create the initial context the engine will be # started with. If a file path was specified on the # command line then this will be sys.argv[0] workAreaPath = os.environ.get('UMEDIA_ORIGINAL_SCENE_FILE_PATH', '') if not workAreaPath and len( sys.argv) > 0 and sys.argv[0].endswith(".nk"): # file path was passed through the command line workAreaPath = sys.argv[0] # don't know the work area if not workAreaPath: return # importing sgtk import sgtk # the 'deserialize' process is going to set the user in sgtk implicitly, # however we want to build a new context from scratch sgtk.Context.deserialize(os.environ['TANK_NUKE_ENGINE_INIT_CONTEXT']) # instantiate an sgtk instance from the current work area path: tk = sgtk.sgtk_from_path(workAreaPath) # make sure we have synchronised the file system structure from # Shotgun (for core v0.15 and above): tk.synchronize_filesystem_structure() # build a context from the work area path: ctx = tk.context_from_path(workAreaPath) # Finally, attempt to start the engine for this context: sgtk.platform.start_engine("tk-nuke", tk, ctx)
def process(self): print "Watching %s", self.root #set up valid file list to publish pfiles = [] publish = False # get directory listing files = os.listdir(self.root) files.sort() for file in files: # NEED A BETTER WAY TO CHECK REQUEST TO PUBLISH if file.lower() == 'publish.txt': print "publish.txt exists" publish = True else: if file.split('.')[-1].lower() in VALID_FILES: #print "Valid File: ", file pfiles.append(file) if publish is True: if fileSequence(pfiles) is False: print "NOT A SEQUNCE" else: print "Valid Sequnce - publish" # get details of project/episode/sequence/shot/version from file data = self.root.split('/')[-1].split('_') #project = self.root.split('/')[3] project = 'pipetest2' version = data[-1] shot = data[0].split('-')[-1] sequence = data[0].split('-')[1] episode = data[0].split('-')[0] print "project %s epsispde %s sequence %s shot %s version %s" % (project, episode, sequence, shot, version) tkpath = '/array/X/outsource/michael/to_mvrcks/pipetest2/Ep01/seq01/ep01-seq01-shot030/Comp/publish/renders/Ep01-seq01-shot030_Comp_v001/ep01-FE-020_comp_v001.%04d.dpx' ctxpath = "/array/X/" + project + "/episodes/"+episode+"/"+sequence+ "/" + shot + "/Comp/" #ctxpath = '/array/X/outsource/michael/to_mvrcks/pipetest2/Ep01/seq01/ep01-seq01-shot030/Comp/publish/renders/Ep01-seq01-shot030_Comp_v001/ #os.makedirs(ctxpath) #sgEntity = tk.entity_from_path(ctxpath) #print sgEntity tk = sgtk.sgtk_from_path(ctxpath) ctx = tk.context_from_path(ctxpath) publish = sgtk.util.register_publish( tk, ctx , tkpath, "Publish Name", 001 ) print publish
def main(): opts = parse_args() # import toolkit from the specified core install sys.path.insert(0, opts.core_python_path) import sgtk if hasattr(sgtk, "set_authenticated_user"): # import authentication from tank_vendor import shotgun_authentication # Initialize the authenticator with Toolkit's defaults manager. dm = sgtk.util.CoreDefaultsManager() sg_auth = shotgun_authentication.ShotgunAuthenticator(dm) # get the current user user = sg_auth.get_default_user() sgtk.set_authenticated_user(user) import sgtk.platform.engine # load up toolkit and get the environment for the project context tk = sgtk.sgtk_from_path(opts.configuration_path) ctx = tk.context_from_entity("Project", int(opts.project_id)) env = sgtk.platform.engine.get_environment_from_context(tk, ctx) # make a backup of the original yml file shutil.copy(env.disk_location, "%s.orig" % env.disk_location) # install the tk-desktop engine if it is not installed if "tk-desktop" not in env.get_engines(): install_cmd = tk.get_command("install_engine") params = { "environment": env.name, "engine_uri": "tk-desktop", } install_cmd.execute(params) # reload the new environment env = sgtk.platform.engine.get_environment_from_context(tk, ctx) # copy the apps from tk-shell copy_apps_cmd = tk.get_command("copy_apps") params = { "environment": env.name, "src_engine_instance": "tk-shell", "dst_engine_instance": "tk-desktop", } copy_apps_cmd.execute(params)
def start_engine(data): """ Start the tk-desktop engine given a data dictionary like the one passed to the launch_python hook. """ sys.path.append(data["core_python_path"]) # make sure we don't inherit the GUI's pipeline configuration os.environ["TANK_CURRENT_PC"] = data["config_path"] import sgtk sgtk.util.append_path_to_env_var("PYTHONPATH", data["core_python_path"]) # Initialize logging right away instead of waiting for the engine if we're using a 0.18 based-core. # This will also ensure that a crash will be tracked if hasattr(sgtk, "LogManager"): sgtk.LogManager().initialize_base_file_handler("tk-desktop") # If the core supports the shotgun_authentication module and the pickle has # a current user, we have to set the authenticated user. if hasattr(sgtk, "set_authenticated_user"): # Retrieve the currently authenticated user for this process. from tank_vendor.shotgun_authentication import ShotgunAuthenticator, deserialize_user current_user = ShotgunAuthenticator( sgtk.util.CoreDefaultsManager()).get_default_user() # If we found no user using the authenticator, we need to use the credentials that # came through the environment variable. # Also, if the credentials are user-based, we need to disregard what we got and use # the credentials from the environment variable. This is required to solve any issues # arising from the changes to the session cache changing place in core 0.18. if not current_user or current_user.login: current_user = deserialize_user( os.environ["SHOTGUN_DESKTOP_CURRENT_USER"]) else: # This happens when the user retrieved from the project's core is a script. # In that case, we use the script user and disregard who is the current # authenticated user at the site level. pass sgtk.set_authenticated_user(current_user) tk = sgtk.sgtk_from_path(data["config_path"]) tk._desktop_data = data["proxy_data"] ctx = tk.context_from_entity("Project", data["project"]["id"]) engine = sgtk.platform.start_engine("tk-desktop", tk, ctx) return engine
def start_engine(data): """ Start the tk-desktop engine given a data dictionary like the one passed to the launch_python hook. """ sys.path.append(data["core_python_path"]) import sgtk sgtk.util.append_path_to_env_var("PYTHONPATH", data["core_python_path"]) # make sure we don't inherit the GUI's pipeline configuration os.environ["TANK_CURRENT_PC"] = data["config_path"] tk = sgtk.sgtk_from_path(data["config_path"]) tk._desktop_data = data["proxy_data"] ctx = tk.context_from_entity("Project", data["project"]["id"]) return sgtk.platform.start_engine("tk-desktop", tk, ctx)
def _import_published_shaders(self,path,ref): tk = sgtk.sgtk_from_path(path) # Get the fields template_obj = tk.template_from_path(path) fields = template_obj.get_fields(path) template_obj.apply_fields(fields) # Get the data folder dataTemplate = tk.templates["maya_asset_data_publish"] published_data_folder = dataTemplate.apply_fields(fields) print "******************************" print "published_data_folder = ".format(published_data_folder) # Init the ShaderAPI reload(libShader) shaderAPI = libShader.MDSshaderAPI() shaderAPI.dataFolder = published_data_folder # Get the model info associated with this model modelUsed = shaderAPI.get_model_info() # Search for the namespace associated with this model nameSpaces = [] for transform in pm.ls(type="transform"): if transform.hasAttr("Namespace"): # check if matches the geo if transform.ModelUsed.get(): if transform.ModelUsed.get().lower() == modelUsed.lower(): nameSpaces.append(transform.Namespace.get()) if nameSpaces: # Apply the shader to the first namespace shaderAPI.namespace = "%s:"%nameSpaces[0] shaderAPI.import_all_shading_and_connection_info() # Reapply to the all the rest if len(nameSpaces) > 1: for nameSpace in nameSpaces[1:]: shaderAPI.namespace = "%s:"%nameSpace shaderAPI.reapply_all_shaders() shaderAPI.assetNameSpace = ref.namespace shaderAPI.add_shader_nameSpace() # Add namespaces to the Shaders else: ref.remove() raise Exception("No Alembics found associated that matches the model used in the published Surface task")
def __find_file_details(self, depot_path, p4): """ Find the depot project root and tk instance for the specified depot path if possible. :param depot_path: Depot path to check :param p4: Perforce connection to use :returns (str, Sgtk): Tuple containing (depot project root, sgtk instance) """ # first, check the cache to see if we found this information previously: if depot_path in self.__depot_path_details_cache: return self.__depot_path_details_cache.get(depot_path) self.__depot_path_details_cache[depot_path] = None self._app.log_debug("Looking for file details for: '%s'" % depot_path) # Determine the depot project root for this depot file: depot_project_root = self.__get_depot_project_root(depot_path, p4) if not depot_project_root: # didn't find a project root so this file is probably not # within a Toolkit data directory! self._app.log_debug(" > No depot root found, depot path is not contained in project storage!") return self._app.log_debug(" > Depot project root found: '%s'" % depot_project_root) # find the pipeline config root from the depot root: local_pc_root = self.__get_local_pc_root(depot_project_root, p4) if not local_pc_root: # didn't find a matching pipeline configuration location! self._app.log_error("Failed to locate pipeline configuration for depot project root '%s'" % depot_project_root) return self._app.log_debug(" > Local PC root found: '%s'" % local_pc_root) # get a tk instance for this pipeline configuration: tk = self.__pc_tk_instances.get(local_pc_root) if not tk: # create a new api instance: self._app.log_debug(" > Creating TK instance for path: '%s'" % local_pc_root) try: tk = sgtk.sgtk_from_path(local_pc_root) except TankError, e: self._app.log_error(" > Failed to create TK instance for PC root '%s'" % local_pc_root) # this shouldn't happen so raise this error: raise self.__pc_tk_instances[local_pc_root] = tk
def set_envs(self, file_path): # setup Shotgun base functions eng = sgtk.platform.current_engine() tk = sgtk.sgtk_from_path(file_path) fields_template = tk.template_from_path(file_path) entity_type = eng.context.entity.get('type') root_template = None # determine context and get templates if entity_type: if entity_type in ['shot', 'Shot', 'SHOT']: root_template = tk.templates['houdini_shot_render_step_ver'] cache_root = tk.templates['houdini_shot_cache_root'] flip_root = tk.templates['houdini_shot_playblast_root'] alembic_root = tk.templates['houdini_shot_alembic_root'] elif entity_type in ['asset', 'Asset', 'ASSET']: root_template = tk.templates['houdini_asset_render_step_ver'] cache_root = tk.templates['houdini_asset_cache_root'] flip_root = tk.templates['houdini_asset_playblast_root'] alembic_root = tk.templates['houdini_asset_alembic_root'] # generate output roots for renders/caches/flipbooks curr_fields = fields_template.get_fields(file_path) output_root = root_template.apply_fields(curr_fields) cache_output = cache_root.apply_fields(curr_fields) flip_output = flip_root.apply_fields(curr_fields) alembic_output = alembic_root.apply_fields(curr_fields) hou.putenv("RENDER_ROOT", output_root.replace(os.path.sep, '/')) hou.putenv("CACHE_ROOT", cache_output.replace(os.path.sep, '/')) hou.putenv("FLIP_ROOT", flip_output.replace(os.path.sep, '/')) hou.putenv("ALEMBIC_ROOT", alembic_output.replace(os.path.sep, '/')) # create variables for filename output filename_base = "%s_%s_" % ( (curr_fields.get('Asset') or curr_fields.get('Shot')), curr_fields.get('task_name')) filename_version = "_v%s" % str(curr_fields.get('version')).zfill(4) hou.putenv("FILENAME_ROOT", filename_base) hou.putenv("FILENAME_VER", filename_version)
def __sgtk_on_save_callback(): """ Callback that fires every time a file is saved. Carefully manage exceptions here so that a bug in Tank never interrupts the normal workflows in Nuke. """ # get the new file name file_name = nuke.root().name() try: logger.debug("SGTK Callback: addOnScriptSave('%s')" % file_name) # this file could be in another project altogether, so create a new Tank # API instance. try: tk = sgtk.sgtk_from_path(file_name) logger.debug("Tk instance '%r' associated with path '%s'" % (tk, file_name)) except sgtk.TankError as e: logger.exception("Could not execute tank_from_path('%s')" % file_name) __create_tank_disabled_menu(e) return # try to get current ctx and inherit its values if possible curr_ctx = None curr_engine = sgtk.platform.current_engine() if curr_engine: curr_ctx = curr_engine.context # and now extract a new context based on the file new_ctx = tk.context_from_path(file_name, curr_ctx) logger.debug("New context computed to be: %r" % new_ctx) # now restart the engine with the new context if curr_ctx != new_ctx: __engine_refresh(new_ctx) except Exception: logger.exception( "An exception was raised during addOnScriptSave callback.") __create_tank_error_menu()
def __init__(self, app): """ main UI for the playblast options NOTE: This currenlty playblasts directly into the publish folder.. it'd be great to avoid this and do the move of the file on register... """ QtGui.QWidget.__init__(self) self.app = app ## Instantiate the API tk = sgtk.sgtk_from_path("T:/software/bubblebathbay") debug(self.app, method = 'MainUI __init__', message = 'API instanced...\n%s' % tk, verbose = False) debug(self.app, method = 'MainUI __init__', message = 'Checking for valid context...', verbose = False) context = self.app.context ## To get the step debug(self.app, method = 'run_app', message = 'Context Step...\n%s' % context.step['name'], verbose = False) if context.step['name'] != 'Light': raise tank.TankError("You are not in a valid lighting step!") cmds.warning("Current context is not a valid Lighting context. Please make sure you are under a valid shotgun Lighting context!") pass else: self.mainLayout = QtGui.QVBoxLayout(self) debug(self.app, method = 'MainUI __init__', message = 'self.mainLayout built successfully....', verbose = False) self.getAllUVs = QtGui.QPushButton('Step 1: Fetch All Published UV XMLs', self) self.getAllUVs.released.connect(partial(self.fetchAllUVs, tk)) debug(self.app, method = 'MainUI __init__', message = 'self.getAllUVs built successfully....', verbose = False) self.sep01 = BB_Widget_hr() self.getSelUVs = QtGui.QPushButton('Fetch UVs for Selected Only', self) self.getSelUVs.released.connect(partial(self.fetchUVsForSelected, tk)) self.getSelUVs.setStyleSheet("QPushButton {text-align: center; background: gray}") self.mainLayout.addWidget(self.getAllUVs) self.mainLayout.addWidget(self.sep01) self.mainLayout.addWidget(self.getSelUVs) self.mainLayout.addStretch(1) self.resize(50,120)