diff --git a/conf/wide.go b/conf/wide.go index 4b1f756..7d38c19 100644 --- a/conf/wide.go +++ b/conf/wide.go @@ -141,9 +141,7 @@ func FixedTimeSave() { func (c *conf) GetUserWorkspace(username string) string { for _, user := range c.Users { if user.Name == username { - ret := strings.Replace(user.Workspace, "{WD}", c.WD, 1) - - return filepath.FromSlash(ret) + return user.GetWorkspace() } } @@ -154,9 +152,13 @@ func (c *conf) GetUserWorkspace(username string) string { // // Compared to the use of Wide.Workspace, this function will be processed as follows: // 1. Replace {WD} variable with the actual directory path -// 2. Replace "/" with "\\" (Windows) +// 2. Replace ${GOPATH} with enviorment variable GOPATH +// 3. Replace "/" with "\\" (Windows) func (c *conf) GetWorkspace() string { - return filepath.FromSlash(strings.Replace(c.Workspace, "{WD}", c.WD, 1)) + w := strings.Replace(c.Workspace, "{WD}", c.WD, 1) + w = strings.Replace(w, "${GOPATH}", os.Getenv("GOPATH"), 1) + + return filepath.FromSlash(w) } // GetGoFmt gets the path of Go format tool, returns "gofmt" if not found. @@ -182,9 +184,13 @@ func (c *conf) GetGoFmt(username string) string { // // Compared to the use of Wide.Workspace, this function will be processed as follows: // 1. Replace {WD} variable with the actual directory path -// 2. Replace "/" with "\\" (Windows) +// 2. Replace ${GOPATH} with enviorment variable GOPATH +// 3. Replace "/" with "\\" (Windows) func (u *User) GetWorkspace() string { - return filepath.FromSlash(strings.Replace(u.Workspace, "{WD}", Wide.WD, 1)) + w := strings.Replace(u.Workspace, "{WD}", Wide.WD, 1) + w = strings.Replace(w, "${GOPATH}", os.Getenv("GOPATH"), 1) + + return filepath.FromSlash(w) } // GetUser gets configuration of the user specified by the given username, returns nil if not found. diff --git a/conf/wide.json b/conf/wide.json index 99d3d6e..b0b2d61 100644 --- a/conf/wide.json +++ b/conf/wide.json @@ -11,13 +11,13 @@ "MaxProcs": 4, "RuntimeMode": "dev", "WD": "${pwd}", - "Workspace": "{WD}/data/workspace", + "Workspace": "${GOPATH}", "Locale": "en_US", "Users": [ { "Name": "admin", "Password": "admin", - "Workspace": "{WD}/data/user_workspaces/admin", + "Workspace": "${GOPATH}", "Locale": "en_US", "GoFormat": "gofmt", "FontFamily": "Helvetica", @@ -31,6 +31,20 @@ "Files": [], "CurrentFile": "" } + }, + { + "Name": "test1", + "Password": "1", + "Workspace": "D:\\test1", + "Locale": "en_US", + "GoFormat": "gofmt", + "FontFamily": "Helvetica", + "FontSize": "13px", + "Editor": { + "FontFamily": "Consolas, 'Courier New', monospace", + "FontSize": "inherit" + }, + "LatestSessionContent": null } ] } \ No newline at end of file diff --git a/data/user_workspaces/README b/data/user_workspaces/README deleted file mode 100755 index 77c7c49..0000000 --- a/data/user_workspaces/README +++ /dev/null @@ -1 +0,0 @@ -User workspaces. \ No newline at end of file diff --git a/data/user_workspaces/admin/src/format/test.css b/data/user_workspaces/admin/src/format/test.css deleted file mode 100644 index 1f4ed9e..0000000 --- a/data/user_workspaces/admin/src/format/test.css +++ /dev/null @@ -1,319 +0,0 @@ -/* start icon */ - -@font-face { - font-family: 'icomoon'; - src: url('fonts/icomoon.eot?35cb2z'); - src: url('fonts/icomoon.eot?#iefix35cb2z') format('embedded-opentype'), url('fonts/icomoon.woff?35cb2z') format('woff'), url('fonts/icomoon.ttf?35cb2z') format('truetype'), url('fonts/icomoon.svg?35cb2z#icomoon') format('svg'); - font-weight: normal; - font-style: normal; -} -.font-ico { - font-family: 'icomoon'; - /* Better Font Rendering =========== */ - - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - color: #666; - cursor: pointer; - font-size: 13px; - line-height: 18px; -} -.font-ico:hover { - color: #333; -} -.ico-play:before { - content: "\e605"; -} -.ico-save:before { - content: "\f0c7"; -} -.ico-max:before { - content: "\f096"; -} -.ico-format:before { - content: "\e60b"; -} -.ico-buildrun:before { - content: "\e607"; -} -.ico-stop:before { - content: "\e608"; -} -.ico-restore:before { - content: "\e60c"; -} -.ico-min:before { - content: "\e60d"; - position: absolute; - right: 5px; -} -.ico-close:before { - content: "\e60a"; -} -/* end ico */ -/* start frame */ - -.frame { - position: absolute; - border: 1px solid #5F5F5F; - background-color: #F8F8F8; - width: 320px; - z-index: 21; - display: none; -} -.frame li { - padding: 0 5px; - line-height: 25px; - cursor: pointer; -} -.frame li.disabled { - color: #999; -} -.frame li:hover { - background-color: #3875D7; - color: #FFF; -} -.frame li.disabled:hover { - background-color: #F8F8F8; - color: #999; -} -.frame a { - color: #000; - text-decoration: none; -} -.frame li:hover a, -.frame a:hover { - color: #FFF; -} -.frame .hr { - background-color: #bdbdbd; - height: 1px; - margin: 0 1px; -} -/* end frame */ -/* start tabs */ - -.tabs { - height: 20px; - overflow: hidden; - width: 100%; - background-color: #E6E6E6; - border-top: 1px solid #A4A4A4; - border-bottom: 1px solid #9D9D9D; -} -.tabs > div { - float: left; - line-height: 18px; - height: 18px; - padding: 0 5px; - cursor: pointer; - background-color: #DDD; - color: #8B8B8B; - border-right: 1px solid #ADADAD; -} -.tabs > div.current { - background-color: #9F9F9F; - color: #FFF; -} -/* end tabs */ -/* start framework */ - -.content { - position: relative; - overflow: hidden; -} -/* end framework */ -/* start menu */ - -.menu { - background-color: #F0F0F0; - height: 24px; -} -.menu > ul > li { - float: left; -} -.menu > ul > li > span { - color: #000; - font-size: 12px; - line-height: 24px; - padding: 5px; - text-decoration: none; - cursor: pointer; -} -/* end menu */ -/* start editor */ - -.edit-panel { - width: 80%; - position: absolute; - left: 20%; - width: 80%; - height: 70%; - overflow: hidden; -} -.edit-panel .tabs > div { - background-color: #d1d1d1; - border-right-color: #9b9b9b; - color: #333; - cursor: auto; -} -.edit-panel .tabs > div.current { - background-color: #F7F7F7; -} -.toolbars { - position: absolute; - right: 5px; - top: 1px; -} -.edit-panel .tabs .ico { - background-image: url("../images/ico-file.png"); - float: left; - height: 16px; - margin: 2px 0 0 -2px; - width: 16px; -} -/* 统一为 static/js/lib/codemirror-4.5/addon/hint/show-hint.css 中的.CodeMirror-hints */ - -.edit-exprinfo { - position: absolute; - z-index: 10; - overflow: hidden; - list-style: none; - margin: 0; - padding: 2px; - -webkit-box-shadow: 2px 3px 5px rgba(0, 0, 0, .2); - -moz-box-shadow: 2px 3px 5px rgba(0, 0, 0, .2); - box-shadow: 2px 3px 5px rgba(0, 0, 0, .2); - border-radius: 3px; - border: 1px solid silver; - background: white; - font-size: 90%; - font-family: Consolas, Courier New, monospace; - max-height: 20em; - overflow-y: auto; -} -.CodeMirror, -.CodeMirror-hints { - font-family: Consolas, Courier New, monospace; -} -.CodeMirror-focused .cm-matchhighlight { - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAFklEQVQI12NgYGBgkKzc8x9CMDAwAAAmhwSbidEoSQAAAABJRU5ErkJggg==); - background-position: bottom; - background-repeat: repeat-x; -} -.CodeMirror-hint { - padding-right: 18px; - max-width: none; -} -.CodeMirror-hint:hover { - background: #08f; - color: white; -} -/* end editor */ -/* start bottom-window-group */ - -.bottom-window-group { - width: 80%; - position: absolute; - left: 20%; - width: 80%; - height: 30%; - top: 70%; - z-index: 7; - background-color: #fff; -} -.bottom-window-group-max { - height: 100%; - left: 0; - top: 0; - width: 100%; - z-index: 11; -} -.bottom-window-group > div > div { - overflow: auto; -} -.bottom-window-group .output { - font-family: Consolas, Courier New, monospace; - padding: 0 5px; - line-height: 16px; - font-size: 12px; -} -.bottom-window-group .output pre { - margin: 0; -} -.bottom-window-group .output .start-build, -.bottom-window-group .output .start-test, -.bottom-window-group .output .start-install, -.bottom-window-group .output .start-get { - color: #999; -} -.bottom-window-group .output .build-succ, -.bottom-window-group .output .test-succ, -.bottom-window-group .output .install-succ, -.bottom-window-group .output .get-succ { - color: rgb(0, 153, 0); -} -.bottom-window-group .output .build-error, -.bottom-window-group .output .test-error, -.bottom-window-group .output .install-error, -.bottom-window-group .output .get-error { - color: red; -} -.bottom-window-group table { - width: 100%; -} -.bottom-window-group td { - border-bottom: 1px solid #DDD; - line-height: 20px; -} -.bottom-window-group .notification .type, -.bottom-window-group .notification .severity { - width: 50px; - padding: 0 5px; -} -.bottom-window-group .search li { - cursor: pointer; - line-height: 20px; - padding: 0 3px; - word-wrap: normal; - word-break: normal; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -.bottom-window-group .search li.selected { - background-color: #3875d7; - color: #FFF; -} -.bottom-window-group .search .path { - color: #999; - font-size: 12px; -} -.bottom-window-group .search li.selected .path { - color: #FFF; -} -/* end bottom-window-group */ -/* start footer */ - -.footer { - border-top: 1px solid #919191; - background-color: #F0F0F0; - padding-left: 5px; - height: 19px; - line-height: 18px; -} -.footer .cursor { - cursor: pointer; -} -.notification-count { - float: right; - display: none; - cursor: pointer; - background-color: red; - color: #FFF; - margin: 1px 5px; - padding: 0 2px; - border-radius: 3px; - line-height: 16px; -} -/* end footer */ \ No newline at end of file diff --git a/data/user_workspaces/admin/src/format/test.html b/data/user_workspaces/admin/src/format/test.html deleted file mode 100644 index 9525b5d..0000000 --- a/data/user_workspaces/admin/src/format/test.html +++ /dev/null @@ -1,333 +0,0 @@ - - - - - - {{.i18n.wide}} - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
- {{.i18n.file}} -
-
-
-
-
    - -
    -
      -
    • {{.i18n.create_file}}
    • -
    • {{.i18n.create_dir}}
    • -
    • {{.i18n.delete}}
    • -
    -
    - - -
    -
      -
    • {{.i18n.delete}}
    • -
    -
    -
    -
    -
    - -
    -
    - - - - -
    -
    -
    -
    - -
    - -
    -
    - {{.i18n.output}} -
    -
    - {{.i18n.search}} -
    -
    - {{.i18n.notification}} -
    -
    -
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    -
    -
    -
    - - - -
    - {{.i18n.isDelete}} ? -
    -
    -
    -
    - -
    -
    - -
    -
    - -
    -
    - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/data/user_workspaces/admin/src/format/test.json b/data/user_workspaces/admin/src/format/test.json deleted file mode 100644 index 5baf1c3..0000000 --- a/data/user_workspaces/admin/src/format/test.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "Server": "{IP}:7070", - "StaticServer": "http://{IP}:7070", - "EditorChannel": "ws://{IP}:7070", - "OutputChannel": "ws://{IP}:7070", - "ShellChannel": "ws://{IP}:7070", - "SessionChannel": "ws://{IP}:7070", - "HTTPSessionMaxAge": 86400, - "StaticResourceVersion": "201410271700", - "MaxProcs": 4, - "RuntimeMode": "dev", - "Pwd": "{pwd}", - "Workspace": "{pwd}/data/workspace", - "Locale": "en_US", - "Users": [{ - "Name": "admin", - "Password": "admin", - "Workspace": "{pwd}/data/user_workspaces/admin", - "Locale": "en_US", - "GoFormat": "gofmt", - "LatestSessionContent": { - "FileTree": [ - "D:\\GoGoGo\\src\\github.com\\b3log\\wide\\data\\user_workspaces\\admin\\src", - "D:\\GoGoGo\\src\\github.com\\b3log\\wide\\data\\user_workspaces\\admin\\src\\format", - "D:\\GoGoGo\\src\\github.com\\b3log\\wide\\data\\user_workspaces\\admin\\src\\gotest", - "D:\\GoGoGo\\src\\github.com\\b3log\\wide\\data\\user_workspaces\\admin\\src\\hello", - "D:\\GoGoGo\\src\\github.com\\b3log\\wide\\data\\user_workspaces\\admin\\src\\time" - ], - "Files": [ - "D:\\GoGoGo\\src\\github.com\\b3log\\wide\\data\\user_workspaces\\admin\\src\\time\\main.go", - "D:\\GoGoGo\\src\\github.com\\b3log\\wide\\data\\user_workspaces\\admin\\src\\format\\index.html" - ], - "CurrentFile": "D:\\GoGoGo\\src\\github.com\\b3log\\wide\\data\\user_workspaces\\admin\\src\\format\\index.html" - } - }] -} \ No newline at end of file diff --git a/data/user_workspaces/admin/src/gotest/example1_test.go b/data/user_workspaces/admin/src/gotest/example1_test.go deleted file mode 100644 index 8c9c857..0000000 --- a/data/user_workspaces/admin/src/gotest/example1_test.go +++ /dev/null @@ -1,16 +0,0 @@ -package test - -import ( - "testing" -) - -func Test_Division_1(t *testing.T) { - if i, e := Division(6, 2); i != 3 || e != nil { //try a unit test on function - t.Error("除法函数测试没通过") // 如果不是如预期的那么就报错 - } else { - t.Log("第一个测试通过了") //记录一些你期望记录的信息 - } -} - -func Test_Division_2(t *testing.T) { -} diff --git a/data/user_workspaces/admin/src/gotest/example2_test.go b/data/user_workspaces/admin/src/gotest/example2_test.go deleted file mode 100644 index ebdfe2b..0000000 --- a/data/user_workspaces/admin/src/gotest/example2_test.go +++ /dev/null @@ -1,17 +0,0 @@ -package test - -import ( - "testing" -) - -func Test_Division_3(t *testing.T) { - if i, e := Division(6, 2); i != 3 || e != nil { //try a unit test on function - t.Error("除法函数测试没通过") // 如果不是如预期的那么就报错 - } else { - t.Log("第一个测试通过了") //记录一些你期望记录的信息 - } -} - -func Test_Division_4(t *testing.T) { - t.Error("就是不通过") -} diff --git a/data/user_workspaces/admin/src/gotest/test.go b/data/user_workspaces/admin/src/gotest/test.go deleted file mode 100644 index 8394003..0000000 --- a/data/user_workspaces/admin/src/gotest/test.go +++ /dev/null @@ -1,13 +0,0 @@ -package test - -import ( - "errors" -) - -func Division(a, b float64) (float64, error) { - if b == 0 { - return 0, errors.New("除数不能为0") - } - - return a / b, nil -} diff --git a/data/user_workspaces/admin/src/hello/main.go b/data/user_workspaces/admin/src/hello/main.go deleted file mode 100644 index 4b8553a..0000000 --- a/data/user_workspaces/admin/src/hello/main.go +++ /dev/null @@ -1,9 +0,0 @@ -package main - -import ( - "fmt" -) - -func main() { - fmt.Println("Hello, 世界") -} diff --git a/data/user_workspaces/admin/src/time/main.go b/data/user_workspaces/admin/src/time/main.go deleted file mode 100644 index 1413c32..0000000 --- a/data/user_workspaces/admin/src/time/main.go +++ /dev/null @@ -1,17 +0,0 @@ -package main - -import ( - "fmt" - "time" - "time/pkg" -) - -func main() { - for i := 0; i < 50; i++ { - - fmt.Println("Hello, 世界", pkg.Now()) - - time.Sleep(time.Second) - } - -} diff --git a/data/user_workspaces/admin/src/time/pkg/time.go b/data/user_workspaces/admin/src/time/pkg/time.go deleted file mode 100644 index 1eb3ccb..0000000 --- a/data/user_workspaces/admin/src/time/pkg/time.go +++ /dev/null @@ -1,17 +0,0 @@ -package pkg - -import ( - "time" -) - -func Now() time.Time { - return time.Now() -} - -func Now1() time.Time { - return time.Now() -} - -func Now2() { - -} diff --git a/data/workspace/README b/data/workspace/README deleted file mode 100755 index ba348ad..0000000 --- a/data/workspace/README +++ /dev/null @@ -1 +0,0 @@ -Master workspace. \ No newline at end of file diff --git a/file/files.go b/file/files.go index f86e65b..1c4f994 100644 --- a/file/files.go +++ b/file/files.go @@ -114,9 +114,15 @@ func GetFile(w http.ResponseWriter, r *http.Request) { data["mode"] = "img" - path2 := strings.Replace(path, "\\", "/", -1) - idx := strings.Index(path2, "/data/user_workspaces") - data["path"] = path2[idx:] + user := GetUsre(path) + if nil == user { + glog.Warningf("The path [%s] has no owner") + data["path"] = "" + + return + } + + data["path"] = "/workspace/" + user.Name + "/" + strings.Replace(path, user.GetWorkspace(), "", 1) return } @@ -568,3 +574,14 @@ func isImg(extension string) bool { return false } } + +// GetUsre gets the user the specified path belongs to. Returns nil if not found. +func GetUsre(path string) *conf.User { + for _, user := range conf.Wide.Users { + if strings.HasPrefix(path, user.GetWorkspace()) { + return user + } + } + + return nil +} diff --git a/main.go b/main.go index 184af9c..89b1f3c 100644 --- a/main.go +++ b/main.go @@ -217,7 +217,10 @@ func main() { serveSingle("/favicon.ico", "./static/favicon.ico") // workspaces - http.Handle("/data/", http.StripPrefix("/data/", http.FileServer(http.Dir("data")))) + for _, user := range conf.Wide.Users { + http.Handle("/workspace/"+user.Name+"/", + http.StripPrefix("/workspace/"+user.Name+"/", http.FileServer(http.Dir(user.GetWorkspace())))) + } // session http.HandleFunc("/session/ws", handlerWrapper(session.WSHandler)) diff --git a/session/users.go b/session/users.go index 31d9d53..155ef1e 100644 --- a/session/users.go +++ b/session/users.go @@ -143,8 +143,6 @@ func SignUpUser(w http.ResponseWriter, r *http.Request) { } func addUser(username, password string) string { - // XXX: validate - for _, user := range conf.Wide.Users { if user.Name == username { return UserExists @@ -155,10 +153,10 @@ func addUser(username, password string) string { dir := filepath.Dir(firstUserWorkspace) workspace := filepath.Join(dir, username) - conf.Wide.Users = append(conf.Wide.Users, - &conf.User{Name: username, Password: password, Workspace: workspace, - Locale: conf.Wide.Locale, GoFormat: "gofmt", FontFamily: "Helvetica", FontSize: "inherit", - Editor: &conf.Editor{FontFamily: "Consolas, 'Courier New', monospace", FontSize: "inherit"}}) + newUser := &conf.User{Name: username, Password: password, Workspace: workspace, + Locale: conf.Wide.Locale, GoFormat: "gofmt", FontFamily: "Helvetica", FontSize: "13px", + Editor: &conf.Editor{FontFamily: "Consolas, 'Courier New', monospace", FontSize: "inherit"}} + conf.Wide.Users = append(conf.Wide.Users, newUser) if !conf.Save() { return UserCreateError @@ -167,6 +165,9 @@ func addUser(username, password string) string { conf.CreateWorkspaceDir(workspace) conf.UpdateCustomizedConf(username) + http.Handle("/workspace/"+username+"/", + http.StripPrefix("/workspace/"+username+"/", http.FileServer(http.Dir(newUser.GetWorkspace())))) + glog.Infof("Created a user [%s]", username) return UserCreated