From bbe5ee4facc8c2ed55bc4f8da21d2c199ab3ace7 Mon Sep 17 00:00:00 2001
From: Alain Takoudjou <talino@tiolive.com>
Date: Wed, 1 Feb 2012 16:24:37 +0100
Subject: [PATCH] Allow people to see content of any file in both software,
 instance "Inspect" tabs

---
 setup.py                                      |   1 +
 slapos/runner/gittools.py                     |   2 +-
 slapos/runner/static/css/colorbox.css         |  51 +++++++++++
 slapos/runner/static/css/images/border.png    | Bin 0 -> 163 bytes
 slapos/runner/static/css/images/controls.png  | Bin 0 -> 2033 bytes
 slapos/runner/static/css/images/loading.gif   | Bin 0 -> 9427 bytes
 .../static/css/images/loading_background.png  | Bin 0 -> 166 bytes
 slapos/runner/static/css/styles.css           |   5 +-
 .../runner/static/images/button_highlight.png | Bin 0 -> 217 bytes
 .../runner/static/{ => js}/ace/ace-compat.js  |   0
 .../static/{ => js}/ace/ace-uncompressed.js   |   0
 slapos/runner/static/{ => js}/ace/ace.js      |   0
 .../static/{ => js}/ace/keybinding-emacs.js   |   0
 .../static/{ => js}/ace/keybinding-vim.js     |   0
 .../static/{ => js}/ace/mode-buildout.js      |   0
 slapos/runner/static/{ => js}/ace/mode-php.js |   0
 .../runner/static/{ => js}/ace/mode-python.js |   0
 .../{ => js}/ace/theme-crimson_editor.js      |   0
 .../{ => js}/jquery/jquery-1.6.2.min.js       |   0
 .../static/js/jquery/jquery.colorbox-min.js   |   4 +
 .../static/{ => js}/jquery/jqueryFileTree.js  |  10 ++-
 .../static/{ => js}/jquery/jqueryTabs.js      |   0
 .../runner/static/{ => js}/scripts/editor.js  |   0
 .../runner/static/{ => js}/scripts/folder.js  |   0
 .../static/js/scripts/inspectInstance.js      |  85 ++++++++++++++++++
 .../{ => js}/scripts/inspectSoftware.js       |  67 +++++++++++++-
 .../runner/static/{ => js}/scripts/project.js |   0
 slapos/runner/static/{ => js}/scripts/repo.js |   0
 .../static/{ => js}/scripts/softwareFolder.js |   0
 slapos/runner/templates/cloneRepository.html  |   4 +-
 slapos/runner/templates/instanceInspect.html  |  27 +++---
 slapos/runner/templates/layout.html           |   2 +-
 slapos/runner/templates/layout_test.html      |  43 ---------
 slapos/runner/templates/manageProject.html    |   4 +-
 slapos/runner/templates/projectDiff.html      |   4 +-
 slapos/runner/templates/projectFolder.html    |   4 +-
 slapos/runner/templates/runResult.html        |  18 +++-
 slapos/runner/templates/softwareFolder.html   |  14 +--
 .../templates/updateInstanceProfile.html      |   8 +-
 .../templates/updateSoftwareProfile.html      |   8 +-
 slapos/runner/utils.py                        |  13 ++-
 slapos/runner/views.py                        |  18 +++-
 42 files changed, 301 insertions(+), 91 deletions(-)
 create mode 100644 slapos/runner/static/css/colorbox.css
 create mode 100644 slapos/runner/static/css/images/border.png
 create mode 100644 slapos/runner/static/css/images/controls.png
 create mode 100644 slapos/runner/static/css/images/loading.gif
 create mode 100644 slapos/runner/static/css/images/loading_background.png
 create mode 100644 slapos/runner/static/images/button_highlight.png
 rename slapos/runner/static/{ => js}/ace/ace-compat.js (100%)
 rename slapos/runner/static/{ => js}/ace/ace-uncompressed.js (100%)
 rename slapos/runner/static/{ => js}/ace/ace.js (100%)
 rename slapos/runner/static/{ => js}/ace/keybinding-emacs.js (100%)
 rename slapos/runner/static/{ => js}/ace/keybinding-vim.js (100%)
 rename slapos/runner/static/{ => js}/ace/mode-buildout.js (100%)
 rename slapos/runner/static/{ => js}/ace/mode-php.js (100%)
 rename slapos/runner/static/{ => js}/ace/mode-python.js (100%)
 rename slapos/runner/static/{ => js}/ace/theme-crimson_editor.js (100%)
 rename slapos/runner/static/{ => js}/jquery/jquery-1.6.2.min.js (100%)
 create mode 100644 slapos/runner/static/js/jquery/jquery.colorbox-min.js
 rename slapos/runner/static/{ => js}/jquery/jqueryFileTree.js (92%)
 rename slapos/runner/static/{ => js}/jquery/jqueryTabs.js (100%)
 rename slapos/runner/static/{ => js}/scripts/editor.js (100%)
 rename slapos/runner/static/{ => js}/scripts/folder.js (100%)
 create mode 100644 slapos/runner/static/js/scripts/inspectInstance.js
 rename slapos/runner/static/{ => js}/scripts/inspectSoftware.js (57%)
 rename slapos/runner/static/{ => js}/scripts/project.js (100%)
 rename slapos/runner/static/{ => js}/scripts/repo.js (100%)
 rename slapos/runner/static/{ => js}/scripts/softwareFolder.js (100%)
 delete mode 100644 slapos/runner/templates/layout_test.html

diff --git a/setup.py b/setup.py
index 112c4af..fff6b8d 100644
--- a/setup.py
+++ b/setup.py
@@ -61,6 +61,7 @@ setup(name=name,
           'equeue = slapos.equeue:main',
           'pubsubserver = slapos.pubsub:main',
           'pubsubnotifier = slapos.pubsub.notifier:main',
+          'slaprunnertest = slapos.runner.testRunner:run',
         ]
       },
     )
diff --git a/slapos/runner/gittools.py b/slapos/runner/gittools.py
index 912d1ec..80f03ae 100644
--- a/slapos/runner/gittools.py
+++ b/slapos/runner/gittools.py
@@ -119,7 +119,7 @@ def gitPush(project, msg):
       code = 1
   except Exception, e:
     if undo_commit:
-      git.reset("HEAD^1") #undo previous commit
+      git.reset("HEAD~") #undo previous commit
     json = str(e)
   return jsonify(code=code, result=json)
 
diff --git a/slapos/runner/static/css/colorbox.css b/slapos/runner/static/css/colorbox.css
new file mode 100644
index 0000000..4ab86f2
--- /dev/null
+++ b/slapos/runner/static/css/colorbox.css
@@ -0,0 +1,51 @@
+/*
+    ColorBox Core Style:
+    The following CSS is consistent between example themes and should not be altered.
+*/
+#colorbox, #cboxOverlay, #cboxWrapper{position:absolute; top:0; left:0; z-index:9999; overflow:hidden;}
+#cboxOverlay{position:fixed; width:100%; height:100%;}
+#cboxMiddleLeft, #cboxBottomLeft{clear:left;}
+#cboxContent{position:relative;}
+#cboxLoadedContent{overflow:auto;}
+#cboxTitle{margin:0;}
+#cboxLoadingOverlay, #cboxLoadingGraphic{position:absolute; top:0; left:0; width:100%; height:100%;}
+#cboxPrevious, #cboxNext, #cboxClose, #cboxSlideshow{cursor:pointer;}
+.cboxPhoto{float:left; margin:auto; border:0; display:block;}
+.cboxIframe{width:100%; height:100%; display:block; border:0;}
+
+/* 
+    User Style:
+    Change the following styles to modify the appearance of ColorBox.  They are
+    ordered & tabbed in a way that represents the nesting of the generated HTML.
+*/
+#cboxOverlay{background:#000;}
+#colorbox{}
+    #cboxTopLeft{width:14px; height:14px; background:url(images/controls.png) no-repeat 0 0;}
+    #cboxTopCenter{height:14px; background:url(images/border.png) repeat-x top left;}
+    #cboxTopRight{width:14px; height:14px; background:url(images/controls.png) no-repeat -36px 0;}
+    #cboxBottomLeft{width:14px; height:43px; background:url(images/controls.png) no-repeat 0 -32px;}
+    #cboxBottomCenter{height:43px; background:url(images/border.png) repeat-x bottom left;}
+    #cboxBottomRight{width:14px; height:43px; background:url(images/controls.png) no-repeat -36px -32px;}
+    #cboxMiddleLeft{width:14px; background:url(images/controls.png) repeat-y -175px 0;}
+    #cboxMiddleRight{width:14px; background:url(images/controls.png) repeat-y -211px 0;}
+    #cboxContent{background:#fff; overflow:visible;}
+        .cboxIframe{background:#fff;}
+        #cboxError{padding:50px; border:1px solid #ccc;}
+        #cboxLoadedContent{margin-bottom:5px;}
+        #cboxLoadingOverlay{background:url(images/loading_background.png) no-repeat center center;}
+        #cboxLoadingGraphic{background:url(images/loading.gif) no-repeat center center;}
+        #cboxTitle{position:absolute; bottom:-25px; left:0; text-align:center; width:100%; font-weight:bold; color:#7C7C7C;}
+        #cboxCurrent{position:absolute; bottom:-25px; left:58px; font-weight:bold; color:#7C7C7C;}
+        
+        #cboxPrevious, #cboxNext, #cboxClose, #cboxSlideshow{position:absolute; bottom:-29px; background:url(images/controls.png) no-repeat 0px 0px; width:23px; height:23px; text-indent:-9999px;}
+        #cboxPrevious{left:0px; background-position: -51px -25px;}
+        #cboxPrevious:hover{background-position:-51px 0px;}
+        #cboxNext{left:27px; background-position:-75px -25px;}
+        #cboxNext:hover{background-position:-75px 0px;}
+        #cboxClose{right:0; background-position:-100px -25px;}
+        #cboxClose:hover{background-position:-100px 0px;}
+        
+        .cboxSlideshow_on #cboxSlideshow{background-position:-125px 0px; right:27px;}
+        .cboxSlideshow_on #cboxSlideshow:hover{background-position:-150px 0px;}
+        .cboxSlideshow_off #cboxSlideshow{background-position:-150px -25px; right:27px;}
+        .cboxSlideshow_off #cboxSlideshow:hover{background-position:-125px 0px;}
\ No newline at end of file
diff --git a/slapos/runner/static/css/images/border.png b/slapos/runner/static/css/images/border.png
new file mode 100644
index 0000000000000000000000000000000000000000..df13bb6daf79307915e7dd1cf29d48730a50c29d
GIT binary patch
literal 163
zcmeAS@N?(olHy`uVBq!ia0vp^j6m$o!3-qZIAk{hDdPa25Z9ofAa{3ne}8{RM@MgO
z?|^^+D=VvngoLiHE@NZkOP4N1MMVV$27dbVsk5{5|NsBbo<1!vSziv+uI=gK7*Y|p
z^k6G*gM$FWhIux5zx_}1v|LF#mgu27<@e;v&wgfZpEc#erGmW@9n6=)zqo$~YGd$p
L^>bP0l+XkK8G}75

literal 0
HcmV?d00001

diff --git a/slapos/runner/static/css/images/controls.png b/slapos/runner/static/css/images/controls.png
new file mode 100644
index 0000000000000000000000000000000000000000..65cfd1dc95c5ee4c6c3d0848b1dcfc0ec69f6aea
GIT binary patch
literal 2033
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
P00000NkvXXu0mjf=5OWV

literal 0
HcmV?d00001

diff --git a/slapos/runner/static/css/images/loading.gif b/slapos/runner/static/css/images/loading.gif
new file mode 100644
index 0000000000000000000000000000000000000000..b4695d811d4f84ed693eff7b5e6b4d61a3e8c48d
GIT binary patch
literal 9427
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
BHE;j`

literal 0
HcmV?d00001

diff --git a/slapos/runner/static/css/images/loading_background.png b/slapos/runner/static/css/images/loading_background.png
new file mode 100644
index 0000000000000000000000000000000000000000..9de11f46719e3f60412a8d925821b8a3aa7b5b2b
GIT binary patch
literal 166
zcmeAS@N?(olHy`uVBq!ia0vp^8X(NV3?%C=ER6$FLIFM@uK!^GC;(x)UpJW#<gk_m
z`31jk5MVez$$QRKpn#pHi(^Pd+}q2Fj0_3_&KDIwNC-JJbvrN#ypCr*FUC+9Z?{)b
zYW}GMOSW7P<zMxP&3Ar6(jwWlbGO?z?LEW#YXh6qUabZrph*m#u6{1-oD!M<zOy|(

literal 0
HcmV?d00001

diff --git a/slapos/runner/static/css/styles.css b/slapos/runner/static/css/styles.css
index 909f319..681fa4b 100644
--- a/slapos/runner/static/css/styles.css
+++ b/slapos/runner/static/css/styles.css
@@ -560,7 +560,7 @@ select {
   white-space: nowrap;}
 
 a.lshare{
-    background: #D9D9D9;
+    background: #fff url(../images/button_highlight.png) repeat-x;
     padding: 4px 7px 4px 7px;
     height: 18px;
     font-size: 15px;
@@ -569,10 +569,11 @@ a.lshare{
     margin-right: 10px;
     -webkit-border-radius: 3px;
     -moz-border-radius: 3px;
+    text-shadow: 0px 1px #F0F1F2;
 }
 
 a.lshare:hover{
-    background:#EFF5FF;
+    background:#D9D9D9 url(../images/button_highlight.png) 50% repeat-x;
     color: #000;
     border:solid 1px #73A6FF;
 }
diff --git a/slapos/runner/static/images/button_highlight.png b/slapos/runner/static/images/button_highlight.png
new file mode 100644
index 0000000000000000000000000000000000000000..8930ed0947dfe14553c9572b3f3bea24ba320f5d
GIT binary patch
literal 217
zcmeAS@N?(olHy`uVBq!ia0vp^96+qj!3HFazH(*&DaPU;cPEB*=VV?2Ic!PZ?k)`f
zL2$v|<&%LToCO|{#S9F5he4R}c>anMpdfpRr>`sf9VSK&HEu(1&!<44NKY5X5R21y
zC!FRy;K1SH8zZn~^Oyd;8eA_O_`AJN%#r`RJLGGlleW?V79-(rGH2GX-Kn)&6noKX
zi!9$73xnc+E2O1#m2R;J6k0vvcCZe1sVfMHo;1_@0qa^vn+2O@mx%){VeoYIb6Mw<
G&;$UDB1Go^

literal 0
HcmV?d00001

diff --git a/slapos/runner/static/ace/ace-compat.js b/slapos/runner/static/js/ace/ace-compat.js
similarity index 100%
rename from slapos/runner/static/ace/ace-compat.js
rename to slapos/runner/static/js/ace/ace-compat.js
diff --git a/slapos/runner/static/ace/ace-uncompressed.js b/slapos/runner/static/js/ace/ace-uncompressed.js
similarity index 100%
rename from slapos/runner/static/ace/ace-uncompressed.js
rename to slapos/runner/static/js/ace/ace-uncompressed.js
diff --git a/slapos/runner/static/ace/ace.js b/slapos/runner/static/js/ace/ace.js
similarity index 100%
rename from slapos/runner/static/ace/ace.js
rename to slapos/runner/static/js/ace/ace.js
diff --git a/slapos/runner/static/ace/keybinding-emacs.js b/slapos/runner/static/js/ace/keybinding-emacs.js
similarity index 100%
rename from slapos/runner/static/ace/keybinding-emacs.js
rename to slapos/runner/static/js/ace/keybinding-emacs.js
diff --git a/slapos/runner/static/ace/keybinding-vim.js b/slapos/runner/static/js/ace/keybinding-vim.js
similarity index 100%
rename from slapos/runner/static/ace/keybinding-vim.js
rename to slapos/runner/static/js/ace/keybinding-vim.js
diff --git a/slapos/runner/static/ace/mode-buildout.js b/slapos/runner/static/js/ace/mode-buildout.js
similarity index 100%
rename from slapos/runner/static/ace/mode-buildout.js
rename to slapos/runner/static/js/ace/mode-buildout.js
diff --git a/slapos/runner/static/ace/mode-php.js b/slapos/runner/static/js/ace/mode-php.js
similarity index 100%
rename from slapos/runner/static/ace/mode-php.js
rename to slapos/runner/static/js/ace/mode-php.js
diff --git a/slapos/runner/static/ace/mode-python.js b/slapos/runner/static/js/ace/mode-python.js
similarity index 100%
rename from slapos/runner/static/ace/mode-python.js
rename to slapos/runner/static/js/ace/mode-python.js
diff --git a/slapos/runner/static/ace/theme-crimson_editor.js b/slapos/runner/static/js/ace/theme-crimson_editor.js
similarity index 100%
rename from slapos/runner/static/ace/theme-crimson_editor.js
rename to slapos/runner/static/js/ace/theme-crimson_editor.js
diff --git a/slapos/runner/static/jquery/jquery-1.6.2.min.js b/slapos/runner/static/js/jquery/jquery-1.6.2.min.js
similarity index 100%
rename from slapos/runner/static/jquery/jquery-1.6.2.min.js
rename to slapos/runner/static/js/jquery/jquery-1.6.2.min.js
diff --git a/slapos/runner/static/js/jquery/jquery.colorbox-min.js b/slapos/runner/static/js/jquery/jquery.colorbox-min.js
new file mode 100644
index 0000000..e84ff66
--- /dev/null
+++ b/slapos/runner/static/js/jquery/jquery.colorbox-min.js
@@ -0,0 +1,4 @@
+// ColorBox v1.3.19 - jQuery lightbox plugin
+// (c) 2011 Jack Moore - jacklmoore.com
+// License: http://www.opensource.org/licenses/mit-license.php
+(function(a,b,c){function Z(c,d,e){var g=b.createElement(c);return d&&(g.id=f+d),e&&(g.style.cssText=e),a(g)}function $(a){var b=y.length,c=(Q+a)%b;return c<0?b+c:c}function _(a,b){return Math.round((/%/.test(a)?(b==="x"?z.width():z.height())/100:1)*parseInt(a,10))}function ba(a){return K.photo||/\.(gif|png|jpe?g|bmp|ico)((#|\?).*)?$/i.test(a)}function bb(){var b;K=a.extend({},a.data(P,e));for(b in K)a.isFunction(K[b])&&b.slice(0,2)!=="on"&&(K[b]=K[b].call(P));K.rel=K.rel||P.rel||"nofollow",K.href=K.href||a(P).attr("href"),K.title=K.title||P.title,typeof K.href=="string"&&(K.href=a.trim(K.href))}function bc(b,c){a.event.trigger(b),c&&c.call(P)}function bd(){var a,b=f+"Slideshow_",c="click."+f,d,e,g;K.slideshow&&y[1]?(d=function(){F.text(K.slideshowStop).unbind(c).bind(j,function(){if(K.loop||y[Q+1])a=setTimeout(W.next,K.slideshowSpeed)}).bind(i,function(){clearTimeout(a)}).one(c+" "+k,e),r.removeClass(b+"off").addClass(b+"on"),a=setTimeout(W.next,K.slideshowSpeed)},e=function(){clearTimeout(a),F.text(K.slideshowStart).unbind([j,i,k,c].join(" ")).one(c,function(){W.next(),d()}),r.removeClass(b+"on").addClass(b+"off")},K.slideshowAuto?d():e()):r.removeClass(b+"off "+b+"on")}function be(b){U||(P=b,bb(),y=a(P),Q=0,K.rel!=="nofollow"&&(y=a("."+g).filter(function(){var b=a.data(this,e).rel||this.rel;return b===K.rel}),Q=y.index(P),Q===-1&&(y=y.add(P),Q=y.length-1)),S||(S=T=!0,r.show(),K.returnFocus&&a(P).blur().one(l,function(){a(this).focus()}),q.css({opacity:+K.opacity,cursor:K.overlayClose?"pointer":"auto"}).show(),K.w=_(K.initialWidth,"x"),K.h=_(K.initialHeight,"y"),W.position(),o&&z.bind("resize."+p+" scroll."+p,function(){q.css({width:z.width(),height:z.height(),top:z.scrollTop(),left:z.scrollLeft()})}).trigger("resize."+p),bc(h,K.onOpen),J.add(D).hide(),I.html(K.close).show()),W.load(!0))}function bf(){!r&&b.body&&(Y=!1,z=a(c),r=Z(X).attr({id:e,"class":n?f+(o?"IE6":"IE"):""}).hide(),q=Z(X,"Overlay",o?"position:absolute":"").hide(),s=Z(X,"Wrapper"),t=Z(X,"Content").append(A=Z(X,"LoadedContent","width:0; height:0; overflow:hidden"),C=Z(X,"LoadingOverlay").add(Z(X,"LoadingGraphic")),D=Z(X,"Title"),E=Z(X,"Current"),G=Z(X,"Next"),H=Z(X,"Previous"),F=Z(X,"Slideshow").bind(h,bd),I=Z(X,"Close")),s.append(Z(X).append(Z(X,"TopLeft"),u=Z(X,"TopCenter"),Z(X,"TopRight")),Z(X,!1,"clear:left").append(v=Z(X,"MiddleLeft"),t,w=Z(X,"MiddleRight")),Z(X,!1,"clear:left").append(Z(X,"BottomLeft"),x=Z(X,"BottomCenter"),Z(X,"BottomRight"))).find("div div").css({"float":"left"}),B=Z(X,!1,"position:absolute; width:9999px; visibility:hidden; display:none"),J=G.add(H).add(E).add(F),a(b.body).append(q,r.append(s,B)))}function bg(){return r?(Y||(Y=!0,L=u.height()+x.height()+t.outerHeight(!0)-t.height(),M=v.width()+w.width()+t.outerWidth(!0)-t.width(),N=A.outerHeight(!0),O=A.outerWidth(!0),r.css({"padding-bottom":L,"padding-right":M}),G.click(function(){W.next()}),H.click(function(){W.prev()}),I.click(function(){W.close()}),q.click(function(){K.overlayClose&&W.close()}),a(b).bind("keydown."+f,function(a){var b=a.keyCode;S&&K.escKey&&b===27&&(a.preventDefault(),W.close()),S&&K.arrowKey&&y[1]&&(b===37?(a.preventDefault(),H.click()):b===39&&(a.preventDefault(),G.click()))}),a("."+g,b).live("click",function(a){a.which>1||a.shiftKey||a.altKey||a.metaKey||(a.preventDefault(),be(this))})),!0):!1}var d={transition:"elastic",speed:300,width:!1,initialWidth:"600",innerWidth:!1,maxWidth:!1,height:!1,initialHeight:"450",innerHeight:!1,maxHeight:!1,scalePhotos:!0,scrolling:!0,inline:!1,html:!1,iframe:!1,fastIframe:!0,photo:!1,href:!1,title:!1,rel:!1,opacity:.9,preloading:!0,current:"image {current} of {total}",previous:"previous",next:"next",close:"close",open:!1,returnFocus:!0,reposition:!0,loop:!0,slideshow:!1,slideshowAuto:!0,slideshowSpeed:2500,slideshowStart:"start slideshow",slideshowStop:"stop slideshow",onOpen:!1,onLoad:!1,onComplete:!1,onCleanup:!1,onClosed:!1,overlayClose:!0,escKey:!0,arrowKey:!0,top:!1,bottom:!1,left:!1,right:!1,fixed:!1,data:undefined},e="colorbox",f="cbox",g=f+"Element",h=f+"_open",i=f+"_load",j=f+"_complete",k=f+"_cleanup",l=f+"_closed",m=f+"_purge",n=!a.support.opacity&&!a.support.style,o=n&&!c.XMLHttpRequest,p=f+"_IE6",q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X="div",Y;if(a.colorbox)return;a(bf),W=a.fn[e]=a[e]=function(b,c){var f=this;b=b||{},bf();if(bg()){if(!f[0]){if(f.selector)return f;f=a("<a/>"),b.open=!0}c&&(b.onComplete=c),f.each(function(){a.data(this,e,a.extend({},a.data(this,e)||d,b))}).addClass(g),(a.isFunction(b.open)&&b.open.call(f)||b.open)&&be(f[0])}return f},W.position=function(a,b){function i(a){u[0].style.width=x[0].style.width=t[0].style.width=a.style.width,t[0].style.height=v[0].style.height=w[0].style.height=a.style.height}var c=0,d=0,e=r.offset(),g=z.scrollTop(),h=z.scrollLeft();z.unbind("resize."+f),r.css({top:-9e4,left:-9e4}),K.fixed&&!o?(e.top-=g,e.left-=h,r.css({position:"fixed"})):(c=g,d=h,r.css({position:"absolute"})),K.right!==!1?d+=Math.max(z.width()-K.w-O-M-_(K.right,"x"),0):K.left!==!1?d+=_(K.left,"x"):d+=Math.round(Math.max(z.width()-K.w-O-M,0)/2),K.bottom!==!1?c+=Math.max(z.height()-K.h-N-L-_(K.bottom,"y"),0):K.top!==!1?c+=_(K.top,"y"):c+=Math.round(Math.max(z.height()-K.h-N-L,0)/2),r.css({top:e.top,left:e.left}),a=r.width()===K.w+O&&r.height()===K.h+N?0:a||0,s[0].style.width=s[0].style.height="9999px",r.dequeue().animate({width:K.w+O,height:K.h+N,top:c,left:d},{duration:a,complete:function(){i(this),T=!1,s[0].style.width=K.w+O+M+"px",s[0].style.height=K.h+N+L+"px",K.reposition&&setTimeout(function(){z.bind("resize."+f,W.position)},1),b&&b()},step:function(){i(this)}})},W.resize=function(a){S&&(a=a||{},a.width&&(K.w=_(a.width,"x")-O-M),a.innerWidth&&(K.w=_(a.innerWidth,"x")),A.css({width:K.w}),a.height&&(K.h=_(a.height,"y")-N-L),a.innerHeight&&(K.h=_(a.innerHeight,"y")),!a.innerHeight&&!a.height&&(A.css({height:"auto"}),K.h=A.height()),A.css({height:K.h}),W.position(K.transition==="none"?0:K.speed))},W.prep=function(b){function g(){return K.w=K.w||A.width(),K.w=K.mw&&K.mw<K.w?K.mw:K.w,K.w}function h(){return K.h=K.h||A.height(),K.h=K.mh&&K.mh<K.h?K.mh:K.h,K.h}if(!S)return;var c,d=K.transition==="none"?0:K.speed;A.remove(),A=Z(X,"LoadedContent").append(b),A.hide().appendTo(B.show()).css({width:g(),overflow:K.scrolling?"auto":"hidden"}).css({height:h()}).prependTo(t),B.hide(),a(R).css({"float":"none"}),o&&a("select").not(r.find("select")).filter(function(){return this.style.visibility!=="hidden"}).css({visibility:"hidden"}).one(k,function(){this.style.visibility="inherit"}),c=function(){function q(){n&&r[0].style.removeAttribute("filter")}var b,c,g=y.length,h,i="frameBorder",k="allowTransparency",l,o,p;if(!S)return;l=function(){clearTimeout(V),C.hide(),bc(j,K.onComplete)},n&&R&&A.fadeIn(100),D.html(K.title).add(A).show();if(g>1){typeof K.current=="string"&&E.html(K.current.replace("{current}",Q+1).replace("{total}",g)).show(),G[K.loop||Q<g-1?"show":"hide"]().html(K.next),H[K.loop||Q?"show":"hide"]().html(K.previous),K.slideshow&&F.show();if(K.preloading){b=[$(-1),$(1)];while(c=y[b.pop()])o=a.data(c,e).href||c.href,a.isFunction(o)&&(o=o.call(c)),ba(o)&&(p=new Image,p.src=o)}}else J.hide();K.iframe?(h=Z("iframe")[0],i in h&&(h[i]=0),k in h&&(h[k]="true"),h.name=f+ +(new Date),K.fastIframe?l():a(h).one("load",l),h.src=K.href,K.scrolling||(h.scrolling="no"),a(h).addClass(f+"Iframe").appendTo(A).one(m,function(){h.src="//about:blank"})):l(),K.transition==="fade"?r.fadeTo(d,1,q):q()},K.transition==="fade"?r.fadeTo(d,0,function(){W.position(0,c)}):W.position(d,c)},W.load=function(b){var c,d,e=W.prep;T=!0,R=!1,P=y[Q],b||bb(),bc(m),bc(i,K.onLoad),K.h=K.height?_(K.height,"y")-N-L:K.innerHeight&&_(K.innerHeight,"y"),K.w=K.width?_(K.width,"x")-O-M:K.innerWidth&&_(K.innerWidth,"x"),K.mw=K.w,K.mh=K.h,K.maxWidth&&(K.mw=_(K.maxWidth,"x")-O-M,K.mw=K.w&&K.w<K.mw?K.w:K.mw),K.maxHeight&&(K.mh=_(K.maxHeight,"y")-N-L,K.mh=K.h&&K.h<K.mh?K.h:K.mh),c=K.href,V=setTimeout(function(){C.show()},100),K.inline?(Z(X).hide().insertBefore(a(c)[0]).one(m,function(){a(this).replaceWith(A.children())}),e(a(c))):K.iframe?e(" "):K.html?e(K.html):ba(c)?(a(R=new Image).addClass(f+"Photo").error(function(){K.title=!1,e(Z(X,"Error").text("This image could not be loaded"))}).load(function(){var a;R.onload=null,K.scalePhotos&&(d=function(){R.height-=R.height*a,R.width-=R.width*a},K.mw&&R.width>K.mw&&(a=(R.width-K.mw)/R.width,d()),K.mh&&R.height>K.mh&&(a=(R.height-K.mh)/R.height,d())),K.h&&(R.style.marginTop=Math.max(K.h-R.height,0)/2+"px"),y[1]&&(K.loop||y[Q+1])&&(R.style.cursor="pointer",R.onclick=function(){W.next()}),n&&(R.style.msInterpolationMode="bicubic"),setTimeout(function(){e(R)},1)}),setTimeout(function(){R.src=c},1)):c&&B.load(c,K.data,function(b,c,d){e(c==="error"?Z(X,"Error").text("Request unsuccessful: "+d.statusText):a(this).contents())})},W.next=function(){!T&&y[1]&&(K.loop||y[Q+1])&&(Q=$(1),W.load())},W.prev=function(){!T&&y[1]&&(K.loop||Q)&&(Q=$(-1),W.load())},W.close=function(){S&&!U&&(U=!0,S=!1,bc(k,K.onCleanup),z.unbind("."+f+" ."+p),q.fadeTo(200,0),r.stop().fadeTo(300,0,function(){r.add(q).css({opacity:1,cursor:"auto"}).hide(),bc(m),A.remove(),setTimeout(function(){U=!1,bc(l,K.onClosed)},1)}))},W.remove=function(){a([]).add(r).add(q).remove(),r=null,a("."+g).removeData(e).removeClass(g).die()},W.element=function(){return a(P)},W.settings=d})(jQuery,document,this);
\ No newline at end of file
diff --git a/slapos/runner/static/jquery/jqueryFileTree.js b/slapos/runner/static/js/jquery/jqueryFileTree.js
similarity index 92%
rename from slapos/runner/static/jquery/jqueryFileTree.js
rename to slapos/runner/static/js/jquery/jqueryFileTree.js
index e613b36..0588c60 100644
--- a/slapos/runner/static/jquery/jqueryFileTree.js
+++ b/slapos/runner/static/js/jquery/jqueryFileTree.js
@@ -16,7 +16,7 @@
 if(jQuery) (function($){
 	
 	$.extend($.fn, {
-		fileTree: function(o, h) {
+		fileTree: function(o, h, p) {
 			// Defaults
 			if( !o ) var o = {};
 			if( o.root == undefined ) o.root = '/';
@@ -70,6 +70,14 @@ if(jQuery) (function($){
 					});
 					// Prevent A from triggering the # on non-click events
 					if( o.folderEvent.toLowerCase != 'click' ) $(t).find('LI A').bind('click', function() { return false; });
+					//Bind double click to open file (only)
+					if(p){
+						$(t).find('LI A').bind('dblclick', function(){
+							if( !$(this).parent().hasClass('directory') ) {
+								p($(this).attr('rel'));
+							}
+						});
+					}
 				}
 				// Loading message
 				$(this).html('<ul class="jqueryFileTree start"><li class="wait">' + o.loadMessage + '<li></ul>');
diff --git a/slapos/runner/static/jquery/jqueryTabs.js b/slapos/runner/static/js/jquery/jqueryTabs.js
similarity index 100%
rename from slapos/runner/static/jquery/jqueryTabs.js
rename to slapos/runner/static/js/jquery/jqueryTabs.js
diff --git a/slapos/runner/static/scripts/editor.js b/slapos/runner/static/js/scripts/editor.js
similarity index 100%
rename from slapos/runner/static/scripts/editor.js
rename to slapos/runner/static/js/scripts/editor.js
diff --git a/slapos/runner/static/scripts/folder.js b/slapos/runner/static/js/scripts/folder.js
similarity index 100%
rename from slapos/runner/static/scripts/folder.js
rename to slapos/runner/static/js/scripts/folder.js
diff --git a/slapos/runner/static/js/scripts/inspectInstance.js b/slapos/runner/static/js/scripts/inspectInstance.js
new file mode 100644
index 0000000..5faf5a4
--- /dev/null
+++ b/slapos/runner/static/js/scripts/inspectInstance.js
@@ -0,0 +1,85 @@
+$(document).ready( function() {
+  var basedir = $("input#basedir").val();
+  var editor;
+  setupFileTree();
+
+  function setupFileTree(){
+    var root = $("input#root").val();
+    if (root == "") return;
+    $('#fileTree').fileTree({ root: root, script: $SCRIPT_ROOT + "/readFolder", folderEvent: 'click', expandSpeed: 750,
+      collapseSpeed: 750, multiFolder: false, selectFolder: false }, function(file) { 
+		      
+      }, function(file){
+	//User have double click on file in to the fileTree
+	viewFile(file);
+    });
+  }
+  
+  function viewFile(file){
+	  //User have double click on file in to the fileTree
+	  var name = file.replace(basedir, "");
+	  loadFileContent(file, name);
+  }
+	
+  function loadFileContent(file, filename){
+  $.ajax({
+	type: "POST",
+	url: $SCRIPT_ROOT + '/checkFileType',
+	data: "path=" + file,
+	success: function(data){
+	  if(data.code == 1){
+	    if (data.result=="text"){
+	      $.ajax({
+	      type: "POST",
+	      url: $SCRIPT_ROOT + '/getFileContent',
+	      data: {file:file, truncate:1500},
+	      success: function(data){	
+		      if(data.code == 1){
+			      $("#flash").empty();
+			      $("#inline_content").empty();
+			      $("#inline_content").append('<h2 style="color: #4c6172; font: 18px \'Helvetica Neue\', Helvetica, Arial, sans-serif;">Inspect Software Content: ' +
+				      filename +'</h2>');
+			      $("#inline_content").append('<br/><div class="main_content"><pre id="editor"></pre></div>');
+			      setupEditor();
+			      $(".inline").colorbox({inline:true, width: "847px", onComplete:function(){						
+				      editor.getSession().setValue(data.result);
+			      }});
+			      $(".inline").click();
+		      }
+		      else{
+			      error("Error: Can not load your file, please make sure that you have selected a Software Release");
+		      }
+		  }
+	      });
+	    }
+	    else{
+	      //Can not displays binary file
+	      error(data.result);
+	    }
+	  }
+	  else{
+	    error(data.result);
+	  }
+	}
+    });
+  }
+  
+  function setupEditor(){		
+    editor = ace.edit("editor");
+    editor.setTheme("ace/theme/crimson_editor");
+
+    var CurentMode = require("ace/mode/text").Mode;
+    editor.getSession().setMode(new CurentMode());
+    editor.getSession().setTabSize(2);
+    editor.getSession().setUseSoftTabs(true);
+    editor.renderer.setHScrollBarAlwaysVisible(false);
+    editor.setReadOnly(true);
+  }
+	
+  function error(msg){
+    $("#flash").fadeOut('normal');
+    $("#flash").empty();
+    $("#flash").fadeIn('normal');
+    $("#flash").append("<ul class='flashes'><li>" + msg + "</li></ul>");
+  }
+});
\ No newline at end of file
diff --git a/slapos/runner/static/scripts/inspectSoftware.js b/slapos/runner/static/js/scripts/inspectSoftware.js
similarity index 57%
rename from slapos/runner/static/scripts/inspectSoftware.js
rename to slapos/runner/static/js/scripts/inspectSoftware.js
index a55979d..1c3d607 100644
--- a/slapos/runner/static/scripts/inspectSoftware.js
+++ b/slapos/runner/static/js/scripts/inspectSoftware.js
@@ -1,4 +1,5 @@
 $(document).ready( function() {
+	var editor;
 	var send = false;
 	var runnerDir = $("input#runnerdir").val();
 	var ajaxRun;
@@ -22,7 +23,7 @@ $(document).ready( function() {
 		$('#fileTree').fileTree({ root: runnerDir + "/" + folder, script: $SCRIPT_ROOT + '/readFolder', 
 			folderEvent: 'click', expandSpeed: 750, collapseSpeed: 750, multiFolder: false, selectFolder: true }, function(file) { 
 			selectFile(file);
-		});
+		}, function(file){ viewFile(file)});
 		$("#softcontent").empty();		
 		$("#softcontent").append("File content: " + elt.attr('title'));
 	}
@@ -58,7 +59,8 @@ $(document).ready( function() {
 					$('#fileTree').fileTree({ root: runnerDir + "/" + folder, script: $SCRIPT_ROOT + '/readFolder', folderEvent: 'click', expandSpeed: 750,
 						collapseSpeed: 750, multiFolder: false, selectFolder: true }, function(file) { 
 					selectFile(file);
-					});
+					setupFileTree(runnerDir);
+					}, function(file){ viewFile(file)});
 					$("input#file").val("");
 					$("#flash").fadeOut('normal');
 					$("#flash").empty();
@@ -80,6 +82,67 @@ $(document).ready( function() {
 		return false;	
 	});
 	
+	function viewFile(file){
+		//User have double click on file in to the fileTree
+		var name = file.replace(runnerDir + "/" + $("#softwarelist").val(), "/software");
+		loadFileContent(file, name);
+	}
+	
+	function loadFileContent(file, filename){
+	    $.ajax({
+		  type: "POST",
+		  url: $SCRIPT_ROOT + '/checkFileType',
+		  data: "path=" + file,
+		  success: function(data){
+		    if(data.code == 1){
+		      if (data.result=="text"){
+			$.ajax({
+			type: "POST",
+			url: $SCRIPT_ROOT + '/getFileContent',
+			data: {file:file, truncate:1500},
+			success: function(data){	
+				if(data.code == 1){
+					$("#flash").empty();
+					$("#inline_content").empty();
+					$("#inline_content").append('<h2 style="color: #4c6172; font: 18px \'Helvetica Neue\', Helvetica, Arial, sans-serif;">Inspect Software Content: ' +
+						filename +'</h2>');
+					$("#inline_content").append('<br/><div class="main_content"><pre id="editor"></pre></div>');
+					setupEditor();
+					$(".inline").colorbox({inline:true, width: "847px", onComplete:function(){						
+						editor.getSession().setValue(data.result);
+					}});
+					$(".inline").click();
+				}
+				else{
+					error("Error: Can not load your file, please make sure that you have selected a Software Release");
+				}
+			    }
+			});
+		      }
+		      else{
+			//Can not displays binary file
+			error(data.result);
+		      }
+		    }
+		    else{
+		      error(data.result);
+		    }
+		  }
+	      });
+	}
+	
+	function setupEditor(){		
+		editor = ace.edit("editor");
+		editor.setTheme("ace/theme/crimson_editor");
+	
+		var CurentMode = require("ace/mode/text").Mode;
+		editor.getSession().setMode(new CurentMode());
+		editor.getSession().setTabSize(2);
+		editor.getSession().setUseSoftTabs(true);
+		editor.renderer.setHScrollBarAlwaysVisible(false);
+		editor.setReadOnly(true);
+	}
+	
 	function error(msg){
 		$("#flash").fadeOut('normal');
 		$("#flash").empty();
diff --git a/slapos/runner/static/scripts/project.js b/slapos/runner/static/js/scripts/project.js
similarity index 100%
rename from slapos/runner/static/scripts/project.js
rename to slapos/runner/static/js/scripts/project.js
diff --git a/slapos/runner/static/scripts/repo.js b/slapos/runner/static/js/scripts/repo.js
similarity index 100%
rename from slapos/runner/static/scripts/repo.js
rename to slapos/runner/static/js/scripts/repo.js
diff --git a/slapos/runner/static/scripts/softwareFolder.js b/slapos/runner/static/js/scripts/softwareFolder.js
similarity index 100%
rename from slapos/runner/static/scripts/softwareFolder.js
rename to slapos/runner/static/js/scripts/softwareFolder.js
diff --git a/slapos/runner/templates/cloneRepository.html b/slapos/runner/templates/cloneRepository.html
index 40cca00..1d26c04 100644
--- a/slapos/runner/templates/cloneRepository.html
+++ b/slapos/runner/templates/cloneRepository.html
@@ -3,8 +3,8 @@
 {% block head %}
   {{ super() }}
   <link href="{{ url_for('static', filename='css/jqueryFileTree.css', _external=False) }}" rel="stylesheet" type="text/css" media="screen" />
-  <script src="{{ url_for('static', filename='jquery/jqueryFileTree.js') }}" type="text/javascript" charset="utf-8"></script>
-  <script src="{{ url_for('static', filename='scripts/folder.js') }}" type="text/javascript" charset="utf-8"></script>
+  <script src="{{ url_for('static', filename='js/jquery/jqueryFileTree.js') }}" type="text/javascript" charset="utf-8"></script>
+  <script src="{{ url_for('static', filename='js/scripts/folder.js') }}" type="text/javascript" charset="utf-8"></script>
 {% endblock %}
 {% block body %}
 
diff --git a/slapos/runner/templates/instanceInspect.html b/slapos/runner/templates/instanceInspect.html
index 84c1b37..ff2829c 100644
--- a/slapos/runner/templates/instanceInspect.html
+++ b/slapos/runner/templates/instanceInspect.html
@@ -3,20 +3,18 @@
 {% block head %}
   {{ super() }}
   <link href="{{ url_for('static', filename='css/jqueryFileTree.css', _external=False) }}" rel="stylesheet" type="text/css" media="screen" />
-  <script src="{{ url_for('static', filename='jquery/jqueryFileTree.js') }}" type="text/javascript" charset="utf-8"></script>
+  <script src="{{ url_for('static', filename='js/jquery/jqueryFileTree.js') }}" type="text/javascript" charset="utf-8"></script>
   <link href="{{ url_for('static', filename='css/jqueryTabs.css', _external=False) }}" rel="stylesheet" type="text/css" media="screen" />
-  <script src="{{ url_for('static', filename='jquery/jqueryTabs.js') }}" type="text/javascript" charset="utf-8"></script>
-  {%if file_path != "" %}
-  <script type="text/javascript" charset="utf-8">
-    $(document).ready( function() {
-      $('#fileTree').fileTree({ root: "{{file_path}}", script: $SCRIPT_ROOT + "/readFolder", folderEvent: 'click', expandSpeed: 750, collapseSpeed: 750, multiFolder: false, selectFolder: false }, function(file) { 
-			
-		});
-    });
-  </script>
-  {%endif%}
+  <script src="{{ url_for('static', filename='js/jquery/jqueryTabs.js') }}" type="text/javascript" charset="utf-8"></script>
+  <script src="{{ url_for('static', filename='js/ace/ace-uncompressed.js') }}" type="text/javascript" charset="utf-8"></script>
+  <script src="{{ url_for('static', filename='js/ace/theme-crimson_editor.js') }}" type="text/javascript" charset="utf-8"></script>
+  <link href="{{ url_for('static', filename='css/colorbox.css', _external=False) }}" rel="stylesheet" type="text/css" media="screen" />
+  <script src="{{ url_for('static', filename='js/jquery/jquery.colorbox-min.js') }}" type="text/javascript" charset="utf-8"></script>
+  <script src="{{ url_for('static', filename='js/scripts/inspectInstance.js') }}" type="text/javascript" charset="utf-8"></script>
 {% endblock %}
 {% block body %}
+<input type='hidden' name='root' id='root' value='{%if file_path != "" %}{{file_path}}{%endif%}' />
+<input type='hidden' name='basedir' id='basedir' value='{{base_dir}}' />
 <h2>Instance inspection</h2><br/>
 <div id="tabContaier">
     <ul>
@@ -57,4 +55,11 @@
         </div><!-- end tab3 -->
     </div>
 </div>
+<!-- This contains the hidden content for inline calls -->
+<a class='inline' style='display:none' href="#inline_content">Inline HTML</a>
+<div style='display:none'>
+<div id='inline_content' style='padding:10px; background:#fff;'>
+
+</div>
+</div>
 {% endblock %}
diff --git a/slapos/runner/templates/layout.html b/slapos/runner/templates/layout.html
index d5af2c9..537c0c1 100644
--- a/slapos/runner/templates/layout.html
+++ b/slapos/runner/templates/layout.html
@@ -13,7 +13,7 @@
         <meta name="description" content="" />
 
         <link href="{{ url_for('static', filename='css/styles.css', _external=False) }}" rel="stylesheet" type="text/css" media="screen" />
-        <script src="{{ url_for('static', filename='jquery/jquery-1.6.2.min.js') }}" type="text/javascript" charset="utf-8"></script>        
+        <script src="{{ url_for('static', filename='js/jquery/jquery-1.6.2.min.js') }}" type="text/javascript" charset="utf-8"></script>        
         <script type=text/javascript>
           $SCRIPT_ROOT = {{ request.script_root|tojson|safe }};
         </script>
diff --git a/slapos/runner/templates/layout_test.html b/slapos/runner/templates/layout_test.html
deleted file mode 100644
index c9308cc..0000000
--- a/slapos/runner/templates/layout_test.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<!doctype html>
-<!-- Piwik --> 
-<script type="text/javascript">
-    var pkBaseURL = (("https:" == document.location.protocol) ? "https://[::1]:9080/piwik/" : "http://[::1]:9080/piwik/");
-    document.write(unescape("%3Cscript src='" + pkBaseURL + "piwik.js' type='text/javascript'%3E%3C/script%3E"));
-</script><script type="text/javascript">
-    try {
-        var piwikTracker = Piwik.getTracker(pkBaseURL + "piwik.php", 1);
-        piwikTracker.trackPageView();
-        piwikTracker.enableLinkTracking();
-    } catch( err ) {}
-</script><noscript><p><img src="http://[::1]:9080/piwik/piwik.php?idsite=1" style="border:0" alt="" /></p></noscript>
-<!-- End Piwik Tracking Code -->
-<title>Buildout runner</title>
-<div class=menu>
-    <a href="{{ url_for('home') }}">Home</a> |
-    Software:
-    <a href="{{ url_for('editSoftwareProfile') }}">Edit</a>
-    <a href="{{ url_for('runSoftwareProfile') }}">Run</a>
-    <a href="{{ url_for('viewSoftwareLog') }}">Build log</a>
-    <a href="{{ url_for('inspectSoftware') }}">Inspect</a>
-    <a href="{{ url_for('removeSoftware') }}">Remove</a>
-    |
-    Instance
-    <a href="{{ url_for('editInstanceProfile') }}">Edit</a>
-    <a href="{{ url_for('runInstanceProfile') }}">Run</a>
-    <a href="{{ url_for('viewInstanceLog') }}">Build log</a>
-    <a href="{{ url_for('inspectInstance') }}">Inspect</a>
-    <a href="{{ url_for('stopAllPartition') }}">Stop all</a>
-    <a href="{{ url_for('removeInstance') }}">Remove</a>
-</div>
-{% with messages = get_flashed_messages() %}
-{% if messages %}
-<ul class=flashes>
-    {% for message in messages %}
-    <li>{{ message }}</li>
-    {% endfor %}
-</ul>
-{% endif %}
-{% endwith %}
-<div class=page>
-    {% block body %}{% endblock %}
-</div>
diff --git a/slapos/runner/templates/manageProject.html b/slapos/runner/templates/manageProject.html
index 4da5b82..f554c5d 100644
--- a/slapos/runner/templates/manageProject.html
+++ b/slapos/runner/templates/manageProject.html
@@ -2,8 +2,8 @@
 {% block title %}Manage your Project{% endblock %}
 {% block head %}
   {{ super() }}  
-  <script src="{{ url_for('static', filename='jquery/jqueryFileTree.js') }}" type="text/javascript" charset="utf-8"></script>
-  <script src="{{ url_for('static', filename='scripts/repo.js') }}" type="text/javascript" charset="utf-8"></script>
+  <script src="{{ url_for('static', filename='js/jquery/jqueryFileTree.js') }}" type="text/javascript" charset="utf-8"></script>
+  <script src="{{ url_for('static', filename='js/scripts/repo.js') }}" type="text/javascript" charset="utf-8"></script>
 {% endblock %}
 {% block body %}
 
diff --git a/slapos/runner/templates/projectDiff.html b/slapos/runner/templates/projectDiff.html
index 948a37c..e997433 100644
--- a/slapos/runner/templates/projectDiff.html
+++ b/slapos/runner/templates/projectDiff.html
@@ -2,8 +2,8 @@
 {% block title %}Diff for '{{project}}'{% endblock %}
 {% block head %}
   {{ super() }}  
-  <script src="{{ url_for('static', filename='ace/ace-uncompressed.js') }}" type="text/javascript" charset="utf-8"></script>
-  <script src="{{ url_for('static', filename='ace/theme-crimson_editor.js') }}" type="text/javascript" charset="utf-8"></script>
+  <script src="{{ url_for('static', filename='js/ace/ace-uncompressed.js') }}" type="text/javascript" charset="utf-8"></script>
+  <script src="{{ url_for('static', filename='js/ace/theme-crimson_editor.js') }}" type="text/javascript" charset="utf-8"></script>
   <script type="text/javascript">
     $(document).ready( function() {
         var editor = ace.edit("editor");
diff --git a/slapos/runner/templates/projectFolder.html b/slapos/runner/templates/projectFolder.html
index e80f791..3827163 100644
--- a/slapos/runner/templates/projectFolder.html
+++ b/slapos/runner/templates/projectFolder.html
@@ -3,8 +3,8 @@
 {% block head %}
   {{ super() }}
   <link href="{{ url_for('static', filename='css/jqueryFileTree.css', _external=False) }}" rel="stylesheet" type="text/css" media="screen" />
-  <script src="{{ url_for('static', filename='jquery/jqueryFileTree.js') }}" type="text/javascript" charset="utf-8"></script>
-  <script src="{{ url_for('static', filename='scripts/project.js') }}" type="text/javascript" charset="utf-8"></script>
+  <script src="{{ url_for('static', filename='js/jquery/jqueryFileTree.js') }}" type="text/javascript" charset="utf-8"></script>
+  <script src="{{ url_for('static', filename='js/scripts/project.js') }}" type="text/javascript" charset="utf-8"></script>
 {% endblock %}
 {% block body %}
 
diff --git a/slapos/runner/templates/runResult.html b/slapos/runner/templates/runResult.html
index a087b96..6e54819 100644
--- a/slapos/runner/templates/runResult.html
+++ b/slapos/runner/templates/runResult.html
@@ -3,8 +3,13 @@
 {% block head %}
   {{ super() }}
   <link href="{{ url_for('static', filename='css/jqueryFileTree.css', _external=False) }}" rel="stylesheet" type="text/css" media="screen" />
-  <script src="{{ url_for('static', filename='jquery/jqueryFileTree.js') }}" type="text/javascript" charset="utf-8"></script>
-  <script src="{{ url_for('static', filename='scripts/inspectSoftware.js') }}" type="text/javascript" charset="utf-8"></script>
+  <script src="{{ url_for('static', filename='js/jquery/jqueryFileTree.js') }}" type="text/javascript" charset="utf-8"></script>  
+  <script src="{{ url_for('static', filename='js/ace/ace-uncompressed.js') }}" type="text/javascript" charset="utf-8"></script>
+  <script src="{{ url_for('static', filename='js/ace/theme-crimson_editor.js') }}" type="text/javascript" charset="utf-8"></script>
+  <script src="{{ url_for('static', filename='js/scripts/inspectSoftware.js') }}" type="text/javascript" charset="utf-8"></script>
+  <link href="{{ url_for('static', filename='css/colorbox.css', _external=False) }}" rel="stylesheet" type="text/css" media="screen" />
+  <script src="{{ url_for('static', filename='js/jquery/jquery.colorbox-min.js') }}" type="text/javascript" charset="utf-8"></script>
+  
 {% endblock %}
 {% block body %}
 <h2>Inspect software</h2>
@@ -21,8 +26,15 @@
 <p><strong><u>Notes:</u> </strong> You can open any software release in the list by cliking on the "Open" button. Now compiling this software will take a very short time</p>
 <br/>
 <h2 id="softcontent">No content to displays</h2>
-<div id="fileTree" class="file_tree"></div>
+<div id="fileTree" class="file_tree" style='height:200px;'></div>
 <div id="file_info" class="file_info">
 <span id="info">Please select your file or folder into the box...</span></div>
+<!-- This contains the hidden content for inline calls -->
+<a class='inline' style='display:none' href="#inline_content">Inline HTML</a>
+<div style='display:none'>
+<div id='inline_content' style='padding:10px; background:#fff;'>
+
+</div>
+</div>
 <br/>
 {% endblock %}
diff --git a/slapos/runner/templates/softwareFolder.html b/slapos/runner/templates/softwareFolder.html
index da06213..471a3e0 100644
--- a/slapos/runner/templates/softwareFolder.html
+++ b/slapos/runner/templates/softwareFolder.html
@@ -3,13 +3,13 @@
 {% block head %}
   {{ super() }}
   <link href="{{ url_for('static', filename='css/jqueryFileTree.css', _external=False) }}" rel="stylesheet" type="text/css" media="screen" />
-  <script src="{{ url_for('static', filename='jquery/jqueryFileTree.js') }}" type="text/javascript" charset="utf-8"></script>
-  <script src="{{ url_for('static', filename='scripts/softwareFolder.js') }}" type="text/javascript" charset="utf-8"></script>
-  <script src="{{ url_for('static', filename='ace/ace-uncompressed.js') }}" type="text/javascript" charset="utf-8"></script>
-    <script src="{{ url_for('static', filename='ace/theme-crimson_editor.js') }}" type="text/javascript" charset="utf-8"></script>
-    <script src="{{ url_for('static', filename='ace/mode-buildout.js') }}" type="text/javascript" charset="utf-8"></script>
-    <script src="{{ url_for('static', filename='ace/mode-python.js') }}" type="text/javascript" charset="utf-8"></script>
-    <script src="{{ url_for('static', filename='ace/mode-php.js') }}" type="text/javascript" charset="utf-8"></script>
+  <script src="{{ url_for('static', filename='js/jquery/jqueryFileTree.js') }}" type="text/javascript" charset="utf-8"></script>
+  <script src="{{ url_for('static', filename='js/scripts/softwareFolder.js') }}" type="text/javascript" charset="utf-8"></script>
+  <script src="{{ url_for('static', filename='js/ace/ace-uncompressed.js') }}" type="text/javascript" charset="utf-8"></script>
+    <script src="{{ url_for('static', filename='js/ace/theme-crimson_editor.js') }}" type="text/javascript" charset="utf-8"></script>
+    <script src="{{ url_for('static', filename='js/ace/mode-buildout.js') }}" type="text/javascript" charset="utf-8"></script>
+    <script src="{{ url_for('static', filename='js/ace/mode-python.js') }}" type="text/javascript" charset="utf-8"></script>
+    <script src="{{ url_for('static', filename='js/ace/mode-php.js') }}" type="text/javascript" charset="utf-8"></script>
 {% endblock %}
 {% block body %}
 
diff --git a/slapos/runner/templates/updateInstanceProfile.html b/slapos/runner/templates/updateInstanceProfile.html
index 861576a..f259d54 100644
--- a/slapos/runner/templates/updateInstanceProfile.html
+++ b/slapos/runner/templates/updateInstanceProfile.html
@@ -2,10 +2,10 @@
 {% block title %}Update instance profile{% endblock %}
 {% block head %}
   {{ super() }}
-    <script src="{{ url_for('static', filename='ace/ace-uncompressed.js') }}" type="text/javascript" charset="utf-8"></script>
-    <script src="{{ url_for('static', filename='ace/theme-crimson_editor.js') }}" type="text/javascript" charset="utf-8"></script>
-    <script src="{{ url_for('static', filename='ace/mode-buildout.js') }}" type="text/javascript" charset="utf-8"></script>
-  <script src="{{ url_for('static', filename='scripts/editor.js') }}" type="text/javascript" charset="utf-8"></script>
+    <script src="{{ url_for('static', filename='js/ace/ace-uncompressed.js') }}" type="text/javascript" charset="utf-8"></script>
+    <script src="{{ url_for('static', filename='js/ace/theme-crimson_editor.js') }}" type="text/javascript" charset="utf-8"></script>
+    <script src="{{ url_for('static', filename='js/ace/mode-buildout.js') }}" type="text/javascript" charset="utf-8"></script>
+  <script src="{{ url_for('static', filename='js/scripts/editor.js') }}" type="text/javascript" charset="utf-8"></script>
 {% endblock %}
 {% block body %}
 <form method=post class=add-entry>
diff --git a/slapos/runner/templates/updateSoftwareProfile.html b/slapos/runner/templates/updateSoftwareProfile.html
index 6bde143..03c2db0 100644
--- a/slapos/runner/templates/updateSoftwareProfile.html
+++ b/slapos/runner/templates/updateSoftwareProfile.html
@@ -2,10 +2,10 @@
 {% block title %}Update software profile{% endblock %}
 {% block head %}
   {{ super() }}
-    <script src="{{ url_for('static', filename='ace/ace-uncompressed.js') }}" type="text/javascript" charset="utf-8"></script>
-    <script src="{{ url_for('static', filename='ace/theme-crimson_editor.js') }}" type="text/javascript" charset="utf-8"></script>
-    <script src="{{ url_for('static', filename='ace/mode-buildout.js') }}" type="text/javascript" charset="utf-8"></script>
-  <script src="{{ url_for('static', filename='scripts/editor.js') }}" type="text/javascript" charset="utf-8"></script>
+    <script src="{{ url_for('static', filename='js/ace/ace-uncompressed.js') }}" type="text/javascript" charset="utf-8"></script>
+    <script src="{{ url_for('static', filename='js/ace/theme-crimson_editor.js') }}" type="text/javascript" charset="utf-8"></script>
+    <script src="{{ url_for('static', filename='js/ace/mode-buildout.js') }}" type="text/javascript" charset="utf-8"></script>
+  <script src="{{ url_for('static', filename='js/scripts/editor.js') }}" type="text/javascript" charset="utf-8"></script>
 {% endblock %}
 {% block body %}
 <form method=post class=add-entry>
diff --git a/slapos/runner/utils.py b/slapos/runner/utils.py
index c234238..71222b9 100755
--- a/slapos/runner/utils.py
+++ b/slapos/runner/utils.py
@@ -423,4 +423,15 @@ def tail(f, lines=20):
       size -= linesFound
       bytes -= BUFSIZ
       block -= 1
-  return string.join(''.join(data).splitlines()[-lines:], '\n')
\ No newline at end of file
+  return string.join(''.join(data).splitlines()[-lines:], '\n')
+
+def isText(file):
+  """Return True if the mimetype of file is Text"""
+  if not os.path.exists(file):
+    return False
+  text_range = ''.join(map(chr, [7,8,9,10,12,13,27] + range(0x20, 0x100)))
+  is_binary_string = lambda bytes: bool(bytes.translate(None, text_range))
+  try:
+    return not is_binary_string(open(file).read(1024))
+  except:
+    return False
\ No newline at end of file
diff --git a/slapos/runner/views.py b/slapos/runner/views.py
index b144a59..d0dded5 100755
--- a/slapos/runner/views.py
+++ b/slapos/runner/views.py
@@ -98,7 +98,7 @@ def inspectInstance():
       result = []
   return render_template('instanceInspect.html',
       file_path=file_content, supervisor=result, slap_status=getSlapStatus(app.config),
-      supervisore=result)
+      supervisore=result, base_dir=app.config['runner_workdir'])
 
 @app.route('/removeInstance')
 def removeInstance():
@@ -244,7 +244,11 @@ def removeSoftwareDir():
 @app.route("/getFileContent", methods=['POST'])
 def getFileContent():
   if os.path.exists(request.form['file']):
-    return jsonify(code=1, result=open(request.form['file'], 'r').read())
+    if not request.form.has_key('truncate'):
+      return jsonify(code=1, result=open(request.form['file'], 'r').read())
+    else:
+      content = tail(open(request.form['file'], 'r'), int(request.form['truncate']))
+      return jsonify(code=1, result=content)
   else:
     return jsonify(code=0, result="Error: No such file!")
   
@@ -276,4 +280,12 @@ def pushProjectFiles():
 
 @app.route("/pullProjectFiles", methods=['POST'])
 def pullProjectFiles():
-  return gitPull(request.form['project'])
\ No newline at end of file
+  return gitPull(request.form['project'])
+
+@app.route("/checkFileType", methods=['POST'])
+def checkFileType():
+  path = request.form['path']
+  if isText(path):
+    return jsonify(code=1, result="text")
+  else:
+    return jsonify(code=0, result="You can only open text files!")
\ No newline at end of file
-- 
2.30.9