This commit is contained in:
Liang Ding 2019-05-17 01:41:04 +08:00
parent 4f48e827f6
commit aa17c25400
No known key found for this signature in database
GPG Key ID: 136F30F901A2231D
9 changed files with 37 additions and 71 deletions

View File

@ -47,7 +47,7 @@ type LatestSessionContent struct {
// User configuration. // User configuration.
type User struct { type User struct {
Id string Id string
Name string Name string
Avatar string Avatar string
Workspace string // the GOPATH of this user (maybe contain several paths splitted by os.PathListSeparator) Workspace string // the GOPATH of this user (maybe contain several paths splitted by os.PathListSeparator)
@ -92,7 +92,7 @@ func (u *User) Save() bool {
return false return false
} }
if err = ioutil.WriteFile(filepath.Join(Wide.Users, u.Id+".json"), bytes, 0644); nil != err { if err = ioutil.WriteFile(filepath.Join(Wide.Data, "users", u.Id+".json"), bytes, 0644); nil != err {
logger.Error(err) logger.Error(err)
return false return false

View File

@ -59,15 +59,12 @@ func main() {
type conf struct { type conf struct {
Server string // server Server string // server
LogLevel string // logging level: trace/debug/info/warn/error LogLevel string // logging level: trace/debug/info/warn/error
Data string // data directory
RuntimeMode string // runtime mode (dev/prod)
HTTPSessionMaxAge int // HTTP session max age (in seciond) HTTPSessionMaxAge int // HTTP session max age (in seciond)
StaticResourceVersion string // version of static resources StaticResourceVersion string // version of static resources
MaxProcs int // Go max procs MaxProcs int // Go max procs
RuntimeMode string // runtime mode (dev/prod)
Locale string // default locale Locale string // default locale
Playground string // playground directory
Users string // users directory
UsersWorkspaces string // users' workspaces directory
AllowRegister bool // allow register or not
Autocomplete bool // default autocomplete Autocomplete bool // default autocomplete
} }
@ -87,8 +84,8 @@ var Docker bool
const DockerImageGo = "golang" const DockerImageGo = "golang"
// Load loads the Wide configurations from wide.json and users' configurations from users/{userId}.json. // Load loads the Wide configurations from wide.json and users' configurations from users/{userId}.json.
func Load(confPath, confUsers, confServer, confLogLevel, confPlayground string, confUsersWorkspaces string) { func Load(confPath, confData, confServer, confLogLevel string) {
initWide(confPath, confUsers, confServer, confLogLevel, confPlayground, confUsersWorkspaces) initWide(confPath, confData, confServer, confLogLevel)
initUsers() initUsers()
cmd := exec.Command("docker", "version") cmd := exec.Command("docker", "version")
@ -105,7 +102,9 @@ func Load(confPath, confUsers, confServer, confLogLevel, confPlayground string,
} }
func initUsers() { func initUsers() {
f, err := os.Open(Wide.Users) os.MkdirAll(Wide.Data + PathSeparator + "users", 0755)
f, err := os.Open(Wide.Data + PathSeparator + "users")
if nil != err { if nil != err {
logger.Error(err) logger.Error(err)
@ -131,7 +130,7 @@ func initUsers() {
user := &User{} user := &User{}
bytes, _ := ioutil.ReadFile(filepath.Join(Wide.Users, name)) bytes, _ := ioutil.ReadFile(filepath.Join(Wide.Data, "users", name))
err := json.Unmarshal(bytes, user) err := json.Unmarshal(bytes, user)
if err != nil { if err != nil {
logger.Errorf("Parses [%s] error: %v, skip loading this user", name, err) logger.Errorf("Parses [%s] error: %v, skip loading this user", name, err)
@ -162,7 +161,7 @@ func initUsers() {
initCustomizedConfs() initCustomizedConfs()
} }
func initWide(confPath, confUsers, confServer, confLogLevel, confPlayground string, confUsersWorkspaces string) { func initWide(confPath, confData, confServer, confLogLevel string) {
bytes, err := ioutil.ReadFile(confPath) bytes, err := ioutil.ReadFile(confPath)
if nil != err { if nil != err {
logger.Error(err) logger.Error(err)
@ -195,38 +194,17 @@ func initWide(confPath, confUsers, confServer, confLogLevel, confPlayground stri
os.Exit(-1) os.Exit(-1)
} }
logger.Debugf("${user.home} [%s]", home) logger.Debugf("${user.home} [%s]", home)
// Users directory // Data directory
if "" != confUsers { if "" != confData {
Wide.Users = confUsers Wide.Data = confData
} }
Wide.Users = filepath.Clean(Wide.Users) Wide.Data = strings.Replace(Wide.Data, "${home}", home, -1)
Wide.Data = filepath.Clean(Wide.Data)
// Playground directory if !util.File.IsExist(Wide.Data) {
Wide.Playground = strings.Replace(Wide.Playground, "${home}", home, 1) if err := os.MkdirAll(Wide.Data, 0775); nil != err {
if "" != confPlayground { logger.Errorf("Create data directory [%s] error", err)
Wide.Playground = confPlayground
}
Wide.Playground = filepath.FromSlash(Wide.Playground)
if !util.File.IsExist(Wide.Playground) {
if err := os.MkdirAll(Wide.Playground, 0775); nil != err {
logger.Errorf("Create Playground [%s] error", err)
os.Exit(-1)
}
}
// Users' workspaces directory
Wide.UsersWorkspaces = strings.Replace(Wide.UsersWorkspaces, "${home}", home, 1)
if "" != confUsersWorkspaces {
Wide.UsersWorkspaces = confUsersWorkspaces
}
Wide.UsersWorkspaces = filepath.FromSlash(Wide.UsersWorkspaces)
if !util.File.IsExist(Wide.UsersWorkspaces) {
if err := os.MkdirAll(Wide.UsersWorkspaces, 0775); nil != err {
logger.Errorf("Create Workspaces [%s] error", err)
os.Exit(-1) os.Exit(-1)
} }
@ -369,7 +347,7 @@ func UpdateCustomizedConf(userId string) {
os.Exit(-1) os.Exit(-1)
} }
dir := filepath.Clean(Wide.UsersWorkspaces + "/" + userId + "/static/") dir := filepath.Clean(Wide.Data + "/static/" + userId)
if err := os.MkdirAll(dir, 0755); nil != err { if err := os.MkdirAll(dir, 0755); nil != err {
logger.Error(err) logger.Error(err)

View File

@ -1,14 +1,11 @@
{ {
"Server": "http://127.0.0.1:7070", "Server": "http://127.0.0.1:7070",
"LogLevel": "debug", "LogLevel": "debug",
"Data": "${home}/wide",
"RuntimeMode": "dev",
"HTTPSessionMaxAge": 86400, "HTTPSessionMaxAge": 86400,
"StaticResourceVersion": "${time}", "StaticResourceVersion": "${time}",
"MaxProcs": 4, "MaxProcs": 4,
"RuntimeMode": "dev",
"Locale": "en_US", "Locale": "en_US",
"Playground": "${home}/wide/playground",
"Users": "conf/users",
"UsersWorkspaces": "${home}/wide/workspaces",
"AllowRegister": true,
"Autocomplete": true "Autocomplete": true
} }

22
main.go
View File

@ -48,12 +48,10 @@ var logger *log.Logger
// The only one init function in Wide. // The only one init function in Wide.
func init() { func init() {
confPath := flag.String("conf", "conf/wide.json", "path of wide.json") confPath := flag.String("conf", "conf/wide.json", "path of wide.json")
confUsers := flag.String("users", "conf/users", "path of users") confData := flag.String("data", "", "path of data dir")
confServer := flag.String("server", "", "this will overwrite Wide.Server if specified") confServer := flag.String("server", "", "this will overwrite Wide.Server if specified")
confLogLevel := flag.String("log_level", "", "this will overwrite Wide.LogLevel if specified") confLogLevel := flag.String("log_level", "", "this will overwrite Wide.LogLevel if specified")
confStat := flag.Bool("stat", false, "whether report statistics periodically") confStat := flag.Bool("stat", false, "whether report statistics periodically")
confPlayground := flag.String("playground", "", "this will overwrite Wide.Playground if specified")
confUsersWorkspaces := flag.String("users_workspaces", "", "this will overwrite Wide.UsersWorkspaces if specified")
flag.Parse() flag.Parse()
@ -69,7 +67,7 @@ func init() {
i18n.Load() i18n.Load()
event.Load() event.Load()
conf.Load(*confPath, *confUsers, *confServer, *confLogLevel, *confPlayground, *confUsersWorkspaces) conf.Load(*confPath, *confData, *confServer, *confLogLevel)
conf.FixedTimeCheckEnv() conf.FixedTimeCheckEnv()
session.FixedTimeSave() session.FixedTimeSave()
@ -105,8 +103,8 @@ func main() {
// workspaces // workspaces
for _, user := range conf.Users { for _, user := range conf.Users {
http.Handle("/workspace/"+user.Id+"/", http.Handle("/workspace/"+user.Id+"/", http.StripPrefix("/workspace/"+user.Id+"/", http.FileServer(http.Dir(user.WorkspacePath()))))
http.StripPrefix("/workspace/"+user.Id+"/", http.FileServer(http.Dir(user.WorkspacePath())))) http.Handle("/static/user/", http.StripPrefix("/workspace/"+user.Id+"/", http.FileServer(http.Dir(conf.Wide.Data + conf.PathSeparator + "static"))))
} }
// session // session
@ -190,14 +188,14 @@ func indexHandler(w http.ResponseWriter, r *http.Request) {
httpSession, _ := session.HTTPSession.Get(r, session.CookieName) httpSession, _ := session.HTTPSession.Get(r, session.CookieName)
if httpSession.IsNew { if httpSession.IsNew {
http.Redirect(w, r, "/start", http.StatusFound) http.Redirect(w, r, "/login", http.StatusFound)
return return
} }
uid := httpSession.Values["uid"].(string) uid := httpSession.Values["uid"].(string)
if "playground" == uid { // reserved user for Playground if "playground" == uid { // reserved user for Playground
http.Redirect(w, r, "/start", http.StatusFound) http.Redirect(w, r, "/login", http.StatusFound)
return return
} }
@ -207,9 +205,7 @@ func indexHandler(w http.ResponseWriter, r *http.Request) {
user := conf.GetUser(uid) user := conf.GetUser(uid)
if nil == user { if nil == user {
logger.Warnf("Not found user [%s]", uid) http.Redirect(w, r, "/login", http.StatusFound)
http.Redirect(w, r, "/start", http.StatusFound)
return return
} }
@ -263,7 +259,7 @@ func serveSingle(pattern string, filename string) {
func startHandler(w http.ResponseWriter, r *http.Request) { func startHandler(w http.ResponseWriter, r *http.Request) {
httpSession, _ := session.HTTPSession.Get(r, session.CookieName) httpSession, _ := session.HTTPSession.Get(r, session.CookieName)
if httpSession.IsNew { if httpSession.IsNew {
http.Redirect(w, r, "/login", http.StatusFound) http.Redirect(w, r, "/s", http.StatusFound)
return return
} }
@ -300,7 +296,7 @@ func startHandler(w http.ResponseWriter, r *http.Request) {
func keyboardShortcutsHandler(w http.ResponseWriter, r *http.Request) { func keyboardShortcutsHandler(w http.ResponseWriter, r *http.Request) {
httpSession, _ := session.HTTPSession.Get(r, session.CookieName) httpSession, _ := session.HTTPSession.Get(r, session.CookieName)
if httpSession.IsNew { if httpSession.IsNew {
http.Redirect(w, r, "/start", http.StatusFound) http.Redirect(w, r, "/login", http.StatusFound)
return return
} }

View File

@ -48,7 +48,7 @@ func BuildHandler(w http.ResponseWriter, r *http.Request) {
} }
fileName := args["fileName"].(string) fileName := args["fileName"].(string)
filePath := filepath.Clean(conf.Wide.Playground + "/" + fileName) filePath := filepath.Clean(conf.Wide.Data + "/playground/" + fileName)
suffix := "" suffix := ""
if util.OS.IsWindows() { if util.OS.IsWindows() {
@ -58,7 +58,7 @@ func BuildHandler(w http.ResponseWriter, r *http.Request) {
data := map[string]interface{}{} data := map[string]interface{}{}
result.Data = &data result.Data = &data
executable := filepath.Clean(conf.Wide.Playground + "/" + strings.Replace(fileName, ".go", suffix, -1)) executable := filepath.Clean(conf.Wide.Data + "/playground/" + strings.Replace(fileName, ".go", suffix, -1))
cmd := exec.Command("go", "build", "-o", executable, filePath) cmd := exec.Command("go", "build", "-o", executable, filePath)
out, err := cmd.CombinedOutput() out, err := cmd.CombinedOutput()

View File

@ -85,7 +85,7 @@ func SaveHandler(w http.ResponseWriter, r *http.Request) {
data["fileName"] = fileName data["fileName"] = fileName
// Step3. write file // Step3. write file
filePath := filepath.Clean(conf.Wide.Playground + "/" + fileName) filePath := filepath.Clean(conf.Wide.Data + "/playground" + fileName)
fout, err := os.Create(filePath) fout, err := os.Create(filePath)
fout.WriteString(code) fout.WriteString(code)
if err := fout.Close(); nil != err { if err := fout.Close(); nil != err {

View File

@ -59,7 +59,7 @@ func IndexHandler(w http.ResponseWriter, r *http.Request) {
if strings.HasSuffix(r.URL.Path, ".go") { if strings.HasSuffix(r.URL.Path, ".go") {
fileNameArg := r.URL.Path[len("/playground/"):] fileNameArg := r.URL.Path[len("/playground/"):]
filePath := filepath.Clean(conf.Wide.Playground + "/" + fileNameArg) filePath := filepath.Clean(conf.Wide.Data+ "/playground" + fileNameArg)
bytes, err := ioutil.ReadFile(filePath) bytes, err := ioutil.ReadFile(filePath)
if nil != err { if nil != err {

View File

@ -161,10 +161,6 @@ func LogoutHandler(w http.ResponseWriter, r *http.Request) {
// //
// Note: user [playground] is a reserved mock user // Note: user [playground] is a reserved mock user
func addUser(userId, userName, userAvatar string) string { func addUser(userId, userName, userAvatar string) string {
if !conf.Wide.AllowRegister {
return notAllowRegister
}
if "playground" == userId { if "playground" == userId {
return userExists return userExists
} }
@ -178,7 +174,7 @@ func addUser(userId, userName, userAvatar string) string {
} }
} }
workspace := filepath.Join(conf.Wide.UsersWorkspaces, userId) workspace := filepath.Join(conf.Wide.Data, "workspaces", userId)
newUser := conf.NewUser(userId, userName, userAvatar, workspace) newUser := conf.NewUser(userId, userName, userAvatar, workspace)
conf.Users = append(conf.Users, newUser) conf.Users = append(conf.Users, newUser)
if !newUser.Save() { if !newUser.Save() {

View File

@ -35,7 +35,6 @@ const (
userExists = "user exists" userExists = "user exists"
userCreated = "user created" userCreated = "user created"
userCreateError = "user create error" userCreateError = "user create error"
notAllowRegister = "not allow register"
) )
// Exclusive lock for adding user. // Exclusive lock for adding user.
@ -46,7 +45,7 @@ func PreferenceHandler(w http.ResponseWriter, r *http.Request) {
httpSession, _ := HTTPSession.Get(r, CookieName) httpSession, _ := HTTPSession.Get(r, CookieName)
if httpSession.IsNew { if httpSession.IsNew {
http.Redirect(w, r, "/start", http.StatusFound) http.Redirect(w, r, "/login", http.StatusFound)
return return
} }