2021-11-09 15:26:18 +01:00
/* -*- 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
2021-11-09 15:21:21 +01:00
* /
/* exported init */
const GETTEXT _DOMAIN = 'monito' ;
let _httpSession ;
let _status ;
let _ok _text ;
const Gettext = imports . gettext . domain ( GETTEXT _DOMAIN ) ;
const _ = Gettext . gettext ;
const Lang = imports . lang ;
const ExtensionUtils = imports . misc . extensionUtils ;
const Me = ExtensionUtils . getCurrentExtension ( ) ;
const Main = imports . ui . main ;
const PanelMenu = imports . ui . panelMenu ;
const PopupMenu = imports . ui . popupMenu ;
2021-11-10 17:21:03 +01:00
const { GObject , St , Soup , Clutter , Gio } = imports . gi ;
2021-11-09 15:21:21 +01:00
const SETTINGS _SCHEMA = "org.gnome.shell.extensions.monito@drieu.org" ;
const Convenience = Me . imports . convenience ;
2021-11-10 17:21:03 +01:00
const Preferences = Me . imports . prefs ;
2021-11-09 15:21:21 +01:00
let settings = Convenience . getSettings ( SETTINGS _SCHEMA ) ;
const Indicator = GObject . registerClass (
class Indicator extends PanelMenu . Button {
_init ( ) {
super . _init ( 0.0 , _ ( 'Monito Checker' ) ) ;
let box = new St . BoxLayout ( { } ) ;
this . add _child ( box ) ;
this . initStatus ( ) ;
2021-11-10 17:21:03 +01:00
this . namesBoxes = { } ;
this . warningBoxes = { } ;
this . criticalBoxes = { } ;
this . unknownBoxes = { } ;
for ( let _server of Preferences . getServersList ( ) )
{
log ( '> Server ' + _server ) ;
let _account _settings = Preferences . getAccountSettings ( _server ) ;
let serverBox = new St . BoxLayout ( { style _class : 'monito-serverbox' } ) ;
box . add _child ( serverBox ) ;
let name _box = new St . BoxLayout ( { style _class : 'monito-namebox' } ) ;
this . namesBoxes [ _server ] = new St . Label ( { text : _account _settings . get _string ( 'name' ) } ) ;
name _box . add _child ( this . namesBoxes [ _server ] ) ;
serverBox . add _child ( name _box ) ;
let warning _box = new St . BoxLayout ( { style _class : 'monito-warning-box monito-box' } ) ;
this . warningBoxes [ _server ] = new St . Label ( { text : String ( _status [ 'WARNING' ] ) } )
warning _box . add _child ( this . warningBoxes [ _server ] ) ;
serverBox . add _child ( warning _box ) ;
let critical _box = new St . BoxLayout ( { style _class : 'monito-critical-box monito-box' } ) ;
this . criticalBoxes [ _server ] = new St . Label ( { text : String ( _status [ 'CRITICAL' ] ) } )
critical _box . add _child ( this . criticalBoxes [ _server ] ) ;
serverBox . add _child ( critical _box ) ;
}
2021-11-09 15:21:21 +01:00
box . add _child ( PopupMenu . arrowIcon ( St . Side . BOTTOM ) ) ;
// Menu
this . _buttonMenu = new PopupMenu . PopupBaseMenuItem ( {
reactive : false ,
style _class : 'monito-menu-button-container' ,
} ) ;
this . menu . addMenuItem ( this . _buttonMenu ) ;
// let item = new PopupMenu.PopupMenuItem(_('Reload'));
// item.connect('activate', () => {
// this.updateStatus ( );
// });
// this.menu.addMenuItem(item);
2021-11-10 17:21:03 +01:00
let _path = Me . path + '/img/monito.png' ;
let _icon = new St . Icon ( {
gicon : Gio . icon _new _for _string ( _path ) ,
} ) ;
let _iconBin = new St . Bin ( ) ;
_iconBin . child = _icon ;
this . _buttonMenu . actor . add _actor ( _iconBin ) ;
2021-11-09 15:21:21 +01:00
this . _mainLabel = new St . Label ( { style _class : 'monito-title' , text : 'Monito Checker' , x _expand : true } ) ;
this . _buttonMenu . actor . add _actor ( this . _mainLabel ) ;
this . _prefsButton = this . _createButton ( 'preferences-system-symbolic' , 'Preferences' , this . _onPreferencesActivate ) ;
this . _buttonMenu . actor . add _child ( this . _prefsButton ) ;
this . _reloadButton = this . _createButton ( 'view-refresh-symbolic' , 'Reload' , this . updateStatus ) ;
this . _buttonMenu . actor . add _child ( this . _reloadButton ) ;
let _intermediate = new PopupMenu . PopupBaseMenuItem ( {
style _class : 'monito-services' ,
reactive : false
} ) ;
this . menu . addMenuItem ( _intermediate ) ;
this . _box = new St . BoxLayout ( {
style _class : 'monito-services' ,
vertical : true ,
x _expand : true
} ) ;
_intermediate . actor . add _actor ( this . _box ) ;
this . updateStatus ( ) ;
}
initStatus ( ) {
_status = { 'OK' : 0 ,
'WARNING' : 0 ,
'CRITICAL' : 0 ,
'UNKNOWN' : 0 } ;
}
updateStatus ( ) {
2021-11-10 17:21:03 +01:00
for ( let _server of Preferences . getServersList ( ) )
{
let account _settings = Preferences . getAccountSettings ( _server ) ;
let username = account _settings . get _string ( "username" ) ;
let password = account _settings . get _string ( "password" ) ;
let urlcgi = account _settings . get _string ( "urlcgi" ) ;
if ( ! urlcgi )
{
log ( 'Not updating monito because no URL configured' ) ;
return ;
}
urlcgi = urlcgi . replace ( /^(https?:\/\/)/ , '$1' + username + ':' + password + '@' ) ;
log ( 'monito >>> ' + urlcgi ) ;
this . load _data _async ( _server , urlcgi , { 'jsonoutput' : '' } ) ;
}
2021-11-09 15:21:21 +01:00
}
2021-11-10 17:21:03 +01:00
createBin ( status , text , col ) {
2021-11-09 15:21:21 +01:00
let _widths = [ 300 , 300 , 200 , 50 , 600 ] ;
let _bin = new St . Bin ( {
style _class : 'monito-service-' + status ,
width : _widths [ col ] ,
x _expand : ( col == 4 ? true : false ) ,
child : new St . Label ( { style _class : 'monito-label' , text : text } )
} ) ;
return _bin ;
}
2021-11-10 17:21:03 +01:00
load _data _async ( server , url , params ) {
2021-11-09 15:21:21 +01:00
if ( _httpSession === undefined ) {
_httpSession = new Soup . Session ( ) ;
_httpSession . user _agent = Me . metadata . uuid ;
2021-11-10 17:21:03 +01:00
}
2021-11-09 15:21:21 +01:00
let message = Soup . form _request _new _from _hash ( 'GET' , url , params ) ;
_httpSession . queue _message ( message , Lang . bind ( this , function ( _httpSession , message ) {
2021-11-10 17:21:03 +01:00
// Main.notify(message.response_body.data);
log ( '>>> ' + message . response _body . data ) ;
2021-11-09 15:21:21 +01:00
try {
// log ( message.response_body.data );
let json = JSON . parse ( message . response _body . data ) ;
this . initStatus ( ) ;
this . _box . remove _all _children ( ) ;
for ( let i = 0 ; i < json . status . service _status . length ; i ++ )
{
_status [ json . status . service _status [ i ] . status ] ++ ;
if ( json . status . service _status [ i ] . status != 'OK' )
{
let infoBox = new St . BoxLayout ( {
style _class : 'monito-service-line monito-service-line-' + json . status . service _status [ i ] . status ,
hover : true ,
x _expand : true
} ) ;
this . _box . add _child ( infoBox ) ;
infoBox . add _child ( this . createBin ( json . status . service _status [ i ] . status ,
json . status . service _status [ i ] . host _name ,
0 ) ) ;
infoBox . add _child ( this . createBin ( json . status . service _status [ i ] . status ,
json . status . service _status [ i ] . service _display _name ,
1 ) ) ;
infoBox . add _child ( this . createBin ( json . status . service _status [ i ] . status ,
json . status . service _status [ i ] . last _check ,
2 ) ) ;
infoBox . add _child ( this . createBin ( json . status . service _status [ i ] . status ,
json . status . service _status [ i ] . attempts ,
3 ) ) ;
infoBox . add _child ( this . createBin ( json . status . service _status [ i ] . status ,
json . status . service _status [ i ] . status _information ,
4 ) ) ;
// let url = 'https://xxx:xxx@host/cgi-bin/icinga/extinfo.cgi?type=2&host='+json.status.service_status[i].host_name+"&service="+json.status.service_status[i].service_description;
// activeLabel.connect('button-press-event', () => {
// Main.notify(url);
// Gtk.show_uri(null, url, global.get_current_time());
// } );
}
}
// _ok_text.set_text ( String(_status.OK) );
2021-11-10 17:21:03 +01:00
this . warningBoxes [ server ] . set _text ( String ( _status . WARNING ) ) ;
this . criticalBoxes [ server ] . set _text ( String ( _status . CRITICAL ) ) ;
2021-11-09 15:21:21 +01:00
} catch ( e ) {
Main . notify ( _ ( 'Zbeu!' ) ) ;
2021-11-10 17:21:03 +01:00
this . warningBoxes [ server ] . set _text ( '…' ) ;
this . criticalBoxes [ server ] . set _text ( '…' ) ;
2021-11-09 15:21:21 +01:00
log ( e ) ;
return ;
}
} ) ) ;
return ;
}
2021-11-10 17:21:03 +01:00
_onPreferencesActivate ( ) {
2021-11-09 15:21:21 +01:00
this . menu . actor . hide ( ) ;
if ( typeof ExtensionUtils . openPrefs === 'function' ) {
ExtensionUtils . openPrefs ( ) ;
} else {
Util . spawn ( [
"gnome-shell-extension-prefs" ,
Me . uuid
] ) ;
}
return 0 ;
}
_createButton ( icon , text , callback ) {
let button = new St . Button ( {
x _align : Clutter . ActorAlign . END ,
y _align : Clutter . ActorAlign . CENTER ,
reactive : true ,
can _focus : true ,
track _hover : true ,
accessible _name : text ,
style _class : 'button'
} ) ;
button . child = new St . Icon ( {
style _class : 'monito-button-icon' ,
icon _name : icon ,
icon _size : 24 ,
width : 24 ,
height : 24 ,
} ) ;
button . connect ( 'clicked' , Lang . bind ( this , callback ) ) ;
return button ;
}
} ) ;
class Extension {
constructor ( uuid ) {
this . _uuid = uuid ;
ExtensionUtils . initTranslations ( GETTEXT _DOMAIN ) ;
}
enable ( ) {
this . _indicator = new Indicator ( ) ;
2021-11-10 17:21:03 +01:00
2021-11-09 15:21:21 +01:00
Main . panel . addToStatusArea ( this . _uuid , this . _indicator ) ;
}
disable ( ) {
this . _indicator . destroy ( ) ;
this . _indicator = null ;
if ( _httpSession !== undefined )
_httpSession . abort ( ) ;
_httpSession = undefined ;
}
}
function init ( meta ) {
return new Extension ( meta . uuid ) ;
}