plugger.py
changeset 29 282380dea497
parent 25 fa7503684c28
child 33 59b84ab7bf8b
equal deleted inserted replaced
28:848ce4b1f9e4 29:282380dea497
    17 
    17 
    18 _BaseParamsClass = GenerateClassesFromXSDstring("""<?xml version="1.0" encoding="ISO-8859-1" ?>
    18 _BaseParamsClass = GenerateClassesFromXSDstring("""<?xml version="1.0" encoding="ISO-8859-1" ?>
    19         <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    19         <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    20           <xsd:element name="BaseParams">
    20           <xsd:element name="BaseParams">
    21             <xsd:complexType>
    21             <xsd:complexType>
    22               <xsd:attribute name="Name" type="xsd:string" use="required"/>
    22               <xsd:attribute name="Name" type="xsd:string" use="required" default="__unnamed__"/>
    23               <xsd:attribute name="IEC_Channel" type="xsd:integer" use="required"/>
    23               <xsd:attribute name="IEC_Channel" type="xsd:integer" use="required"/>
    24               <xsd:attribute name="Enabled" type="xsd:boolean" use="required" default="true"/>
    24               <xsd:attribute name="Enabled" type="xsd:boolean" use="required" default="true"/>
    25             </xsd:complexType>
    25             </xsd:complexType>
    26           </xsd:element>
    26           </xsd:element>
    27         </xsd:schema>""")[0]["BaseParams"]
    27         </xsd:schema>""")[0]["BaseParams"]
    37     PlugChildsTypes = []
    37     PlugChildsTypes = []
    38     PlugMaxCount = None
    38     PlugMaxCount = None
    39     PluginMethods = []
    39     PluginMethods = []
    40 
    40 
    41     def _AddParamsMembers(self):
    41     def _AddParamsMembers(self):
    42         Classes = GenerateClassesFromXSDstring(self.XSD)[0]
       
    43         self.PlugParams = None
    42         self.PlugParams = None
    44         Classes = [(name, XSDclass) for name, XSDclass in Classes.items() if XSDclass.IsBaseClass]
    43         if self.XSD:
    45         if len(Classes) == 1:
    44             Classes = GenerateClassesFromXSDstring(self.XSD)[0]
    46             name, XSDclass = Classes[0]
    45             Classes = [(name, XSDclass) for name, XSDclass in Classes.items() if XSDclass.IsBaseClass]
    47             obj = XSDclass()
    46             if len(Classes) == 1:
    48             self.PlugParams = (name, obj)
    47                 name, XSDclass = Classes[0]
    49             setattr(self, name, obj)
    48                 obj = XSDclass()
       
    49                 self.PlugParams = (name, obj)
       
    50                 setattr(self, name, obj)
    50 
    51 
    51     def __init__(self):
    52     def __init__(self):
    52         # Create BaseParam 
    53         # Create BaseParam 
    53         self.BaseParams = _BaseParamsClass()
    54         self.BaseParams = _BaseParamsClass()
    54         self.MandatoryParams = ("BaseParams", self.BaseParams)
    55         self.MandatoryParams = ("BaseParams", self.BaseParams)
    86                 params.append(self.MandatoryParams[1].getElementInfos(self.MandatoryParams[0]))
    87                 params.append(self.MandatoryParams[1].getElementInfos(self.MandatoryParams[0]))
    87             if self.PlugParams:
    88             if self.PlugParams:
    88                 params.append(self.PlugParams[1].getElementInfos(self.PlugParams[0]))
    89                 params.append(self.PlugParams[1].getElementInfos(self.PlugParams[0]))
    89             return params
    90             return params
    90         
    91         
    91     def SetParamsAttribute(self, path, value):
    92     def SetParamsAttribute(self, path, value, logger):
       
    93         # Filter IEC_Channel and Name, that have specific behavior
       
    94         if path == "BaseParams.IEC_Channel":
       
    95             return self.FindNewIEC_Channel(value,logger), False
       
    96         elif path == "BaseParams.Name":
       
    97             res = self.FindNewName(value,logger)
       
    98             self.PlugRequestSave()
       
    99             return res, True
       
   100         
    92         parts = path.split(".", 1)
   101         parts = path.split(".", 1)
    93         if self.MandatoryParams and parts[0] == self.MandatoryParams[0]:
   102         if self.MandatoryParams and parts[0] == self.MandatoryParams[0]:
    94             self.MandatoryParams[1].setElementValue(parts[1], value)
   103             self.MandatoryParams[1].setElementValue(parts[1], value)
    95         elif self.PlugParams and parts[0] == self.PlugParams[0]:
   104         elif self.PlugParams and parts[0] == self.PlugParams[0]:
    96             self.PlugParams[1].setElementValue(parts[1], value)
   105             self.PlugParams[1].setElementValue(parts[1], value)
       
   106         return value, False
    97 
   107 
    98     def PlugRequestSave(self):
   108     def PlugRequestSave(self):
    99         # If plugin do not have corresponding directory
   109         # If plugin do not have corresponding directory
   100         plugpath = self.PlugPath()
   110         plugpath = self.PlugPath()
   101         if not os.path.isdir(plugpath):
   111         if not os.path.isdir(plugpath):
   213         childs = []
   223         childs = []
   214         for child in self.IterChilds():
   224         for child in self.IterChilds():
   215             childs.append(child.GetPlugInfos())
   225             childs.append(child.GetPlugInfos())
   216         return {"name" : self.BaseParams.getName(), "type" : None, "values" : childs}
   226         return {"name" : self.BaseParams.getName(), "type" : None, "values" : childs}
   217     
   227     
   218     def FindNewIEC_Channel(self, DesiredChannel):
   228     
       
   229     def FindNewName(self, DesiredName, logger):
       
   230         """
       
   231         Changes Name to DesiredName if available, Name-N if not.
       
   232         @param DesiredName: The desired Name (string)
       
   233         """
       
   234         # Get Current Name
       
   235         CurrentName = self.BaseParams.getName()
       
   236         # Do nothing if no change
       
   237         #if CurrentName == DesiredName: return CurrentName
       
   238         # Build a list of used Name out of parent's PluggedChilds
       
   239         AllNames=[]
       
   240         for PlugInstance in self.PlugParent.IterChilds():
       
   241             if PlugInstance != self:
       
   242                 AllNames.append(PlugInstance.BaseParams.getName())
       
   243 
       
   244         # Find a free name, eventually appending digit
       
   245         res = DesiredName
       
   246         suffix = 1
       
   247         while res in AllNames:
       
   248             res = "%s-%d"%(DesiredName, suffix)
       
   249             suffix += 1
       
   250         
       
   251         # Get old path
       
   252         oldname = self.PlugPath()
       
   253         # Check previous plugin existance
       
   254         dontexist = self.BaseParams.getName() == "__unnamed__"
       
   255         # Set the new name
       
   256         self.BaseParams.setName(res)
       
   257         # Rename plugin dir if exist
       
   258         if not dontexist:
       
   259             shutil.move(oldname, self.PlugPath())
       
   260         # warn user he has two left hands
       
   261         if DesiredName != res:
       
   262             logger.write_warning("A child names \"%s\" already exist -> \"%s\"\n"%(DesiredName,res))
       
   263         return res
       
   264 
       
   265     def FindNewIEC_Channel(self, DesiredChannel, logger):
   219         """
   266         """
   220         Changes IEC Channel number to DesiredChannel if available, nearest available if not.
   267         Changes IEC Channel number to DesiredChannel if available, nearest available if not.
   221         @param DesiredChannel: The desired IEC channel (int)
   268         @param DesiredChannel: The desired IEC channel (int)
   222         """
   269         """
   223         # Get Current IEC channel
   270         # Get Current IEC channel
   224         CurrentChannel = self.BaseParams.getIEC_Channel()
   271         CurrentChannel = self.BaseParams.getIEC_Channel()
   225         # Do nothing if no change
   272         # Do nothing if no change
   226         if CurrentChannel == DesiredChannel: return CurrentChannel
   273         #if CurrentChannel == DesiredChannel: return CurrentChannel
   227         # Build a list of used Channels out of parent's PluggedChilds
   274         # Build a list of used Channels out of parent's PluggedChilds
   228         AllChannels=[]
   275         AllChannels=[]
   229         for PlugInstance in self.PlugParent.IterChilds():
   276         for PlugInstance in self.PlugParent.IterChilds():
   230             if PlugInstance != self:
   277             if PlugInstance != self:
   231                 AllChannels.append(PlugInstance.BaseParams.getIEC_Channel())
   278                 AllChannels.append(PlugInstance.BaseParams.getIEC_Channel())
   239                 if res < 0 : return CurrentChannel # Can't go bellow 0, do nothing
   286                 if res < 0 : return CurrentChannel # Can't go bellow 0, do nothing
   240             else : # Want to go up ?
   287             else : # Want to go up ?
   241                 res +=  1 # Test for n-1
   288                 res +=  1 # Test for n-1
   242         # Finally set IEC Channel
   289         # Finally set IEC Channel
   243         self.BaseParams.setIEC_Channel(res)
   290         self.BaseParams.setIEC_Channel(res)
       
   291         if logger and DesiredChannel != res:
       
   292             logger.write_warning("A child with IEC channel %d already exist -> %d\n"%(DesiredChannel,res))
   244         return res
   293         return res
   245 
   294 
   246     def OnPlugClose(self):
   295     def OnPlugClose(self):
   247         return True
   296         return True
   248 
   297 
   299                 _self.PlugParent = self
   348                 _self.PlugParent = self
   300                 # Keep track of the plugin type name
   349                 # Keep track of the plugin type name
   301                 _self.PlugType = PlugType
   350                 _self.PlugType = PlugType
   302                 # Call the base plugin template init - change XSD into class members
   351                 # Call the base plugin template init - change XSD into class members
   303                 PlugTemplate.__init__(_self)
   352                 PlugTemplate.__init__(_self)
       
   353                 # check name is unique
       
   354                 NewPlugName = _self.FindNewName(PlugName, logger)
   304                 # If dir have already be made, and file exist
   355                 # If dir have already be made, and file exist
   305                 if os.path.isdir(_self.PlugPath(PlugName)) and os.path.isfile(_self.PluginXmlFilePath(PlugName)):
   356                 if os.path.isdir(_self.PlugPath(NewPlugName)): #and os.path.isfile(_self.PluginXmlFilePath(PlugName)):
   306                     #Load the plugin.xml file into parameters members
   357                     #Load the plugin.xml file into parameters members
   307                     _self.LoadXMLParams(PlugName)
   358                     _self.LoadXMLParams(NewPlugName)
   308                     # Basic check. Better to fail immediately.
   359                     # Basic check. Better to fail immediately.
   309                     if (_self.BaseParams.getName() != PlugName):
   360                     if (_self.BaseParams.getName() != NewPlugName):
   310                         raise Exception, "Project tree layout do not match plugin.xml %s!=%s "%(PlugName, _self.BaseParams.getName())
   361                         raise Exception, "Project tree layout do not match plugin.xml %s!=%s "%(NewPlugName, _self.BaseParams.getName())
   311 
   362 
   312                     # Now, self.PlugPath() should be OK
   363                     # Now, self.PlugPath() should be OK
   313                     
   364                     
   314                     # Check that IEC_Channel is not already in use.
   365                     # Check that IEC_Channel is not already in use.
   315                     _self.FindNewIEC_Channel(_self.BaseParams.getIEC_Channel())
   366                     _self.FindNewIEC_Channel(_self.BaseParams.getIEC_Channel(),logger)
   316                     # Call the plugin real __init__
   367                     # Call the plugin real __init__
   317                     if getattr(PlugClass, "__init__", None):
   368                     if getattr(PlugClass, "__init__", None):
   318                         PlugClass.__init__(_self)
   369                         PlugClass.__init__(_self)
   319                     #Load and init all the childs
   370                     #Load and init all the childs
   320                     _self.LoadChilds(logger)
   371                     _self.LoadChilds(logger)
   321                 else:
   372                 else:
   322                     # If plugin do not have corresponding file/dirs - they will be created on Save
   373                     # If plugin do not have corresponding file/dirs - they will be created on Save
   323                     # Set plugin name
       
   324                     _self.BaseParams.setName(PlugName)
       
   325                     os.mkdir(_self.PlugPath())
   374                     os.mkdir(_self.PlugPath())
   326                     # Find an IEC number
   375                     # Find an IEC number
   327                     _self.FindNewIEC_Channel(0)
   376                     _self.FindNewIEC_Channel(0, None)
   328                     # Call the plugin real __init__
   377                     # Call the plugin real __init__
   329                     if getattr(PlugClass, "__init__", None):
   378                     if getattr(PlugClass, "__init__", None):
   330                         PlugClass.__init__(_self)
   379                         PlugClass.__init__(_self)
   331                     _self.PlugRequestSave()
   380                     _self.PlugRequestSave()
   332 
   381