// DecompressHandler handles request of decompressing zip/tar.gz. func DecompressHandler(w http.ResponseWriter, r *http.Request) { data := map[string]interface{}{"succ": true} defer util.RetJSON(w, r, data) var args map[string]interface{} if err := json.NewDecoder(r.Body).Decode(&args); err != nil { logger.Error(err) data["succ"] = false return } path := args["path"].(string) // base := filepath.Base(path) dir := filepath.Dir(path) if !util.File.IsExist(path) { data["succ"] = false data["msg"] = "Can't find file [" + path + "] to descompress" return } err := util.Zip.Unzip(path, dir) if nil != err { logger.Error(err) data["succ"] = false return } }
func setCursorHandler(w http.ResponseWriter, r *http.Request) { data := map[string]interface{}{"succ": true} defer util.RetJSON(w, r, data) httpSession, _ := httpSessionStore.Get(r, "coditor-session") userSession := httpSession.Values[user_session] if nil == userSession { data["succ"] = false data["msg"] = "permission denied" return } var args map[string]interface{} if err := json.NewDecoder(r.Body).Decode(&args); err != nil { logger.Error(err) data["succ"] = false return } sid := args["sid"].(string) docName := args["docName"].(string) offset := args["offset"].(float64) color := args["color"].(string) user := userSession.(*User) md5Email := toMd5(user.Email) cursor := &Cursor{Sid: sid, Offset: int(offset), Username: user.Username, Color: color, Email: user.Email, Md5Email: md5Email} docName = filepath.Clean(docName) doc := documentHolder.getDoc(docName) doc.addCursor(cursor) }
// LoginHandler handles request of user login. func LoginHandler(w http.ResponseWriter, r *http.Request) { if "GET" == r.Method { // show the login page model := map[string]interface{}{"conf": conf.Wide, "i18n": i18n.GetAll(conf.Wide.Locale), "locale": conf.Wide.Locale, "ver": conf.WideVersion, "year": time.Now().Year()} t, err := template.ParseFiles("views/login.html") if nil != err { logger.Error(err) http.Error(w, err.Error(), 500) return } t.Execute(w, model) return } // non-GET request as login request succ := true data := map[string]interface{}{"succ": &succ} defer util.RetJSON(w, r, data) args := struct { Username string Password string }{} args.Username = r.FormValue("username") args.Password = r.FormValue("password") succ = false for _, user := range conf.Users { if user.Name == args.Username && user.Password == conf.Salt(args.Password, user.Salt) { succ = true break } } if !succ { return } // create a HTTP session httpSession, _ := HTTPSession.Get(r, "wide-session") httpSession.Values["username"] = args.Username httpSession.Values["id"] = strconv.Itoa(rand.Int()) httpSession.Options.MaxAge = conf.Wide.HTTPSessionMaxAge if "" != conf.Wide.Context { httpSession.Options.Path = conf.Wide.Context } httpSession.Save(r, w) logger.Debugf("Created a HTTP session [%s] for user [%s]", httpSession.Values["id"].(string), args.Username) }
func listCursorsHandler(w http.ResponseWriter, r *http.Request) { data := map[string]interface{}{"succ": true} defer util.RetJSON(w, r, data) httpSession, _ := httpSessionStore.Get(r, "coditor-session") userSession := httpSession.Values[user_session] if nil == userSession { data["succ"] = false data["msg"] = "permission denied" return } var args map[string]interface{} if err := json.NewDecoder(r.Body).Decode(&args); err != nil { logger.Error(err) data["succ"] = false return } docName := args["docName"].(string) doc := documentHolder.getDoc(docName) if doc == nil { data["succ"] = false data["msg"] = "Can not find the document." return } cursors := doc.getCursors() data["cursors"] = cursors }
func fetchDocHandler(w http.ResponseWriter, r *http.Request) { data := map[string]interface{}{"succ": true} defer util.RetJSON(w, r, data) var args map[string]interface{} if err := json.NewDecoder(r.Body).Decode(&args); err != nil { logger.Error(err) data["succ"] = false data["msg"] = "args decode error!" return } fileArgs := args["file"].(map[string]interface{}) if fileArgs == nil { data["succ"] = false data["msg"] = "args error!" return } fileName := fileArgs["name"].(string) fileVersion := DocVersion(uint32(fileArgs["version"].(float64))) httpSession, _ := httpSessionStore.Get(r, "coditor-session") userSession := httpSession.Values[user_session] if nil == userSession { data["succ"] = false data["msg"] = "permission denied" return } user := userSession.(*User) // FIXME: doc permission check docName := filepath.Clean(fileName) doc := documentHolder.getDoc(docName) if doc == nil { data["succ"] = false data["msg"] = "document not exist!" return } patchss, err := doc.tail(fileVersion, user.Username) if err != nil { data["succ"] = false data["msg"] = err.Error() return } data["patchss"] = patchss version, err := doc.getVersion(user.Username) if err != nil { data["succ"] = false data["msg"] = err.Error() return } data["version"] = version }
func GoFmtHandler(w http.ResponseWriter, r *http.Request) { data := map[string]interface{}{"succ": true} defer util.RetJSON(w, r, data) decoder := json.NewDecoder(r.Body) var args map[string]interface{} if err := decoder.Decode(&args); err != nil { glog.Error(err) data["succ"] = false return } filePath := args["file"].(string) fout, err := os.Create(filePath) if nil != err { glog.Error(err) data["succ"] = false return } code := args["code"].(string) fout.WriteString(code) if err := fout.Close(); nil != err { glog.Error(err) data["succ"] = false return } argv := []string{filePath} cmd := exec.Command("gofmt", argv...) bytes, _ := cmd.Output() output := string(bytes) if "" == output { data["succ"] = false return } code = string(output) data["code"] = code fout, err = os.Create(filePath) fout.WriteString(code) if err := fout.Close(); nil != err { glog.Error(err) data["succ"] = false return } }
// LogoutHandler handles request of user logout (exit). func LogoutHandler(w http.ResponseWriter, r *http.Request) { data := map[string]interface{}{"succ": true} defer util.RetJSON(w, r, data) httpSession, _ := HTTPSession.Get(r, "wide-session") httpSession.Options.MaxAge = -1 httpSession.Save(r, w) }
func getHeadDocHandler(w http.ResponseWriter, r *http.Request) { data := map[string]interface{}{"succ": true} defer util.RetJSON(w, r, data) var args map[string]interface{} if err := json.NewDecoder(r.Body).Decode(&args); err != nil { logger.Error(err) data["succ"] = false data["msg"] = "args decode error!" return } var fileName string fileNameArg := args["fileName"] if fileNameArg == nil { data["succ"] = false data["msg"] = "fileName can not bu nil." return } fileName = fileNameArg.(string) httpSession, _ := httpSessionStore.Get(r, "coditor-session") userSession := httpSession.Values[user_session] if nil == userSession { data["succ"] = false data["msg"] = "permission denied" return } user := userSession.(*User) // FIXME: doc permission check docName := filepath.Clean(fileName) doc := documentHolder.getDoc(docName) if doc == nil { data["succ"] = false data["msg"] = "document not exist!" return } output := make(map[string]interface{}) content, err := doc.getContents(user.Username) if err != nil { data["succ"] = false data["msg"] = err.Error() return } output["content"] = content version, _ := doc.getVersion(user.Username) output["version"] = version data["output"] = output }
// UploadHandler handles request of file upload. func UploadHandler(w http.ResponseWriter, r *http.Request) { data := map[string]interface{}{"succ": true} defer util.RetJSON(w, r, data) q := r.URL.Query() dir := q["path"][0] data["files"] = handleUploads(r, dir) }
func HTMLFmtHandler(w http.ResponseWriter, r *http.Request) { data := map[string]interface{}{"succ": true} defer util.RetJSON(w, r, data) decoder := json.NewDecoder(r.Body) var args map[string]interface{} if err := decoder.Decode(&args); err != nil { glog.Error(err) data["succ"] = false return } filePath := args["file"].(string) fout, err := os.Create(filePath) if nil != err { glog.Error(err) data["succ"] = false return } code := args["code"].(string) fout.WriteString(code) if err := fout.Close(); nil != err { glog.Error(err) data["succ"] = false return } output := gohtml.Format(code) if "" == output { data["succ"] = false return } code = string(output) data["code"] = code fout, err = os.Create(filePath) fout.WriteString(code) if err := fout.Close(); nil != err { glog.Error(err) data["succ"] = false return } }
// SaveFileHandler handles request of saving file. func SaveFileHandler(w http.ResponseWriter, r *http.Request) { httpSession, _ := session.HTTPSession.Get(r, "wide-session") if httpSession.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) return } username := httpSession.Values["username"].(string) data := map[string]interface{}{"succ": true} defer util.RetJSON(w, r, data) var args map[string]interface{} if err := json.NewDecoder(r.Body).Decode(&args); err != nil { logger.Error(err) data["succ"] = false return } filePath := args["file"].(string) sid := args["sid"].(string) if util.Go.IsAPI(filePath) || !session.CanAccess(username, filePath) { http.Error(w, "Forbidden", http.StatusForbidden) return } fout, err := os.Create(filePath) if nil != err { logger.Error(err) data["succ"] = false return } code := args["code"].(string) fout.WriteString(code) if err := fout.Close(); nil != err { logger.Error(err) data["succ"] = false wSession := session.WideSessions.Get(sid) wSession.EventQueue.Queue <- &event.Event{Code: event.EvtCodeServerInternalError, Sid: sid, Data: "can't save file " + filePath} return } }
// FindHandler handles request of find files under the specified directory with the specified filename pattern. func FindHandler(w http.ResponseWriter, r *http.Request) { httpSession, _ := session.HTTPSession.Get(r, "wide-session") if httpSession.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) return } username := httpSession.Values["username"].(string) data := map[string]interface{}{"succ": true} defer util.RetJSON(w, r, data) var args map[string]interface{} if err := json.NewDecoder(r.Body).Decode(&args); err != nil { logger.Error(err) data["succ"] = false return } path := args["path"].(string) // path of selected file in file tree if !util.Go.IsAPI(path) && !session.CanAccess(username, path) { http.Error(w, "Forbidden", http.StatusForbidden) return } name := args["name"].(string) userWorkspace := conf.GetUserWorkspace(username) workspaces := filepath.SplitList(userWorkspace) if "" != path && !util.File.IsDir(path) { path = filepath.Dir(path) } founds := foundPaths{} for _, workspace := range workspaces { rs := find(workspace+conf.PathSeparator+"src", name, []*string{}) for _, r := range rs { substr := util.Str.LCS(path, *r) founds = append(founds, &foundPath{Path: *r, score: len(substr)}) } } sort.Sort(founds) data["founds"] = founds }
func InitGitRepos(w http.ResponseWriter, r *http.Request) { data := map[string]interface{}{"succ": true} defer util.RetJSON(w, r, data) session, _ := Session.Get(r, "wide-session") username := session.Values["username"].(string) userRepos := conf.Wide.UserWorkspaces + string(os.PathSeparator) + username + string(os.PathSeparator) + "src" // TODO: git clone glog.Infof("Git Cloned from [%s] to [%s]", conf.Wide.Workspace+string(os.PathSeparator)+"src", userRepos) }
// RenameFileHandler handles request of renaming file or directory. func RenameFileHandler(w http.ResponseWriter, r *http.Request) { httpSession, _ := session.HTTPSession.Get(r, "wide-session") if httpSession.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) return } username := httpSession.Values["username"].(string) data := map[string]interface{}{"succ": true} defer util.RetJSON(w, r, data) var args map[string]interface{} if err := json.NewDecoder(r.Body).Decode(&args); err != nil { logger.Error(err) data["succ"] = false return } oldPath := args["oldPath"].(string) if util.Go.IsAPI(oldPath) || !session.CanAccess(username, oldPath) { http.Error(w, "Forbidden", http.StatusForbidden) return } newPath := args["newPath"].(string) if util.Go.IsAPI(newPath) || !session.CanAccess(username, newPath) { http.Error(w, "Forbidden", http.StatusForbidden) return } sid := args["sid"].(string) wSession := session.WideSessions.Get(sid) if !renameFile(oldPath, newPath) { data["succ"] = false wSession.EventQueue.Queue <- &event.Event{Code: event.EvtCodeServerInternalError, Sid: sid, Data: "can't rename file " + oldPath} return } logger.Debugf("Renamed a file [%s] to [%s] by user [%s]", oldPath, newPath, wSession.Username) }
func fileTreeHandler(w http.ResponseWriter, r *http.Request) { // XXX: it's a list now, not a tree data := map[string]interface{}{"succ": true} defer util.RetJSON(w, r, data) httpSession, _ := httpSessionStore.Get(r, "coditor-session") userSession := httpSession.Values[user_session] if nil == userSession { data["succ"] = false data["msg"] = "permission denied" return } user := userSession.(*User) names := listFiles(user.getWorkspace()) files := []*file{} for i, fname := range names { t := filepath.Ext(fname) if strings.HasPrefix(t, ".") { t = t[1:] } isShare := false var dmd *DocumentMetaData var err error docName := filepath.Join("workspaces", user.Username, "workspace", fname) doc := documentHolder.getDoc(docName) if doc != nil { dmd = doc.metaData } else { fileRelPath := filepath.Join(user.getWorkspace(), fname) dmd, err = newDocumentMetaData(fileRelPath) } if err != nil { // TODO how to handler this err? logger.Error(err) } else { if dmd.IsPublic == 1 || len(dmd.Editors) > 0 || len(dmd.Viewers) > 0 { isShare = true } } f := &file{ID: strconv.Itoa(i), IsShare: isShare, Name: fname, Type: t} files = append(files, f) } data["files"] = files }
// NewFileHandler handles request of creating file or directory. func NewFileHandler(w http.ResponseWriter, r *http.Request) { httpSession, _ := session.HTTPSession.Get(r, "wide-session") if httpSession.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) return } username := httpSession.Values["username"].(string) data := map[string]interface{}{"succ": true} defer util.RetJSON(w, r, data) var args map[string]interface{} if err := json.NewDecoder(r.Body).Decode(&args); err != nil { logger.Error(err) data["succ"] = false return } path := args["path"].(string) if util.Go.IsAPI(path) || !session.CanAccess(username, path) { http.Error(w, "Forbidden", http.StatusForbidden) return } fileType := args["fileType"].(string) sid := args["sid"].(string) wSession := session.WideSessions.Get(sid) if !createFile(path, fileType) { data["succ"] = false wSession.EventQueue.Queue <- &event.Event{Code: event.EvtCodeServerInternalError, Sid: sid, Data: "can't create file " + path} return } if "f" == fileType { logger.Debugf("Created a file [%s] by user [%s]", path, wSession.Username) } else { logger.Debugf("Created a dir [%s] by user [%s]", path, wSession.Username) } }
func getShareInfoHandler(w http.ResponseWriter, r *http.Request) { data := map[string]interface{}{"succ": true} defer util.RetJSON(w, r, data) httpSession, _ := httpSessionStore.Get(r, "coditor-session") userSession := httpSession.Values[user_session] if nil == userSession { data["succ"] = false data["msg"] = "permission denied" return } var args map[string]interface{} if err := json.NewDecoder(r.Body).Decode(&args); err != nil { logger.Error(err) data["succ"] = false data["msg"] = "args decode error!" return } docName := args["docName"] if docName == nil || len(docName.(string)) == 0 { data["succ"] = false data["msg"] = "docName can not be null!" return } filePath := docName.(string) // check file first metaDataFileName := filePath + ".json.coditor" absMetaDataFileName := filepath.Clean(metaDataFileName) file, err := os.Open(absMetaDataFileName) if err != nil { logger.Error(err) data["succ"] = false data["msg"] = err.Error() return } file.Close() dmd, err := newDocumentMetaData(filePath) if err != nil { logger.Error(err) data["succ"] = false data["msg"] = err.Error() return } data["shareInfo"] = dmd }
// CreateZipHandler handles request of creating zip. func CreateZipHandler(w http.ResponseWriter, r *http.Request) { data := map[string]interface{}{"succ": true} defer util.RetJSON(w, r, data) var args map[string]interface{} if err := json.NewDecoder(r.Body).Decode(&args); err != nil { logger.Error(err) data["succ"] = false return } path := args["path"].(string) var name string base := filepath.Base(path) if nil != args["name"] { name = args["name"].(string) } else { name = base } dir := filepath.Dir(path) if !util.File.IsExist(path) { data["succ"] = false data["msg"] = "Can't find file [" + path + "]" return } zipPath := filepath.Join(dir, name) zipFile, err := util.Zip.Create(zipPath + ".zip") if nil != err { logger.Error(err) data["succ"] = false return } defer zipFile.Close() if util.File.IsDir(path) { zipFile.AddDirectory(base, path) } else { zipFile.AddEntry(base, path) } data["path"] = zipPath }
// SearchTextHandler handles request of searching files under the specified directory with the specified keyword. func SearchTextHandler(w http.ResponseWriter, r *http.Request) { httpSession, _ := session.HTTPSession.Get(r, "wide-session") if httpSession.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) return } data := map[string]interface{}{"succ": true} defer util.RetJSON(w, r, data) var args map[string]interface{} if err := json.NewDecoder(r.Body).Decode(&args); err != nil { logger.Error(err) data["succ"] = false return } sid := args["sid"].(string) wSession := session.WideSessions.Get(sid) if nil == wSession { data["succ"] = false return } // XXX: just one directory dir := args["dir"].(string) if "" == dir { userWorkspace := conf.GetUserWorkspace(wSession.Username) workspaces := filepath.SplitList(userWorkspace) dir = workspaces[0] } extension := args["extension"].(string) text := args["text"].(string) founds := []*Snippet{} if util.File.IsDir(dir) { founds = search(dir, extension, text, []*Snippet{}) } else { founds = searchInFile(dir, text) } data["founds"] = founds }
func GetFile(w http.ResponseWriter, r *http.Request) { data := map[string]interface{}{"succ": true} defer util.RetJSON(w, r, data) decoder := json.NewDecoder(r.Body) var args map[string]interface{} if err := decoder.Decode(&args); err != nil { glog.Error(err) data["succ"] = false return } path := args["path"].(string) buf, _ := ioutil.ReadFile(path) extension := filepath.Ext(path) // 通过文件扩展名判断是否是图片文件(图片在浏览器里新建 tab 打开) if isImg(extension) { data["mode"] = "img" path2 := strings.Replace(path, "\\", "/", -1) idx := strings.Index(path2, "/data/user_workspaces") data["path"] = path2[idx:] return } isBinary := false // 判断是否是其他二进制文件 for _, b := range buf { if 0 == b { // 包含 0 字节就认为是二进制文件 isBinary = true } } if isBinary { // 是二进制文件的话前端编辑器不打开 data["succ"] = false data["msg"] = "Can't open a binary file :(" } else { data["content"] = string(buf) data["mode"] = getEditorMode(extension) } }
// BuildHandler handles request of Playground building. func BuildHandler(w http.ResponseWriter, r *http.Request) { data := map[string]interface{}{"succ": true} defer util.RetJSON(w, r, data) httpSession, _ := session.HTTPSession.Get(r, "wide-session") if httpSession.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) return } var args map[string]interface{} if err := json.NewDecoder(r.Body).Decode(&args); err != nil { logger.Error(err) data["succ"] = false return } fileName := args["fileName"].(string) filePath := filepath.Clean(conf.Wide.Playground + "/" + fileName) suffix := "" if util.OS.IsWindows() { suffix = ".exe" } executable := filepath.Clean(conf.Wide.Playground + "/" + strings.Replace(fileName, ".go", suffix, -1)) cmd := exec.Command("go", "build", "-o", executable, filePath) out, err := cmd.CombinedOutput() data["output"] = template.HTML(string(out)) if nil != err { data["succ"] = false return } data["executable"] = executable }
func RemoveFile(w http.ResponseWriter, r *http.Request) { data := map[string]interface{}{"succ": true} defer util.RetJSON(w, r, data) decoder := json.NewDecoder(r.Body) var args map[string]interface{} if err := decoder.Decode(&args); err != nil { glog.Error(err) data["succ"] = false return } path := args["path"].(string) if !removeFile(path) { data["succ"] = false } }
// ShortURLHandler handles request of short URL. func ShortURLHandler(w http.ResponseWriter, r *http.Request) { data := map[string]interface{}{"succ": true} defer util.RetJSON(w, r, data) session, _ := session.HTTPSession.Get(r, "wide-session") if session.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) return } var args map[string]interface{} if err := json.NewDecoder(r.Body).Decode(&args); err != nil { logger.Error(err) data["succ"] = false return } url := args["url"].(string) resp, _ := http.Post("http://dwz.cn/create.php", "application/x-www-form-urlencoded", strings.NewReader("url="+url)) var response map[string]interface{} if err := json.NewDecoder(resp.Body).Decode(&response); err != nil { logger.Error(err) data["succ"] = false return } shortURL := url if 0 == response["status"].(float64) { shortURL = response["tinyurl"].(string) } data["shortURL"] = shortURL }
func shareListHandler(w http.ResponseWriter, r *http.Request) { data := map[string]interface{}{"succ": true} defer util.RetJSON(w, r, data) httpSession, _ := httpSessionStore.Get(r, "coditor-session") userSession := httpSession.Values[user_session] if nil == userSession { data["succ"] = false data["msg"] = "permission denied" return } user := userSession.(*User) shareList, err := getOrInitShareFiles(user) if err != nil { data["succ"] = false data["msg"] = err.Error() return } data["shares"] = shareList }
// SaveContentHandler handles request of session content string. func SaveContentHandler(w http.ResponseWriter, r *http.Request) { data := map[string]interface{}{"succ": true} defer util.RetJSON(w, r, data) args := struct { Sid string *conf.LatestSessionContent }{} if err := json.NewDecoder(r.Body).Decode(&args); err != nil { logger.Error(err) data["succ"] = false return } wSession := WideSessions.Get(args.Sid) if nil == wSession { data["succ"] = false return } wSession.Content = args.LatestSessionContent for _, user := range conf.Users { if user.Name == wSession.Username { // update the variable in-memory, session.FixedTimeSave() function will persist it periodically user.LatestSessionContent = wSession.Content user.Lived = time.Now().UnixNano() wSession.Refresh() return } } }
// 构造用户工作空间文件树. // 将 Go API 源码包($GOROOT/src/pkg)也作为子节点,这样能方便用户查看 Go API 源码. func GetFiles(w http.ResponseWriter, r *http.Request) { data := map[string]interface{}{"succ": true} defer util.RetJSON(w, r, data) session, _ := user.Session.Get(r, "wide-session") username := session.Values["username"].(string) userSrc := conf.Wide.GetUserWorkspace(username) + string(os.PathSeparator) + "src" root := FileNode{Name: "projects", Path: userSrc, IconSkin: "ico-ztree-dir ", Type: "d", FileNodes: []*FileNode{}} // 构造 Go API 节点 apiPath := runtime.GOROOT() + string(os.PathSeparator) + "src" + string(os.PathSeparator) + "pkg" apiNode := FileNode{Name: "Go API", Path: apiPath, FileNodes: []*FileNode{}} go func() { fio, _ := os.Lstat(apiPath) if fio.IsDir() { apiNode.Type = "d" // TOOD: Go API 用另外的样式 apiNode.IconSkin = "ico-ztree-dir " walk(apiPath, &apiNode) } else { apiNode.Type = "f" ext := filepath.Ext(apiPath) apiNode.IconSkin = getIconSkin(ext) apiNode.Mode = getEditorMode(ext) } }() // 构造用户工作空间文件树 walk(userSrc, &root) // 添加 Go API 节点 root.FileNodes = append(root.FileNodes, &apiNode) data["root"] = root }
// StopHandler handles request of stoping a running process. func StopHandler(w http.ResponseWriter, r *http.Request) { data := map[string]interface{}{"succ": true} defer util.RetJSON(w, r, data) var args map[string]interface{} if err := json.NewDecoder(r.Body).Decode(&args); err != nil { logger.Error(err) data["succ"] = false return } sid := args["sid"].(string) pid := int(args["pid"].(float64)) wSession := session.WideSessions.Get(sid) if nil == wSession { data["succ"] = false return } output.Processes.Kill(wSession, pid) }
func AddUser(w http.ResponseWriter, r *http.Request) { data := map[string]interface{}{"succ": true} defer util.RetJSON(w, r, data) decoder := json.NewDecoder(r.Body) var args map[string]interface{} if err := decoder.Decode(&args); err != nil { glog.Error(err) data["succ"] = false return } username := args["username"].(string) password := args["password"].(string) msg := addUser(username, password) if USER_CREATED != msg { data["succ"] = false data["msg"] = msg } }
func GoGetHandler(w http.ResponseWriter, r *http.Request) { data := map[string]interface{}{"succ": true} defer util.RetJSON(w, r, data) session, _ := user.Session.Get(r, "wide-session") sid := session.Values["id"].(string) username := session.Values["username"].(string) decoder := json.NewDecoder(r.Body) var args map[string]interface{} if err := decoder.Decode(&args); err != nil { glog.Error(err) data["succ"] = false return } filePath := args["file"].(string) curDir := filePath[:strings.LastIndex(filePath, string(os.PathSeparator))] cmd := exec.Command("go", "get") cmd.Dir = curDir setCmdEnv(cmd, username) stdout, err := cmd.StdoutPipe() if nil != err { glog.Error(err) data["succ"] = false return } stderr, err := cmd.StderrPipe() if nil != err { glog.Error(err) data["succ"] = false return } reader := io.MultiReader(stdout, stderr) cmd.Start() channelRet := map[string]interface{}{} go func(runningId int) { glog.V(3).Infof("Session [%s] is running [go get] [runningId=%d]", sid, runningId) for { buf := make([]byte, 1024) count, err := reader.Read(buf) if nil != err || 0 == count { glog.V(3).Infof("Session [%s] 's running [go get] [runningId=%d] has done", sid, runningId) break } else { channelRet["output"] = string(buf[:count]) channelRet["cmd"] = "go get" if nil != outputWS[sid] { err := outputWS[sid].WriteJSON(&channelRet) if nil != err { glog.Error(err) break } } } } }(rand.Int()) }
func GoInstallHandler(w http.ResponseWriter, r *http.Request) { data := map[string]interface{}{"succ": true} defer util.RetJSON(w, r, data) session, _ := user.Session.Get(r, "wide-session") sid := session.Values["id"].(string) username := session.Values["username"].(string) decoder := json.NewDecoder(r.Body) var args map[string]interface{} if err := decoder.Decode(&args); err != nil { glog.Error(err) data["succ"] = false return } filePath := args["file"].(string) curDir := filePath[:strings.LastIndex(filePath, string(os.PathSeparator))] fout, err := os.Create(filePath) if nil != err { glog.Error(err) data["succ"] = false return } code := args["code"].(string) fout.WriteString(code) if err := fout.Close(); nil != err { glog.Error(err) data["succ"] = false return } cmd := exec.Command("go", "install") cmd.Dir = curDir setCmdEnv(cmd, username) glog.V(5).Infof("go install %s", curDir) stdout, err := cmd.StdoutPipe() if nil != err { glog.Error(err) data["succ"] = false return } stderr, err := cmd.StderrPipe() if nil != err { glog.Error(err) data["succ"] = false return } if data["succ"].(bool) { reader := io.MultiReader(stdout, stderr) cmd.Start() go func(runningId int) { glog.V(3).Infof("Session [%s] is running [go install] [id=%d, dir=%s]", sid, runningId, curDir) // 一次性读取 buf := make([]byte, 1024*8) count, _ := reader.Read(buf) channelRet := map[string]interface{}{} channelRet["output"] = string(buf[:count]) channelRet["cmd"] = "go install" if 0 != count { // 构建失败 // 解析错误信息,返回给编辑器 gutter lint lines := strings.Split(string(buf[:count]), "\n")[1:] lints := []map[string]interface{}{} for _, line := range lines { if len(line) <= 1 { continue } file := line[:strings.Index(line, ":")] left := line[strings.Index(line, ":")+1:] lineNo, _ := strconv.Atoi(left[:strings.Index(left, ":")]) msg := left[strings.Index(left, ":")+2:] lint := map[string]interface{}{} lint["file"] = file lint["lineNo"] = lineNo - 1 lint["msg"] = msg lint["severity"] = "error" // warning lints = append(lints, lint) } channelRet["lints"] = lints } if nil != outputWS[sid] { glog.V(3).Infof("Session [%s] 's running [go install] [id=%d, dir=%s] has done", sid, runningId, curDir) err := outputWS[sid].WriteJSON(&channelRet) if nil != err { glog.Error(err) } } }(rand.Int()) } }