This commit is contained in:
		
							parent
							
								
									6e5d13cf2f
								
							
						
					
					
						commit
						190f30c9f4
					
				|  | @ -75,11 +75,13 @@ func FixedTimeCheckEnv() { | |||
| 		for _ = range time.Tick(time.Minute * 7) { | ||||
| 			if "" == os.Getenv("GOPATH") { | ||||
| 				glog.Fatal("Not found $GOPATH") | ||||
| 
 | ||||
| 				os.Exit(-1) | ||||
| 			} | ||||
| 
 | ||||
| 			if "" == os.Getenv("GOROOT") { | ||||
| 				glog.Fatal("Not found $GOROOT") | ||||
| 
 | ||||
| 				os.Exit(-1) | ||||
| 			} | ||||
| 
 | ||||
|  | @ -87,7 +89,8 @@ func FixedTimeCheckEnv() { | |||
| 			cmd := exec.Command(gocode, "close") | ||||
| 			_, err := cmd.Output() | ||||
| 			if nil != err { | ||||
| 				event.EventQueue <- event.EvtCodeGocodeNotFound | ||||
| 				event.EventQueue <- &event.Event{Code: event.EvtCodeGocodeNotFound} | ||||
| 
 | ||||
| 				glog.Warningf("Not found gocode [%s]", gocode) | ||||
| 			} | ||||
| 
 | ||||
|  | @ -95,7 +98,8 @@ func FixedTimeCheckEnv() { | |||
| 			cmd = exec.Command(ide_stub, "version") | ||||
| 			_, err = cmd.Output() | ||||
| 			if nil != err { | ||||
| 				event.EventQueue <- event.EvtCodeIDEStubNotFound | ||||
| 				event.EventQueue <- &event.Event{Code: event.EvtCodeIDEStubNotFound} | ||||
| 
 | ||||
| 				glog.Warningf("Not found ide_stub [%s]", ide_stub) | ||||
| 			} | ||||
| 		} | ||||
|  |  | |||
|  | @ -4,10 +4,11 @@ package event | |||
| import "github.com/golang/glog" | ||||
| 
 | ||||
| const ( | ||||
| 	EvtCodeGOPATHNotFound  = iota // 事件代码:找不到环境变量 $GOPATH
 | ||||
| 	EvtCodeGOROOTNotFound         // 事件代码:找不到环境变量 $GOROOT
 | ||||
| 	EvtCodeGocodeNotFound         // 事件代码:找不到 gocode
 | ||||
| 	EvtCodeIDEStubNotFound        // 事件代码:找不到 IDE stub
 | ||||
| 	EvtCodeGOPATHNotFound      = iota // 事件代码:找不到环境变量 $GOPATH
 | ||||
| 	EvtCodeGOROOTNotFound             // 事件代码:找不到环境变量 $GOROOT
 | ||||
| 	EvtCodeGocodeNotFound             // 事件代码:找不到 gocode
 | ||||
| 	EvtCodeIDEStubNotFound            // 事件代码:找不到 IDE stub
 | ||||
| 	EvtCodeServerInternalError        // 事件代码:服务器内部错误
 | ||||
| ) | ||||
| 
 | ||||
| // 事件队列最大长度.
 | ||||
|  | @ -15,20 +16,21 @@ const MaxQueueLength = 10 | |||
| 
 | ||||
| // 事件结构.
 | ||||
| type Event struct { | ||||
| 	Code int    `json:"code"` // 事件代码
 | ||||
| 	Sid  string `json:"sid"`  // 用户会话 id
 | ||||
| 	Code int         `json:"code"` // 事件代码
 | ||||
| 	Sid  string      `json:"sid"`  // 用户会话 id
 | ||||
| 	Data interface{} `json:"data"` // 事件数据
 | ||||
| } | ||||
| 
 | ||||
| // 全局事件队列.
 | ||||
| //
 | ||||
| // 入队的事件将分发到每个用户的事件队列中.
 | ||||
| var EventQueue = make(chan int, MaxQueueLength) | ||||
| var EventQueue = make(chan *Event, MaxQueueLength) | ||||
| 
 | ||||
| // 用户事件队列.
 | ||||
| type UserEventQueue struct { | ||||
| 	Sid      string    // 关联的会话 id
 | ||||
| 	Queue    chan int  // 队列
 | ||||
| 	Handlers []Handler // 事件处理器集
 | ||||
| 	Sid      string      // 关联的会话 id
 | ||||
| 	Queue    chan *Event // 队列
 | ||||
| 	Handlers []Handler   // 事件处理器集
 | ||||
| } | ||||
| 
 | ||||
| // 事件队列集类型.
 | ||||
|  | @ -43,10 +45,12 @@ var UserEventQueues = Queues{} | |||
| func Load() { | ||||
| 	go func() { | ||||
| 		for event := range EventQueue { | ||||
| 			glog.V(5).Info("收到全局事件 [%d]", event) | ||||
| 			glog.V(5).Infof("收到全局事件 [%d]", event.Code) | ||||
| 
 | ||||
| 			// 将事件分发到每个用户的事件队列里
 | ||||
| 			for _, userQueue := range UserEventQueues { | ||||
| 				event.Sid = userQueue.Sid | ||||
| 
 | ||||
| 				userQueue.Queue <- event | ||||
| 			} | ||||
| 		} | ||||
|  | @ -71,19 +75,18 @@ func (ueqs Queues) New(sid string) *UserEventQueue { | |||
| 
 | ||||
| 	q = &UserEventQueue{ | ||||
| 		Sid:   sid, | ||||
| 		Queue: make(chan int, MaxQueueLength), | ||||
| 		Queue: make(chan *Event, MaxQueueLength), | ||||
| 	} | ||||
| 
 | ||||
| 	ueqs[sid] = q | ||||
| 
 | ||||
| 	go func() { // 队列开始监听事件
 | ||||
| 		for evtCode := range q.Queue { | ||||
| 			glog.V(5).Infof("Session [%s] received a event [%d]", sid, evtCode) | ||||
| 		for evt := range q.Queue { | ||||
| 			glog.V(5).Infof("Session [%s] received a event [%d]", sid, evt.Code) | ||||
| 
 | ||||
| 			// 将事件交给事件处理器进行处理
 | ||||
| 			for _, handler := range q.Handlers { | ||||
| 				handler.Handle(&Event{Code: evtCode, Sid: sid}) | ||||
| 
 | ||||
| 				handler.Handle(evt) | ||||
| 			} | ||||
| 		} | ||||
| 	}() | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| // 文件树操作.
 | ||||
| // File tree manipulations.
 | ||||
| package file | ||||
| 
 | ||||
| import ( | ||||
|  | @ -12,17 +12,18 @@ import ( | |||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/b3log/wide/conf" | ||||
| 	"github.com/b3log/wide/event" | ||||
| 	"github.com/b3log/wide/session" | ||||
| 	"github.com/b3log/wide/util" | ||||
| 	"github.com/golang/glog" | ||||
| ) | ||||
| 
 | ||||
| // 文件节点,用于构造文件树.
 | ||||
| // File node, used to construct the file tree.
 | ||||
| type FileNode struct { | ||||
| 	Name      string      `json:"name"` | ||||
| 	Path      string      `json:"path"` | ||||
| 	IconSkin  string      `json:"iconSkin"` // 值的末尾应该有一个空格
 | ||||
| 	Type      string      `json:"type"`     // "f":文件,"d":文件夹
 | ||||
| 	IconSkin  string      `json:"iconSkin"` // Value should be end with a space
 | ||||
| 	Type      string      `json:"type"`     // "f": file,"d": directory
 | ||||
| 	Mode      string      `json:"mode"` | ||||
| 	FileNodes []*FileNode `json:"children"` | ||||
| } | ||||
|  | @ -175,7 +176,7 @@ func SaveFile(w http.ResponseWriter, r *http.Request) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| // 新建文件/目录.
 | ||||
| // NewFile handles request of creating file or directory.
 | ||||
| func NewFile(w http.ResponseWriter, r *http.Request) { | ||||
| 	data := map[string]interface{}{"succ": true} | ||||
| 	defer util.RetJSON(w, r, data) | ||||
|  | @ -191,10 +192,16 @@ func NewFile(w http.ResponseWriter, r *http.Request) { | |||
| 
 | ||||
| 	path := args["path"].(string) | ||||
| 	fileType := args["fileType"].(string) | ||||
| 	sid := args["sid"].(string) | ||||
| 
 | ||||
| 	wSession := session.WideSessions.Get(sid) | ||||
| 
 | ||||
| 	if !createFile(path, fileType) { | ||||
| 		data["succ"] = false | ||||
| 
 | ||||
| 		wSession.EventQueue.Queue <- &event.Event{Code: event.EvtCodeServerInternalError, Sid: sid, | ||||
| 			Data: "can't create file " + path} | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
|  | @ -204,7 +211,7 @@ func NewFile(w http.ResponseWriter, r *http.Request) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| // 删除文件/目录.
 | ||||
| // RemoveFile handles request of removing file or directory.
 | ||||
| func RemoveFile(w http.ResponseWriter, r *http.Request) { | ||||
| 	data := map[string]interface{}{"succ": true} | ||||
| 	defer util.RetJSON(w, r, data) | ||||
|  | @ -225,7 +232,7 @@ func RemoveFile(w http.ResponseWriter, r *http.Request) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| // 在目录中搜索包含指定字符串的文件.
 | ||||
| // SearchText handles request of searching files under the specified directory with the specified keyword.
 | ||||
| func SearchText(w http.ResponseWriter, r *http.Request) { | ||||
| 	data := map[string]interface{}{"succ": true} | ||||
| 	defer util.RetJSON(w, r, data) | ||||
|  |  | |||
|  | @ -35,6 +35,7 @@ | |||
|     "unread_notification": "Unread", | ||||
|     "notification_2": "Not found [gocode], thereby [Autocomplete] will not work", | ||||
|     "notification_3": "Not found [ide_stub], thereby [Jump to Decl], [Find Usages] will not work", | ||||
|     "notification_4": "Server internal error", | ||||
|     "goto_line": "Goto Line", | ||||
|     "go": "Go", | ||||
|     "tip": "Tip", | ||||
|  |  | |||
|  | @ -35,6 +35,7 @@ | |||
|     "unread_notification": "未読の通知", | ||||
|     "notification_2": "[gocode] が見つかりません。[Autocomplete] は動作しません。", | ||||
|     "notification_3": "[ide_stub] が見つかりません。[Jump to Decl]、[Find Usages] は動作しません。", | ||||
|     "notification_4": "内部サーバーエラー", | ||||
|     "goto_line": "指定行にジャンプ", | ||||
|     "go": "Go", | ||||
|     "tip": "ヒント", | ||||
|  |  | |||
|  | @ -35,6 +35,7 @@ | |||
|     "unread_notification": "未读通知", | ||||
|     "notification_2": "没有检查到 gocode,这将会导致 [自动完成] 失效", | ||||
|     "notification_3": "没有检查到 ide_stub,这将会导致 [跳转到声明]、[查找使用] 失效", | ||||
|     "notification_4": "服务器内部错误", | ||||
|     "goto_line": "跳转到行", | ||||
|     "go": "跳转", | ||||
|     "tip": "提示", | ||||
|  |  | |||
|  | @ -3,7 +3,6 @@ package notification | |||
| 
 | ||||
| import ( | ||||
| 	"net/http" | ||||
| 
 | ||||
| 	"time" | ||||
| 
 | ||||
| 	"strconv" | ||||
|  | @ -21,7 +20,8 @@ const ( | |||
| 	Warn  = "WARN"  // 通知.严重程度:WARN
 | ||||
| 	Info  = "INFO"  // 通知.严重程度:INFO
 | ||||
| 
 | ||||
| 	Setup = "Setup" // 通知.类型:安装
 | ||||
| 	Setup  = "Setup"  // 通知.类型:安装
 | ||||
| 	Server = "Server" // 通知.类型:服务器
 | ||||
| ) | ||||
| 
 | ||||
| // 通知结构.
 | ||||
|  | @ -41,16 +41,7 @@ func event2Notification(e *event.Event) { | |||
| 	} | ||||
| 
 | ||||
| 	wsChannel := session.NotificationWS[e.Sid] | ||||
| 
 | ||||
| 	var notification Notification | ||||
| 
 | ||||
| 	switch e.Code { | ||||
| 	case event.EvtCodeGocodeNotFound: | ||||
| 		notification = Notification{event: e, Type: Setup, Severity: Error} | ||||
| 	case event.EvtCodeIDEStubNotFound: | ||||
| 		notification = Notification{event: e, Type: Setup, Severity: Error} | ||||
| 	default: | ||||
| 		glog.Warningf("Can't handle event[code=%d]", e.Code) | ||||
| 	if nil == wsChannel { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
|  | @ -58,13 +49,26 @@ func event2Notification(e *event.Event) { | |||
| 	username := httpSession.Values["username"].(string) | ||||
| 	locale := conf.Wide.GetUser(username).Locale | ||||
| 
 | ||||
| 	// 消息国际化处理
 | ||||
| 	notification.Message = i18n.Get(locale, "notification_"+strconv.Itoa(e.Code)).(string) | ||||
| 	var notification *Notification | ||||
| 
 | ||||
| 	wsChannel.Conn.WriteJSON(¬ification) | ||||
| 	switch e.Code { | ||||
| 	case event.EvtCodeGocodeNotFound: | ||||
| 		fallthrough | ||||
| 	case event.EvtCodeIDEStubNotFound: | ||||
| 		notification = &Notification{event: e, Type: Setup, Severity: Error, | ||||
| 			Message: i18n.Get(locale, "notification_"+strconv.Itoa(e.Code)).(string)} | ||||
| 	case event.EvtCodeServerInternalError: | ||||
| 		notification = &Notification{event: e, Type: Server, Severity: Error, | ||||
| 			Message: i18n.Get(locale, "notification_"+strconv.Itoa(e.Code)).(string) + " [" + e.Data.(string) + "]"} | ||||
| 	default: | ||||
| 		glog.Warningf("Can't handle event[code=%d]", e.Code) | ||||
| 
 | ||||
| 	// 更新通道最近使用时间
 | ||||
| 	wsChannel.Time = time.Now() | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	wsChannel.Conn.WriteJSON(notification) | ||||
| 
 | ||||
| 	wsChannel.Refresh() | ||||
| } | ||||
| 
 | ||||
| // 建立通知通道.
 | ||||
|  | @ -101,6 +105,7 @@ func WSHandler(w http.ResponseWriter, r *http.Request) { | |||
| 			} | ||||
| 
 | ||||
| 			glog.Error("Notification WS ERROR: " + err.Error()) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
|  |  | |||
|  | @ -19,3 +19,8 @@ type WSChannel struct { | |||
| func (c *WSChannel) Close() { | ||||
| 	c.Conn.Close() | ||||
| } | ||||
| 
 | ||||
| // Refresh refreshes the channel by updating its Time.
 | ||||
| func (c *WSChannel) Refresh() { | ||||
| 	c.Time = time.Now() | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue