1717import itertools
1818import logging
1919import os
20- import re
2120import xml .etree .ElementTree as ET
2221from collections import defaultdict
2322from collections .abc import Mapping
3332__status__ = 'Production'
3433
3534__all__ = [
36- 'URN_CLF' , 'SEPARATOR_URN_CLF ' , 'SEPARATOR_ID_CLF' , 'NAMESPACE_CLF' ,
35+ 'URN_CLF' , 'SEPARATOR_VERSION_CLF ' , 'SEPARATOR_ID_CLF' , 'NAMESPACE_CLF' ,
3736 'TRANSFORM_TYPES_CLF' , 'TRANSFORM_FAMILIES_CLF' ,
3837 'TRANSFORM_GENUS_DEFAULT_CLF' , 'TRANSFORM_FILTERERS_DEFAULT_CLF' ,
3938 'PATTERNS_DESCRIPTION_CLF' , 'ROOT_TRANSFORMS_CLF' ,
4342 'filter_clf_transforms' , 'print_clf_taxonomy'
4443]
4544
46- URN_CLF = 'urn:aswf:ocio:transformId:v1 .0'
45+ URN_CLF = 'urn:aswf:ocio:transformId:1 .0'
4746"""
4847*CLF* Uniform Resource Name (*URN*).
4948
5049URN_CLF : unicode
5150"""
5251
53- SEPARATOR_URN_CLF = ': '
52+ SEPARATOR_VERSION_CLF = '. '
5453"""
55- *CLFtransformID* separator used to separate the *URN* and *ID* part of the
54+ *CLFtransformID* separator used to tokenize the *VERSION* parts of the
5655*CLFtransformID*.
5756
58- SEPARATOR_URN_CLF : unicode
57+ urn:aswf:ocio:transformId:1.0:OCIO:ACES:AP0_to_AP1-Gamma2pnt2:1.0
58+ |---| |---|
59+
60+ SEPARATOR_ID_CLF : unicode
5961"""
6062
61- SEPARATOR_ID_CLF = '. '
63+ SEPARATOR_ID_CLF = ': '
6264"""
6365*CLFtransformID* separator used to tokenize the *ID* part of the
6466*CLFtransformID*.
6567
66- urn:aswf:ocio:transformId:v1 .0:ACES. OCIO. AP0_to_AP1-Gamma2pnt2.c1.v1
67- |-------------URN------------ |:|-----------------ID- ---------------|
68+ urn:aswf:ocio:transformId:1 .0:OCIO:ACES: AP0_to_AP1-Gamma2pnt2:1.0
69+ |-------------URN-----------|:|----------------ID ---------------|
6870
6971SEPARATOR_ID_CLF : unicode
7072"""
7173
7274NAMESPACE_CLF = 'OCIO'
7375"""
74- *ACES* namespace for the *OCIO* *CLF* transforms.
76+ Namespace for the *OCIO* *CLF* transforms.
7577
7678NAMESPACE_CLF : unicode
7779"""
7880
7981TRANSFORM_TYPES_CLF = [
80- 'ACES' ,
81- 'Common' ,
82+ 'Utility' ,
8283]
8384"""
8485*CLF* transform types.
8586
8687TRANSFORM_TYPES_CLF : list
8788"""
8889
89- TRANSFORM_FAMILIES_CLF = {'aces ' : 'aces ' }
90+ TRANSFORM_FAMILIES_CLF = {'utility ' : 'Utility ' }
9091"""
9192*CLF* transform families mapping the *CLF* transform directories to family
9293names.
119120 os .environ .get (
120121 'OPENCOLORIO_CONFIG_ACES__CLF_TRANSFORMS_ROOT' ,
121122 os .path .join (
122- os .path .dirname (__file__ ), '..' , 'transforms' , 'builtins ' )))
123+ os .path .dirname (__file__ ), '..' , 'transforms' , 'ocio ' )))
123124"""
124125*CLF* transforms root directory, default to the version controlled
125126sub-module repository. It can be defined by setting the
@@ -457,30 +458,31 @@ def _parse(self):
457458
458459 clf_transform_id = self ._clf_transform_id
459460
460- self ._urn , components = clf_transform_id .rsplit (SEPARATOR_URN_CLF , 1 )
461- components = components .split (SEPARATOR_ID_CLF )
462- self ._type , components = components [0 ], components [1 :]
463-
464- assert self ._urn == URN_CLF , (
461+ assert clf_transform_id .startswith (URN_CLF ), (
465462 f'{ self ._clf_transform_id } URN { self ._urn } is invalid!' )
466463
467- assert len (components ) in (4 , 5 ), (
464+ self ._urn = clf_transform_id [:len (URN_CLF ) + 1 ]
465+ components = clf_transform_id [len (URN_CLF ) + 1 :]
466+ components = components .split (SEPARATOR_ID_CLF )
467+
468+ assert len (components ) == 4 , (
468469 f'{ self ._clf_transform_id } is an invalid "CLFtransformID"!' )
469470
470- if len (components ) == 4 :
471- (self ._namespace , self ._name , self ._major_version_number ,
472- self ._minor_version_number ) = components
473- else :
474- (self ._namespace , self ._name , self ._major_version_number ,
475- self ._minor_version_number ,
476- self ._patch_version_number ) = components
471+ (self ._namespace , self ._type , self ._name , version ) = components
477472
478473 assert self ._type in TRANSFORM_TYPES_CLF , (
479474 f'{ self ._clf_transform_id } type { self ._type } is invalid!' )
480475
481476 if self ._name is not None :
482477 self ._source , self ._target = self ._name .split ('_to_' )
483478
479+ assert version .count (SEPARATOR_VERSION_CLF ) == 1 , (
480+ f'{ self ._clf_transform_id } has an invalid "CLFtransformID" '
481+ f'version!' )
482+
483+ (self ._major_version_number ,
484+ self ._minor_version_number ) = version .split (SEPARATOR_VERSION_CLF )
485+
484486
485487class CLFTransform :
486488 """
@@ -503,6 +505,8 @@ class CLFTransform:
503505 clf_transform_id
504506 user_name
505507 description
508+ input_descriptor
509+ output_descriptor
506510 family
507511 genus
508512
@@ -521,6 +525,8 @@ def __init__(self, path, family=None, genus=None):
521525 self ._clf_transform_id = None
522526 self ._user_name = None
523527 self ._description = ''
528+ self ._input_descriptor = ''
529+ self ._output_descriptor = ''
524530
525531 self ._family = family
526532 self ._genus = genus
@@ -641,6 +647,52 @@ def description(self):
641647
642648 return self ._description
643649
650+ @property
651+ def input_descriptor (self ):
652+ """
653+ Getter and setter property for the *CLF* transform input descriptor
654+ extracted from parsing the file content header.
655+
656+ Parameters
657+ ----------
658+ value : unicode
659+ Attribute value.
660+
661+ Returns
662+ -------
663+ unicode
664+ *CLF* transform input descriptor.
665+
666+ Notes
667+ -----
668+ - This property is read only.
669+ """
670+
671+ return self ._input_descriptor
672+
673+ @property
674+ def output_descriptor (self ):
675+ """
676+ Getter and setter property for the *CLF* transform output descriptor
677+ extracted from parsing the file content header.
678+
679+ Parameters
680+ ----------
681+ value : unicode
682+ Attribute value.
683+
684+ Returns
685+ -------
686+ unicode
687+ *CLF* transform output descriptor.
688+
689+ Notes
690+ -----
691+ - This property is read only.
692+ """
693+
694+ return self ._output_descriptor
695+
644696 @property
645697 def family (self ):
646698 """
@@ -785,10 +837,21 @@ def _parse(self):
785837
786838 self ._clf_transform_id = CLFTransformID (root .attrib ['id' ])
787839 self ._user_name = root .attrib ['name' ]
840+
788841 description = next (iter (root .findall ('./Description' )), None )
789842 if description is not None :
790843 self ._description = description .text
791844
845+ input_descriptor = next (
846+ iter (root .findall ('./InputDescriptor' )), None )
847+ if input_descriptor is not None :
848+ self ._input_descriptor = input_descriptor .text
849+
850+ output_descriptor = next (
851+ iter (root .findall ('./OutputDescriptor' )), None )
852+ if output_descriptor is not None :
853+ self ._output_descriptor = output_descriptor .text
854+
792855
793856class CLFTransformPair :
794857 """
@@ -965,9 +1028,7 @@ def stem(path):
9651028 # to define which transform is the forward transform.
9661029 paths = defaultdict (list )
9671030 for clf_transform in sorted (clf_transforms , key = stem ):
968- forward_path = tuple (
969- re .split ('_to_' ,
970- stem (clf_transform ).split ('.' , 2 )[- 1 ]))
1031+ forward_path = tuple (stem (clf_transform ).split ('_to_' , 1 ))
9711032 inverse_path = tuple (reversed (forward_path ))
9721033 if inverse_path in paths :
9731034 paths [inverse_path ].append (clf_transform )
@@ -1012,9 +1073,10 @@ def discover_clf_transforms(root_directory=ROOT_TRANSFORMS_CLF):
10121073 >>> clf_transforms = discover_clf_transforms()
10131074 >>> key = sorted(clf_transforms.keys())[0]
10141075 >>> os.path.basename(key)
1015- 'aces '
1076+ 'utility '
10161077 >>> sorted([os.path.basename(path) for path in clf_transforms[key]])[:2]
1017- ['ACES.OCIO.AP0_to_AP1-Gamma2.2.clf', 'ACES.OCIO.AP0_to_P3-D65.clf']
1078+ ['OCIO.Utility.AP0_to_AP1-Gamma2.2.clf', \
1079+ 'OCIO.Utility.AP0_to_P3-D65-Linear.clf']
10181080 """
10191081
10201082 root_directory = os .path .normpath (os .path .expandvars (root_directory ))
@@ -1071,24 +1133,28 @@ def classify_clf_transforms(unclassified_clf_transforms):
10711133 ... discover_clf_transforms())
10721134 >>> family = sorted(clf_transforms.keys())[0]
10731135 >>> str(family)
1074- 'aces '
1136+ 'Utility '
10751137 >>> genera = sorted(clf_transforms[family])
10761138 >>> print(genera)
10771139 ['undefined']
10781140 >>> genus = genera[0]
10791141 >>> sorted(clf_transforms[family][genus].items())[:2] # doctest: +ELLIPSIS
1080- [('ACES. OCIO.AP0_to_AP1-Gamma2.2', \
1081- CLFTransform('aces ...ACES. OCIO.AP0_to_AP1-Gamma2.2.clf')), \
1082- ('ACES. OCIO.AP0_to_P3-D65', \
1083- CLFTransform('aces ...ACES. OCIO.AP0_to_P3-D65.clf'))]
1142+ [('OCIO.Utility .AP0_to_AP1-Gamma2.2', \
1143+ CLFTransform('utility ...OCIO.Utility .AP0_to_AP1-Gamma2.2.clf')), \
1144+ ('OCIO.Utility. AP0_to_P3-D65-Linear ', \
1145+ CLFTransform('utility ...OCIO.Utility. AP0_to_P3-D65-Linear .clf'))]
10841146 """
10851147
10861148 classified_clf_transforms = defaultdict (lambda : defaultdict (dict ))
10871149
10881150 root_directory = paths_common_ancestor (
10891151 * itertools .chain .from_iterable (unclassified_clf_transforms .values ()))
10901152 for directory , clf_transforms in unclassified_clf_transforms .items ():
1091- sub_directory = directory .replace (f'{ root_directory } { os .sep } ' , '' )
1153+ if directory == root_directory :
1154+ sub_directory = os .path .basename (root_directory )
1155+ else :
1156+ sub_directory = directory .replace (f'{ root_directory } { os .sep } ' , '' )
1157+
10921158 family , * genus = [
10931159 TRANSFORM_FAMILIES_CLF .get (part , part )
10941160 for part in sub_directory .split (os .sep )
@@ -1149,7 +1215,7 @@ def unclassify_clf_transforms(classified_clf_transforms):
11491215 ... discover_clf_transforms())
11501216 >>> sorted( # doctest: +ELLIPSIS
11511217 ... unclassify_clf_transforms(clf_transforms), key=lambda x: x.path)[0]
1152- CLFTransform('aces ...ACES. OCIO.AP0_to_AP1-Gamma2.2.clf')
1218+ CLFTransform('utility ...OCIO.Utility .AP0_to_AP1-Gamma2.2.clf')
11531219 """
11541220
11551221 unclassified_clf_transforms = []
@@ -1202,9 +1268,9 @@ def filter_clf_transforms(clf_transforms, filterers=None):
12021268 >>> sorted( # doctest: +ELLIPSIS
12031269 ... filter_clf_transforms(
12041270 ... clf_transforms,
1205- ... [lambda x: x.family == 'common ']),
1271+ ... [lambda x: x.family == 'Utility ']),
12061272 ... key=lambda x: x.path)[0]
1207- CLFTransform('common ...Common. OCIO.Linear_to_Rec1886 .clf')
1273+ CLFTransform('utility ...OCIO.Utility.AP0_to_AP1-Gamma2.2 .clf')
12081274 """
12091275
12101276 if filterers is None :
0 commit comments