Commit 13e2382b authored by Cédric de Saint Martin's avatar Cédric de Saint Martin

Merge branch 'slaprunner'

parents 2e078567 c5eaa61f
......@@ -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',
]
},
)
......@@ -30,7 +30,9 @@ def cloneRepo(data):
repo = Repo.clone_from(data["repo"], workDir)
config_writer = repo.config_writer()
config_writer.add_section("user")
if data["user"] != "":
config_writer.set_value("user", "name", data["user"])
if data["email"] != "":
config_writer.set_value("user", "email", data["email"])
code = 1
except Exception, e:
......@@ -63,17 +65,73 @@ def switchBranch(project, name):
if name == current_branch:
json = "This is already your active branch for this project"
else:
branch = none
for b in branches:
if b.name == name:
branch = b
if branch != none:
repo.heads.master.checkout()
repo.heads.branch.checkout()
json = "Error: Can not found branch '" + name + "'"
git = repo.git
git.checkout(name)
except Exception, e:
json = str(e)
return jsonify(code=code, result=json)
def createBranch(project, name):
code = 0
json = ""
try:
repo = Repo(project)
git = repo.git
git.checkout('-b', name)
code = 1
else:
except Exception, e:
json = str(e)
return jsonify(code=code, result=json)
def getDiff(project):
result = ""
try:
repo = Repo(project)
git = repo.git
current_branch = repo.active_branch.name
result = git.diff(current_branch)
except Exception, e:
result = str(e)
return result
def gitPush(project, msg):
code = 0
json = "Error: Can not found branch '" + name + "'"
json = ""
undo_commit = False
try:
repo = Repo(project)
if repo.is_dirty:
git = repo.git
current_branch = repo.active_branch.name
#add file to be commited
files = repo.untracked_files
for f in files:
git.add(f)
#Commit all modified and untracked files
git.commit('-a', '-m', msg)
undo_commit = True
#push changes to repo
git.push('origin', current_branch)
code = 1
else:
json = "Nothing to be commited"
code = 1
except Exception, e:
if undo_commit:
git.reset("HEAD~") #undo previous commit
json = str(e)
return jsonify(code=code, result=json)
def gitPull(project):
result = ""
code = 0
try:
repo = Repo(project)
git = repo.git
current_branch = repo.active_branch.name
git.pull()
code = 1
except Exception, e:
result = str(e)
return jsonify(code=code, result=result)
\ No newline at end of file
/*
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
#tabContaier{
background: #e4e4e4;
padding:3px;
position:relative;
width:757px;
font-size: 14px;
}
#tabContaier textarea {
width:702px;
}
#tabContaier > ul{
overflow:hidden;
border-right:1px solid #fff;
height:34px;
position:absolute;
z-index:100;
}
#tabContaier > ul > li{
float:left;
list-style:none;
}
#tabContaier > ul > li a{
background:#ddd;
border:1px solid #fcfcfc;
border-right:0;
border-bottom: 0;
color:#666;
cursor:pointer;
display:block;
height:34px;
line-height:34px;
padding:0 30px;
text-decoration:none;
color: #737373;
text-shadow: 0px 1px #FFF;
font-size: 17px;
}
#tabContaier > ul > li a:hover{
background:#eee;
}
#tabContaier > ul > li a.active{
background:#fbfbfb;
border:1px solid #fff;
border-right:0;
color:#333;
}
.tabDetails{
background:#fbfbfb;
border:1px solid #fff;
border-top: none;
margin:34px 0 0;
}
.tabContents{
padding:20px
}
.tabContents p{
padding:0 0 10px;
}
......@@ -6,32 +6,37 @@ padding: 0px;
}
a{
color: #4DA0C6;
text-decoration: none;
color: #19485C;
}
a:hover {
text-decoration: none;
color: #000;
color: #4DA0C6;
}
table {
margin: 0;
border: 1px solid #0271BF;
border: 1px solid #A8A8A8;
border-right: none;
border-bottom: none;
font-size: 14px;
background: #fff;
}
td{
padding: 5px;
border: none;
border-bottom: 1px solid #0271BF;
border-right: 1px solid #0271BF;
border-bottom: 1px solid #A8A8A8;
border-right: 1px solid #A8A8A8;
}
th{
background: #D0D0D0;
background: #e4e4e4;
padding: 5px;
border: none;
border-bottom: 1px solid #0271BF;
border-right: 1px solid #0271BF;
border-bottom: 1px solid #A8A8A8;
border-right: 1px solid #A8A8A8;
color: #4c6172;
font-weight: normal;
font-size: 16px;
}
textarea {
......@@ -39,7 +44,7 @@ textarea {
}
body {
background: #0271BF;
background: #7195c2 url('../images/cloud_bg.jpg') repeat-x;
font: 13px 'Helvetica Neue', Helvetica, Arial, sans-serif;
color: #000000;
}
......@@ -212,6 +217,13 @@ body {
font-weight: normal;
font-size: 18px;
}
.content h2 a{
text-decoration:none;
color: #4DA0C6;
}
.content h2 a:hover{
color: #19485C;
}
.main_foot{
height: 15px;
......@@ -241,8 +253,6 @@ body {
font-weight: bold;
border:1px solid #000;
margin-top:10px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
}
.button:hover {
background-position: 0 center;
......@@ -310,7 +320,7 @@ body {
}
#home_box a{
color: #4c6172;
color: #475F73;
cursor: pointer;
text-decoration: none;
}
......@@ -327,6 +337,7 @@ body {
#home_box p{
font-size: 13px;
color: #475F73;
float: left;
}
......@@ -348,7 +359,7 @@ body {
.inner_box p{
font-size: 13px;
float: left;
width: 400px;
width: 460px;
cursor:default;
}
......@@ -357,10 +368,10 @@ body {
display: block;
height: 80px;
margin: 10px;
margin-left: 80px;
margin-left: 60px;
padding: 15px;
border: #678dad;
width: 500px;
width: 540px;
border: 1px solid #678dad;
}
......@@ -372,11 +383,11 @@ body {
.smenu{
display: block;
height: 80px;
margin-left: 80px;
margin-left: 60px;
margin-right: 10px;
padding: 15px;
border: #678dad;
width: 230px;
width: 250px;
border: 1px solid #678dad;
float: left;
}
......@@ -386,7 +397,7 @@ body {
height: 80px;
padding: 15px;
border: #678dad;
width: 227px;
width: 247px;
border: 1px solid #678dad;
float: left;
}
......@@ -394,7 +405,7 @@ body {
.sright_menu p, .smenu p{
font-size: 13px;
float: left;
width: 150px;
width: 170px;
cursor:default;
}
......@@ -407,9 +418,18 @@ body {
padding: 5px;
}
.file_tree_tabs {
width: 702px;
height: 250px;
border: solid 1px #678dad;
background: #fff;
overflow: auto;
padding: 5px;
}
.file_tree_short{
width: 352px;
height: 100px;
height: 170px;
border: solid 1px #678dad;
background: #fff;
overflow: auto;
......@@ -418,19 +438,22 @@ body {
}
.box_software{
width: 382px;
width: 362px;
height: 100px;
background: #fff;
padding: 5px;
float:right;
}
#details_box{
display:none;
}
#contentInfo{
width: 752px;
width: 756px;
border: solid 1px #678dad;
background: #fff;
overflow: auto;
padding: 5px;
padding: 3px;
}
#contentInfo p{
......@@ -438,6 +461,32 @@ body {
margin: 5px;
}
#contentInfo h2, .hight{
background: #e4e4e4;
width: 100%;
height: 25px;
padding-top:2px;
text-indent: 5px;
color: #737373;
text-shadow: 0px 1px #FFF;
}
.show{
background: #e4e4e4 url(../images/arrow_up.png) 97% 50% no-repeat;
}
.hide{
background: #e4e4e4 url(../images/arrow_down.png) 97% 50% no-repeat;
}
h2.hight:hover{
cursor: pointer;
}
.software_details{
padding: 10px;
}
.log_content{
border: solid 1px #4c6172;
padding: 2px;
......@@ -496,7 +545,7 @@ body {
height: 1px;
width: 734px;
margin: 10px;
margin-top: 15px;
margin-top: 20px;
}
select {
......@@ -516,3 +565,81 @@ select {
padding: 4px;
text-overflow: ellipsis;
white-space: nowrap;}
a.lshare{
background: #fff url(../images/button_highlight.png) repeat-x;
padding: 4px 7px 4px 7px;
height: 18px;
font-size: 15px;
border: solid 1px #678dad;
color: #000;
margin-right: 10px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
text-shadow: 0px 1px #F0F1F2;
}
a.lshare:hover{
background:#D9D9D9 url(../images/button_highlight.png) 50% repeat-x;
color: #000;
border:solid 1px #73A6FF;
}
a.lshare:focus{
border:solid 1px #73A6FF;
}
a.lshare img{
margin: 5px;
}
#error{
padding: 0px;
position: absolute;
top: -2px;
left:0;
right: 0;
}
#error > div{
background: none repeat scroll 0 0 #afcee4;
border: 1px solid #FFF;
width:500px;
margin: 0 auto;
border-top:none;
border-radius: 0 0 4px 4px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
text-align: center;
}
#error table{
background: none;
width: 100%;
font-weight: normal;
}
#error table, #error th, #error tr, #error td{
border: none;
padding:0;
}
#error td{
margin:2px;
}
#error td.logo{
width: 36px;
height: 26px;
}
#error td.close{
width: 30px;
height:22px;
}
.alert_message{ background: url(../images/alert.png) center no-repeat; height: 26px;}
.error_message{ background: url(../images/exit.png) center no-repeat; height: 26px;}
.confirm_message{ background: url(../images/confirm.png) center no-repeat; height: 26px;}
.info_message{ background: url(../images/info.png) center no-repeat; height: 26px;}
#error p{ fon-size: 13px; color: #4A131F;}
#pClose{background:url(../images/close.png) no-repeat 0px 0px; display:block; width:22px; height:22px; cursor:pointer}
#pClose:hover{background:url(../images/close_hover.png) no-repeat 0px 0px;}
.md5sum {margin:10px; font-size:15px;}
.title{background: #e4e4e4; width: 100%; height: 25px; padding-top:2px; text-indent: 5px; color: #737373; text-shadow: 0px 1px #FFF;}
\ No newline at end of file
#
# jQuery File Tree
# Python/Django connector script
# By Martin Skou
#
import os
import urllib
def dirlist(request):
r=['<ul class="jqueryFileTree" style="display: none;">']
try:
r=['<ul class="jqueryFileTree" style="display: none;">']
d=urllib.unquote(request.POST.get('dir','c:\\temp'))
for f in os.listdir(d):
ff=os.path.join(d,f)
if os.path.isdir(ff):
r.append('<li class="directory collapsed"><a href="#" rel="%s/">%s</a></li>' % (ff,f))
else:
e=os.path.splitext(f)[1][1:] # get .ext and remove dot
r.append('<li class="file ext_%s"><a href="#" rel="%s">%s</a></li>' % (e,ff,f))
r.append('</ul>')
except Exception,e:
r.append('Could not load directory: %s' % str(e))
r.append('</ul>')
return HttpResponse(''.join(r))
\ No newline at end of file
......@@ -98,40 +98,13 @@ define('ace/mode/buildout', function(require, exports, module) {
return indent;
};
var outdents = {
"\r\n": 1,
"\r": 1,
"\n": 1
};
this.checkOutdent = function(state, line, input) {
if (input !== "\r\n" && input !== "\r" && input !== "\n")
return false;
var tokens = this.$tokenizer.getLineTokens(line.trim(), state).tokens;
if (!tokens)
return false;
// ignore trailing comments
do {
var last = tokens.pop();
} while (last && (last.type == "comment" || (last.type == "text" && last.value.match(/^\s+$/))));
if (!last)
return false;
return (last.type == "keyword" && outdents[last.value]);
};
this.autoOutdent = function(state, doc, row) {
// outdenting in python is slightly different because it always applies
// to the next line and only of a new line is inserted
row += 1;
var indent = this.$getIndent(doc.getLine(row));
var tab = doc.getTabString();
if (indent.slice(-tab.length) == tab)
doc.remove(new Range(row, indent.length-tab.length, row, indent.length));
};
}).call(Mode.prototype);
......@@ -148,11 +121,8 @@ define('ace/mode/buildout_highlight_rules', function(require, exports, module) {
var BuildoutHighlightRules = function() {
var keywords = lang.arrayToMap(
("parts|develop|versions|extends|depends|find-links|allow-hosts").split("|")
);
var buildinConstants = lang.arrayToMap(
("null|true|false").split("|")
("null|true|false|None").split("|")
);
var strPre = "(?:r|u|ur|R|U|UR|Ur|uR)?";
var decimalInteger = "(?:(?:[1-9]\\d*)|(?:0))";
......@@ -167,6 +137,7 @@ define('ace/mode/buildout_highlight_rules', function(require, exports, module) {
var pointFloat = "(?:(?:" + intPart + "?" + fraction + ")|(?:" + intPart + "\\.))";
var exponentFloat = "(?:(?:" + pointFloat + "|" + intPart + ")" + exponent + ")";
var floatNumber = "(?:" + exponentFloat + "|" + pointFloat + ")";
var pythonVariable = "%\\([\\w-_:][\\w\\d-_:\\.]*\\)s";
// regexp must not have capturing parentheses. Use (?:) instead.
// regexps are ordered -> the first match is used
......@@ -175,7 +146,10 @@ define('ace/mode/buildout_highlight_rules', function(require, exports, module) {
"start" : [
{
token : "keyword", // begin buildout part
regex : "^\\[[a-zA-Z-_][a-zA-Z0-9-_]*\\]"
regex : "^\\[[\\w\\d_][\\w\\d-_\\.]*\\]"
},{
token : "keyword", //begin buildout part with variable
regex : "^\\[" + pythonVariable + "\\]"
}, {
token : "comment",
regex : "#.*$"
......@@ -218,20 +192,20 @@ define('ace/mode/buildout_highlight_rules', function(require, exports, module) {
regex: "^[\\w\\d-_\\.]+\\s*\\+?="
}, {
token : function(value) {
if (keywords.hasOwnProperty(value.toLowerCase())) {
return "support.function";
}
else if (buildinConstants.hasOwnProperty(value.toLowerCase())) {
if (buildinConstants.hasOwnProperty(value.toLowerCase())) {
return "support.constant";
}
else {
return "text";
}
},
regex : "\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"
regex : "\\-?[\\w_][\\w\\d\\._-]*"
}, {
token : "variable",
regex : "\\$\\{[\\w-_:][\\w\\d-_:\\.]*\\}"
}, {
token : "variable",
regex : "\\$\\{[a-zA-Z-_:\\.][a-zA-Z0-9-_:\\.]*\\}"
regex : pythonVariable
}, {
token: "string",
regex: '\\s(?:ht|f)tps?:\\/\\/[a-z0-9-\\._:]+\\.[a-z]{2,4}\\/?(?:[^\\s<>\\#%"\\,\\{\\}\\\\|\\\\\\^\\[\\]`]+)?\\s*$'
......
// 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
// jQuery File Tree Plugin
// jQuery File Tree
//
// Version 1.01
//
// Cory S.N. LaViska
// A Beautiful Site (http://abeautifulsite.net/)
// 24 March 2008
//
// Visit http://abeautifulsite.net/notebook.php?article=58 for more information
//
// Usage: $('.fileTreeDemo').fileTree( options, callback )
// Usage: $('.tree').fileTree( options, callback )
//
// Options: root - root folder to display; default = /
// script - location of the serverside AJAX file to use; default = jqueryFileTree.php
// script - location of the serverside AJAX file to use;
// folderEvent - event to trigger expand/collapse; default = click
// expandSpeed - default = 500 (ms); use -1 for no animation
// collapseSpeed - default = 500 (ms); use -1 for no animation
......@@ -19,25 +11,16 @@
// collapseEasing - easing function to use on collapse (optional)
// multiFolder - whether or not to limit the browser to one subfolder at a time
// loadMessage - Message to display while initial tree loads (can be HTML)
//
// History:
//
// 1.01 - updated to work with foreign characters in directory/file names (12 April 2008)
// 1.00 - released (24 March 2008)
//
// TERMS OF USE
//
// This plugin is dual-licensed under the GNU General Public License and the MIT License and
// is copyright 2008 A Beautiful Site, LLC.
// selectFolder - if true, also return path of folder when event happen on it
//
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 = '/';
if( o.script == undefined ) o.script = 'jqueryFileTree.php';
if( o.script == undefined ) o.script = '';
if( o.folderEvent == undefined ) o.folderEvent = 'click';
if( o.expandSpeed == undefined ) o.expandSpeed= 500;
if( o.collapseSpeed == undefined ) o.collapseSpeed= 500;
......@@ -87,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>');
......
$(document).ready(function(){
$(".tabContents").hide(); // Hide all tab conten divs by default
$(".tabContents:first").show(); // Show the first div of tab content by default
$("#tabContaier ul li a").click(function(){ //Fire the click event
if($(this).hasClass('active')){
return;
}
var activeTab = $(this).attr("href"); // Catch the click link
$("#tabContaier ul li a").removeClass("active"); // Remove pre-highlighted link
$(this).addClass("active"); // set clicked link to highlight state
$(".tabContents").hide(); // hide currently visible tab content div
$(activeTab).fadeIn(); // show the target tab content div by matching clicked link.
});
});
\ No newline at end of file
// jQuery Message Popup
// Display a message on the top of page, with floating
//
(function ($, document, window) {
$.extend($.fn, {
Popup: function(msg, option) {
if (option.type == undefined) option.type = "info";
if (option.closebtn == undefined) option.closebtn = false;
if (option.duration == undefined) option.duration = 0;
if (option.load == undefined) option.load = false;
$box = $(this);
$box.empty();
$box.css('top','-1000px');
$box.show();
$box.append('<div><table id="bcontent"><tr>' +
'<td valign="middle" class="logo ' + option.type + '_message"></td>' +
'<td valign="middle"><p>' + msg + '</p></td>' +
'<td valign="middle" class="close"><span id="pClose"></span></td></tr></table></div>');
$(window).scroll(function(){
$box.animate({top:$(window).scrollTop()+"px" },{queue: false, duration: 350});
});
var h = $("#bcontent").height()+5;
$("#pClose").bind("click", function() {
close();
});
if(option.load){
$(window).load(function(){
$box.css('top', + ($(window).scrollTop() - h) +'px');
$box.animate({ top:"+=" + h + "px" }, "slow");
});
}
else{
$box.css('top', + ($(window).scrollTop() - h) +'px');
$box.animate({ top:"+=" + h + "px" }, "slow");
}
if(option.duration != 0){
setTimeout(function(){
close();
}, option.duration);
}
function close(){
$box.animate({ top:"-=" + h + "px" }, "slow", function(){
$box.fadeOut("normal");
});
}
}
});
}(jQuery, document, this));
\ No newline at end of file
$(document).ready( function() {
var editor = ace.edit("editor");
editor.setTheme("ace/theme/crimson_editor");
var CurentMode = require("ace/mode/buildout").Mode;
editor.getSession().setMode(new CurentMode());
editor.getSession().setTabSize(2);
editor.getSession().setUseSoftTabs(true);
editor.renderer.setHScrollBarAlwaysVisible(false);
var file = $("input#profile").val();
var edit = false;
var send = false;
selectFile(file);
$("#save").click(function(){
if(!edit){
$("#error").Popup("Can not load your file, please make sure that you have selected a Software Release", {type:'alert', duration:5000});
return false;
}
if (send) return;
send =true
$.ajax({
type: "POST",
url: $SCRIPT_ROOT + '/saveFileContent',
data: {file: file, content: editor.getSession().getValue()},
success: function(data){
if(data.code == 1){
$("#error").Popup("File Saved!", {type:'confirm', duration:2000});
}
else{
$("#error").Popup(data.result, {type:'error', duration:5000});
}
send = false;
}
});
return false;
});
$("#getmd5").click(function(){
getmd5sum();
return false;
});
function selectFile(file){
edit = false;
$.ajax({
type: "POST",
url: $SCRIPT_ROOT + '/getFileContent',
data: "file=" + file,
success: function(data){
if(data.code == 1){
editor.getSession().setValue(data.result);
edit = true;
}
else{
$("#error").Popup("Can not load your file, please make sure that you have selected a Software Release", {type:'alert', duration:5000});
}
}
});
return;
}
function getmd5sum(){
if (send) return;
send =true
$.ajax({
type: "POST",
url: $SCRIPT_ROOT + '/getmd5sum',
data: {file: file},
success: function(data){
if(data.code == 1){
$("#md5sum").empty();
$("#md5sum").append('md5sum : <span>' + data.result + '</span>');
}
else{
$("#error").Popup(data.result, {type:'error', duration:5000});
}
send = false;
}
});
}
});
\ No newline at end of file
......@@ -13,27 +13,28 @@ $(document).ready( function() {
send = false;
return;
}
$("#flash").fadeOut('normal');
$("#flash").empty();
$("#flash").fadeIn('normal');
repo_url = $("input#repo").val();
var repo_url = $("input#repo").val();
var email = "";
var name = ""
/* /^(ht|f)tps?:\/\/[a-z0-9-\.]+\.[a-z]{2,4}\/?([^\s<>\#%"\,\{\}\\|\\\^\[\]`]+)?$/ */
if($("input#repo").val() == "" || !repo_url.match(/^[\w\d\.\/:~@_-]+$/)){
$("#flash").append("<ul class='flashes'><li>Error: Invalid url for the repository</li></ul>");
$("#error").Popup("Invalid url for the repository", {type:'alert', duration:3000});
return false;
}
if($("input#name").val() == "" || !$("input#name").val().match(/^[\w\d\._-]+$/)){
$("#flash").append("<ul class='flashes'><li>Error: Invalid project name</li></ul>");
$("#error").Popup("Invalid project name", {type:'alert', duration:3000});
return false;
}
if($("input#user").val() == "" || $("input#user").val() == "Enter your name..."){
$("#flash").append("<ul class='flashes'><li>Error: Please enter your name!</li></ul>");
return false;
if($("input#user").val() != "" && $("input#user").val() != "Enter your name..."){
name = $("input#user").val();
}
if($("input#email").val() == "" || !$("input#email").val().match(/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/)){
$("#flash").append("<ul class='flashes'><li>Error: Please enter your email adress!</li></ul>");
if($("input#email").val() != "" && $("input#email").val() != "Enter your email adress..."){
if(!$("input#email").val().match(/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/)){
$("#error").Popup("Please enter a valid email adress!", {type:'alert', duration:3000});
return false;
}
email = $("input#email").val();
}
$("#imgwaitting").fadeIn('normal');
$("#clone").empty();
$("#clone").append("Stop");
......@@ -41,12 +42,12 @@ $(document).ready( function() {
cloneRequest = $.ajax({
type: "POST",
url: $SCRIPT_ROOT + '/cloneRepository',
data: "repo=" + repo_url + "&name=" + $("input#name").val() + "&email=" + $("input#email").val() +
"&user=" + $("input#user").val(),
data: "repo=" + repo_url + "&name=" + $("input#name").val() + "&email=" + email +
"&user=" + name,
success: function(data){
if(data.code == 1){
$("#file_navigation").fadeIn('normal');
$("#flash").append("<ul class='flashes'><li>Repository is cloned!</li></ul>");
$("#error").Popup("Your repository is cloned!", {type:'confirm', duration:3000});
$("input#repo").val("Enter the url of your repository...");
$("input#name").val("Enter the project name...");
$('#fileTree').fileTree({ root: $("input#workdir").val(), script: $SCRIPT_ROOT + '/readFolder', folderEvent: 'click', expandSpeed: 750, collapseSpeed: 750, multiFolder: false }, function(file) {
......@@ -54,9 +55,9 @@ $(document).ready( function() {
});
}
else{
$("#flash").append("<ul class='flashes'><li>Error: " + data.result + "</li></ul>");
$("#error").Popup(data.result, {type:'error'});
}
$("#imgwaitting").hide()
$("#imgwaitting").hide();
$("#clone").empty();
$("#clone").append("Clone");
send = false;
......
$(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){
$("#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").Popup("Can not load your file, please make sure that you have selected a Software Release", {type:'alert', duration:5000});
}
}
});
}
else{
//Can not displays binary file
$("#error").Popup(data.result, {type:'alert', duration:5000});
}
}
else{
$("#error").Popup(data.result, {type:'alert', duration:5000});
}
}
});
}
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);
}
});
\ No newline at end of file
$(document).ready( function() {
var editor;
var send = false;
var runnerDir = $("input#runnerdir").val();
var ajaxRun;
fillContent();
$("#softwarelist").change(function(){
$("#info").empty();
$("#info").append("Please select your file or folder into the box...");
fillContent();
});
function selectFile(file){
var relativeFile = file.replace(runnerDir + "/" + $("#softwarelist").val(), "");
$("#info").empty();
$("#info").append("Selection: " + relativeFile);
return;
}
function fillContent(selectedElt){
var folder = $("#softwarelist").val();
var elt = $("option:selected", $("#softwarelist"));
$('#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'));
}
$("#open").click(function(){
var elt = $("option:selected", $("#softwarelist"));
$.ajax({
type: "POST",
url: $SCRIPT_ROOT + '/setCurentProject',
data: "path=" + elt.attr('rel'),
success: function(data){
if(data.code == 1){
location.href = $SCRIPT_ROOT + '/editSoftwareProfile'
}
else{
$("#error").Popup(data.result, {type:'error'});
}
}
});
return false;
});
$("#delete").click(function(){
if(send) return;
send = false;
$.ajax({
type: "POST",
url: $SCRIPT_ROOT + '/removeSoftwareDir',
data: "name=" + $("#softwarelist").val(),
success: function(data){
if(data.code == 1){
var folder = $("#softwarelist").val();
$('#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("");
$("#info").empty();
$("#info").append("Please select your file or folder into the box...");
$("#softwarelist").empty();
for(i=0; i<data.result.length; i++){
$("#softwarelist").append('<option value="' + data.result[i]["md5"] +
'" title="' + data.result[i]["title"] +'" rel="' +
data.result[i]["path"] +'">' + data.result[i]["title"] + '</option>');
}
$("#error").Popup("Operation complete, Selected Software Release has been delete!", {type:'confirm', duration:5000});
}
else{
$("#error").Popup(data.result, {type:'error'});
}
send = false;
}
});
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){
$("#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").Popup("Can not load your file, please make sure that you have selected a Software Release", {type:'alert', duration:5000});
}
}
});
}
else{
//Can not displays binary file
$("#error").Popup(data.result, {type:'alert', duration:5000});
}
}
else{
$("#error").Popup(data.result, {type:'alert', duration:5000});
}
}
});
}
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);
}
});
\ No newline at end of file
......@@ -2,23 +2,20 @@ $(document).ready( function() {
var method = $("input#method").val();
var workdir = $("input#workdir").val();
if (method != "file"){
script = (method == "new") ? "/openFolder" : "/readFolder";
script = "/openFolder";
$('#fileTree').fileTree({ root: workdir, script: $SCRIPT_ROOT + script, folderEvent: 'click', expandSpeed: 750, collapseSpeed: 750, multiFolder: false, selectFolder: true }, function(file) {
selectFile(file);
});
}
$("input#subfolder").val("");
$("#create").click(function(){
$("#flash").fadeOut('normal');
$("#flash").empty();
$("#flash").fadeIn('normal');
repo_url = $("input#software").val();
if($("input#software").val() == "" || !$("input#software").val().match(/^[\w\d._-]+$/)){
$("#flash").append("<ul class='flashes'><li>Error: Invalid Software name</li></ul>");
$("#error").Popup("Invalid Software name", {type:'alert', duration:3000})
return false;
}
if($("input#subfolder").val() == ""){
$("#flash").append("<ul class='flashes'><li>Error: Select the parent folder of your software!</li></ul>");
$("#error").Popup("Select the parent folder of your software!", {type:'alert', duration:3000})
return false;
}
$.ajax({
......@@ -30,7 +27,8 @@ $(document).ready( function() {
location.href = $SCRIPT_ROOT + '/editSoftwareProfile'
}
else{
$("#flash").append("<ul class='flashes'><li>Error: " + data.result + "</li></ul>");
$("#error").Popup(data.result, {type:'error', duration:5000})
}
}
});
......@@ -42,7 +40,7 @@ $(document).ready( function() {
$("#flash").empty();
$("#flash").fadeIn('normal');
if($("input#path").val() == ""){
$("#flash").append("<ul class='flashes'><li>Error: Select the folder of your software</li></ul>");
$("#error").Popup("Select a valid Software Release folder!", {type:'alert', duration:3000})
return false;
}
$.ajax({
......@@ -54,7 +52,7 @@ $(document).ready( function() {
location.href = $SCRIPT_ROOT + '/editSoftwareProfile'
}
else{
$("#flash").append("<ul class='flashes'><li>Error: " + data.result + "</li></ul>");
$("#error").Popup(data.result, {type:'error', duration:5000})
}
}
});
......@@ -62,14 +60,22 @@ $(document).ready( function() {
});
function selectFile(file){
relativeFile = file.replace(workdir, "");
var relativeFile = file.replace(workdir, "");
$("#info").empty();
$("#info").append("Selection: " + relativeFile);
$("input#subfolder").val(file);
path = "";
if(method == "open"){
$("#info").append("Selection: " + relativeFile);
checkFolder(file);
}
else{
if($("input#software").val() != "" && $("input#software").val().match(/^[\w\d._-]+$/)){
$("#info").append("New Software in: " + relativeFile + $("input#software").val());
}
else{
$("#info").append("Selection: " + relativeFile);
}
}
return;
}
......
$(document).ready( function() {
var send = false;
var getStatus;
gitStatus();
$("#project").change(function(){
if (send){
......@@ -9,26 +10,118 @@ $(document).ready( function() {
gitStatus();
});
$("#activebranch").change(function(){
var branch = $("#activebranch").val();
var project = $("#project").val();
$.ajax({
type: "POST",
url: $SCRIPT_ROOT + '/changeBranch',
data: "project=" + $("input#workdir").val() + "/" + project + "&name=" + branch,
success: function(data){
if(data.code == 1){
gitStatus();
}
else{
$("#error").Popup(data.result, {type:'error', duration:5000});
}
}
});
});
$("#addbranch").click(function(){
if($("input#branchname").val() == "" ||
$("input#branchname").val() == "Enter the branch name..."){
error("Error: Please Enter your branch name");
$("#error").Popup("Please Enter your branch name", {type:'alert', duration:3000});
return false;
}
alert($("input#branchname").val());
var project = $("#project").val();
var branch = $("input#branchname").val();
$.ajax({
type: "POST",
url: $SCRIPT_ROOT + '/newBranch',
data: "project=" + $("input#workdir").val() + "/" + project + "&name=" + branch,
success: function(data){
if(data.code == 1){
$("input#branchname").val("");
gitStatus();
}
else{
$("#error").Popup(data.result, {type:'error'});
}
}
});
return false;
});
$("#commit").click(function(){
if($("input#commitmsg").val() == "" ||
$("input#commitmsg").val() == "Enter message..."){
error("Error: Please Enter the commit message");
$("#error").Popup("Please Enter the commit message", {type:'alert', duration:3000});
return false;
}
alert($("input#commitmsg").val());
if (send){
return false;
}
send = true;
var project = $("#project").val();
$("#imgwaitting").fadeIn('normal');
$("#commit").empty();
$("#commit").attr("value", "Wait...");
$.ajax({
type: "POST",
url: $SCRIPT_ROOT + '/pushProjectFiles',
data: {project: $("input#workdir").val() + "/" + project, msg: $("input#commitmsg").val()},
success: function(data){
if(data.code == 1){
if (data.result != ""){
$("#error").Popup(data.result, {type:'error', duration:5000});
}
else
$("#error").Popup("Commit done!", {type:'confirm', duration:3000});
gitStatus();
}
else{
$("#error").Popup(data.result, {type:'error', duration:5000});
}
$("#imgwaitting").hide()
$("#commit").empty();
$("#commit").attr("value", "Commit");
send = false;
}
});
return false;
});
/*
$("#pullbranch").click(function(){
if (send){
return false;
}
send = true;
var project = $("#project").val();
$("#pullimgwaitting").fadeIn('normal');
$("#pullbranch").empty();
$("#pullbranch").attr("value", "Wait...");
$.ajax({
type: "POST",
url: $SCRIPT_ROOT + '/pullProjectFiles',
data: "project=" + $("input#workdir").val() + "/" + project,
success: function(data){
if(data.code == 1){
if (data.result != ""){
error(data.result);
}
else
error("Pull done!");
gitStatus();
}
else{
error(data.result);
}
$("#pullimgwaitting").hide()
$("#pullbranch").empty();
$("#pullbranch").attr("value", "Git Pull");
send = false;
}
});
return false;
});*/
function gitStatus(){
var project = $("#project").val();
$("#status").empty();
......@@ -40,10 +133,11 @@ $(document).ready( function() {
return;
}
send = true;
var urldata = $("input#workdir").val() + "/" + project;
getStatus = $.ajax({
type: "POST",
url: $SCRIPT_ROOT + '/getProjectStatus',
data: "project=" + $("input#workdir").val() + "/" + project,
data: "project=" + urldata,
success: function(data){
if(data.code == 1){
$("#branchlist").show();
......@@ -51,14 +145,19 @@ $(document).ready( function() {
message = data.result.split('\n').join('<br/>');
//alert(message);
$("#status").append("<p>" + message + "</p>");
loadBranch(data.branch);
if(data.dirty){
$("#push").show();
$("#status").append("<br/><h2>Display Diff for current Project</h2>");
$("#status").append("<p style='font-size:15px;'>You have changes in your project." +
" <a href='" + $SCRIPT_ROOT + "/getProjectDiff/"
+ encodeURI(project) + "'>Watch the diff</a></p>");
}
loadBranch(data.branch);
}
else{
$("#flash").append("<ul class='flashes'><li>Error: " + data.result + "</li></ul>");
$("#error").Popup(data.result, {type:'error', duration:5000});
}
send = false;
}
});
}
......@@ -67,14 +166,7 @@ $(document).ready( function() {
for(i=0; i< branch.length; i++){
selected = (branch[i].indexOf('*') == 0)? "selected":"";
$("#activebranch").append("<option value='" + branch[i] +
"'>" + branch[i] + "</option>");
}
"' " + selected + ">" + branch[i] + "</option>");
}
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
......@@ -9,6 +9,7 @@ $(document).ready( function() {
editor.renderer.setHScrollBarAlwaysVisible(false);
var script = "/readFolder";
var softwareDisplay = true;
var Mode = function(name, desc, clazz, extensions) {
this.name = name;
this.desc = desc;
......@@ -24,18 +25,20 @@ $(document).ready( function() {
new Mode("buildout", "Python Buildout config", require("ace/mode/buildout").Mode, ["cfg"])
];
var projectDir = $("input#project").val();
var workdir = $("input#workdir").val();
var currentProject = workdir + "/" + projectDir.replace(workdir, "").split('/')[1];
var send = false;
var edit = false;
var workdir = $("input#workdir").val();
$('#fileTree').fileTree({ root: projectDir, script: $SCRIPT_ROOT + script, folderEvent: 'click', expandSpeed: 750, collapseSpeed: 750, multiFolder: false, selectFolder: true }, function(file) {
selectFile(file);
});
setDetailBox();
$("#add").click(function(){
var path = $("input#project").val();
var path = (softwareDisplay)? projectDir:currentProject;
if (send) return false;
if($("input#file").val() == "" ||
$("input#file").val() == "Enter name here..."){
error("Error: Please enter your file or folder name");
$("#error").Popup("Please enter your file or folder name", {type:'alert', duration:3000});
return false;
}
if($("input#subfolder").val() != ""){
......@@ -49,18 +52,16 @@ $(document).ready( function() {
data: "file=" + path + "&type=" + $("#type").val(),
success: function(data){
if(data.code == 1){
$('#fileTree').fileTree({ root: projectDir, script: $SCRIPT_ROOT + script, folderEvent: 'click', expandSpeed: 750, collapseSpeed: 750, multiFolder: false, selectFolder: true }, function(file) {
selectFile(file);
});
switchContent();
$("input#file").val("");
$("#flash").fadeOut('normal');
$("#flash").empty();
$("#info").empty();
$("#info").append("Please select your file or folder into the box...");
$("#info").append("Select parent directory or nothing for root...");
$("input#subfolder").val("");
}
else{
error(data.result);
$("#error").Popup(data.result, {type:'error', duration:5000});
}
send = false;
}
......@@ -70,21 +71,21 @@ $(document).ready( function() {
$("#save").click(function(){
if(!edit){
error("Please select the file to edit");
$("#error").Popup("Please select the file to edit", {type:'alert', duration:3000});
return false;
}
send = false;
if (send) return false;
send = true;
$.ajax({
type: "POST",
url: $SCRIPT_ROOT + '/saveFileContent',
data: "file=" + $("input#subfolder").val() + "&content=" + editor.getSession().getValue(),
data: {file: $("input#subfolder").val(), content: editor.getSession().getValue()},
success: function(data){
if(data.code == 1){
$("#flash").fadeOut('normal');
$("#flash").empty();
$("#error").Popup("File saved succefuly!", {type:'confirm', duration:3000});
}
else{
error(data.result);
$("#error").Popup(data.result, {type:'error', duration:5000});
}
send = false;
}
......@@ -92,17 +93,87 @@ $(document).ready( function() {
return false;
});
function error(msg){
$("#flash").fadeOut('normal');
$("#flash").empty();
$("#flash").fadeIn('normal');
$("#flash").append("<ul class='flashes'><li>" + msg + "</li></ul>");
$("#details_head").click(function(){
setDetailBox();
});
$("#switch").click(function(){
softwareDisplay = !softwareDisplay;
switchContent();
return false;
});
$("#clearselect").click(function(){
$("#info").empty();
$("#info").append("Select parent directory or nothing for root...");
$("input#subfolder").val("");
$("#edit_info").empty();
$("#edit_info").append("No file selected");
editor.getSession().setValue("");
$("#md5sum").empty();
return false;
});
function getmd5sum(){
var file = $("input#subfolder").val();
if (send) return;
send =true
$.ajax({
type: "POST",
url: $SCRIPT_ROOT + '/getmd5sum',
data: {file: $("input#subfolder").val()},
success: function(data){
if(data.code == 1){
$("#md5sum").empty();
$("#md5sum").append('md5sum : <span>' + data.result + '</span>');
}
else{
$("#error").Popup(data.result, {type:'error', duration:5000});
}
send = false;
}
});
}
function switchContent(){
var root = projectDir;
if(!softwareDisplay){
$("#switch").empty();
$("#switch").append("Switch to Software files");
root = currentProject;
}
else{
$("#switch").empty();
$("#switch").append("Switch to Project files");
}
$('#fileTree').fileTree({ root: root, script: $SCRIPT_ROOT + script, folderEvent: 'click', expandSpeed: 750, collapseSpeed: 750, multiFolder: false, selectFolder: true }, function(file) {
selectFile(file);
});
$("#info").empty();
$("#info").append("Select parent directory or nothing for root...");
$("input#subfolder").val("");
}
function setDetailBox(){
var state = $("#details_box").css("display");
if (state == "none"){
$("#details_box").slideDown("normal");
$("#details_head").removeClass("hide");
$("#details_head").addClass("show");
}
else{
$("#details_box").slideUp("normal");
$("#details_head").removeClass("show");
$("#details_head").addClass("hide");
}
}
function selectFile(file){
relativeFile = file.replace(projectDir, "");
relativeFile = file.replace(workdir, "");
$("#info").empty();
$("#info").append(relativeFile);
$("input#subfolder").val(file);
$("#md5sum").empty();
path = "";
send = false;
edit = false;
......@@ -113,18 +184,21 @@ $(document).ready( function() {
data: "file=" + file,
success: function(data){
if(data.code == 1){
$("#flash").fadeOut('normal');
$("#flash").empty();
md5link = " <a href='#' id='getmd5' title='Show or Update md5sum value'>[md5]</a>"
$("#edit_info").empty();
var name = file.split('/');
$("#edit_info").append("Edit selected file (" +
name[name.length - 1] + ")");
$("#edit_info").append("Current file: " +
relativeFile + md5link);
editor.getSession().setValue(data.result);
setEditMode(name[name.length - 1]);
$("#getmd5").click(function(){
getmd5sum();
return false;
});
edit = true;
}
else{
error(data.result);
$("#error").Popup(data.result, {type:'error', duration:5000});
}
send = false;
}
......@@ -132,7 +206,7 @@ $(document).ready( function() {
}
else{
$("#edit_info").empty();
$("#edit_info").append("Edit your selected file");
$("#edit_info").append("No file selected");
editor.getSession().setValue("");
}
return;
......
......@@ -3,32 +3,32 @@
{% 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 %}
<div id="repository">
<h2>Clone your repository into the workspace</h2>
<label for='name'>Project name: </label>
<h2>Clone your repository into the workspace</h2><br/>
<label for='name'>Project name*: </label>
<input type="text" name="name" id="name" size='20' value="Enter the project name..." />
<label for='repo'>url: &nbsp;&nbsp;&nbsp;</label>
<label for='repo'>&nbsp;url: &nbsp;&nbsp;&nbsp;</label>
<input type="text" name="repo" id="repo" size='25' value="Enter the url of your repository..." /><br/>
<label for='user'>Your name: &nbsp;&nbsp;</label>
<label for='user'>Your name: &nbsp;&nbsp;&nbsp;&nbsp;</label>
<input type="text" name="user" id="user" size='20' value="Enter your name..." />
<label for='email'>Email: </label>
<input type="text" name="email" id="email" size='25' value="Enter your email adress..." />
<input type="hidden" name="workdir" id="workdir" value="{{workDir}}" />
<button class="button" id="clone">clone</button>
<img class="waitting" id="imgwaitting" src="{{ url_for('static', filename='images/waiting.gif') }}" alt="" />
<br/><br/>
<br/><br/><br/>
</div>
<h2>You can use this public key for Git SSH</h2>
<textarea class="public_key" readonly>
{{public_key}}
</textarea>
<p>to use git with https, please enter your repository url like this
<strong><i>https://your_login:your_passeword@your_repository_url</i></strong></p><br/>
<strong><i>https://your_login:your_password@your_repository</i></strong></p><br/><br/>
<div id="file_navigation">
<h2>Your project folder</h2>
<div id="fileTree" class="file_tree"></div>
......
......@@ -12,20 +12,21 @@
<div class="clear"></div>
</div>
<div class="smenu">
<h2><a href="{{ url_for('openProject', method='open')}}">Open Existing Project</a></h2>
<p>Once you have cloned your repository, you can open project here.</p>
<h2><a href="{{ url_for('openProject', method='open')}}">Open Software Release</a></h2>
<p>Once you have cloned your repository, you can now edit existing Software Release.</p>
<img src="{{ url_for('static', filename='images/mydocuments.png') }}" />
<div class="clear"></div>
</div>
<div class="sright_menu">
<h2><a href="{{ url_for('manageProject')}}">Manage your Project</a></h2>
<p>You can view details of your project and commit content here.</p>
<h2><a href="{{ url_for('manageProject')}}">Manage your Projects</a></h2>
<p>You can view details of all projects and commit your Software Release here.</p>
<img src="{{ url_for('static', filename='images/manage_repo.png') }}" />
</div>
<div class="clear"></div>
<div class="lmenu">
<h2><a href="{{ url_for('openProject', method='new')}}">Start a new software release</a></h2>
<p>Create a new software into your selected project directory. This allows you to create, edit and run a new software on SlapOs, using webrunner tools.
<h2><a href="{{ url_for('openProject', method='new')}}">Create your new Software Release</a></h2>
<p>To create a new Software Release, choose the project directory in which you want to create your software. You will then be able to edit and
run the new software on SlapOs, using webrunner tools.
</p>
<img src="{{ url_for('static', filename='images/folder_blue.png') }}" />
<div class="clear"></div>
......
......@@ -3,43 +3,63 @@
{% 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>
{%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) {
alert(file);
});
});
</script>
{%endif%}
<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='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/>
<h2>Supervisor:</h2>
{% if supervisor != [] %}
<table cellpadding="0" cellspacing="0" width="100%">
<div id="tabContaier">
<ul>
<li><a class="active" href="#tab1">Slapgrid Supervisor</a></li>
<li><a href="#tab2">SLAP response</a></li>
<li><a href="#tab3">Partitions Content</a></li>
</ul><!-- //Tab buttons -->
<div class="tabDetails">
<div id="tab1" class="tabContents">
<p>This tab show all process generated by slapgrid for your application. You can click on the process name to display logs.</p>
{% if supervisor != []%}
<table cellpadding="0" cellspacing="0" width="100%">
<tr>
<th>Partition and Process name</th><th>Status</th><th>Process PID </th><th> UpTime</th><th></th>
</tr>
{% for item in supervisor %}
{% for item in supervisor %}
<tr>
<td><b><a href="{{ url_for('tailProcess', process=item[0]) }}">{{ item[0]}}</a></b></td>
<td align="center"><a href="{{ url_for('startStopProccess', process=item[0], action=item[1]) }}">{{ item[1]}}</a></td>
<td align="center">{{ item[3]}}</td><td>{{ item[5]}}</td>
<td align="center"><a href="{{ url_for('startStopProccess', process=item[0], action='RESTART') }}">Restart</a></td>
</tr>
{% endfor %}
</table>
{% else %}
<h3>Please run the software instance before displaying process</h3>
{%endif%}
<br/>
<h2>SLAP:</h2>
{% for item in slap_status %}
<b>{{ item[0 ]}}</b><br>
<textarea cols=103 rows=5 readonly>{{ item[1] }}</textarea><br>
{% endfor %}
<h2>File content:</h2>
<div id="fileTree" class="file_tree"></div>
{% endfor %}
</table>
{% else %}
<h2>Please run the software instance before displaying process</h2>
{%endif%}
</div><!-- end tab1 -->
<div id="tab2" class="tabContents">
<p>Uses parameters below to run your application</p>
{% for item in slap_status %}
<h2>{{ item[0 ]}}</h2>
<textarea rows=5 readonly>{{ item[1] }}</textarea><br>
{% endfor %}
</div><!-- end tab2 -->
<div id="tab3" class="tabContents">
<div id="fileTree" class="file_tree_tabs"></div>
</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 %}
......@@ -13,28 +13,8 @@
<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>
{% if request.path == '/editSoftwareProfile' or request.path == '/editInstanceProfile' %}
<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 type="text/javascript">
$(document).ready(function() {
var editor = ace.edit("editor");
editor.setTheme("ace/theme/crimson_editor");
var CurentMode = require("ace/mode/buildout").Mode;
editor.getSession().setMode(new CurentMode());
editor.getSession().setTabSize(2);
editor.getSession().setUseSoftTabs(true);
editor.renderer.setHScrollBarAlwaysVisible(false);
$('#save').click(function(){
$('#editor_content').val(editor.getSession().getValue());
});
});
</script>
{% endif %}
<script src="{{ url_for('static', filename='js/jquery/jquery-1.6.2.min.js') }}" type="text/javascript" charset="utf-8"></script>
<script src="{{ url_for('static', filename='js/jquery/popup.js') }}" type="text/javascript" charset="utf-8"></script>
<script type=text/javascript>
$SCRIPT_ROOT = {{ request.script_root|tojson|safe }};
</script>
......@@ -56,12 +36,17 @@
this.value = (this.defaultValue ? this.defaultValue : '');
}
});
if($("input#fmsg").val() != ""){
$("#error").Popup($("input#fmsg").val(), {type:'info', duration:10000, load:true});
}
});
</script>
{% endblock %}
</head>
<body>
<div id="error"></div>
<div id="page">
<input type="hidden" name="fmsg" value="{{ get_flashed_messages()[0] }}" id="fmsg" />
<div id="logo">
<a href="{{ url_for('home') }}"><img src="{{ url_for('static', filename='images/logo.png') }}" alt="" /></a>
</div>
......@@ -69,7 +54,7 @@
<div class="block_header">
<a href="{{ url_for('home') }}" style="float:left;" title="Home"><img alt="" src="{{ url_for('static', filename='images/home.png') }}" /></a>
<div class="line"></div>
<a href="{{ url_for('curentSoftware') }}" style="float:left" title="Current Software Folder"><img alt="" src="{{ url_for('static', filename='images/project.png') }}" /></a>
<a href="{{ url_for('curentSoftware') }}" style="float:left" title="Edit current software release"><img alt="" src="{{ url_for('static', filename='images/project.png') }}" /></a>
<div class="line"></div>
<h2 class="info">{% block title %}{% endblock %} - {{session.title}}</h2>
</div>
......@@ -94,17 +79,6 @@
<div class="clear"></div>
</div>
<div id="main">
<div class="flash" id="flash">
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul class="flashes">
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
</div>
<div {% if request.path == '/' %} class="home_content" {%else%} id="content" {% endif %}>
{% if request.path != '/' %}
<div class="main_head">
......@@ -120,7 +94,7 @@
</div>
</div>
<div id="footer">
SlapOs webrunner &copy; Vifib SARL 2011 - All right reserved - Creative Commons Shared Alike Non Commercial
SlapOs web runner &copy; Vifib SARL 2011 - All right reserved - Creative Commons Shared Alike Non Commercial
</div>
</div>
</body>
......
<!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>
{% extends "layout.html" %}
{% block title %}Manage your Project folder{% endblock %}
{% 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 %}
......@@ -21,28 +21,31 @@
</select>
<br/><br/>
<div id="contentInfo">
<div id="status">
<div id="status" style="margin-bottom:20px;">
<h2>Please select one project...</h2>
</div>
<div id="branchlist">
<div class="div"></div>
<h2>Your Repository Branch</h2>
<div id="branchlist" style="margin-bottom:20px;">
<h2>Your Repository Branches</h2>
<div style="margin-left:15px;">
<label for='activebranch'>Select the active Branch here: </label>
<label for='activebranch'>Select your active Branch: </label>
<select name="activebranch" id="activebranch">
</select>
&nbsp;&nbsp;&nbsp;<label for='branchname'>Branch Name: </label>
<input type="text" name="branchname" id="branchname" size='20' value="Enter the branch name..." />
&nbsp;&nbsp;<label for='branchname'>Branch Name: </label>
<input type="text" name="branchname" id="branchname" size='22' value="Enter the branch name..." />
<input type="submit" name="addbranch" id ="addbranch" value="Add" class="button"/>
<br/>
<!--<label for='pullbranch'>Update your local repository: </label>-->
<!--<input type="submit" name="pullbranch" id ="pullbranch" value="Pull" class="button"/>-->
<!--<img class="waitting" id="pullimgwaitting" src="{{ url_for('static', filename='images/waiting.gif') }}" alt="" />-->
</div>
</div>
<div id="push">
<div class="div"></div>
<h2>Commit All your changes</h2>
<div id="push" style="margin-bottom:20px;">
<h2>Commit All your changes (On active branch)</h2>
<div style="margin-left:15px;">
<label for='commitmsg'>Enter your commit message here: </label>
<label for='commitmsg'>Commit message: </label>
<input type="text" name="commitmsg" id="commitmsg" size='40' value="Enter message..." />
<input type="submit" name="commit" id ="commit" value="Commit" class="button"/>
<img class="waitting" id="imgwaitting" src="{{ url_for('static', filename='images/waiting.gif') }}" alt="" />
</div>
</div>
<br/>
......
{% extends "layout.html" %}
{% block title %}Log for {{ process }}{% endblock %}
{% block body %}
<h2>Displaying log for {{ process }}</h2><br/>
<textarea cols=103 rows=40 readonly>{{ process_log }}</textarea>
......
{% extends "layout.html" %}
{% block title %}Diff for '{{project}}'{% endblock %}
{% block head %}
{{ super() }}
<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");
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);
});
</script>
{% endblock %}
{% block body %}
<form action="{{ url_for('manageProject') }}" method=get>
<dl>
<dd><h2>Diff file for "{{project}}"</h2></dd>
<dd>
<div class="main_content">
<pre id="editor">
{{ diff }}
</pre>
</div>
</dd>
<dd><input type=submit value="Back" class="button"></dd>
</dl>
</form>
{% endblock %}
......@@ -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 %}
......@@ -14,7 +14,7 @@
<input type="hidden" name="method" id="method" value="{{method}}" />
{% if method == "new" %}
<div id="addsoftware">
<h2>What is the name of your software?</h2>
<h2>What is the name of your software release?</h2>
<label for='software'>Name: </label>
<input type="text" name="software" id="software" size='30' value="Enter software name..." />
<br/><br/>
......@@ -28,7 +28,7 @@
</div>
{% elif method == "open" %}
<div id="openSoftware">
<h2>Select the folder of your software into the box</h2>
<h2>Select the folder of your software release into the box</h2>
<div id="fileTree" class="file_tree"></div>
<div id="file_info" class="file_info">
<img src="{{ url_for('static', filename='images/check.png') }}" class="check" id="check" alt=""/>
......
{% extends "layout.html" %}
{% block title %}Webrunner software content{% endblock %}
{% block title %}Webrunner software Inspection{% endblock %}
{% 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>
{%if result != "" %}
<script type="text/javascript" charset="utf-8">
$(document).ready( function() {
$('#fileTree').fileTree({ root: "{{result}}", script: $SCRIPT_ROOT + "/readFolder", folderEvent: 'click', expandSpeed: 750, collapseSpeed: 750, multiFolder: false, selectFolder: false }, function(file) {
alert(file);
});
});
</script>
{%endif%}
<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>Result for {{ type }}</h2>
<div id="fileTree" class="file_tree"></div>
<h2>Inspect software</h2>
<input type="hidden" name="runnerdir" id="runnerdir" value="{{softwareRoot}}" />
<label for='softwarelist'>Select software: </label>
<select name="softwarelist" id="softwarelist">
{%for soft in softwares %}
<option value="{{soft['md5']}}" title="{{soft['title']}}" rel="{{soft['path']}}">{{soft['title']}}</option>
{%endfor%}
</select>
&nbsp;&nbsp;<button id ="delete" class="button" title="Remove this software">Remove</button>
&nbsp;&nbsp;<button id ="open" class="button" title="Set this software as current software release">Open</button>
<br/><br/>
<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" 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 %}
......@@ -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 %}
......@@ -17,22 +17,28 @@
<input type="hidden" name="project" id="project" value="{{project}}" />
<input type="hidden" name="workdir" id="workdir" value="{{workDir}}" />
<input type="hidden" name="subfolder" id="subfolder" value="" />
<div id="file_navigation">
<h2>Current software file content</h2>
<div id="software_folder">
<h2 class="hight show" id="details_head">Current software release file content</h2>
<div class="software_details" id="details_box">
<div id="fileTree" class="file_tree_short"></div>
<div class="box_software">
<h2>Add new file or folder</h2>
<input type="text" name="file" id="file" size='25' value="Enter name here..." />
&nbsp;&nbsp;<select name="type" id="type">
<input type="text" name="file" id="file" size='22' value="Enter name here..." />
&nbsp;&nbsp;&nbsp;<select name="type" id="type">
<option value="file">file</option>
<option value="folder">folder</option>
</select>
&nbsp;&nbsp;<input type="submit" name="add" id ="add" value="Add" class="button"/>
<div id="file_info" class="file_info"><span id="info">Please select your file or folder into the box...</span></div>
&nbsp;&nbsp;&nbsp;<input type="submit" name="add" id ="add" value="Add" class="button"/>
<br/><br/>
<a href="#" id="switch" class="lshare">Switch to Project files</a>
<a href="" id="clearselect" class="lshare">Clear selection</a><br/><br/>
<div id="file_info" class="file_info"><span id="info">Select parent directory or nothing for root...</span></div>
</div>
<div class="clear"></div>
</div>
<div id="code" style="margin-top:10px">
<h2 id="edit_info">Edit your selected file</h2>
<h2 id="edit_info" class='title'>No file selected</h2>
<div class='md5sum' id='md5sum'></div>
<div class="main_content">
<pre id="editor">
......
{% extends "layout.html" %}
{% block title %}Update instance profile{% endblock %}
{% block head %}
{{ super() }}
<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 action="{{ url_for('updateInstanceProfile') }}" method=post class=add-entry>
<form method=post class=add-entry>
<dl>
<dd><h2>Instance Profile:</h2></dd>
<dd> <!--<textarea name=content rows=20 cols=103 id="editor">{{ profile }}</textarea>-->
<dd><h2>Edit instance profile <a href='#' id='getmd5' title='Show or Update md5sum value'>[md5]</a>:</h2></dd>
<dd><div class='md5sum' id='md5sum'></div></dd>
<dd>
<div class="main_content">
<pre id="editor">
{{ profile }}
</pre>
<pre id="editor"></pre>
<input type="hidden" name="profile" id="profile" value="{{ profile|safe }}" />
</div>
<input type="hidden" name=content id="editor_content"/>
</dd>
......
{% extends "layout.html" %}
{% block title %}Update software profile{% endblock %}
{% block head %}
{{ super() }}
<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 action="{{ url_for('updateSoftwareProfile') }}" method=post class=add-entry>
<form method=post class=add-entry>
<dl>
<dt><strong>Note:</strong> Url of instance.cfg is <tt>{{ instance_url }}</tt></dt>
<dd><h2>Software Profile:</h2></dd>
<dd> <!--<textarea name=content rows=20 cols=103 id="editor">{{ profile }}</textarea>-->
<dd><h2>Edit software profile <a href='#' id='getmd5' title='Show or Update md5sum value'>[md5]</a>:</h2></dd>
<dd><div class='md5sum' id='md5sum'></div></dd>
<dd>
<div class="main_content">
<pre id="editor">
{{ profile }}
</pre>
<pre id="editor"></pre>
</div>
<input type="hidden" value="{{ profile }}" name=content id="editor_content"/>
<input type="hidden" name="profile" id="profile" value="{{ profile|safe }}" />
</dd>
<dd><input type=submit value=Update id="save" class="button"></dd>
</dl>
......
{% extends "layout.html" %}
{% block title %}View {{ type }} log{% endblock %}
{% block body %}
Currently running: <span class="message">{{ running }}</span><br>
<strong>Note:</strong> You can refresh this page from time to time to have updates.<br>
<h2>Currently running: <span class="message">{{ running }}</span></h2><br>
<h2>Result for {{ type }}</h2>
<div class="log_content"><textarea class="log" readonly >{{ result }}</textarea></div>
{% endblock %}
......@@ -8,6 +8,7 @@ import urllib
from flask import jsonify
import shutil
import string
import hashlib
class Popen(subprocess.Popen):
......@@ -133,6 +134,25 @@ def runSoftwareWithLock(config):
slapgrid = Popen([config['slapgrid_sr'], '-vc', config['configuration_file_path']], stdout=logfile)
writePid(slapgrid_pid, slapgrid.pid)
slapgrid.wait()
#Saves the current compile software for re-use
#This uses the new software create by slapgrid (if not exits yet)
data = loadSoftwareData(config['runner_workdir'])
md5 = ""
for path in os.listdir(config['software_root']):
exist = False
for val in data:
if val['md5'] == path:
exist = True
conf = os.path.join(config['runner_workdir'], ".project")
if not exist: #save this compile software folder
if os.path.exists(conf):
data.append({"title":getProjectTitle(config), "md5":path,
"path": open(os.path.join(config['runner_workdir'],
".project"), 'r').read()})
writeSoftwareData(config['runner_workdir'], data)
else:
shutil.rmtree(os.path.join(config['software_root'], path))
break
return True
return False
......@@ -170,7 +190,7 @@ def getProfile(peojectDir, profileName):
if os.path.exists(profile):
return open(profile).read()
else:
return ''
return None
def getProfilePath(peojectDir, profile):
if not os.path.exists(os.path.join(peojectDir, ".project")):
......@@ -204,9 +224,24 @@ def runBuildoutAnnotate(config):
return False
def svcStopAll(config):
#stop all process running in supervisord
request = Popen([config['supervisor'], config['configuration_file_path'],
'stop', 'all'])
request.wait()
return Popen([config['supervisor'], config['configuration_file_path'],
'shutdown']).communicate()[0]
def removeInstanceRoot(config):
if os.path.exists(config['instance_root']):
svcStopAll(config)
for root, dirs, files in os.walk(config['instance_root']):
for fname in dirs:
fullPath = os.path.join(root, fname)
if not os.access(fullPath, os.W_OK) :
# Some directories may be read-only, preventing to remove files in it
os.chmod(fullPath, 0744)
shutil.rmtree(config['instance_root'])
def getSvcStatus(config):
result = Popen([config['supervisor'], config['configuration_file_path'],
'status']).communicate()[0]
......@@ -222,7 +257,7 @@ def getSvcTailProcess(config, process):
"tail", process]).communicate()[0]
def svcStartStopProcess(config, process, action):
cmd = {"RESTART":"restart", "STOPPED":"start", "RUNNING":"stop"}
cmd = {"RESTART":"restart", "STOPPED":"start", "RUNNING":"stop", "EXITED":"start", "STOP":"stop"}
return Popen([config['supervisor'], config['configuration_file_path'],
cmd[action], process]).communicate()[0]
......@@ -231,7 +266,8 @@ def getFolderContent(folder):
try:
r=['<ul class="jqueryFileTree" style="display: none;">']
d=urllib.unquote(folder)
for f in os.listdir(d):
ldir = sorted(os.listdir(d), key=unicode.lower)
for f in ldir:
if f.startswith('.'): #do not displays this file/folder
continue
ff=os.path.join(d,f)
......@@ -251,7 +287,8 @@ def getFolder(folder):
try:
r=['<ul class="jqueryFileTree" style="display: none;">']
d=urllib.unquote(folder)
for f in os.listdir(d):
ldir = sorted(os.listdir(d), key=unicode.lower)
for f in ldir:
if f.startswith('.'): #do not display this file/folder
continue
ff=os.path.join(d,f)
......@@ -265,10 +302,22 @@ def getFolder(folder):
def getProjectList(folder):
project = []
for elt in os.listdir(folder):
project_list = sorted(os.listdir(folder), key=str.lower)
for elt in project_list:
project.append(elt)
return project
def configNewSR(config, project):
if os.path.exists(project):
stopProxy(config)
removeProxyDb(config)
startProxy(config)
removeInstanceRoot(config)
open(os.path.join(config['runner_workdir'], ".project"), 'w').write(project)
return True
else:
return False
def newSoftware(folder, config, session):
json = ""
code = 0
......@@ -304,8 +353,7 @@ def checkSoftwareFolder(path, config):
tmp = path.split('/')
del tmp[len(tmp) - 1]
path = string.join(tmp, '/')
if os.path.exists(os.path.join(path, config['software_profile'])) and \
os.path.exists(os.path.join(path, config['instance_profile'])):
if os.path.exists(os.path.join(path, config['software_profile'])):
return jsonify(result=path)
return jsonify(result="")
......@@ -315,5 +363,96 @@ def getProjectTitle(config):
project = open(conf, "r").read().replace(config['workspace'] + "/", "").split("/")
software = project[len(project) - 1]
del project[len(project) - 1]
return software + "(" + string.join(project, '/') + ")"
return ""
\ No newline at end of file
return software + "(SR in /" + string.join(project, '/') + ")"
return "No Profile"
def loadSoftwareData(runner_dir):
import pickle
file_path = os.path.join(runner_dir, '.softdata')
if not os.path.exists(file_path):
return []
pkl_file = open(file_path, 'rb')
data = pickle.load(pkl_file)
pkl_file.close()
return data
def writeSoftwareData(runner_dir, data):
import pickle
file_path = os.path.join(runner_dir, '.softdata')
pkl_file = open(file_path, 'wb')
# Pickle dictionary using protocol 0.
pickle.dump(data, pkl_file)
pkl_file.close()
def removeSoftwareByName(config, folderName):
if isSoftwareRunning(config) or isInstanceRunning(config):
return jsonify(code=0, result="Software installation or instantiation in progress, cannot remove")
path = os.path.join(config['software_root'], folderName)
if not os.path.exists(path):
return jsonify(code=0, result="Can not remove software: No such file or directory")
svcStopAll(config)
shutil.rmtree(path)
#update compiled software list
data = loadSoftwareData(config['runner_workdir'])
i = 0
for p in data:
if p['md5'] == folderName:
del data[i]
writeSoftwareData(config['runner_workdir'], data)
break
i = i+1
return jsonify(code=1, result=data)
def tail(f, lines=20):
"""
Returns the last `lines` lines of file `f`. It is an implementation of tail -f n.
"""
BUFSIZ = 1024
f.seek(0, 2)
bytes = f.tell()
size = lines + 1
block = -1
data = []
while size > 0 and bytes > 0:
if bytes - BUFSIZ > 0:
# Seek back one whole BUFSIZ
f.seek(block * BUFSIZ, 2)
# read BUFFER
data.insert(0, f.read(BUFSIZ))
else:
# file too small, start from begining
f.seek(0,0)
# only read what was not read
data.insert(0, f.read(bytes))
linesFound = data[0].count('\n')
size -= linesFound
bytes -= BUFSIZ
block -= 1
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
def md5sum(file):
"""Compute md5sum of `file` and return hexdigest value"""
if os.path.isdir(file):
return False
try:
fh = open(file, 'rb')
m = hashlib.md5()
while True:
data = fh.read(8192)
if not data:
break
m.update(data)
return m.hexdigest()
except:
return False
\ No newline at end of file
......@@ -3,17 +3,21 @@ from flask import Flask, request, redirect, url_for, \
from utils import *
import os
import shutil
from gittools import cloneRepo, gitStatus
import md5
from gittools import cloneRepo, gitStatus, switchBranch, createBranch, getDiff, \
gitPush, gitPull
app = Flask(__name__)
@app.before_request
def before_request():
session['title'] = getProjectTitle(app.config)
# general views
@app.route('/')
def home():
if not os.path.exists(app.config['workspace']) or len(os.listdir(app.config['workspace'])) == 0:
session['title'] = "No project"
return redirect(url_for('configRepo'))
session['title'] = getProjectTitle(app.config)
return render_template('index.html')
@app.route('/configRepo')
......@@ -24,12 +28,11 @@ def configRepo():
# software views
@app.route('/editSoftwareProfile')
def editSoftwareProfile():
profile = getProfile(app.config['runner_workdir'], app.config['software_profile'])
profile = getProfilePath(app.config['runner_workdir'], app.config['software_profile'])
if profile == "":
flash('Error: can not open profile, please select your project first')
return render_template('updateSoftwareProfile.html',
profile=profile,
instance_url=url_for('getInstance', _external=True))
profile=profile)
@app.route('/software.cfg', methods=['GET', 'POST'])
def getSoftware():
......@@ -40,18 +43,19 @@ def inspectSoftware():
if not os.path.exists(app.config['software_root']):
result = ""
else:
#process = Popen(['find'], cwd=app.config['software_root'])
result = app.config['software_root']
return render_template('runResult.html', type='Software',
result=result)
return render_template('runResult.html', softwareRoot=app.config['software_root'],
softwares=loadSoftwareData(app.config['runner_workdir']))
@app.route('/removeSoftware')
def removeSoftware():
file_config = os.path.join(app.config['runner_workdir'], ".softdata")
if isSoftwareRunning(app.config) or isInstanceRunning(app.config):
flash('Software installation or instantiation in progress, cannot remove')
elif os.path.exists(app.config['software_root']):
elif os.path.exists(file_config):
svcStopAll(app.config)
shutil.rmtree(app.config['software_root'])
os.remove(os.path.join(app.config['runner_workdir'], ".softdata"))
flash('Software removed')
return redirect(url_for('inspectSoftware'))
......@@ -66,25 +70,18 @@ def runSoftwareProfile():
@app.route('/viewSoftwareLog', methods=['GET'])
def viewSoftwareLog():
if os.path.exists(app.config['software_log']):
result = open(app.config['software_log'], 'r').read()
result = tail(open(app.config['software_log'], 'r'), lines=1500)
else:
result = 'Not found yet'
return render_template('viewLog.html', type='Software',
result=result, running=isSoftwareRunning(app.config))
@app.route('/updateSoftwareProfile', methods=['POST'])
def updateSoftwareProfile():
profile = getProfilePath(app.config['runner_workdir'], app.config['software_profile'])
if profile != "":
open(profile, 'w').write(request.form['content'])
return redirect(url_for('editSoftwareProfile'))
# instance views
@app.route('/editInstanceProfile')
def editInstanceProfile():
profile = getProfile(app.config['runner_workdir'], app.config['instance_profile'])
profile = getProfilePath(app.config['runner_workdir'], app.config['instance_profile'])
if profile == "":
flash('Error: can not open profile, please select your project first')
flash('Error: can not open instance profile for this Software Release')
return render_template('updateInstanceProfile.html',
profile=profile)
......@@ -99,23 +96,18 @@ def inspectInstance():
if os.path.exists(app.config['instance_root']):
file_content = app.config['instance_root']
result = getSvcStatus(app.config)
if len(result) == 0:
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():
if isInstanceRunning(app.config):
flash('Instantiation in progress, cannot remove')
elif os.path.exists(app.config['instance_root']):
svcStopAll(app.config)
for root, dirs, files in os.walk(app.config['instance_root']):
for fname in dirs:
fullPath = os.path.join(root, fname)
if not os.access(fullPath, os.W_OK) :
# Some directories may be read-only, preventing to remove files in it
os.chmod(fullPath, 0744)
shutil.rmtree(app.config['instance_root'])
else:
removeInstanceRoot(app.config)
flash('Instance removed')
return redirect(url_for('inspectInstance'))
......@@ -138,13 +130,6 @@ def viewInstanceLog():
return render_template('viewLog.html', type='Instance',
result=result, running=isInstanceRunning(app.config))
@app.route('/updateInstanceProfile', methods=['POST'])
def updateInstanceProfile():
profile = getProfilePath(app.config['runner_workdir'], app.config['instance_profile'])
if profile != "":
open(profile, 'w').write(request.form['content'])
return redirect(url_for('editInstanceProfile'))
@app.route('/stopAllPartition', methods=['GET'])
def stopAllPartition():
svcStopAll(app.config)
......@@ -209,12 +194,11 @@ def checkFolder():
@app.route("/setCurentProject", methods=['POST'])
def setCurentProject():
folder = request.form['path']
if os.path.exists(folder):
open(os.path.join(app.config['runner_workdir'], ".project"), 'w').write(folder)
if configNewSR(app.config, folder):
session['title'] = getProjectTitle(app.config)
return jsonify(code=1, result="")
else:
return jsonify(code=0, result=("Can not open '" + folder + "'"))
return jsonify(code=0, result=("Can not setup this Software Release"))
@app.route("/manageProject", methods=['GET'])
def manageProject():
......@@ -244,10 +228,29 @@ def createFile():
except Exception, e:
return jsonify(code=0, result=str(e))
@app.route("/removeFile", methods=['POST'])
def removeFile():
try:
if request.form['type'] == "folder":
shutil.rmtree(request.form['path'])
else:
os.remove(request.form['path'])
return jsonify(code=1, result="")
except Exception, e:
return jsonify(code=0, result=str(e))
@app.route("/removeSoftwareDir", methods=['POST'])
def removeSoftwareDir():
return removeSoftwareByName(app.config, request.form['name'])
@app.route("/getFileContent", methods=['POST'])
def getFileContent():
if os.path.exists(request.form['file']):
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!")
......@@ -258,3 +261,41 @@ def saveFileContent():
return jsonify(code=1, result="")
else:
return jsonify(code=0, result="Error: No such file!")
@app.route("/changeBranch", methods=['POST'])
def changeBranch():
return switchBranch(request.form['project'], request.form['name'])
@app.route("/newBranch", methods=['POST'])
def newBranch():
return createBranch(request.form['project'], request.form['name'])
@app.route("/getProjectDiff/<project>", methods=['GET'])
def getProjectDiff(project):
path = os.path.join(app.config['workspace'], project)
return render_template('projectDiff.html', project=project,
diff=getDiff(path))
@app.route("/pushProjectFiles", methods=['POST'])
def pushProjectFiles():
return gitPush(request.form['project'], request.form['msg'])
@app.route("/pullProjectFiles", methods=['POST'])
def pullProjectFiles():
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!")
@app.route("/getmd5sum", methods=['POST'])
def getmd5sum():
md5 = md5sum(request.form['file'])
if md5:
return jsonify(code=1, result=md5)
else:
return jsonify(code=0, result="Can not get md5sum for this file!")
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment