175 lines
4.9 KiB
Go
175 lines
4.9 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type test struct {
|
|
path, output string
|
|
}
|
|
|
|
func main() {
|
|
|
|
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
|
|
|
r := gin.Default()
|
|
|
|
// r.StaticFS("/", gin.Dir("./view/", false))
|
|
r.StaticFile("", filepath.Join("view", "index.html"))
|
|
r.StaticFile("index.css", filepath.Join("view", "index.css"))
|
|
// r.StaticFile("", filepath.Join("view", "index.html"))
|
|
|
|
r.NoRoute(func(c *gin.Context) {
|
|
c.String(http.StatusNotFound, "404")
|
|
})
|
|
|
|
r.GET("/room/:id", func (c *gin.Context) {
|
|
id := c.Param("id")
|
|
})
|
|
|
|
r.POST("/answer", func (c *gin.Context) {
|
|
|
|
// log.Panic("foo")
|
|
|
|
language := c.PostForm("language");
|
|
if language == "" {
|
|
c.JSON(http.StatusBadRequest, gin.H{"status": "error"})
|
|
log.Panic(fmt.Errorf("null language"))
|
|
}
|
|
|
|
fmt.Println(language)
|
|
|
|
answer := c.PostForm("answer");
|
|
if answer == "" {
|
|
c.JSON(http.StatusBadRequest, gin.H{"status": "error", "message": "no answer"})
|
|
log.Panic(fmt.Errorf("null answer"))
|
|
}
|
|
|
|
uuid := uuid.NewString()
|
|
|
|
dirPath := filepath.Join("sandbox", uuid)
|
|
err := os.Mkdir(dirPath, 0755)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"status": "error"})
|
|
log.Panic(err)
|
|
}
|
|
defer os.RemoveAll(dirPath)
|
|
|
|
programPath := filepath.Join("sandbox", uuid, "program")
|
|
file, err := os.Create(programPath)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"status": "error"})
|
|
log.Panic(err)
|
|
}
|
|
|
|
_, err = file.Write([]byte(answer))
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"status": "error"})
|
|
log.Panic(err)
|
|
}
|
|
|
|
var tests []test
|
|
testsDirPath := filepath.Join("test", "teste1")
|
|
testDirs, err := os.ReadDir(testsDirPath)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"status": "error"})
|
|
log.Panic(err)
|
|
}
|
|
|
|
for _, testDir := range testDirs {
|
|
testDirFilePath := filepath.Join(testsDirPath, testDir.Name())
|
|
|
|
inputOuptut, err := os.ReadDir(testDirFilePath)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"status": "error"})
|
|
log.Panic(err)
|
|
}
|
|
if len(inputOuptut) != 2 {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"status": "error"})
|
|
log.Panic(len(inputOuptut) != 2)
|
|
}
|
|
|
|
inputPath := filepath.Join(testDirFilePath, inputOuptut[0].Name())
|
|
|
|
output, err := os.ReadFile(filepath.Join(testDirFilePath, inputOuptut[1].Name()))
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"status": "error"})
|
|
log.Panic(err)
|
|
}
|
|
|
|
// fmt.Println("output:", string(output))
|
|
tests = append(tests, test{
|
|
path: inputPath,
|
|
output: string(output),
|
|
})
|
|
|
|
}
|
|
|
|
|
|
for _, test := range tests {
|
|
|
|
input, err := os.ReadFile(test.path)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"status": "error"})
|
|
log.Panic(err)
|
|
}
|
|
|
|
var cmd *exec.Cmd
|
|
|
|
switch language {
|
|
case "python":
|
|
cmd = exec.Command("python", programPath)
|
|
default:
|
|
c.JSON(http.StatusInternalServerError, gin.H{"status": "error"})
|
|
log.Panic(fmt.Errorf("unregonized language: \"%s\"", language))
|
|
}
|
|
|
|
stdin, _ := cmd.StdinPipe()
|
|
|
|
io.WriteString(stdin, string(input))
|
|
|
|
stderr, _ := cmd.StderrPipe()
|
|
stdout, _ := cmd.StdoutPipe()
|
|
|
|
err = cmd.Start()
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"status": "error"})
|
|
log.Panic(err)
|
|
}
|
|
|
|
errBuf, err := io.ReadAll(stderr)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
outBuf, err := io.ReadAll(stdout)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
err = cmd.Wait()
|
|
if err != nil {
|
|
c.JSON(http.StatusOK, gin.H{"status": "comp-exec", "message": string(errBuf)})
|
|
return
|
|
}
|
|
|
|
if string(outBuf) != test.output {
|
|
msg := gin.H{"status": "wrong", "input": string(input), "output": string(outBuf), "expected": test.output}
|
|
c.JSON(http.StatusOK, msg)
|
|
return
|
|
}
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{"status": "pass", "id": 0, "success": "success"})
|
|
})
|
|
|
|
r.Run(":8001")
|
|
}
|