diff --git a/python/common/src/rascsi/sys_cmds.py b/python/common/src/rascsi/sys_cmds.py index 46971d8a..2432dfbe 100644 --- a/python/common/src/rascsi/sys_cmds.py +++ b/python/common/src/rascsi/sys_cmds.py @@ -181,3 +181,15 @@ class SysCmds: return process.returncode, process.stdout.decode("utf-8") return process.returncode, process.stderr.decode("utf-8") + + @staticmethod + def get_filecontents(file_path): + """ + Takes (str) file_path, with the path to the file to fetch the contents of. + Returns either the file contents, or the exception error. + """ + try: + with open(file_path) as file: + return 0, file.read() + except Exception as error: + return 1, error diff --git a/python/web/src/templates/base.html b/python/web/src/templates/base.html index e8a21057..eeb51247 100644 --- a/python/web/src/templates/base.html +++ b/python/web/src/templates/base.html @@ -89,7 +89,7 @@ {% block content %}{% endblock content %} diff --git a/python/web/src/templates/index.html b/python/web/src/templates/index.html index ed53f90d..01e2494b 100644 --- a/python/web/src/templates/index.html +++ b/python/web/src/templates/index.html @@ -171,7 +171,7 @@ -
  • {{ _("Read more about supported device types on the wiki.", url="https://github.com/akuker/RASCSI/wiki/Supported-Device-Types") }} +
  • {{ _("Read more about supported device types on the wiki.", url="https://github.com/akuker/RASCSI/wiki/Supported-Device-Types") }}
  • - + {% for type in REMOVABLE_DEVICE_TYPES + PERIPHERAL_DEVICE_TYPES %} @@ -442,7 +442,7 @@ @@ -498,7 +498,7 @@ @@ -579,11 +579,7 @@ {{ _("Create Empty Disk Image File") }}
    {{ _("Device") }}{{ _("Code") }}{{ _("Key") }} {{ _("Parameters and Actions") }}
    diff --git a/python/web/src/templates/manpage.html b/python/web/src/templates/manpage.html new file mode 100644 index 00000000..9b79ac96 --- /dev/null +++ b/python/web/src/templates/manpage.html @@ -0,0 +1,8 @@ +{% extends "base.html" %} + +{% block content %} +

    {{ _("Manual for %(app)s:", app=app) }}

    +

    {{ manpage }}

    +

    {{ _("Go to Home") }}

    + +{% endblock content %} diff --git a/python/web/src/web.py b/python/web/src/web.py index 0d8785ac..386929ab 100644 --- a/python/web/src/web.py +++ b/python/web/src/web.py @@ -57,6 +57,7 @@ from web_utils import ( upload_with_dropzonejs, ) from settings import ( + WEB_DIR, AFP_DIR, MAX_FILE_SIZE, DEFAULT_CONFIG, @@ -487,6 +488,45 @@ def show_diskinfo(): ) +@APP.route("/sys/manpage", methods=["GET"]) +def show_manpage(): + """ + Displays manpage + """ + app_allowlist = ["rascsi", "rasctl", "rasdump", "scsimon"] + + app = request.args.get("app", type = str) + + if app not in app_allowlist: + return response( + error=True, + message=_("%(app)s is not a recognized RaSCSI app", app=app) + ) + + server_info = ractl_cmd.get_server_info() + file_path = f"{WEB_DIR}/../../../doc/{app}_man_page.txt" + + returncode, manpage = sys_cmd.get_filecontents(file_path) + if returncode == 0: + formatted_manpage = "" + for line in manpage.splitlines(True): + # Strip out irrelevant header + if not line.startswith("!!"): + formatted_manpage += line + + return response( + template="manpage.html", + app=app, + manpage=formatted_manpage, + version=server_info["version"], + ) + + return response( + error=True, + message=_("An error occurred when accessing man page: %(error)s", error=manpage) + ) + + @APP.route("/logs/show", methods=["POST"]) def show_logs(): """ diff --git a/python/web/tests/api/test_misc.py b/python/web/tests/api/test_misc.py index b1084bcc..a88a7243 100644 --- a/python/web/tests/api/test_misc.py +++ b/python/web/tests/api/test_misc.py @@ -95,3 +95,11 @@ def test_create_image_with_properties_file(http_client, delete_file): # Cleanup delete_file(file_name) + +# route("/sys/manpage", methods=["POST"]) +def test_show_manpage(http_client): + response = http_client.get("/sys/manpage?app=rascsi") + response_data = response.json() + + assert response.status_code == 200 + assert "rascsi" in response_data["data"]["manpage"]