SG Python request
py
# Python built-in modules import
import re
# Third-party modules import
class ShotgunYamlLoader(YamlLoader):
def __init__(self, *args, **kwargs):
super(ShotgunYamlLoader, self).__init__(*args, **kwargs)
@property
def paths(self):
return self.__dict__.get('paths')
@property
def strings(self):
return self.__dict__.get('strings')
@property
def regex_variables(self):
return r'(@\w*[^_\/.\]\[\\\}\{])'
def _clean_dictionary(self):
""" Clean the dictionary by removing all None values."""
temp_dict = self.paths.copy()
for key, val in temp_dict.items():
if isinstance(val, str):
continue
if isinstance(val, dict) and 'definition' in val.keys():
self.paths[key] = val['definition']
continue
print(f"Removing {key} from paths: {val}")
del self.paths[key]
def _parse_shotgun_yaml(self):
""" Parse shotgun yaml file to find all variables keys"""
if not 'paths' in self.keys:
return
dict_paths = self.paths
# find all regex matches
for key, val in dict_paths.items():
value = self._find_all_variables_keys(val)
self.paths[key] = value
def _find_all_variables_keys(self, path_token) -> str:
""" Find all @variables by their value for each path_token.
We need to use recursion to find all variables keys because a path_token can also contain a path_token.
:param path_token: The path_token to parse, like @project_root/something/@project_name
"""
dict_paths = self.paths
dict_strings = self.strings
if not isinstance(path_token, str):
return path_token
if not '@' in path_token:
return path_token
regex = re.compile(self.regex_variables)
matches = regex.findall(path_token)
for match in matches:
rk = match.replace('@', '')
clean_path = path_token.replace(match, '')
value = None
if dict_paths.get(rk):
value = dict_paths.get(rk)
if dict_strings.get(rk):
value = dict_strings.get(rk)
if value:
# if value start with /, and clean_path end with /, we need to remove one of them
if clean_path.startswith('/') and value[-1] == '/':
value = value[:-1]
value = path_token.replace(match, value)
return self._find_all_variables_keys(value)
print(f"Can't find {rk} in paths or strings")
def load(self, file_path: str) -> None:
""" Load method, to get yaml as dict and parse it to find all variables keys, used by sgtk.
:param file_path: The path to the yaml file.
"""
super(ShotgunYamlLoader, self).load(file_path)
self._clean_dictionary()
self._parse_shotgun_yaml()