This commit is contained in:
parent
1be7dc89e0
commit
7fcc39be60
|
@ -266,7 +266,12 @@ func NewFileHandler(w http.ResponseWriter, r *http.Request) {
|
|||
if "f" == fileType {
|
||||
extension := filepath.Ext(path)
|
||||
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.
|
||||
|
@ -293,7 +298,11 @@ func RemoveFileHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
wSession.EventQueue.Queue <- &event.Event{Code: event.EvtCodeServerInternalError, Sid: sid,
|
||||
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.
|
||||
|
@ -321,7 +330,11 @@ func RenameFileHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
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)
|
||||
}
|
||||
|
||||
// Use to find results sorting.
|
||||
|
@ -582,7 +595,7 @@ func createFile(path, fileType string) bool {
|
|||
|
||||
defer file.Close()
|
||||
|
||||
logger.Debugf("Created file [%s]", path)
|
||||
logger.Tracef("Created file [%s]", path)
|
||||
|
||||
return true
|
||||
case "d":
|
||||
|
@ -594,7 +607,7 @@ func createFile(path, fileType string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
logger.Debugf("Created directory [%s]", path)
|
||||
logger.Tracef("Created directory [%s]", path)
|
||||
|
||||
return true
|
||||
default:
|
||||
|
@ -612,7 +625,7 @@ func removeFile(path string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
logger.Debugf("Removed [%s]", path)
|
||||
logger.Tracef("Removed [%s]", path)
|
||||
|
||||
return true
|
||||
}
|
||||
|
@ -625,7 +638,7 @@ func renameFile(oldPath, newPath string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
logger.Debugf("Renamed [%s] to [%s]", oldPath, newPath)
|
||||
logger.Tracef("Renamed [%s] to [%s]", oldPath, newPath)
|
||||
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import (
|
|||
"encoding/json"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
@ -36,6 +37,7 @@ import (
|
|||
"github.com/b3log/wide/event"
|
||||
"github.com/b3log/wide/log"
|
||||
"github.com/b3log/wide/util"
|
||||
"github.com/go-fsnotify/fsnotify"
|
||||
"github.com/gorilla/sessions"
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
@ -77,6 +79,7 @@ type WideSession struct {
|
|||
EventQueue *event.UserEventQueue // event queue
|
||||
State int // state
|
||||
Content *conf.LatestSessionContent // the latest session content
|
||||
FileWatcher *fsnotify.Watcher // files change watcher
|
||||
Created time.Time // create 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
|
||||
userEventQueue := event.UserEventQueues.New(sid)
|
||||
|
||||
username := httpSession.Values["username"].(string)
|
||||
|
||||
ret := &WideSession{
|
||||
ID: sid,
|
||||
Username: httpSession.Values["username"].(string),
|
||||
Username: username,
|
||||
HTTPSession: httpSession,
|
||||
EventQueue: userEventQueue,
|
||||
State: sessionStateActive,
|
||||
|
@ -313,6 +318,81 @@ func (sessions *wSessions) New(httpSession *sessions.Session, sid string) *WideS
|
|||
|
||||
*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
|
||||
}
|
||||
|
||||
|
@ -337,6 +417,7 @@ func (sessions *wSessions) Get(sid string) *WideSession {
|
|||
// 1. user event queue
|
||||
// 2. process set
|
||||
// 3. websocket channels
|
||||
// 4. file watcher
|
||||
func (sessions *wSessions) Remove(sid string) {
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
|
@ -379,6 +460,11 @@ func (sessions *wSessions) Remove(sid string) {
|
|||
delete(PlaygroundWS, sid)
|
||||
}
|
||||
|
||||
// file watcher
|
||||
if nil != s.FileWatcher {
|
||||
s.FileWatcher.Close()
|
||||
}
|
||||
|
||||
cnt := 0 // count wide sessions associated with HTTP session
|
||||
for _, ses := range *sessions {
|
||||
if ses.Username == s.Username {
|
||||
|
|
|
@ -161,6 +161,14 @@ var session = {
|
|||
|
||||
sessionWS.onmessage = function (e) {
|
||||
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) {
|
||||
console.log('[session onclose] disconnected (' + e.code + ')');
|
||||
|
|
Loading…
Reference in New Issue