svghmi/svghmi.py
branchsvghmi
changeset 3180 c059026d8626
parent 3177 5a8abd549aa8
child 3193 8006bb60a4dd
equal deleted inserted replaced
3179:73d26eae5fb1 3180:c059026d8626
   360         runtimefile.write(svghmiservercode)
   360         runtimefile.write(svghmiservercode)
   361         runtimefile.close()
   361         runtimefile.close()
   362 
   362 
   363         # Backup HMI Tree in XML form so that it can be loaded without building
   363         # Backup HMI Tree in XML form so that it can be loaded without building
   364         hmitree_backup_path = os.path.join(buildpath, "hmitree.xml")
   364         hmitree_backup_path = os.path.join(buildpath, "hmitree.xml")
   365         hmitree_backup_file = open(hmitree_backup_path, 'w')
   365         hmitree_backup_file = open(hmitree_backup_path, 'wb')
   366         hmitree_backup_file.write(etree.tostring(hmi_tree_root.etree()))
   366         hmitree_backup_file.write(etree.tostring(hmi_tree_root.etree()))
   367         hmitree_backup_file.close()
   367         hmitree_backup_file.close()
   368 
   368 
   369         return ((["svghmi"], [(gen_svghmi_c_path, IECCFLAGS)], True), "",
   369         return ((["svghmi"], [(gen_svghmi_c_path, IECCFLAGS)], True), "",
   370                 ("runtime_00_svghmi.py", open(runtimefile_path, "rb")))
   370                 ("runtime_00_svghmi.py", open(runtimefile_path, "rb")))
   447 
   447 
   448         if hmi_tree_root is None:
   448         if hmi_tree_root is None:
   449             buildpath = self.Controler.GetCTRoot()._getBuildPath()
   449             buildpath = self.Controler.GetCTRoot()._getBuildPath()
   450             hmitree_backup_path = os.path.join(buildpath, "hmitree.xml")
   450             hmitree_backup_path = os.path.join(buildpath, "hmitree.xml")
   451             if os.path.exists(hmitree_backup_path):
   451             if os.path.exists(hmitree_backup_path):
   452                 hmitree_backup_file = open(hmitree_backup_path, 'r')
   452                 hmitree_backup_file = open(hmitree_backup_path, 'rb')
   453                 hmi_tree_root = HMITreeNode.from_etree(etree.parse(hmitree_backup_file).getroot())
   453                 hmi_tree_root = HMITreeNode.from_etree(etree.parse(hmitree_backup_file).getroot())
   454 
   454 
   455         return HMITreeSelector(parent)
   455         return HMITreeSelector(parent)
   456 
   456 
   457 class SVGHMI(object):
   457 class SVGHMI(object):
   600 
   600 
   601         res = ([], "", False)
   601         res = ([], "", False)
   602 
   602 
   603         target_fname = "svghmi_"+location_str+".xhtml"
   603         target_fname = "svghmi_"+location_str+".xhtml"
   604 
   604 
   605         target_path = os.path.join(self._getBuildPath(), target_fname)
   605         build_path = self._getBuildPath()
   606         target_file = open(target_path, 'wb')
   606         target_path = os.path.join(build_path, target_fname)
       
   607         hash_path = os.path.join(build_path, "svghmi.md5")
   607 
   608 
   608         self.GetCTRoot().logger.write("SVGHMI:\n")
   609         self.GetCTRoot().logger.write("SVGHMI:\n")
   609 
   610 
   610         if os.path.exists(svgfile):
   611         if os.path.exists(svgfile):
   611 
   612 
   612             # TODO : move to __init__
   613             hasher = hashlib.md5()
   613             transform = XSLTransform(os.path.join(ScriptDirectory, "gen_index_xhtml.xslt"),
   614             hmi_tree_root._hash(hasher)
   614                           [("GetSVGGeometry", lambda *_ignored:self.GetSVGGeometry()),
   615             with open(svgfile, 'rb') as afile:
   615                            ("GetHMITree", lambda *_ignored:self.GetHMITree()),
   616                 while True:
   616                            ("GetTranslations", self.GetTranslations),
   617                     buf = afile.read(65536)
   617                            ("ProgressStart", lambda _ign,k,m:self.ProgressStart(str(k),str(m))),
   618                     if len(buf) > 0:
   618                            ("ProgressEnd", lambda _ign,k:self.ProgressEnd(str(k)))])
   619                         hasher.update(buf)
   619 
   620                     else:
   620             self.ProgressStart("svg", "source SVG parsing")
   621                         break
   621 
   622             digest = hasher.hexdigest()
   622             # load svg as a DOM with Etree
   623 
   623             svgdom = etree.parse(svgfile)
   624             if os.path.exists(hash_path):
   624 
   625                 with open(hash_path, 'rb') as digest_file:
   625             self.ProgressEnd("svg")
   626                     last_digest = digest_file.read()
   626 
   627             else:
   627             # call xslt transform on Inkscape's SVG to generate XHTML
   628                 last_digest = None
   628             try: 
   629             
   629                 self.ProgressStart("xslt", "XSLT transform")
   630             if digest != last_digest:
   630                 result = transform.transform(svgdom)  # , profile_run=True)
   631 
   631                 self.ProgressEnd("xslt")
   632                 transform = XSLTransform(os.path.join(ScriptDirectory, "gen_index_xhtml.xslt"),
   632             except XSLTApplyError as e:
   633                               [("GetSVGGeometry", lambda *_ignored:self.GetSVGGeometry()),
   633                 self.FatalError("SVGHMI " + view_name  + ": " + e.message)
   634                                ("GetHMITree", lambda *_ignored:self.GetHMITree()),
   634             finally:
   635                                ("GetTranslations", self.GetTranslations),
   635                 for entry in transform.get_error_log():
   636                                ("ProgressStart", lambda _ign,k,m:self.ProgressStart(str(k),str(m))),
   636                     message = "SVGHMI: "+ entry.message + "\n" 
   637                                ("ProgressEnd", lambda _ign,k:self.ProgressEnd(str(k)))])
   637                     self.GetCTRoot().logger.write_warning(message)
   638 
   638 
   639                 self.ProgressStart("svg", "source SVG parsing")
   639             result.write(target_file, encoding="utf-8")
   640 
   640             # print(str(result))
   641                 # load svg as a DOM with Etree
   641             # print(transform.xslt.error_log)
   642                 svgdom = etree.parse(svgfile)
   642             # print(etree.tostring(result.xslt_profile,pretty_print=True))
   643 
   643 
   644                 self.ProgressEnd("svg")
   644             # TODO
   645 
   645             #   - Errors on HMI semantics
   646                 # call xslt transform on Inkscape's SVG to generate XHTML
   646             #   - ... maybe something to have a global view of what is declared in SVG.
   647                 try: 
       
   648                     self.ProgressStart("xslt", "XSLT transform")
       
   649                     result = transform.transform(svgdom)  # , profile_run=True)
       
   650                     self.ProgressEnd("xslt")
       
   651                 except XSLTApplyError as e:
       
   652                     self.FatalError("SVGHMI " + view_name  + ": " + e.message)
       
   653                 finally:
       
   654                     for entry in transform.get_error_log():
       
   655                         message = "SVGHMI: "+ entry.message + "\n" 
       
   656                         self.GetCTRoot().logger.write_warning(message)
       
   657 
       
   658                 target_file = open(target_path, 'wb')
       
   659                 result.write(target_file, encoding="utf-8")
       
   660                 target_file.close()
       
   661 
       
   662                 # print(str(result))
       
   663                 # print(transform.xslt.error_log)
       
   664                 # print(etree.tostring(result.xslt_profile,pretty_print=True))
       
   665 
       
   666                 with open(hash_path, 'wb') as digest_file:
       
   667                     digest_file.write(digest)
       
   668             else:
       
   669                 self.GetCTRoot().logger.write("    No changes - XSLT transformation skipped\n")
   647 
   670 
   648         else:
   671         else:
   649             # TODO : use default svg that expose the HMI tree as-is
   672             target_file = open(target_path, 'wb')
   650             target_file.write("""<!DOCTYPE html>
   673             target_file.write("""<!DOCTYPE html>
   651 <html>
   674 <html>
   652 <body>
   675 <body>
   653 <h1> No SVG file provided </h1>
   676 <h1> No SVG file provided </h1>
   654 </body>
   677 </body>
   655 </html>
   678 </html>
   656 """)
   679 """)
   657 
   680             target_file.close()
   658         target_file.close()
       
   659 
   681 
   660         res += ((target_fname, open(target_path, "rb")),)
   682         res += ((target_fname, open(target_path, "rb")),)
   661 
   683 
   662         svghmi_cmds = {}
   684         svghmi_cmds = {}
   663         for thing in ["Start", "Stop", "Watchdog"]:
   685         for thing in ["Start", "Stop", "Watchdog"]: