--- a/svghmi/svghmi.py Mon Jan 06 17:00:03 2025 +0100
+++ b/svghmi/svghmi.py Thu Jan 09 09:45:21 2025 +0100
@@ -399,6 +399,18 @@
"tooltip": _("Remove font previously added to HMI"),
"method": "_DelFont"
},
+ {
+ "bitmap": "AddFile",
+ "name": _("Add File"),
+ "tooltip": _("Add file to be served for HMI"),
+ "method": "_AddFile"
+ },
+ {
+ "bitmap": "DelFile",
+ "name": _("Delete File"),
+ "tooltip": _("Remove file previously added to HMI"),
+ "method": "_DelFile"
+ },
]
def _getSVGpath(self, project_path=None):
@@ -554,6 +566,20 @@
ctroot.logger.write("SVGHMI:\n")
+ # To serve user provided static files
+ # - transfer them as file with a prefixed name
+ # to avoid potential conflicts
+ # - generate server code that serve them with
+ # original name as http path
+ project_path = self.CTNPath()
+ static_dir = os.path.join(project_path, "static")
+ static_files_pairs = []
+ for fname in os.listdir(static_dir):
+ undercover_fname = location_str+"_"+fname
+ static_files_pairs.append('(b"%s","%s")'%(fname, undercover_fname))
+ res += ((undercover_fname, open(os.path.join(static_dir, fname), "rb")),)
+ static_files = ",\n ".join(static_files_pairs)
+
if os.path.exists(svgfile):
hasher = hashlib.md5()
@@ -673,6 +699,10 @@
max_svghmi_sessions = {maxConnections_total}
+_{location}_static_files = [
+ {static_files}
+]
+
def _runtime_{location}_svghmi_start():
global svghmi_watchdog, svghmi_servers, browser_proc
@@ -699,6 +729,10 @@
path_list.append("{path}")
+ for url_path, file_path in _{location}_static_files:
+ svghmi_root.putChild(url_path, File(file_path))
+ path_list.append(url_path)
+
browser_proc = {svghmi_cmds[Start]}
if {enable_watchdog}:
@@ -723,6 +757,10 @@
path_list.remove('{path}')
+ for url_path, file_path in _{location}_static_files:
+ svghmi_root.delEntity(url_path)
+ path_list.remove(url_path)
+
if len(path_list)==0:
svghmi_root.delEntity(b"ws")
svghmi_listener.stopListening()
@@ -740,6 +778,7 @@
watchdog_interval = self.GetParamsAttributes("SVGHMI.WatchdogInterval")["value"],
maxConnections = self.GetParamsAttributes("SVGHMI.MaxConnections")["value"],
maxConnections_total = svghmilib.maxConnectionsTotal,
+ static_files = static_files,
**svghmi_options
))
@@ -814,6 +853,62 @@
else:
self.GetCTRoot().logger.write_error(_("POT file does not exist, add translatable text (label starting with '_') in Inkscape first\n"))
+ def _AddFile(self):
+ dialog = wx.FileDialog(
+ self.GetCTRoot().AppFrame,
+ _("Choose files so serve"),
+ os.path.expanduser("~"),
+ "",
+ _("Any files (*.*)|*.*"), wx.FD_OPEN)
+
+ if dialog.ShowModal() == wx.ID_OK:
+ staticfile = dialog.GetPath()
+ if not os.path.isfile(staticfile):
+ self.GetCTRoot().logger.write_error(
+ _('Selected file%s is not a readable file\n')%staticfile)
+ return
+
+ project_path = self.CTNPath()
+
+ staticfname = os.path.basename(staticfile)
+ staticdir = os.path.join(project_path, "static")
+ newstaticfile = os.path.join(staticdir, staticfname)
+
+ if not os.path.exists(staticdir):
+ os.mkdir(staticdir)
+
+ shutil.copyfile(staticfile, newstaticfile)
+
+ self.GetCTRoot().logger.write(
+ _('Added file %s as %s\n')%(staticfile,newstaticfile))
+
+ def _DelFile(self):
+ project_path = self.CTNPath()
+ staticdir = os.path.join(project_path, "static")
+ if not os.path.exists(staticdir) or len(os.listdir(staticdir))==0 :
+ self.GetCTRoot().logger.write_error(
+ _("No file in %s\n")%staticdir)
+ return
+ dialog = wx.FileDialog(
+ self.GetCTRoot().AppFrame,
+ _("Choose a file to remove"),
+ staticdir,
+ "",
+ _("Any files (*.*);*.*"), wx.FD_OPEN)
+ if dialog.ShowModal() == wx.ID_OK:
+ staticfile = dialog.GetPath()
+ if os.path.isfile(staticfile):
+ if os.path.relpath(staticfile, staticdir) == os.path.basename(staticfile):
+ os.remove(staticfile)
+ self.GetCTRoot().logger.write(
+ _('Removed static file%s\n')%staticfile)
+ else:
+ self.GetCTRoot().logger.write_error(
+ _("StaticFile to remove %s is not in %s\n") % (staticfile,staticdir))
+ else:
+ self.GetCTRoot().logger.write_error(
+ _("StaticFile file does not exist: %s\n") % staticfile)
+
def _AddFont(self):
dialog = wx.FileDialog(
self.GetCTRoot().AppFrame,
@@ -852,6 +947,10 @@
def _DelFont(self):
project_path = self.CTNPath()
fontdir = os.path.join(project_path, "fonts")
+ if not os.path.exists(fontdir) or len(os.listdir(fontdir))==0 :
+ self.GetCTRoot().logger.write_error(
+ _("No font file in %s\n")%fontdir)
+ return
dialog = wx.FileDialog(
self.GetCTRoot().AppFrame,
_("Choose a font to remove"),