def validate_filepath(self, filepath): # type: (Union[str, Path]) -> None ''' Attempts to parse the given filepath. Args: filepath (str or Path): filepath to asset file. Raises: ValidationError: If parse fails. ValidationError: If asset directory name is invalid. ''' filepath = Path(filepath) try: data = AssetNameParser(self.filename_fields).parse(filepath.name) except ParseException as e: raise ValidationError(repr(e)) if self.asset_type == 'file': return parser = AssetNameParser(self.asset_name_fields) actual = self.get_asset_path(filepath).name try: parser.parse(actual) except ParseException as e: raise ValidationError(repr(e)) expected = parser.to_string(data) if actual != expected: msg = 'Invalid asset directory name. ' msg += f'Expecting: {expected}. Found: {actual} in ' msg += f'{filepath.as_posix()}.' raise ValidationError(msg)
def test_parse_frame_indicator(self): name = 'p-proj001_s-spec002_d-desc_v003_c0004-0005-0006_0007.exr' msg = f'Illegal frame field indicator in "{name}". Expecting: "f"' with self.assertRaisesRegexp(ParseException, msg): AssetNameParser(self.fields).parse(name) name = 'p-proj001_s-spec002_d-desc_v003_c0004-0005-0006_#0007.exr' msg = f'Illegal frame field indicator in "{name}". Expecting: "f"' with self.assertRaisesRegexp(ParseException, msg): AssetNameParser(self.fields).parse(name)
def test_parse_version_token(self): name = 'p-proj001_s-spec002_d-desc_v03_c0004-0005-0006_f0007.exr' msg = f'Illegal version field token in "{name}". Expecting: .*' with self.assertRaisesRegexp(ParseException, msg): AssetNameParser(self.fields).parse(name) name = 'p-proj001_s-spec002_d-desc_v03' msg = f'Illegal version field token in "{name}". Expecting: .*' with self.assertRaisesRegexp(ParseException, msg): AssetNameParser(self.fields[:-3]).parse(name)
def test_parse_bad_indicator(self): fields = [ 'project', 'specification', 'descriptor', 'version', 'frame', 'extension' ] name = 'p-proj002_s-spec062_f-desc_v099_f0078.exr' msg = f'Illegal descriptor field indicator in "{name}". Expecting: "d-"' with self.assertRaisesRegexp(ParseException, msg): AssetNameParser(fields).parse(name) name = 'pp-proj002_s-spec062_d-desc_v099_f0078.exr' msg = f'Illegal project field indicator in "{name}". Expecting: "p-"' with self.assertRaisesRegexp(ParseException, msg): AssetNameParser(fields).parse(name)
def get_asset_name(self, filepath): # type: (Union[str, Path]) -> str ''' Returns the expected asset name give a filepath. Args: filepath (str or Path): filepath to asset file. Returns: str: Asset name. ''' filepath = Path(filepath) data = AssetNameParser(self.filename_fields).parse(filepath.name) return AssetNameParser(self.asset_name_fields).to_string(data)
def is_descriptor(item): # type: (str) -> bool ''' Validates a descriptor. Args: item (str): Descriptor. Raises: ValidationError: If descriptor is invalid. Returns: bool: Validity of descriptor. ''' try: ind = AssetNameParser.DESCRIPTOR_INDICATOR AssetNameParser(['descriptor']).parse(ind + item) except ParseException: return False # pragma: no cover if re.search('^[a-z0-9-]+$', item) is None: return False # pragma: no cover # the mast/final/last asset is never actually that # asset should only ever be thought of in terms of latest version if re.search('^(master|final|last)', item): return False # pragma: no cover if len(item) < 1: return False # pragma: no cover return True
def test_parse_bad_order(self): fields = [ 'project', 'specification', 'descriptor', 'version', 'frame', 'extension' ] name = 's-spec062_p-proj002_v099_d-desc_f0078.exr' with self.assertRaises(ParseException): AssetNameParser(fields).parse(name)
def test_parse_2(self): fields = ['project', 'specification', 'coordinate', 'version'] name = 'p-proj002_s-spec062_c0000-0000-0000_v099' result = AssetNameParser(fields).parse(name) expected = dict(project='proj002', specification='spec062', version=99, coordinate=[0, 0, 0]) self.assertEqual(result, expected)
def test_parse_bad_token(self): fields = [ 'project', 'specification', 'descriptor', 'version', 'frame', 'extension' ] name = 'p-proj002_s-spec062_d-HELLO_v099_f0078.exr' msg = f'Illegal descriptor field token in "{name}". Expecting: .*' with self.assertRaisesRegexp(ParseException, msg): AssetNameParser(fields).parse(name)
def test_recurse_init(self): fields = [ 'project', 'specification', 'descriptor', 'version', 'frame', 'extension' ] expected = 'p-proj002_s-spec062_d-desc_v099_f0078.exr' parser = AssetNameParser(fields) result = parser.parse(expected) result = parser.to_string(result) self.assertEqual(result, expected)
def test_parse_0(self): name = 'p-proj001_s-spec002_d-desc_v003_c0004-0005-0006_f0007.exr' result = AssetNameParser(self.fields).parse(name) expected = dict(project='proj001', specification='spec002', descriptor='desc', version=3, coordinate=[4, 5, 6], frame=7, extension='exr') self.assertEqual(result, expected)
def test_parse_1(self): fields = [ 'project', 'specification', 'descriptor', 'version', 'frame', 'extension' ] name = 'p-proj002_s-spec062_d-desc_v099_f0078.exr' result = AssetNameParser(fields).parse(name) expected = dict( project='proj002', specification='spec062', descriptor='desc', version=99, frame=78, extension='exr', ) self.assertEqual(result, expected)
def test_to_string(self): fields = [ 'project', 'specification', 'descriptor', 'version', 'coordinate', 'frame', 'extension' ] metadata = dict(project='proj002', specification='spec062', descriptor='desc', version=99, coordinate=[1, 2, 3], frame=78, extension='exr', foo='bar') result = AssetNameParser(fields).to_string(metadata) expected = 'p-proj002_s-spec062_d-desc_v099_c0001-0002-0003_f0078.exr' self.assertEqual(result, expected)
def get_filename_traits(self, filepath): # type: (Union[str, Path]) -> Dict[str, Any] ''' Returns a dictionary of filename traits from given filepath. Returns error in filename_error key if one is encountered. Args: filepath (str or Path): filepath to asset file. Returns: dict: Traits. ''' try: return AssetNameParser(self.filename_fields)\ .parse(Path(filepath).name) except ParseException as e: return dict(filename_error=tools.error_to_string(e))
def is_project(item): # type: (str) -> bool ''' Validates a project name. Args: item (str): Project name. Raises: ValidationError: If project name is invalid. Returns: bool: Validity of project name. ''' try: ind = AssetNameParser.PROJECT_INDICATOR AssetNameParser(['project']).parse(ind + item) except ParseException: return False # pragma: no cover if re.search('^[a-z0-9]+$', item) is None: return False # pragma: no cover return True
def test_init(self): with self.assertRaisesRegexp(ValueError, 'Fields cannot be empty.'): AssetNameParser([]) with self.assertRaisesRegexp(ValueError, 'Fields cannot contain duplicates.'): AssetNameParser(['foo', 'foo']) with self.assertRaisesRegexp( ValueError, r"Illegal fields found: \['foo', 'bar'\]"): AssetNameParser(['project', 'specification', 'foo', 'bar']) err = 'Illegal field order: Extension field must be last if it is included in fields.' with self.assertRaisesRegexp(ValueError, err): AssetNameParser( ['project', 'specification', 'extension', 'descriptor']) fields = ['project', 'specification', 'version'] result = AssetNameParser(fields) self.assertEqual(result._fields, fields) fields = ['specification', 'version', 'project', 'frame'] result = AssetNameParser(fields) self.assertEqual(result._fields, fields)
def test_parse_descriptor_single_field(self): name = 'd-desc003' result = AssetNameParser(['descriptor']).parse(name) expected = dict(descriptor='desc003') self.assertEqual(result, expected)
def test_parse_frame_single_field(self): name = 'f0007' result = AssetNameParser(['frame']).parse(name) expected = dict(frame=7) self.assertEqual(result, expected)
def test_parse_descriptor_token(self): name = 'p-proj001_s-spec002_d-DeSC_v003_c0004-0005-0006_f0007.exr' msg = f'Illegal descriptor field token in "{name}". Expecting: .*' with self.assertRaisesRegexp(ParseException, msg): AssetNameParser(self.fields).parse(name)
def test_parse_descriptor_containing_indicators(self): name = 'p-proj001_s-spec002_d-v012-p-banana-f99_v003_c0004-0005-0006_f0007.exr' result = AssetNameParser(self.fields).parse(name)['descriptor'] expected = 'v012-p-banana-f99' self.assertEqual(result, expected)
def test_parse_version_single_field(self): name = 'v003' result = AssetNameParser(['version']).parse(name) expected = dict(version=3) self.assertEqual(result, expected)
def test_parse_coordinate_token(self): name = 'p-proj001_s-spec002_d-desc_v003_c05-06_f0007.exr' msg = f'Illegal coordinate field token in "{name}". Expecting: .*' with self.assertRaisesRegexp(ParseException, msg): AssetNameParser(self.fields).parse(name)
def test_parse_extension_uppercase(self): fields = ['descriptor', 'extension'] name = 'd-desc.EXR' expected = dict(descriptor='desc', extension='EXR') result = AssetNameParser(fields).parse(name) self.assertEqual(result, expected)
def test_parse_extension_single_field(self): name = 'exr' result = AssetNameParser(['extension']).parse(name) expected = dict(extension='exr') self.assertEqual(result, expected)
def test_parse_specification_single_field(self): name = 's-spec002' result = AssetNameParser(['specification']).parse(name) expected = dict(specification='spec002') self.assertEqual(result, expected)
def test_parse_coordinate_single_field(self): name = 'c0004-0005-0006' result = AssetNameParser(['coordinate']).parse(name) expected = dict(coordinate=[4, 5, 6]) self.assertEqual(result, expected)
def test_parse_project_single_field(self): name = 'p-proj001' result = AssetNameParser(['project']).parse(name) expected = dict(project='proj001') self.assertEqual(result, expected)