Skip to content

Commit

Permalink
some refactoring and additional tests
Browse files Browse the repository at this point in the history
  • Loading branch information
philipphoffmann committed May 4, 2014
1 parent 0f20408 commit 1f2d879
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 142 deletions.
12 changes: 6 additions & 6 deletions extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ let event_signals = [];
const _httpSession = new Soup.SessionAsync();
Soup.Session.prototype.add_feature.call(_httpSession, new Soup.ProxyResolverDefault());

function createIndicator(server_num)
{
function createIndicator(server_num) {
// create indicator and add to status area
_indicators[server_num] = new JenkinsIndicator.JenkinsIndicator(settingsJSON['servers'][server_num], _httpSession);
Main.panel.addToStatusArea("jenkins-indicator-"+settingsJSON['servers'][server_num]['id'], _indicators[server_num]);
Expand Down Expand Up @@ -71,21 +70,22 @@ function enable() {
});

// update all indicators
for( let i=0 ; i<_indicators.length ; ++i )
{
for( let i=0 ; i<_indicators.length ; ++i ) {
_indicators[i].updateSettings(settingsJSON['servers'][i]);
_indicators[i].request();
}
}) );
}

function disable() {
for( var i=0 ; i<_indicators.length ; ++i )
for( var i=0 ; i<_indicators.length ; ++i ) {
_indicators[i].destroy();
}

_indicators = [];

// disconnect all signal listeners
for( var i=0 ; i<event_signals.length ; ++i )
for( var i=0 ; i<event_signals.length ; ++i ) {
settings.disconnect(event_signals[i]);
}
}
15 changes: 5 additions & 10 deletions prefs.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ function init() {
}

// builds a line (icon + label + switch) for a setting
function buildIconSwitchSetting(icon, label, setting_name, server_num)
{
function buildIconSwitchSetting(icon, label, setting_name, server_num) {
let hboxFilterJobs = new Gtk.Box({orientation: Gtk.Orientation.HORIZONTAL});
let iconFilterJobs = new Gtk.Image({file: Me.dir.get_path() + "/icons/prefs/" + icon + ".png"});
let labelFilterJobs = new Gtk.Label({label: label, xalign: 0});
Expand All @@ -37,16 +36,14 @@ function buildIconSwitchSetting(icon, label, setting_name, server_num)
}

// update json settings for server in settings schema
function updateServerSetting(server_num, setting, value)
{
function updateServerSetting(server_num, setting, value) {
settingsJSON = Settings.getSettingsJSON(settings);
settingsJSON["servers"][server_num][setting] = value;
settings.set_string("settings-json", JSON.stringify(settingsJSON));
}

// create a new server tab and add it to the notebook
function addTabPanel(notebook, server_num)
{
function addTabPanel(notebook, server_num) {
// use server name as tab label
let tabLabel = new Gtk.Label({ label: settingsJSON['servers'][server_num]['name']});

Expand Down Expand Up @@ -245,8 +242,7 @@ function addTabPanel(notebook, server_num)
let btnRemoveServer = new Gtk.Button({image: iconRemoveServer});

btnRemoveServer.connect('clicked', Lang.bind(notebook, function(){
if( notebook.get_n_pages()>1 )
{
if( notebook.get_n_pages()>1 ) {
// remove server from settings
settingsJSON['servers'].splice(notebook.page_num(tabContent), 1);
settings.set_string("settings-json", JSON.stringify(settingsJSON));
Expand Down Expand Up @@ -274,8 +270,7 @@ function buildPrefsWidget() {
// *** tab panel ***
let notebook = new Gtk.Notebook();

for( let i=0 ; i<settingsJSON['servers'].length ; ++i )
{
for( let i=0 ; i<settingsJSON['servers'].length ; ++i ) {
// add tab panels for each server
addTabPanel(notebook, i);
}
Expand Down
102 changes: 64 additions & 38 deletions src/helpers/utils.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
// append a uri to a domain regardless whether domains ends with '/' or not
function urlAppend(domain, uri)
{
if( domain.length>=1 )
function urlAppend(domain, uri) {
if( domain.length>=1 ) {
return domain + (domain.charAt(domain.length-1)!='/' ? '/' : '') + uri;
else
}
else {
return uri;
}
}

// call operation on all elements of array2 which are not in array1 using a compare function
function arrayOpCompare(array1, array2, compare_func, operation_func)
{
for( var i=0 ; i<array1.length ; ++i )
{
function arrayOpCompare(array1, array2, compare_func, operation_func) {
for( var i=0 ; i<array1.length ; ++i ) {
let found_in_array2 = false;
for( var j=0 ; j<array2.length ; ++j )
{
if( compare_func(array1[i], array2[j]) )

for( var j=0 ; j<array2.length ; ++j ) {
if( compare_func(array1[i], array2[j]) ) {
found_in_array2 = true;
}
}

if( !found_in_array2 )
if( !found_in_array2 ) {
operation_func(i, array1[i]);
}
}
}

Expand Down Expand Up @@ -48,8 +49,36 @@ function versionIsAtLeast(currentVersion, thresholdVersion) {
return true;
}

// filters jobs according to filter settings
function filterJobs(jobs, settings) {
jobs = jobs || [];
let showAllJobs = false;
let filteredJobs = [];
let jobToShow = settings['jobs_to_show'].trim().split(",");

if ((jobToShow.length == 1) && jobToShow[0] == "all") {
showAllJobs = true;
}

for (var i=0 ; i<jobs.length ; ++i) {
// filter job if user decided not to show jobs with this state (in settings dialog)
let filterJobState = settings[jobStates.getFilter(jobs[i].color)];
// filter job if user decided not to show jobs with this name (in settings dialog)
let filterJobByName = true;
if (!showAllJobs) {
filterJobByName = jobMatches(jobs[i], jobToShow);
}

if(filterJobState && filterJobByName){
filteredJobs[filteredJobs.length] = jobs[i];
}
}

return filteredJobs;
}

// return if a job matches a list of patterns ('!' char negates a pattern)
function jobMatches(job, patterns){
function jobMatches(job, patterns) {
var patternsLength = patterns.length;
for (var i = 0; i < patternsLength; i++) {
var pattern = patterns[i];
Expand Down Expand Up @@ -94,62 +123,59 @@ const jobStates = new function() {

// returns the rank of a job state, highest rank is 0, -1 means that the job state is unknown
// this is used to determine the state of the overall indicator which shows the state of the highest ranked job
this.getRank = function(job_color)
{
for( let i=0 ; i<states.length ; ++i )
{
this.getRank = function(job_color) {
for( let i=0 ; i<states.length ; ++i ) {
if( job_color==states[i].color ) return i;
}
return -1;
};

// returns the corresponding icon name of a job state
this.getIcon = function(job_color, with_green_balls)
{
for( let i=0 ; i<states.length ; ++i )
{
this.getIcon = function(job_color, with_green_balls) {
for( let i=0 ; i<states.length ; ++i ) {
// use green balls plugin if actived
if( with_green_balls && job_color=='blue' ) return 'jenkins_green';

if( with_green_balls && job_color=='blue' ) {
return 'jenkins_green';
}
// if not just return a regular icon
else if( job_color==states[i].color ) return 'jenkins_' + states[i].icon;
else if( job_color==states[i].color ) {
return 'jenkins_' + states[i].icon;
}
}
// if job color is unknown, use the grey icon
return 'jenkins_grey';
};

// returns the corresponding icon name of a job state
this.getFilter = function(job_color)
{
for( let i=0 ; i<states.length ; ++i )
{
if( job_color==states[i].color ) return states[i].filter;
this.getFilter = function(job_color) {
for( let i=0 ; i<states.length ; ++i ) {
if( job_color==states[i].color ) {
return states[i].filter;
}
}
// if job color is unknown, use the filter setting for disabled jobs
return 'show_disabled_jobs';
};

// returns the corresponding icon name of a job state
this.getName = function(job_color)
{
for( let i=0 ; i<states.length ; ++i )
{
if( job_color==states[i].color ) return _(states[i].name);
this.getName = function(job_color) {
for( let i=0 ; i<states.length ; ++i ) {
if( job_color==states[i].color ) {
return _(states[i].name);
}
}
// if job color is unknown, use the filter setting for disabled jobs
return 'unknown';
};

// returns the default job state to use for overall indicator
this.getDefaultState = function()
{
this.getDefaultState = function() {
// return lowest ranked job state
return states[states.length-1].color;
};

// return the color of the error state for the overall indicator
this.getErrorState = function()
{
this.getErrorState = function() {
return "red";
};
};
66 changes: 17 additions & 49 deletions src/jenkinsIndicator.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ const JenkinsIndicator = new Lang.Class({
// create new main loop
this._mainloop = Mainloop.timeout_add(this.settings.autorefresh_interval*1000, Lang.bind(this, function(){
// request new job states if auto-refresh is enabled
if( this.settings.autorefresh )
if( this.settings.autorefresh ) {
this.request();
}

// returning true is important for restarting the mainloop after timeout
return true;
Expand All @@ -70,28 +71,25 @@ const JenkinsIndicator = new Lang.Class({
// request local jenkins server for current state
request: function() {
// only update if no update is currently running
if( !this._isRequesting )
{
if( !this._isRequesting ) {
this._isRequesting = true;
// ajax request to local jenkins server
let request = Soup.Message.new('GET', Utils.urlAppend(this.settings.jenkins_url, 'api/json'));

// append authentication header (if necessary)
// jenkins only supports preemptive authentication so we have to provide authentication info on first request
if( this.settings.use_authentication )
if( this.settings.use_authentication ) {
request.request_headers.append('Authorization', 'Basic ' + Glib.base64_encode(this.settings.auth_user + ':' + this.settings.api_token));
}

if( request )
{
if( request ) {
this.httpSession.queue_message(request, Lang.bind(this, function(httpSession, message) {
// http error
if( message.status_code!==200 )
{
if( message.status_code!==200 ) {
this.showError(_("Invalid Jenkins CI Server web frontend URL (HTTP Error %s)").format(message.status_code));
}
// http ok
else
{
else {
// parse json
try {
let jenkinsState = JSON.parse(request.response_body.data);
Expand All @@ -102,8 +100,7 @@ const JenkinsIndicator = new Lang.Class({
// update indicator (icon and popupmenu contents)
this.update();
}
catch( e )
{
catch( e ) {
global.log(e)
this.showError(_("Invalid Jenkins CI Server web frontend URL"));
}
Expand All @@ -114,8 +111,7 @@ const JenkinsIndicator = new Lang.Class({
}));
}
// no valid url was provided in settings dialog
else
{
else {
this.showError(_("Invalid Jenkins CI Server web frontend URL"));

// we're done updating and ready for the next request
Expand All @@ -127,7 +123,7 @@ const JenkinsIndicator = new Lang.Class({
// update indicator icon and popupmenu contents
update: function() {
// filter jobs to be shown
let displayJobs = this._filterJobs(this.jobs);
let displayJobs = Utils.filterJobs(this.jobs, this.settings);

// update popup menu
this.menu.updateJobs(displayJobs);
Expand All @@ -138,51 +134,23 @@ const JenkinsIndicator = new Lang.Class({
let overallState = Utils.jobStates.getDefaultState();

// set state to red if there are no jobs
if( displayJobs.length<=0 )
if( displayJobs.length<=0 ) {
overallState = Utils.jobStates.getErrorState();
else
{
}
else {
// determine jobs overall state for the indicator
for( let i=0 ; i<displayJobs.length ; ++i )
{
for( let i=0 ; i<displayJobs.length ; ++i ) {
// set overall job state to highest ranked (most important) state
if( Utils.jobStates.getRank(displayJobs[i].color)>-1 && Utils.jobStates.getRank(displayJobs[i].color)<Utils.jobStates.getRank(overallState) )
if( Utils.jobStates.getRank(displayJobs[i].color)>-1 && Utils.jobStates.getRank(displayJobs[i].color)<Utils.jobStates.getRank(overallState) ) {
overallState = displayJobs[i].color;
}
}
}

// set new overall indicator icon representing current jenkins state
this._iconActor.icon_name = Utils.jobStates.getIcon(overallState, this.settings.green_balls_plugin);
},

// filters jobs according to filter settings
_filterJobs: function(jobs) {
jobs = jobs || [];
let showAllJobs = false;
let filteredJobs = [];
let jobToShow = this.settings['jobs_to_show'].trim().split(",");

if ((jobToShow.length == 1) && jobToShow[0] == "all") {
showAllJobs = true;
}

for (var i=0 ; i<jobs.length ; ++i) {
// filter job if user decided not to show jobs with this state (in settings dialog)
let filterJobState = this.settings[Utils.jobStates.getFilter(jobs[i].color)];
// filter job if user decided not to show jobs with this name (in settings dialog)
let filterJobByName = true;
if (!showAllJobs) {
filterJobByName = Utils.jobMatches(jobs[i], jobToShow);
}

if(filterJobState && filterJobByName){
filteredJobs[filteredJobs.length] = jobs[i];
}
}

return filteredJobs;
},

// update settings
updateSettings: function(settings) {
this.settings = settings;
Expand Down
Loading

0 comments on commit 1f2d879

Please sign in to comment.