summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSunil Shetye2025-04-13 22:51:29 +0530
committerSunil Shetye2025-04-15 10:29:36 +0530
commit6c220510f6152f259782234e4b24a131887a38f6 (patch)
treecf060548901a44d94740fbed7f1420944d242527
parent4d4471e9d8c9fdf76d1090d0e3d85d1b40244f1c (diff)
downloadCommon-Interface-Project-6c220510f6152f259782234e4b24a131887a38f6.tar.gz
Common-Interface-Project-6c220510f6152f259782234e4b24a131887a38f6.tar.bz2
Common-Interface-Project-6c220510f6152f259782234e4b24a131887a38f6.zip
use pexpect for interactive scilab-cli
send the expression to scilab-cli add convert_scientific_notation to replace multiple replace calls replace workspace_filename with workspace_file scriptcount and diagramlock no longer required in UserData class pass task_id or script_task_id based on context use shutil.move() instead of os.rename() convert task.task_id to string pass workspace to MxGraphParser
-rw-r--r--blocks/Xcos/common/AAAAAA.py150
-rw-r--r--blocks/requirements.txt4
-rw-r--r--blocks/simulationAPI/helpers/ngspice_helper.py4
-rw-r--r--blocks/simulationAPI/helpers/scilab_manager.py141
-rw-r--r--blocks/simulationAPI/models.py1
-rw-r--r--blocks/simulationAPI/tasks.py7
-rw-r--r--blocks/simulationAPI/views.py1
-rwxr-xr-xblocks/xcos2xml/replacesplitblocks.sh22
8 files changed, 217 insertions, 113 deletions
diff --git a/blocks/Xcos/common/AAAAAA.py b/blocks/Xcos/common/AAAAAA.py
index 7c8f82c5..3deb7135 100644
--- a/blocks/Xcos/common/AAAAAA.py
+++ b/blocks/Xcos/common/AAAAAA.py
@@ -1,10 +1,12 @@
import datetime
+import os
+from os.path import abspath, join
+import pexpect
import re
import sys
import traceback
import xml.etree.ElementTree as ET
import math
-import random
import uuid
TYPE_ARRAY = 'Array'
@@ -69,10 +71,85 @@ LINK_EXPLICIT = 'ExplicitLink'
LINK_IMPLICIT = 'ImplicitLink'
LINK_COMMANDCONTROL = 'CommandControlLink'
+SCILAB_DIR = '../../scilab_for_xcos_on_cloud'
+SCILAB_DIR = abspath(SCILAB_DIR)
+SCILAB = join(SCILAB_DIR, 'bin', 'scilab-cli')
+
+WORKSPACE = None
+
+
+def load_variables(filename):
+ '''
+ add scilab commands to load only user defined variables
+ '''
+
+ command = "[__V1,__V2]=listvarinfile('%s');" % filename
+ command += "__V5=grep(string(__V2),'/^([124568]|1[07])$/','r');"
+ command += "__V1=__V1(__V5);"
+ command += "__V2=__V2(__V5);"
+ command += "__V5=grep(__V1,'/^[^%]+$/','r');"
+ command += "if ~isempty(__V5) then;"
+ command += "__V1=__V1(__V5);"
+ command += "__V2=__V2(__V5);"
+ command += "__V6=''''+strcat(__V1,''',''')+'''';"
+ command += "__V7='load(''%s'','+__V6+');';" % filename
+ command += "execstr(__V7);"
+ command += "end;"
+ command += "clear __V1 __V2 __V5 __V6 __V7;"
+ return command
+
+
+class ScilabWorkspace:
+ def __init__(self, workspace):
+ cmd = load_variables(workspace)
+
+ scilab_cmd = [SCILAB,
+ "-noatomsautoload",
+ "-nogui",
+ "-nouserstartup",
+ "-nb",
+ "-e", cmd
+ ]
+
+ env = os.environ.copy()
+ env['TERM'] = 'dumb'
+ self.child = pexpect.spawn(scilab_cmd[0], scilab_cmd[1:], env=env, encoding='utf-8', timeout=15)
+ self.child.expect('--> ')
+
+ def clean_output(self, text, expr):
+ # Remove echoed input and Scilab formatting
+ text = re.sub(r'\x1b\[[0-9;]*[a-zA-Z]', '', text)
+ text = re.sub(r'.\x08', '', text)
+ lines = [line.strip() for line in text.splitlines()]
+ if lines and lines[0] == expr:
+ lines = lines[1:]
+ text = '\n'.join(lines).strip()
+ return text
+
+ def send_expression(self, expression):
+ """Send a line to the process and return its output"""
+ expression = expression.strip(' \t\n\r\f\v;')
+ if expression == '':
+ print('No expression')
+ return ''
+
+ expr = f'disp({expression})'
+ self.child.sendline(expr)
+ self.child.expect('--> ')
+ output = self.child.before.strip()
+
+ return self.clean_output(output, expr)
+
+ def clean(self):
+ """Terminate the process cleanly"""
+ self.child.sendline('exit')
+ self.child.close()
+ self.child = None
+
def addNode(node, subNodeType, **kwargs):
subNode = ET.SubElement(node, subNodeType)
- for (key, value) in kwargs.items():
+ for key, value in kwargs.items():
if value is not None:
subNode.set(key, str(value))
return subNode
@@ -332,8 +409,7 @@ def addSuperNode(node, subNodeType,
title, **kwargs):
newkwargs = {'as': a, 'background': background,
'gridEnabled': gridEnabled,
- 'title': title
- }
+ 'title': title}
newkwargs.update(kwargs)
return addNode(node, subNodeType, **newkwargs)
@@ -341,8 +417,7 @@ def addSuperNode(node, subNodeType,
def addSuperBlkNode(node, subNodeType,
a, scilabClass,
**kwargs):
- newkwargs = {'as': a, 'scilabClass': scilabClass
- }
+ newkwargs = {'as': a, 'scilabClass': scilabClass}
newkwargs.update(kwargs)
return addNode(node, subNodeType, **newkwargs)
@@ -350,8 +425,7 @@ def addSuperBlkNode(node, subNodeType,
def superAddNode(node, subNodeType,
value,
**kwargs):
- newkwargs = {'value': value
- }
+ newkwargs = {'value': value}
newkwargs.update(kwargs)
return addNode(node, subNodeType, **newkwargs)
@@ -359,8 +433,7 @@ def superAddNode(node, subNodeType,
def addmxGraphModelNode(node, subNodeType,
a,
**kwargs):
- newkwargs = {'as': a
- }
+ newkwargs = {'as': a}
newkwargs.update(kwargs)
return addNode(node, subNodeType, **newkwargs)
@@ -368,8 +441,7 @@ def addmxGraphModelNode(node, subNodeType,
def addmxCellNode(node, subNodeType,
id,
**kwargs):
- newkwargs = {'id': id
- }
+ newkwargs = {'id': id}
newkwargs.update(kwargs)
return addNode(node, subNodeType, **newkwargs)
@@ -377,8 +449,7 @@ def addmxCellNode(node, subNodeType,
def addNodemxCell(node, subNodeType, a,
id,
**kwargs):
- newkwargs = {'as': a, 'id': id
- }
+ newkwargs = {'as': a, 'id': id}
newkwargs.update(kwargs)
return addNode(node, subNodeType, **newkwargs)
@@ -386,8 +457,7 @@ def addNodemxCell(node, subNodeType, a,
def addmxCell(node, subNodeType,
id,
**kwargs):
- newkwargs = {'id': id
- }
+ newkwargs = {'id': id}
newkwargs.update(kwargs)
return addNode(node, subNodeType, **newkwargs)
@@ -718,19 +788,37 @@ def get_number_power(value):
value)
-def format_real_number(parameter, workspace_file):
+def convert_scientific_notation(parameter):
+ def repl(match):
+ if match.group('bare_exp'): # Case: '10^3' with no coefficient
+ return f"1e{match.group('bare_exp')}"
+ elif match.group('with_coeff'): # Case: '2*10^3' or '*10^3'
+ return 'e' + match.group('with_coeff')
+ elif match.group('fortran'): # Case: '1.23d4' or '1.23D4'
+ return f"{match.group('num')}e{match.group('exp')}"
+ return match.group(0) # Fallback (shouldn't happen)
+
+ pattern = re.compile(
+ r"(?P<bare> (?<![\d*])10\^(?P<bare_exp>[-+]?\d+))"
+ r"|(?P<with_star>\*?10\^(?P<with_coeff>[-+]?\d+))"
+ r"|(?P<fortran>(?P<num>\d+\.?\d*)[dD](?P<exp>[-+]?\d+))",
+ re.VERBOSE
+ )
+
+ return pattern.sub(repl, parameter)
+
+
+def format_real_number(parameter):
+ if re.search(r'[a-zA-Z]', parameter): # Check if parameter contains alphabetic characters
+ if WORKSPACE is None:
+ print(f'No Scilab workspace available for {parameter} evaluation')
+ return parameter
+ print(f'send {parameter} to Scilab')
+ parameter = WORKSPACE.send_expression(parameter)
if not parameter.strip(): # Handle empty strings
return '0'
- elif re.search(r'[dDeE\^]', parameter): # Check for scientific notation
- real_number = float(parameter.replace('*10^', 'e').replace('10^', '1e').replace('d', 'e').replace('D', 'e'))
- return "{:.10g}".format(real_number)
- elif re.search(r'[a-zA-Z]', parameter): # Check if parameter contains alphabetic characters
- print('send to Scilab', workspace_file)
- with open("params.txt", "a") as f:
- f.write(parameter + "\n")
- # uploadscript("params.txt")
- # return parameter # Or return some status
try:
+ parameter = convert_scientific_notation(parameter)
return "{:.10g}".format(float(parameter)) # Convert numeric strings safely
except ValueError:
return parameter # Return original non-numeric string
@@ -1404,6 +1492,12 @@ def getSplitPoints(attrib, switch_split, blkgeometry, sourceVertex, targetVertex
def process_xcos_model(model, title, rootattribid, parentattribid,
workspace_file=None):
+ global WORKSPACE
+
+ if workspace_file is not None and workspace_file != '' and WORKSPACE is None:
+ print('workspace_file=', workspace_file)
+ WORKSPACE = ScilabWorkspace(workspace_file)
+
checkModelTag(model)
outdiagram = ET.Element('XcosDiagram')
outdiagram.set('background', '-1')
@@ -1609,4 +1703,8 @@ def process_xcos_model(model, title, rootattribid, parentattribid,
outnode.set('id', parentattribid)
outnode.set('parent', rootattribid)
+ if WORKSPACE is not None:
+ WORKSPACE.clean()
+ WORKSPACE = None
+
return outdiagram
diff --git a/blocks/requirements.txt b/blocks/requirements.txt
index 550214f7..54104e6a 100644
--- a/blocks/requirements.txt
+++ b/blocks/requirements.txt
@@ -33,8 +33,10 @@ mccabe==0.7.0
oauthlib==3.2.2
outcome==1.3.0.post0
packaging==24.1
+pexpect==4.9.0
pillow==10.3.0
prompt-toolkit==3.0.36
+ptyprocess==0.7.0
pycodestyle==2.12.1
pycparser==2.22
pyflakes==3.2.0
@@ -49,6 +51,7 @@ redis==4.5.4
requests==2.32.2
requests-oauthlib==2.0.0
selenium==4.24.0
+setuptools==78.1.0
six==1.16.0
sniffio==1.3.1
social-auth-app-django==5.4.1
@@ -65,6 +68,7 @@ vine==5.1.0
wcwidth==0.2.6
webdriver-manager==4.0.2
websocket-client==1.8.0
+wheel==0.45.1
wsproto==1.2.0
zope.event==5.0
zope.interface==7.2
diff --git a/blocks/simulationAPI/helpers/ngspice_helper.py b/blocks/simulationAPI/helpers/ngspice_helper.py
index 3fd42e42..75b70e4f 100644
--- a/blocks/simulationAPI/helpers/ngspice_helper.py
+++ b/blocks/simulationAPI/helpers/ngspice_helper.py
@@ -130,13 +130,9 @@ def ExecXml(task, task_name, workspace_file):
if result == "":
logger.info('Simulation completed successfully for task %s', task_id)
- update_task_status(task_id, 'SUCCESS',
- meta={'current_process': 'Simulation Completed'})
return 'Streaming'
else:
logger.warning('Simulation failed for task %s: %s', task_id, result)
- update_task_status(task_id, 'FAILURE',
- meta={'current_process': result})
return 'Failure'
except BaseException as e:
diff --git a/blocks/simulationAPI/helpers/scilab_manager.py b/blocks/simulationAPI/helpers/scilab_manager.py
index 8f015d74..b3c1af24 100644
--- a/blocks/simulationAPI/helpers/scilab_manager.py
+++ b/blocks/simulationAPI/helpers/scilab_manager.py
@@ -91,8 +91,6 @@ def makedirs(dirname, dirtype=None):
def rmdir(dirname, dirtype=None):
- if dirname is None:
- return False
if not isdir(dirname):
logger.error('dir %s does not exist', dirname)
return False
@@ -108,8 +106,6 @@ def rmdir(dirname, dirtype=None):
def remove(filename):
- if filename is None:
- return False
if not isfile(filename):
logger.error('file %s does not exist', filename)
return False
@@ -153,7 +149,7 @@ class Diagram:
workspace_counter = 0
save_variables = set()
# workspace from script
- workspace_filename = None
+ workspace_file = None
# tk count
tk_count = 0
# store log name
@@ -183,9 +179,9 @@ class Diagram:
if self.xcos_file_name is not None:
remove(self.xcos_file_name)
self.xcos_file_name = None
- if self.workspace_filename is not None:
- remove(self.workspace_filename)
- self.workspace_filename = None
+ if self.workspace_file is not None:
+ remove(self.workspace_file)
+ self.workspace_file = None
if self.file_image != '':
remove(join(IMAGEDIR, self.file_image))
self.file_image = ''
@@ -197,14 +193,14 @@ class Script:
filename = None
status = 0
instance = None
- workspace_filename = None
+ workspace_file = None
def __str__(self):
return (
"{script_id: %s, filename: %s, status: %d, instance: %s, "
- "workspace_filename: %s}") % (
+ "workspace_file: %s}") % (
self.script_id, self.filename, self.status, self.instance,
- self.workspace_filename)
+ self.workspace_file)
def clean(self):
if self.instance is not None:
@@ -213,15 +209,18 @@ class Script:
if self.filename is not None:
remove(self.filename)
self.filename = None
- if self.workspace_filename is not None:
- remove(self.workspace_filename)
- self.workspace_filename = None
+ if self.workspace_file is not None:
+ remove(self.workspace_file)
+ self.workspace_file = None
class SciFile:
'''Variables used in sci-func block'''
instance = None
+ def __str__(self):
+ return "{instance: %s}" % self.instance
+
def clean(self):
if self.instance is not None:
kill_scifile(self)
@@ -233,9 +232,7 @@ class UserData:
diagrams = None
scripts = None
datafiles = None
- scriptcount = None
scifile = None
- diagramlock = None
timestamp = None
def __init__(self):
@@ -244,30 +241,20 @@ class UserData:
self.diagrams = {}
self.datafiles = []
self.scripts = {}
- self.scriptcount = 0
self.scifile = SciFile()
- self.diagramlock = RLock()
self.timestamp = time()
def __str__(self):
return (f"UserData(sessiondir={self.sessiondir}, "
- f"diagrams={len(self.diagrams)}, "
+ f"diagrams={list(self.diagrams.keys())}, "
f"datafiles={len(self.datafiles)}, "
f"scripts={list(self.scripts.keys())}, "
- f"scriptcount={self.scriptcount}, "
f"scifile={self.scifile}, "
- f"timestamp={self.timestamp})")
+ f"timestamp={datetime.fromtimestamp(self.timestamp).strftime('%Y-%m-%dT%H:%M:%S')})")
def __repr__(self):
return self.__str__()
- def getscriptcount(self):
- with self.diagramlock:
- rv = self.scriptcount
- self.scriptcount += 1
-
- return str(rv)
-
def clean(self):
for diagram in self.diagrams.values():
diagram.clean()
@@ -280,7 +267,6 @@ class UserData:
self.datafiles = None
self.scifile.clean()
self.scifile = None
- self.diagramlock = None
# name of workspace file
workspace = join(self.sessiondir, WORKSPACE_FILES_FOLDER,
"workspace.dat")
@@ -615,8 +601,7 @@ def init_session(session):
makedirs(join(sessiondir, SCRIPT_FILES_FOLDER), 'script files')
makedirs(join(sessiondir, WORKSPACE_FILES_FOLDER), 'workspace files')
- return (ud.diagrams, ud.scripts, ud.getscriptcount, ud.scifile,
- ud.datafiles, sessiondir, ud.diagramlock)
+ return (ud.diagrams, ud.scripts, ud.scifile, ud.datafiles, sessiondir)
def prestart_scilab():
@@ -711,7 +696,7 @@ def uploadscript(session, task):
'''
Below route is called for uploading script file.
'''
- (script, sessiondir) = add_script(session, task)
+ (script, sessiondir) = add_script(session, str(task.task_id))
file = task.file
if not file:
@@ -736,7 +721,7 @@ def uploadscript(session, task):
wfname = join(sessiondir, WORKSPACE_FILES_FOLDER,
f"{script.script_id}_script_workspace.dat")
- script.workspace_filename = wfname
+ script.workspace_file = wfname
command = "exec('%s');save('%s');" % (fname, wfname)
script.instance = run_scilab(command, script)
@@ -753,7 +738,7 @@ def uploadscript(session, task):
msg = ''
script.status = 1
- rv = {'task_id': task.task_id, 'script_id': script.script_id, 'status': script.status, 'msg': msg}
+ rv = {'task_id': str(task.task_id), 'script_id': script.script_id, 'status': script.status, 'msg': msg}
return rv
@@ -773,7 +758,7 @@ def getscriptoutput(session, task):
'''
Below route is called for uploading script file.
'''
- script = get_script(session, task)
+ script = get_script(session, str(task.task_id))
if script is None:
# when called with same script_id again or with incorrect script_id
logger.warning('no script')
@@ -819,11 +804,11 @@ def getscriptoutput(session, task):
return rv
logger.info('workspace for %s saved in %s',
- script.script_id, script.workspace_filename)
+ script.script_id, script.workspace_file)
msg = ''
script.status = 0
- cmd = list_variables(script.workspace_filename)
+ cmd = list_variables(script.workspace_file)
script.instance = run_scilab(cmd, script)
instance = script.instance
@@ -972,7 +957,7 @@ def start_scilab(session, task, xcosfile):
return "error"
# name of primary workspace file
- workspace_filename = diagram.workspace_filename
+ workspace_file = diagram.workspace_file
# name of workspace file
workspace = join(diagram.sessiondir, WORKSPACE_FILES_FOLDER,
"workspace.dat")
@@ -983,7 +968,7 @@ def start_scilab(session, task, xcosfile):
"Please simulate a diagram with TOWS_c block first. "
"Do not use any FROMWSB block in that diagram.")
- loadfile = workspace_filename is not None or \
+ loadfile = workspace_file is not None or \
diagram.workspace_counter in (2, 3)
command = ""
@@ -992,8 +977,8 @@ def start_scilab(session, task, xcosfile):
# ignore import errors
command += "try;"
- if workspace_filename is not None:
- command += load_variables(workspace_filename)
+ if workspace_file is not None:
+ command += load_variables(workspace_file)
if diagram.workspace_counter in (2, 3):
# 3 - for both TOWS_c and FROMWSB and also workspace dat file exist
@@ -1131,9 +1116,13 @@ def upload(session, task, xcosfile):
# Make the filename safe, remove unsupported chars
(diagram, scripts, sessiondir) = add_diagram(session, task)
- script = get_script(session, task, scripts=scripts)
+ script = get_script(session, task.script_task_id, scripts=scripts)
+ if script is None and task.workspace_file is not None:
+ logger.info('adding script')
+ (script, __) = add_script(session, task.script_task_id)
+ script.workspace_file = task.workspace_file
if script is not None:
- diagram.workspace_filename = script.workspace_filename
+ diagram.workspace_file = script.workspace_file
# Save the file in xml extension and using it for further modification
# by using xml parser
temp_file_xml_name = diagram.diagram_id + ".xml"
@@ -1294,7 +1283,7 @@ def upload(session, task, xcosfile):
f.truncate()
fname = join(sessiondir, UPLOAD_FOLDER,
splitext(temp_file_xml_name)[0] + ".xcos")
- os.rename(temp_file_xml_name, fname)
+ shutil.move(temp_file_xml_name, fname)
diagram.xcos_file_name = fname
return diagram.diagram_id
@@ -1409,7 +1398,7 @@ def upload(session, task, xcosfile):
fname = join(sessiondir, UPLOAD_FOLDER,
splitext(temp_file_xml_name)[0] + ".xcos")
# Move the xcos file to uploads directory
- os.rename(temp_file_xml_name, fname)
+ shutil.move(temp_file_xml_name, fname)
diagram.xcos_file_name = fname
return diagram.diagram_id
@@ -1418,67 +1407,67 @@ def get_diagram(session, task, remove=False):
if not task:
logger.warning('no id')
return None
- xcos_file_id = task.task_id
+ task_id = str(task.task_id)
- (diagrams, __, __, __, __, __, __) = init_session(session)
+ (diagrams, __, __, __, __) = init_session(session)
- if xcos_file_id not in diagrams:
- logger.warning('id %s not in diagrams', xcos_file_id)
+ if task_id not in diagrams:
+ logger.warning('id %s not in diagrams', task_id)
return None
- diagram = diagrams[xcos_file_id]
+ diagram = diagrams[task_id]
if remove:
- diagrams[xcos_file_id] = Diagram()
+ diagrams[task_id] = Diagram()
return diagram
def add_diagram(session, task):
- (diagrams, scripts, __, __, __, sessiondir, diagramlock) = init_session(session)
+ task_id = str(task.task_id)
+
+ (diagrams, scripts, __, __, sessiondir) = init_session(session)
- with diagramlock:
- diagram = Diagram()
- diagram.diagram_id = str(len(diagrams))
- diagram.sessiondir = sessiondir
- # diagrams.append(diagram)
- diagrams[task.task_id] = diagram
+ diagram = Diagram()
+ diagram.diagram_id = task_id
+ diagram.sessiondir = sessiondir
+ diagrams[task_id] = diagram
return (diagram, scripts, sessiondir)
-def get_script(session, task, scripts=None, remove=False):
- if task is None:
+def get_script(session, task_id, scripts=None, remove=False):
+ if task_id is None:
return None
if scripts is None:
- (__, scripts, __, __, __, __, __) = init_session(session)
+ (__, scripts, __, __, __) = init_session(session)
- if task.task_id not in scripts:
- logger.warning('id %s not in scripts', task.task_id)
+ if task_id not in scripts:
+ logger.warning('id %s not in scripts', task_id)
return None
- script = scripts[task.task_id]
+ script = scripts[task_id]
if remove:
- del scripts[task.task_id]
+ del scripts[task_id]
return script
-def add_script(session, task):
- (__, scripts, __, __, __, sessiondir, __) = init_session(session)
+def add_script(session, task_id):
+ (__, scripts, __, __, sessiondir) = init_session(session)
script = Script()
- script.script_id = task.task_id
+ script.script_id = task_id
script.sessiondir = sessiondir
- scripts[task.task_id] = script
+ scripts[task_id] = script
return (script, sessiondir)
def add_datafile(session):
- (__, __, __, __, datafiles, sessiondir, __) = init_session(session)
+ (__, __, __, datafiles, sessiondir) = init_session(session)
datafile = DataFile()
datafile.sessiondir = sessiondir
@@ -1534,7 +1523,7 @@ def get_request_id(request, key='id'):
def internal_fun(session, task, internal_key):
- (__, __, __, scifile, __, sessiondir, __) = init_session(session)
+ (__, __, scifile, __, sessiondir) = init_session(session)
if internal_key not in config.INTERNAL:
msg = internal_key + ' not found'
@@ -1661,7 +1650,7 @@ def kill_scilab(diagram=None, session=None, task=None):
def kill_script(script=None, session=None, task=None):
'''Below route is called for stopping a running script file.'''
if script is None:
- script = get_script(session, task, remove=True)
+ script = get_script(session, str(task.task_id), remove=True)
if script is None:
# when called with same script_id again or with incorrect script_id
logger.warning('no script')
@@ -1677,11 +1666,11 @@ def kill_script(script=None, session=None, task=None):
remove(script.filename)
script.filename = None
- if script.workspace_filename is None:
+ if script.workspace_file is None:
logger.warning('empty workspace')
else:
- remove(script.workspace_filename)
- script.workspace_filename = None
+ remove(script.workspace_file)
+ script.workspace_file = None
return "ok"
@@ -1689,7 +1678,7 @@ def kill_script(script=None, session=None, task=None):
def kill_scifile(scifile=None, session=None):
'''Below route is called for stopping a running sci file.'''
if scifile is None:
- (__, __, __, scifile, __, __, __) = init_session(session)
+ (__, __, scifile, __, __) = init_session(session)
logger.info('kill_scifile: scifile=%s', scifile)
diff --git a/blocks/simulationAPI/models.py b/blocks/simulationAPI/models.py
index 65251dd1..1f639c5a 100644
--- a/blocks/simulationAPI/models.py
+++ b/blocks/simulationAPI/models.py
@@ -75,6 +75,7 @@ class Task(models.Model):
parameters = models.TextField(blank=True, null=True)
upload_time = models.DateTimeField(auto_now=True)
log_name = models.CharField(max_length=500, blank=True, null=True)
+ script_task_id = models.CharField(max_length=40, blank=True, null=True)
workspace_file = models.CharField(max_length=500, blank=True, null=True)
returncode = models.IntegerField(blank=True, null=True)
session = models.ForeignKey(Session, on_delete=models.CASCADE, related_name='task', null=True)
diff --git a/blocks/simulationAPI/tasks.py b/blocks/simulationAPI/tasks.py
index e6e8680a..4c7e57e6 100644
--- a/blocks/simulationAPI/tasks.py
+++ b/blocks/simulationAPI/tasks.py
@@ -3,7 +3,6 @@ from celery.exceptions import Ignore
from celery.utils.log import get_task_logger
from redis import Redis
from threading import current_thread
-import traceback
from blocks.celery_tasks import app
from simulationAPI.helpers.ngspice_helper import ExecXml, update_task_status
@@ -53,6 +52,10 @@ def process_task(self, task_id):
elif output == "Success":
state = 'SUCCESS'
current_process = 'Processed Xml, Loading Output'
+ else:
+ logger.error('Failed %s', output)
+ state = 'FAILURE'
+ current_process = 'Failed'
update_task_status(task_id, state,
meta={'current_process': current_process})
@@ -63,7 +66,7 @@ def process_task(self, task_id):
update_task_status(task_id, 'FAILURE',
meta={
'exc_type': type(e).__name__,
- 'exc_message': traceback.format_exc().split('\n')
+ 'exc_message': str(e)
})
logger.exception('Exception Occurred:')
raise Ignore()
diff --git a/blocks/simulationAPI/views.py b/blocks/simulationAPI/views.py
index 4d74e4e0..0908c3f1 100644
--- a/blocks/simulationAPI/views.py
+++ b/blocks/simulationAPI/views.py
@@ -72,6 +72,7 @@ class XmlUploader(APIView):
try:
script_task = Task.objects.get(task_id=script_task_id, type='SCRIPT')
if script_task.workspace_file:
+ task.script_task_id = script_task_id
task.workspace_file = script_task.workspace_file
task.save()
logger.info(f'Copied workspace file from script task {script_task_id} to xcos task {task.task_id}')
diff --git a/blocks/xcos2xml/replacesplitblocks.sh b/blocks/xcos2xml/replacesplitblocks.sh
index 3fe60922..c2e9ad07 100755
--- a/blocks/xcos2xml/replacesplitblocks.sh
+++ b/blocks/xcos2xml/replacesplitblocks.sh
@@ -2,12 +2,12 @@
usage() {
echo "Usage:" >&2
- echo " $0 input-file.xcos" >&2
- echo " $0 input-file.xml" >&2
+ echo " $0 input-file.xcos workspace.dat" >&2
+ echo " $0 input-file.xml workspace.dat" >&2
exit 101
}
-if test $# -ne 1; then
+if test $# -ne 1 -a $# -ne 2; then
usage
fi
@@ -60,6 +60,18 @@ else
usage
fi
+WORKSPACE="$2"
+if test -n "$WORKSPACE"; then
+ if test ! -f "$WORKSPACE"; then
+ echo "$WORKSPACE: not found" >&2
+ usage
+ fi
+ if test "${WORKSPACE%.dat}" = "$WORKSPACE"; then
+ echo "$WORKSPACE: not dat" >&2
+ usage
+ fi
+fi
+
set -e
TMPFILE1="$(mktemp -t XXXXXX.xml)"
@@ -145,8 +157,8 @@ INPUT1="$BASE-$rv.xml"
xmllint --format "$INPUT1" >"$TMPFILE2"
cp -f "$TMPFILE2" "$INPUT1"
-echo "Running Xcos/MxGraphParser.py $INPUT1" >&2
-Xcos/MxGraphParser.py "$INPUT1" >&2
+echo "Running Xcos/MxGraphParser.py $INPUT1 $WORKSPACE" >&2
+Xcos/MxGraphParser.py "$INPUT1" "$WORKSPACE" >&2
INPUT1="$BASE.xcos"
echo "Created $INPUT1" >&2