Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/src/man/man1/mtconnect-agent.1.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ All configuration is read from the *[MTCONNECT]* section:
*TRANSPORT*:: Comma-separated list of *http*, *mqtt*, *shdr* (default *http*).
*HTTP_PORT*:: Embedded HTTP agent port (default 5000).
*HTTP_BIND*:: Interface to bind (default 127.0.0.1; use 0.0.0.0 for the LAN).
*USER_PAGES*:: Path to optional user pages / html files.
*SHDR_PORT*:: Port for the SHDR adapter when *shdr* is in *TRANSPORT* (default
7878). SHDR feeds an external MTConnect agent (e.g. cppagent) `<ts>|id|value`
lines; configure that agent with a Devices.xml from *--dump-probe*.
Expand Down
14 changes: 14 additions & 0 deletions lib/python/mtc/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ def __init__(self, ini_path, buffer_size=131072):
self._last_in_spindle = None
self._last_values = {}
self._lock = threading.Lock()
self.user_pages = self.ini.find("MTCONNECT", "USER_PAGES", "")
if self.user_pages and self.user_pages[0] != "/":
# use relativ path
self.user_pages = os.path.join(os.path.dirname(ini_path), self.user_pages)

# -- data collection -----------------------------------------------------

Expand Down Expand Up @@ -112,6 +116,16 @@ def extension_schema(self):
with open(path, "rb") as fh:
return fh.read(), "application/xml"

def user_page(self, name):
"""Return (bytes, content_type) for a served user file, or None."""
if not self.user_pages:
return None
path = os.path.realpath(os.path.join(self.user_pages, name))
if path.startswith(self.user_pages) and os.path.isfile(path):
with open(path, "r") as fh:
return fh.read(), "text/html"
return None

def model_file(self, name):
"""Return (bytes, content_type) for a served mesh, or None."""
ref = self.models.served.get(name)
Expand Down
8 changes: 8 additions & 0 deletions lib/python/mtc/http_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,14 @@ def do_GET(self):
else:
data, content_type = result
self._send(data, content_type=content_type)
elif route.startswith(f"/html/"):
result = agent.user_page(route[len("/html/"):])
if result is None:
self._send(_error_document("NOT_FOUND",
"no such file: %s" % route), status=404)
else:
data, content_type = result
self._send(data, content_type=content_type)
else:
self._send(_error_document("UNSUPPORTED",
"unsupported request: %s" % route), status=404)
Expand Down