7 - ... TODO : document |
7 - ... TODO : document |
8 """ |
8 """ |
9 |
9 |
10 import os,traceback,types |
10 import os,traceback,types |
11 import shutil |
11 import shutil |
12 from xml.dom import minidom |
12 from lxml import etree |
13 |
13 |
14 from xmlclass import GenerateClassesFromXSDstring |
14 from xmlclass import GenerateParserFromXSDstring |
15 from util.misc import GetClassImporter |
15 from util.misc import GetClassImporter |
16 |
16 |
17 from PLCControler import PLCControler, LOCATION_CONFNODE |
17 from PLCControler import PLCControler, LOCATION_CONFNODE |
18 from editors.ConfTreeNodeEditor import ConfTreeNodeEditor |
18 from editors.ConfTreeNodeEditor import ConfTreeNodeEditor |
19 |
19 |
20 _BaseParamsClass = GenerateClassesFromXSDstring("""<?xml version="1.0" encoding="ISO-8859-1" ?> |
20 _BaseParamsParser = GenerateParserFromXSDstring("""<?xml version="1.0" encoding="ISO-8859-1" ?> |
21 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> |
21 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> |
22 <xsd:element name="BaseParams"> |
22 <xsd:element name="BaseParams"> |
23 <xsd:complexType> |
23 <xsd:complexType> |
24 <xsd:attribute name="Name" type="xsd:string" use="optional" default="__unnamed__"/> |
24 <xsd:attribute name="Name" type="xsd:string" use="optional" default="__unnamed__"/> |
25 <xsd:attribute name="IEC_Channel" type="xsd:integer" use="required"/> |
25 <xsd:attribute name="IEC_Channel" type="xsd:integer" use="required"/> |
26 <xsd:attribute name="Enabled" type="xsd:boolean" use="optional" default="true"/> |
26 <xsd:attribute name="Enabled" type="xsd:boolean" use="optional" default="true"/> |
27 </xsd:complexType> |
27 </xsd:complexType> |
28 </xsd:element> |
28 </xsd:element> |
29 </xsd:schema>""")["BaseParams"] |
29 </xsd:schema>""") |
30 |
30 |
31 NameTypeSeparator = '@' |
31 NameTypeSeparator = '@' |
|
32 XSDSchemaErrorMessage = _("%s XML file doesn't follow XSD schema at line %d:\n%s") |
32 |
33 |
33 class ConfigTreeNode: |
34 class ConfigTreeNode: |
34 """ |
35 """ |
35 This class is the one that define confnodes. |
36 This class is the one that define confnodes. |
36 """ |
37 """ |
44 IconPath = None |
45 IconPath = None |
45 |
46 |
46 def _AddParamsMembers(self): |
47 def _AddParamsMembers(self): |
47 self.CTNParams = None |
48 self.CTNParams = None |
48 if self.XSD: |
49 if self.XSD: |
49 self.Classes = GenerateClassesFromXSDstring(self.XSD) |
50 self.Parser = GenerateParserFromXSDstring(self.XSD) |
50 Classes = [(name, XSDclass) for name, XSDclass in self.Classes.items() if XSDclass.IsBaseClass] |
51 obj = self.Parser.CreateRoot() |
51 if len(Classes) == 1: |
52 name = obj.getLocalTag() |
52 name, XSDclass = Classes[0] |
53 self.CTNParams = (name, obj) |
53 obj = XSDclass() |
54 setattr(self, name, obj) |
54 self.CTNParams = (name, obj) |
|
55 setattr(self, name, obj) |
|
56 |
55 |
57 def __init__(self): |
56 def __init__(self): |
58 # Create BaseParam |
57 # Create BaseParam |
59 self.BaseParams = _BaseParamsClass() |
58 self.BaseParams = _BaseParamsParser.CreateRoot() |
60 self.MandatoryParams = ("BaseParams", self.BaseParams) |
59 self.MandatoryParams = ("BaseParams", self.BaseParams) |
61 self._AddParamsMembers() |
60 self._AddParamsMembers() |
62 self.Children = {} |
61 self.Children = {} |
63 self._View = None |
62 self._View = None |
64 # copy ConfNodeMethods so that it can be later customized |
63 # copy ConfNodeMethods so that it can be later customized |
168 os.mkdir(ctnpath) |
167 os.mkdir(ctnpath) |
169 |
168 |
170 # generate XML for base XML parameters controller of the confnode |
169 # generate XML for base XML parameters controller of the confnode |
171 if self.MandatoryParams: |
170 if self.MandatoryParams: |
172 BaseXMLFile = open(self.ConfNodeBaseXmlFilePath(),'w') |
171 BaseXMLFile = open(self.ConfNodeBaseXmlFilePath(),'w') |
173 BaseXMLFile.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") |
172 BaseXMLFile.write(etree.tostring( |
174 BaseXMLFile.write(self.MandatoryParams[1].generateXMLText(self.MandatoryParams[0], 0).encode("utf-8")) |
173 self.MandatoryParams[1], |
|
174 pretty_print=True, |
|
175 xml_declaration=True, |
|
176 encoding='utf-8')) |
175 BaseXMLFile.close() |
177 BaseXMLFile.close() |
176 |
178 |
177 # generate XML for XML parameters controller of the confnode |
179 # generate XML for XML parameters controller of the confnode |
178 if self.CTNParams: |
180 if self.CTNParams: |
179 XMLFile = open(self.ConfNodeXmlFilePath(),'w') |
181 XMLFile = open(self.ConfNodeXmlFilePath(),'w') |
180 XMLFile.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") |
182 XMLFile.write(etree.tostring( |
181 XMLFile.write(self.CTNParams[1].generateXMLText(self.CTNParams[0], 0).encode("utf-8")) |
183 self.CTNParams[1], |
|
184 pretty_print=True, |
|
185 xml_declaration=True, |
|
186 encoding='utf-8')) |
182 XMLFile.close() |
187 XMLFile.close() |
183 |
188 |
184 # Call the confnode specific OnCTNSave method |
189 # Call the confnode specific OnCTNSave method |
185 result = self.OnCTNSave(from_project_path) |
190 result = self.OnCTNSave(from_project_path) |
186 if not result: |
191 if not result: |
575 def LoadXMLParams(self, CTNName = None): |
580 def LoadXMLParams(self, CTNName = None): |
576 methode_name = os.path.join(self.CTNPath(CTNName), "methods.py") |
581 methode_name = os.path.join(self.CTNPath(CTNName), "methods.py") |
577 if os.path.isfile(methode_name): |
582 if os.path.isfile(methode_name): |
578 execfile(methode_name) |
583 execfile(methode_name) |
579 |
584 |
|
585 ConfNodeName = CTNName if CTNName is not None else self.CTNName() |
|
586 |
580 # Get the base xml tree |
587 # Get the base xml tree |
581 if self.MandatoryParams: |
588 if self.MandatoryParams: |
582 try: |
589 try: |
583 basexmlfile = open(self.ConfNodeBaseXmlFilePath(CTNName), 'r') |
590 basexmlfile = open(self.ConfNodeBaseXmlFilePath(CTNName), 'r') |
584 basetree = minidom.parse(basexmlfile) |
591 self.BaseParams, error = _BaseParamsParser.LoadXMLString(basexmlfile.read()) |
585 self.MandatoryParams[1].loadXMLTree(basetree.childNodes[0]) |
592 if error is not None: |
|
593 self.GetCTRoot().logger.write_warning( |
|
594 XSDSchemaErrorMessage % ((ConfNodeName + " BaseParams",) + error)) |
|
595 self.MandatoryParams = ("BaseParams", self.BaseParams) |
586 basexmlfile.close() |
596 basexmlfile.close() |
587 except Exception, exc: |
597 except Exception, exc: |
588 self.GetCTRoot().logger.write_error(_("Couldn't load confnode base parameters %s :\n %s") % (CTNName, unicode(exc))) |
598 self.GetCTRoot().logger.write_error(_("Couldn't load confnode base parameters %s :\n %s") % (ConfNodeName, unicode(exc))) |
589 self.GetCTRoot().logger.write_error(traceback.format_exc()) |
599 self.GetCTRoot().logger.write_error(traceback.format_exc()) |
590 |
600 |
591 # Get the xml tree |
601 # Get the xml tree |
592 if self.CTNParams: |
602 if self.CTNParams: |
593 try: |
603 try: |
594 xmlfile = open(self.ConfNodeXmlFilePath(CTNName), 'r') |
604 xmlfile = open(self.ConfNodeXmlFilePath(CTNName), 'r') |
595 tree = minidom.parse(xmlfile) |
605 obj, error = self.Parser.LoadXMLString(xmlfile.read()) |
596 self.CTNParams[1].loadXMLTree(tree.childNodes[0]) |
606 if error is not None: |
|
607 self.GetCTRoot().logger.write_warning( |
|
608 XSDSchemaErrorMessage % ((ConfNodeName,) + error)) |
|
609 name = obj.getLocalTag() |
|
610 setattr(self, name, obj) |
|
611 self.CTNParams = (name, obj) |
597 xmlfile.close() |
612 xmlfile.close() |
598 except Exception, exc: |
613 except Exception, exc: |
599 self.GetCTRoot().logger.write_error(_("Couldn't load confnode parameters %s :\n %s") % (CTNName, unicode(exc))) |
614 self.GetCTRoot().logger.write_error(_("Couldn't load confnode parameters %s :\n %s") % (ConfNodeName, unicode(exc))) |
600 self.GetCTRoot().logger.write_error(traceback.format_exc()) |
615 self.GetCTRoot().logger.write_error(traceback.format_exc()) |
601 |
616 |
602 def LoadChildren(self): |
617 def LoadChildren(self): |
603 # Iterate over all CTNName@CTNType in confnode directory, and try to open them |
618 # Iterate over all CTNName@CTNType in confnode directory, and try to open them |
604 for CTNDir in os.listdir(self.CTNPath()): |
619 for CTNDir in os.listdir(self.CTNPath()): |