summaryrefslogtreecommitdiff
path: root/testing/SendLog/SendLog.py
blob: fbf646fd4c8375be349911080dc53a5897f838a9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
## Hrishi Hiraskar
## 23 October 2016

import gevent
import time
import subprocess
from gevent import monkey
from gevent.pywsgi import WSGIServer
from flask import Flask, request, Response, render_template, send_from_directory

monkey.patch_all()

app = Flask(__name__, static_folder='')

# 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
# List to store figure IDs
figure_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():
	global figure_list
	# 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
	subprocess.Popen("./../../bin/xcos")
	# 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]
	# 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, "a+")
	# Seek the file pointer to the end of file
	# 0 signifies the displacement index relative to given position and
	# 2 signifies the position (here, end of file; 0 is for start of file and 1 is for current position)
	# Refer https://www.tutorialspoint.com/python/file_seek.htm for more
	log_file.seek(0,2)
	# 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
		line = line_and_state(None, NOLINE)
	# Finished Sending Log
	# Exit xcos
	subprocess.Popen(["kill","-9",pid])
	# Remove log file, so server won't send same line twice
	subprocess.Popen(["rm",log_dir+log_name])
	# Notify Client
	yield "event: DONE\ndata: None\n\n";
		
@app.route('/SendLog')
def sse_request():
	# Set response method to event-stream
	return Response(event_stream(), 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()