$ nmap -p 8888 127.0.0.1Starting Nmap 7.80 ( https://nmap.org ) at 2022-06-01 12:12 CESTNmap scan report for localhost (127.0.0.1)Host is up (0.00013s latency).PORT STATE SERVICE8888/tcp open sun-answerbookNmap done: 1 IP address (1 host up) scanned in 0.07 seconds
$ nmap -p 8888 127.0.0.1Starting Nmap 7.80 ( https://nmap.org ) at 2022-06-01 12:13 CESTNmap scan report for localhost (127.0.0.1)Host is up (0.00012s latency).PORT STATE SERVICE8888/tcp closed sun-answerbookNmap done: 1 IP address (1 host up) scanned in 0.06 seconds
while [ 1 ]; do nc -zv 127.0.0.1 8888 2>/dev/nullif [ "$?" -ne "0" ]; then zenity --info --text="$(date) nedostupny port"; fisleep 30sdone
systemd user service
const { GObject, St, Clutter, GLib, Gio } = imports.gi;const ExtensionUtils = imports.misc.extensionUtils;const Me = ExtensionUtils.getCurrentExtension();const ByteArray = imports.byteArray;const Util = imports.misc.util;const Main = imports.ui.main;const PanelMenu = imports.ui.panelMenu;const PopupMenu = imports.ui.popupMenu;const Gettext = imports.gettext;const Domain = Gettext.domain(Me.metadata.uuid);const _ = Domain.gettext;const Status = { ONLINE: 1, OFFLINE: 2, ERROR: 3, UNDEFINED: 4,};const Icon = { ONLINE: 'online.svg', OFFLINE: 'offline.svg', ERROR: 'error.svg', UNDEFINED: 'undefined.svg',};const Settings = { SERVER_MAC: 'servermac', SERVER_IP: 'serverip', SERVER_POLL: 'serverpoll',};const HomeServer = GObject.registerClass( class HomeServerIndicator extends PanelMenu.Button { _init() { super._init(0.0, _('Server')); this._indicatorStatus = { lastResponse: null, status: Status.UNDEFINED, }; this._settings = ExtensionUtils.getSettings(); this._isConnected = false; this._setupWidgets(); this._mainLoop(); this._startMainLoop(); } _setupWidgets() { this._menuLayout = new St.BoxLayout(); this._ServerIcon = new St.Icon({ style_class: 'system-status-icon' }); this._setIndicatorIcon(Icon.UNDEFINED); this._menuLayout.add_actor(this._ServerIcon); this.add_actor(this._menuLayout); this._setupPopupMenu(); } _setupPopupMenu() { this._settingsMenuItem = new PopupMenu.PopupMenuItem(_('Settings')); this._settingsMenuItem.connect('activate', () => { const extensionManager = imports.ui.main.extensionManager; extensionManager.openExtensionPrefs(Me.uuid, '', {}); }); this.menu.addMenuItem(this._settingsMenuItem); } _setIndicatorIcon(iconFileName) { const iconPath = Me.dir .get_child('icons') .get_child(iconFileName) .get_path(); this._ServerIcon.set_gicon(Gio.Icon.new_for_string(iconPath)); } _setIndicator(status) { if (status == Status.ONLINE) { if ( this._indicatorStatus.status !== Status.ONLINE ) { this._setIndicatorIcon(Icon.ONLINE); this._log('Set status ONLINE'); this._indicatorStatus.status = Status.ONLINE; if (this._wakeonlanMenuItem) { this._log('Remove WOL menu item'); this._wakeonlanMenuItem.disconnect(); this._wakeonlanMenuItem.destroy(); } } return; } if (status == Status.OFFLINE) { if ( this._indicatorStatus.status !== Status.OFFLINE ) { this._setIndicatorIcon(Icon.OFFLINE); this._log('Set status OFFLINE'); this._indicatorStatus.status = Status.OFFLINE; if (!this._wakeonlanMenuItem) { this._log('Add WOL menu item'); this._wakeonlanMenuItem = new PopupMenu.PopupMenuItem(_('Start Server')); this._wakeonlanMenuItem.connect('activate', () => { this._wakeup(); }); this.menu.addMenuItem(this._wakeonlanMenuItem); } } return; } if (status == Status.ERROR) { if ( this._indicatorStatus.status !== Status.ERROR ) { this._setIndicatorIcon(Icon.ERROR); this._log('Set status ERROR'); this._indicatorStatus.status = Status.ERROR; if (this._wakeonlanMenuItem) { this._log('Remove WOL menu item'); this._wakeonlanMenuItem.disconnect(); this._wakeonlanMenuItem.destroy(); } } return; } if (status == Status.UNDEFINED) { if ( this._indicatorStatus.status !== Status.UNDEFINED ) { this._setIndicatorIcon(Icon.UNDEFINED); this._log('Set status UNDEFINED'); this._indicatorStatus.status = Status.UNDEFINED; if (this._wakeonlanMenuItem) { this._log('Remove WOL menu item'); this._wakeonlanMenuItem.disconnect(); this._wakeonlanMenuItem.destroy(); } } return; } } _wakeup() { try { let proc = Gio.Subprocess.new( ['wakeonlan', this._settings.get_string('servermac')], Gio.SubprocessFlags.STDOUT_PIPE | Gio.SubprocessFlags.STDERR_PIPE); proc.communicate_utf8_async(null, null, (proc, res) => { try { Main.notify(Me.metadata.name, _('Start Server now. Please wait...')) let [, stdout, stderr] = proc.communicate_utf8_finish(res); } catch (e) { Main.notify(Me.metadata.name, _('Start Server failed')) this._log('Executing Wake On LAN failed. ' + e); } }); } catch (e) { Main.notify(Me.metadata.name, _('Start Server failed. Already installed wakeonlan?')) this._log('Wake On LAN failed. Already installed wakeonlan? ' + e); } } _startMainLoop() { this._mainLoopTimeout = GLib.timeout_add_seconds( GLib.PRIORITY_DEFAULT, this._settings.get_int(Settings.SERVER_POLL), () => { this._mainLoop(); return true; } ); } _stopMainLoop() { if (this._mainLoopTimeout) { GLib.source_remove(this._mainLoopTimeout); this._mainLoopTimeout = null; } this._connection = null; } async _mainLoop() { let ip = this._settings.get_string('serverip') let cmd = []; if ( this._isConnected == true ) { this._log('Connection established'); cmd = ['sh', '-c', `ping -q -c1 -w5 ${ip} >/dev/null 2>&1`]; } else { this._log('Awaiting established connection'); cmd = ['sh', '-c', 'ping -q -c1 -w1 `ip r | grep default | cut -d " " -f 3` >/dev/null 2>&1 && exit 0 || exit 1']; } try { let proc = Gio.Subprocess.new(cmd, Gio.SubprocessFlags.STDOUT_PIPE | Gio.SubprocessFlags.STDERR_PIPE); proc.communicate_utf8_async(null, null, (proc, res) => { try { if (proc.get_successful()) { if ( this._isConnected == true ) { this._log('Ping success'); this._setIndicator(Status.ONLINE); } else { this._isConnected = true; this._setIndicator(Status.UNDEFINED); } } else { if ( this._isConnected == true ) { this._log('Ping failed'); this._setIndicator(Status.OFFLINE); } else { this._setIndicator(Status.UNDEFINED); } } } catch (e) { this._setIndicator(Status.UNDEFINED); if ( this._isConnected == true ) { this._log('Ping failed. ' + e); } else { this._log('Awaiting connection failed. ' + e); } } }); } catch (e) { this._setIndicator(Status.ERROR); if ( this._isConnected == true ) { this._log('Ping failed. ' + e); } else { this._log('Awaiting connection failed. ' + e); } } } _log(msg) { if (this._settings.get_boolean('serverdebug')) { log(`${Me.metadata.name}: ${msg}`); } } _onDestroy() { this._log('Indicator._onDestroy()'); this._stopMainLoop(); this._menuLayout = null; this._indicatorStatus = null; this._settings = null; super._onDestroy(); } });class Extension { constructor(uuid) { this._uuid = uuid; } enable() { this._homeServerIndicator = new HomeServer(); Main.panel.addToStatusArea(this._uuid, this._homeServerIndicator); } disable() { this._homeServerIndicator.destroy(); this._homeServerIndicator = null; }}function init(meta) { ExtensionUtils.initTranslations(Me.metadata.uuid); return new Extension(meta.uuid);}