def test_valid_parse_in_strict_mode(pattern, path, expected): '''Extract data in strict mode when no invalid duplicates detected.''' template = Template( 'test', pattern, duplicate_placeholder_mode=Template.STRICT ) data = template.parse(path) assert data == expected
def template_resolver(): '''Return template resolver instance.''' resolver = ResolverFixture() resolver.templates.extend([ Template('reference', '{variable}', template_resolver=resolver), Template('nested', '/root/{@reference}', template_resolver=resolver) ]) return resolver
def dict_to_path(data): if not data: raise SpilException('[dict_to_path] Data is empty') data = data.copy() debug('Data: {}'.format(data)) # setting defaults for key in data.keys(): if not data.get(key) and path_defaults.get(key): data[key] = path_defaults.get(key) # adding defaults subtype = get_sidtype(data) # reverse path mapping for key, value in six.iteritems(data): if key == "project": for project, project_sid in path_mapping[key].items(): if os.path.normcase(project_sid) == value: data[key] = project elif value and path_mapping.get(key): mapping = path_mapping.get(key) data[key] = utils.get_key(mapping, value) debug('sidtype: {}'.format(subtype)) pattern = path_templates.get(subtype) debug('pattern: {}'.format(pattern)) if not pattern: raise SpilException( '[dict_to_path] Unable to find pattern for sidtype: "{}" \nGiven data: "{}"' .format(subtype, data)) template = Template(subtype, pattern) template.template_resolver = resolvers debug('template: {}'.format(template)) if not template: raise SpilException('toe') # adding template specific defaults for key in template.keys(): if key not in data.keys() and path_defaults.get(key): data[key] = path_defaults.get(key) debug('data after path_defaults: {}'.format(data)) path = template.format(data) debug('found: {}'.format(path)) return path
def test_valid_parse_in_strict_mode(pattern, path, expected, template_resolver): '''Extract data in strict mode when no invalid duplicates detected.''' template = Template('test', pattern, duplicate_placeholder_mode=Template.STRICT, template_resolver=template_resolver) data = template.parse(path) assert data == expected
def test_invalid_parse_in_strict_mode(pattern, path): '''Fail to extract data in strict mode when invalid duplicates detected.''' template = Template( 'test', pattern, duplicate_placeholder_mode=Template.STRICT ) with pytest.raises(ParseError) as exception: template.parse(path) assert 'Different extracted values' in str(exception.value)
def test_invalid_parse_in_strict_mode(pattern, path, template_resolver): '''Fail to extract data in strict mode when invalid duplicates detected.''' template = Template('test', pattern, duplicate_placeholder_mode=Template.STRICT, template_resolver=template_resolver) with pytest.raises(ParseError) as exception: template.parse(path) assert 'Different extracted values' in str(exception.value)
def test_anchor(path, anchor, expected): '''Parse path with specific anchor setting.''' pattern = '/static/{variable}' template = Template('test', pattern, anchor=anchor) if not expected: with pytest.raises(ParseError): template.parse(path) else: data = template.parse(path) assert data == {'variable': 'value'}
def test_keys_mutable_side_effect(): '''Avoid side effects mutating internal keys set.''' template = Template('test', '/single/{variable}') placeholders = template.keys() assert placeholders == set(['variable']) # Mutate returned set. placeholders.add('other') # Newly returned set should be unaffected. placeholders_b = template.keys() assert placeholders_b == set(['variable'])
def register(): """Register templates.""" templates = [ # User paths Template('workspace', '{workspace}'), Template('project', '{@workspace}/{project}'), # Data paths Template('workspace_data', '{workspace}'), Template('project_data', '{@workspace_data}/{project}'), ] return templates
def path_to_dict(path): path = str(path) # path = os.path.normcase(path) path = path.replace(os.sep, '/') templates = [] for name, pattern in six.iteritems(path_templates): template = Template( name, pattern, anchor=lucidity.Template.ANCHOR_BOTH, default_placeholder_expression= '[^/]*', # needed to use '#' for a path duplicate_placeholder_mode=lucidity.Template.STRICT) template.template_resolver = resolvers templates.append(template) try: data, template = lucidity.parse(path, templates) # print 'found', data, template except Exception as e: warn(e) return None, None if not data: return None, None for key, value in six.iteritems(data): if path_mapping.get(key): value = path_mapping.get(key).get(value, value) data[key] = value for key in list(data.keys()): if key not in shot_keys + asset_keys: data.pop(key) return template.name, data # need the name ?
def sid_to_dict(sid): templates = [] for name, pattern in six.iteritems(sid_templates): template = Template( name, pattern, anchor=lucidity.Template.ANCHOR_BOTH, default_placeholder_expression= '[^/]*', # allows for empty keys // should it be '[^|]*' ? duplicate_placeholder_mode=lucidity.Template.STRICT) # template.template_resolver = resolvers templates.append(template) try: """ if len(sid.split('/')) >= 8: data = [] for ext in sid.split('/')[-1].split(','): sid_copy = sid sid_copy = sid_copy.replace(sid_copy.split('/')[-1], ext) data.extend(lucidity.parse(str(sid_copy), templates)[0]) else: """ data, template = lucidity.parse(str(sid), templates) # print 'found', data, template except Exception as e: warn(e) return None if not data: return None ''' for key in list(data.keys()): if key not in shot_keys + asset_keys: data.pop(key) ''' # return template.name, data # need the name ? return data
import os if six.PY3: import spil.vendor import lucidity from lucidity import Template from spil.libs.util import utils from spil.libs.util.exception import SpilException from spil.libs.util.log import debug, warn, info from spil.conf.fs_conf import path_templates, path_templates_reference, path_mapping, path_defaults from spil.conf.sid_conf import asset_keys, shot_keys, get_sidtype resolvers = { path_templates_reference: Template(path_templates_reference, path_templates.get(path_templates_reference)) } def path_to_dict(path): path = str(path) # path = os.path.normcase(path) path = path.replace(os.sep, '/') templates = [] for name, pattern in six.iteritems(path_templates): template = Template( name, pattern, anchor=lucidity.Template.ANCHOR_BOTH,
def test_keys(pattern, expected): '''Get keys in pattern.''' template = Template('test', pattern) placeholders = template.keys() assert sorted(placeholders) == sorted(expected)
def test_valid_pattern(pattern): '''Construct template with valid pattern.''' Template('test', pattern)
def test_missing_resolver(operation, arguments): '''Fail operations when missing resolver and using template references.''' template = Template('test', '{@reference}') with pytest.raises(ResolveError): getattr(template, operation)(*arguments)
def test_extract_placeholders(pattern, expected): '''Extract data from matching path.''' template = Template('test', pattern) placeholders = template.keys() assert sorted(placeholders) == sorted(expected)
def register(): '''注册模板''' return [ Template('job', '/jobs/{job.code}'), Template('shot', '/jobs/{job.code}/shots/{scene.code}_{shot.code}') ]
def test_matching_parse(pattern, path, expected): '''Extract data from matching path.''' template = Template('test', pattern) data = template.parse(path) assert data == expected
def register(): """Register templates.""" templates = [ # User file name Template('level_file_name', '{major_component}-{major_ver}.{minor_ver}.{extension}'), # Shot Template('levels', '{@project}/{levels}'), Template('level', '{@levels}/{level}'), Template('level_task', '{@level}/Production/{task}'), Template('level_software', '{@level_task}/{software}'), Template('level_working_dir', '{@level_software}/{working_dir}'), Template('level_major_component', ''), Template('level_minor_component', '{@level_working_dir}/{@level_file_name}'), # Data paths Template('levels_data', '{@project_data}/{levels}'), Template('level_data', '{@levels_data}/{level}'), Template('level_task_data', '{@level_data}/{task}'), Template('level_major_component_data', '{@level_task_data}/{major_component}'), Template('level_minor_component_data', '{@level_major_component_data}/{minor_component}') ] return templates
def test_format(pattern, data, expected): '''Format data against pattern.''' template = Template('test', pattern) formatted = template.format(data) assert formatted == expected
def register(): """Register templates.""" templates = [ # User file name Template('shot_file_name', '{major_component}-{major_ver}.{minor_ver}.{extension}'), # Shot Template('sequences', '{@project}/{sequences}'), Template('sequence', '{@sequences}/{sequence}'), Template('shot', '{@sequence}/{shot}'), Template('shot_task', '{@shot}/Production/{task}'), Template('shot_software', '{@shot_task}/{software}'), Template('shot_working_dir', '{@shot_software}/{working_dir}'), Template('shot_major_component', ''), Template('shot_minor_component', '{@shot_working_dir}/{@shot_file_name}'), # Data paths Template('sequences_data', '{@project_data}/{sequences}'), Template('sequence_data', '{@sequences_data}/{sequence}'), Template('shot_data', '{@sequence_data}/{shot}'), Template('shot_task_data', '{@shot_data}/{task}'), Template('shot_major_component_data', '{@shot_task_data}/{major_component}'), Template('shot_minor_component_data', '{@shot_major_component_data}/{minor_component}') ] return templates
def test_references(pattern, expected): '''Get template references in pattern.''' template = Template('test', pattern) references = template.references() assert sorted(references) == sorted(expected)
def test_deepcopy(): '''Deepcopy template.''' template = Template('test', '/single/{variable}') copied_template = copy.deepcopy(template) assert template._regex == copied_template._regex
def test_invalid_pattern(pattern): '''Construct template with invalid pattern.''' with pytest.raises(ValueError): Template('test', pattern)
def test_format_failure(pattern, data): '''Format incomplete data against pattern.''' template = Template('test', pattern) with pytest.raises(FormatError): template.format(data)
def test_non_matching_parse(pattern, path): '''Extract data from non-matching path.''' template = Template('test', pattern) with pytest.raises(ParseError): data = template.parse(path)
def test_repr(): '''Represent template.''' assert (repr(Template('test', '/foo/{bar}/{baz:\d+}')) == 'Template(name=\'test\', pattern=\'/foo/{bar}/{baz:\\\d+}\')')
def test_escaping_pattern(): '''Escape regex components in pattern.''' template = Template('test', '{filename}.{index:\d\\{4\\}}.{ext}') expected = {'filename': 'filename', 'index': '0001', 'ext': 'ext'} assert template.parse('filename.0001.ext') == expected
def test_resolver_failure(operation, arguments): '''Fail operations when resolver unable to resolver template references.''' template = Template('test', '{@reference}', template_resolver={}) with pytest.raises(ResolveError): getattr(template, operation)(*arguments)
def register(): """Register templates.""" templates = [ # User file name Template('asset_file_name', '{major_component}-{major_ver}.{minor_ver}.{extension}'), # Asset Template('asset_library', '{@project}/{asset_library}'), Template('asset_type', '{@asset_library}/{asset_type}'), Template('asset', '{@asset_type}/{asset}'), Template('asset_task', '{@asset}/Production/{task}'), Template('asset_software', '{@asset_task}/{software}'), Template('asset_working_dir', '{@asset_software}/{working_dir}'), Template('asset_major_component', ''), Template('asset_minor_component', '{@asset_working_dir}/{@asset_file_name}'), # Data paths Template('asset_library_data', '{@project_data}/{asset_library}'), Template('asset_type_data', '{@asset_library_data}/{asset_type}'), Template('asset_data', '{@asset_type_data}/{asset}'), Template('asset_task_data', '{@asset_data}/{task}'), Template('asset_major_component_data', '{@asset_task_data}/{major_component}'), Template('asset_minor_component_data', '{@asset_major_component_data}/{minor_component}') ] return templates
def register(): # Register templates. return [ Template('proj-dir', '{project}'), Template('general-dir', '{project}/general'), Template('lib-dir', '{project}/lib'), Template('episode-dir', '{project}/general/{episode}'), Template('sequence-dir', '{project}/general/{episode}/{sequence}'), Template('shot-dir', '{project}/general/{episode}/{sequence}/{shot}'), Template('shot-maya-dir', '{project}/general/{episode}/{sequence}/{shot}/maya'), Template('lib-asset-dir', '{project}/lib/asset'), Template('lib-char-dir', '{project}/lib/asset/char/{asset}'), Template('lib-char-maya-dir', '{project}/lib/asset/char/{asset}/maya'), Template('lib-envir-dir', '{project}/lib/asset/envir/{asset}'), Template('lib-envir-maya-dir', '{project}/lib/asset/envir/{asset}/maya') ]
def register(): return [ Template("project", "{project}"), # -------------------- BASIC ----------------------- Template("sequence", "{@project}/05_SEQUENCE/{sequence}"), Template("shot", "{@sequence}/{shot}"), Template("task", "{@shot}/{task_category}/{shot_task}"), Template("asset_build", "{@project}/04_ASSET/{asset_build}"), Template("ab_task", "{@asset_build}/{task_category}/{shot_task}"), # -------------------- VERSION --------------------- Template("asset_version", "{@shot}/{asset}_{asset_version}"), Template("asset_version_task", "{@task}/{asset}_{asset_version}"), Template( "asset_version_sources_seq", "{@sequence}/_INGEST/{asset_category}/{asset}_{asset_version}", ), Template( "asset_version_sources", "{@shot}/_INGEST/{asset_category}/{asset}_{asset_version}", ), Template( "asset_version_task_category", "{@task}/{asset_category}/{asset}_{asset_version}", ), Template("ab_asset_version", "{@asset_build}/{asset}_{asset_version}"), Template("ab_asset_version_task", "{@ab_task}/{asset}_{asset_version}"), Template( "ab_asset_version_task_category", "{@ab_task}/{asset_category}/{asset}_{asset_version}", ), ]