-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathserver.py
109 lines (87 loc) · 3.07 KB
/
server.py
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
from flask import Flask, request
from flask_socketio import SocketIO, emit
import os
import compiler
import singleton
import settings
app = Flask('javaplay', static_url_path='', static_folder=settings.static_dir)
import logging
logging.getLogger('werkzeug').setLevel(logging.WARNING)
socketio = SocketIO(app, async_mode='threading')
class Callbacks:
def __init__(self, socketio, sid):
self._sock = socketio
self._sid = sid
self._emit('started', {})
def _emit(self, key, msg):
self._sock.emit(key, msg, room=self._sid, namespace="/compiler")
def compiled(self, ecode, logs):
self._emit('compiled', {'ecode': ecode, 'logs': logs.decode('utf-8')})
def stdout(self, data):
self._emit('stdout', {'data': data.decode('utf-8')})
def stderr(self, data):
self._emit('stderr', {'data': data.decode('utf-8')})
def stdin_ack(self, data):
self._emit('stdin_ack', {'data': data.decode('utf-8')})
def done(self, ecode):
self._emit('done', {'ecode': ecode})
def error(self, msg):
self._emit('backend_error', {'description': msg})
def reset_dir(path):
if os.path.isdir(path):
for root, dirs, files in os.walk(path, topdown=False):
for name in files:
os.remove(os.path.join(root, name))
for name in dirs:
os.rmdir(os.path.join(root, name))
else:
os.makedirs(path)
sid_program_map = {}
def map_kill(sid):
if sid in sid_program_map:
sid_program_map[sid].kill()
del sid_program_map[sid]
@app.route('/')
def root():
return app.send_static_file('index.html')
@socketio.on('compile', namespace="/compiler")
def compile(msg):
sid = request.sid
print("compile:", sid)
prog_dir = os.path.join(settings.sessions_dir, sid)
reset_dir(prog_dir)
prog = compiler.Program(msg, prog_dir, Callbacks(socketio, sid))
prog.spawn_bg()
map_kill(sid)
sid_program_map[sid] = prog
@socketio.on('kill', namespace="/compiler")
def kill(msg):
sid = request.sid
print("kill:", sid)
map_kill(sid)
@socketio.on('stdin', namespace="/compiler")
def stdin(data):
sid = request.sid
print("stdin:", sid)
if sid in sid_program_map:
sid_program_map[sid].stdin(data.encode('utf-8'))
@socketio.on('connect', namespace="/compiler")
def connect():
print("connected:", request.sid)
@socketio.on('disconnect', namespace="/compiler")
def disconnect():
sid = request.sid
print("disconnected:", sid)
map_kill(sid)
if settings.is_frozen or __name__ == "__main__":
lockpath = os.path.join(settings.root_dir, 'instance.lock')
with singleton.InstanceFileLock(lockpath):
if not os.path.isdir(settings.sessions_dir):
os.makedirs(settings.sessions_dir)
print()
print(" +-----------------------------------------+")
print(" | Compiler Backend listening on port 8040 |")
print(" | Keep this running in background... |")
print(" +-----------------------------------------+")
print()
socketio.run(app, port=8040)