2 To use, make sure that pyJsonAttrPatternFactory.py is in your MAYA_PLUG_IN_PATH 
    6 maya.cmds.loadPlugin("pyJsonAttrPatternFactory.py") 
    7 maya.cmds.listAttrPatterns(patternType=True) 
   14 import maya.api.OpenMaya 
as omAPI
 
   21     Equivalent to these import statements but presuming installation into 
   22     a utils/ subdirectory of the current directory that's not in the current 
   25         from pyJsonAttrPatternInfo import PyJsonAttrPatternInfo as JsonKeys 
   26         from pyJsonAttrPatternInfo import jsonDebug as jsonDebug 
   28     The method is set up to still work even if the module path was already 
   29     visible in the PYTHONPATH so there's no harm in setting it. 
   31     Calling this twice will force re-import of the modules; that's a good 
   32     thing for testing since you can unload the plug-in, load it back in and 
   33     it will pick up the modified modules. 
   44     location = os.environ[
'MAYA_LOCATION']
 
   45     moduleDir = os.path.join( location, 
'devkit', 
'plug-ins', 
'scripted', 
'modules' )
 
   46     sys.path.append(moduleDir)
 
   49     module = __import__(
'pyJsonAttrPatternInfo', globals(), locals(), [
"PyJsonAttrPatternInfo", 
"jsonDebug"], -1)
 
   53     JsonKeys = module.PyJsonAttrPatternInfo
 
   54     jsonDebug = module.jsonDebug
 
   62     The presence of this function tells Maya that the plugin produces, and 
   63     expects to be passed, objects created using the Maya Python API 2.0. 
   68 class PyJsonAttrPatternFactory(omAPI.MPxAttributePatternFactory):
 
   71         omAPI.MPxAttributePatternFactory.__init__(self)
 
   72         self.currentPattern = 
None 
   73         self.currentAttribute = 
None 
   77     def patternFactoryCreator():
 
   78         return PyJsonAttrPatternFactory()
 
   81     def reportWarning(self, warningStr):
 
   83         Report a pattern parsing problem but do not raise a failure exception. 
   84         This is for harmless errors that may or may not indicate a problem 
   85         (e.g. a misspelled flag name) 
   87         print 'WARN: Pattern %s, attribute %s: %s' % (self.currentPattern, self.currentAttribute, warningStr)
 
   90     def reportError(self, errorStr):
 
   92         Report a pattern parsing error and raise a failure exception. 
   93         Unfortunately there doesn't seem to be any way to report the actual 
   94         line of the definition that failed (when it could be known) so 
   95         the pattern name and attribute name will have to suffice to narrow 
   96         down the source of the error. 
   98         traceback.print_stack()
 
   99         raise ValueError( 
'ERR: Pattern %s, attribute %s: %s' % (self.currentPattern, self.currentAttribute, errorStr) )
 
  102     def parseStandardFlags(self, attr, flags):
 
  104         Apply the JSON-described flags to the given attributes. Only check the 
  105         flags understood by all attribute types; let specific types handle 
  106         their own particular flags. 
  107             attr = Created attribute object 
  108             flags = Array of flags to set 
  110         jsonDebug( 
'Parsing %d standard flags for "%s"' % (len(flags), str(attr)) )
 
  113             strippedFlag = flag.strip().rstrip()
 
  115             if strippedFlag.startswith(
'!'):
 
  116                 strippedFlag = strippedFlag[1:]
 
  120             if strippedFlag.lower() 
in [x.lower() 
for x 
in JsonKeys.kFlagFunctions]:
 
  122                     jsonDebug( 
'--- Set flag %s' % strippedFlag )
 
  123                     jsonDebug( 
'--- Flag function = %s, value = %s' % ( JsonKeys.kFlagFunctions[strippedFlag.lower()], valueToSet ) )
 
  124                     setattr( attr, JsonKeys.kFlagFunctions[strippedFlag.lower()], valueToSet )
 
  126                     self.reportError( 
'Failed setting flag %s on attribute %s : %s"' % (strippedFlag, attr.name, str(e)) )
 
  128                 self.reportWarning( 
'Unrecognized attribute flag "%s" is ignored' % strippedFlag )
 
  131     def parseCompoundAttribute(self, name, shortName, attrInfo):
 
  133         Given a JSON subsection describing a compound attribute create the 
  134         attribute and all children, and set all of the provided flags/members 
  136             name = Attribute long name 
  137             shortName = Attribute short name 
  138             attrInfo = JSON object containing the main attribute information 
  140         jsonDebug( 
'parseCompoundAttribute(%s : %s)' % (name, attrInfo) )
 
  143             cAttr = omAPI.MFnCompoundAttribute()
 
  144             attr = cAttr.create( name, shortName )
 
  147             if JsonKeys.kKeyChildren 
in attrInfo:
 
  148                 childInfo = attrInfo[JsonKeys.kKeyChildren]
 
  149                 tmpAttr = self.currentAttribute
 
  150                 for child 
in childInfo:
 
  151                     jsonDebug( 
'Add compound child %s' % child )
 
  152                     childAttr = self.parseAttribute( child )
 
  153                     cAttr.addChild( childAttr )
 
  154                 self.currentAttribute = tmpAttr
 
  156             self.reportError( 
'Error creating compound: %s' % str(e) )
 
  160     def parseEnumAttribute(self, name, shortName, attrInfo):
 
  162         Given a JSON subsection describing an enum attribute create the 
  163         attribute and set all of the provided flags/members for it. 
  164             name = Attribute long name 
  165             shortName = Attribute short name 
  166             attrInfo = JSON object containing the main attribute information 
  168         jsonDebug( 
'parseEnumAttribute(%s)' % name )
 
  169         eAttr = omAPI.MFnEnumAttribute()
 
  170         attr = eAttr.create( name, shortName )
 
  174         if JsonKeys.kKeyEnumNames 
in attrInfo:
 
  177                 for enumName 
in attrInfo[JsonKeys.kKeyEnumNames]:
 
  178                     equalSign = enumName.find(
'=')
 
  180                         enumIndex = int(enumName[equalSign+1:])
 
  181                         enumName = enumName[:equalSign]
 
  182                     eAttr.addField( enumName, enumIndex )
 
  185                 self.reportError( 
'Bad enum specification: "%s"' % str(e) )
 
  189         if JsonKeys.kKeyDefault 
in attrInfo:
 
  190             defaultValue = attrInfo[JsonKeys.kKeyDefault]
 
  191             jsonDebug( 
'Setting the enum default to "%s" of type %s' % (defaultValue, type(defaultValue)) )
 
  192             if type(defaultValue) == int 
or str(defaultValue).isdigit():
 
  193                 eAttr.default = defaultValue
 
  195                 eAttr.setDefaultByName( defaultValue )
 
  200     def parseTypedAttribute(self, name, shortName, attrInfo):
 
  202         Given a JSON subsection describing a typed attribute create the 
  203         attribute and set all of the provided flags/members for it. 
  204             name = Attribute long name 
  205             shortName = Attribute short name 
  206             attrInfo = JSON object containing the main attribute information 
  208         jsonDebug( 
'parseTypedAttribute(%s)' % name )
 
  212         acceptedTypeEnums = []
 
  213         acceptedNumericEnums = []
 
  214         acceptedPluginTypes = []
 
  219         if JsonKeys.kKeyAcceptedPluginTypes 
in attrInfo:
 
  220             jsonDebug( 
'...getting accepted plugin types %s' % attrInfo[JsonKeys.kKeyAcceptedPluginTypes] )
 
  221             for pluginId 
in attrInfo[JsonKeys.kKeyAcceptedPluginTypes]:
 
  222                 pId = omAPI.MTypeId()
 
  223                 acceptedPluginTypes.append( pId.create( int(pluginId) ) )
 
  224         if JsonKeys.kKeyAcceptedTypes 
in attrInfo:
 
  225             if 'any' in attrInfo[JsonKeys.kKeyAcceptedTypes]:
 
  226                 acceptedTypeEnums.append( omAPI.MFnData.kAny )
 
  228                 for typeName 
in attrInfo[JsonKeys.kKeyAcceptedTypes]:
 
  229                     if typeName == 
'numeric':
 
  231                         acceptedTypeEnums.append( JsonKeys.kGenericTypes[typeName] )
 
  232                     elif typeName 
in JsonKeys.kGenericTypes:
 
  233                         jsonDebug( 
'...getting accepted generic %s' % JsonKeys.kGenericTypes[typeName] )
 
  234                         acceptedTypeEnums.append( JsonKeys.kGenericTypes[typeName] )
 
  236                         self.reportError( 
'Bad type name specification: "%s"' % str(typeName) )
 
  237         if JsonKeys.kKeyAcceptedNumericTypes 
in attrInfo:
 
  238             for typeName 
in attrInfo[JsonKeys.kKeyAcceptedNumericTypes]:
 
  239                 if typeName 
in JsonKeys.kNumericTypes:
 
  240                     jsonDebug( 
'...getting accepted numeric %s' % JsonKeys.kNumericTypes[typeName] )
 
  241                     acceptedNumericEnums.append( JsonKeys.kNumericTypes[typeName] )
 
  243                     self.reportError( 
'Bad numeric type name specification: "%s"' % str(typeName) )
 
  246         if len(acceptedTypeEnums) == 0 
and len(acceptedNumericEnums) == 0 
and len(acceptedPluginTypes) == 0:
 
  247             self.reportError( 
'Need at least one accepted type' )
 
  250         elif len(acceptedTypeEnums) == 1 
and len(acceptedNumericEnums) == 0 
and len(acceptedPluginTypes) == 0 
and not hasNumeric:
 
  251             jsonDebug( 
'--- Accepts only one type : %s' % acceptedTypeEnums[0] )
 
  252             tAttr = omAPI.MFnTypedAttribute()
 
  253             attr = tAttr.create( name, shortName, acceptedTypeEnums[0] )
 
  254             jsonDebug( 
'--- created' )
 
  256         elif len(acceptedTypeEnums) == 0 
and len(acceptedNumericEnums) == 0 
and len(acceptedPluginTypes) == 1:
 
  257             jsonDebug( 
'--- Accepts only one plugin : %s' % acceptedPluginTypes[0] )
 
  258             tAttr = omAPI.MFnTypedAttribute()
 
  259             attr = tAttr.create( name, shortName, acceptedPluginTypes[0] )
 
  260             jsonDebug( 
'--- created' )
 
  263             jsonDebug( 
'--- Accepts multiple or base numeric types' )
 
  264             tAttr = omAPI.MFnGenericAttribute()
 
  265             attr = tAttr.create( name, shortName )
 
  266             for typeEnum 
in acceptedTypeEnums:
 
  267                 jsonDebug( 
'--> add data type %s' % typeEnum )
 
  268                 tAttr.addDataType( typeEnum )
 
  269             for numericEnum 
in acceptedNumericEnums:
 
  270                 jsonDebug( 
'--> add numeric type %s' % numericEnum )
 
  271                 tAttr.addNumericType( numericEnum )
 
  272             for pluginId 
in acceptedPluginTypes:
 
  273                 jsonDebug( 
'--> add plugin type %s' % pluginId )
 
  274                 tAttr.addTypeId( pluginId )
 
  275             jsonDebug( 
'--- created' )
 
  280     def parseLightDataAttribute(self, name, shortName, attrInfo):
 
  282         Given a JSON subsection describing a light data attribute create the 
  283         attribute and set all of the provided flags/members for it. 
  284             name = Attribute long name 
  285             shortName = Attribute short name 
  286             attrInfo = JSON object containing the main attribute information 
  289         cNames =  [ 
'direction', 
'intensity', 
'ambient', 
'diffuse', 
'specular',
 
  290                     'shadowFraction', 
'preShadowIntensity', 
'blindData' ]
 
  291         lightChildren = { cNames[0] : (omAPI.MFnNumericData.k3Float,  [0.0,0.0,0.0]),
 
  292                           cNames[1] : (omAPI.MFnNumericData.k3Float,  [0.0,0.0,0.0]),
 
  293                           cNames[2] : (omAPI.MFnNumericData.kBoolean, 0),
 
  294                           cNames[3] : (omAPI.MFnNumericData.kBoolean, 0),
 
  295                           cNames[4] : (omAPI.MFnNumericData.kBoolean, 0),
 
  296                           cNames[5] : (omAPI.MFnNumericData.kFloat,   0.0),
 
  297                           cNames[6] : (omAPI.MFnNumericData.kFloat,   0.0),
 
  298                           cNames[7] : (omAPI.MFnNumericData.kAddr,    0) }
 
  300         jsonDebug( 
'parseLightDataAttribute(%s)' % name )
 
  301         ldAttr = omAPI.MFnLightDataAttribute()
 
  308                 jsonDebug( 
'Creating light data child %s' % child )
 
  309                 childInfo = attrInfo[child]
 
  310                 cName = childInfo[JsonKeys.kKeyName]
 
  311                 jsonDebug( 
'--- child name %s' % cName )
 
  312                 if JsonKeys.kKeyShortName 
in childInfo:
 
  313                     cShortName = childInfo[JsonKeys.kKeyShortName]
 
  316                 jsonDebug( 
'--- child short name %s' % cShortName )
 
  317                 if JsonKeys.kKeyDefault 
in childInfo 
and child != 
'blindData':
 
  318                     jsonDebug( 
'--- Defining a default' )
 
  319                     defaultValues.append( childInfo[JsonKeys.kKeyDefault] )
 
  321                     jsonDebug( 
'--- Accepting default 0' )
 
  322                     defaultValues.append( lightChildren[child][1] )
 
  323                 jsonDebug( 
'--- child default %s' % defaultValues[-1] )
 
  325                 nAttr = omAPI.MFnNumericAttribute()
 
  326                 jsonDebug( 
'--- created numeric type %s' % lightChildren[child][0] )
 
  327                 ldChildren.append( nAttr.create( cName, cShortName, lightChildren[child][0] ) )
 
  329                 jsonDebug( 
'Missing data for sub-attribute %s : %s' % (child, str(e)) )
 
  330                 missingNames.append( child )
 
  332         if len(missingNames) > 0:
 
  333             self.reportError( 
'Not all required subattribute names are present. Add %s' % str(missingNames) )
 
  336         jsonDebug( 
'Creating master light data attribute' )
 
  337         attr = ldAttr.create( name, shortName,
 
  338                               ldChildren[0], ldChildren[1], ldChildren[2],
 
  339                               ldChildren[3], ldChildren[4], ldChildren[5],
 
  340                               ldChildren[6], ldChildren[7] )
 
  341         jsonDebug( 
'Setting master light data defaults' )
 
  342         ldAttr.default = defaultValues
 
  347     def parseMessageAttribute(self, name, shortName, attrInfo):
 
  349         Given a JSON subsection describing a message attribute create the 
  350         attribute and set all of the provided flags/members for it. 
  351             name = Attribute long name 
  352             shortName = Attribute short name 
  353             attrInfo = JSON object containing the main attribute information 
  355         jsonDebug( 
'parseMessageAttribute(%s)' % name )
 
  356         mAttr = omAPI.MFnMessageAttribute()
 
  358         jsonDebug( 
'Creating message attribute' )
 
  359         attr = mAttr.create( name, shortName )
 
  364     def parseStringAttribute(self, name, shortName, attrInfo):
 
  366         Given a JSON subsection describing a string attribute create the 
  367         attribute and set all of the provided flags/members for it. 
  368             name = Attribute long name 
  369             shortName = Attribute short name 
  370             attrInfo = JSON object containing the main attribute information 
  372         jsonDebug( 
'parseStringAttribute(%s)' % name )
 
  373         sAttr = omAPI.MFnTypedAttribute()
 
  375         if JsonKeys.kKeyDefault 
in attrInfo:
 
  376             jsonDebug( 
'Setting the string default to "%s"' % attrInfo[JsonKeys.kKeyDefault] )
 
  377             sDefault = omAPI.MFnStringData()
 
  378             defaultValue = sDefault.create( attrInfo[JsonKeys.kKeyDefault] )
 
  379             attr = sAttr.create( name, shortName, omAPI.MFnData.kString, defaultValue )
 
  381             jsonDebug( 
'Creating string attribute with no default' )
 
  382             attr = sAttr.create( name, shortName, omAPI.MFnData.kString )
 
  387     def parseMatrixAttribute(self, name, shortName, attrInfo):
 
  389         Given a JSON subsection describing a matrix attribute create the 
  390         attribute and set all of the provided flags/members for it. 
  391             name = Attribute long name 
  392             shortName = Attribute short name 
  393             attrInfo = JSON object containing the main attribute information 
  395         jsonDebug( 
'parseMatrixAttribute(%s)' % name )
 
  397         matrixType = JsonKeys.kTypeMatrixTypes[attrInfo[JsonKeys.kKeyAttrType]]
 
  398         if JsonKeys.kKeyDefault 
in attrInfo:
 
  399             jsonDebug( 
'Setting the matrix default to "%s"' % attrInfo[JsonKeys.kKeyDefault] )
 
  400             mDefault = omAPI.MFnMatrixData()
 
  401             defaultValue = mDefault.create( omAPI.MMatrix(attrInfo[JsonKeys.kKeyDefault]) )
 
  402             mAttr = omAPI.MFnMatrixAttribute( defaultValue )
 
  403             attr = mAttr.create( name, shortName, matrixType )
 
  405             jsonDebug( 
'Creating matrix attribute with no default' )
 
  406             mAttr = omAPI.MFnMatrixAttribute()
 
  407             attr = mAttr.create( name, shortName, matrixType )
 
  412     def parseNumericAttribute(self, name, shortName, numericType, attrInfo):
 
  414         Given a JSON subsection describing a numeric attribute create the 
  415         attribute and set all of the provided flags/members for it. 
  416             name = Attribute long name 
  417             shortName = Attribute short name 
  419             attrInfo = JSON object containing the main attribute information 
  421         jsonDebug( 
'parseNumericAttribute(%s, type=%s)' % (name, type) )
 
  423         if numericType 
in [ 
'angle', 
'distance', 
'time' ]:
 
  424             jsonDebug( 
'... unit attribute type being set up' )
 
  425             nAttr = omAPI.MFnUnitAttribute()
 
  427             jsonDebug( 
'... regular numeric attribute type being set up' )
 
  428             nAttr = omAPI.MFnNumericAttribute()
 
  430         jsonDebug( 
'Creating numeric attribute' )
 
  431         attr = nAttr.create( name, shortName, JsonKeys.kNumericTypes[numericType] )
 
  432         jsonDebug( 
'...creation succeeded' )
 
  433         if JsonKeys.kKeyDefault 
in attrInfo:
 
  434             defaultValue = attrInfo[JsonKeys.kKeyDefault]
 
  435             jsonDebug( 
'...setting numeric default to %s - it is a %s' % (str(defaultValue), type(defaultValue)) )
 
  436             if type(defaultValue) == list:
 
  438                 jsonDebug( 
'...converting to tuple %s' % str(tuple(defaultValue)) )
 
  439                 nAttr.default = tuple(defaultValue)
 
  441                 nAttr.default = defaultValue
 
  443         jsonDebug( 
'Setting range information on attribute' )
 
  446         if JsonKeys.kKeyMin 
in attrInfo:
 
  447             jsonDebug( 
'...setting minimum' )
 
  448             if type(attrInfo[JsonKeys.kKeyMin]) == list:
 
  451                 jsonDebug( 
'...converting list %s to tuple' % attrInfo[JsonKeys.kKeyMin] )
 
  452                 nAttr.setMin( tuple(attrInfo[JsonKeys.kKeyMin]) )
 
  454                 jsonDebug( 
'...using %s as-is' % attrInfo[JsonKeys.kKeyMin] )
 
  455                 nAttr.setMin( attrInfo[JsonKeys.kKeyMin] )
 
  457         if JsonKeys.kKeyMax 
in attrInfo:
 
  458             jsonDebug( 
'...setting maximum' )
 
  459             if type(attrInfo[JsonKeys.kKeyMax]) == list:
 
  462                 jsonDebug( 
'...converting list %s to tuple' % attrInfo[JsonKeys.kKeyMax] )
 
  463                 nAttr.setMax( tuple(attrInfo[JsonKeys.kKeyMax]) )
 
  465                 jsonDebug( 
'...using %s as-is' % attrInfo[JsonKeys.kKeyMax] )
 
  466                 nAttr.setMax( attrInfo[JsonKeys.kKeyMax] )
 
  468         if JsonKeys.kKeySoftMin 
in attrInfo:
 
  469             jsonDebug( 
'...setting soft minimum to %s' % attrInfo[JsonKeys.kKeySoftMin] )
 
  470             nAttr.setSoftMin( attrInfo[JsonKeys.kKeySoftMin] )
 
  472         if JsonKeys.kKeySoftMax 
in attrInfo:
 
  473             jsonDebug( 
'...setting soft maximum to %s' % attrInfo[JsonKeys.kKeySoftMax] )
 
  474             nAttr.setSoftMax( attrInfo[JsonKeys.kKeySoftMax] )
 
  476         jsonDebug( 
'Numeric attribute creation of "%s" complete' % attr )
 
  480     def parseAttribute(self, jsonInfo):
 
  482         Create an attribute using the JSON parameters to decode the structure 
  483         and values for the attribute. If the attribute is a compound then this 
  484         method will be recursively called so as to create the entire attribute 
  486             jsonInfo = JSON object containing the attribute's information 
  487         Returns the newly created attribute. 
  489         if JsonKeys.kKeyName 
not in jsonInfo:
 
  490             self.reportError( 
'Missing attribute name' )
 
  491         self.currentAttribute = jsonInfo[JsonKeys.kKeyName]
 
  492         jsonDebug( 
'parseAttribute(%s)' % str(jsonInfo) )
 
  496         if JsonKeys.kKeyShortName 
in jsonInfo:
 
  497             shortName = jsonInfo[JsonKeys.kKeyShortName]
 
  499             shortName = self.currentAttribute
 
  500         jsonDebug( 
'...got short name %s' % shortName )
 
  506         if JsonKeys.kKeyAttrType 
not in jsonInfo:
 
  507             self.reportError(
'Required keyword "%s" missing' % JsonKeys.kKeyAttrType)
 
  508         elif jsonInfo[JsonKeys.kKeyAttrType] 
in JsonKeys.kNumericTypes:
 
  509             attr = self.parseNumericAttribute( self.currentAttribute, shortName, jsonInfo[JsonKeys.kKeyAttrType], jsonInfo )
 
  510         elif jsonInfo[JsonKeys.kKeyAttrType] == JsonKeys.kTypeCompound:
 
  511             attr = self.parseCompoundAttribute( self.currentAttribute, shortName, jsonInfo )
 
  512         elif jsonInfo[JsonKeys.kKeyAttrType] == JsonKeys.kTypeEnum:
 
  513             attr = self.parseEnumAttribute( self.currentAttribute, shortName, jsonInfo )
 
  514         elif jsonInfo[JsonKeys.kKeyAttrType] == JsonKeys.kTypeString:
 
  515             attr = self.parseStringAttribute( self.currentAttribute, shortName, jsonInfo )
 
  516         elif jsonInfo[JsonKeys.kKeyAttrType] 
in JsonKeys.kTypeMatrix:
 
  517             attr = self.parseMatrixAttribute( self.currentAttribute, shortName, jsonInfo )
 
  518         elif jsonInfo[JsonKeys.kKeyAttrType] == JsonKeys.kTypeTyped:
 
  519             attr = self.parseTypedAttribute( self.currentAttribute, shortName, jsonInfo )
 
  520         elif jsonInfo[JsonKeys.kKeyAttrType] == JsonKeys.kTypeLightData:
 
  521             attr = self.parseLightDataAttribute( self.currentAttribute, shortName, jsonInfo )
 
  522         elif jsonInfo[JsonKeys.kKeyAttrType] == JsonKeys.kTypeMessage:
 
  523             attr = self.parseMessageAttribute( self.currentAttribute, shortName, jsonInfo )
 
  525             self.reportError( 
'Unknown attribute type "%s"' % jsonInfo[JsonKeys.kKeyAttrType] )
 
  528         jsonDebug( 
'Done creating attribute "%s", now setting shared parameters' % str(attr) )
 
  533         aBase = omAPI.MFnAttribute( attr )
 
  534         jsonDebug( 
'...handling common attribute flags for "%s"' % str(aBase) )
 
  537         if JsonKeys.kKeyFlags 
in jsonInfo:
 
  538             self.parseStandardFlags( aBase, jsonInfo[JsonKeys.kKeyFlags] )
 
  541         if JsonKeys.kKeyNiceName 
in jsonInfo:
 
  542             jsonDebug( 
'...Overriding nice name with "%s"' % jsonInfo[JsonKeys.kKeyNiceName] )
 
  543             aBase.setNiceNameOverride( jsonInfo[JsonKeys.kKeyNiceName] )
 
  546         if JsonKeys.kKeyCategories 
in jsonInfo:
 
  547             for category 
in jsonInfo[JsonKeys.kKeyCategories]:
 
  548                 jsonDebug( 
'...Adding category "%s"' % category )
 
  549                 aBase.addToCategory( category )
 
  550                 jsonDebug( 
'...Done on category "%s"' % category )
 
  551         jsonDebug( 
'...Done the categories' )
 
  554         if JsonKeys.kKeyDisconnect 
in jsonInfo:
 
  555             behavior = jsonInfo[JsonKeys.kKeyDisconnect]
 
  556             jsonDebug( 
'...Setting disconnect behaviour to "%s"' % behavior )
 
  557             if behavior 
in JsonKeys.kDisconnectBehaviors:
 
  558                 aBase.disconnectBehavior = JsonKeys.kDisconnectBehaviors[behavior]
 
  560                 self.reportError( 
'Unknown behavior type "%s"' % behavior )
 
  565     def parseJsonPatterns(self, jsonObj):
 
  567         The workhorse method. Takes the JSON Python object and deconstructs it 
  568         into one or more pattern descriptions and returns them. 
  570         If any of the patterns fail to create an exception is raised. 
  571             ValueError : When the JSON text is not valid 
  572             ValueError : When the pattern name already exists 
  576             jsonDebug( 
'parseJsonPatterns(%d patterns)' % len(jsonObj) )
 
  577             for thisPattern 
in jsonObj:
 
  578                 jsonDebug( 
'...Pattern is %s' % thisPattern )
 
  579                 if JsonKeys.kKeyName 
not in thisPattern:
 
  580                     self.reportError( 
'Missing pattern name' )
 
  582                 self.currentPattern = thisPattern[JsonKeys.kKeyName]
 
  583                 newPattern = omAPI.MAttributePattern( self.currentPattern )
 
  584                 jsonDebug( 
'...Pattern %s has %d attributes' % (self.currentPattern, len(thisPattern[
"attributes"])) )
 
  585                 if "attributes" not in thisPattern:
 
  586                     self.reportError( 
'Empty attribute list' )
 
  588                 for thisAttribute 
in thisPattern[
"attributes"]:
 
  589                     jsonDebug(
'Started parsing attribute "%s"' % str(thisAttribute))
 
  590                     attr = self.parseAttribute( thisAttribute )
 
  591                     jsonDebug(
'Completed parsing of attribute "%s"' % str(attr))
 
  595                     newPattern.addRootAttr(attr)
 
  596                     jsonDebug( 
'Done adding the attribute to the pattern' )
 
  597                 patternList.append( newPattern )
 
  599             self.reportError( e )
 
  603     def createPatternsFromString(self, definition):
 
  605         Decode the input string from JSON format and create a set of 
  606         patterns each containing the set of root attributes described in 
  609         jsonDebug( 
'createPatternsFromString(%d chars, %d lines)' % (len(definition), definition.count(
'\n')) )
 
  612             jsonPattern = json.loads( definition )
 
  613             jsonDebug( 
'Created pattern %s' % str(jsonPattern) )
 
  614             parsedPattern = self.parseJsonPatterns( jsonPattern )
 
  616             self.reportError( e )
 
  620     def createPatternsFromFile(self, fileName):
 
  622         Decode the input file contents from JSON format and create a set of 
  623         patterns each containing the set of root attributes described in 
  627         jsonDebug( 
'createPatternsFromFile(%s)' % fileName )
 
  630             fd = open(fileName, 
'r') 
  635             parsedPattern = self.createPatternsFromString( definition )
 
  637             self.reportError( e )
 
  643         Get the name of this pattern type. 
  645         return JsonKeys.kPluginPatternFactoryName
 
  650 def initializePlugin(plugin):
 
  652     pluginFn = omAPI.MFnPlugin(plugin)
 
  654         pluginFn.registerAttributePatternFactory(
 
  655             JsonKeys.kPluginPatternFactoryName, PyJsonAttrPatternFactory.patternFactoryCreator
 
  659             "Failed to register attribute pattern factory: %s\n" % JsonKeys.kPluginPatternFactoryName
 
  665 def uninitializePlugin(plugin):
 
  666     pluginFn = omAPI.MFnPlugin(plugin)
 
  668         pluginFn.deregisterAttributePatternFactory(JsonKeys.kPluginPatternFactoryName)
 
  671             "Failed to unregister command: %s\n" % JsonKeys.kPluginPatternFactoryName