This commit is contained in:
Liang Ding 2015-03-13 21:04:31 +08:00
parent 1be7dc89e0
commit 7fcc39be60
3 changed files with 113 additions and 6 deletions

View File

@ -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
}

View File

@ -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 {

View File

@ -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 + ')');