python works
This commit is contained in:
commit
7482f8e1bf
9 changed files with 456 additions and 0 deletions
46
.air.toml
Normal file
46
.air.toml
Normal file
|
@ -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
|
10
go.mod
Normal file
10
go.mod
Normal file
|
@ -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
|
6
go.sum
Normal file
6
go.sum
Normal file
|
@ -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=
|
58
main.go
Normal file
58
main.go
Normal file
|
@ -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()))
|
||||||
|
}
|
||||||
|
}
|
63
runtime.go
Normal file
63
runtime.go
Normal file
|
@ -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
|
||||||
|
}
|
268
source.py
Normal file
268
source.py
Normal file
|
@ -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'<color={color_mapping[color_code]}>'
|
||||||
|
else:
|
||||||
|
translated_code += f'<color={color_code}>'
|
||||||
|
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()
|
1
tmp/build-errors.log
Normal file
1
tmp/build-errors.log
Normal file
|
@ -0,0 +1 @@
|
||||||
|
exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1
|
BIN
tmp/main.exe
Normal file
BIN
tmp/main.exe
Normal file
Binary file not shown.
4
workspace/main.py
Normal file
4
workspace/main.py
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
import time
|
||||||
|
for i in range(50):
|
||||||
|
print(i)
|
||||||
|
time.sleep(0.5)
|
Loading…
Reference in a new issue