commit 7482f8e1bfb1237395b3eb11fc62431334bd8ea2 Author: Merith-TK Date: Sat Mar 16 06:41:03 2024 -0700 python works diff --git a/.air.toml b/.air.toml new file mode 100644 index 0000000..90e83bf --- /dev/null +++ b/.air.toml @@ -0,0 +1,46 @@ +root = "." +testdata_dir = "testdata" +tmp_dir = "tmp" + +[build] + args_bin = [] + bin = "tmp\\main.exe" + cmd = "go build -o ./tmp/main.exe ." + delay = 1000 + exclude_dir = ["assets", "tmp", "vendor", "testdata"] + exclude_file = [] + exclude_regex = ["_test.go"] + exclude_unchanged = false + follow_symlink = false + full_bin = "" + include_dir = [] + include_ext = ["go", "tpl", "tmpl", "html"] + include_file = [] + kill_delay = "0s" + log = "build-errors.log" + poll = false + poll_interval = 0 + post_cmd = [] + pre_cmd = [] + rerun = false + rerun_delay = 500 + send_interrupt = false + stop_on_error = false + +[color] + app = "" + build = "yellow" + main = "magenta" + runner = "green" + watcher = "cyan" + +[log] + main_only = false + time = false + +[misc] + clean_on_exit = false + +[screen] + clear_on_rebuild = false + keep_scroll = true diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..eb9b11f --- /dev/null +++ b/go.mod @@ -0,0 +1,10 @@ +module bingus-exec + +go 1.21.3 + +require ( + github.com/gorilla/mux v1.8.1 + github.com/gorilla/websocket v1.5.1 +) + +require golang.org/x/net v0.22.0 // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..a1d0af7 --- /dev/null +++ b/go.sum @@ -0,0 +1,6 @@ +github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= +github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= diff --git a/main.go b/main.go new file mode 100644 index 0000000..c153673 --- /dev/null +++ b/main.go @@ -0,0 +1,58 @@ +package main + +import ( + "fmt" + "log" + "net/http" + "os" + "strings" + + "github.com/gorilla/websocket" +) + +const ( + WS_HOST = "0.0.0.0" + WS_PORT = 5000 +) + +var Upgrader = websocket.Upgrader{ + CheckOrigin: func(r *http.Request) bool { return true }, +} + +func main() { + http.HandleFunc("/", HandleWs) + + // if ./workspace/ directory does not exist, create it + if _, err := os.Stat("./workspace/"); os.IsNotExist(err) { + os.Mkdir("./workspace/", 0755) + } + + addr := fmt.Sprintf("%s:%d", WS_HOST, WS_PORT) + log.Println("Server started at", addr) + log.Fatal(http.ListenAndServe(addr, nil)) +} + +func HandleWs(w http.ResponseWriter, r *http.Request) { + c, err := Upgrader.Upgrade(w, r, nil) + if err != nil { + log.Print("upgrade:", err) + return + } + defer c.Close() + for { + // get the first line of the message from the client + _, message, err := c.ReadMessage() + if err != nil { + log.Println("read:", err) + break + } + // print the message to the console + log.Printf("recv: %s", message) + + // seperate message into chunks by newline + msg := strings.Split(string(message), "\n") + sendMessage := handleCase(msg[0], strings.Join(msg[1:], "\n")) + // send the message back to the client + err = c.WriteMessage(websocket.TextMessage, []byte(sendMessage.String())) + } +} diff --git a/runtime.go b/runtime.go new file mode 100644 index 0000000..ba86e6e --- /dev/null +++ b/runtime.go @@ -0,0 +1,63 @@ +package main + +import ( + "log" + "os/exec" + "strings" + + // import file writer + "os" + // import websocket +) + +func handleCase(caseName string, data string) strings.Builder { + // get the first line of the message from the client + // strip : from the caseName + caseName = strings.Replace(caseName, ":", "", -1) + returnData := strings.Builder{} + switch caseName { + case "py", "python", "python3": + log.Println("Python is not supported yet") + returnData = runPython(data) + case "go", "golang": + log.Println("Golang is not supported yet") + // returnData = runGo(data) + case "js", "javascript": + log.Println("Javascript is not supported yet") + // returnData = runJs(data) + case "cpp", "c++": + log.Println("C++ is not supported yet") + } + return returnData +} + +func runPython(data string) strings.Builder { + // write Data to `./workspace/main.py` + file, err := os.Create("./workspace/main.py") + if err != nil { + log.Println("Error creating file") + } + defer file.Close() + file.WriteString(data) + + // find python, python3, or py in the system + fname, err := exec.LookPath("python3") + if err != nil { + log.Println("Python not found") + } + + // run the python file + cmd := exec.Command(fname, "./workspace/main.py") + // write output to value, and then return it + cmdOut := &strings.Builder{} + cmd.Stdout = cmdOut + cmdErr := &strings.Builder{} + cmd.Stderr = cmdErr + cmd.Run() + + // combine the output and error + cmdOut.WriteString(cmdErr.String()) + // print the output to the console + log.Println(cmdOut.String()) + return *cmdOut +} diff --git a/source.py b/source.py new file mode 100644 index 0000000..c115790 --- /dev/null +++ b/source.py @@ -0,0 +1,268 @@ +import asyncio +import websockets +import pexpect +import os +import subprocess +import re + +WS_HOST = "127.0.0.1" +WS_PORT = 5000 +ws_port2 = 5001 +ws_port3 = 5002 +ws_port4 = 5003 +ws_port5 = 5004 +ws_port6 = 5005 +ws_port7 = 5006 +ws_port8 = 5007 +ws_port9 = 5008 +ws_port10 = 5009 + +SHELL = "/bin/bash" +TEMP_PYTHON_FILE = "code/temp.py" +TEMP_BASH_FILE = "code/temp.sh" +TEMP_CPP_FILE = "code/temp.cpp" +TEMP_NODE_FILE = "code/temp.js" +TEMP_GO_FILE = "code/temp.go" + +DIRECTORY= "code" +if not os.path.exists(DIRECTORY): + os.makedirs(DIRECTORY) +def translate_terminal_colors(code): + color_mapping = { + '0': 'black', + '1': 'red', + '2': 'green', + '3': 'yellow', + '4': 'blue', + '5': 'magenta', + '6': 'cyan', + '7': 'white', + '8': 'black', + '9': 'red', + '10': 'green', + '11': 'yellow', + '12': 'blue', + '13': 'magenta', + '14': 'cyan', + '15': 'white', + '9': 'red', + '10': 'green', + '11': 'yellow', + '12': 'blue', + '13': 'magenta', + '14': 'cyan', + '15': 'white', + '30': 'black', + '31': 'red', + '32': 'green', + '33': 'yellow', + '34': 'blue', + '35': 'magenta', + '36': 'cyan', + '37': 'white', + '100': 'black', + '101': 'red', + '110': 'green', + '111': 'yellow', + '112': 'blue', + '113': 'magenta', + '114': 'cyan', + '115': 'white', + '40': 'black', + '41': 'red', + '42': 'green', + '43': 'yellow', + '44': 'blue', + '45': 'magenta', + '46': 'cyan', + '47': 'white', + '100': 'black', + '101': 'red', + '102': 'green', + '103': 'yellow', + '104': 'blue', + '105': 'magenta', + '106': 'cyan', + '107': 'white', + '108': 'black' + + } + + translated_code = '' + i = 0 + while i < len(code): + if code[i] == '\x1b' and code[i+1] == '[': + j = i + 2 + while code[j].isdigit() or code[j] == ';': + j += 1 + if code[j] == 'm': + color_codes = code[i+2:j].split(';') + for color_code in color_codes: + if color_code in color_mapping: + translated_code += f'' + else: + translated_code += f'' + i = j + 1 + continue + translated_code += code[i] + i += 1 + + return translated_code +### START +async def execute_GO(code, websocket): + with open(TEMP_GO_FILE, 'w') as file: + file.write(code) + + child = pexpect.spawn(f"g++ {TEMP_GO_FILE} -o temp", encoding="utf-8") + + while True: + try: + index = child.expect(['\n', pexpect.EOF, pexpect.TIMEOUT], timeout=1) + if index == 0: + coded_text = translate_terminal_colors(child.before) + await websocket.send(coded_text) + elif index == 1: + coded_text = translate_terminal_colors(child.before) + await websocket.send(coded_text) + break + except pexpect.exceptions.TIMEOUT: + break + os.remove(TEMP_GO_FILE) + +async def GO(websocket, path): + try: + + async for code in websocket: + await execute_GO(code, websocket) + except websockets.exceptions.ConnectionClosedOK: + pass +#### END +### START +async def execute_CPP(code, websocket): + with open(TEMP_CPP_FILE, 'w') as file: + file.write(code) + + child = pexpect.spawn(f"g++ {TEMP_CPP_FILE} -o temp", encoding="utf-8") + + while True: + try: + index = child.expect(['\n', pexpect.EOF, pexpect.TIMEOUT], timeout=1) + if index == 0: + coded_text = translate_terminal_colors(child.before) + await websocket.send(coded_text) + elif index == 1: + coded_text = translate_terminal_colors(child.before) + await websocket.send(coded_text) + break + except pexpect.exceptions.TIMEOUT: + break + os.remove(TEMP_CPP_FILE) + +async def CPP(websocket, path): + try: + + async for code in websocket: + await execute_CPP(code, websocket) + except websockets.exceptions.ConnectionClosedOK: + pass +#### END +### START +async def execute_NODE(code, websocket): + with open(TEMP_NODE_FILE, 'w') as file: + file.write(code) + + child = pexpect.spawn(f"node {TEMP_NODE_FILE}", encoding="utf-8") + + while True: + try: + index = child.expect(['\n', pexpect.EOF, pexpect.TIMEOUT], timeout=1) + if index == 0: + coded_text = translate_terminal_colors(child.before) + await websocket.send(coded_text) + elif index == 1: + coded_text = translate_terminal_colors(child.before) + await websocket.send(coded_text) + break + except pexpect.exceptions.TIMEOUT: + break + os.remove(TEMP_NODE_FILE) + +async def NODE(websocket, path): + try: + async for code in websocket: + await execute_NODE(code, websocket) + except websockets.exceptions.ConnectionClosedOK: + pass +#### END +### START +async def execute_shell(code, websocket): + with open(TEMP_BASH_FILE, 'w') as file: + file.write(code) + + child = pexpect.spawn(f"/bin/bash {TEMP_BASH_FILE}", encoding="utf-8") + + while True: + try: + index = child.expect(['\n', pexpect.EOF, pexpect.TIMEOUT], timeout=1) + if index == 0: + coded_text = translate_terminal_colors(child.before) + await websocket.send(coded_text) + elif index == 1: + coded_text = translate_terminal_colors(child.before) + await websocket.send(coded_text) + break + except pexpect.exceptions.TIMEOUT: + break + os.remove(TEMP_BASH_FILE) + +async def shell(websocket, path): + try: + async for code in websocket: + await execute_shell(code, websocket) + except websockets.exceptions.ConnectionClosedOK: + pass +#### END +async def execute_code(code, websocket): + with open(TEMP_PYTHON_FILE, 'w') as file: + file.write(code) + + child = pexpect.spawn(f"python3 {TEMP_PYTHON_FILE}", encoding="utf-8") + + while True: + try: + index = child.expect(['\n', pexpect.EOF, pexpect.TIMEOUT], timeout=1) + if index == 0: + await websocket.send(child.before) + elif index == 1: + await websocket.send(child.before) + break + except pexpect.exceptions.TIMEOUT: + break + os.remove(TEMP_PYTHON_FILE) + +async def server(websocket, path): + try: + async for code in websocket: + await execute_code(code, websocket) + except websockets.exceptions.ConnectionClosedOK: + pass + + +ws_server = websockets.serve(server, WS_HOST, WS_PORT) +ws_shell = websockets.serve(shell, WS_HOST, ws_port2) +ws_node = websockets.serve(NODE, WS_HOST, ws_port3) +ws_cpp = websockets.serve(CPP, WS_HOST, ws_port4) +ws_go = websockets.serve(GO, WS_HOST, ws_port5) + + +print("Server started at port", WS_PORT) +print("Shell started at port", ws_port2) +print("Node started at port", ws_port3) +print("C++ started at port", ws_port4) +print("Go started at port", ws_port5) +asyncio.get_event_loop().run_until_complete(ws_go) +asyncio.get_event_loop().run_until_complete(ws_shell) +asyncio.get_event_loop().run_until_complete(ws_server) +asyncio.get_event_loop().run_until_complete(ws_node) +asyncio.get_event_loop().run_until_complete(ws_cpp) +asyncio.get_event_loop().run_forever() \ No newline at end of file diff --git a/tmp/build-errors.log b/tmp/build-errors.log new file mode 100644 index 0000000..6ccc48a --- /dev/null +++ b/tmp/build-errors.log @@ -0,0 +1 @@ +exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1 \ No newline at end of file diff --git a/tmp/main.exe b/tmp/main.exe new file mode 100644 index 0000000..aaf86f2 Binary files /dev/null and b/tmp/main.exe differ diff --git a/workspace/main.py b/workspace/main.py new file mode 100644 index 0000000..5e1e9e0 --- /dev/null +++ b/workspace/main.py @@ -0,0 +1,4 @@ +import time +for i in range(50): + print(i) + time.sleep(0.5) \ No newline at end of file