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

Merge branch 'slaprunner'

Conflicts:
	CHANGES.txt
parents f209a4f8 a17c7c92
...@@ -5,6 +5,7 @@ import logging.handlers ...@@ -5,6 +5,7 @@ import logging.handlers
import os import os
import sys import sys
import subprocess import subprocess
import hashlib
class Parser(OptionParser): class Parser(OptionParser):
""" """
...@@ -121,5 +122,11 @@ def serve(config): ...@@ -121,5 +122,11 @@ def serve(config):
) )
if not os.path.exists(workdir): if not os.path.exists(workdir):
os.mkdir(workdir) os.mkdir(workdir)
if not os.path.exists(os.path.join(config.runner_workdir, '.users')):
#set default user and password
salt = "runner81" #to be changed
pwd = hashlib.md5( salt + "insecure" ).hexdigest()
user = "root;"+pwd+";;Slaprunner Administrator"
open(os.path.join(config.runner_workdir, '.users'), 'w').write(user)
app.run(host=config.runner_host, port=int(config.runner_port), app.run(host=config.runner_host, port=int(config.runner_port),
debug=config.debug, threaded=True) debug=config.debug, threaded=True)
# -*- coding: utf-8 -*-
import slapos.slap import slapos.slap
import time import time
import subprocess import subprocess
...@@ -21,6 +23,15 @@ class Popen(subprocess.Popen): ...@@ -21,6 +23,15 @@ class Popen(subprocess.Popen):
self.stdin = None self.stdin = None
def cloneRepo(data): def cloneRepo(data):
"""Clonne a repository
Args:
data: a dictionnary of parameters to use:
data['path'] is the path of the new project
data['repo'] is the url of the repository to be cloned
data['email'] is the user email
data['user'] is the name of the user
Returns:
a jsonify data"""
workDir = data['path'] workDir = data['path']
if not workDir: if not workDir:
return jsonify(code=0, return jsonify(code=0,
...@@ -34,7 +45,7 @@ def cloneRepo(data): ...@@ -34,7 +45,7 @@ def cloneRepo(data):
config_writer = repo.config_writer() config_writer = repo.config_writer()
config_writer.add_section("user") config_writer.add_section("user")
if data["user"] != "": if data["user"] != "":
config_writer.set_value("user", "name", data["user"]) config_writer.set_value("user", "name", data["user"].encode("utf-8"))
if data["email"] != "": if data["email"] != "":
config_writer.set_value("user", "email", data["email"]) config_writer.set_value("user", "email", data["email"])
code = 1 code = 1
...@@ -45,6 +56,11 @@ def cloneRepo(data): ...@@ -45,6 +56,11 @@ def cloneRepo(data):
return jsonify(code=code, result=json) return jsonify(code=code, result=json)
def gitStatus(project): def gitStatus(project):
"""Run git status and return status of specified project folder
Args:
project: path of the projet ti get status
Returns:
a parsed string that contains the result of git status"""
code = 0 code = 0
json = "" json = ""
try: try:
...@@ -59,6 +75,12 @@ def gitStatus(project): ...@@ -59,6 +75,12 @@ def gitStatus(project):
return jsonify(code=code, result=json, branch=branch, dirty=isdirty) return jsonify(code=code, result=json, branch=branch, dirty=isdirty)
def switchBranch(project, name): def switchBranch(project, name):
"""Switch a git branch
Args:
project: directory of the local git repository
name: switch from current branch to `name` branch
Returns:
a jsonify data"""
code = 0 code = 0
json = "" json = ""
try: try:
...@@ -76,6 +98,13 @@ def switchBranch(project, name): ...@@ -76,6 +98,13 @@ def switchBranch(project, name):
return jsonify(code=code, result=json) return jsonify(code=code, result=json)
def addBranch(project, name, onlyCheckout=False): def addBranch(project, name, onlyCheckout=False):
"""Add new git branch to the repository
Args:
project: directory of the local git repository
name: name of the new branch
onlyCheckout: if True then the branch `name` is created before checkout
Returns:
a jsonify data"""
code = 0 code = 0
json = "" json = ""
try: try:
...@@ -91,6 +120,7 @@ def addBranch(project, name, onlyCheckout=False): ...@@ -91,6 +120,7 @@ def addBranch(project, name, onlyCheckout=False):
return jsonify(code=code, result=json) return jsonify(code=code, result=json)
def getDiff(project): def getDiff(project):
"""Get git diff for the specified project directory"""
result = "" result = ""
try: try:
repo = Repo(project) repo = Repo(project)
...@@ -102,6 +132,10 @@ def getDiff(project): ...@@ -102,6 +132,10 @@ def getDiff(project):
return result return result
def gitPush(project, msg): def gitPush(project, msg):
"""Commit and Push changes for the specified repository
Args:
project: directory of the local repository
msg: commit message"""
code = 0 code = 0
json = "" json = ""
undo_commit = False undo_commit = False
...@@ -143,5 +177,6 @@ def gitPull(project): ...@@ -143,5 +177,6 @@ def gitPull(project):
return jsonify(code=code, result=result) return jsonify(code=code, result=result)
def safeResult(result): def safeResult(result):
"""Parse string and remove credential of the user"""
regex=re.compile("(https:\/\/)([\w\d\._-]+:[\w\d\._-]+)\@([\S]+\s)", re.VERBOSE) regex=re.compile("(https:\/\/)([\w\d\._-]+:[\w\d\._-]+)\@([\S]+\s)", re.VERBOSE)
return regex.sub(r'\1\3', result) return regex.sub(r'\1\3', result)
\ No newline at end of file
...@@ -10,6 +10,9 @@ ...@@ -10,6 +10,9 @@
#tabContaier textarea { #tabContaier textarea {
width:702px; width:702px;
} }
#tabContaier textarea.slap{white-space: pre-wrap;word-wrap: break-word;overflow: hidden;color: #6F6F6F;width:430px; max-height:120px;
resize: none; height:18px;padding:3px;min-height:18px;font-size: 13px;}
#tabContaier textarea.mb_style{width:560px;}
#tabContaier > ul{ #tabContaier > ul{
overflow:hidden; overflow:hidden;
height:34px; height:34px;
...@@ -39,9 +42,9 @@ ...@@ -39,9 +42,9 @@
} }
#tabContaier > ul > li a.active{ #tabContaier > ul > li a.active{
background:#fbfbfb; background:#fbfbfb;
border:1px solid #fff; border:1px solid #fff;
border-top:0; border-top:0;
border-right:0; border-right:0;
color:#333; color:#333;
} }
#tabContaier > ul > li:first-child a{border-left:0} #tabContaier > ul > li:first-child a{border-left:0}
...@@ -55,4 +58,4 @@ ...@@ -55,4 +58,4 @@
} }
.tabContents p{ .tabContents p{
padding:0 0 10px; padding:0 0 10px;
} }
...@@ -4,7 +4,6 @@ blockquote, q {quotes: none;} ...@@ -4,7 +4,6 @@ blockquote, q {quotes: none;}
blockquote:before, blockquote:after, q:before, q:after {content: none;} blockquote:before, blockquote:after, q:before, q:after {content: none;}
:focus {outline: 0 none;} :focus {outline: 0 none;}
img{border:0} img{border:0}
a{ a{
text-decoration: none; text-decoration: none;
color: #19485C; color: #19485C;
...@@ -15,11 +14,12 @@ a:hover { ...@@ -15,11 +14,12 @@ a:hover {
} }
table { table {
margin: 0; margin: 0;padding:0;
border-right: none; border-right: none;
border-bottom: none; border-bottom: none;
font-size: 14px; font-size: 14px;
background: #fff; background: #fff;
border-spacing:0;
} }
td{ td{
padding: 4px; padding: 4px;
...@@ -36,16 +36,19 @@ th{ ...@@ -36,16 +36,19 @@ th{
font-weight: normal; font-weight: normal;
font-size: 18px; font-size: 18px;
} }
table.small th{padding: 4px;font-size: 16px;}
textarea { textarea {
width:762px; width:762px;
font-family: 'Helvetica Neue',Tahoma,Helvetica,Arial,sans-serif;
} }
body { body {
background: url("../images/1307251316-background-stripes.gif") repeat #9C9C9C; background: #2281C1;/*url("../images/1307251316-background-stripes.gif") repeat #9C9C9C;*/
font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; font-family: 'Helvetica Neue',Tahoma,Helvetica,Arial,sans-serif;
color: #000000; color: #000000;
font-size: 13px; font-size: 13px;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
} }
#page #page
...@@ -67,7 +70,7 @@ body { ...@@ -67,7 +70,7 @@ body {
.block_header{ .block_header{
text-align: left; text-align: left;
padding-left: 25px; padding-left: 20px;
height: 30px; height: 30px;
} }
...@@ -81,7 +84,7 @@ body { ...@@ -81,7 +84,7 @@ body {
font-weight: normal; font-weight: normal;
padding-top: 3px; padding-top: 3px;
float: left; float: left;
width: 690px; width: 656px;
height: 22px; height: 22px;
text-align: center; text-align: center;
color: #4c6172; color: #4c6172;
...@@ -257,11 +260,8 @@ body { ...@@ -257,11 +260,8 @@ body {
box-shadow: 1px 1px 1px #888888; box-shadow: 1px 1px 1px #888888;
} }
.button:active { .button:active {
background-position: 0 top; background: #eee;
position: relative; color: #000;
top: 1px;
padding: 6px 10px 4px;
box-shadow: 1px 1px 1px #888888;
} }
.focusField{ .focusField{
...@@ -314,7 +314,7 @@ input[type="radio"], input[type="checkbox"]{ ...@@ -314,7 +314,7 @@ input[type="radio"], input[type="checkbox"]{
#home_box{ #home_box{
background: none; background: none;
border: 1px solid #678dad; border: 2px solid #87B0D4;
padding: 0; padding: 0;
color: #4c6172; color: #4c6172;
margin: 15px 59px 15px 59px; margin: 15px 59px 15px 59px;
...@@ -333,7 +333,7 @@ input[type="radio"], input[type="checkbox"]{ ...@@ -333,7 +333,7 @@ input[type="radio"], input[type="checkbox"]{
#home_box h2{ #home_box h2{
font-weight: normal; font-weight: normal;
font-size: 23px; font-size: 23px;
color: #4c6172; color: #475F73;
} }
#home_box p{ #home_box p{
...@@ -351,7 +351,6 @@ input[type="radio"], input[type="checkbox"]{ ...@@ -351,7 +351,6 @@ input[type="radio"], input[type="checkbox"]{
.inner_box{ .inner_box{
background: none; background: none;
margin: 0; margin: 0;
border: 1px solid #CAD4DC;
display: block; display: block;
padding: 30px 0 30px 0; padding: 30px 0 30px 0;
} }
...@@ -371,23 +370,24 @@ input[type="radio"], input[type="checkbox"]{ ...@@ -371,23 +370,24 @@ input[type="radio"], input[type="checkbox"]{
margin: 10px 45px 10px 45px; margin: 10px 45px 10px 45px;
padding: 10px; padding: 10px;
padding-bottom:15px; padding-bottom:15px;
border: #678dad;
width: 530px; width: 530px;
border: 1px solid #678dad; border: 1px solid #678dad;
} }
.lmenu:hover, .smenu:hover, .sright_menu:hover{ .smaller{margin-left:10px; width: 350px; float:right}
.smaller p{width: 280px;}
.umenu{display: block;margin: 10px 0 10px 45px; width: 147px; float:left;border: 1px solid #678dad;
padding: 10px;height: 80px;padding-bottom:15px;}
.umenu p{font-size: 13px;float: left;width: 77px;cursor:default;}
.lmenu:hover, .smenu:hover, .sright_menu:hover, .smaller:hover, .umenu:hover{
background: #96b9d7; background: #96b9d7;
} }
.smenu{ .smenu{
display: block; display: block;
height: 80px; height: 80px;
margin: 0 10px 0 45px; margin: 0 10px 0 45px;
padding: 10px; padding: 10px;
padding-bottom:15px; padding-bottom:15px;
border: #678dad;
width: 250px; width: 250px;
border: 1px solid #678dad; border: 1px solid #678dad;
float: left; float: left;
...@@ -541,7 +541,6 @@ h2.hight:hover{ ...@@ -541,7 +541,6 @@ h2.hight:hover{
overflow: auto; overflow: auto;
height: 95px; height: 95px;
padding: 5px; padding: 5px;
width: 604px;
background:#fff; background:#fff;
margin-bottom: 10px; margin-bottom: 10px;
color: #3A494F; color: #3A494F;
...@@ -580,9 +579,10 @@ a.lshare{ ...@@ -580,9 +579,10 @@ a.lshare{
height: 18px; height: 18px;
font-size: 15px; font-size: 15px;
border: solid 1px #678dad; border: solid 1px #678dad;
color: #4DA0C6; color: #4DA0C6;
text-align:center; text-align:center;
font-weight:bold; font-weight:bold;
cursor:pointer;
} }
a.lshare:hover{ a.lshare:hover{
background:#D9D9D9; background:#D9D9D9;
...@@ -593,7 +593,9 @@ a.lshare:hover{ ...@@ -593,7 +593,9 @@ a.lshare:hover{
a.lshare:focus{ a.lshare:focus{
border:solid 1px #73A6FF; border:solid 1px #73A6FF;
} }
a.no-right-border{border-right:none}
a.no-right-border:hover{border-right:none}
a.no-right-border:focus{border-right:none}
a.lshare img{ a.lshare img{
margin: 5px; margin: 5px;
} }
...@@ -635,19 +637,28 @@ a.lshare img{ ...@@ -635,19 +637,28 @@ a.lshare img{
width: 36px; width: 36px;
height: 26px; height: 26px;
} }
#error td.close{ #error td.b_close{
width: 30px; width: 30px;
height:22px; height:22px;
} }
#error p{white-space: pre-wrap; word-wrap: break-word; width: 430px; padding-bottom: 5px;}
.noscroll {
overflow: hidden;
}
.form{padding:10px; padding-left:20px;}
.form label{display:block; float:left; width:150px; padding-top:10px;}
.form input[type=text] ,.form input[type=password] {float:left; width:190px;margin:5px;}
.hiddendiv {display: none;white-space: pre-wrap;min-height: 18px;font-size: 13px;
padding:3px;word-wrap: break-word;width:430px; max-height:120px;font-family: 'Helvetica Neue',Tahoma,Helvetica,Arial,sans-serif;}
.list{background: url(../images/menu_dropdown.png) left center no-repeat; padding-left:10px;} .list{background: url(../images/menu_dropdown.png) left center no-repeat; padding-left:10px;}
.slidebox{padding:10px; }
.alert_message{ background: url(../images/alert.png) center no-repeat; height: 26px;} .alert_message{ background: url(../images/alert.png) center no-repeat; height: 26px;}
.error_message{ background: url(../images/exit.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;} .confirm_message{ background: url(../images/confirm.png) center no-repeat; height: 26px;}
.info_message{ background: url(../images/info.png) center no-repeat; height: 26px;} .info_message{ background: url(../images/info.png) center no-repeat; height: 26px;}
#error p{ font-size: 13px; color: #4A131F;} #error p{ font-size: 13px; color: #4A131F;}
#pClose{background:url(../images/close.png) no-repeat 0px 0px; display:block; width:22px; height:22px; cursor:pointer} #pClose, .close{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;} #pClose:hover, .close:hover{background:url(../images/close_hover.png) no-repeat 0px 0px;}
.md5sum {margin:10px; font-size:15px;} .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;} .title{background: #e4e4e4; width: 100%; height: 25px; padding-top:2px; text-indent: 5px; color: #737373; text-shadow: 0px 1px #FFF;}
.menu-box-left{float:left; width: 120px; font-size:14px; background: #e4e4e4; padding:5px 0 5px 5px; margin-top:10px; .menu-box-left{float:left; width: 120px; font-size:14px; background: #e4e4e4; padding:5px 0 5px 5px; margin-top:10px;
...@@ -656,6 +667,7 @@ a.lshare img{ ...@@ -656,6 +667,7 @@ a.lshare img{
margin-top:10px; box-shadow: 1px 1px 1px #888888;} margin-top:10px; box-shadow: 1px 1px 1px #888888;}
.menu-box-left ul{margin:0px; list-style:none;} .menu-box-left ul{margin:0px; list-style:none;}
.menu-box-left li{padding: 2px; padding-left:10px; padding-right:10px; text-shadow: 0px 1px #fff;border-bottom:1px solid #fff;} .menu-box-left li{padding: 2px; padding-left:10px; padding-right:10px; text-shadow: 0px 1px #fff;border-bottom:1px solid #fff;}
.menu-box-left li label, .menu-box-left li input[type=radio] { cursor:pointer}
.menu-box-left li:hover{background:#F0F2F2;} .menu-box-left li:hover{background:#F0F2F2;}
.menu-box-left li.checked{background:#fff;} .menu-box-left li.checked{background:#fff;}
.menu-box-right h2{text-align:center} .menu-box-right h2{text-align:center}
...@@ -679,7 +691,8 @@ a.lshare img{ ...@@ -679,7 +691,8 @@ a.lshare img{
.popup li{border-bottom: 1px dashed #666666; padding:5px; padding-top:5px;} .popup li{border-bottom: 1px dashed #666666; padding:5px; padding-top:5px;}
.popup-value{display:none;} .popup-value{display:none;}
textarea.parameter {border: solid 1px #678dad; color: #666666; height:110px;} textarea.parameter {border: solid 1px #678dad; color: #666666; height:110px;}
.link{color:#fff; font-weight:bold; text-decoration:none}
.link:hover{color: #19485C;}
input[type=radio] { input[type=radio] {
} }
...@@ -689,3 +702,12 @@ input[type=radio]:checked { ...@@ -689,3 +702,12 @@ input[type=radio]:checked {
input[type=radio]:hover { input[type=radio]:hover {
box-shadow: 0px 1px 3px #F0F1F2; box-shadow: 0px 1px 3px #F0F1F2;
} }
/* Login Css region *******/
#login-page{width:429px; height:236px; margin:130px auto 0px; background:url(../images/loginBox.png) no-repeat;
padding:10px; font-size:14px; color:#03406A}
#login-page h2{color:#fff; font-size:26px; font-weight:normal; text-indent:50px;}
.login-content{margin:10px; margin-top:40px; margin-bottom:0; height:90px;}
.login-button{width:140px; margin:0 auto;}
.login-element{float:left; min-width:120px;}
.login-label{padding:5px; font-size:16px;}
.login-input{width:220px;}
\ No newline at end of file
$(document).ready(function(){ $(document).ready(function(){
$(".tabContents").hide(); // Hide all tab content divs by default $(".tabContents").hide(); // Hide all tab content divs by default
var hashes = window.location.href.split('#'); var hashes = window.location.href.split('#');
if (hashes.length == 2){ var fromheight = 0;
var previoustab = null;
if (hashes.length == 2 && hashes[1] != ""){
$("#tabContaier>ul li").each(function() { $("#tabContaier>ul li").each(function() {
var $tab = $(this).find("a"); var $tab = $(this).find("a");
if($tab.hasClass("active")) $tab.removeClass("active"); if($tab.hasClass("active")){
$tab.removeClass("active");
}
if ($tab.attr("href") == "#"+hashes[1]){ if ($tab.attr("href") == "#"+hashes[1]){
$tab.addClass("active"); $tab.addClass("active");
$("#"+hashes[1]).show(); $("#"+hashes[1]).show();
previoustab = "#"+hashes[1];
} }
//alert($(this).attr("href")); //alert($(this).attr("href"));
}); });
} }
else{$(".tabContents:first").show();} // Show the first div of tab content by default else{$(".tabContents:first").show(); previoustab = ".tabContents:first";} // Show the first div of tab content by default
$("#tabContaier ul li a").click(function(){ //Fire the click event $("#tabContaier ul li a").click(function(){ //Fire the click event
if($(this).hasClass('active')){ if($(this).hasClass('active')){
return; return;
} }
fromheight = $(previoustab).height();
var activeTab = $(this).attr("href"); // Catch the click link var activeTab = $(this).attr("href"); // Catch the click link
$("#tabContaier .tabDetails").css("height", $("#tabContaier .tabDetails").height());
$("#tabContaier ul li a").removeClass("active"); // Remove pre-highlighted link $("#tabContaier ul li a").removeClass("active"); // Remove pre-highlighted link
$(this).addClass("active"); // set clicked link to highlight state $(this).addClass("active"); // set clicked link to highlight state
$(".tabContents").hide(); // hide currently visible tab content div $(".tabContents").hide(); // hide currently visible tab content div
$(activeTab).fadeIn(); // show the target tab content div by matching clicked link. $(activeTab).fadeIn(); // show the target tab content div by matching clicked link.
var diff = fromheight - $(activeTab).height();
if (diff > 0){$("#tabContaier .tabDetails").animate({height: '-=' + diff + 'px'}, 850, 'swing', function() {
$("#tabContaier .tabDetails").css("height", "");
});}
else{diff = -1*diff; $("#tabContaier .tabDetails").animate({height: '+=' + diff + 'px'}, 850, 'swing', function() {
$("#tabContaier .tabDetails").css("height", "");
});}
previoustab = activeTab;
$("#tabContaier .tabDetails").css("height", $("#tabContaier .tabDetails").height());
}); });
}); });
\ No newline at end of file
...@@ -3,47 +3,67 @@ ...@@ -3,47 +3,67 @@
// //
(function ($, document, window) { (function ($, document, window) {
var isShow = null;
var showDelayTimer = null;
$.extend($.fn, { $.extend($.fn, {
Popup: function(msg, option) { Popup: function(msg, option) {
var h;
if (option.type == undefined) option.type = "info"; if (option.type == undefined) option.type = "info";
if (option.closebtn == undefined) option.closebtn = false; if (option.closebtn == undefined) option.closebtn = false;
if (option.duration == undefined) option.duration = 0; if (option.duration == undefined) option.duration = 0;
if (option.load == undefined) option.load = false; if (option.load == undefined) option.load = false;
$box = $(this); $box = $(this);
$box.empty(); if(showDelayTimer){clearTimeout(showDelayTimer);}
$box.css('top','-1000px'); if(isShow){
$box.show(); $box.fadeOut('normal', function() {
$box.append('<div><table id="bcontent"><tr>' + setupBox();
'<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{ else{setupBox();}
$box.css('top', + ($(window).scrollTop() - h) +'px'); function setupBox(){
$box.animate({ top:"+=" + h + "px" }, "slow"); $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="b_close"><span id="pClose"></span></td></tr></table></div>');
$(window).scroll(function(){
$box.animate({top:$(window).scrollTop()+"px" },{queue: false, duration: 350});
});
h = $("#bcontent").height()+5;
$("#pClose").bind("click", function() {
close();
});
showBox();
if(option.duration != 0){
showDelayTimer = setTimeout(function(){
showDelayTimer = null;
close();
}, option.duration);
}
} }
if(option.duration != 0){ function showBox(){
setTimeout(function(){ if(option.load){
close(); $(window).load(function(){
}, option.duration); $box.css('top', + ($(window).scrollTop() - h) +'px');
$box.animate({ top:"+=" + h + "px" }, "slow");
isShow = true;
});
}
else{
$box.css('top', + ($(window).scrollTop() - h) +'px');
$box.animate({ top:"+=" + h + "px" }, "slow");
isShow = true;
}
} }
function close(){ function close(){
$box.animate({ top:"-=" + h + "px" }, "slow", function(){ $box.animate({ top:"-=" + h + "px" }, "slow", function(){
$box.fadeOut("normal"); $box.fadeOut("normal", function() {
}); isShow = false;
});
});
} }
} }
}); });
}(jQuery, document, this)); }(jQuery, document, this));
\ No newline at end of file
$(document).ready( function() {
var send = false;
$("#update").click(function(){
var haspwd = false;
if($("input#username").val() === "" || !$("input#username").val().match(/^[\w\d\._-]+$/)){
$("#error").Popup("Invalid user name. Please check it!", {type:'alert', duration:3000});
return false;
}
if($("input#name").val() === ""){
$("#error").Popup("Please enter your name and surname!", {type:'alert', duration:3000});
return false;
}
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;
}
if($("input#password").val() !== ""){
if($("input#password").val() === "" || !$("input#password").val().match(/^[\w\d\._-]+$/)){
$("#error").Popup("Please enter your new password!", {type:'alert', duration:3000});
return false;
}
if($("input#password").val() !== $("input#cpassword").val()){
$("#error").Popup("your password does not match!", {type:'alert', duration:3000});
return false;
}
haspwd = true;
}
if(send) return false;
send = true;
$.ajax({
type: "POST",
url: $SCRIPT_ROOT + '/updateAccount',
data: {name: $("input#name").val(), username:$("input#username").val(), email:$("input#email").val(),
password:((haspwd) ? $("input#password").val():"")},
success: function(data){
if(data.code ==1){
$("#error").Popup("Your account informations has been saved!", {type:'confirm', duration:3000});
}
else{
$("#error").Popup(data.result, {type:'error', duration:5000});
}
send = false;
},
error:function(){send = false;}
});
return false;
});
});
\ No newline at end of file
/*Common javascript function*/ /*Common javascript function*/
String.prototype.toHtmlChar = function(){ String.prototype.toHtmlChar = function(){
c = {'<':'&lt;', '>':'&gt;', '&':'&amp;', '"':'&quot;', "'":'&#039;', var c = {'<':'&lt;', '>':'&gt;', '&':'&amp;', '"':'&quot;', "'":'&#039;',
'#':'&#035;' }; '#':'&#035;' };
return this.replace( /[<&>'"#]/g, function(s) { return c[s]; } ); return this.replace( /[<&>'"#]/g, function(s) { return c[s]; } );
} }
...@@ -8,23 +8,50 @@ String.prototype.trim = function () { ...@@ -8,23 +8,50 @@ String.prototype.trim = function () {
return this.replace(/^\s*/, "").replace(/\s*$/, ""); return this.replace(/^\s*/, "").replace(/\s*$/, "");
} }
/**************************/
$(document).ready(function() { /****************************************/
$('input[type="text"]').addClass("idleField"); function setInput($elt) {
$('input[type="text"]').focus(function() { if(!$elt){var $elt = $('input[type="text"], input[type="password"]');}
$(this).removeClass("idleField").addClass("focusField"); $elt.addClass("idleField");
if (this.value == this.defaultValue){ $elt.focus(function() {
this.value = ''; $(this).removeClass("idleField").addClass("focusField");
} if (this.value == this.defaultValue){
if(this.value != this.defaultValue){ this.value = '';
this.select(); }
} if(this.value != this.defaultValue){
}); this.select();
$('input[type="text"]').blur(function() { }
$(this).removeClass("focusField").addClass("idleField"); });
if ($.trim(this.value) == ''){ $elt.blur(function() {
this.value = (this.defaultValue ? this.defaultValue : ''); $(this).removeClass("focusField").addClass("idleField");
} if ($.trim(this.value) == ''){
}); this.value = (this.defaultValue ? this.defaultValue : '');
}); }
\ No newline at end of file });
}
/**************************/
(function ($, document, window) {
$.extend($.fn, {
slideBox: function(state) {
if (!state) state = "hide";
var header = $("#"+$(this).attr('id')+">h2");
var box = $("#"+$(this).attr('id')+">div");
header.addClass(state);
if(state=="hide"){box.css('display', 'none');}
header.click(function(){
var state = box.css("display");
if (state == "none"){
box.slideDown("normal");
header.removeClass("hide");
header.addClass("show");
}
else{
box.slideUp("normal");
header.removeClass("show");
header.addClass("hide");
}
});
}
});
}(jQuery, document, this));
\ No newline at end of file
$(document).ready( function() { $(document).ready( function() {
var send = false; var send = false;
var cloneRequest; var cloneRequest;
$('#fileTree').fileTree({ root: $("input#workdir").val(), script: $SCRIPT_ROOT + '/readFolder', folderEvent: 'click', expandSpeed: 750, collapseSpeed: 750, multiFolder: false }, function(file) { $('#fileTree').fileTree({ root: $("input#workdir").val(), script: $SCRIPT_ROOT + '/readFolder', folderEvent: 'click', expandSpeed: 750, collapseSpeed: 750, multiFolder: false }, function(file) {
selectFile(file); selectFile(file);
}); });
configRadio(); configRadio();
...@@ -22,12 +22,12 @@ $(document).ready( function() { ...@@ -22,12 +22,12 @@ $(document).ready( function() {
$("#clone").append("Clone"); $("#clone").append("Clone");
send = false; send = false;
return; return;
} }
var repo_url = $("input#repo").val(); var repo_url = $("input#repo").val();
var email = ""; var email = "";
var name = "" var name = ""
/* /^(ht|f)tps?:\/\/[a-z0-9-\.]+\.[a-z]{2,4}\/?([^\s<>\#%"\,\{\}\\|\\\^\[\]`]+)?$/ */ /* /^(ht|f)tps?:\/\/[a-z0-9-\.]+\.[a-z]{2,4}\/?([^\s<>\#%"\,\{\}\\|\\\^\[\]`]+)?$/ */
if($("input#repo").val() == "" || !repo_url.match(/^[\w\d\.\/:~@_-]+$/)){ if($("input#repo").val() == "" || !repo_url.match(/^[\w\d\.\/:~@_-]+$/)){
$("#error").Popup("Invalid url for the repository", {type:'alert', duration:3000}); $("#error").Popup("Invalid url for the repository", {type:'alert', duration:3000});
return false; return false;
} }
...@@ -35,7 +35,7 @@ $(document).ready( function() { ...@@ -35,7 +35,7 @@ $(document).ready( function() {
$("#error").Popup("Invalid project name", {type:'alert', duration:3000}); $("#error").Popup("Invalid project name", {type:'alert', duration:3000});
return false; return false;
} }
if($("input#user").val() != "" && $("input#user").val() != "Enter your name..."){ if($("input#user").val() !== ""){
name = $("input#user").val(); name = $("input#user").val();
} }
if($("input#email").val() != "" && $("input#email").val() != "Enter your email adress..."){ if($("input#email").val() != "" && $("input#email").val() != "Enter your email adress..."){
...@@ -86,7 +86,7 @@ $(document).ready( function() { ...@@ -86,7 +86,7 @@ $(document).ready( function() {
$("#error").Popup("Your repository is cloned!", {type:'confirm', duration:3000}); $("#error").Popup("Your repository is cloned!", {type:'confirm', duration:3000});
$("input#repo").val("Enter the url of your repository..."); $("input#repo").val("Enter the url of your repository...");
$("input#name").val("Enter the project name..."); $("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) { $('#fileTree').fileTree({ root: $("input#workdir").val(), script: $SCRIPT_ROOT + '/readFolder', folderEvent: 'click', expandSpeed: 750, collapseSpeed: 750, multiFolder: false }, function(file) {
selectFile(file); selectFile(file);
}); });
} }
...@@ -97,15 +97,21 @@ $(document).ready( function() { ...@@ -97,15 +97,21 @@ $(document).ready( function() {
$("#clone").empty(); $("#clone").empty();
$("#clone").append("Clone"); $("#clone").append("Clone");
send = false; send = false;
} },
error: function(request,error) {
$("#error").Popup("unable to clone your project, please check your internet connection", {type:'error', duration:3000});
$("#imgwaitting").hide();
$("#clone").empty();
$("#clone").append("Clone");
}
}); });
return false; return false;
}); });
function configRadio(){ function configRadio(){
$("#modelist li").each(function(index) { $("#modelist li").each(function(index) {
var boxselector = "#box" + index; var boxselector = "#box" + index;
if($(this).hasClass('checked')){ if($(this).hasClass('checked')){
$(this).removeClass('checked'); $(this).removeClass('checked');
$(boxselector).slideUp("normal"); $(boxselector).slideUp("normal");
} }
if($(this).find("input:radio").is(':checked')){ if($(this).find("input:radio").is(':checked')){
...@@ -119,7 +125,7 @@ $(document).ready( function() { ...@@ -119,7 +125,7 @@ $(document).ready( function() {
} }
}); });
} }
function selectFile(file){ function selectFile(file){
//nothing //nothing
return; return;
......
...@@ -9,27 +9,33 @@ $(document).ready( function() { ...@@ -9,27 +9,33 @@ $(document).ready( function() {
$("#info").append("Please select your file or folder into the box..."); $("#info").append("Please select your file or folder into the box...");
fillContent(); fillContent();
}); });
function selectFile(file){ function selectFile(file){
var relativeFile = file.replace(runnerDir + "/" + $("#softwarelist").val(), ""); var relativeFile = file.replace(runnerDir + "/" + $("#softwarelist").val(), "");
$("#info").empty(); $("#info").empty();
$("#info").append("Selection: " + relativeFile); $("#info").append("Selection: " + relativeFile);
return; return;
} }
function fillContent(){ function fillContent(){
var folder = $("#softwarelist").val(); var folder = $("#softwarelist").val();
var elt = $("option:selected", $("#softwarelist")); var elt = $("option:selected", $("#softwarelist"));
$('#fileTree').fileTree({ root: runnerDir + "/" + folder, script: $SCRIPT_ROOT + '/readFolder', if(elt.val() !== "No Software Release found"){
folderEvent: 'click', expandSpeed: 750, collapseSpeed: 750, multiFolder: false, selectFolder: true }, function(file) { $('#fileTree').fileTree({ root: runnerDir + "/" + folder, script: $SCRIPT_ROOT + '/readFolder',
selectFile(file); folderEvent: 'click', expandSpeed: 750, collapseSpeed: 750, multiFolder: false, selectFolder: true }, function(file) {
}, function(file){ viewFile(file)}); selectFile(file);
$("#softcontent").empty(); }, function(file){ viewFile(file)});
$("#softcontent").append("File content: " + elt.attr('title')); $("#softcontent").empty();
$("#softcontent").append("File content: " + elt.attr('title'));
}
} }
$("#open").click(function(){ $("#open").click(function(){
var elt = $("option:selected", $("#softwarelist")); var elt = $("option:selected", $("#softwarelist"));
if(elt.val() === "No Software Release found"){
$("#error").Popup("Please select your Software Release", {type:'alert', duration:5000});
return false;
}
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: $SCRIPT_ROOT + '/setCurrentProject', url: $SCRIPT_ROOT + '/setCurrentProject',
...@@ -39,14 +45,18 @@ $(document).ready( function() { ...@@ -39,14 +45,18 @@ $(document).ready( function() {
location.href = $SCRIPT_ROOT + '/editSoftwareProfile' location.href = $SCRIPT_ROOT + '/editSoftwareProfile'
} }
else{ else{
$("#error").Popup(data.result, {type:'error'}); $("#error").Popup(data.result, {type:'error', duration:5000});
} }
} }
}); });
return false; return false;
}); });
$("#delete").click(function(){ $("#delete").click(function(){
if($("#softwarelist").val() === "No Software Release found"){
$("#error").Popup("Please select your Software Release", {type:'alert', duration:5000});
return false;
}
if(send) return; if(send) return;
send = false; send = false;
$.ajax({ $.ajax({
...@@ -55,21 +65,27 @@ $(document).ready( function() { ...@@ -55,21 +65,27 @@ $(document).ready( function() {
data: "name=" + $("#softwarelist").val(), data: "name=" + $("#softwarelist").val(),
success: function(data){ success: function(data){
if(data.code == 1){ if(data.code == 1){
var folder = $("#softwarelist").val(); 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(""); $("input#file").val("");
$("#info").empty(); $("#info").empty();
$("#info").append("Please select your file or folder into the box..."); $("#info").append("Please select your file or folder into the box...");
$("#softwarelist").empty(); $("#softwarelist").empty();
for(i=0; i<data.result.length; i++){ for(i=0; i<data.result.length; i++){
$("#softwarelist").append('<option value="' + data.result[i]["md5"] + $("#softwarelist").append('<option value="' + data.result[i]["md5"] +
'" title="' + data.result[i]["title"] +'" rel="' + '" title="' + data.result[i]["title"] +'" rel="' +
data.result[i]["path"] +'">' + data.result[i]["title"] + '</option>'); data.result[i]["path"] +'">' + data.result[i]["title"] + '</option>');
} }
if(data.result.length < 1){
$("#softwarelist").append('<option>No Software Release found</option>');
$('#fileTree').empty();
}
else{
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);
}, function(file){ viewFile(file)});
}
$("#error").Popup("Operation complete, Selected Software Release has been delete!", {type:'confirm', duration:5000}); $("#error").Popup("Operation complete, Selected Software Release has been delete!", {type:'confirm', duration:5000});
} }
else{ else{
...@@ -78,15 +94,15 @@ $(document).ready( function() { ...@@ -78,15 +94,15 @@ $(document).ready( function() {
send = false; send = false;
} }
}); });
return false; return false;
}); });
function viewFile(file){ function viewFile(file){
//User have double click on file in to the fileTree //User have double click on file in to the fileTree
var name = file.replace(runnerDir + "/" + $("#softwarelist").val(), "/software"); var name = file.replace(runnerDir + "/" + $("#softwarelist").val(), "/software");
loadFileContent(file, name); loadFileContent(file, name);
} }
function loadFileContent(file, filename){ function loadFileContent(file, filename){
$.ajax({ $.ajax({
type: "POST", type: "POST",
...@@ -99,14 +115,14 @@ $(document).ready( function() { ...@@ -99,14 +115,14 @@ $(document).ready( function() {
type: "POST", type: "POST",
url: $SCRIPT_ROOT + '/getFileContent', url: $SCRIPT_ROOT + '/getFileContent',
data: {file:file, truncate:1500}, data: {file:file, truncate:1500},
success: function(data){ success: function(data){
if(data.code == 1){ if(data.code == 1){
$("#inline_content").empty(); $("#inline_content").empty();
$("#inline_content").append('<h2 style="color: #4c6172; font: 18px \'Helvetica Neue\', Helvetica, Arial, sans-serif;">Inspect Software Content: ' + $("#inline_content").append('<h2 style="color: #4c6172; font: 18px \'Helvetica Neue\', Helvetica, Arial, sans-serif;">Inspect Software Content: ' +
filename +'</h2>'); filename +'</h2>');
$("#inline_content").append('<br/><div class="main_content"><pre id="editor"></pre></div>'); $("#inline_content").append('<br/><div class="main_content"><pre id="editor"></pre></div>');
setupEditor(); setupEditor();
$(".inline").colorbox({inline:true, width: "847px", onComplete:function(){ $(".inline").colorbox({inline:true, width: "847px", onComplete:function(){
editor.getSession().setValue(data.result); editor.getSession().setValue(data.result);
}}); }});
$(".inline").click(); $(".inline").click();
...@@ -128,11 +144,11 @@ $(document).ready( function() { ...@@ -128,11 +144,11 @@ $(document).ready( function() {
} }
}); });
} }
function setupEditor(){ function setupEditor(){
editor = ace.edit("editor"); editor = ace.edit("editor");
editor.setTheme("ace/theme/crimson_editor"); editor.setTheme("ace/theme/crimson_editor");
var CurentMode = require("ace/mode/text").Mode; var CurentMode = require("ace/mode/text").Mode;
editor.getSession().setMode(new CurentMode()); editor.getSession().setMode(new CurentMode());
editor.getSession().setTabSize(2); editor.getSession().setTabSize(2);
......
$(document).ready( function() {
var send = false;
//change background
$("body").css("background", "#9C9C9C");
$("#login").click(function(){
if (send) return false;
if($("input#clogin").val() === "" || !$("input#clogin").val().match(/^[\w\d\.-]+$/)){
$("#error").Popup("Please enter a valid user name", {type:'alert', duration:3000});
return false;
}
if($("input#cpwd").val() === "" || $("input#cpwd").val() ==="******"){
$("#error").Popup("Please enter your password", {type:'alert', duration:3000});
return false;
}
send = true;
var param = {clogin:$("input#clogin").val(), cpwd:$("input#cpwd").val()};
var url = $SCRIPT_ROOT + "/doLogin";
$.post(url, param, function(data) {
if (data.code==1){
location.href = $SCRIPT_ROOT + '/';
}
else{
$("#error").Popup(data.result, {type:'alert', duration:3000});
}
})
.error(function() {$("#error").Popup("Cannot send your account identifier please try again!!",
{type:'alert', duration:3000});})
.complete(function() {
send = false;
});
return false;
});
});
\ No newline at end of file
...@@ -106,7 +106,7 @@ function setRunningState(data){ ...@@ -106,7 +106,7 @@ function setRunningState(data){
$current.css("color", "#000"); $current.css("color", "#000");
$current = undefined; $current = undefined;
currentState = false; currentState = false;
$("#error").Popup("Successfully run " + processType + " Profile", {type:'info', duration:3000}); $("#error").Popup("Slapgrid completely finish running your " + processType + " Profile", {type:'info', duration:3000});
} }
} }
currentState = data.result; currentState = data.result;
......
{% extends "layout.html" %}
{% block title %}Update your account{% endblock %}
{% block head %}
{{ super() }}
<script src="{{ url_for('static', filename='js/scripts/account.js') }}" type="text/javascript" charset="utf-8"></script>
{% endblock %}
{% block body %}
<h2 class='title'>Your personal informations</h2><br/>
<form>
<div class='form'>
<label for="name">Your name: </label>
<input type='text' name='name' id='name' value='{{name}}'/>
<div class='clear'></div>
<label for="email">Your email adress: </label>
<input type='text' name='email' id='email' value='{{email}}'/>
<div class='clear'></div>
<label for="username">User name: </label>
<input type='text' name='username' id='username' value='{{username}}'/>
<div class='clear'></div>
<label for="password">Password: </label>
<input type='password' name='password' id='password' value=''/>
<div class='clear'></div>
<label for="cpassword">Confirm Password: </label>
<input type='password' name='cpassword' id='cpassword' value=''/>
<div class='clear'></div>
<br/>
<label></label>
<input type="submit" name="update" id ="update" value="Update" class="button"/>
<div class='clear'></div>
<br/><br/><br/>
</div>
<div id="file_info" class="file_info">leave passwords blank to preserve your current password...</div>
<br/>
</form>
{% endblock %}
...@@ -3,64 +3,77 @@ ...@@ -3,64 +3,77 @@
{% block head %} {% block head %}
{{ super() }} {{ super() }}
<link href="{{ url_for('static', filename='css/jqueryFileTree.css', _external=False) }}" rel="stylesheet" type="text/css" media="screen" /> <link href="{{ url_for('static', filename='css/jqueryFileTree.css', _external=False) }}" rel="stylesheet" type="text/css" media="screen" />
<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/jqueryFileTree.js') }}" type="text/javascript" charset="utf-8"></script> <script src="{{ url_for('static', filename='js/jquery/jqueryFileTree.js') }}" type="text/javascript" charset="utf-8"></script>
<script src="{{ url_for('static', filename='js/scripts/folder.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>
<script src="{{ url_for('static', filename='js/jquery/jqueryTabs.js') }}" type="text/javascript" charset="utf-8"></script>
{% endblock %} {% endblock %}
{% block body %} {% block body %}
<h2>Clone a repository into your workspace</h2><br/>
<h2 class='title'>Clone your repository into the workspace</h2><br/> <div id="tabContaier">
<div id="repository" style="margin-left:40px;"> <ul>
<label for='name'>Project name*: </label> <li><a href="#tab1" class="active">Clone your repository</a></li>
<input type="text" name="name" id="name" size='20' value="Enter the project name..." /> <li><a href="#tab2">Manage your project folder</a></li>
<label for='repo'>&nbsp;url*: &nbsp;&nbsp;</label> </ul><!-- //Tab buttons -->
<input type="text" name="repo" id="repo" size='25' value="Enter the url of your repository..." /><br/> <div class="tabDetails">
<label for='user'>Your name: &nbsp;&nbsp;&nbsp;&nbsp;</label> <div id="tab1" class="tabContents">
<input type="text" name="user" id="user" size='20' value="Enter your name..." /> <div id="repository" style="margin-left:40px;">
<label for='email'>Email: </label> <label for='name'>Project name*: </label>
<input type="text" name="email" id="email" size='25' value="Enter your email adress..." /> <input type="text" name="name" id="name" size='20' value="Enter the project name..." />
<input type="hidden" name="workdir" id="workdir" value="{{workDir}}" /> <label for='repo'>&nbsp;url*: &nbsp;&nbsp;</label>
<button class="button" id="clone">clone</button> <input type="text" name="repo" id="repo" size='25' value="Enter the url of your repository..." /><br/>
<img class="waitting" id="imgwaitting" src="{{ url_for('static', filename='images/waiting.gif') }}" alt="" /> <label for='user'>Your name: &nbsp;&nbsp;&nbsp;&nbsp;</label>
<br/><br/> <input type="text" name="user" id="user" size='20' value="{{name}}" />
</div> <label for='email'>Email: </label>
<h2>Set your Security Mode</h2> <input type="text" name="email" id="email" size='25' value="{% if not email %}Enter your email adress...{% else %}{{email}}{%endif%}" />
<div class="menu-box-right"> <input type="hidden" name="workdir" id="workdir" value="{{workDir}}" />
<div style="background:#fff; padding:10px; min-height:100px; font-size:14px;"> <button class="button" id="clone">clone</button>
<div id="box0"> <img class="waitting" id="imgwaitting" src="{{ url_for('static', filename='images/waiting.gif') }}" alt="" />
<h2>Clone Repository without using HTTPS and SSH</h2><br/> <br/><br/>
<p>Choose this mode if you don't have login and password for the repository and you if you don't have the possibility to </div>
use SSH authentication. Otherwise use your public key or your login and password to clone your project by choosing https or ssh mode. Note <br/>
that, with readonly mode you can not be able to push your changes.</p> <h2>Set your Security Mode</h2>
<br/> <div class="menu-box-right" style="width: 592px;">
</div> <div style="background:#fff; padding:10px; min-height:100px; font-size:14px;">
<div id="box1" style="display:none"> <div id="box0">
<h2>You can use this public key to setup your repository</h2><br/> <h2>Clone Repository without using HTTPS and SSH</h2><br/>
<textarea class="public_key" readonly> <p>Choose this mode if you don't have login and password for the repository and you if you don't have the possibility to
{{public_key}} use SSH authentication. Otherwise use your public key or your login and password to clone your project by choosing https or ssh mode. Note
</textarea> that, with readonly mode you can not be able to push your changes.</p>
</div> <br/>
<div id="box2" style="display:none;"> </div>
<h2>Enter your username and password for https authentication access</h2><br/> <div id="box1" style="display:none">
<div style="margin-left:80px; margin-bottom:20px;"> <h2>You can use this public key to setup your repository</h2><br/>
<label for='username'>Your username:&nbsp;&nbsp;</label> <textarea class="mb_style public_key" readonly>
<input type="text" name="username" id="username" size='20' value="Enter your username..." /><br/><br/> {{public_key}}
<label for='password'>Your password: &nbsp;&nbsp;</label> </textarea>
<input type="password" name="password" id="password" size='20' value="" class="idleField" /> </div>
</div> <div id="box2" style="display:none;">
<p></p> <h2>Enter your username and password for https authentication access</h2><br/>
</div> <div style="margin-left:80px; margin-bottom:20px;">
</div> <label for='username'>Your username:&nbsp;&nbsp;</label>
</div> <input type="text" name="username" id="username" size='20' value="Enter your username..." /><br/><br/>
<div class="menu-box-left"> <label for='password'>Your password: &nbsp;&nbsp;</label>
<ul id="modelist"> <input type="password" name="password" id="password" size='20' value="" class="idleField" />
<li class="checked"><input type="radio" name="security" id="nothing" value="nothing" /><label for="nothing">ReadOnly</label></li> </div>
<li><input type="radio" name="security" id="ssh" value="SSH" checked /><label for="ssh">SSH Mode</label></li> <p></p>
<li style="border-bottom:none"><input type="radio" name="security" id="https" value="HTTPS" /><label for="https">Https Mode</label></li> </div>
</ul> </div>
</div> </div>
<div class="clear"></div><br/> <div class="menu-box-left" style="width: 115px;">
<div id="file_navigation"> <ul id="modelist">
<h2 class='title'>Your project folder</h2><br/> <li class="checked"><input type="radio" name="security" id="nothing" value="nothing" /><label for="nothing">ReadOnly</label></li>
<div id="fileTree" class="file_tree"></div> <li><input type="radio" name="security" id="ssh" value="SSH" checked /><label for="ssh">SSH Mode</label></li>
<li style="border-bottom:none"><input type="radio" name="security" id="https" value="HTTPS" /><label for="https">Https Mode</label></li>
</ul>
</div>
<div class="clear"></div><br/>
<!--Fin tab1-->
</div>
<div id="tab2" class="tabContents">
<h2>Content of your cloned project</h2><br/>
<div id="fileTree" class="file_tree_tabs"></div>
</div>
</div>
</div> </div>
{% endblock %} {% endblock %}
{% extends "layout.html" %} {% extends "layout.html" %}
{% block title %}SlapOs buildout web based runner {% endblock %} {% block title %}SlapOS buildout web based runner {% endblock %}
{% block body %} {% block body %}
<div id="home_box"> <div id="home_box">
<div class="inner_box"> <div class="inner_box">
...@@ -23,14 +23,20 @@ ...@@ -23,14 +23,20 @@
<img src="{{ url_for('static', filename='images/manage_repo.png') }}" /> <img src="{{ url_for('static', filename='images/manage_repo.png') }}" />
</div> </div>
<div class="clear"></div> <div class="clear"></div>
<div class="lmenu"> <div class="lmenu smaller">
<h2><a href="{{ url_for('openProject', method='new')}}">Create your new Software Release</a></h2> <h2><a href="{{ url_for('openProject', method='new')}}">Create your 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 <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 release. run the new software release.-->
</p> </p>
<img src="{{ url_for('static', filename='images/folder_blue.png') }}" /> <img src="{{ url_for('static', filename='images/folder_blue.png') }}" />
<div class="clear"></div> <div class="clear"></div>
</div> </div>
<div class="umenu">
<h2><a href="{{ url_for('myAccount')}}">Your Account</a></h2>
<p>Update your account informations</p>
<img src="{{ url_for('static', filename='images/user_card.png') }}" />
</div>
<div class="clear"></div>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}
...@@ -19,14 +19,15 @@ ...@@ -19,14 +19,15 @@
<div id="tabContaier"> <div id="tabContaier">
<ul> <ul>
<li><a href="#tab1" class="active">Slapgrid Supervisor</a></li> <li><a href="#tab1" class="active">Slapgrid Supervisor</a></li>
<li><a href="#tab2">SLAP Response & Parameters</a></li> <li><a href="#tab2">SLAP Response</a></li>
<li><a href="#tab3">Partitions Content</a></li> <li><a href="#tab3" id="parameterTab">Parameters</a></li>
<li><a href="#tab4" id="instancetabfiles">Partitions Content</a></li>
</ul><!-- //Tab buttons --> </ul><!-- //Tab buttons -->
<div class="tabDetails"> <div class="tabDetails">
<div id="tab1" class="tabContents"> <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 log.</p> <p>This tab show all process generated by slapgrid for your application. You can click on the process name to display log.</p>
{% if supervisor %} {% if supervisor %}
<table cellpadding="0" cellspacing="0" width="100%"> <table cellpadding="0" cellspacing="0" width="100%" id="supervisordcontent">
<tr> <tr>
<th>Partition and Process name</th><th>Status</th><th>Process PID </th><th> UpTime</th><th></th> <th>Partition and Process name</th><th>Status</th><th>Process PID </th><th> UpTime</th><th></th>
</tr> </tr>
...@@ -39,7 +40,10 @@ ...@@ -39,7 +40,10 @@
</tr> </tr>
{% endfor %} {% endfor %}
</table><br/> </table><br/>
<a href="{{ url_for('stopAllPartition') }}" class="lshare simple">Stop all process</a> <a href="#" id="refresh" class="lshare simple no-right-border" style="float:left">Refresh Status</a>
<a href="{{ url_for('stopAllPartition') }}" class="lshare simple" style="float:left">Stop all process</a>
<img class="waitting" id="imgwaitting" src="{{ url_for('static', filename='images/waiting.gif') }}" alt="" />
<div class="clear"></div><br/>
{% else %} {% else %}
<h2>No process to display, please run your instance</h2> <h2>No process to display, please run your instance</h2>
{%endif%} {%endif%}
...@@ -52,13 +56,13 @@ ...@@ -52,13 +56,13 @@
{% for item in slap_status %} {% for item in slap_status %}
<div id="box{{item[0]}}" style="display:none;"> <div id="box{{item[0]}}" style="display:none;">
{% if item[1] %} {% if item[1] %}
<!--<h2><span style="float:left; margin-left:10px;" id="{{item[0]}}title">Slap Response for {{item[0]}}</span> <h2><span style="float:left; margin-left:10px;" id="{{item[0]}}title">Slap Response for {{item[0]}}</span>
<a href="#" id="{{item[0]}}Parameter" rel="{{item[0]}}" class="lshare simple" style="float:right">SLAP Parameters</a> <a href="#" id="{{item[0]}}Parameter" rel="{{item[0]}}" class="lshare simple" style="float:right" title='Restart all partition process'>Restart</a>
</h2>--> <a href="#" id="{{item[0]}}Files" rel="{{item[0]}}" class="lshare simple no-right-border" style="float:right">Files</a>
<h2>Slap Response for {{item[0]}}</h2> </h2>
<div class="clear"></div><br/> <div class="clear"></div><br/>
<div id="bcontent{{item[0]}}"> <div id="bcontent{{item[0]}}">
<table cellpadding="0" cellspacing="0" width="100%"> <table cellpadding="0" cellspacing="0" width="100%">
<tr> <tr>
<th>Parameter Name</th><th>Parameter Value</th> <th>Parameter Name</th><th>Parameter Value</th>
</tr> </tr>
...@@ -67,9 +71,9 @@ ...@@ -67,9 +71,9 @@
<td class="propertie first">{{k}}</td><td align='left'>{{item[1][k]}}</td> <td class="propertie first">{{k}}</td><td align='left'>{{item[1][k]}}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>
</div> </div>
{% else %} {% else %}
<h2>Empty Partition</h2></br> <h2>Empty Partition</h2></br>
<center><img alt="" src="{{ url_for('static', filename='images/empty.png') }}" /></center> <center><img alt="" src="{{ url_for('static', filename='images/empty.png') }}" /></center>
<br/><h2>Partition {{item[0]}} is still empty</h2> <br/><h2>Partition {{item[0]}} is still empty</h2>
...@@ -82,8 +86,8 @@ ...@@ -82,8 +86,8 @@
<ul id="slappart"> <ul id="slappart">
{% for item in slap_status %} {% for item in slap_status %}
<li><input type="radio" name="slapresponse" id="{{item[0]}}" value="{{item[0]}}" /> <li><input type="radio" name="slapresponse" id="{{item[0]}}" value="{{item[0]}}" />
<label for="{{item[0]}}" {% if item[1] %}style="font-weight:bold"{%endif%}>{{item[0]}}</label></li> <label for="{{item[0]}}" {% if item[1] %}style="font-weight:bold"{%endif%}>{{item[0]}}</label></li>
{% endfor %} {% endfor %}
</ul> </ul>
</div> </div>
<div class="clear"></div><br/> <div class="clear"></div><br/>
...@@ -92,8 +96,39 @@ ...@@ -92,8 +96,39 @@
{%endif%} {%endif%}
</div><!-- end tab2 --> </div><!-- end tab2 -->
<div id="tab3" class="tabContents"> <div id="tab3" class="tabContents">
<div id="fileTree" class="file_tree_tabs"></div> <div id="softwareType">
<h2 class='hight'>Software Type parameter</h2>
<div class="slidebox">
<label for="software_type">Software Type </label>
<input type="text" name="software_type" id="software_type" size="35" value="Software Type here..." />
</div>
</div>
<br/>
<div id="parameterkw">
<h2 class='hight'>Partitions Parameter</h2>
<div class="slidebox">
<table class="small" cellpadding="0" cellspacing="0" width="100%" id="partitionParameter">
<tr id="row_1">
<th width="150">Parameter Name</th><th>Parameter Value</th><th width="49">
<a href="#" class="link" id="add_attribute">[new]</a>
</th>
</tr>
</table>
</div>
</div>
<br/>
<div>
<a id="updateParameters" class="lshare simple no-right-border" style="float:left">Update Values</a>
<a href="#" id="xmlview" class="lshare simple" style="float:left">Load XML</a>
</div>
<div class="clear"></div>
</div><!-- end tab3 --> </div><!-- end tab3 -->
<div id="tab4" class="tabContents">
<h2>File content for all your partitions</h2>
<div id="fileTree" class="file_tree_tabs" title="Double click to open file"></div>
<br/>
<a href="#" id="reloadfiles" class="lshare simple">Reload Files</a>
</div><!-- end tab4 -->
</div> </div>
</div> </div>
<!-- This contains the hidden content for inline calls --> <!-- This contains the hidden content for inline calls -->
...@@ -103,4 +138,5 @@ ...@@ -103,4 +138,5 @@
</div> </div>
</div> </div>
{{instance}}
{% endblock %} {% endblock %}
...@@ -19,10 +19,16 @@ ...@@ -19,10 +19,16 @@
<script type=text/javascript> <script type=text/javascript>
$SCRIPT_ROOT = {{ request.script_root|tojson|safe }}; $SCRIPT_ROOT = {{ request.script_root|tojson|safe }};
</script> </script>
<script src="{{ url_for('static', filename='js/scripts/process.js') }}" type="text/javascript" charset="utf-8"></script>
<script src="{{ url_for('static', filename='js/scripts/cookies.js') }}" type="text/javascript" charset="utf-8"></script> <script src="{{ url_for('static', filename='js/scripts/cookies.js') }}" type="text/javascript" charset="utf-8"></script>
<script src="{{ url_for('static', filename='js/scripts/common.js') }}" type="text/javascript" charset="utf-8"></script> <script src="{{ url_for('static', filename='js/scripts/common.js') }}" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() {
setInput();
});
</script>
{% if request.path != '/login' %}
<script src="{{ url_for('static', filename='js/scripts/process.js') }}" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
$(document).ready(function() { $(document).ready(function() {
if($("input#fmsg").val() != ""){ if($("input#fmsg").val() != ""){
$("#error").Popup($("input#fmsg").val(), {type:'info', duration:5000, load:true}); $("#error").Popup($("input#fmsg").val(), {type:'info', duration:5000, load:true});
...@@ -33,20 +39,22 @@ ...@@ -33,20 +39,22 @@
} }
}); });
</script> </script>
{%endif%}
{% endblock %} {% endblock %}
</head> </head>
<body> <body>
<div id="error"></div> <div id="error"></div>
<div id="page">
<div {% if request.path != '/login' %}id="page"{%else%}id="login-page"{%endif%}>
<input type="hidden" name="fmsg" value="{{ get_flashed_messages()[0] }}" id="fmsg" /> <input type="hidden" name="fmsg" value="{{ get_flashed_messages()[0] }}" id="fmsg" />
<!--<div id="logo">--> {% if request.path != '/login' %}
<!--<a href="{{ url_for('home') }}"><img src="{{ url_for('static', filename='images/logo.png') }}" alt="" /></a>-->
<!--</div>-->
<div id="header"> <div id="header">
<div class="block_header"> <div class="block_header">
<a href="{{ url_for('home') }}" style="float:left;" id="home" {% if request.path != '/' %}rel="tooltip"{% endif %} title="Home"><img alt="" src="{{ url_for('static', filename='images/home.png') }}" /></a> <a href="{{ url_for('home') }}" style="float:left;" id="home" {% if request.path != '/' %}rel="tooltip"{% endif %} title="Home"><img alt="" src="{{ url_for('static', filename='images/home.png') }}" /></a>
<div class="line"></div> <div class="line"></div>
<a href="{{ url_for('editCurrentProject') }}" style="float:left" title="Edit your current project"><img alt="" src="{{ url_for('static', filename='images/project.png') }}" /></a> <a href="{{ url_for('editCurrentProject') }}" style="float:left" title="Edit your current project"><img alt="" src="{{ url_for('static', filename='images/project.png') }}" /></a>
<div class="line"></div>
<a href="{{ url_for('logout') }}" style="float:left" title="Close your session"><img alt="" src="{{ url_for('static', filename='images/logout.png') }}" /></a>
<div class="line"></div> <div class="line"></div>
<h2 class="info">{% block title %}{% endblock %} - {{session.title}}</h2> <h2 class="info">{% block title %}{% endblock %} - {{session.title}}</h2>
<div class="run"><span id="running" style="display:none"><img alt="" src="{{ url_for('static', filename='images/ajax_roller.gif') }}" <div class="run"><span id="running" style="display:none"><img alt="" src="{{ url_for('static', filename='images/ajax_roller.gif') }}"
...@@ -71,24 +79,27 @@ ...@@ -71,24 +79,27 @@
</div> </div>
<div class="clear"></div> <div class="clear"></div>
</div> </div>
<div id="main"> {% endif %}
<div {% if request.path == '/' %} class="home_content" {%else%} id="content" {% endif %}> <div {% if request.path != '/login' %}id="main"{% endif %}>
{% if request.path != '/' %} <div {% if request.path == '/' %} class="home_content" {%elif request.path == '/login'%} {%else%} id="content" {% endif %}>
{% if request.path != '/' and request.path != '/login'%}
<div class="main_head"> <div class="main_head">
</div> </div>
<div class="content"> <div class="content">
{% endif %} {% endif %}
{% block body %}{% endblock %} {% block body %}{% endblock %}
{% if request.path != '/' %} {% if request.path != '/' and request.path != '/login'%}
</div> </div>
<div class="main_foot"> <div class="main_foot">
</div> </div>
{% endif %} {% endif %}
</div> </div>
</div> </div>
{% if request.path != '/login' %}
<div id="footer"> <div id="footer">
SlapOs web runner &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>
{%endif%}
</div> </div>
<div class="popup"> <div class="popup">
<table id="dpop" cellpadding="0" border="0"> <table id="dpop" cellpadding="0" border="0">
...@@ -110,11 +121,11 @@ ...@@ -110,11 +121,11 @@
<div id="tooltip-home" style="display:none"> <div id="tooltip-home" style="display:none">
<span style="font-weight:bold">QUICK ACCESS TO MENU</span><br/><br/> <span style="font-weight:bold">QUICK ACCESS TO MENU</span><br/><br/>
<div style="margin-top:3px;border-bottom: 1px dashed #666666; heigth:1px"></div> <div style="margin-top:3px;border-bottom: 1px dashed #666666; heigth:1px"></div>
<ul> <ul>
<li><a href="{{ url_for('manageProject')}}">Manage Repositories</a></li> <li><a href="{{ url_for('manageProject')}}">Manage Repositories</a></li>
<li><a href="{{ url_for('configRepo')}}" >Clone your Repository</a></li> <li><a href="{{ url_for('configRepo')}}" >Clone your repository</a></li>
<li><a href="{{ url_for('openProject', method='open')}}">Open Software Release</a></li> <li><a href="{{ url_for('openProject', method='open')}}">Open Software Release</a></li>
<li><a href="{{ url_for('openProject', method='new')}}">Create Software Release</a></li> <li><a href="{{ url_for('openProject', method='new')}}">Create Software Release</a></li>
</ul> </ul>
</div> </div>
</body> </body>
......
{% extends "layout.html" %}
{% block head %}
{{ super() }}
<script src="{{ url_for('static', filename='js/scripts/login.js') }}" type="text/javascript" charset="utf-8"></script>
{% endblock %}
{% block body %}
<form method="POST" action="">
<h2>Login to Slapos Web Runner</h2>
<div class="login-content">
<div class="login-element login-label"><label for="clogin">Your login&nbsp; : </label></div>
<div class="login-element"><input type="text" class="login-input" name="clogin" id="clogin" value="Enter login..." /></div><br/><br/>
<div class="clear"></div>
<div class="login-element login-label"><label for="cpwd">Password : </label></div>
<div class="login-element"><input type="password" class="idleField login-input" name="cpwd" id="cpwd" value="******" /></div>
<div class="clear"></div>
</div>
<div style="text-align:center">
<input type="reset" class="button" value="reset" />
<input type="submit" class="button" id="login" value="login" />
</div>
</form>
{% endblock %}
\ No newline at end of file
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
<input type="hidden" name="method" id="method" value="{{method}}" /> <input type="hidden" name="method" id="method" value="{{method}}" />
{% if method == "new" %} {% if method == "new" %}
<div id="addsoftware"> <div id="addsoftware">
<h2>Create your software release</h2> <h2 class="title">Create your software release</h2><br/>
<label for='software'>Name: </label> <label for='software'>Name: </label>
<input type="text" name="software" id="software" size='30' value="Enter software name..." /> <input type="text" name="software" id="software" size='30' value="Enter software name..." />
<br/><br/> <br/><br/>
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
</div> </div>
{% elif method == "open" %} {% elif method == "open" %}
<div id="openSoftware"> <div id="openSoftware">
<h2>Select the folder of your software release into the box</h2> <h2 class="title">Select the folder of your software release into the box</h2><br/>
<div id="fileTree" class="file_tree"></div> <div id="fileTree" class="file_tree"></div>
<div id="file_info" class="file_info"> <div id="file_info" class="file_info">
<img src="{{ url_for('static', filename='images/check.png') }}" class="check" id="check" alt=""/> <img src="{{ url_for('static', filename='images/check.png') }}" class="check" id="check" alt=""/>
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
<input type="hidden" name="runnerdir" id="runnerdir" value="{{softwareRoot}}" /> <input type="hidden" name="runnerdir" id="runnerdir" value="{{softwareRoot}}" />
<label for='softwarelist'>Select software: </label> <label for='softwarelist'>Select software: </label>
<select name="softwarelist" id="softwarelist"> <select name="softwarelist" id="softwarelist">
{%if not softwares %}<option >No Software Release found</option>{% endif %}
{%for soft in softwares %} {%for soft in softwares %}
<option value="{{soft['md5']}}" title="{{soft['title']}}" rel="{{soft['path']}}">{{soft['title']}}</option> <option value="{{soft['md5']}}" title="{{soft['title']}}" rel="{{soft['path']}}">{{soft['title']}}</option>
{%endfor%} {%endfor%}
...@@ -23,8 +24,8 @@ ...@@ -23,8 +24,8 @@
&nbsp;&nbsp;<button id ="delete" class="button" title="Remove this software">Remove</button> &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> &nbsp;&nbsp;<button id ="open" class="button" title="Set this software as current software release">Open</button>
<br/><br/> <br/><br/>
<h2 id="softcontent">No content to displays</h2> <h2 id="softcontent">No file or folder to display</h2>
<div id="fileTree" class="file_tree" style='height:200px;'></div> <div id="fileTree" class="file_tree" style='height:200px;' title="Double click to open file"></div>
<div id="file_info" class="file_info"> <div id="file_info" class="file_info">
<span id="info">Please select your file or folder into the box...</span></div> <span id="info">Please select your file or folder into the box...</span></div>
<!-- This contains the hidden content for inline calls --> <!-- This contains the hidden content for inline calls -->
......
This diff is collapsed.
# -*- coding: utf-8 -*-
from flask import Flask, request, redirect, url_for, \ from flask import Flask, request, redirect, url_for, \
render_template, flash, jsonify, session render_template, flash, jsonify, session
from utils import * from utils import *
...@@ -9,21 +11,51 @@ from gittools import cloneRepo, gitStatus, switchBranch, addBranch, getDiff, \ ...@@ -9,21 +11,51 @@ from gittools import cloneRepo, gitStatus, switchBranch, addBranch, getDiff, \
app = Flask(__name__) app = Flask(__name__)
#Access Control: Only static files and login pages are allowed to guest
@app.before_request @app.before_request
def before_request(): def before_request():
session['title'] = getProjectTitle(app.config) if (not session.has_key('account') or not session['account']) \
and request.path != '/login' \
and request.path != '/doLogin' and not request.path.startswith('/static'):
return redirect(url_for('login'))
if session.has_key('account') and session['account']:
session['title'] = getProjectTitle(app.config)
session['account'] = getSession(app.config)
# general views # general views
@app.route('/') @app.route('/')
def home(): def home():
if not os.path.exists(app.config['workspace']) or len(os.listdir(app.config['workspace'])) == 0:
return redirect(url_for('configRepo'))
return render_template('index.html') return render_template('index.html')
@app.route("/login")
def login():
return render_template('login.html')
@app.route("/myAccount")
def myAccount():
return render_template('account.html', username=session['account'][0],
email=session['account'][2], name=session['account'][3].decode('utf-8'))
@app.route("/logout")
def logout():
session['account'] = None
return redirect(url_for('login'))
@app.route('/configRepo') @app.route('/configRepo')
def configRepo(): def configRepo():
public_key = open(app.config['public_key'], 'r').read() public_key = open(app.config['public_key'], 'r').read()
return render_template('cloneRepository.html', workDir='workspace', public_key=public_key) return render_template('cloneRepository.html', workDir='workspace',
public_key=public_key, name=session['account'][3].decode('utf-8'),
email=session['account'][2])
@app.route("/doLogin", methods=['POST'])
def doLogin():
check_user = checkLogin(app.config, request.form['clogin'], request.form['cpwd'])
if not check_user:
return jsonify(code=0, result="Login or password is incorrect, please check it!")
else:
session['account'] = check_user
return jsonify(code=1, result=check_user)
# software views # software views
@app.route('/editSoftwareProfile') @app.route('/editSoftwareProfile')
...@@ -43,6 +75,7 @@ def inspectSoftware(): ...@@ -43,6 +75,7 @@ def inspectSoftware():
return render_template('runResult.html', softwareRoot='software_root', return render_template('runResult.html', softwareRoot='software_root',
softwares=loadSoftwareData(app.config['runner_workdir'])) softwares=loadSoftwareData(app.config['runner_workdir']))
#remove content of compiled software release
@app.route('/removeSoftware') @app.route('/removeSoftware')
def removeSoftware(): def removeSoftware():
file_config = os.path.join(app.config['runner_workdir'], ".softdata") file_config = os.path.join(app.config['runner_workdir'], ".softdata")
...@@ -80,6 +113,7 @@ def editInstanceProfile(): ...@@ -80,6 +113,7 @@ def editInstanceProfile():
return render_template('updateInstanceProfile.html', workDir='workspace', return render_template('updateInstanceProfile.html', workDir='workspace',
profile=profile, projectList=getProjectList(app.config['workspace'])) profile=profile, projectList=getProjectList(app.config['workspace']))
# get status of all computer partitions and process state
@app.route('/inspectInstance', methods=['GET']) @app.route('/inspectInstance', methods=['GET'])
def inspectInstance(): def inspectInstance():
file_content = '' file_content = ''
...@@ -88,17 +122,39 @@ def inspectInstance(): ...@@ -88,17 +122,39 @@ def inspectInstance():
file_content = 'instance_root' file_content = 'instance_root'
result = getSvcStatus(app.config) result = getSvcStatus(app.config)
if len(result) == 0: if len(result) == 0:
result = [] result = []
return render_template('instanceInspect.html', return render_template('instanceInspect.html',
file_path=file_content, supervisor=result, slap_status=getSlapStatus(app.config), file_path=file_content, supervisor=result, slap_status=getSlapStatus(app.config),
supervisore=result, partition_amount=app.config['partition_amount']) supervisore=result, partition_amount=app.config['partition_amount'])
#Reload instance process ans returns new value to ajax
@app.route('/supervisordStatus', methods=['GET'])
def supervisordStatus():
result = getSvcStatus(app.config)
if not (result):
return jsonify(code=0, result="")
html = "<tr><th>Partition and Process name</th><th>Status</th><th>Process PID </th><th> UpTime</th><th></th></tr>"
for item in result:
html += "<tr>"
html +="<td class='first'><b><a href='" + url_for('tailProcess', process=item[0])+"'>"+item[0]+"</a></b></td>"
html +="<td align='center'><a href='"+url_for('startStopProccess', process=item[0], action=item[1])+"'>"+item[1]+"</a></td>"
html +="<td align='center'>"+item[3]+"</td><td>"+item[5]+"</td>"
html +="<td align='center'><a href='"+url_for('startStopProccess', process=item[0], action='RESTART')+"'>Restart</a></td>"
html +="</tr>"
return jsonify(code=1, result=html)
@app.route('/removeInstance') @app.route('/removeInstance')
def removeInstance(): def removeInstance():
if isInstanceRunning(app.config): if isInstanceRunning(app.config):
flash('Instantiation in progress, cannot remove') flash('Instantiation in progress, cannot remove')
else: else:
stopProxy(app.config)
removeProxyDb(app.config)
startProxy(app.config)
removeInstanceRoot(app.config) removeInstanceRoot(app.config)
param_path = os.path.join(app.config['runner_workdir'], ".parameter.xml")
if os.path.exists(param_path):
os.remove(param_path)
flash('Instance removed') flash('Instance removed')
return redirect(url_for('inspectInstance')) return redirect(url_for('inspectInstance'))
...@@ -201,6 +257,7 @@ def getProjectStatus(): ...@@ -201,6 +257,7 @@ def getProjectStatus():
else: else:
return jsonify(code=0, result="Can not read folder: Permission Denied") return jsonify(code=0, result="Can not read folder: Permission Denied")
#view for current software release files
@app.route("/editCurrentProject") @app.route("/editCurrentProject")
def editCurrentProject(): def editCurrentProject():
project = os.path.join(app.config['runner_workdir'], ".project") project = os.path.join(app.config['runner_workdir'], ".project")
...@@ -210,6 +267,7 @@ def editCurrentProject(): ...@@ -210,6 +267,7 @@ def editCurrentProject():
projectList=getProjectList(app.config['workspace'])) projectList=getProjectList(app.config['workspace']))
return redirect(url_for('configRepo')) return redirect(url_for('configRepo'))
#create file or directory
@app.route("/createFile", methods=['POST']) @app.route("/createFile", methods=['POST'])
def createFile(): def createFile():
path = realpath(app.config, request.form['file'], False) path = realpath(app.config, request.form['file'], False)
...@@ -225,6 +283,7 @@ def createFile(): ...@@ -225,6 +283,7 @@ def createFile():
except Exception, e: except Exception, e:
return jsonify(code=0, result=str(e)) return jsonify(code=0, result=str(e))
#remove file or directory
@app.route("/removeFile", methods=['POST']) @app.route("/removeFile", methods=['POST'])
def removeFile(): def removeFile():
try: try:
...@@ -238,8 +297,13 @@ def removeFile(): ...@@ -238,8 +297,13 @@ def removeFile():
@app.route("/removeSoftwareDir", methods=['POST']) @app.route("/removeSoftwareDir", methods=['POST'])
def removeSoftwareDir(): def removeSoftwareDir():
return removeSoftwareByName(app.config, request.form['name']) try:
data = removeSoftwareByName(app.config, request.form['name'])
return jsonify(code=1, result=data)
except Exception, e:
return jsonify(code=0, result=str(e))
#read file and return content to ajax
@app.route("/getFileContent", methods=['POST']) @app.route("/getFileContent", methods=['POST'])
def getFileContent(): def getFileContent():
file_path = realpath(app.config, request.form['file']) file_path = realpath(app.config, request.form['file'])
...@@ -256,7 +320,7 @@ def getFileContent(): ...@@ -256,7 +320,7 @@ def getFileContent():
def saveFileContent(): def saveFileContent():
file_path = realpath(app.config, request.form['file']) file_path = realpath(app.config, request.form['file'])
if file_path: if file_path:
open(file_path, 'w').write(request.form['content']) open(file_path, 'w').write(request.form['content'].encode("utf-8"))
return jsonify(code=1, result="") return jsonify(code=1, result="")
else: else:
return jsonify(code=0, result="Error: No such file!") return jsonify(code=0, result="Error: No such file!")
...@@ -323,6 +387,7 @@ def getmd5sum(): ...@@ -323,6 +387,7 @@ def getmd5sum():
else: else:
return jsonify(code=0, result="Can not get md5sum for this file!") return jsonify(code=0, result="Can not get md5sum for this file!")
#return informations about state of slapgrid process
@app.route("/slapgridResult", methods=['POST']) @app.route("/slapgridResult", methods=['POST'])
def slapgridResult(): def slapgridResult():
software_state = isSoftwareRunning(app.config) software_state = isSoftwareRunning(app.config)
...@@ -359,31 +424,61 @@ def getPath(): ...@@ -359,31 +424,61 @@ def getPath():
else: else:
return jsonify(code=1, result=realfile) return jsonify(code=1, result=realfile)
#update instance parameter into a local xml file
@app.route("/saveParameterXml", methods=['POST']) @app.route("/saveParameterXml", methods=['POST'])
def redParameterXml(): def saveParameterXml():
project = os.path.join(app.config['runner_workdir'], ".project") project = os.path.join(app.config['runner_workdir'], ".project")
if not os.path.exists(project): if not os.path.exists(project):
return jsonify(code=0, result="Please first open a Software Release") return jsonify(code=0, result="Please first open a Software Release")
content = request.form['parameter'] content = request.form['parameter'].encode("utf-8")
param_path = os.path.join(app.config['runner_workdir'], ".parameter.xml") param_path = os.path.join(app.config['runner_workdir'], ".parameter.xml")
f = open(param_path, 'w') try:
f.write(content) f = open(param_path, 'w')
f.close() f.write(content)
result = readParameters(param_path) f.close()
result = readParameters(param_path)
except Exception, e:
result = str(e)
software_type = None
if(request.form['software_type']):
software_type = request.form['software_type']
if type(result) == type(''): if type(result) == type(''):
return jsonify(code=0, result="XML Error: " + result) return jsonify(code=0, result=result)
else: else:
try: try:
updateProxy(app.config) updateInstanceParameter(app.config, software_type)
except Exeption: except Exception, e:
return jsonify(code=0, result="An error occurred while applying your settings!") return jsonify(code=0, result="An error occurred while applying your settings!<br/>" + str(e))
return jsonify(code=1, result="") return jsonify(code=1, result="")
@app.route("/getParameterXml", methods=['GET']) #read instance parameters into the local xml file and return a dict
def getParameterXml(): @app.route("/getParameterXml/<request>", methods=['GET'])
def getParameterXml(request):
param_path = os.path.join(app.config['runner_workdir'], ".parameter.xml") param_path = os.path.join(app.config['runner_workdir'], ".parameter.xml")
if os.path.exists(param_path): if not os.path.exists(param_path):
content = open(param_path, 'r').read() default = '<?xml version="1.0" encoding="utf-8"?>\n'
return html_escape(content) default += '<instance>\n</instance>'
return jsonify(code=1, result=default)
if request == "xml":
parameters = open(param_path, 'r').read()
else:
parameters = readParameters(param_path)
if type(parameters) == type('') and request != "xml":
return jsonify(code=0, result=parameters)
else:
return jsonify(code=1, result=parameters)
#update user account data
@app.route("/updateAccount", methods=['POST'])
def updateAccount():
account = []
user = os.path.join(app.config['runner_workdir'], '.users')
account.append(request.form['username'].strip())
account.append(request.form['password'].strip())
account.append(request.form['email'].strip())
account.append(request.form['name'].strip())
result = saveSession(app.config, session, account)
if type(result) == type(""):
return jsonify(code=0, result=result)
else: else:
return "&lt;?xml version='1.0' encoding='utf-8'?&gt;" return jsonify(code=1, result="")
\ No newline at end of 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