wide/output/outputs.go

122 lines
2.3 KiB
Go

package output
import (
"encoding/json"
"github.com/b3log/wide/session"
"github.com/golang/glog"
"github.com/gorilla/websocket"
"io"
"math/rand"
"net/http"
"os"
"os/exec"
)
var outputWS = map[string]*websocket.Conn{}
func WSHandler(w http.ResponseWriter, r *http.Request) {
session, _ := session.Store.Get(r, "wide-session")
sid := session.Values["id"].(string)
outputWS[sid], _ = websocket.Upgrade(w, r, nil, 1024, 1024)
ret := map[string]interface{}{"output": "Ouput initialized", "cmd": "init-output"}
outputWS[sid].WriteJSON(&ret)
glog.Infof("Open a new [Output] with session [%s], %d", sid, len(outputWS))
}
func RunHandler(w http.ResponseWriter, r *http.Request) {
session, _ := session.Store.Get(r, "wide-session")
sid := session.Values["id"].(string)
decoder := json.NewDecoder(r.Body)
var args map[string]interface{}
if err := decoder.Decode(&args); err != nil {
glog.Error(err)
http.Error(w, err.Error(), 500)
return
}
filePath := args["file"].(string)
fout, err := os.Create(filePath)
if nil != err {
glog.Error(err)
http.Error(w, err.Error(), 500)
return
}
code := args["code"].(string)
fout.WriteString(code)
if err := fout.Close(); nil != err {
glog.Error(err)
http.Error(w, err.Error(), 500)
return
}
argv := []string{"run", filePath}
cmd := exec.Command("go", argv...)
stdout, err := cmd.StdoutPipe()
if nil != err {
glog.Error(err)
http.Error(w, err.Error(), 500)
return
}
stderr, err := cmd.StderrPipe()
if nil != err {
glog.Error(err)
http.Error(w, err.Error(), 500)
return
}
reader := io.MultiReader(stdout, stderr)
cmd.Start()
rec := map[string]interface{}{}
go func(runningId int) {
glog.Infof("Session [%s] is running [id=%d, file=%s]", sid, runningId, filePath)
for {
buf := make([]byte, 1024)
count, err := reader.Read(buf)
if nil != err || 0 == count {
glog.Infof("Session [%s] 's running [id=%d, file=%s] has done", sid, runningId, filePath)
break
} else {
rec["output"] = string(buf[:count])
if nil != outputWS[sid] {
err := outputWS[sid].WriteJSON(&rec)
if nil != err {
glog.Error(err)
break
}
}
}
}
}(rand.Int())
ret, _ := json.Marshal(map[string]interface{}{"succ": true})
w.Header().Set("Content-Type", "application/json")
w.Write(ret)
}