/* -*- mode: js; js-basic-offset: 4; indent-tabs-mode: nil -*- */ /* Monito Gnome-Shell extension Copyright (C) 2021 Benjamin Drieu This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. SPDX-License-Identifier: GPL-2.0-or-later */ const { Soup, Gio } = imports.gi; const ExtensionUtils = imports.misc.extensionUtils; const Lang = imports.lang; const Main = imports.ui.main; const Me = ExtensionUtils.getCurrentExtension(); const Preferences = Me.imports.prefs; var GenericServer = class { constructor ( _server, _extension, _serverType = 'Generic' ) { // this.monitoLog ( '>>> New %s server #%s'.format ( _serverType, _server ) ); this._server = _server; this._settings = Preferences.getAccountSettings ( this._server ); this._httpSession = null; this._url = null; this.extension = _extension; this.canRecheck = true; } getServer ( ) { return this._server; } buildURL ( ) { // if ( ! this._settings ) // this.monitoLog ( 'monito build URL' ); this._settings = Preferences.getAccountSettings ( this._server ); if ( this.type != this._settings.get_string ( "type" ) || this.username != this._settings.get_string ( "username" ) || this.strict_ssl != this._settings.get_boolean ( "strict-ssl" ) || this.name != this._settings.get_string ( "name" ) || this.password != this._settings.get_string ( "password" ) || this.urlcgi != this._settings.get_string ( "urlcgi" ) || this.proxy != this._settings.get_string ( "proxy" ) ) { this.type = this._settings.get_string ( "type" ); this.username = this._settings.get_string ( "username" ); this.strict_ssl = this._settings.get_boolean ( "strict-ssl" ); this.name = this._settings.get_string ( "name" ); this.password = this._settings.get_string ( "password" ); this.urlcgi = this._settings.get_string ( "urlcgi" ); this.proxy = this._settings.get_string ( "proxy" ); this._httpSession = null; this.monitoLog ( 'Refreshing URL parameters' ); } // this.monitoLog ( 'monito server >>> ' + this._server ); // this.monitoLog ( 'monito name >>> ' + this.name ); // this.monitoLog ( 'monito type >>> ' + this.type ); // this.monitoLog ( 'monito username >>> ' + this.username ); // this.monitoLog ( 'monito urlcgi >>> ' + this.urlcgi ); } prepareHttp ( ) { if ( this._httpSession == null ) { this.monitoLog ( 'Preparing new HTTP with strict SSL ' + this.strict_ssl ); this._httpSession = new Soup.SessionSync(); this._httpSession.timeout = 5; if ( this.proxy ) { this.monitoLog ( 'monito Proxy ' + this.proxy + ' for ' + this.name ); let proxy = new Gio.SimpleProxyResolver ( { default_proxy: this.proxy } ); //let proxy = new Gio.SimpleProxyResolver ( { default_proxy: 'socks://127.0.0.1:3128' } ); this._httpSession.proxy_resolver = proxy; } // Soup.Session.prototype.add_feature.call(this._httpSession, new Soup.SimpleProxyResolver()); this._httpSession.ssl_strict = this.strict_ssl; this._httpSession.user_agent = Me.metadata.uuid; } } authenticateAndSend ( message, callback = this.handleMessage ) { let auth = new Soup.AuthBasic() auth.authenticate ( this.username, this.password ); message.request_headers.append ( "Authorization", auth.get_authorization ( message ) ); // this.monitoLog ( 'Sending message' ); this._httpSession.queue_message ( message, Lang.bind (this, callback ) ); } handleMessage ( _httpSession, message ) { this.status = { }; this.status.service_status = [ ]; this.error = null; // this.monitoLog ( message.status_code ); // this.monitoLog ( message.response_body ); <<<<<<< HEAD message.response_headers.foreach ((name, val) => { // this.monitoLog (name, val); }); ======= // message.response_headers.foreach ((name, val) => { // this.monitoLog (name, val); // }); >>>>>>> 0d8113e52b9d6e05fe8ad6a0c7dab045291ac987 // this.monitoLog ( message.response_body.data ); if ( message.status_code != Soup.Status.OK ) { this.monitoLog ( '>>> Error: ' + message.reason_phrase ); //this.monitoLog ( '>>> Data: ' + message.data ); // TODO: add pref for that // Main.notifyError ( 'Monito: ' + this.name, // 'URL: ' + this.urlcgi + "\n" + // message.status_code + ': ' + message.reason_phrase ); this.error = message.reason_phrase; return null; } else { return message.response_body.data; } } handleCMDMessage ( _httpSession, message ) { let _data; try { _data = this.handleMessage ( _httpSession, message ); if ( this.error ) this.monitoLog ( 'Parent error ' + this.error ); else { // if error, grep for class='errorMessage' // else grep for class='successBox' // this.monitoLog ( 'Cmd output ' + _data ); } } catch ( e ) { this.monitoLog ( e ); this.monitoLog ( _data ); } if ( message.button ) this.extension.stopChildSpin ( message.button ); } getProcessedStatus ( ) { let status = this.status.service_status; this.columns = Preferences.getColumns ( this._server ); this.sortOrder = Preferences.getSortOrder ( this._server ); status = this.filterStatus ( status ); status = status.sort ( Lang.bind ( this, this.compareServices ) ); return status; } filterStatus ( status ) { let filters = [ { prefKey: 'service-grep', entryKey: 'service_display_name', positive: true }, { prefKey: 'service-filter-out', entryKey: 'service_display_name', positive: false }, { prefKey: 'host-grep', entryKey: 'host_name', positive: true }, { prefKey: 'host-filter-out', entryKey: 'host_name', positive: false }, { prefKey: 'status-info-grep', entryKey: 'status_information', positive: true }, { prefKey: 'status-info-filter-out', entryKey: 'status_information', positive: false } ]; for ( var _filter of filters ) _filter.value = this._settings.get_string ( _filter.prefKey ); entries: for ( var i = 0 ; i < status.length ; i ++ ) { if ( status[i]['has_been_acknowledged'] && this._settings.get_boolean ( 'acknowledged-filter-out' ) ) { // this.monitoLog ( '> ACKED:%s ' . format ( status[i]['service_display_name'] ) ); status.splice ( i, 1 ); i --; // This has been removed, so get back one step. continue entries; } for ( var _filter of filters ) { if ( _filter['value'] && ( status[i][_filter['entryKey']].match ( new RegExp ( _filter['value'], 'i' ) ) <= 0 ) == _filter['positive'] ) { status.splice ( i, 1 ); i --; // This has been removed, so get back one step. continue entries; } } } return status; } compareServices ( a, b ) { for ( let _comparison of this.sortOrder ) { let _name = _comparison.substring ( 0, _comparison.length - 1 ); let _order = _comparison.substring ( _comparison.length - 1, _comparison.length ); if ( _name && _order && _name in a && _name in b ) { if ( ! a [ _name ] ) return 1; let _result = a [ _name ] . localeCompare ( b [ _name ] ); if ( _result != 0 ) { if ( _order == '-' ) return - _result; else return _result; } } } return 0; } formatDate ( date ) { if ( typeof date == 'string' || date instanceof String ) date = Date.parse ( date ) / 1000; return this.timeAgo ( new Date ( date * 1000 ) ); } getFormattedDate(date, prefomattedDate = false, hideYear = false) { const MONTH_NAMES = [ 'Jan.', 'Feb.', 'Mar.', 'Apr.', 'May', 'Jun.', 'Jul.', 'Aug.', 'Sep.', 'Oct.', 'Nov.', 'Dec.' ]; const day = date.getDate(); const month = MONTH_NAMES[date.getMonth()]; const year = date.getFullYear(); const hours = date.getHours(); let minutes = date.getMinutes(); if (minutes < 10) { // Adding leading zero to minutes minutes = _(`0${ minutes }`); } if (prefomattedDate) { // Today at 10:20 // Yesterday at 10:20 return _(`${ prefomattedDate } at ${ hours }:${ minutes }`); } if (hideYear) { // 10. January at 10:20 return _(`${ month } ${ day } at ${ hours }:${ minutes }`); } // 10. January 2017. at 10:20 return _(`${ year } ${ month } ${ day }`); } timeAgo ( dateParam ) { if (!dateParam) { return null; } const date = typeof dateParam === 'object' ? dateParam : new Date(dateParam); const DAY_IN_MS = 86400000; // 24 * 60 * 60 * 1000 const today = new Date(); const yesterday = new Date(today - DAY_IN_MS); const seconds = Math.round((today - date) / 1000); const minutes = Math.round(seconds / 60); const isToday = today.toDateString() === date.toDateString(); const isYesterday = yesterday.toDateString() === date.toDateString(); const isThisYear = today.getFullYear() === date.getFullYear(); if (seconds < 5) { return 'now'; } else if (seconds < 60) { return `${ seconds } seconds ago`; } else if (seconds < 90) { return 'a minute ago'; } else if (minutes < 60) { return `${ minutes } minutes ago`; } else if (isToday) { return this.getFormattedDate(date, 'today'); // Today at 10:20 } else if (isYesterday) { return this.getFormattedDate(date, 'yesterday'); // Yesterday at 10:20 } else if (isThisYear) { return this.getFormattedDate(date, false, true); // 10. January at 10:20 } return this.getFormattedDate(date); // 10. January 2017. at 10:20 } monitoLog ( msg ) { log ( 'Monito: ' + msg ); // eslint-disable-line no-undef } }