This commit is contained in:
parent
1be7dc89e0
commit
7fcc39be60
|
@ -266,7 +266,12 @@ func NewFileHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
if "f" == fileType {
|
if "f" == fileType {
|
||||||
extension := filepath.Ext(path)
|
extension := filepath.Ext(path)
|
||||||
data["mode"] = getEditorMode(extension)
|
data["mode"] = getEditorMode(extension)
|
||||||
|
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveFileHandler handles request of removing file or directory.
|
// RemoveFileHandler handles request of removing file or directory.
|
||||||
|
@ -293,7 +298,11 @@ func RemoveFileHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
wSession.EventQueue.Queue <- &event.Event{Code: event.EvtCodeServerInternalError, Sid: sid,
|
wSession.EventQueue.Queue <- &event.Event{Code: event.EvtCodeServerInternalError, Sid: sid,
|
||||||
Data: "can't remove file " + path}
|
Data: "can't remove file " + path}
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.Debugf("Removed a file [%s] by user [%s]", path, wSession.Username)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RenameFileHandler handles request of renaming file or directory.
|
// RenameFileHandler handles request of renaming file or directory.
|
||||||
|
@ -321,7 +330,11 @@ func RenameFileHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
wSession.EventQueue.Queue <- &event.Event{Code: event.EvtCodeServerInternalError, Sid: sid,
|
wSession.EventQueue.Queue <- &event.Event{Code: event.EvtCodeServerInternalError, Sid: sid,
|
||||||
Data: "can't rename file " + oldPath}
|
Data: "can't rename file " + oldPath}
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.Debugf("Renamed a file [%s] to [%s] by user [%s]", oldPath, newPath, wSession.Username)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use to find results sorting.
|
// Use to find results sorting.
|
||||||
|
@ -582,7 +595,7 @@ func createFile(path, fileType string) bool {
|
||||||
|
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
logger.Debugf("Created file [%s]", path)
|
logger.Tracef("Created file [%s]", path)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
case "d":
|
case "d":
|
||||||
|
@ -594,7 +607,7 @@ func createFile(path, fileType string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Debugf("Created directory [%s]", path)
|
logger.Tracef("Created directory [%s]", path)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
default:
|
default:
|
||||||
|
@ -612,7 +625,7 @@ func removeFile(path string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Debugf("Removed [%s]", path)
|
logger.Tracef("Removed [%s]", path)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -625,7 +638,7 @@ func renameFile(oldPath, newPath string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Debugf("Renamed [%s] to [%s]", oldPath, newPath)
|
logger.Tracef("Renamed [%s] to [%s]", oldPath, newPath)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -36,6 +37,7 @@ import (
|
||||||
"github.com/b3log/wide/event"
|
"github.com/b3log/wide/event"
|
||||||
"github.com/b3log/wide/log"
|
"github.com/b3log/wide/log"
|
||||||
"github.com/b3log/wide/util"
|
"github.com/b3log/wide/util"
|
||||||
|
"github.com/go-fsnotify/fsnotify"
|
||||||
"github.com/gorilla/sessions"
|
"github.com/gorilla/sessions"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
)
|
)
|
||||||
|
@ -77,6 +79,7 @@ type WideSession struct {
|
||||||
EventQueue *event.UserEventQueue // event queue
|
EventQueue *event.UserEventQueue // event queue
|
||||||
State int // state
|
State int // state
|
||||||
Content *conf.LatestSessionContent // the latest session content
|
Content *conf.LatestSessionContent // the latest session content
|
||||||
|
FileWatcher *fsnotify.Watcher // files change watcher
|
||||||
Created time.Time // create time
|
Created time.Time // create time
|
||||||
Updated time.Time // the latest use time
|
Updated time.Time // the latest use time
|
||||||
}
|
}
|
||||||
|
@ -300,9 +303,11 @@ func (sessions *wSessions) New(httpSession *sessions.Session, sid string) *WideS
|
||||||
// create user event queue
|
// create user event queue
|
||||||
userEventQueue := event.UserEventQueues.New(sid)
|
userEventQueue := event.UserEventQueues.New(sid)
|
||||||
|
|
||||||
|
username := httpSession.Values["username"].(string)
|
||||||
|
|
||||||
ret := &WideSession{
|
ret := &WideSession{
|
||||||
ID: sid,
|
ID: sid,
|
||||||
Username: httpSession.Values["username"].(string),
|
Username: username,
|
||||||
HTTPSession: httpSession,
|
HTTPSession: httpSession,
|
||||||
EventQueue: userEventQueue,
|
EventQueue: userEventQueue,
|
||||||
State: sessionStateActive,
|
State: sessionStateActive,
|
||||||
|
@ -313,6 +318,81 @@ func (sessions *wSessions) New(httpSession *sessions.Session, sid string) *WideS
|
||||||
|
|
||||||
*sessions = append(*sessions, ret)
|
*sessions = append(*sessions, ret)
|
||||||
|
|
||||||
|
if "playground" == username {
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
// add a filesystem watcher to notify front-end after the files changed
|
||||||
|
watcher, err := fsnotify.NewWatcher()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logger.Error(err)
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
workspaces := filepath.SplitList(conf.GetUserWorkspace(username))
|
||||||
|
for _, workspace := range workspaces {
|
||||||
|
filepath.Walk(filepath.Join(workspace, "src"), func(dirPath string, f os.FileInfo, err error) error {
|
||||||
|
if ".git" == f.Name() { // XXX: discard other unconcered dirs
|
||||||
|
return filepath.SkipDir
|
||||||
|
}
|
||||||
|
|
||||||
|
if f.IsDir() {
|
||||||
|
if err = watcher.Add(dirPath); nil != err {
|
||||||
|
logger.Error(err, dirPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Tracef("Added a file watcher [%s]", dirPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ret.FileWatcher = watcher
|
||||||
|
}()
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case event := <-watcher.Events:
|
||||||
|
path := event.Name
|
||||||
|
dir := filepath.Dir(path)
|
||||||
|
|
||||||
|
ch := SessionWS[sid]
|
||||||
|
|
||||||
|
if nil == ch {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if event.Op&fsnotify.Create == fsnotify.Create {
|
||||||
|
if err = watcher.Add(path); nil != err {
|
||||||
|
logger.Warn(err, path)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Tracef("Added a file watcher [%s]", path)
|
||||||
|
|
||||||
|
cmd := map[string]interface{}{"path": path, "dir": dir, "cmd": "create-file"}
|
||||||
|
ch.WriteJSON(&cmd)
|
||||||
|
} else if event.Op&fsnotify.Remove == fsnotify.Remove {
|
||||||
|
cmd := map[string]interface{}{"path": path, "dir": dir, "cmd": "remove-file"}
|
||||||
|
ch.WriteJSON(&cmd)
|
||||||
|
|
||||||
|
} else if event.Op&fsnotify.Rename == fsnotify.Rename {
|
||||||
|
cmd := map[string]interface{}{"path": path, "dir": dir, "cmd": "rename-file"}
|
||||||
|
ch.WriteJSON(&cmd)
|
||||||
|
}
|
||||||
|
case err := <-watcher.Errors:
|
||||||
|
if nil != err {
|
||||||
|
logger.Error("File watcher ERROR: ", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,6 +417,7 @@ func (sessions *wSessions) Get(sid string) *WideSession {
|
||||||
// 1. user event queue
|
// 1. user event queue
|
||||||
// 2. process set
|
// 2. process set
|
||||||
// 3. websocket channels
|
// 3. websocket channels
|
||||||
|
// 4. file watcher
|
||||||
func (sessions *wSessions) Remove(sid string) {
|
func (sessions *wSessions) Remove(sid string) {
|
||||||
mutex.Lock()
|
mutex.Lock()
|
||||||
defer mutex.Unlock()
|
defer mutex.Unlock()
|
||||||
|
@ -379,6 +460,11 @@ func (sessions *wSessions) Remove(sid string) {
|
||||||
delete(PlaygroundWS, sid)
|
delete(PlaygroundWS, sid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// file watcher
|
||||||
|
if nil != s.FileWatcher {
|
||||||
|
s.FileWatcher.Close()
|
||||||
|
}
|
||||||
|
|
||||||
cnt := 0 // count wide sessions associated with HTTP session
|
cnt := 0 // count wide sessions associated with HTTP session
|
||||||
for _, ses := range *sessions {
|
for _, ses := range *sessions {
|
||||||
if ses.Username == s.Username {
|
if ses.Username == s.Username {
|
||||||
|
|
|
@ -161,6 +161,14 @@ var session = {
|
||||||
|
|
||||||
sessionWS.onmessage = function (e) {
|
sessionWS.onmessage = function (e) {
|
||||||
console.log('[session onmessage]' + e.data);
|
console.log('[session onmessage]' + e.data);
|
||||||
|
var data = JSON.parse(e.data);
|
||||||
|
|
||||||
|
switch (data.cmd) {
|
||||||
|
case 'create-file':
|
||||||
|
break;
|
||||||
|
case 'remove-file':
|
||||||
|
break;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
sessionWS.onclose = function (e) {
|
sessionWS.onclose = function (e) {
|
||||||
console.log('[session onclose] disconnected (' + e.code + ')');
|
console.log('[session onclose] disconnected (' + e.code + ')');
|
||||||
|
|
Loading…
Reference in New Issue