summaryrefslogtreecommitdiff
path: root/src/main/SendLog.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/SendLog.py')
-rwxr-xr-xsrc/main/SendLog.py206
1 files changed, 206 insertions, 0 deletions
diff --git a/src/main/SendLog.py b/src/main/SendLog.py
new file mode 100755
index 0000000..9f0af39
--- /dev/null
+++ b/src/main/SendLog.py
@@ -0,0 +1,206 @@
+## Hrishi Hiraskar
+## 23 October 2016
+
+import gevent
+import time
+import os
+import threading
+from gevent import monkey
+from gevent.pywsgi import WSGIServer
+from flask import Flask, request, Response, render_template, send_from_directory
+from werkzeug import secure_filename
+
+monkey.patch_all(aggressive=False)
+
+import subprocess
+
+app = Flask(__name__, static_folder='webapp/')
+
+# This is the path to the upload directory
+app.config['UPLOAD_FOLDER'] = 'uploads/'
+# These are the extension that we are accepting to be uploaded
+app.config['ALLOWED_EXTENSIONS'] = set(['zcos', 'xcos'])
+
+# Delay time to look for new line (in s)
+LOOK_DELAY = 0.1
+# States of the line
+INITIALIZATION = 0
+ENDING = 1
+DATA = 2
+NOLINE = -1
+# Scilab dir, can't run absolute paths
+SCI = "../../../../scilab/scilab_master_old/scilab/"
+# List to store figure IDs
+figure_list = []
+# List to store filenames of files
+xcos_file_list = []
+
+class line_and_state:
+ # Class to store the line and its state
+ line = None
+ state = NOLINE
+ def __init__(self, line, state):
+ self.line = line
+ self.state = state
+ def set(self, line_state):
+ self.line = line_state[0]
+ self.state = line_state[1]
+ return False
+ def get_line(self):
+ return self.line
+ def get_state(self):
+ return self.state
+
+def parse_line(line):
+ # Function to parse the line
+ # Returns tuple of figure ID and state
+ # state = INITIALIZATION if new figure is created
+ # ENDING if current fig end
+ # DATA otherwise
+ line_words = line.split(' ')
+ if line_words[2] == "Initialization":
+ # New figure created
+ # Get fig id
+ figure_id = int(line_words[-1])
+ return (figure_id, INITIALIZATION)
+ elif line_words[2] == "Ending":
+ # Current figure end
+ # Get fig id
+ figure_id = int(line_words[-1])
+ return (figure_id, ENDING)
+ else:
+ # Current figure coordinates
+ figure_id = int(line_words[2])
+ return (figure_id, DATA)
+
+def get_line_and_state(file):
+ # Function to get a new line from file
+ # This also parses the line and appends new figures to figure List
+ global figure_list
+ line = file.readline()
+ if not line:
+ return (None, NOLINE)
+ parse_result = parse_line(line)
+ figure_id = parse_result[0]
+ state = parse_result[1]
+ if state == INITIALIZATION:
+ # New figure created
+ # Add figure ID to list
+ figure_list.append(figure_id)
+ return (None, INITIALIZATION)
+ elif state == ENDING:
+ # End of figure
+ # Remove figure ID from list
+ figure_list.remove(figure_id)
+ return (None, ENDING)
+ return (line, DATA)
+
+def event_stream(xcos_file_id):
+ global figure_list
+ # If no id is sent, return
+ if(len(xcos_file_id)==0):
+ return
+ xcos_file_id = int(xcos_file_id)
+ xcos_file_dir = os.getcwd() + '/uploads/'
+ xcos_file_name = xcos_file_list[xcos_file_id]
+ # Get previously running scilab process IDs
+ proc = subprocess.Popen("pgrep scilab", stdout=subprocess.PIPE, shell=True)
+ # out will contain output of command, the list of process IDs of scilab
+ (out, err) = proc.communicate()
+ _l = len(out)
+ # Run xcos file
+ command = ["./"+SCI+"bin/scilab-adv-cli", "-nogui", "-noatomsautoload", "-nb", "-nw", "-e", "loadXcosLibs();importXcosDiagram('" + xcos_file_dir + xcos_file_name + "');xcos_simulate(scs_m,4);mode(2);quit()"]
+ scilab_proc = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=False);
+ # Wait till xcos is launched
+ while len(out) == _l:
+ # If length of out equals _l,
+ # it means scilab hasn't launched yet
+ # Wait
+ gevent.sleep(LOOK_DELAY)
+ # Get process IDs of scilab instances
+ proc = subprocess.Popen("pgrep scilab", stdout=subprocess.PIPE, shell=True)
+ # out will contain output of command, the list of process IDs of scilab
+ (out, err) = proc.communicate()
+ # out will contain output of command, the list of process IDs of scilab
+ # Get the latest process ID of scilab
+ pid = out.split()[-1]
+ # Define function to kill scilab(if still running) and remove files
+ def kill_scilab():
+ # Kill scilab by it's pid
+ subprocess.Popen(["kill","-9",pid])
+ # Remove log file
+ subprocess.Popen(["rm",log_dir+log_name])
+ # Remove xcos file
+ subprocess.Popen(["rm",xcos_file_dir+xcos_file_name])
+ # Log file directory
+ # As the scilab process is spawned by this script
+ # the log directory is same as that of this script
+ log_dir = ""
+ # Log file name
+ log_name = "scilab-log-"+pid+".txt"
+ # Open the log file
+ log_file = open(log_dir + log_name, "w+")
+ # Kill scilab-adv-cli, if running and get it's output
+ # If the simulation is error free, no output is generated
+ scilab_proc.kill()
+ (scilab_out, scilab_err) = scilab_proc.communicate();
+ # Check for empty diagram
+ if "Empty diagram" in scilab_out:
+ yield "event: ERROR\ndata: Empty diagram\n\n"
+ kill_scilab();
+ return
+ # Some other error
+ elif len(scilab_out) > 0:
+ yield "event: ERROR\ndata: " + scilab_out + "\n\n"
+ kill_scilab();
+ return
+ # Start sending log
+ line = line_and_state(None, NOLINE)
+ while (line.set(get_line_and_state(log_file)) or line.get_state() != ENDING or len(figure_list) > 0):
+ # Get the line and loop until the state is ENDING and figure_list empty
+ if line.get_state() != DATA:
+ gevent.sleep(LOOK_DELAY)
+ else:
+ yield "event: log\ndata: "+line.get_line()+"\n\n"
+ # Reset line, so server won't send same line twice
+ line = line_and_state(None, NOLINE)
+ # Finished Sending Log
+ kill_scilab()
+ # Notify Client
+ yield "event: DONE\ndata: None\n\n"
+
+# Route that will process the file upload
+@app.route('/upload', methods=['POST'])
+def upload():
+ # Get the file
+ file = request.files['file']
+ # Check if the file is not null
+ if file:
+ # Make the filename safe, remove unsupported chars
+ client_id = len(xcos_file_list)
+ filename = str(client_id)+".xcos"
+ # Move the file form the temporal folder to
+ # the upload folder we setup
+ file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
+ xcos_file_list.append(filename)
+ return str(client_id)
+ else:
+ return "error"
+
+@app.route('/SendLog')
+def sse_request():
+ # Set response method to event-stream
+ return Response(event_stream(request.args.get('id', '')), mimetype='text/event-stream')
+
+@app.route('/<path:path>')
+def static_file(path):
+ return app.send_static_file(path)
+
+@app.route('/')
+def page():
+ return app.send_static_file('index.html')
+
+if __name__ == '__main__':
+ # Set server address 127.0.0.1:8001/
+ http_server = WSGIServer(('127.0.0.1', 8001), app)
+ http_server.serve_forever() \ No newline at end of file