terminal window

This commit is contained in:
Devaev Maxim 2021-04-17 15:41:05 +03:00
parent 3a2ffcfd5c
commit be012fd38d
10 changed files with 63 additions and 11 deletions

View File

@ -23,6 +23,7 @@
import os import os
import contextlib import contextlib
from typing import Tuple
from typing import Dict from typing import Dict
from typing import Optional from typing import Optional
@ -67,7 +68,7 @@ class ExtrasInfoSubmanager(BaseInfoSubmanager):
def __rewrite_app_daemon(self, extras: Dict) -> None: def __rewrite_app_daemon(self, extras: Dict) -> None:
daemon = extras.get("daemon", "") daemon = extras.get("daemon", "")
if isinstance(daemon, str) and daemon.strip(): if isinstance(daemon, str) and daemon.strip():
extras["enabled"] = self.__is_daemon_enabled(daemon) (extras["enabled"], extras["started"]) = self.__get_daemon_status(daemon)
def __rewrite_app_port(self, extras: Dict) -> None: def __rewrite_app_port(self, extras: Dict) -> None:
port_path = extras.get("port", "") port_path = extras.get("port", "")
@ -79,25 +80,23 @@ class ExtrasInfoSubmanager(BaseInfoSubmanager):
if isinstance(config, int): if isinstance(config, int):
extras["port"] = config extras["port"] = config
def __is_daemon_enabled(self, name: str) -> bool: def __get_daemon_status(self, name: str) -> Tuple[bool, bool]:
if not name.endswith(".service"): if not name.endswith(".service"):
name += ".service" name += ".service"
try: try:
with contextlib.closing(dbus.SystemBus()) as bus: with contextlib.closing(dbus.SystemBus()) as bus:
systemd = bus.get_object("org.freedesktop.systemd1", "/org/freedesktop/systemd1") # pylint: disable=no-member systemd = bus.get_object("org.freedesktop.systemd1", "/org/freedesktop/systemd1") # pylint: disable=no-member
manager = dbus.Interface(systemd, dbus_interface="org.freedesktop.systemd1.Manager") manager = dbus.Interface(systemd, dbus_interface="org.freedesktop.systemd1.Manager")
try: try:
unit_proxy = bus.get_object("org.freedesktop.systemd1", manager.GetUnit(name)) # pylint: disable=no-member unit_proxy = bus.get_object("org.freedesktop.systemd1", manager.GetUnit(name)) # pylint: disable=no-member
unit_properties = dbus.Interface(unit_proxy, dbus_interface="org.freedesktop.DBus.Properties") unit_properties = dbus.Interface(unit_proxy, dbus_interface="org.freedesktop.DBus.Properties")
enabled = (unit_properties.Get("org.freedesktop.systemd1.Unit", "ActiveState") == "active") started = (unit_properties.Get("org.freedesktop.systemd1.Unit", "ActiveState") == "active")
except dbus.exceptions.DBusException as err: except dbus.exceptions.DBusException as err:
if "NoSuchUnit" not in str(err): if "NoSuchUnit" not in str(err):
raise raise
enabled = False started = False
enabled = (manager.GetUnitFileState(name) in ["enabled", "enabled-runtime", "static", "indirect", "generated"])
return (enabled or (manager.GetUnitFileState(name) in ["enabled", "enabled-runtime", "static", "indirect", "generated"])) return (enabled, started)
except Exception as err: except Exception as err:
get_logger(0).error("Can't get info about the service %r: %s", name, tools.efmt(err)) get_logger(0).error("Can't get info about the service %r: %s", name, tools.efmt(err))
return True return (True, True)

View File

@ -0,0 +1,3 @@
{
"src-not-empty": false
}

View File

@ -58,4 +58,4 @@ commands = eslint --cache-location=/tmp --config=testenv/linters/eslintrc.yaml -
[testenv:htmlhint] [testenv:htmlhint]
whitelist_externals = htmlhint whitelist_externals = htmlhint
commands = htmlhint web/*.html web/*/*.html commands = htmlhint --config=testenv/linters/htmlhint.json web/*.html web/*/*.html

View File

@ -205,6 +205,10 @@
<hr> <hr>
<button disabled id="wol-wakeup-button">&bull; Wake-on-LAN server</button> <button disabled id="wol-wakeup-button">&bull; Wake-on-LAN server</button>
</div> </div>
<div class="buttons feature-disabled" id="webterm">
<hr>
<button data-force-hide-menu id="show-webterm-button">&bull; Show terminal</button>
</div>
</div> </div>
</li> </li>
<li class="right feature-disabled" id="atx-dropdown"><a class="menu-button" href="#"><img class="led-gray" data-dont-hide-menu id="atx-power-led" src="/share/svg/led-atx-power.svg"><img class="led-gray" data-dont-hide-menu id="atx-hdd-led" src="/share/svg/led-atx-hdd.svg">ATX</a> <li class="right feature-disabled" id="atx-dropdown"><a class="menu-button" href="#"><img class="led-gray" data-dont-hide-menu id="atx-power-led" src="/share/svg/led-atx-power.svg"><img class="led-gray" data-dont-hide-menu id="atx-hdd-led" src="/share/svg/led-atx-hdd.svg">ATX</a>
@ -1744,6 +1748,16 @@
</p> </p>
</div> </div>
</div> </div>
<div class="window window-resizable" id="webterm-window" data-show-by-button="show-webterm-button" style="width: 640px; height: 480px">
<div class="window-header">
<div class="window-grab">Terminal</div>
<button class="window-button-close">&times;</button>
<button class="window-button-maximize">&#9744;</button>
<!-- Терминал глючит из-за зажимаемой клавиши ESC для выхода-->
<!-- button(class="window-button-full-screen") &#10530;-->
</div>
<iframe id="webterm-iframe" src="" style="width: 100%; height: 100%"></iframe>
</div>
<ul class="footer"> <ul class="footer">
<li class="footer-left" id="kvmd-meta-server-host"></li> <li class="footer-left" id="kvmd-meta-server-host"></li>
<li class="footer-right"><a target="_blank" href="https://pikvm.org">Pi-KVM Project</a></li> <li class="footer-right"><a target="_blank" href="https://pikvm.org">Pi-KVM Project</a></li>

View File

@ -66,3 +66,6 @@ li(class="right")
div(id="wol" class="buttons feature-disabled") div(id="wol" class="buttons feature-disabled")
hr hr
button(disabled id="wol-wakeup-button") &bull; Wake-on-LAN server button(disabled id="wol-wakeup-button") &bull; Wake-on-LAN server
div(id="webterm" class="buttons feature-disabled")
hr
button(data-force-hide-menu id="show-webterm-button") &bull; Show terminal

View File

@ -0,0 +1,8 @@
div(id="webterm-window" class="window window-resizable" data-show-by-button="show-webterm-button" style="width: 640px; height: 480px")
div(class="window-header")
div(class="window-grab") Terminal
button(class="window-button-close") &times;
button(class="window-button-maximize") &#9744;
// Терминал глючит из-за зажимаемой клавиши ESC для выхода
// button(class="window-button-full-screen") &#10530;
iframe(id="webterm-iframe" src="" style="width: 100%; height: 100%")

View File

@ -1,3 +1,4 @@
include window-stream.pug include window-stream.pug
include window-keyboard.pug include window-keyboard.pug
include window-about.pug include window-about.pug
include window-webterm.pug

View File

@ -80,7 +80,7 @@ function __loadKvmdInfo() {
} }
for (let app of apps) { for (let app of apps) {
if (app.enabled) { if (app.enabled || app.started) {
$("apps").innerHTML += __makeApp(null, app.path, app.icon, app.name); $("apps").innerHTML += __makeApp(null, app.path, app.icon, app.name);
} }
} }

View File

@ -107,6 +107,26 @@ export function Session() {
} }
}; };
var __setExtras = function(state) {
let show_hook = null;
let close_hook = null;
let has_webterm = (state.webterm && state.webterm.started);
if (has_webterm) {
let path = "/" + state.webterm.path;
show_hook = function() {
tools.info("Terminal opened: ", path);
$("webterm-iframe").src = path;
};
close_hook = function() {
tools.info("Terminal closed");
$("webterm-iframe").src = "";
};
}
tools.featureSetEnabled($("webterm"), has_webterm);
$("webterm-window").show_hook = show_hook;
$("webterm-window").close_hook = close_hook;
};
var __formatTemp = function(temp) { var __formatTemp = function(temp) {
let pairs = []; let pairs = [];
for (let field of Object.keys(temp).sort()) { for (let field of Object.keys(temp).sort()) {
@ -218,6 +238,7 @@ export function Session() {
case "info_meta_state": __setAboutInfoMeta(data.event); break; case "info_meta_state": __setAboutInfoMeta(data.event); break;
case "info_hw_state": __setAboutInfoHw(data.event); break; case "info_hw_state": __setAboutInfoHw(data.event); break;
case "info_system_state": __setAboutInfoSystem(data.event); break; case "info_system_state": __setAboutInfoSystem(data.event); break;
case "info_extras_state": __setExtras(data.event); break;
case "wol_state": __wol.setState(data.event); break; case "wol_state": __wol.setState(data.event); break;
case "gpio_model_state": __gpio.setModel(data.event); break; case "gpio_model_state": __gpio.setModel(data.event); break;
case "gpio_state": __gpio.setState(data.event); break; case "gpio_state": __gpio.setState(data.event); break;

View File

@ -263,6 +263,9 @@ function __WindowManager() {
el_window.focus(); el_window.focus();
el_window.blur(); el_window.blur();
el_window.style.visibility = "hidden"; el_window.style.visibility = "hidden";
if (el_window.close_hook) {
el_window.close_hook();
}
}; };
var __toggleMenu = function(el_a) { var __toggleMenu = function(el_a) {