<commit_before>const Applet = imports.ui.applet;
const Util = imports.misc.util;

const Lang = imports.lang
// http://developer.gnome.org/glib/unstable/glib-The-Main-Event-Loop.html
const Mainloop = imports.mainloop
const Gtk = imports.gi.Gtk
const Json = imports.gi.Json

const PopupMenu = imports.ui.popupMenu
const Settings = imports.ui.settings

// http://developer.gnome.org/st/stable/
const St = imports.gi.St

// http://developer.gnome.org/libsoup/stable/libsoup-client-howto.html
const Soup = imports.gi.Soup

const UUID = "<EMAIL>"
const MAX_JOB = 15


// Settings keys
//----------------------------------

const JENKINS_REFRESH_INTERVAL = 'refreshInterval'
const JENKINS_SSL_STRICT = 'sslStrict'
const JENKINS_URL = 'jenkinsUrl'
const JENKINS_USERNAME = 'jenkinsUsername'
const JENKINS_PASSWORD = '<PASSWORD>'

const KEYS = [
  JENKINS_REFRESH_INTERVAL,
  JENKINS_SSL_STRICT,
  JENKINS_URL,
  JENKINS_USERNAME,
  JENKINS_PASSWORD
]

// Soup session (see https://bugzilla.gnome.org/show_bug.cgi?id=661323#c64)
const _httpSession = new Soup.Session()
Soup.Session.prototype.add_feature.call(_httpSession, new Soup.ProxyResolverDefault())

function MyApplet(metadata, orientation, panel_height, instance_id) {
    this.settings = new Settings.AppletSettings(this, UUID, instance_id);
    this._init(metadata, orientation, panel_height, instance_id);
}

MyApplet.prototype = {
    __proto__: Applet.TextIconApplet.prototype,

    _init: function(metadata, orientation, panel_height, instance_id) {
        Applet.TextIconApplet.prototype._init.call(this, orientation, panel_height, instance_id);

        Gtk.IconTheme.get_default().append_search_path(metadata.path);

        // Interface: TextIconApplet
        this.set_applet_icon_name('jenkins-grey');
        this.set_applet_label('...');
        this.set_applet_tooltip(_('Jenkins status'));

        // bind settings
        //----------------------------------

        for (let k in KEYS) {
            let key = KEYS[k]
            let keyProp = "_" + key
            this.settings.bindProperty(Settings.BindingDirection.IN, key, keyProp,
                                       this.refreshAndRebuild, null)
        }

        // http auth if needed
        //----------------------------------

        let applet = this        
        _httpSession.connect("authenticate",function(session,message,auth,retrying) {
            log("Authenticating with " + applet._jenkinsUsername);
            auth.authenticate(applet._jenkinsUsername, applet._jenkinsPassword);
        });        

        // PopupMenu
        //----------------------------------

        this.menuManager = new PopupMenu.PopupMenuManager(this)
        this.menu = new Applet.AppletPopupMenu(this, orientation)
        // this.menu.actor.add_style_class_name(STYLE_WEATHER_MENU)
        this.menuManager.addMenu(this.menu)

        this.menu.addMenuItem(new PopupMenu.PopupMenuItem(_('Loading jobs...')));

        //------------------------------
        // run
        //------------------------------
        Mainloop.timeout_add_seconds(3, Lang.bind(this, function mainloopTimeout() {
          this.refreshBuildStatuses(true)
        }))
      }

    , on_applet_clicked: function() {
        this.menu.toggle();
    }

    , refreshAndRebuild: function() {
        refreshBuildStatuses(false);
    }

    , refreshBuildStatuses: function(recurse) {
        log("Loading " + this.jenkinsUrl());
        this.loadJsonAsync(this.jenkinsUrl(), function(json) {  
            this.destroyMenu();          
            try {
                let jobs = json.get_array_member('jobs').get_elements();
                let maxJobs = Math.min(jobs.length,MAX_JOB);
                let success = 0;
                for (let i = 0; i < jobs.length; i ++) {
                    if( jobs[i].get_object().get_string_member('color') == 'blue') {
                        success += 1;
                    }
                }
                let failure = jobs.length - success;

                this.updateAppletLabel(failure, success);

                if( success < jobs.length ) {
                    this.set_applet_icon_name('jenkins-red');
                }

                for (let i = 0; i < maxJobs; i ++) {                                        
                    let job = jobs[i].get_object();

                    let jobName = job.get_string_member('name');
                    let color = job.get_string_member('color');
                    let success = (color == 'blue' || color == 'blue_anime');
                    let url = job.get_string_member('url');  
                    // log("Found job " + jobName + " color=" + color + " success=" + success + " url=" + url)

                    this.menu.addMenuItem(new JobMenuItem(jobName, success, url));                    
                }
                
            } catch(error) {
                this.set_applet_icon_name('jenkins-grey');
                this.set_applet_label('!');                                
                logError(error.message)
                this.menu.addMenuItem(new PopupMenu.PopupMenuItem(error.message));
            }
        })

        if (recurse) {
            Mainloop.timeout_add_seconds(this._refreshInterval, Lang.bind(this, function() {
                this.refreshBuildStatuses(true)
            }))
        }
    }

    , updateAppletLabel: function(failure, success) {
        let appletLabel = '';
        let appletTooltip = '';

        if( failure > 0 ) {
            appletLabel += failure + '\u2717'
            appletTooltip += failure + " failing jobs"
        }
        if( success > 0 && failure > 0 ) {
            appletLabel += ' '
            appletTooltip += ' / '
        }
        if( success > 0 ) {
            appletLabel += success + '\u2713'
            appletTooltip += success + " successful jobs"
        }

        this.set_applet_label(appletLabel);
        this.set_applet_tooltip(appletTooltip);<commit_msg>factorize isColorSuccess<commit_after>const Applet = imports.ui.applet;
const Util = imports.misc.util;

const Lang = imports.lang
// http://developer.gnome.org/glib/unstable/glib-The-Main-Event-Loop.html
const Mainloop = imports.mainloop
const Gtk = imports.gi.Gtk
const Json = imports.gi.Json

const PopupMenu = imports.ui.popupMenu
const Settings = imports.ui.settings

// http://developer.gnome.org/st/stable/
const St = imports.gi.St

// http://developer.gnome.org/libsoup/stable/libsoup-client-howto.html
const Soup = imports.gi.Soup

const UUID = "<EMAIL>"
const MAX_JOB = 15


// Settings keys
//----------------------------------

const JENKINS_REFRESH_INTERVAL = 'refreshInterval'
const JENKINS_SSL_STRICT = 'sslStrict'
const JENKINS_URL = 'jenkinsUrl'
const JENKINS_USERNAME = 'jenkinsUsername'
const JENKINS_PASSWORD = '<PASSWORD>'

const KEYS = [
  JENKINS_REFRESH_INTERVAL,
  JENKINS_SSL_STRICT,
  JENKINS_URL,
  JENKINS_USERNAME,
  JENKINS_PASSWORD
]

// Soup session (see https://bugzilla.gnome.org/show_bug.cgi?id=661323#c64)
const _httpSession = new Soup.Session()
Soup.Session.prototype.add_feature.call(_httpSession, new Soup.ProxyResolverDefault())

function MyApplet(metadata, orientation, panel_height, instance_id) {
    this.settings = new Settings.AppletSettings(this, UUID, instance_id);
    this._init(metadata, orientation, panel_height, instance_id);
}

MyApplet.prototype = {
    __proto__: Applet.TextIconApplet.prototype,

    _init: function(metadata, orientation, panel_height, instance_id) {
        Applet.TextIconApplet.prototype._init.call(this, orientation, panel_height, instance_id);

        Gtk.IconTheme.get_default().append_search_path(metadata.path);

        // Interface: TextIconApplet
        this.set_applet_icon_name('jenkins-grey');
        this.set_applet_label('...');
        this.set_applet_tooltip(_('Jenkins status'));

        // bind settings
        //----------------------------------

        for (let k in KEYS) {
            let key = KEYS[k]
            let keyProp = "_" + key
            this.settings.bindProperty(Settings.BindingDirection.IN, key, keyProp,
                                       this.refreshAndRebuild, null)
        }

        // http auth if needed
        //----------------------------------

        let applet = this        
        _httpSession.connect("authenticate",function(session,message,auth,retrying) {
            log("Authenticating with " + applet._jenkinsUsername);
            auth.authenticate(applet._jenkinsUsername, applet._jenkinsPassword);
        });        

        // PopupMenu
        //----------------------------------

        this.menuManager = new PopupMenu.PopupMenuManager(this)
        this.menu = new Applet.AppletPopupMenu(this, orientation)
        // this.menu.actor.add_style_class_name(STYLE_WEATHER_MENU)
        this.menuManager.addMenu(this.menu)

        this.menu.addMenuItem(new PopupMenu.PopupMenuItem(_('Loading jobs...')));

        //------------------------------
        // run
        //------------------------------
        Mainloop.timeout_add_seconds(3, Lang.bind(this, function mainloopTimeout() {
          this.refreshBuildStatuses(true)
        }))
      }

    , on_applet_clicked: function() {
        this.menu.toggle();
    }

    , refreshAndRebuild: function() {
        refreshBuildStatuses(false);
    }

    , refreshBuildStatuses: function(recurse) {
        log("Loading " + this.jenkinsUrl());
        this.loadJsonAsync(this.jenkinsUrl(), function(json) {  
            this.destroyMenu();          
            try {
                let jobs = json.get_array_member('jobs').get_elements();
                let maxJobs = Math.min(jobs.length,MAX_JOB);
                let success = this.countSuccesses(jobs);
                let failure = jobs.length - success;

                this.updateAppletLabel(failure, success);

                if (success < jobs.length) {
                    this.set_applet_icon_name('jenkins-red');
                }

                for (let i = 0; i < maxJobs; i ++) {                                        
                    let job = jobs[i].get_object();

                    let jobName = job.get_string_member('name');
                    let color = job.get_string_member('color');
                    let success = this.isColorSuccess(color);
                    let url = job.get_string_member('url');  
                    // log("Found job " + jobName + " color=" + color + " success=" + success + " url=" + url)

                    this.menu.addMenuItem(new JobMenuItem(jobName, success, url));                    
                }
                
            } catch(error) {
                this.set_applet_icon_name('jenkins-grey');
                this.set_applet_label('!');                                
                logError(error.message)
                this.menu.addMenuItem(new PopupMenu.PopupMenuItem(error.message));
            }
        })

        if (recurse) {
            Mainloop.timeout_add_seconds(this._refreshInterval, Lang.bind(this, function() {
                this.refreshBuildStatuses(true)
            }))
        }
    }

    , countSuccesses: function(jobs) {
        let success = 0;
        for (let i = 0; i < jobs.length; i ++) {
            let color = jobs[i].get_object().get_string_member('color');
            if (this.isColorSuccess(color)) {
                success += 1;
            }
        }
        return success;
    }

    , isColorSuccess: function(color) {
        return color == 'blue' || 
               color == 'blue_anime';
    }

    , updateAppletLabel: function(failure, success) {
        let appletLabel = '';
        let appletTooltip = '';

        if( failure > 0 ) {
            appletLabel += failure + '\u2717'
            appletTooltip += failure + " failing jobs"
        }
        if( success > 0 && failure > 0 ) {
            appletLabel += ' '
            appletTooltip += ' / '
        }
        if( success > 0 ) {
            appletLabel += success + '\u2713'
            appletTooltip += success + " successful jobs"
        }

        this.set_applet_label(appletLabel);
        this.set_applet_tooltip(appletTooltip);
{'fraction_non_alphanumeric': 0.14309116225735113, 'fraction_numerical': 0.00442296666393644, 'mean_word_length': 1.8043178686265502, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 15, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '946137', 'n_tokens_mistral': 3607, 'n_tokens_neox': 3423, 'n_words': 589}