summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSuchita Lad2025-03-26 18:01:40 +0530
committerSuchita Lad2025-03-26 18:01:40 +0530
commitfc774d0e4e111edac525ff545177d1a48c399e8d (patch)
tree2594f7d7bda8ad7653704508c80c8e3207fcef07
parent6a29c484e21bf1aff7cbf090ccba0e7381100fcd (diff)
downloadCommon-Interface-Project-fc774d0e4e111edac525ff545177d1a48c399e8d.tar.gz
Common-Interface-Project-fc774d0e4e111edac525ff545177d1a48c399e8d.tar.bz2
Common-Interface-Project-fc774d0e4e111edac525ff545177d1a48c399e8d.zip
Updated uploadscript function
-rw-r--r--blocks/simulationAPI/helpers/config.py2
-rw-r--r--blocks/simulationAPI/helpers/ngspice_helper.py2
-rw-r--r--blocks/simulationAPI/helpers/scilab_manager.py112
-rw-r--r--blocks/simulationAPI/tasks.py24
-rw-r--r--blocks/simulationAPI/urls.py2
-rw-r--r--blocks/simulationAPI/views.py18
6 files changed, 93 insertions, 67 deletions
diff --git a/blocks/simulationAPI/helpers/config.py b/blocks/simulationAPI/helpers/config.py
index 9bc8bce3..c1593a68 100644
--- a/blocks/simulationAPI/helpers/config.py
+++ b/blocks/simulationAPI/helpers/config.py
@@ -21,3 +21,5 @@ SPECIAL_CHARACTERS = r'["\'\\]'
# The directory where images are created
IMAGEDIR = 'images'
+
+REMOVEFILE = True
diff --git a/blocks/simulationAPI/helpers/ngspice_helper.py b/blocks/simulationAPI/helpers/ngspice_helper.py
index c5eb8e71..ad4fd778 100644
--- a/blocks/simulationAPI/helpers/ngspice_helper.py
+++ b/blocks/simulationAPI/helpers/ngspice_helper.py
@@ -137,7 +137,7 @@ def ExecXml(task, task_name):
os.close(LOGFILEFD)
update_task_status(task_id, 'STREAMING',
- meta={'current_process': 'Processed Xml, Streaming Output'})
+ meta={'current_process': 'Processed Xml, Streaming Output'})
cmd = "try;"
cmd += "chdir('%s');" % current_dir
diff --git a/blocks/simulationAPI/helpers/scilab_manager.py b/blocks/simulationAPI/helpers/scilab_manager.py
index 79000d91..6e40bc3f 100644
--- a/blocks/simulationAPI/helpers/scilab_manager.py
+++ b/blocks/simulationAPI/helpers/scilab_manager.py
@@ -17,6 +17,7 @@ from threading import current_thread
from time import time
import unicodedata
import uuid
+import logging
from simulationAPI.helpers import config
@@ -66,7 +67,8 @@ SCILAB_CMD = [SCILAB,
"-nouserstartup",
"-nb",
"-nw",
- "-e", SCILAB_START]
+ "-e", SCILAB_START
+ ]
USER_DATA = {}
@@ -615,15 +617,22 @@ def prestart_scilab():
return (proc, log_name)
-def run_scilab(command, base, createlogfile=False, timeout=70):
+def run_scilab(command, base, createlogfile=False, timeout=1800):
instance = get_scilab_instance()
if instance is None:
logger.error('cannot run command %s', command)
return None
- cmd = command + SCILAB_END
+ logger.info('Scilab instance log file: %s', instance.log_name)
+ cmd = command + SCILAB_END + '\n'
logger.info('running command %s', cmd)
instance.proc.stdin.write(cmd)
+ instance.proc.stdin.flush()
+
+ # output, error = instance.proc.communicate(timeout=timeout)
+ # with open(instance.log_name, 'a') as log:
+ # log.write(output if output else '')
+ # log.write(error if error else '')
if not createlogfile:
remove(instance.log_name)
@@ -673,17 +682,20 @@ def uploadscript(session, task):
'''
Below route is called for uploading script file.
'''
- (script, sessiondir) = add_script(session)
+ (script, sessiondir) = add_script(session, task)
- file = task.file.name
+ file = task.file
if not file:
msg = "Upload Error\n"
rv = {'msg': msg}
- return JsonResponse(rv)
+ return rv
fname = join(sessiondir, SCRIPT_FILES_FOLDER,
script.script_id + '_script.sce')
- file.save(fname)
+ # file.save(fname)
+ with open(fname, 'wb+') as destination:
+ for chunk in file.chunks():
+ destination.write(chunk)
script.filename = fname
if is_unsafe_script(fname):
@@ -691,25 +703,30 @@ def uploadscript(session, task):
"Please edit the script again.\n")
script.status = -1
rv = {'status': script.status, 'msg': msg}
- return JsonResponse(rv)
+ return rv
- wfname = join(sessiondir, SCRIPT_FILES_FOLDER,
+ wfname = join(sessiondir, WORKSPACE_FILES_FOLDER,
script.script_id + '_script_workspace.dat')
script.workspace_filename = wfname
- command = "exec('%s');save('%s');" % (fname, wfname)
+ command = "try;exec('%s');save('%s');" % (fname, wfname)
script.instance = run_scilab(command, script)
+
if script.instance is None:
msg = "Resource not available"
script.status = -2
rv = {'status': script.status, 'msg': msg}
- return JsonResponse(rv)
+ return rv
+
+ # Save workspace file in task model
+ task.workspace_file = wfname
+ task.save()
msg = ''
script.status = 1
- rv = {'script_id': script.script_id, 'status': script.status, 'msg': msg}
- return JsonResponse(rv)
+ rv = {'task_id': task.task_id, 'script_id': script.script_id, 'status': script.status, 'msg': msg}
+ return rv
def clean_output(s):
@@ -724,24 +741,24 @@ def clean_output(s):
return s
-def getscriptoutput(session):
+def getscriptoutput(session, task):
'''
Below route is called for uploading script file.
'''
- script = get_script(session, get_script_id())
+ script = get_script(session, task)
if script is None:
# when called with same script_id again or with incorrect script_id
logger.warning('no script')
msg = "no script"
rv = {'msg': msg}
- return JsonResponse(rv)
+ return rv
instance = script.instance
if instance is None:
logger.warning('no instance')
msg = "no instance"
rv = {'msg': msg}
- return JsonResponse(rv)
+ return rv
proc = instance.proc
@@ -758,7 +775,7 @@ def getscriptoutput(session):
msg = 'Script stopped'
script.status = -5
rv = {'status': script.status, 'msg': msg, 'output': output}
- return JsonResponse(rv)
+ return rv
if returncode > 0:
logger.info('return code is %s', returncode)
if output:
@@ -771,7 +788,7 @@ def getscriptoutput(session):
"Please edit the script and execute again.\n")
script.status = -3
rv = {'status': script.status, 'msg': msg, 'output': output}
- return JsonResponse(rv)
+ return rv
logger.info('workspace for %s saved in %s',
script.script_id, script.workspace_filename)
@@ -786,7 +803,7 @@ def getscriptoutput(session):
msg = "Resource not available"
script.status = -2
rv = {'status': script.status, 'msg': msg}
- return JsonResponse(rv)
+ return rv
proc = instance.proc
listoutput = proc.communicate(timeout=10)[0]
@@ -799,7 +816,7 @@ def getscriptoutput(session):
msg = 'Script stopped'
script.status = -5
rv = {'status': script.status, 'msg': msg, 'output': listoutput}
- return JsonResponse(rv)
+ return rv
if returncode > 0:
logger.info('return code is %s', returncode)
if listoutput:
@@ -815,19 +832,19 @@ def getscriptoutput(session):
rv = {'script_id': script.script_id, 'status': script.status,
'msg': msg, 'output': output, 'returncode': returncode,
'variables': variables}
- return JsonResponse(rv)
+ return rv
except subprocess.TimeoutExpired:
kill_script(script)
msg = 'Timeout'
script.status = -4
rv = {'status': script.status, 'msg': msg}
- return JsonResponse(rv)
+ return rv
except UnicodeDecodeError:
kill_script(script)
msg = 'Unicode Decode Error'
script.status = -6
rv = {'status': script.status, 'msg': msg}
- return JsonResponse(rv)
+ return rv
def sendfile(session):
@@ -1101,37 +1118,32 @@ def add_diagram(session):
return (diagram, scripts, sessiondir)
-def get_script(session, script_id, scripts=None, remove=False):
- if script_id is None:
- return None
- if not script_id:
- logger.warning('no id')
+def get_script(session, task, scripts=None, remove=False):
+ if task is None:
return None
if scripts is None:
(__, scripts, __, __, __, __, __) = init_session(session)
- if script_id not in scripts:
- logger.warning('id %s not in scripts', script_id)
+ if task.task_id not in scripts:
+ logger.warning('id %s not in scripts', task.task_id)
return None
- script = scripts[script_id]
+ script = scripts[task.task_id]
if remove:
- del scripts[script_id]
+ del scripts[task.task_id]
return script
-def add_script(session):
- (__, scripts, getscriptcount, __, __, sessiondir, __) = init_session(session)
-
- script_id = getscriptcount()
+def add_script(session, task):
+ (__, scripts, __, __, __, sessiondir, __) = init_session(session)
script = Script()
- script.script_id = script_id
+ script.script_id = task.task_id
script.sessiondir = sessiondir
- scripts[script_id] = script
+ scripts[task.task_id] = script
return (script, sessiondir)
@@ -1192,24 +1204,6 @@ def get_request_id(request, key='id'):
return ''
-def get_script_id(request, key='script_id', default=''):
- form = request.form
- if form is None:
- logger.warning('No form in request')
- return default
- if key not in form:
- logger.warning('No %s in request.form', key)
- return default
- value = form[key]
- if re.fullmatch(r'[0-9]+', value):
- return value
- displayvalue = value if len(
- value) <= DISPLAY_LIMIT + 3 else value[:DISPLAY_LIMIT] + '...'
- logger.warning('Invalid value %s for %s in request.form',
- displayvalue, key)
- return default
-
-
def internal_fun(session, task, internal_key):
(__, __, __, scifile, __, sessiondir, __) = init_session(session)
@@ -1335,10 +1329,10 @@ def kill_scilab(diagram=None, session=None):
stopDetailsThread(diagram)
-def kill_script(script=None, session=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, get_script_id(), remove=True)
+ script = get_script(session, task, remove=True)
if script is None:
# when called with same script_id again or with incorrect script_id
logger.warning('no script')
diff --git a/blocks/simulationAPI/tasks.py b/blocks/simulationAPI/tasks.py
index e13c73bb..fe3d32b8 100644
--- a/blocks/simulationAPI/tasks.py
+++ b/blocks/simulationAPI/tasks.py
@@ -8,6 +8,7 @@ import traceback
from blocks.celery_tasks import app
from simulationAPI.helpers.ngspice_helper import ExecXml, update_task_status
from simulationAPI.models import Task
+from simulationAPI.helpers.scilab_manager import uploadscript
logger = get_task_logger(__name__)
@@ -27,6 +28,7 @@ def release_lock(lock):
def process_task(self, task_id):
task = Task.objects.get(task_id=task_id)
session_id = task.session.session_id
+ task_type = task.type
current_thread().name = f"{session_id[:6]}:{task_id[:8]}"
lock = acquire_lock(session_id) # Prevent multiple runs per session
@@ -37,16 +39,24 @@ def process_task(self, task_id):
update_task_status(task_id, 'STARTED',
meta={'current_process': 'Started Processing File'})
- output = ExecXml(task, self.name)
- if output == "Streaming":
+ if task_type == 'SCRIPT':
+ output = uploadscript(task.session, task)
state = 'STREAMING'
- current_process = 'Processed Xml, Streaming Output'
- elif output == "Success":
- state = 'SUCCESS'
- current_process = 'Processed Xml, Loading Output'
+ current_process = 'Processed Script, Streaming Output'
+ else:
+ output = ExecXml(task, self.name)
+ # Set default values
+ # state = 'FAILED'
+ # current_process = 'Unknown error occurred'
+ if output == "Streaming":
+ state = 'STREAMING'
+ current_process = 'Processed Xml, Streaming Output'
+ elif output == "Success":
+ state = 'SUCCESS'
+ current_process = 'Processed Xml, Loading Output'
update_task_status(task_id, state,
- meta={'current_process': current_process})
+ meta={'current_process': current_process})
return output
except Exception as e:
diff --git a/blocks/simulationAPI/urls.py b/blocks/simulationAPI/urls.py
index 5e37d066..04d91a2e 100644
--- a/blocks/simulationAPI/urls.py
+++ b/blocks/simulationAPI/urls.py
@@ -18,4 +18,6 @@ urlpatterns = [
path('cancel/<uuid:task_id>', simulationAPI_views.CancelTaskView.as_view(), name='cancel'),
path('get_session', simulationAPI_views.get_session, name='get_session'),
+
+ path('get_script_output/<uuid:task_id>', simulationAPI_views.GetScriptOutputView.as_view(), name='get_script_output'),
]
diff --git a/blocks/simulationAPI/views.py b/blocks/simulationAPI/views.py
index dd1a7758..e5ffe344 100644
--- a/blocks/simulationAPI/views.py
+++ b/blocks/simulationAPI/views.py
@@ -18,6 +18,7 @@ from simulationAPI.negotiation import IgnoreClientContentNegotiation
from simulationAPI.serializers import TaskSerializer
from simulationAPI.tasks import process_task
from simulationAPI.helpers.ngspice_helper import CreateXcos
+from simulationAPI.helpers.scilab_manager import getscriptoutput
SCILAB_INSTANCE_TIMEOUT_INTERVAL = 300
@@ -353,6 +354,23 @@ class StreamView(APIView):
yield "event: DONE\ndata: None\n\n"
+class GetScriptOutputView(APIView):
+ """
+ API endpoint to get the output of a script execution.
+ """
+
+ def get(self, request, task_id, *args, **kwargs):
+
+ task = Task.objects.get(task_id=task_id)
+ session = task.session
+ try:
+ result = getscriptoutput(session, task)
+ return Response(result, status=status.HTTP_200_OK)
+ except Exception as e:
+ logger.error(f"Error calling getscriptoutput (Session: {session}): {str(e)}")
+ return Response({"error": "Internal server error"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
+
+
def get_session(request):
if not request.session.session_key:
request.session.save() # Create a new session if not already exists