397 "bitmap": "DelFont", |
397 "bitmap": "DelFont", |
398 "name": _("Delete Font"), |
398 "name": _("Delete Font"), |
399 "tooltip": _("Remove font previously added to HMI"), |
399 "tooltip": _("Remove font previously added to HMI"), |
400 "method": "_DelFont" |
400 "method": "_DelFont" |
401 }, |
401 }, |
|
402 { |
|
403 "bitmap": "AddFile", |
|
404 "name": _("Add File"), |
|
405 "tooltip": _("Add file to be served for HMI"), |
|
406 "method": "_AddFile" |
|
407 }, |
|
408 { |
|
409 "bitmap": "DelFile", |
|
410 "name": _("Delete File"), |
|
411 "tooltip": _("Remove file previously added to HMI"), |
|
412 "method": "_DelFile" |
|
413 }, |
402 ] |
414 ] |
403 |
415 |
404 def _getSVGpath(self, project_path=None): |
416 def _getSVGpath(self, project_path=None): |
405 if project_path is None: |
417 if project_path is None: |
406 project_path = self.CTNPath() |
418 project_path = self.CTNPath() |
551 build_path = self._getBuildPath() |
563 build_path = self._getBuildPath() |
552 target_path = os.path.join(build_path, target_fname) |
564 target_path = os.path.join(build_path, target_fname) |
553 hash_path = os.path.join(build_path, "svghmi_"+location_str+".md5") |
565 hash_path = os.path.join(build_path, "svghmi_"+location_str+".md5") |
554 |
566 |
555 ctroot.logger.write("SVGHMI:\n") |
567 ctroot.logger.write("SVGHMI:\n") |
|
568 |
|
569 # To serve user provided static files |
|
570 # - transfer them as file with a prefixed name |
|
571 # to avoid potential conflicts |
|
572 # - generate server code that serve them with |
|
573 # original name as http path |
|
574 project_path = self.CTNPath() |
|
575 static_dir = os.path.join(project_path, "static") |
|
576 static_files_pairs = [] |
|
577 for fname in os.listdir(static_dir): |
|
578 undercover_fname = location_str+"_"+fname |
|
579 static_files_pairs.append('(b"%s","%s")'%(fname, undercover_fname)) |
|
580 res += ((undercover_fname, open(os.path.join(static_dir, fname), "rb")),) |
|
581 static_files = ",\n ".join(static_files_pairs) |
556 |
582 |
557 if os.path.exists(svgfile): |
583 if os.path.exists(svgfile): |
558 |
584 |
559 hasher = hashlib.md5() |
585 hasher = hashlib.md5() |
560 hmi_tree_root._hash(hasher) |
586 hmi_tree_root._hash(hasher) |
671 waitpid_timeout(browser_proc, "SVGHMI browser process") |
697 waitpid_timeout(browser_proc, "SVGHMI browser process") |
672 browser_proc = {svghmi_cmds[Start]} |
698 browser_proc = {svghmi_cmds[Start]} |
673 |
699 |
674 max_svghmi_sessions = {maxConnections_total} |
700 max_svghmi_sessions = {maxConnections_total} |
675 |
701 |
|
702 _{location}_static_files = [ |
|
703 {static_files} |
|
704 ] |
|
705 |
676 def _runtime_{location}_svghmi_start(): |
706 def _runtime_{location}_svghmi_start(): |
677 global svghmi_watchdog, svghmi_servers, browser_proc |
707 global svghmi_watchdog, svghmi_servers, browser_proc |
678 |
708 |
679 srv = svghmi_servers.get("{interface}:{port}", None) |
709 srv = svghmi_servers.get("{interface}:{port}", None) |
680 if srv is not None: |
710 if srv is not None: |
697 NoCacheFile('{xhtml}', |
727 NoCacheFile('{xhtml}', |
698 defaultType='application/xhtml+xml')) |
728 defaultType='application/xhtml+xml')) |
699 |
729 |
700 path_list.append("{path}") |
730 path_list.append("{path}") |
701 |
731 |
|
732 for url_path, file_path in _{location}_static_files: |
|
733 svghmi_root.putChild(url_path, File(file_path)) |
|
734 path_list.append(url_path) |
|
735 |
702 browser_proc = {svghmi_cmds[Start]} |
736 browser_proc = {svghmi_cmds[Start]} |
703 |
737 |
704 if {enable_watchdog}: |
738 if {enable_watchdog}: |
705 if svghmi_watchdog is None: |
739 if svghmi_watchdog is None: |
706 svghmi_watchdog = Watchdog( |
740 svghmi_watchdog = Watchdog( |
721 svghmi_root, svghmi_listener, path_list = svghmi_servers["{interface}:{port}"] |
755 svghmi_root, svghmi_listener, path_list = svghmi_servers["{interface}:{port}"] |
722 svghmi_root.delEntity(b'{path}') |
756 svghmi_root.delEntity(b'{path}') |
723 |
757 |
724 path_list.remove('{path}') |
758 path_list.remove('{path}') |
725 |
759 |
|
760 for url_path, file_path in _{location}_static_files: |
|
761 svghmi_root.delEntity(url_path) |
|
762 path_list.remove(url_path) |
|
763 |
726 if len(path_list)==0: |
764 if len(path_list)==0: |
727 svghmi_root.delEntity(b"ws") |
765 svghmi_root.delEntity(b"ws") |
728 svghmi_listener.stopListening() |
766 svghmi_listener.stopListening() |
729 svghmi_servers.pop("{interface}:{port}") |
767 svghmi_servers.pop("{interface}:{port}") |
730 |
768 |
738 svghmi_cmds=svghmi_cmds, |
776 svghmi_cmds=svghmi_cmds, |
739 watchdog_initial = self.GetParamsAttributes("SVGHMI.WatchdogInitial")["value"], |
777 watchdog_initial = self.GetParamsAttributes("SVGHMI.WatchdogInitial")["value"], |
740 watchdog_interval = self.GetParamsAttributes("SVGHMI.WatchdogInterval")["value"], |
778 watchdog_interval = self.GetParamsAttributes("SVGHMI.WatchdogInterval")["value"], |
741 maxConnections = self.GetParamsAttributes("SVGHMI.MaxConnections")["value"], |
779 maxConnections = self.GetParamsAttributes("SVGHMI.MaxConnections")["value"], |
742 maxConnections_total = svghmilib.maxConnectionsTotal, |
780 maxConnections_total = svghmilib.maxConnectionsTotal, |
|
781 static_files = static_files, |
743 **svghmi_options |
782 **svghmi_options |
744 )) |
783 )) |
745 |
784 |
746 runtimefile.close() |
785 runtimefile.close() |
747 |
786 |
812 if os.path.isfile(POFile): |
851 if os.path.isfile(POFile): |
813 self._StartPOEdit(POFile) |
852 self._StartPOEdit(POFile) |
814 else: |
853 else: |
815 self.GetCTRoot().logger.write_error(_("POT file does not exist, add translatable text (label starting with '_') in Inkscape first\n")) |
854 self.GetCTRoot().logger.write_error(_("POT file does not exist, add translatable text (label starting with '_') in Inkscape first\n")) |
816 |
855 |
|
856 def _AddFile(self): |
|
857 dialog = wx.FileDialog( |
|
858 self.GetCTRoot().AppFrame, |
|
859 _("Choose files so serve"), |
|
860 os.path.expanduser("~"), |
|
861 "", |
|
862 _("Any files (*.*)|*.*"), wx.FD_OPEN) |
|
863 |
|
864 if dialog.ShowModal() == wx.ID_OK: |
|
865 staticfile = dialog.GetPath() |
|
866 if not os.path.isfile(staticfile): |
|
867 self.GetCTRoot().logger.write_error( |
|
868 _('Selected file%s is not a readable file\n')%staticfile) |
|
869 return |
|
870 |
|
871 project_path = self.CTNPath() |
|
872 |
|
873 staticfname = os.path.basename(staticfile) |
|
874 staticdir = os.path.join(project_path, "static") |
|
875 newstaticfile = os.path.join(staticdir, staticfname) |
|
876 |
|
877 if not os.path.exists(staticdir): |
|
878 os.mkdir(staticdir) |
|
879 |
|
880 shutil.copyfile(staticfile, newstaticfile) |
|
881 |
|
882 self.GetCTRoot().logger.write( |
|
883 _('Added file %s as %s\n')%(staticfile,newstaticfile)) |
|
884 |
|
885 def _DelFile(self): |
|
886 project_path = self.CTNPath() |
|
887 staticdir = os.path.join(project_path, "static") |
|
888 if not os.path.exists(staticdir) or len(os.listdir(staticdir))==0 : |
|
889 self.GetCTRoot().logger.write_error( |
|
890 _("No file in %s\n")%staticdir) |
|
891 return |
|
892 dialog = wx.FileDialog( |
|
893 self.GetCTRoot().AppFrame, |
|
894 _("Choose a file to remove"), |
|
895 staticdir, |
|
896 "", |
|
897 _("Any files (*.*);*.*"), wx.FD_OPEN) |
|
898 if dialog.ShowModal() == wx.ID_OK: |
|
899 staticfile = dialog.GetPath() |
|
900 if os.path.isfile(staticfile): |
|
901 if os.path.relpath(staticfile, staticdir) == os.path.basename(staticfile): |
|
902 os.remove(staticfile) |
|
903 self.GetCTRoot().logger.write( |
|
904 _('Removed static file%s\n')%staticfile) |
|
905 else: |
|
906 self.GetCTRoot().logger.write_error( |
|
907 _("StaticFile to remove %s is not in %s\n") % (staticfile,staticdir)) |
|
908 else: |
|
909 self.GetCTRoot().logger.write_error( |
|
910 _("StaticFile file does not exist: %s\n") % staticfile) |
|
911 |
817 def _AddFont(self): |
912 def _AddFont(self): |
818 dialog = wx.FileDialog( |
913 dialog = wx.FileDialog( |
819 self.GetCTRoot().AppFrame, |
914 self.GetCTRoot().AppFrame, |
820 _("Choose a font"), |
915 _("Choose a font"), |
821 os.path.expanduser("~"), |
916 os.path.expanduser("~"), |
850 _('Added font %s as %s\n')%(fontfile,newfontfile)) |
945 _('Added font %s as %s\n')%(fontfile,newfontfile)) |
851 |
946 |
852 def _DelFont(self): |
947 def _DelFont(self): |
853 project_path = self.CTNPath() |
948 project_path = self.CTNPath() |
854 fontdir = os.path.join(project_path, "fonts") |
949 fontdir = os.path.join(project_path, "fonts") |
|
950 if not os.path.exists(fontdir) or len(os.listdir(fontdir))==0 : |
|
951 self.GetCTRoot().logger.write_error( |
|
952 _("No font file in %s\n")%fontdir) |
|
953 return |
855 dialog = wx.FileDialog( |
954 dialog = wx.FileDialog( |
856 self.GetCTRoot().AppFrame, |
955 self.GetCTRoot().AppFrame, |
857 _("Choose a font to remove"), |
956 _("Choose a font to remove"), |
858 fontdir, |
957 fontdir, |
859 "", |
958 "", |