def _get_body_ref_movs_data(force=False): """Read reference movs spreadsheet data. Args: force (bool): force reread from disk Returns: (dict): vendor in mov, reference mov and start frame data """ _data_file = '{}/_fr_ref_movs_body.data'.format(_DIR) _data = {} for _line in File(_data_file).read_lines(): _line = _line.strip() if not _line.strip(): continue # Extract blast comp _blast_comp = _line.split('.mov')[0] + '.mov' assert _line.count(_blast_comp) == 1 _line = _line.replace(_blast_comp, '').strip() _blast_comp = abs_path(_blast_comp) # Extract ref mov _body_ref = _line.split('.mov')[0] + '.mov' assert _line.count(_body_ref) == 1 _line = _line.replace(_body_ref, '').strip() _body_ref = abs_path(_body_ref) # Extract start _start = float(_line.strip()) _data[_blast_comp] = _body_ref, _start return _data
def remove_sys_path(path): """Remove a path from sys.path list. Paths are compared in their absolute form. Args: path (str): path to remove """ _path = abs_path(path) for _sys_path in copy.copy(sys.path): if abs_path(_sys_path) == _path: print 'REMOVING', _sys_path sys.path.remove(_sys_path)
def test_move_to(self): _file_a = File(abs_path( '{}/A/file.text'.format(tempfile.gettempdir()))) _file_b = File(abs_path( '{}/B/file.text'.format(tempfile.gettempdir()))) _file_a.touch() _dir = _file_a.parent() print _dir _file_a.parent().move_to(_file_b.parent()) assert _file_b.exists() _file_b.parent().delete(force=True) assert not _file_b.parent().exists()
def process_movs_for_review(dir_=None, filter_=None, verbose=0): """Process review movs. Each set of three input movs in Front/Left/Right/Producer suffix is comped into an output mov using the template nk file. Args: dir_ (str): dir to search from input mov groups filter_ (str): apply file path filter verbose (int): print process data """ # Get dirs to search _today_dir = abs_path(time.strftime( r'P:\projects\frasier_38732V\production\vendor_in\Motion Burner' r'\%Y-%m-%d')) _dirs = set([_today_dir]) if dir_: _dirs.add(abs_path(dir_)) _dirs = sorted(_dirs) print 'SEARCH DIRS:' pprint.pprint(_dirs) _movs = [] for _dir in _dirs: _movs += find(_dir, type_='f', extn='mov', class_=_InputReviewMov, filter_=filter_) # Find review movs _review_movs = {} for _input_mov in sorted(_movs): lprint('ADDING MOV', _input_mov, verbose=verbose) _key = _input_mov.review_mov.path.lower() if _key not in _review_movs: _review_movs[_key] = _input_mov.review_mov _review_movs[_key].input_movs.append(_input_mov) print 'FOUND {:d} REVIEW MOVS'.format(len(_review_movs)) for _path, _review_mov in _review_movs.items(): if _review_mov.exists(): del _review_movs[_path] print '{:d} TO GENERATE'.format(len(_review_movs)) for _idx, _review_mov in enumerate(sorted(_review_movs.values())): print '{:d}/{:d} {}'.format(_idx+1, len(_review_movs), _review_mov) for _input_mov in _review_mov.input_movs: print ' -', _input_mov assert len(_review_mov.input_movs) == 3 _review_mov.generate()
def __init__(self, path): """Constructor. Args: path (str): path to workfile """ super(WorkFile, self).__init__(abs_path(path)) del path self.shot = Shot(self.path) self.project = self.shot.project _b_tokens = self.basename.split('_') _d_tokens = self.shot.rel_path(self.path).split('/') if not _b_tokens[0] == self.shot.name: raise ValueError(self.path) # Read ver data self.ver = _b_tokens[-1] self.ver_n = read_ver_n(self.ver) assert self.path.count(self.ver) == 1 self.ver_fmt = self.path.replace(self.ver, 'v{ver_n:03d}') self.step = _d_tokens[0] self.task = _b_tokens[1] self.dcc = _d_tokens[2]
def save_as(self, path, force=False, verbose=0): """Save this pixmap at the given path. Args: path (str): path to save at force (bool): force overwrite with no confirmation verbose (int): print process data """ from psyhive import qt assert self.width() and self.height() _file = File(path) _fmt = {}.get(_file.extn, _file.extn.upper()) lprint("SAVING", path, _fmt, verbose=verbose) if _file.exists(): if not force: _result = qt.yes_no_cancel('Overwrite existing image?\n\n' + path) if _result == 'No': return os.remove(_file.path) test_path(_file.dir) self.save(abs_path(path, win=os.name == 'nt'), format=_fmt, quality=100) assert _file.exists()
def __init__(self, path, hint=None, tmpl=None, data=None, verbose=0): """Constructor. Args: path (str): path to object hint (str): template name tmpl (TemplatePath): override template object data (dict): override data dict verbose (int): print process data """ _path = abs_path(path) lprint('PATH', _path, verbose=verbose) super(TTBase, self).__init__(_path) self.hint = hint or self.hint self.tmpl = tmpl or get_current_engine().tank.templates[self.hint] self.project = pipe.Project(path) if self.project != pipe.cur_project(): raise ValueError('Not current project ' + self.path) try: self.data = data or self.tmpl.get_fields(self.path) except tank.TankError as _exc: lprint('TANK ERROR', _exc.message, verbose=verbose) raise ValueError("Tank rejected {} {}".format( self.hint, self.path)) lprint('DATA', pprint.pformat(self.data), verbose=verbose) for _key, _val in self.data.items(): _key = _key.lower() if getattr(self, _key, None) is not None: continue setattr(self, _key, _val)
def save_test(self, file_=None, timestamp=True, extn='jpg', verbose=1): """Save test image and copy it to pictures dir. Args: file_ (str): override save file path - this can be used to switch this method with a regular save timestamp (bool): write timestamped file extn (str): test file extension verbose (int): print process data Returns: (str): path to saved file """ if file_: self.save_as(file_, force=True) return file_ _test_img = File(TEST_IMG).apply_extn(extn).path self.save_as(_test_img, verbose=verbose, force=True) _file = _test_img if timestamp: _timestamp_file = abs_path( time.strftime( '~/Documents/My Pictures/tests/%y%m%d_%H%M.{}'.format( extn))) self.save_as(_timestamp_file, verbose=verbose, force=True) _file = _timestamp_file return _file
def __init__(self, path): """Constructor. Args: path (str): path to work file inc """ super(WorkFileInc, self).__init__(abs_path(path)) del path self.shot = Shot(self.path) self.project = self.shot.project _b_tokens = self.basename.split('_') _d_tokens = self.shot.rel_path(self.path).split('/') if not _b_tokens[0] == self.shot.name: raise ValueError(self.path) if not _d_tokens[-2] == 'increments': raise ValueError(self.path) self.ver = _b_tokens[-2] self.ver_n = read_ver_n(self.ver) self.inc = _b_tokens[-1] self.inc_n = int(self.inc) self.step = _d_tokens[0] self.task = _b_tokens[1] self.dcc = _d_tokens[2]
def map_file_to_psy_asset(file_, step='rig'): """Map off pipeline reference path to a psyop file. Args: file_ (str): file to map step (str): asset step Returns: (TTOutputFile): psyop asset file """ from .. import ingest _file = File(abs_path(file_)) if _file.extn == 'mb' and _file.basename.startswith('camera_rig_main'): _name = 'camera' elif ingest.is_vendor_file(file_): _file = ingest.VendorFile(file_) _name = _file.tag elif ingest.is_psy_asset(file_): _file = ingest.PsyAsset(file_) _name = _file.asset else: return None _asset = tk2.find_asset(asset=_name) _step = _asset.find_step_root(step) try: _file = _step.find_output_file(version='latest', format_='maya', task=step) except ValueError: raise ValueError('failed to find output file - ' + _step.path) return _file
def __init__(self, path): """Constructor. Args: path (str): path within a project Raises: (ValueError): if path was not in projects root """ try: _tokens = Dir(PROJECTS_ROOT).rel_path(path).split('/') except ValueError: raise ValueError('Not in projects root ' + path) _path = '/'.join([PROJECTS_ROOT, _tokens[0]]) super(Project, self).__init__(_path) self.name = _tokens[0] if self.name.startswith('~'): raise ValueError self.seqs_path = '/'.join([self.path, 'sequences']) self.maya_scripts_path = '{}/code/primary/addons/maya/scripts'.format( os.environ.get('PSYOP_PROJECT_PATH')) self.psylaunch_cfg = abs_path(_PSYLAUNCH_CFG_FMT.format(self.path)) self.cache_fmt = '{}/production/psyhive/cache/{{}}.pkl'.format( self.path)
def _get_job_environ(local=False): """Get environment for psyq job. Args: local (bool): if job is being executed locally Returns: (dict): environ """ _result = {} _result.update(psyop.env.get_bootstrap_variables()) # Update python path _clean_env = psyrc.original_environment() _result["PYTHONPATH"] = _clean_env.get("PYTHONPATH", "") # Set psyq plugin path if dev_mode() and not local: _plugin_path = ( 'P:/projects/hvanderbeek_0001P/code/primary/addons/' 'maya/modules/psyhive/scripts/psyhive/farm/psyq_plugin') else: _plugin_path = abs_path(os.path.dirname(__file__)+'/psyq_plugin') print "PSYQ_PLUGIN_PATH", _plugin_path _result["PSYQ_PLUGIN_PATH"] = _plugin_path return _result
def __init__(self): """Constructor.""" from psyhive.tools import batch_rerender batch_rerender.DIALOG = self self._all_steps = [] self._all_renders = [] self._work_files = {} self._renders = [] self._passes = [] _ui_file = abs_path( 'batch_rerender.ui', root=os.path.dirname(__file__)) super(_BatchRerenderUi, self).__init__(ui_file=_ui_file) self.setWindowTitle('Batch Rerender') self.set_icon(ICON) self.ui.sequences.itemSelectionChanged.connect( self.ui.shots.redraw) self.ui.shots.itemSelectionChanged.connect( self.ui.steps.redraw) self.ui.steps.itemSelectionChanged.connect( self.ui.tasks.redraw) self.ui.tasks.itemSelectionChanged.connect( self.ui.renders.redraw) self.ui.renders.itemSelectionChanged.connect( self.ui.info.redraw) self.ui.steps.select_text('lighting', catch=True) self.ui.tasks.select_text('lighting', catch=True)
def __init__(self, traceback_=None): """Constructor. Args: traceback_ (str): override traceback string (otherwise read from traceback module) """ self.body = (traceback_ or traceback.format_exc()).strip() _lines = self.body.split('\n') assert _lines.pop(0) == 'Traceback (most recent call last):' _file_lines = [] while _lines and _lines[0] and _lines[0].startswith(' '): check_heart() _file_lines.append(_lines.pop(0)) _file_text = '\n'.join(_file_lines) _splitter = ' File "' try: self.lines = [ _TraceStep((_splitter+_item).strip().split('\n')) for _item in _file_text.split(_splitter)[1:]] except IndexError: print '############## Traceback ##############' print self.body print '#######################################' raise RuntimeError("Failed to parse traceback") self.clean_text = '# '+self.body.replace('\n', '\n# ') for _token in self.clean_text.split('"'): if os.path.exists(_token): _path = abs_path(_token) self.clean_text = self.clean_text.replace(_token, _path)
def update_nk(template, shot, diff=True, force=True): """Update nk template to new shot. Args: template (TTWorkFileBase): template work file shot (TTShotRoot): shot to update to diff (bool): show diffs force (bool): save with no confirmation """ _new_work = template.map_to(Shot=shot.shot).find_next() _start, _end = shot.get_frame_range() _nk = _NkFile(template.path) _update_nk_reads(nk_file=_nk, shot=shot) # Update write nodes for _node in _nk.find_nodes(type_='Write'): for _attr in ['file', 'proxy']: _file = _node.read_attr(_attr) _orig_out = tk.get_output(_file) if not _orig_out: continue print 'ORIG OUT', _orig_out _new_out = _orig_out.map_to(Shot=shot.shot, version=_new_work.version) print 'NEW OUT', _orig_out _node.set_attr(_attr, _new_out.path) print # Update root _root = _nk.find_node(type_='Root') _root.set_attr('name', _new_work.path) _root.set_attr('first_frame', _start) _root.set_attr('last_frame', _end) # Update header _header = _nk.data[0] assert isinstance(_header, six.string_types) _tokens = [_token for _token in re.split('[ "]', _header) if _token] for _token in _tokens: _orig_out = tk.get_output(_token) if not _orig_out: continue _new_out = _orig_out.map_to(Shot=shot.shot, version=_new_work.version) assert _header.count(_token) == 1 _header = _header.replace(_token, _new_out.path) _nk.data[0] = _header if diff: _tmp_nk = File(abs_path('{}/test.nk'.format(tempfile.gettempdir()))) _nk.write(_tmp_nk.path, force=True) _tmp_nk.diff(template.path) # Write new work if not force: qt.ok_cancel('Write new work file?\n\n{}'.format(_new_work.path)) _nk.write(_new_work.path, force=True) _new_work.set_comment(comment='Scene built by shot_builder') print 'WROTE NK:', _new_work.path
def __init__(self, path, hint=None, verbose=0): """Constructor. Args: path (str): path to object hint (str): template name verbose (int): print process data """ _raw_path = abs_path(path) _hint = hint or self.hint _tmpl = get_current_engine().tank.templates[_hint] _def = abs_path(_tmpl.definition, root=pipe.Project(path).path) _path = '/'.join(_raw_path.split('/')[:_def.count('/') + 1]) if verbose: print 'RAW PATH', _raw_path print 'PATH ', _path super(TTDirBase, self).__init__(_path, hint=hint, tmpl=_tmpl)
def obtain_ref(file_, namespace, class_=None): """Search for a reference and create it if it doesn't exist. Args: file_ (str): file to reference namespace (str): reference namespace class_ (FileRef): override FileRef class """ _ref = find_ref(namespace, catch=True, class_=class_) if _ref: if abs_path(_ref.path) != abs_path(file_): print 'A', abs_path(_ref.path) print 'B', abs_path(file_) raise ValueError('Path mismatch') return _ref return create_ref(file_=file_, namespace=namespace, class_=class_)
def __init__(self, lines): """Constructor. Args: lines (list): traceback lines """ self.text = '\n '.join([_line.strip() for _line in lines]) self.file_ = abs_path(lines[0].split('"')[1]) self.line_n = int(lines[0].split(',')[1].strip(' line'))
def test_find(self): _test_dir = '{}/psyhive/testing/blah'.format(tempfile.gettempdir()) _test_file = abs_path('{}/test.txt'.format(_test_dir)) if os.path.exists(_test_dir): shutil.rmtree(_test_dir) touch(_test_file) assert get_single(find(_test_dir)) == _test_file assert get_single(find(_test_dir, full_path=False)) == 'test.txt'
def create_ref(file_, namespace, class_=None, force=False): """Create a reference. Args: file_ (str): path to reference namespace (str): reference namespace class_ (type): override FileRef class force (bool): force replace any existing ref Returns: (FileRef): reference """ from psyhive import qt from psyhive import host _file = File(abs_path(file_)) if not _file.exists(): raise OSError("File does not exist: " + _file.path) _class = class_ or FileRef _rng = host.t_range() if _file.extn == 'abc': cmds.loadPlugin('AbcImport', quiet=True) elif _file.extn.lower() == 'fbx': cmds.loadPlugin('fbxmaya', quiet=True) # Test for existing cmds.namespace(set=":") if cmds.namespace(exists=namespace): _ref = find_ref(namespace, catch=True) if _ref: if not force: qt.ok_cancel( 'Replace existing {} reference?'.format(namespace)) _ref.remove(force=True) else: del_namespace(namespace, force=force) # Create the reference _cur_refs = set(cmds.ls(type='reference')) _kwargs = { 'reference': True, 'namespace': namespace, 'options': "v=0;p=17", 'ignoreVersion': True } cmds.file(_file.abs_path(), **_kwargs) # Find new reference node _ref = get_single(set(cmds.ls(type='reference')).difference(_cur_refs)) # Fbx ref seems to update timeline (?) if host.t_range() != _rng: host.set_range(*_rng) return _class(_ref)
def cur_scene(): """Get the path to the current scene. Returns: (str|None): path to current scene (if any) """ _cur_scene = _get_cur_scene() if not _cur_scene or _cur_scene == 'unknown': return None return abs_path(_cur_scene)
def _revert_scene_fn(*args, **kwargs): _cur_file = host.cur_scene() _tmp_file = abs_path('{}/_psyhive_tmp.mb'.format( tempfile.gettempdir())) host.save_as(_tmp_file, force=True) _result = func(*args, **kwargs) host.open_scene(_tmp_file, force=True) if _cur_file: cmds.file(rename=_cur_file) return _result
def settings(self): """Get settings object. Returns: (QSettings): settings """ _name = type(self).__name__.strip('_') _settings_file = abs_path('{}/{}.ini'.format(SETTINGS_DIR, _name)) touch(_settings_file) # Check settings writable return QtCore.QSettings(_settings_file, QtCore.QSettings.IniFormat)
def __init__(self, path): """Constructor. Args: path (str): path to output name dir """ _path = abs_path(path) _area = get_area(_path) _hint = self.hint_fmt.format(area=_area) super(TTOutputName, self).__init__(path, hint=_hint)
def test_check_docs(self): _example = abs_path('example.py', root=os.path.dirname(__file__)) _py_file = PyFile(_example) with self.assertRaises(MissingDocs): _py_file.find_def('missing_docs').check_docs() with self.assertRaises(MissingDocs): _py_file.find_def('missing_docs_args').check_docs() with self.assertRaises(MissingDocs): _py_file.find_def('missing_period').check_docs()
def __init__(self, rigs): """Constructor. Args: rigs (FileRef): list of rigs outside frustrum """ self.rigs = rigs _ui_file = abs_path('remove_rigs.ui', root=os.path.dirname(__file__)) super(_RemoveRigsUi, self).__init__(_ui_file, save_settings=False) self._redraw__List()
def __init__(self, rigs): """Constructor. Args: rigs (FileRef): list of rigs outside frustrum """ self.rigs = rigs _ui_file = abs_path('remove_rigs.ui', root=os.path.dirname(__file__)) super(_RemoveRigsUi, self).__init__(_ui_file, save_settings=False) self.ui.list.itemSelectionChanged.connect(self.ui.remove.redraw)
def __init__(self, path): """Constructor. Args: path (str): path to step root """ _path = abs_path(path) _area = get_area(_path) _hint = self.hint_fmt.format(area=_area) super(TTStepRoot, self).__init__(path, hint=_hint) self.name = self.step
def __init__(self, path): """Constructor. Args: path (str): path to work area """ _path = abs_path(path) _area = get_area(_path) _dcc = get_dcc(_path) _hint = self.hint_fmt.format(area=_area, dcc=_dcc) super(TTWorkArea, self).__init__(path, hint=_hint)
def __init__(self, path): """Constructor. Args: path (str): path to increment file """ _path = abs_path(path) _area = get_area(_path) _dcc = get_dcc(_path) _hint = self.hint_fmt.format(dcc=_dcc, area=_area) super(TTIncrement, self).__init__(path, hint=_hint)