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