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 ;
let _warning _text ;
let _critical _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 ;
const { GObject , St , Soup , Clutter } = imports . gi ;
const SETTINGS _SCHEMA = "org.gnome.shell.extensions.monito@drieu.org" ;
const Convenience = Me . imports . convenience ;
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 ( ) ;
// Main Box
/ *
let ok _box = new St . BoxLayout ( { style _class : 'monito-ok-box monito-box' } ) ;
_ok _text = new St . Label ( { text : String ( _status [ 'OK' ] ) } )
ok _box . add _child ( _ok _text ) ;
box . add _child ( ok _box ) ;
* /
let warning _box = new St . BoxLayout ( { style _class : 'monito-warning-box monito-box' } ) ;
_warning _text = new St . Label ( { text : String ( _status [ 'WARNING' ] ) } )
warning _box . add _child ( _warning _text ) ;
box . add _child ( warning _box ) ;
let critical _box = new St . BoxLayout ( { style _class : 'monito-critical-box monito-box' } ) ;
_critical _text = new St . Label ( { text : String ( _status [ 'CRITICAL' ] ) } )
critical _box . add _child ( _critical _text ) ;
box . add _child ( critical _box ) ;
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);
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 ( ) {
const SETTINGS _SCHEMA _ACCOUNT = "org.gnome.shell.extensions.monito@drieu.org.account" ;
const Convenience = Me . imports . convenience ;
2021-11-10 15:52:40 +01:00
let account _settings = Convenience . getSettings ( SETTINGS _SCHEMA _ACCOUNT , '/org/gnome/shell/extensions/monito@drieu.org/account/0/' ) ;
2021-11-09 15:21:21 +01:00
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 ( urlcgi , { 'jsonoutput' : '' } , function ( res ) { Main . notify ( res ) ; } )
}
createBin ( status , text , col ) {
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 ;
}
load _data _async ( url , params , fun ) {
if ( _httpSession === undefined ) {
_httpSession = new Soup . Session ( ) ;
_httpSession . user _agent = Me . metadata . uuid ;
} else {
// abort previous requests.
_httpSession . abort ( ) ;
}
let message = Soup . form _request _new _from _hash ( 'GET' , url , params ) ;
_httpSession . queue _message ( message , Lang . bind ( this , function ( _httpSession , message ) {
//Main.notify(message.response_body.data);
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) );
_warning _text . set _text ( String ( _status . WARNING ) ) ;
_critical _text . set _text ( String ( _status . CRITICAL ) ) ;
} catch ( e ) {
Main . notify ( _ ( 'Zbeu!' ) ) ;
_warning _text . set _text ( '…' ) ;
_critical _text . set _text ( '…' ) ;
log ( e ) ;
return ;
}
} ) ) ;
return ;
}
_onPreferencesActivate ( ) {
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 ( ) ;
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 ) ;
}