Skip to content

Instantly share code, notes, and snippets.

@spudtrooper
Created November 30, 2011 13:37
Show Gist options
  • Select an option

  • Save spudtrooper/1409077 to your computer and use it in GitHub Desktop.

Select an option

Save spudtrooper/1409077 to your computer and use it in GitHub Desktop.
A bookmarklet to monitor a Jenkins build page, and play the theme from golden girls when the build breaks and play the theme from arrested development when the build is fixed.
<a href='javascript:(function(){function k(r,q){for(var p in q){r.style[p]=q[p]}}function c(r,q){var p=document.createTextNode(r);if(q){q.appendChild(p)}return p}function e(p,s,r){var q=document.createElement(p);if(s){s.appendChild(q)}if(r){k(q,r)}return q}function j(q){try{console.log(q)}catch(p){}}function l(p){while(p.childNodes.length>0){p.removeChild(p.firstChild)}}function m(p){this.name=p;this.callbacks=[]}m.prototype={addListener:function(p){this.callbacks.push(p)},notifyListeners:function(r){var p=this.callbacks;j("notify "+p.length+" ["+this.name+"]("+r+")");for(var q=0;q<p.length;q++){p[q](r)}}};var n={None:"None",Success:"Success",Fail:"Fail",Pending:"Pending"};function d(){this.lastState=n.None;this.state=n.None;this.stateChangeEvent=new m("Change")}d.prototype={setState:function(p){this.lastState=this.state;this.state=p;j(this.lastState+" -> "+this.state);if(this.lastState!=this.state){this.stateChangeEvent.notifyListeners(this)}},getState:function(){return this.state},getLastState:function(){return this.lastState},getStateChangeEvent:function(){return this.stateChangeEvent},};function a(){var y={position:"fixed",bottom:"10px",right:"10px",backgroundColor:"#ddd",border:"1px solid black",padding:"5px",zIndez:"1000000000"};var t=this;var q=e("div",document.body,y);var z=e("div",q);var s=e("button",z);s.innerHTML="Success";s.addEventListener("click",function(){t.changeStateEvent.notifyListeners(n.Success)},true);var p=e("button",z);p.innerHTML="Fail";p.addEventListener("click",function(){t.changeStateEvent.notifyListeners(n.Fail)},true);var x=e("button",z);x.innerHTML="None";x.addEventListener("click",function(){t.changeStateEvent.notifyListeners(n.None)},true);var v={minWidth:"250px",minHeight:"250px",backgroundColor:"#aa7788",textAlign:"center"};var r=e("div",q,v);var u={fontSize:"48pt",color:"#000000",fontFamily:"Arial",paddingTop:"80px",};var w=e("div",r,u);this.el=q;this.mainDiv=r;this.mainText=w;this.changeStateEvent=new m("Change State")}a.prototype={Color:{None:"#000077",Success:"#007700",Fail:"#770000",Pending:"#770077"},updateWithState:function(q,t){var r=t;var s=this.Color;var p=s.None;if(r==n.Success){p=s.Success}else{if(r==n.Fail){p=s.Fail}else{if(r==n.Pending){p=s.Pending}}}this.mainDiv.style.backgroundColor=p;this.mainText.innerHTML=String(r)},getChangeStateEvent:function(){return this.changeStateEvent}};function o(r){var p;if(!r){p=""}else{p="http://www.youtube.com/v/"+r+"&hl=en&fs=1&autoplay=1"}j("playUrl: "+p);var r="__playUrlId__";var q=document.getElementById(r);if(!q){q=document.createElement("div");q.id=r;document.body.appendChild(q)}q.innerHTML="<object width=0 height=0><param name=autoplay value=true><param name=movie value="+p+"></param><param name=allowFullScreen value=true></param><param name=allowscriptaccess value=always></param><embed src="+p+" type=application/x-shockwave-flash allowscriptaccess=always allowfullscreen=true width=0 height=0></embed></object>";q.style.width="0px";q.style.height="0px"}function b(){}b.prototype={updateWithState:function(p,r){if(p==r){return}j("Playing for "+r);var q=r;if(q==n.None){this.playNone()}else{if(q==n.Success){this.playSuccess()}else{if(q==n.Fail){this.playFail()}}}},playNone:function(){o("")},playFail:function(){o("zYqPs0LInls")},playSuccess:function(){o("QFl7r2dUmTA")}};function h(t,r,u){this.model=t;this.view=r;this.player=u;var w=this;var q=this.model;var s=this.view;var x=this.player;s.getChangeStateEvent().addListener(function(p){q.setState(p)});q.getStateChangeEvent().addListener(function(v){var p=v.getLastState();var y=v.getState();s.updateWithState(p,y);x.updateWithState(p,y)})}h.prototype={showMenu:function(){this.view.updateWithState(this.model.getLastState(),this.model.getState())},updateState:function(p){this.model.setState(p)},};function f(p){var q=this;this.controller=p}const i=30*1000;f.prototype={go:function(){this.controller.showMenu();var p=this;p.checkState();setInterval(function(){p.checkState()},i)},checkState:function(){j("checkState");var t=document.getElementsByTagName("IMG");for(var q=0;q<t.length;q++){var p=t[q];if(!p.src){continue}var s=p.src;var r=null;if(s.match(/blue.png/)){r=n.Success}else{if(s.match(/red.png/)){r=n.Fail}else{if(s.match(/grey.png/)||s.match(/blue_anime.gif/)){r=n.None}}}if(!!r){this.controller.updateState(r);break}}}};function g(){var q=new a();var r=new d();var s=new b();var p=new h(r,q,s);var t=new f(p);t.go()}g()})();'>jenkins</a>
(function() {
function setStyle(el,style) {
for (var i in style) {
el.style[i] = style[i];
}
}
function createTextElement(text,onto) {
var res = document.createTextNode(text);
if (onto) onto.appendChild(res);
return res;
}
function createElement(tag,onto,style) {
var res = document.createElement(tag);
if (onto) onto.appendChild(res);
if (style) setStyle(res,style);
return res;
}
function log(msg) {
try {
console.log(msg);
} catch (e) {}
}
function removeChildren(el) {
while (el.childNodes.length > 0) {
el.removeChild(el.firstChild);
}
}
function EventNotifier(name) {
this.name = name;
this.callbacks = [];
}
EventNotifier.prototype = {
addListener: function(callback) {
this.callbacks.push(callback);
},
notifyListeners: function(value) {
var cbs = this.callbacks;
log("notify " + cbs.length + " [" + this.name + "](" + value + ")");
for (var i=0; i<cbs.length; i++) {
cbs[i](value);
}
}
};
var State = {
None: "None",
Success: "Success",
Fail: "Fail",
Pending: "Pending"
}
function Model() {
this.lastState = State.None;
this.state = State.None;
this.stateChangeEvent = new EventNotifier("Change");
}
Model.prototype = {
/** State -> Void */
setState: function(newState) {
this.lastState = this.state;
this.state = newState;
log(this.lastState + " -> " + this.state);
if (this.lastState != this.state) {
this.stateChangeEvent.notifyListeners(this);
}
},
/** Void -> State */
getState: function() {
return this.state;
},
/** Void -> State */
getLastState: function() {
return this.lastState;
},
/** Void -> EventNotifier(Model) */
getStateChangeEvent: function() {
return this.stateChangeEvent;
},
};
function View() {
var elStyle = {
"position": "fixed",
"bottom": "10px",
"right": "10px",
"backgroundColor": "#ddd",
"border": "1px solid black",
"padding": "5px",
"zIndez": "1000000000"
};
var thiz = this;
var el = createElement("div",document.body,elStyle);
var row = createElement("div",el);
var successButton = createElement("button",row);
successButton.innerHTML = "Success";
successButton.addEventListener("click",
function() {
thiz.changeStateEvent.
notifyListeners(State.Success);
}, true);
var failButton = createElement("button",row);
failButton.innerHTML = "Fail";
failButton.addEventListener("click",
function() {
thiz.changeStateEvent.
notifyListeners(State.Fail);
}, true);
var noneButton = createElement("button",row);
noneButton.innerHTML = "None";
noneButton.addEventListener("click",
function() {
thiz.changeStateEvent.
notifyListeners(State.None);
}, true);
var mainDivStyle = {
"minWidth": "250px",
"minHeight": "250px",
"backgroundColor": "#aa7788",
"textAlign": "center"
};
var mainDiv = createElement("div",el,mainDivStyle);
var mainTextStyle = {
"fontSize": "48pt",
"color": "#000000",
"fontFamily": "Arial",
"paddingTop": "80px",
};
var mainText = createElement("div",mainDiv,mainTextStyle);
this.el = el;
this.mainDiv = mainDiv;
this.mainText = mainText;
this.changeStateEvent = new EventNotifier("Change State");
}
View.prototype = {
Color : {
None: "#000077",
Success: "#007700",
Fail: "#770000",
Pending: "#770077"
},
updateWithState: function(oldState,newState) {
var state = newState;
var Color = this.Color;
var color = Color.None;
if (state == State.Success) {
color = Color.Success;
} else if (state == State.Fail) {
color = Color.Fail;
} else if (state == State.Pending) {
color = Color.Pending;
}
this.mainDiv.style.backgroundColor = color;
this.mainText.innerHTML = String(state);
},
/** Void -> EventNotifier(State) */
getChangeStateEvent: function() {
return this.changeStateEvent;
}
};
function playUrl(id) {
var url;
if (!id) {
url = "";
} else {
url = "http://www.youtube.com/v/" + id + "&hl=en&fs=1&autoplay=1";
}
log("playUrl: " + url);
var id = "__playUrlId__";
var div = document.getElementById(id);
if (!div) {
div = document.createElement("div");
div.id = id;
document.body.appendChild(div);
}
div.innerHTML = "<object width=0 height=0><param name=autoplay value=true><param name=movie value="
+ url
+ "></param><param name=allowFullScreen value=true></param><param name=allowscriptaccess value=always></param><embed src="
+ url
+ " type=application/x-shockwave-flash allowscriptaccess=always allowfullscreen=true width=0 height=0></embed></object>"
;
div.style.width = "0px";
div.style.height = "0px";
}
function Player() {
}
Player.prototype = {
updateWithState: function(oldState,newState) {
if (oldState == newState) return;
log("Playing for " + newState);
var state = newState;
if (state == State.None) {
this.playNone();
} else if (state == State.Success) {
this.playSuccess();
} else if (state == State.Fail) {
this.playFail();
}
},
playNone: function() {
playUrl("");
},
playFail: function() {
playUrl("zYqPs0LInls");
},
playSuccess: function() {
playUrl("QFl7r2dUmTA");
}
};
function Controller(model,view,player) {
this.model = model;
this.view = view;
this.player = player;
var thiz = this;
var m = this.model;
var v = this.view;
var p = this.player;
v.getChangeStateEvent().addListener(function(state) {
m.setState(state);
});
m.getStateChangeEvent().addListener(function(model) {
var oldState = model.getLastState();
var newState = model.getState();
v.updateWithState(oldState,newState);
p.updateWithState(oldState,newState);
});
}
Controller.prototype = {
/** Void -> Void */
showMenu: function() {
this.view.updateWithState(this.model.getLastState(),
this.model.getState());
},
updateState: function(state) {
this.model.setState(state);
},
};
function App(controller) {
var thiz = this;
this.controller = controller;
}
const LOOP_PERIOD_MILLIS = 30 * 1000;
App.prototype = {
go: function() {
this.controller.showMenu();
var thiz = this;
thiz.checkState();
setInterval(function(){thiz.checkState();},LOOP_PERIOD_MILLIS);
},
checkState: function() {
log("checkState");
var imgs = document.getElementsByTagName("IMG");
for (var i=0; i<imgs.length; i++) {
var img = imgs[i];
if (!img.src) continue;
var src = img.src;
var state = null;
if (src.match(/blue.png/)) {
state = State.Success
} else if (src.match(/red.png/)) {
state = State.Fail;
} else if (src.match(/grey.png/) || src.match(/blue_anime.gif/)) {
state = State.None;
}
if (!!state) {
this.controller.updateState(state);
break;
}
}
}
};
function main() {
var view = new View();
var model = new Model();
var player = new Player();
var controller = new Controller(model,view,player);
var app = new App(controller);
app.go();
}
main();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment