ambiente-prova/main.go
2025-08-23 19:51:01 -03:00

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")
}