From d1a4f9b42909948de7958c9a344ca8683331e73d Mon Sep 17 00:00:00 2001 From: baigner <benedikt.aigner@rwth-aachen.de> Date: Wed, 4 Jul 2018 15:18:23 +0200 Subject: [PATCH] VISTOMS update: Implemented possibility to create graphs from scratch using a template cmdows file. CAUTION: Currently, adding competence blocks to that new graph does only work for mathematical functions, not for DCs. Former-commit-id: 28f7d78a634343118d18486372f6ab2594d1c181 --- kadmos/vistoms/interface_vistoms.py | 110 ++- kadmos/vistoms/templates/VISTOMS.html | 129 ++- .../vistoms/templates/VISTOMS_sessions.html | 858 ++++++++++-------- kadmos/vistoms/templates/cmdows_template.xml | 42 + kadmos/vistoms/vistoms.py | 47 +- 5 files changed, 776 insertions(+), 410 deletions(-) create mode 100644 kadmos/vistoms/templates/cmdows_template.xml diff --git a/kadmos/vistoms/interface_vistoms.py b/kadmos/vistoms/interface_vistoms.py index f8985f819..5ab32f710 100644 --- a/kadmos/vistoms/interface_vistoms.py +++ b/kadmos/vistoms/interface_vistoms.py @@ -1,8 +1,10 @@ import ast +import fnmatch import json import logging import os import shutil +import sys import tempfile import time import uuid @@ -233,6 +235,50 @@ def interface(debug=True, tempdir=None): return "ERROR: " + e.message # Logs the error appropriately. + + @app.route('/kadmos_create_new_graph', methods=['POST']) + def kadmos_create_new_graph(): + try: + # Get request form + graph_name = request.form['graph_name'] + graph_description = request.form['graph_description'] + sessionID = request.form['sessionID'] + upload_folder = UPLOAD_FOLDERS[sessionID] + + # Open cmdows template file and load it as graph + cmdows_template = os.path.join('templates', 'cmdows_template.xml') + graph_template = load(cmdows_template, check_list=['consistent_root', 'invalid_leaf_elements']) + + # Determine graph_id + graph_ids = [] + for aFile in os.listdir(upload_folder): + if aFile.endswith('.kdms'): + filename = aFile.split('.kdms')[0] + graph_ids.append(int(filename.split('_')[1])) + graph_id_int = max(graph_ids)+1 + graph_id = format(graph_id_int, "02") + + # Allocate graph name, description and id + graph_template.graph['name'] = graph_name + graph_template.graph['description'] = graph_description + graph_template.graph['id'] = graph_id + + # Delete dummy design competence + graph_template.remove_node('dummy') + + # Save empty graph as kdms file + graph_template.save(os.path.join(upload_folder, 'tmp_'+graph_id+'.kdms'), file_type='kdms', graph_check_critical=False, mpg=None) + + # Add graph to vistoms data + newVistomsData = graph_template.vistoms_add_json(mpg=None, graph_id=graph_id) + + return newVistomsData + + except Exception as e: + return "ERROR: " + e.message + # Logs the error appropriately. + + @app.route('/kadmos_export_all_graphs', methods=['POST']) def kadmos_export_all_graphs(): """ @@ -527,32 +573,32 @@ def interface(debug=True, tempdir=None): backupGraphFileName = TEMP_FILE + '_' + graphID + '_backup.kdms' backupMpgFileName = TEMP_FILE + '_' + graphID + '_backup_mpg.kdms' - graph = load(os.path.join(tmpDir, graphFileName), file_check_critical=False) - backupGraph = load(os.path.join(tmpDir, backupGraphFileName), file_check_critical=False) - if os.path.exists(os.path.join(tmpDir, mpgFileName)): - mpg = load(os.path.join(tmpDir, mpgFileName), file_check_critical=False) - os.remove(os.path.join(tmpDir, mpgFileName)) - else: - mpg = None - - if os.path.exists(os.path.join(tmpDir, backupMpgFileName)): - backupMpg = load(os.path.join(tmpDir, backupMpgFileName), file_check_critical=False) - os.remove(os.path.join(tmpDir, backupMpgFileName)) - else: - backupMpg = None - - # Switch graph and backup graph (What used to be the backup graph is now the new graph and vice versa) - graph.save(os.path.join(upload_folder, backupGraphFileName), file_type="kdms", graph_check_critical=False, - mpg=mpg) - backupGraph.save(os.path.join(upload_folder, graphFileName), file_type="kdms", graph_check_critical=False, - mpg=backupMpg) - - # Get function_oder of the backup graph - function_order = None - if backupGraph.graph_has_nested_attributes('problem_formulation', 'function_order'): - function_order = backupGraph.graph['problem_formulation']['function_order'] - - newVistomsData = backupGraph.vistoms_add_json(function_order=function_order, mpg=backupMpg, graph_id=graphID) + graph = load(os.path.join(tmpDir, graphFileName), file_check_critical=False) + backupGraph = load(os.path.join(tmpDir, backupGraphFileName), file_check_critical=False) + if os.path.exists(os.path.join(tmpDir, mpgFileName)): + mpg = load(os.path.join(tmpDir, mpgFileName), file_check_critical=False) + os.remove(os.path.join(tmpDir, mpgFileName)) + else: + mpg = None + + if os.path.exists(os.path.join(tmpDir, backupMpgFileName)): + backupMpg = load(os.path.join(tmpDir, backupMpgFileName), file_check_critical=False) + os.remove(os.path.join(tmpDir, backupMpgFileName)) + else: + backupMpg = None + + # Switch graph and backup graph (What used to be the backup graph is now the new graph and vice versa) + graph.save(os.path.join(upload_folder, backupGraphFileName), file_type="kdms", graph_check_critical=False, + mpg=mpg) + backupGraph.save(os.path.join(upload_folder, graphFileName), file_type="kdms", graph_check_critical=False, + mpg=backupMpg) + + # Get function_oder of the backup graph + function_order = None + if backupGraph.graph_has_nested_attributes('problem_formulation', 'function_order'): + function_order = backupGraph.graph['problem_formulation']['function_order'] + + newVistomsData = backupGraph.vistoms_add_json(function_order=function_order, mpg=backupMpg, graph_id=graphID) return newVistomsData @@ -583,10 +629,10 @@ def interface(debug=True, tempdir=None): def delete_backup_graphs(upload_folder): """ Function deletes all graphs that end with a _backup - """ - for file in os.listdir(upload_folder): - if fnmatch.fnmatch(file, '*_backup*'): - os.remove(os.path.join(upload_folder, file)) + """ + for file in os.listdir(upload_folder): + if fnmatch.fnmatch(file, '*_backup*'): + os.remove(os.path.join(upload_folder, file)) ######################################################################################################################## @@ -972,7 +1018,9 @@ def interface(debug=True, tempdir=None): try: # Get request form graphID = request.form['graphID'] - function_order = request.form['currentOrder'].split(',') + function_order = [] + if request.form['currentOrder'] != '': + function_order = request.form['currentOrder'].split(',') form_data_str = request.form['form_data'] # convert stringified data into python objects/arrays/.. with json.loads function diff --git a/kadmos/vistoms/templates/VISTOMS.html b/kadmos/vistoms/templates/VISTOMS.html index 120c2acf2..89ee0900c 100644 --- a/kadmos/vistoms/templates/VISTOMS.html +++ b/kadmos/vistoms/templates/VISTOMS.html @@ -261,9 +261,115 @@ //############################################################## + + function createNewGraph(theData, theCurrentGraph=null) + { + bootbox.hideAll(); + + var html = d3.select("html") + var form_content = html.append("div").attr("class","form-content").attr("style","display:none") + var form = form_content.append("form").attr("class","form").attr("role","form") + var form_group, input; + + //Tool information + form_group = form.append("div").attr("class","form-group") + form_group.append("text").text("Name") + input = form_group.append("input") + .attr("id","graph_name") + .attr("class","form-control") + .attr("name","graph_name") + .attr("placeholder","Add a graph name here...") + //Tool information + form_group = form.append("div").attr("class","form-group") + form_group.append("text").text("Description") + input = form_group.append("input") + .attr("id","graph_description") + .attr("class","form-control") + .attr("name","graph_description") + .attr("placeholder","Add a graph description here...") + + var modal = bootbox.dialog({ + message: $(".form-content").html(), + title: "Create new graph", + size: "large", + buttons: [ + { + label: "Cancel", + className: "btn btn-default pull-left", + callback: function() { + modal.modal("hide"); + d3.selectAll(".form-content").remove(); + } + }, + { + label: "OK", + className: "btn btn-primary pull-left", + callback: function() { + + //get form data + var graph_name = $('form #graph_name').val(); + var graph_description = $('form #graph_description').val(); + + + var bootboxContent = {title: "Create new graph", message: '<p>Please be patient...</p>'}; + var xhr = $.ajax({ + type: 'POST', + url: '/kadmos_create_new_graph', + data: {'graph_name':graph_name, 'graph_description':graph_description}, + success: function(result) + { + if (result.includes("ERROR:")) + { + bootboxContent.message = result + kadmosErrorMessage(bootboxContent); + } + else + { + var updatedData = {}; + if (theData != "REP__GRAPH_DATA__REP") + { + updatedData = theData; + var graphData = JSON.parse(result); + updatedData.graphs.push(graphData.graphs[0]); + } + else + { + updatedData = JSON.parse(result); + } + + clearView(); + makeKadmosMenu(updatedData); + mainPage(); + + bootboxContent.message = "Success!" + kadmosSuccessMessage(bootboxContent) + } + }, + error: function(result) + { + bootboxContent.message = result + kadmosErrorMessage(bootboxContent); + } + }); + kadmosHavePatience(xhr, bootboxContent) + modal.modal("hide"); + d3.selectAll(".form-content").remove(); + } + } + ], + onEscape: function() { + modal.modal("hide"); + d3.selectAll(".form-content").remove(); + } + }); + + } + + //aigner: HIER WEITER!!! - function addDesignCompetence() + function addDesignCompetence(theData, theCurrentGraph=null) { + console.log(data) bootbox.hideAll(); var html = d3.select("html") @@ -324,10 +430,10 @@ } - var bootboxContent = {title: "Add mathematical function", message: '<p>Please be patient...</p>'}; + var bootboxContent = {title: "Add design competence", message: '<p>Please be patient...</p>'}; var xhr = $.ajax({ type: 'POST', - url: '/kadmos_add_mathematical_function', + url: '/kadmos_add_design_competence', data: {'graphID':graphID, 'currentOrder':nodeOrder, 'form_data':JSON.stringify(form_data)}, success: function(result) { @@ -339,7 +445,7 @@ else { var updatedData = {}; - updatedData = data; + updatedData = theData; var graphData = JSON.parse(result); for (var i = 0; i < updatedData.graphs.length; i++) { @@ -367,6 +473,9 @@ kadmosHavePatience(xhr, bootboxContent) modal.modal("hide"); d3.selectAll(".form-content").remove(); + + //aigner: After the competence has been added, add metadata for the competence + addDCMetadata(data,theCurrentGraph) } } ], @@ -379,7 +488,7 @@ } //aigner: HIER WEITER!!! --> Add contacts if not already existing - function addDCMetadata(theCurrentGraph, aNode=null) + function addDCMetadata(theData, theCurrentGraph, aNode=null) { bootbox.hideAll(); @@ -568,7 +677,7 @@ else { var updatedData = {}; - updatedData = data; + updatedData = theData; var graphData = JSON.parse(result); for (var i = 0; i < updatedData.graphs.length; i++) { @@ -985,7 +1094,7 @@ .text("Go!") submit.on("mousedown", function() { - addDesignCompetence(); + createNewGraph(data); }) } else if (include(selectValue,"KDMS")) @@ -19532,7 +19641,7 @@ } } varCategories = data.categories; - + //aigner: Get xdsm data var mdo = currentGraph.xdsm; @@ -20083,7 +20192,7 @@ { title: 'Add metadata', onMouseDown: function(elm, k, i) { - addDCMetadata(currentGraph,k) + addDCMetadata(data,currentGraph,k) //sendDCMetadata(dc_metadata); }, onMouseUp: function(elm, k, i) { @@ -20551,7 +20660,7 @@ } else if(result == "dc") { - addDesignCompetence(); + addDesignCompetence(data, currentGraph); } else; } diff --git a/kadmos/vistoms/templates/VISTOMS_sessions.html b/kadmos/vistoms/templates/VISTOMS_sessions.html index 70762c897..422e3de9c 100644 --- a/kadmos/vistoms/templates/VISTOMS_sessions.html +++ b/kadmos/vistoms/templates/VISTOMS_sessions.html @@ -32,6 +32,10 @@ alert("OOPS! VISTOMS unfortunately does not work properly on " + bowser.name + ". Please use a different browser to see its awesome visualization features!") } + //aigner: Include function + function include(arr,obj) { + return (arr.indexOf(obj) != -1); + } //aigner: Move to front function d3.selection.prototype.moveToFront = function() { @@ -257,6 +261,469 @@ //############################################################## + + function createNewGraph(theData, theCurrentGraph=null) + { + bootbox.hideAll(); + + var html = d3.select("html") + var form_content = html.append("div").attr("class","form-content").attr("style","display:none") + var form = form_content.append("form").attr("class","form").attr("role","form") + var form_group, input; + + //Tool information + form_group = form.append("div").attr("class","form-group") + form_group.append("text").text("Name") + input = form_group.append("input") + .attr("id","graph_name") + .attr("class","form-control") + .attr("name","graph_name") + .attr("placeholder","Add a graph name here...") + //Tool information + form_group = form.append("div").attr("class","form-group") + form_group.append("text").text("Description") + input = form_group.append("input") + .attr("id","graph_description") + .attr("class","form-control") + .attr("name","graph_description") + .attr("placeholder","Add a graph description here...") + + var modal = bootbox.dialog({ + message: $(".form-content").html(), + title: "Create new graph", + size: "large", + buttons: [ + { + label: "Cancel", + className: "btn btn-default pull-left", + callback: function() { + modal.modal("hide"); + d3.selectAll(".form-content").remove(); + } + }, + { + label: "OK", + className: "btn btn-primary pull-left", + callback: function() { + + //get form data + var graph_name = $('form #graph_name').val(); + var graph_description = $('form #graph_description').val(); + + + var bootboxContent = {title: "Create new graph", message: '<p>Please be patient...</p>'}; + var xhr = $.ajax({ + type: 'POST', + url: '/kadmos_create_new_graph', + data: {'graph_name':graph_name, 'graph_description':graph_description, 'sessionID':sessionID}, + success: function(result) + { + if (result.includes("ERROR:")) + { + bootboxContent.message = result + kadmosErrorMessage(bootboxContent); + } + else + { + var updatedData = {}; + if (theData != "REP__GRAPH_DATA__REP") + { + updatedData = theData; + var graphData = JSON.parse(result); + updatedData.graphs.push(graphData.graphs[0]); + } + else + { + updatedData = JSON.parse(result); + } + + clearView(); + makeKadmosMenu(updatedData); + mainPage(); + + bootboxContent.message = "Success!" + kadmosSuccessMessage(bootboxContent) + } + }, + error: function(result) + { + bootboxContent.message = result + kadmosErrorMessage(bootboxContent); + } + }); + kadmosHavePatience(xhr, bootboxContent) + modal.modal("hide"); + d3.selectAll(".form-content").remove(); + } + } + ], + onEscape: function() { + modal.modal("hide"); + d3.selectAll(".form-content").remove(); + } + }); + + } + + + //aigner: HIER WEITER!!! + function addDesignCompetence(theData, theCurrentGraph=null) + { + console.log(data) + bootbox.hideAll(); + + var html = d3.select("html") + var form_content = html.append("div").attr("class","form-content").attr("style","display:none") + var form = form_content.append("form").attr("class","form").attr("role","form") + var form_group, input; + + //Tool information + form_group = form.append("div").attr("class","form-group") + form_group.append("text").text("Name") + input = form_group.append("input") + .attr("id","function_node") + .attr("class","form-control") + .attr("name","function_node") + .attr("placeholder","Add a tool name here...") + //Tool input xml + form_group = form.append("div").attr("class","form-group") + form_group.append("text").text("Tool input XML") + input = form_group.append("input") + .attr("type","file") + .attr("id","input_xml") + .attr("name","input_xml") + //Tool output xml + form_group = form.append("div").attr("class","form-group") + form_group.append("text").text("Tool output XML") + input = form_group.append("input") + .attr("type","file") + .attr("id","output_xml") + .attr("name","output_xml") + + + var modal = bootbox.dialog({ + message: $(".form-content").html(), + title: "Add design competence", + size: "large", + buttons: [ + { + label: "Cancel", + className: "btn btn-default pull-left", + callback: function() { + modal.modal("hide"); + d3.selectAll(".form-content").remove(); + } + }, + { + label: "OK", + className: "btn btn-primary pull-left", + callback: function() { + + //get form data + var form_data = { + function_node: $('form #function_node').val(), + input_nodes_xPath: $('form #input_nodes_xPath').val(), + input_nodes_name: $('form #input_nodes_name').val(), + output_node_xPath: $('form #output_node_xPath').val(), + equation: $('form #equation').val(), + language: $('form #language').val() + } + + + var bootboxContent = {title: "Add design competence", message: '<p>Please be patient...</p>'}; + var xhr = $.ajax({ + type: 'POST', + url: '/kadmos_add_design_competence', + data: {'graphID':graphID, 'currentOrder':nodeOrder, 'form_data':JSON.stringify(form_data), 'sessionID:sessionID}, + success: function(result) + { + if (result.includes("ERROR:")) + { + bootboxContent.message = result + kadmosErrorMessage(bootboxContent); + } + else + { + var updatedData = {}; + updatedData = theData; + var graphData = JSON.parse(result); + for (var i = 0; i < updatedData.graphs.length; i++) + { + if (graphID == updatedData.graphs[i].id) + { + updatedData.graphs[i] = graphData.graphs[0]; + } + } + + clearView(); + makeKadmosMenu(updatedData); + xdsm_script(updatedData,graphID); + + bootboxContent.message = "Success!" + kadmosSuccessMessage(bootboxContent) + } + }, + error: function(result) + { + bootboxContent.message = result + kadmosErrorMessage(bootboxContent); + } + }); + kadmosHavePatience(xhr, bootboxContent) + kadmosHavePatience(xhr, bootboxContent) + modal.modal("hide"); + d3.selectAll(".form-content").remove(); + + //aigner: After the competence has been added, add metadata for the competence + addDCMetadata(data,theCurrentGraph) + } + } + ], + onEscape: function() { + modal.modal("hide"); + d3.selectAll(".form-content").remove(); + } + }); + + } + + //aigner: HIER WEITER!!! --> Add contacts if not already existing + function addDCMetadata(theData, theCurrentGraph, aNode=null) + { + bootbox.hideAll(); + + var metadata; + if (aNode != null) + { + metadata = aNode.metadata; + } + + var html = d3.select("html") + var form_content = html.append("div").attr("class","form-content").attr("style","display:none") + var form = form_content.append("form").attr("class","form").attr("role","form") + var form_group, input; + + //General information + form_group = form.append("div").attr("class","form-group") + form_group.append("label").text("General information") + form_group = form.append("div").attr("class","form-group") + form_group.append("text").text("Description") + input = form_group.append("textarea") + .attr("id","description") + .attr("class","form-control") + .attr("name","description") + .attr("placeholder","Add a description for the DC here") + + form_group = form.append("div").attr("class","form-group") + form_group.append("text").text("Status") + input = form_group.append("select").attr("id","status").style("margin-left","5px") + input.append("option").attr("type","select").attr("value","-").text("Please select...") + input.append("option").attr("type","select").attr("value","Available").text("Available") + input.append("option").attr("type","select").attr("value","N/A").text("N/A") + var contacts = [] + if (theCurrentGraph.organization.contacts){contacts=theCurrentGraph.organization.contacts}; + console.log(theCurrentGraph) + form_group = form.append("div").attr("class","form-group") + form_group.append("text").text("Owner") + input = form_group.append("select").attr("id","owner_uid").style("margin-left","5px") + input.append("option").attr("type","select").attr("value","-").text("Please select...") + contacts.forEach(function(contact){ + input.append("option").attr("type","select").attr("value",contact.attrib.uID).text(contact.name + " (" + contact.company + ")") + }) + form_group = form.append("div").attr("class","form-group") + form_group.append("text").text("Creator") + input = form_group.append("select").attr("id","creator_uid").style("margin-left","5px") + input.append("option").attr("type","select").attr("value","-").text("Please select...") + contacts.forEach(function(contact){ + input.append("option").attr("type","select").attr("value",contact.attrib.uID).text(contact.name + " (" + contact.company + ")") + }) + form_group = form.append("div").attr("class","form-group") + form_group.append("text").text("Operator") + input = form_group.append("select").attr("id","operator_uid").style("margin-left","5px") + input.append("option").attr("type","select").attr("value","-").text("Please select...") + contacts.forEach(function(contact){ + input.append("option").attr("type","select").attr("value",contact.attrib.uID).text(contact.name + " (" + contact.company + ")") + }) + + + //Information on tool execution + form_group = form.append("div").attr("class","form-group").style("margin-top","40px") + form_group.append("label").text("Execution information") + form_group = form.append("div").attr("class","form-group") + form_group.append("text").text("Operating System") + input = form_group.append("select").attr("id","operating_system").style("margin-left","5px") + input.append("option").attr("type","select").attr("value","-").text("Please select...") + input.append("option").attr("type","select").attr("value","windows").text("Windows") + input.append("option").attr("type","select").attr("value","linux").text("Linux") + input.append("option").attr("type","select").attr("value","mac").text("Mac OS") + input.append("option").attr("type","select").attr("value","other").text("Other") + form_group = form.append("div").attr("class","form-group") + form_group.append("text").text("Integration platform") + input = form_group.append("input") + .attr("id","integration_platform") + .attr("class","form-control") + .attr("name","integration_platform") + .attr("placeholder","Integration platform (e.g. RCE, Optimus)") + form_group = form.append("div").attr("class","form-group") + form_group.append("text").text("Execution command") + input = form_group.append("textarea") + .attr("id","command") + .attr("class","form-control") + .attr("cols","40") + .attr("rows","5") + .attr("name","command") + .attr("placeholder","Execution command") + form_group = form.append("div").attr("class","form-group") + input = form_group.append("input") + .attr("id","description_cmd") + .attr("class","form-control") + .attr("name","description_cmd") + .attr("placeholder","Details on the exectuion command (optional)") + form_group = form.append("div").attr("class","form-group") + input = form_group.append("input") + .attr("id","software_requirements") + .attr("class","form-control") + .attr("name","software_requirements") + .attr("placeholder","Software requirements") + form_group = form.append("div").attr("class","form-group") + input = form_group.append("input") + .attr("id","hardware_requirements") + .attr("class","form-control") + .attr("name","hardware_requirements") + .attr("placeholder","Hardware requirements") + + //Information on tool licensing + form_group = form.append("div").attr("class","form-group").style("margin-top","40px") + form_group.append("label").text("License information (optional)") + input = form_group.append("input") + .attr("id","license_type") + .attr("class","form-control") + .attr("name","license_type") + .attr("placeholder","License type (e.g. open-source, commercial)") + form_group = form.append("div").attr("class","form-group") + input = form_group.append("input") + .attr("id","license_specification") + .attr("class","form-control") + .attr("name","license_specification") + .attr("placeholder","License specification (e.g. Apache License 2.0)") + form_group = form.append("div").attr("class","form-group") + input = form_group.append("input") + .attr("id","license_info") + .attr("class","form-control") + .attr("name","license_info") + .attr("placeholder","License information (e.g. https://www.apache.org/licenses/LICENSE-2.0)") + + //Information on tool sources + form_group = form.append("div").attr("class","form-group").style("margin-top","40px") + form_group.append("label").text("Source information (optional)") + input = form_group.append("input") + .attr("id","repository_link") + .attr("class","form-control") + .attr("name","repository_link") + .attr("placeholder","Repository link") + form_group = form.append("div").attr("class","form-group") + input = form_group.append("input") + .attr("id","download_link") + .attr("class","form-control") + .attr("name","download_link") + .attr("placeholder","Download link") + form_group = form.append("div").attr("class","form-group") + input = form_group.append("input") + .attr("id","references") + .attr("class","form-control") + .attr("name","references") + .attr("placeholder","References") + + + var modal = bootbox.dialog({ + message: $(".form-content").html(), + title: "Add Competence Metadata", + size: "large", + buttons: [ + { + label: "Cancel", + className: "btn btn-default pull-left", + callback: function() { + modal.modal("hide"); + d3.selectAll(".form-content").remove(); + } + }, + { + label: "OK", + className: "btn btn-primary pull-left", + callback: function() { + var metadata = { + uID: aNode.uID, + description: $('form #description').val(), + status: $('form #status').val(), + owner_uid: $('form #owner_uid').val(), + creator_uid: $('form #creator_uid').val(), + operator_uid: $('form #operator_uid').val() + } + var metadata_str = JSON.stringify(metadata) + var bootboxContent = {title: "Get graph elements", message: '<p>Please be patient...</p>'}; + var xhr = $.ajax( + { + type: 'POST', + url: '/kadmos_add_DC_metadata', + data: {'graphID':graphID, 'sessionID':sessionID, 'currentOrder':nodeOrder, 'nodeName':metadata.uID, 'metadata_str':metadata_str}, + success: function(result) + { + if (result.includes("ERROR:")) + { + bootboxContent.message = result + kadmosErrorMessage(bootboxContent); + } + else + { + var updatedData = {}; + updatedData = theData; + var graphData = JSON.parse(result); + for (var i = 0; i < updatedData.graphs.length; i++) + { + if (graphID == updatedData.graphs[i].id) + { + updatedData.graphs[i] = graphData.graphs[0]; + } + } + + clearView(); + makeKadmosMenu(updatedData); + xdsm_script(updatedData,graphID); + + bootboxContent.message = "Success!" + kadmosSuccessMessage(bootboxContent) + } + }, + error: function(result) + { + bootboxContent.message = result + kadmosErrorMessage(bootboxContent); + } + }); + kadmosHavePatience(xhr, bootboxContent) + modal.modal("hide"); + d3.selectAll(".form-content").remove(); + } + } + ], + onEscape: function() { + modal.modal("hide"); + d3.selectAll(".form-content").remove(); + } + }); + + + } + + function sendDCMetadata(aMetadata) + { + + } + + + + function makeKadmosMenu(data, initial=false) { //First of all, clear everything if it is already there @@ -590,7 +1057,7 @@ .style("display","inline-block") - var options = ["Choose...","KDMS file(s)", "CMDOWS file", "Database"]; + var options = ["Choose...", "Create graph from scratch", "Upload KDMS file(s)", "Upload CMDOWS file", "Upload Database"]; var select = panelBody.append('select') .attr('id','addselect') @@ -614,7 +1081,24 @@ function onchange() { selectValue = d3.select('#addselect').property('value') - if (selectValue == "KDMS file(s)") + if (include(selectValue,"Create")) + { + if (file){ + fileText.remove(); + file.remove(); + } + if (submit){submit.remove();} + submit = label.append("button") + .style("margin-top","10pt") + .attr("type","button") + .attr("class","btn btn-primary") + .text("Go!") + submit.on("mousedown", function() + { + createNewGraph(data); + }) + } + else if (include(selectValue,"KDMS")) { if (file){ fileText.remove(); @@ -628,7 +1112,7 @@ file = label.append("input").attr("type","file").attr("name","file[]").attr("multiple","") submit = label.append("input").attr("type","submit").attr("value","Submit"); } - else if (selectValue == "CMDOWS file") + else if (include(selectValue,"CMDOWS")) { if (file){ fileText.remove(); @@ -642,7 +1126,7 @@ file = label.append("input").attr("type","file").attr("name","file[]") submit = label.append("input").attr("type","submit").attr("value","Submit"); } - else if (selectValue == "Database") + else if (include(selectValue,"Database")) { if (file){ fileText.remove(); @@ -18593,10 +19077,7 @@ this.parentNode.appendChild(this); }); }; - //aigner: Include function - function include(arr,obj) { - return (arr.indexOf(obj) != -1); - } + //d3-context-menu for right-click-option d3.contextMenu = function (menu, openCallback) { @@ -19614,355 +20095,6 @@ - } - - - //aigner: HIER WEITER!!! - function addDesignCompetence() - { - bootbox.hideAll(); - - var html = d3.select("html") - var form_content = html.append("div").attr("class","form-content").attr("style","display:none") - var form = form_content.append("form").attr("class","form").attr("role","form") - var form_group, input; - - //Tool information - form_group = form.append("div").attr("class","form-group") - form_group.append("text").text("Name") - input = form_group.append("input") - .attr("id","function_node") - .attr("class","form-control") - .attr("name","function_node") - .attr("placeholder","Add a tool name here...") - //Tool input xml - form_group = form.append("div").attr("class","form-group") - form_group.append("text").text("Tool input xml") - input = form_group.append("input") - .attr("type","file") - .attr("id","input_xml") - .attr("name","input_xml") - //Tool output xml - form_group = form.append("div").attr("class","form-group") - form_group.append("text").text("Tool output xml") - input = form_group.append("input") - .attr("type","file") - .attr("id","output_xml") - .attr("name","output_xml") - - - var modal = bootbox.dialog({ - message: $(".form-content").html(), - title: "Add mathematical function", - size: "large", - buttons: [ - { - label: "Cancel", - className: "btn btn-default pull-left", - callback: function() { - modal.modal("hide"); - d3.selectAll(".form-content").remove(); - } - }, - { - label: "OK", - className: "btn btn-primary pull-left", - callback: function() { - - //get form data - var form_data = { - function_node: $('form #function_node').val(), - input_nodes_xPath: $('form #input_nodes_xPath').val(), - input_nodes_name: $('form #input_nodes_name').val(), - output_node_xPath: $('form #output_node_xPath').val(), - equation: $('form #equation').val(), - language: $('form #language').val() - } - - - var bootboxContent = {title: "Add mathematical function", message: '<p>Please be patient...</p>'}; - var xhr = $.ajax({ - type: 'POST', - url: '/kadmos_add_mathematical_function', - data: {'graphID':graphID, 'sessionID':sessionID, 'currentOrder':nodeOrder, 'form_data':JSON.stringify(form_data)}, - success: function(result) - { - if (result.includes("ERROR:")) - { - bootboxContent.message = result - kadmosErrorMessage(bootboxContent); - } - else - { - var updatedData = {}; - updatedData = data; - var graphData = JSON.parse(result); - for (var i = 0; i < updatedData.graphs.length; i++) - { - if (graphID == updatedData.graphs[i].id) - { - updatedData.graphs[i] = graphData.graphs[0]; - } - } - - clearView(); - makeKadmosMenu(updatedData); - xdsm_script(updatedData,graphID); - - bootboxContent.message = "Success!" - kadmosSuccessMessage(bootboxContent) - } - }, - error: function(result) - { - bootboxContent.message = result - kadmosErrorMessage(bootboxContent); - } - }); - kadmosHavePatience(xhr, bootboxContent) - kadmosHavePatience(xhr, bootboxContent) - modal.modal("hide"); - d3.selectAll(".form-content").remove(); - } - } - ], - onEscape: function() { - modal.modal("hide"); - d3.selectAll(".form-content").remove(); - } - }); - - } - - function addDCMetadata(aNode=null) - { - bootbox.hideAll(); - - var metadata; - if (aNode != null) - { - metadata = aNode.metadata; - } - - var html = d3.select("html") - var form_content = html.append("div").attr("class","form-content").attr("style","display:none") - var form = form_content.append("form").attr("class","form").attr("role","form") - var form_group, input; - - //General information - form_group = form.append("div").attr("class","form-group") - form_group.append("label").text("General information") - form_group = form.append("div").attr("class","form-group") - form_group.append("text").text("Description") - input = form_group.append("textarea") - .attr("id","description") - .attr("class","form-control") - .attr("name","description") - .attr("placeholder","Add a description for the DC here") - - form_group = form.append("div").attr("class","form-group") - form_group.append("text").text("Status") - input = form_group.append("select").attr("id","status").style("margin-left","5px") - input.append("option").attr("type","select").attr("value","-").text("Please select...") - input.append("option").attr("type","select").attr("value","Available").text("Available") - input.append("option").attr("type","select").attr("value","N/A").text("N/A") - var contacts = currentGraph.organization.contacts; - form_group = form.append("div").attr("class","form-group") - form_group.append("text").text("Owner") - input = form_group.append("select").attr("id","owner_uid").style("margin-left","5px") - input.append("option").attr("type","select").attr("value","-").text("Please select...") - contacts.forEach(function(contact){ - input.append("option").attr("type","select").attr("value",contact.attrib.uID).text(contact.name + " (" + contact.company + ")") - }) - form_group = form.append("div").attr("class","form-group") - form_group.append("text").text("Creator") - input = form_group.append("select").attr("id","creator_uid").style("margin-left","5px") - input.append("option").attr("type","select").attr("value","-").text("Please select...") - contacts.forEach(function(contact){ - input.append("option").attr("type","select").attr("value",contact.attrib.uID).text(contact.name + " (" + contact.company + ")") - }) - form_group = form.append("div").attr("class","form-group") - form_group.append("text").text("Operator") - input = form_group.append("select").attr("id","operator_uid").style("margin-left","5px") - input.append("option").attr("type","select").attr("value","-").text("Please select...") - contacts.forEach(function(contact){ - input.append("option").attr("type","select").attr("value",contact.attrib.uID).text(contact.name + " (" + contact.company + ")") - }) - - - //Information on tool execution - form_group = form.append("div").attr("class","form-group").style("margin-top","40px") - form_group.append("label").text("Execution information") - form_group = form.append("div").attr("class","form-group") - form_group.append("text").text("Operating System") - input = form_group.append("select").attr("id","operating_system").style("margin-left","5px") - input.append("option").attr("type","select").attr("value","-").text("Please select...") - input.append("option").attr("type","select").attr("value","windows").text("Windows") - input.append("option").attr("type","select").attr("value","linux").text("Linux") - input.append("option").attr("type","select").attr("value","mac").text("Mac OS") - input.append("option").attr("type","select").attr("value","other").text("Other") - form_group = form.append("div").attr("class","form-group") - form_group.append("text").text("Integration platform") - input = form_group.append("input") - .attr("id","integration_platform") - .attr("class","form-control") - .attr("name","integration_platform") - .attr("placeholder","Integration platform (e.g. RCE, Optimus)") - form_group = form.append("div").attr("class","form-group") - form_group.append("text").text("Execution command") - input = form_group.append("textarea") - .attr("id","command") - .attr("class","form-control") - .attr("cols","40") - .attr("rows","5") - .attr("name","command") - .attr("placeholder","Execution command") - form_group = form.append("div").attr("class","form-group") - input = form_group.append("input") - .attr("id","description_cmd") - .attr("class","form-control") - .attr("name","description_cmd") - .attr("placeholder","Details on the exectuion command (optional)") - form_group = form.append("div").attr("class","form-group") - input = form_group.append("input") - .attr("id","software_requirements") - .attr("class","form-control") - .attr("name","software_requirements") - .attr("placeholder","Software requirements") - form_group = form.append("div").attr("class","form-group") - input = form_group.append("input") - .attr("id","hardware_requirements") - .attr("class","form-control") - .attr("name","hardware_requirements") - .attr("placeholder","Hardware requirements") - - //Information on tool licensing - form_group = form.append("div").attr("class","form-group").style("margin-top","40px") - form_group.append("label").text("License information (optional)") - input = form_group.append("input") - .attr("id","license_type") - .attr("class","form-control") - .attr("name","license_type") - .attr("placeholder","License type (e.g. open-source, commercial)") - form_group = form.append("div").attr("class","form-group") - input = form_group.append("input") - .attr("id","license_specification") - .attr("class","form-control") - .attr("name","license_specification") - .attr("placeholder","License specification (e.g. Apache License 2.0)") - form_group = form.append("div").attr("class","form-group") - input = form_group.append("input") - .attr("id","license_info") - .attr("class","form-control") - .attr("name","license_info") - .attr("placeholder","License information (e.g. https://www.apache.org/licenses/LICENSE-2.0)") - - //Information on tool sources - form_group = form.append("div").attr("class","form-group").style("margin-top","40px") - form_group.append("label").text("Source information (optional)") - input = form_group.append("input") - .attr("id","repository_link") - .attr("class","form-control") - .attr("name","repository_link") - .attr("placeholder","Repository link") - form_group = form.append("div").attr("class","form-group") - input = form_group.append("input") - .attr("id","download_link") - .attr("class","form-control") - .attr("name","download_link") - .attr("placeholder","Download link") - form_group = form.append("div").attr("class","form-group") - input = form_group.append("input") - .attr("id","references") - .attr("class","form-control") - .attr("name","references") - .attr("placeholder","References") - - - var modal = bootbox.dialog({ - message: $(".form-content").html(), - title: "Add Competence Metadata", - size: "large", - buttons: [ - { - label: "Cancel", - className: "btn btn-default pull-left", - callback: function() { - modal.modal("hide"); - d3.selectAll(".form-content").remove(); - } - }, - { - label: "OK", - className: "btn btn-primary pull-left", - callback: function() { - var metadata = { - uID: aNode.uID, - description: $('form #description').val(), - status: $('form #status').val(), - owner_uid: $('form #owner_uid').val(), - creator_uid: $('form #creator_uid').val(), - operator_uid: $('form #operator_uid').val() - } - var metadata_str = JSON.stringify(metadata) - var bootboxContent = {title: "Get graph elements", message: '<p>Please be patient...</p>'}; - var xhr = $.ajax( - { - type: 'POST', - url: '/kadmos_add_DC_metadata', - data: {'graphID':graphID, 'sessionID':sessionID, 'currentOrder':nodeOrder, 'nodeName':metadata.uID, 'metadata_str':metadata_str}, - success: function(result) - { - if (result.includes("ERROR:")) - { - bootboxContent.message = result - kadmosErrorMessage(bootboxContent); - } - else - { - var updatedData = {}; - updatedData = data; - var graphData = JSON.parse(result); - for (var i = 0; i < updatedData.graphs.length; i++) - { - if (graphID == updatedData.graphs[i].id) - { - updatedData.graphs[i] = graphData.graphs[0]; - } - } - - clearView(); - makeKadmosMenu(updatedData); - xdsm_script(updatedData,graphID); - - bootboxContent.message = "Success!" - kadmosSuccessMessage(bootboxContent) - } - }, - error: function(result) - { - bootboxContent.message = result - kadmosErrorMessage(bootboxContent); - } - }); - kadmosHavePatience(xhr, bootboxContent) - modal.modal("hide"); - d3.selectAll(".form-content").remove(); - } - } - ], - onEscape: function() { - modal.modal("hide"); - d3.selectAll(".form-content").remove(); - } - }); - - - } - - function sendDCMetadata(aMetadata) - { - } @@ -20064,7 +20196,7 @@ { title: 'Add metadata', onMouseDown: function(elm, k, i) { - addDCMetadata(k) + addDCMetadata(data,currentGraph,k) //sendDCMetadata(dc_metadata); }, onMouseUp: function(elm, k, i) { @@ -20532,7 +20664,7 @@ } else if(result == "dc") { - addDesignCompetence(); + addDesignCompetence(data, currentGraph); } else; } @@ -24785,10 +24917,6 @@ }); return input; } - - function include(arr,obj) { - return (arr.indexOf(obj) != -1); - } function prepareTreeData(aSchema,aLink) @@ -25589,10 +25717,6 @@ }; }; - //aigner: Include function - function include(arr,obj) { - return (arr.indexOf(obj) != -1); - } //aigner: Function creates a table function tabulate(aTable,data,columns) { diff --git a/kadmos/vistoms/templates/cmdows_template.xml b/kadmos/vistoms/templates/cmdows_template.xml new file mode 100644 index 000000000..d4c810155 --- /dev/null +++ b/kadmos/vistoms/templates/cmdows_template.xml @@ -0,0 +1,42 @@ +<?xml version='1.0' encoding='UTF-8'?> +<cmdows xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://bitbucket.org/imcovangent/cmdows/raw/master/schema/0.7/cmdows.xsd"> + <header> + <creator>Lukas Mueller</creator> + <description>RCG CMDOWS file of the super-sonic business jet test case optimization problem</description> + <timestamp>2018-03-21T18:06:39.928759</timestamp> + <fileVersion>0.1</fileVersion> + <cmdowsVersion>0.7</cmdowsVersion> + <updates> + <update> + <modification>KADMOS export of a repository connectivity graph (RCG).</modification> + <creator>Lukas Mueller</creator> + <timestamp>2018-03-21T18:06:39.928759</timestamp> + <fileVersion>0.1</fileVersion> + <cmdowsVersion>0.7</cmdowsVersion> + </update> + </updates> + </header> + <executableBlocks> + <designCompetences> + <designCompetence uID="dummy"> + <ID>dummy</ID> + <modeID>main</modeID> + <instanceID>1</instanceID> + <version>1.0</version> + <label>Dummy</label> + <inputs> + </inputs> + <outputs> + </outputs> + </designCompetence> + </designCompetences> + <mathematicalFunctions></mathematicalFunctions> + </executableBlocks> + <parameters></parameters> + <workflow> + <dataGraph> + <name>RCG</name> + <edges></edges> + </dataGraph> + </workflow> +</cmdows> diff --git a/kadmos/vistoms/vistoms.py b/kadmos/vistoms/vistoms.py index 300ba5c65..df1dd7ebc 100644 --- a/kadmos/vistoms/vistoms.py +++ b/kadmos/vistoms/vistoms.py @@ -1,9 +1,9 @@ # Imports import ast +import fnmatch import json import logging import os -import fnmatch import shutil import sys import tempfile @@ -149,6 +149,47 @@ def kadmos_upload_file(): # Logs the error appropriately. +@app.route('/kadmos_create_new_graph', methods=['POST']) +def kadmos_create_new_graph(): + try: + # Get request form + graph_name = request.form['graph_name'] + graph_description = request.form['graph_description'] + + # Open cmdows template file and load it as graph + cmdows_template = os.path.join('templates', 'cmdows_template.xml') + graph_template = load(cmdows_template, check_list=['consistent_root', 'invalid_leaf_elements']) + + # Determine graph_id + graph_ids = [] + for aFile in os.listdir(UPLOAD_FOLDER): + if aFile.endswith('.kdms'): + filename = aFile.split('.kdms')[0] + graph_ids.append(int(filename.split('_')[1])) + graph_id_int = max(graph_ids)+1 + graph_id = format(graph_id_int, "02") + + # Allocate graph name, description and id + graph_template.graph['name'] = graph_name + graph_template.graph['description'] = graph_description + graph_template.graph['id'] = graph_id + + # Delete dummy design competence + graph_template.remove_node('dummy') + + # Save empty graph as kdms file + graph_template.save(os.path.join(UPLOAD_FOLDER, 'tmp_'+graph_id+'.kdms'), file_type='kdms', graph_check_critical=False, mpg=None) + + # Add graph to vistoms data + newVistomsData = graph_template.vistoms_add_json(mpg=None, graph_id=graph_id) + + return newVistomsData + + except Exception as e: + return "ERROR: " + e.message + # Logs the error appropriately. + + @app.route('/kadmos_export_all_graphs', methods=['POST']) def kadmos_export_all_graphs(): """ @@ -835,7 +876,9 @@ def kadmos_add_mathematical_function(): try: # Get request form graphID = request.form['graphID'] - function_order = request.form['currentOrder'].split(',') + function_order = [] + if request.form['currentOrder'] != '': + function_order = request.form['currentOrder'].split(',') form_data_str = request.form['form_data'] # convert stringified data into python objects/arrays/.. with json.loads function -- GitLab