Commit 6ca08bcc authored by Jerome Mariette's avatar Jerome Mariette

save

parent 6f225cb0
......@@ -2,10 +2,7 @@
<html lang="en">
<head>
<meta charset="utf-8">
<title>Jflow - Test page</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<title>Jflow</title>
<!-- Le styles -->
<link href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css" rel="stylesheet">
......@@ -16,17 +13,6 @@
}
</style>
<link href="http://twitter.github.com/bootstrap/assets/css/bootstrap-responsive.css" rel="stylesheet">
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="../assets/js/html5shiv.js"></script>
<![endif]-->
<!-- Fav and touch icons -->
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="../assets/ico/apple-touch-icon-144-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="../assets/ico/apple-touch-icon-114-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="../assets/ico/apple-touch-icon-72-precomposed.png">
<link rel="apple-touch-icon-precomposed" href="../assets/ico/apple-touch-icon-57-precomposed.png">
<link rel="shortcut icon" href="../assets/ico/favicon.png">
</head>
......@@ -44,7 +30,7 @@
<div class="nav-collapse collapse">
<ul class="nav">
<li class="active"><a href="#">Home</a></li>
<li><a href="#about">About</a></li>
<li><a target="_blank" href="https://mulcyber.toulouse.inra.fr/plugins/mediawiki/wiki/jflow/index.php/Accueil">About</a></li>
<li><a href="#contact">Contact</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
......@@ -64,40 +50,60 @@
</div>
</div>
<div class="jumbotron masthead"></div>
<div class="container">
<!-- Main hero unit for a primary marketing message or call to action -->
<div class="hero-unit">
<h1>Hello, world!</h1>
<p>This is a template for a simple marketing or informational website. It includes a large callout called the hero unit and three supporting pieces of content. Use it as a starting point to create something more unique.</p>
<p><a href="#" class="btn btn-primary btn-large">Learn more &raquo;</a></p>
<p>This is a template for a simple workflow manager website. It includes a large callout called the hero unit and three supporting pieces of content. Use it as a starting point to create something more unique.</p>
<p><a target="_blank" href="https://mulcyber.toulouse.inra.fr/plugins/mediawiki/wiki/jflow/index.php/Accueil" class="btn btn-primary btn-large">Learn more &raquo;</a></p>
</div>
<!-- Example row of columns -->
<div class="row">
<div class="span4">
<h2>Heading</h2>
<p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. </p>
<p><a class="btn" href="#">View details &raquo;</a></p>
<div class="span6">
<div class="page-header">
<h1>Available workflows <small>to run</small></h1>
</div>
<div id="available-workflows-list"></div>
</div>
<div class="span4">
<h2>Heading</h2>
<p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. </p>
<p><a class="btn" href="#">View details &raquo;</a></p>
<div class="span6">
<div class="page-header">
<h1>Actives workflows <small>to monitor</small></h1>
</div>
<div class="span4">
<h2>Heading</h2>
<p>Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p>
<p><a class="btn" href="#">View details &raquo;</a></p>
<div id="actives-workflows-list"></div>
</div>
</div>
<!-- setAndRunModal -->
<div id="setAndRunModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="setAndRunModalLabel" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="setAndRunModalLabel"></h3>
</div>
<div id="setAndRunModalBody" class="modal-body"></div>
<div class="modal-footer">
<button class="btn"><i class="icon-refresh"></i> Reset</button>
<button id="run_workflow" class="btn btn-primary"><i class="icon-cog icon-white"></i> Run</button>
</div>
</div>
<!-- statusModal -->
<div id="statusModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="statusModalLabel" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="statusModalLabel"></h3>
</div>
<div id="statusModalBody" class="modal-body"></div>
<div class="modal-footer">
<button class="btn"><i class="icon-refresh"></i> Reset</button>
<button id="rerun_workflow" class="btn btn-primary"><i class="icon-cog icon-white"></i> ReRun</button>
</div>
</div>
<div id="target"></div>
<div id="target2"></div>
<div id="target3"></div>
<hr>
<footer>
<p>&copy; Company 2013</p>
<p>PF bioinformatic GenoToul 2013</p>
</footer>
</div> <!-- /container -->
......@@ -121,14 +127,58 @@
<script src="http://twitter.github.com/bootstrap/assets/js/bootstrap-affix.js"></script>
<script src='jquery.tmpl.min.js' type='text/javascript'></script>
<script src='jflow.js' type='text/javascript'></script>
<script type='text/javascript'>
$(document).ready(function(){
$("#target").jflow({
$("#run_workflow").click(function() {
var params = "";
$.each ( $('#workflow_form').serializeArray(), function(_, kv) {
params += kv.name + "=" +kv.value + "&";
});
$.ajax({
url: 'http://localhost:8080/run_workflow?'+params+'callback=?',
dataType: "json",
success: function(data) {
alert("runnnnnnnnnnn");
}
});
});
$("#available-workflows-list").jflow({
jflowServerWebPath: "http://localhost:8080",
view: "workflowsList",
availableWorkflowsList: {
setAndRunCallback: function(workflow) {
$('#setAndRunModalLabel').html(workflow["name"] + " <small>" + workflow["help"] + "</small>");
$('#setAndRunModalBody').jflow({
jflowServerWebPath: "http://localhost:8080",
view: "workflowForm",
workflowForm: {
workflow_class: workflow["class"]
}
});
$('#setAndRunModal').modal();
}
}
});
$("#actives-workflows-list").jflow({
jflowServerWebPath: "http://localhost:8080",
template: "workflowForm",
workflow_class: "R454"
view: "activeWorkflowsList",
activeWorkflowsList: {
viewCallback: function(workflow) {
$('#statusModalLabel').html(workflow["id"] + " <small>" + workflow["status"] + "</small>");
$('#statusModal').modal();
}
}
});
});
</script>
</body>
</html>
\ No newline at end of file
......@@ -25,27 +25,82 @@
var JFLOW_CONTAINER_PREFIX = "jflow_container_";
var defaults = {
jflowServerWebPath: "http://localhost:8080",
template: "workflowsList",
workflow_class: null,
workflowsList: ['{{each(index, workflow) workflows}}',
'<blockquote>',
'<p>${workflow.name}</p>',
'<small>${workflow.help}</small>',
'</blockquote>',
'{{/each}}'].join('\n'),
workflowForm: ['<form class="form-horizontal">',
view: "workflowsList",
template: "basic",
availableWorkflowsList: {
templates: {
basic: ['<table class="table table-striped table-striped">',
'<thead>',
'<tr>',
'<th>Name</th>',
'<th>Description</th>',
'</tr>',
'</thead>',
'{{each(index, workflow) workflows}}',
'<tr>',
'<td><a id="set_and_run_${workflow.class}" href="#">${workflow.name}</a></td>',
'<td>${workflow.help}</td>',
'</tr>',
'{{/each}}',
'</dl>'].join('\n')
},
setAndRunCallback: function(workflow) { alert("clicking on " + workflow.name); }
},
activeWorkflowsList: {
templates: {
basic: ['<table class="table table-striped table-striped">',
'<thead>',
'<tr>',
'<th>ID<th>',
'<th>Name</th>',
'<th>Status</th>',
'<th>Start time</th>',
'<th>End time</th>',
'</tr>',
'</thead>',
'{{each(index, workflow) workflows}}',
'<tr>',
'<td><a id="monitor_${workflow.id}" href="#">${workflow.id}</a><td>',
'<td>${workflow.name}</td>',
'{{if workflow.status == "completed"}}',
'<td> <span class="label label-success">${workflow.status}</span></td>',
'{{else workflow.status == "aborted"}}',
'<td> <span class="label label-important">${workflow.status}</span></td>',
'{{else workflow.status == "started"}}',
'<td> <span class="label label-info">${workflow.status}</span></td>',
'{{else}}',
'<td>${workflow.status}</td>',
'{{/if}}',
'<td>${workflow.start_time}</td>',
'<td>${workflow.end_time}</td>',
'</tr>',
'{{/each}}',
'</table>'].join('\n')
},
viewCallback: function(workflow) { alert("clicking on " + workflow.id); }
},
/**
* Workflow form template
*
* @param service:
* @param service:
*/
workflowForm: {
templates: {
basic: ['<form id="workflow_form" class="form-horizontal">',
'<fieldset>',
' <div id="legend" class="">',
' <legend class="">${workflow.name} <small>${workflow.help}</small></legend>',
' </div>',
' {{each(index, param) workflow.parameters}}',
' <div class="control-group">',
' <label class="control-label">${param.name}</label>',
' <div class="controls">',
// if it's a multiple choice parameter, add a select
' {{if param.choices}}',
' <select class="input-xlarge">',
' <select name="${param.name}" class="input-xlarge">',
' {{each(j, choice) param.choices}}',
' {{if choice == param.default}}',
' <option selected>${choice}</option>',
......@@ -56,45 +111,56 @@
' </select>',
// else a simple text input
' {{else}}',
' <input placeholder="${param.default}" class="input-xlarge" type="text">',
' <input name="${param.name}" value="${param.default}" class="input-xlarge" type="text">',
' {{/if}}',
' <p class="help-block">${param.help}</p>',
' </div>',
' </div>',
' {{/each}}',
' <div class="control-group">',
' <label class="control-label"></label>',
' <div class="controls">',
' <div class="btn-toolbar">',
' <div class="btn-group">',
' <a class="btn" href="#"><i class="icon-refresh"></i>Reset</a>',
' <a class="btn btn-primary" href="#"><i class="icon-cog icon-white"></i> Run</a>',
' </div>',
' </div>',
' </div>',
' </div>',
// for all workflow add the workflow_class
' <input name="workflow_class" value="${workflow.class}" type="hidden">',
'</fieldset>',
'</form>'].join('\n'),
errorTemplate: ['<div class="alert alert-error">',
'<button type="button" class="close" data-dismiss="alert">&times;</button>',
'<strong>${title}</strong> ${message}',
'</div>'].join('\n')
'</form>'].join('\n')
},
workflow_class: null,
run_function: function() {
alert(run);
}
}
};
var opts = $.extend(defaults, options);
var opts = $.extend(true, defaults, options);
var _displayWorkflowsList = function(div) {
var _generateAvailableWorkflowsListView = function(div) {
$.ajax({
url: opts.jflowServerWebPath + '/get_available_workflows?callback=?',
dataType: "json",
success: function(data) {
$.tmpl(opts["workflowsList"], {workflows: data}).appendTo(div);
var workflow_by_class = {};
for (var i in data) {
workflow_by_class[data[i]["class"]] = data[i];
}
$.tmpl(opts["availableWorkflowsList"].templates[opts.template], {workflows: data}).appendTo(div);
$("[id^=set_and_run_]").click(function(){
var workflow_class = $(this).attr("id").split("set_and_run_")[1];
opts.availableWorkflowsList.setAndRunCallback(workflow_by_class[workflow_class]);
});
}
});
}
var _run_workflow = function() {
$.ajax({
url: opts.jflowServerWebPath + '/run_workflow?callback=?',
dataType: "json",
success: function(data) {
alert("runnnnnnnnnnn");
}
});
}
var _displayWorkflowForm = function(div) {
if (opts.workflow_class == null) {
$.tmpl(opts["errorTemplate"], {"title": "Error!", "message": "workflow_class option is required."}).appendTo(div);
var _generateWorkflowFormView = function(div) {
if (opts.workflowForm.workflow_class == null) {
alert("error")
} else {
$.ajax({
url: opts.jflowServerWebPath + '/get_available_workflows?callback=?',
......@@ -102,15 +168,33 @@
success: function(data) {
var workflow = null;
for (var i in data) {
if (data[i]["class"] == opts.workflow_class) {
if (data[i]["class"] == opts.workflowForm.workflow_class) {
workflow = data[i];
break;
}
}
$.tmpl(opts["workflowForm"], {workflow: workflow}).appendTo(div);
$.tmpl(opts["workflowForm"].templates[opts.template], {workflow: workflow}).appendTo(div);
}
});
}
}
var _generateActiveWorkflowsListView = function(div) {
$.ajax({
url: opts.jflowServerWebPath + '/get_workflows_status?callback=?',
dataType: "json",
success: function(data) {
var workflow_by_id = {};
for (var i in data) {
workflow_by_id[data[i]["id"]] = data[i];
}
$.tmpl(opts["activeWorkflowsList"].templates[opts.template], {workflows: data}).appendTo(div);
$("[id^=monitor_]").click(function(){
var workflow_id = $(this).attr("id").split("monitor_")[1];
opts.activeWorkflowsList.viewCallback(workflow_by_id[workflow_id]);
});
}
});
}
this.each(function() {
......@@ -127,12 +211,15 @@
}
$t.html('<div id="'+JFLOW_CONTAINER_PREFIX+index.toString()+'"></div>');
var $div = $("#"+JFLOW_CONTAINER_PREFIX+index.toString());
switch (opts.template) {
switch (opts.view) {
case "workflowForm":
_displayWorkflowForm($div);
_generateWorkflowFormView($div);
break;
case "activeWorkflowsList":
_generateActiveWorkflowsListView($div);
break;
default:
_displayWorkflowsList($div);
_generateAvailableWorkflowsListView($div);
break
}
});
......
......@@ -89,6 +89,23 @@ class JFlowServer (object):
return status
def extend_parameters(self, workflow_class, kwargs):
extended_kwargs = {}
workflow = self.wfmanager.get_workflow_by_class(workflow_class)
for param in workflow.parameters:
# if it's an append parameter, the result should be a list
if param.action == "append":
if kwargs.has_key(param.name):
extended_kwargs[param.name] = kwargs[param.name].split(",")
else:
extended_kwargs[param.name] = []
else:
if kwargs.has_key(param.name):
extended_kwargs[param.name] = kwargs[param.name]
else:
extended_kwargs[param.name] = param.default
return extended_kwargs
@cherrypy.expose
@jsonify
def get_available_workflows(self, **kwargs):
......@@ -111,9 +128,8 @@ class JFlowServer (object):
@cherrypy.expose
@jsonify
def run_workflow(self, **kwargs):
print kwargs
return [{"return": "sdsdsd"}]
# self.wfmanager.run_workflow(workflow_class, args, True)
args = self.extend_parameters(kwargs["workflow_class"], kwargs)
self.wfmanager.run_workflow(kwargs["workflow_class"], args)
@cherrypy.expose
@jsonify
......
......@@ -88,6 +88,16 @@ class WorkflowsManager(object):
except: pass
return workflows
def get_workflow_by_class(self, workflow_class):
# Load all modules within the workflow module
for importer, modname, ispkg in pkgutil.iter_modules(workflows.__path__, workflows.__name__ + "."):
__import__(modname)
# Search for Workflow classes
for class_name, obj in inspect.getmembers(sys.modules[modname], inspect.isclass):
if class_name == workflow_class:
return obj()
return None
def get_workflow(self, workflow_id):
from jflow.workflow import Workflow
search_directory = self.WF_DIRECTORY_PREFIX + utils.get_nb_string(workflow_id)
......
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