♻️ 引入 Gulu 工具库
This commit is contained in:
parent
1405d7482a
commit
4930408b17
27
conf/wide.go
27
conf/wide.go
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-present, b3log.org
|
// Copyright (c) 2014-present, b3gulu.Log.org
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -27,9 +27,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/b3log/gulu"
|
||||||
"github.com/b3log/wide/event"
|
"github.com/b3log/wide/event"
|
||||||
"github.com/b3log/wide/log"
|
|
||||||
"github.com/b3log/wide/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -69,7 +68,7 @@ type conf struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logger.
|
// Logger.
|
||||||
var logger = log.NewLogger(os.Stdout)
|
var logger = gulu.Log.NewLogger(os.Stdout)
|
||||||
|
|
||||||
// Wide configurations.
|
// Wide configurations.
|
||||||
var Wide *conf
|
var Wide *conf
|
||||||
|
@ -91,7 +90,7 @@ func Load(confPath, confData, confServer, confLogLevel string, confSiteStatCode
|
||||||
cmd := exec.Command("docker", "version")
|
cmd := exec.Command("docker", "version")
|
||||||
_, err := cmd.CombinedOutput()
|
_, err := cmd.CombinedOutput()
|
||||||
if nil != err {
|
if nil != err {
|
||||||
if !util.OS.IsWindows() {
|
if !gulu.OS.IsWindows() {
|
||||||
logger.Errorf("Not found 'docker' installed, running user's code will cause security problem")
|
logger.Errorf("Not found 'docker' installed, running user's code will cause security problem")
|
||||||
|
|
||||||
os.Exit(-1)
|
os.Exit(-1)
|
||||||
|
@ -179,16 +178,16 @@ func initWide(confPath, confData, confServer, confLogLevel string, confSiteStatC
|
||||||
Wide.Autocomplete = true // default to true
|
Wide.Autocomplete = true // default to true
|
||||||
|
|
||||||
// Logging Level
|
// Logging Level
|
||||||
log.SetLevel(Wide.LogLevel)
|
gulu.Log.SetLevel(Wide.LogLevel)
|
||||||
if "" != confLogLevel {
|
if "" != confLogLevel {
|
||||||
Wide.LogLevel = confLogLevel
|
Wide.LogLevel = confLogLevel
|
||||||
log.SetLevel(confLogLevel)
|
gulu.Log.SetLevel(confLogLevel)
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Debug("Conf: \n" + string(bytes))
|
logger.Debug("Conf: \n" + string(bytes))
|
||||||
|
|
||||||
// User Home
|
// User Home
|
||||||
home, err := util.OS.Home()
|
home, err := gulu.OS.Home()
|
||||||
if nil != err {
|
if nil != err {
|
||||||
logger.Error("Can't get user's home, please report this issue to developer", err)
|
logger.Error("Can't get user's home, please report this issue to developer", err)
|
||||||
|
|
||||||
|
@ -241,14 +240,14 @@ func FixedTimeCheckEnv() {
|
||||||
checkEnv() // check immediately
|
checkEnv() // check immediately
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for _ = range time.Tick(time.Minute * 7) {
|
for _ = range time.Tick(time.Minute*7) {
|
||||||
checkEnv()
|
checkEnv()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkEnv() {
|
func checkEnv() {
|
||||||
defer util.Recover()
|
defer gulu.Panic.Recover()
|
||||||
|
|
||||||
cmd := exec.Command("go", "version")
|
cmd := exec.Command("go", "version")
|
||||||
buf, err := cmd.CombinedOutput()
|
buf, err := cmd.CombinedOutput()
|
||||||
|
@ -265,7 +264,7 @@ func checkEnv() {
|
||||||
os.Exit(-1)
|
os.Exit(-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
gocode := util.Go.GetExecutableInGOBIN("gocode")
|
gocode := gulu.Go.GetExecutableInGOBIN("gocode")
|
||||||
cmd = exec.Command(gocode)
|
cmd = exec.Command(gocode)
|
||||||
_, err = cmd.Output()
|
_, err = cmd.Output()
|
||||||
if nil != err {
|
if nil != err {
|
||||||
|
@ -274,7 +273,7 @@ func checkEnv() {
|
||||||
logger.Warnf("Not found gocode [%s], please install it with this command: go get github.com/nsf/gocode", gocode)
|
logger.Warnf("Not found gocode [%s], please install it with this command: go get github.com/nsf/gocode", gocode)
|
||||||
}
|
}
|
||||||
|
|
||||||
ideStub := util.Go.GetExecutableInGOBIN("gotools")
|
ideStub := gulu.Go.GetExecutableInGOBIN("gotools")
|
||||||
cmd = exec.Command(ideStub, "version")
|
cmd = exec.Command(ideStub, "version")
|
||||||
_, err = cmd.Output()
|
_, err = cmd.Output()
|
||||||
if nil != err {
|
if nil != err {
|
||||||
|
@ -303,7 +302,7 @@ func GetGoFmt(userId string) string {
|
||||||
case "gofmt":
|
case "gofmt":
|
||||||
return "gofmt"
|
return "gofmt"
|
||||||
case "goimports":
|
case "goimports":
|
||||||
return util.Go.GetExecutableInGOBIN("goimports")
|
return gulu.Go.GetExecutableInGOBIN("goimports")
|
||||||
default:
|
default:
|
||||||
logger.Errorf("Unsupported Go Format tool [%s]", user.GoFormat)
|
logger.Errorf("Unsupported Go Format tool [%s]", user.GoFormat)
|
||||||
return "gofmt"
|
return "gofmt"
|
||||||
|
@ -413,7 +412,7 @@ func CreateWorkspaceDir(path string) {
|
||||||
|
|
||||||
// createDir creates a directory on the path if it not exists.
|
// createDir creates a directory on the path if it not exists.
|
||||||
func createDir(path string) {
|
func createDir(path string) {
|
||||||
if !util.File.IsExist(path) {
|
if !gulu.File.IsExist(path) {
|
||||||
if err := os.MkdirAll(path, 0775); nil != err {
|
if err := os.MkdirAll(path, 0775); nil != err {
|
||||||
logger.Error(err)
|
logger.Error(err)
|
||||||
|
|
||||||
|
|
|
@ -27,16 +27,16 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/b3log/gulu"
|
||||||
"github.com/b3log/wide/conf"
|
"github.com/b3log/wide/conf"
|
||||||
"github.com/b3log/wide/file"
|
"github.com/b3log/wide/file"
|
||||||
"github.com/b3log/wide/log"
|
|
||||||
"github.com/b3log/wide/session"
|
"github.com/b3log/wide/session"
|
||||||
"github.com/b3log/wide/util"
|
"github.com/b3log/wide/util"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Logger.
|
// Logger.
|
||||||
var logger = log.NewLogger(os.Stdout)
|
var logger = gulu.Log.NewLogger(os.Stdout)
|
||||||
|
|
||||||
// WSHandler handles request of creating editor channel.
|
// WSHandler handles request of creating editor channel.
|
||||||
// XXX: NOT used at present
|
// XXX: NOT used at present
|
||||||
|
@ -77,7 +77,7 @@ func WSHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
logger.Tracef("offset: %d", offset)
|
logger.Tracef("offset: %d", offset)
|
||||||
|
|
||||||
gocode := util.Go.GetExecutableInGOBIN("gocode")
|
gocode := gulu.Go.GetExecutableInGOBIN("gocode")
|
||||||
argv := []string{"-f=json", "autocomplete", strconv.Itoa(offset)}
|
argv := []string{"-f=json", "autocomplete", strconv.Itoa(offset)}
|
||||||
|
|
||||||
var output bytes.Buffer
|
var output bytes.Buffer
|
||||||
|
@ -159,7 +159,7 @@ func AutocompleteHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
logger.Tracef("gocode set lib-path [%s]", libPath)
|
logger.Tracef("gocode set lib-path [%s]", libPath)
|
||||||
|
|
||||||
// FIXME: using gocode set lib-path has some issues while accrossing workspaces
|
// FIXME: using gocode set lib-path has some issues while accrossing workspaces
|
||||||
gocode := util.Go.GetExecutableInGOBIN("gocode")
|
gocode := gulu.Go.GetExecutableInGOBIN("gocode")
|
||||||
exec.Command(gocode, []string{"set", "lib-path", libPath}...).Run()
|
exec.Command(gocode, []string{"set", "lib-path", libPath}...).Run()
|
||||||
|
|
||||||
argv := []string{"-f=json", "--in=" + path, "autocomplete", strconv.Itoa(offset)}
|
argv := []string{"-f=json", "--in=" + path, "autocomplete", strconv.Itoa(offset)}
|
||||||
|
@ -179,8 +179,8 @@ func AutocompleteHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
// GetExprInfoHandler handles request of getting expression infomation.
|
// GetExprInfoHandler handles request of getting expression infomation.
|
||||||
func GetExprInfoHandler(w http.ResponseWriter, r *http.Request) {
|
func GetExprInfoHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
result := util.NewResult()
|
result := gulu.Ret.NewResult()
|
||||||
defer util.RetResult(w, r, result)
|
defer gulu.Ret.RetResult(w, r, result)
|
||||||
|
|
||||||
session, _ := session.HTTPSession.Get(r, session.CookieName)
|
session, _ := session.HTTPSession.Get(r, session.CookieName)
|
||||||
uid := session.Values["uid"].(string)
|
uid := session.Values["uid"].(string)
|
||||||
|
@ -223,7 +223,7 @@ func GetExprInfoHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
logger.Tracef("offset [%d]", offset)
|
logger.Tracef("offset [%d]", offset)
|
||||||
|
|
||||||
ideStub := util.Go.GetExecutableInGOBIN("gotools")
|
ideStub := gulu.Go.GetExecutableInGOBIN("gotools")
|
||||||
argv := []string{"types", "-pos", filename + ":" + strconv.Itoa(offset), "-info", "."}
|
argv := []string{"types", "-pos", filename + ":" + strconv.Itoa(offset), "-info", "."}
|
||||||
cmd := exec.Command(ideStub, argv...)
|
cmd := exec.Command(ideStub, argv...)
|
||||||
cmd.Dir = curDir
|
cmd.Dir = curDir
|
||||||
|
@ -250,8 +250,8 @@ func GetExprInfoHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
// FindDeclarationHandler handles request of finding declaration.
|
// FindDeclarationHandler handles request of finding declaration.
|
||||||
func FindDeclarationHandler(w http.ResponseWriter, r *http.Request) {
|
func FindDeclarationHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
result := util.NewResult()
|
result := gulu.Ret.NewResult()
|
||||||
defer util.RetResult(w, r, result)
|
defer gulu.Ret.RetResult(w, r, result)
|
||||||
|
|
||||||
session, _ := session.HTTPSession.Get(r, session.CookieName)
|
session, _ := session.HTTPSession.Get(r, session.CookieName)
|
||||||
if session.IsNew {
|
if session.IsNew {
|
||||||
|
@ -299,7 +299,7 @@ func FindDeclarationHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
logger.Tracef("offset [%d]", offset)
|
logger.Tracef("offset [%d]", offset)
|
||||||
|
|
||||||
ideStub := util.Go.GetExecutableInGOBIN("gotools")
|
ideStub := gulu.Go.GetExecutableInGOBIN("gotools")
|
||||||
argv := []string{"types", "-pos", filename + ":" + strconv.Itoa(offset), "-def", "."}
|
argv := []string{"types", "-pos", filename + ":" + strconv.Itoa(offset), "-def", "."}
|
||||||
cmd := exec.Command(ideStub, argv...)
|
cmd := exec.Command(ideStub, argv...)
|
||||||
cmd.Dir = curDir
|
cmd.Dir = curDir
|
||||||
|
@ -338,8 +338,8 @@ func FindDeclarationHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
// FindUsagesHandler handles request of finding usages.
|
// FindUsagesHandler handles request of finding usages.
|
||||||
func FindUsagesHandler(w http.ResponseWriter, r *http.Request) {
|
func FindUsagesHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
result := util.NewResult()
|
result := gulu.Ret.NewResult()
|
||||||
defer util.RetResult(w, r, result)
|
defer gulu.Ret.RetResult(w, r, result)
|
||||||
|
|
||||||
session, _ := session.HTTPSession.Get(r, session.CookieName)
|
session, _ := session.HTTPSession.Get(r, session.CookieName)
|
||||||
if session.IsNew {
|
if session.IsNew {
|
||||||
|
@ -387,7 +387,7 @@ func FindUsagesHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
offset := getCursorOffset(code, line, ch)
|
offset := getCursorOffset(code, line, ch)
|
||||||
logger.Tracef("offset [%d]", offset)
|
logger.Tracef("offset [%d]", offset)
|
||||||
|
|
||||||
ideStub := util.Go.GetExecutableInGOBIN("gotools")
|
ideStub := gulu.Go.GetExecutableInGOBIN("gotools")
|
||||||
argv := []string{"types", "-pos", filename + ":" + strconv.Itoa(offset), "-use", "."}
|
argv := []string{"types", "-pos", filename + ":" + strconv.Itoa(offset), "-use", "."}
|
||||||
cmd := exec.Command(ideStub, argv...)
|
cmd := exec.Command(ideStub, argv...)
|
||||||
cmd.Dir = curDir
|
cmd.Dir = curDir
|
||||||
|
|
|
@ -20,9 +20,9 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
|
||||||
|
"github.com/b3log/gulu"
|
||||||
"github.com/b3log/wide/conf"
|
"github.com/b3log/wide/conf"
|
||||||
"github.com/b3log/wide/session"
|
"github.com/b3log/wide/session"
|
||||||
"github.com/b3log/wide/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// GoFmtHandler handles request of formatting Go source code.
|
// GoFmtHandler handles request of formatting Go source code.
|
||||||
|
@ -31,8 +31,8 @@ import (
|
||||||
// 1. gofmt
|
// 1. gofmt
|
||||||
// 2. goimports
|
// 2. goimports
|
||||||
func GoFmtHandler(w http.ResponseWriter, r *http.Request) {
|
func GoFmtHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
result := util.NewResult()
|
result := gulu.Ret.NewResult()
|
||||||
defer util.RetResult(w, r, result)
|
defer gulu.Ret.RetResult(w, r, result)
|
||||||
|
|
||||||
session, _ := session.HTTPSession.Get(r, session.CookieName)
|
session, _ := session.HTTPSession.Get(r, session.CookieName)
|
||||||
if session.IsNew {
|
if session.IsNew {
|
||||||
|
@ -53,7 +53,7 @@ func GoFmtHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
filePath := args["file"].(string)
|
filePath := args["file"].(string)
|
||||||
|
|
||||||
if util.Go.IsAPI(filePath) {
|
if gulu.Go.IsAPI(filePath) {
|
||||||
result.Succ = false
|
result.Succ = false
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
|
@ -18,8 +18,7 @@ package event
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/b3log/wide/log"
|
"github.com/b3log/gulu"
|
||||||
"github.com/b3log/wide/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -39,7 +38,7 @@ const (
|
||||||
const maxQueueLength = 10
|
const maxQueueLength = 10
|
||||||
|
|
||||||
// Logger.
|
// Logger.
|
||||||
var logger = log.NewLogger(os.Stdout)
|
var logger = gulu.Log.NewLogger(os.Stdout)
|
||||||
|
|
||||||
// Event represents an event.
|
// Event represents an event.
|
||||||
type Event struct {
|
type Event struct {
|
||||||
|
@ -70,7 +69,7 @@ var UserEventQueues = queues{}
|
||||||
// Load initializes the event handling.
|
// Load initializes the event handling.
|
||||||
func Load() {
|
func Load() {
|
||||||
go func() {
|
go func() {
|
||||||
defer util.Recover()
|
defer gulu.Panic.Recover()
|
||||||
|
|
||||||
for event := range EventQueue {
|
for event := range EventQueue {
|
||||||
logger.Debugf("Received a global event [code=%d]", event.Code)
|
logger.Debugf("Received a global event [code=%d]", event.Code)
|
||||||
|
@ -107,7 +106,7 @@ func (ueqs queues) New(sid string) *UserEventQueue {
|
||||||
ueqs[sid] = q
|
ueqs[sid] = q
|
||||||
|
|
||||||
go func() { // start listening
|
go func() { // start listening
|
||||||
defer util.Recover()
|
defer gulu.Panic.Recover()
|
||||||
|
|
||||||
for evt := range q.Queue {
|
for evt := range q.Queue {
|
||||||
logger.Debugf("Session [%s] received an event [%d]", sid, evt.Code)
|
logger.Debugf("Session [%s] received an event [%d]", sid, evt.Code)
|
||||||
|
|
|
@ -20,7 +20,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/b3log/wide/util"
|
"github.com/b3log/gulu"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetZipHandler handles request of retrieving zip file.
|
// GetZipHandler handles request of retrieving zip file.
|
||||||
|
@ -34,7 +34,7 @@ func GetZipHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !util.File.IsExist(path) {
|
if !gulu.File.IsExist(path) {
|
||||||
http.Error(w, "Not Found", 404)
|
http.Error(w, "Not Found", 404)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -51,8 +51,8 @@ func GetZipHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
// CreateZipHandler handles request of creating zip.
|
// CreateZipHandler handles request of creating zip.
|
||||||
func CreateZipHandler(w http.ResponseWriter, r *http.Request) {
|
func CreateZipHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
data := util.NewResult()
|
data := gulu.Ret.NewResult()
|
||||||
defer util.RetResult(w, r, data)
|
defer gulu.Ret.RetResult(w, r, data)
|
||||||
|
|
||||||
var args map[string]interface{}
|
var args map[string]interface{}
|
||||||
if err := json.NewDecoder(r.Body).Decode(&args); err != nil {
|
if err := json.NewDecoder(r.Body).Decode(&args); err != nil {
|
||||||
|
@ -75,7 +75,7 @@ func CreateZipHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
dir := filepath.Dir(path)
|
dir := filepath.Dir(path)
|
||||||
|
|
||||||
if !util.File.IsExist(path) {
|
if !gulu.File.IsExist(path) {
|
||||||
data.Succ = false
|
data.Succ = false
|
||||||
data.Msg = "Can't find file [" + path + "]"
|
data.Msg = "Can't find file [" + path + "]"
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ func CreateZipHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
zipPath := filepath.Join(dir, name)
|
zipPath := filepath.Join(dir, name)
|
||||||
zipFile, err := util.Zip.Create(zipPath + ".zip")
|
zipFile, err := gulu.Zip.Create(zipPath + ".zip")
|
||||||
if nil != err {
|
if nil != err {
|
||||||
logger.Error(err)
|
logger.Error(err)
|
||||||
data.Succ = false
|
data.Succ = false
|
||||||
|
@ -92,7 +92,7 @@ func CreateZipHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
defer zipFile.Close()
|
defer zipFile.Close()
|
||||||
|
|
||||||
if util.File.IsDir(path) {
|
if gulu.File.IsDir(path) {
|
||||||
zipFile.AddDirectory(base, path)
|
zipFile.AddDirectory(base, path)
|
||||||
} else {
|
} else {
|
||||||
zipFile.AddEntry(base, path)
|
zipFile.AddEntry(base, path)
|
||||||
|
|
|
@ -24,15 +24,14 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/b3log/gulu"
|
||||||
"github.com/b3log/wide/conf"
|
"github.com/b3log/wide/conf"
|
||||||
"github.com/b3log/wide/event"
|
"github.com/b3log/wide/event"
|
||||||
"github.com/b3log/wide/log"
|
|
||||||
"github.com/b3log/wide/session"
|
"github.com/b3log/wide/session"
|
||||||
"github.com/b3log/wide/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Logger.
|
// Logger.
|
||||||
var logger = log.NewLogger(os.Stdout)
|
var logger = gulu.Log.NewLogger(os.Stdout)
|
||||||
|
|
||||||
// Node represents a file node in file tree.
|
// Node represents a file node in file tree.
|
||||||
type Node struct {
|
type Node struct {
|
||||||
|
@ -61,7 +60,7 @@ var apiNode *Node
|
||||||
|
|
||||||
// initAPINode builds the Go API file node.
|
// initAPINode builds the Go API file node.
|
||||||
func initAPINode() {
|
func initAPINode() {
|
||||||
apiPath := util.Go.GetAPIPath()
|
apiPath := gulu.Go.GetAPIPath()
|
||||||
|
|
||||||
apiNode = &Node{Name: "Go API", Path: apiPath, IconSkin: "ico-ztree-dir-api ", Type: "d",
|
apiNode = &Node{Name: "Go API", Path: apiPath, IconSkin: "ico-ztree-dir-api ", Type: "d",
|
||||||
Creatable: false, Removable: false, IsGoAPI: true, Children: []*Node{}}
|
Creatable: false, Removable: false, IsGoAPI: true, Children: []*Node{}}
|
||||||
|
@ -82,8 +81,8 @@ func GetFilesHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
uid := httpSession.Values["uid"].(string)
|
uid := httpSession.Values["uid"].(string)
|
||||||
|
|
||||||
result := util.NewResult()
|
result := gulu.Ret.NewResult()
|
||||||
defer util.RetGzResult(w, r, result)
|
defer gulu.Ret.RetGzResult(w, r, result)
|
||||||
|
|
||||||
userWorkspace := conf.GetUserWorkspace(uid)
|
userWorkspace := conf.GetUserWorkspace(uid)
|
||||||
workspaces := filepath.SplitList(userWorkspace)
|
workspaces := filepath.SplitList(userWorkspace)
|
||||||
|
@ -134,7 +133,7 @@ func RefreshDirectoryHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
r.ParseForm()
|
r.ParseForm()
|
||||||
path := r.FormValue("path")
|
path := r.FormValue("path")
|
||||||
|
|
||||||
if !util.Go.IsAPI(path) && !session.CanAccess(uid, path) {
|
if !gulu.Go.IsAPI(path) && !session.CanAccess(uid, path) {
|
||||||
http.Error(w, "Forbidden", http.StatusForbidden)
|
http.Error(w, "Forbidden", http.StatusForbidden)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -164,8 +163,8 @@ func GetFileHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
uid := httpSession.Values["uid"].(string)
|
uid := httpSession.Values["uid"].(string)
|
||||||
|
|
||||||
result := util.NewResult()
|
result := gulu.Ret.NewResult()
|
||||||
defer util.RetResult(w, r, result)
|
defer gulu.Ret.RetResult(w, r, result)
|
||||||
|
|
||||||
var args map[string]interface{}
|
var args map[string]interface{}
|
||||||
|
|
||||||
|
@ -178,13 +177,13 @@ func GetFileHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
path := args["path"].(string)
|
path := args["path"].(string)
|
||||||
|
|
||||||
if !util.Go.IsAPI(path) && !session.CanAccess(uid, path) {
|
if !gulu.Go.IsAPI(path) && !session.CanAccess(uid, path) {
|
||||||
http.Error(w, "Forbidden", http.StatusForbidden)
|
http.Error(w, "Forbidden", http.StatusForbidden)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
size := util.File.GetFileSize(path)
|
size := gulu.File.GetFileSize(path)
|
||||||
if size > 5242880 { // 5M
|
if size > 5242880 { // 5M
|
||||||
result.Succ = false
|
result.Succ = false
|
||||||
result.Msg = "This file is too large to open :("
|
result.Msg = "This file is too large to open :("
|
||||||
|
@ -199,7 +198,7 @@ func GetFileHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
extension := filepath.Ext(path)
|
extension := filepath.Ext(path)
|
||||||
|
|
||||||
if util.File.IsImg(extension) {
|
if gulu.File.IsImg(extension) {
|
||||||
// image file will be open in a browser tab
|
// image file will be open in a browser tab
|
||||||
|
|
||||||
data["mode"] = "img"
|
data["mode"] = "img"
|
||||||
|
@ -221,7 +220,7 @@ func GetFileHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
content := string(buf)
|
content := string(buf)
|
||||||
|
|
||||||
if util.File.IsBinary(content) {
|
if gulu.File.IsBinary(content) {
|
||||||
result.Succ = false
|
result.Succ = false
|
||||||
result.Msg = "Can't open a binary file :("
|
result.Msg = "Can't open a binary file :("
|
||||||
} else {
|
} else {
|
||||||
|
@ -240,8 +239,8 @@ func SaveFileHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
uid := httpSession.Values["uid"].(string)
|
uid := httpSession.Values["uid"].(string)
|
||||||
|
|
||||||
result := util.NewResult()
|
result := gulu.Ret.NewResult()
|
||||||
defer util.RetResult(w, r, result)
|
defer gulu.Ret.RetResult(w, r, result)
|
||||||
|
|
||||||
var args map[string]interface{}
|
var args map[string]interface{}
|
||||||
|
|
||||||
|
@ -255,7 +254,7 @@ func SaveFileHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
filePath := args["file"].(string)
|
filePath := args["file"].(string)
|
||||||
sid := args["sid"].(string)
|
sid := args["sid"].(string)
|
||||||
|
|
||||||
if util.Go.IsAPI(filePath) || !session.CanAccess(uid, filePath) {
|
if gulu.Go.IsAPI(filePath) || !session.CanAccess(uid, filePath) {
|
||||||
http.Error(w, "Forbidden", http.StatusForbidden)
|
http.Error(w, "Forbidden", http.StatusForbidden)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -296,8 +295,8 @@ func NewFileHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
uid := httpSession.Values["uid"].(string)
|
uid := httpSession.Values["uid"].(string)
|
||||||
|
|
||||||
result := util.NewResult()
|
result := gulu.Ret.NewResult()
|
||||||
defer util.RetResult(w, r, result)
|
defer gulu.Ret.RetResult(w, r, result)
|
||||||
|
|
||||||
var args map[string]interface{}
|
var args map[string]interface{}
|
||||||
|
|
||||||
|
@ -310,7 +309,7 @@ func NewFileHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
path := args["path"].(string)
|
path := args["path"].(string)
|
||||||
|
|
||||||
if util.Go.IsAPI(path) || !session.CanAccess(uid, path) {
|
if gulu.Go.IsAPI(path) || !session.CanAccess(uid, path) {
|
||||||
http.Error(w, "Forbidden", http.StatusForbidden)
|
http.Error(w, "Forbidden", http.StatusForbidden)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -348,8 +347,8 @@ func RemoveFileHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
uid := httpSession.Values["uid"].(string)
|
uid := httpSession.Values["uid"].(string)
|
||||||
|
|
||||||
result := util.NewResult()
|
result := gulu.Ret.NewResult()
|
||||||
defer util.RetResult(w, r, result)
|
defer gulu.Ret.RetResult(w, r, result)
|
||||||
|
|
||||||
var args map[string]interface{}
|
var args map[string]interface{}
|
||||||
|
|
||||||
|
@ -362,7 +361,7 @@ func RemoveFileHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
path := args["path"].(string)
|
path := args["path"].(string)
|
||||||
|
|
||||||
if util.Go.IsAPI(path) || !session.CanAccess(uid, path) {
|
if gulu.Go.IsAPI(path) || !session.CanAccess(uid, path) {
|
||||||
http.Error(w, "Forbidden", http.StatusForbidden)
|
http.Error(w, "Forbidden", http.StatusForbidden)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -394,8 +393,8 @@ func RenameFileHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
uid := httpSession.Values["uid"].(string)
|
uid := httpSession.Values["uid"].(string)
|
||||||
|
|
||||||
result := util.NewResult()
|
result := gulu.Ret.NewResult()
|
||||||
defer util.RetResult(w, r, result)
|
defer gulu.Ret.RetResult(w, r, result)
|
||||||
|
|
||||||
var args map[string]interface{}
|
var args map[string]interface{}
|
||||||
|
|
||||||
|
@ -407,7 +406,7 @@ func RenameFileHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
oldPath := args["oldPath"].(string)
|
oldPath := args["oldPath"].(string)
|
||||||
if util.Go.IsAPI(oldPath) ||
|
if gulu.Go.IsAPI(oldPath) ||
|
||||||
!session.CanAccess(uid, oldPath) {
|
!session.CanAccess(uid, oldPath) {
|
||||||
http.Error(w, "Forbidden", http.StatusForbidden)
|
http.Error(w, "Forbidden", http.StatusForbidden)
|
||||||
|
|
||||||
|
@ -415,7 +414,7 @@ func RenameFileHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
newPath := args["newPath"].(string)
|
newPath := args["newPath"].(string)
|
||||||
if util.Go.IsAPI(newPath) || !session.CanAccess(uid, newPath) {
|
if gulu.Go.IsAPI(newPath) || !session.CanAccess(uid, newPath) {
|
||||||
http.Error(w, "Forbidden", http.StatusForbidden)
|
http.Error(w, "Forbidden", http.StatusForbidden)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -459,8 +458,8 @@ func FindHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
uid := httpSession.Values["uid"].(string)
|
uid := httpSession.Values["uid"].(string)
|
||||||
|
|
||||||
result := util.NewResult()
|
result := gulu.Ret.NewResult()
|
||||||
defer util.RetResult(w, r, result)
|
defer gulu.Ret.RetResult(w, r, result)
|
||||||
|
|
||||||
var args map[string]interface{}
|
var args map[string]interface{}
|
||||||
if err := json.NewDecoder(r.Body).Decode(&args); err != nil {
|
if err := json.NewDecoder(r.Body).Decode(&args); err != nil {
|
||||||
|
@ -471,7 +470,7 @@ func FindHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
path := args["path"].(string) // path of selected file in file tree
|
path := args["path"].(string) // path of selected file in file tree
|
||||||
if !util.Go.IsAPI(path) && !session.CanAccess(uid, path) {
|
if !gulu.Go.IsAPI(path) && !session.CanAccess(uid, path) {
|
||||||
http.Error(w, "Forbidden", http.StatusForbidden)
|
http.Error(w, "Forbidden", http.StatusForbidden)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -482,7 +481,7 @@ func FindHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
userWorkspace := conf.GetUserWorkspace(uid)
|
userWorkspace := conf.GetUserWorkspace(uid)
|
||||||
workspaces := filepath.SplitList(userWorkspace)
|
workspaces := filepath.SplitList(userWorkspace)
|
||||||
|
|
||||||
if "" != path && !util.File.IsDir(path) {
|
if "" != path && !gulu.File.IsDir(path) {
|
||||||
path = filepath.Dir(path)
|
path = filepath.Dir(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -492,7 +491,7 @@ func FindHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
rs := find(workspace+conf.PathSeparator+"src", name, []*string{})
|
rs := find(workspace+conf.PathSeparator+"src", name, []*string{})
|
||||||
|
|
||||||
for _, r := range rs {
|
for _, r := range rs {
|
||||||
substr := util.Str.LCS(path, *r)
|
substr := gulu.Str.LCS(path, *r)
|
||||||
|
|
||||||
founds = append(founds, &foundPath{Path: filepath.ToSlash(*r), score: len(substr)})
|
founds = append(founds, &foundPath{Path: filepath.ToSlash(*r), score: len(substr)})
|
||||||
}
|
}
|
||||||
|
@ -512,8 +511,8 @@ func SearchTextHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
result := util.NewResult()
|
result := gulu.Ret.NewResult()
|
||||||
defer util.RetResult(w, r, result)
|
defer gulu.Ret.RetResult(w, r, result)
|
||||||
|
|
||||||
var args map[string]interface{}
|
var args map[string]interface{}
|
||||||
|
|
||||||
|
@ -545,7 +544,7 @@ func SearchTextHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
text := args["text"].(string)
|
text := args["text"].(string)
|
||||||
|
|
||||||
founds := []*Snippet{}
|
founds := []*Snippet{}
|
||||||
if util.File.IsDir(dir) {
|
if gulu.File.IsDir(dir) {
|
||||||
founds = search(dir, extension, text, []*Snippet{})
|
founds = search(dir, extension, text, []*Snippet{})
|
||||||
} else {
|
} else {
|
||||||
founds = searchInFile(dir, text)
|
founds = searchInFile(dir, text)
|
||||||
|
@ -644,7 +643,7 @@ func listFiles(dirname string) []string {
|
||||||
//
|
//
|
||||||
// Refers to the zTree document for CSS class names.
|
// Refers to the zTree document for CSS class names.
|
||||||
func getIconSkin(filenameExtension string) string {
|
func getIconSkin(filenameExtension string) string {
|
||||||
if util.File.IsImg(filenameExtension) {
|
if gulu.File.IsImg(filenameExtension) {
|
||||||
return "ico-ztree-img "
|
return "ico-ztree-img "
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -763,7 +762,7 @@ func find(dir, name string, results []*string) []*string {
|
||||||
path := dir + fname
|
path := dir + fname
|
||||||
|
|
||||||
if fileInfo.IsDir() {
|
if fileInfo.IsDir() {
|
||||||
if util.Str.Contains(fname, defaultExcludesFind) {
|
if gulu.Str.Contains(fname, defaultExcludesFind) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -836,7 +835,7 @@ func searchInFile(path string, text string) []*Snippet {
|
||||||
}
|
}
|
||||||
|
|
||||||
content := string(bytes)
|
content := string(bytes)
|
||||||
if util.File.IsBinary(content) {
|
if gulu.File.IsBinary(content) {
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/b3log/wide/util"
|
"github.com/b3log/gulu"
|
||||||
)
|
)
|
||||||
|
|
||||||
type element struct {
|
type element struct {
|
||||||
|
@ -34,8 +34,8 @@ type element struct {
|
||||||
|
|
||||||
// GetOutlineHandler gets outfile of a go file.
|
// GetOutlineHandler gets outfile of a go file.
|
||||||
func GetOutlineHandler(w http.ResponseWriter, r *http.Request) {
|
func GetOutlineHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
result := util.NewResult()
|
result := gulu.Ret.NewResult()
|
||||||
defer util.RetResult(w, r, result)
|
defer gulu.Ret.RetResult(w, r, result)
|
||||||
|
|
||||||
var args map[string]interface{}
|
var args map[string]interface{}
|
||||||
|
|
||||||
|
|
9
go.mod
9
go.mod
|
@ -3,6 +3,7 @@ module github.com/b3log/wide
|
||||||
go 1.12
|
go 1.12
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/b3log/gulu v0.0.0-20190524125155-0ed03084217c
|
||||||
github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f // indirect
|
github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f // indirect
|
||||||
github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f // indirect
|
github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f // indirect
|
||||||
github.com/fsnotify/fsnotify v1.4.7
|
github.com/fsnotify/fsnotify v1.4.7
|
||||||
|
@ -10,12 +11,12 @@ require (
|
||||||
github.com/gorilla/securecookie v0.0.0-20150327155805-8e98dd730fc4 // indirect
|
github.com/gorilla/securecookie v0.0.0-20150327155805-8e98dd730fc4 // indirect
|
||||||
github.com/gorilla/sessions v0.0.0-20150417174705-f61c3ec2cf65
|
github.com/gorilla/sessions v0.0.0-20150417174705-f61c3ec2cf65
|
||||||
github.com/gorilla/websocket v0.0.0-20150530030352-a3ec486e6a7a
|
github.com/gorilla/websocket v0.0.0-20150530030352-a3ec486e6a7a
|
||||||
github.com/hashicorp/go-version v1.2.0
|
|
||||||
github.com/moul/http2curl v1.0.0 // indirect
|
github.com/moul/http2curl v1.0.0 // indirect
|
||||||
github.com/parnurzeal/gorequest v0.2.15
|
github.com/parnurzeal/gorequest v0.2.15
|
||||||
github.com/pkg/errors v0.8.1 // indirect
|
github.com/pkg/errors v0.8.1 // indirect
|
||||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a // indirect
|
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a // indirect
|
||||||
golang.org/x/net v0.0.0-20190514140710-3ec191127204 // indirect
|
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f // indirect
|
||||||
golang.org/x/sys v0.0.0-20190515190549-87c872767d25 // indirect
|
golang.org/x/net v0.0.0-20190522155817-f3200d17e092 // indirect
|
||||||
golang.org/x/text v0.3.2
|
golang.org/x/sys v0.0.0-20190524122548-abf6ff778158 // indirect
|
||||||
|
golang.org/x/tools v0.0.0-20190523174634-38d8bcfa38af // indirect
|
||||||
)
|
)
|
||||||
|
|
14
go.sum
14
go.sum
|
@ -1,3 +1,7 @@
|
||||||
|
github.com/b3log/gulu v0.0.0-20190524124046-926f105c6dd8 h1:Ir8QVO1dwv6MEdkAE7L1oS5bJheb0Dr+AYmBXskQPF0=
|
||||||
|
github.com/b3log/gulu v0.0.0-20190524124046-926f105c6dd8/go.mod h1:UmyB0pe8jv1K3dZy/4UE3uCpM8zYkB4nbiIgjemuQ7A=
|
||||||
|
github.com/b3log/gulu v0.0.0-20190524125155-0ed03084217c h1:1+Pr5/IUfYBTiZVyzX7CfdkLVtL+LZa5yrxhjLlPYXY=
|
||||||
|
github.com/b3log/gulu v0.0.0-20190524125155-0ed03084217c/go.mod h1:UmyB0pe8jv1K3dZy/4UE3uCpM8zYkB4nbiIgjemuQ7A=
|
||||||
github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f h1:8GDPb0tCY8LQ+OJ3dbHb5sA6YZWXFORQYZx5sdsTlMs=
|
github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f h1:8GDPb0tCY8LQ+OJ3dbHb5sA6YZWXFORQYZx5sdsTlMs=
|
||||||
github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||||
github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f h1:AUj1VoZUfhPhOPHULCQQDnGhRelpFWHMLhQVWDsS0v4=
|
github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f h1:AUj1VoZUfhPhOPHULCQQDnGhRelpFWHMLhQVWDsS0v4=
|
||||||
|
@ -14,8 +18,6 @@ github.com/gorilla/sessions v0.0.0-20150417174705-f61c3ec2cf65 h1:bDPV+Nh80WIp0U
|
||||||
github.com/gorilla/sessions v0.0.0-20150417174705-f61c3ec2cf65/go.mod h1:+WVp8kdw6VhyKExm03PAMRn2ZxnPtm58pV0dBVPdhHE=
|
github.com/gorilla/sessions v0.0.0-20150417174705-f61c3ec2cf65/go.mod h1:+WVp8kdw6VhyKExm03PAMRn2ZxnPtm58pV0dBVPdhHE=
|
||||||
github.com/gorilla/websocket v0.0.0-20150530030352-a3ec486e6a7a h1:p/PGT+3UGSK7eULOGHUMCUxI5U976R34HWuKHbFpK3Q=
|
github.com/gorilla/websocket v0.0.0-20150530030352-a3ec486e6a7a h1:p/PGT+3UGSK7eULOGHUMCUxI5U976R34HWuKHbFpK3Q=
|
||||||
github.com/gorilla/websocket v0.0.0-20150530030352-a3ec486e6a7a/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
github.com/gorilla/websocket v0.0.0-20150530030352-a3ec486e6a7a/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||||
github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E=
|
|
||||||
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
|
||||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
github.com/moul/http2curl v1.0.0 h1:dRMWoAtb+ePxMlLkrCbAqh4TlPHXvoGUSQ323/9Zahs=
|
github.com/moul/http2curl v1.0.0 h1:dRMWoAtb+ePxMlLkrCbAqh4TlPHXvoGUSQ323/9Zahs=
|
||||||
|
@ -30,14 +32,22 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1
|
||||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs=
|
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs=
|
||||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190514140710-3ec191127204 h1:4yG6GqBtw9C+UrLp6s2wtSniayy/Vd/3F7ffLE427XI=
|
golang.org/x/net v0.0.0-20190514140710-3ec191127204 h1:4yG6GqBtw9C+UrLp6s2wtSniayy/Vd/3F7ffLE427XI=
|
||||||
golang.org/x/net v0.0.0-20190514140710-3ec191127204/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190514140710-3ec191127204/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco=
|
||||||
|
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190515190549-87c872767d25 h1:SSKQq5sjDoW0L0NaDoVl7d7HmtTxM0ezm0Ef9azs4uQ=
|
golang.org/x/sys v0.0.0-20190515190549-87c872767d25 h1:SSKQq5sjDoW0L0NaDoVl7d7HmtTxM0ezm0Ef9azs4uQ=
|
||||||
golang.org/x/sys v0.0.0-20190515190549-87c872767d25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190515190549-87c872767d25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190524122548-abf6ff778158/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
golang.org/x/tools v0.0.0-20190523174634-38d8bcfa38af/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
|
|
|
@ -22,11 +22,11 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/b3log/wide/log"
|
"github.com/b3log/gulu"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Logger.
|
// Logger.
|
||||||
var logger = log.NewLogger(os.Stdout)
|
var logger = gulu.Log.NewLogger(os.Stdout)
|
||||||
|
|
||||||
// Locale.
|
// Locale.
|
||||||
type locale struct {
|
type locale struct {
|
||||||
|
|
217
log/logs.go
217
log/logs.go
|
@ -1,217 +0,0 @@
|
||||||
// Copyright (c) 2014-present, b3log.org
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Package log includes logging related manipulations.
|
|
||||||
//
|
|
||||||
// log.SetLevel("debug")
|
|
||||||
// logger := log.NewLogger(os.Stdout)
|
|
||||||
//
|
|
||||||
// logger.Trace("trace message)
|
|
||||||
// logger.Debug("debug message")
|
|
||||||
// logger.Info("info message")
|
|
||||||
// logger.Warn("warning message")
|
|
||||||
// logger.Error("error message")
|
|
||||||
//
|
|
||||||
// logger.Errorf("formatted %s message", "error")
|
|
||||||
package log
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
stdlog "log"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Logging level.
|
|
||||||
const (
|
|
||||||
Off = iota
|
|
||||||
Trace
|
|
||||||
Debug
|
|
||||||
Info
|
|
||||||
Warn
|
|
||||||
Error
|
|
||||||
)
|
|
||||||
|
|
||||||
// all loggers.
|
|
||||||
var loggers []*Logger
|
|
||||||
|
|
||||||
// the global default logging level, it will be used for creating logger.
|
|
||||||
var logLevel = Debug
|
|
||||||
|
|
||||||
// Logger represents a simple logger with level.
|
|
||||||
// The underlying logger is the standard Go logging "log".
|
|
||||||
type Logger struct {
|
|
||||||
level int
|
|
||||||
logger *stdlog.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewLogger creates a logger.
|
|
||||||
func NewLogger(out io.Writer) *Logger {
|
|
||||||
ret := &Logger{level: logLevel, logger: stdlog.New(out, "", stdlog.Ldate|stdlog.Ltime|stdlog.Lshortfile)}
|
|
||||||
|
|
||||||
loggers = append(loggers, ret)
|
|
||||||
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetLevel sets the logging level of all loggers.
|
|
||||||
func SetLevel(level string) {
|
|
||||||
logLevel = getLevel(level)
|
|
||||||
|
|
||||||
for _, l := range loggers {
|
|
||||||
l.SetLevel(level)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// getLevel gets logging level int value corresponding to the specified level.
|
|
||||||
func getLevel(level string) int {
|
|
||||||
level = strings.ToLower(level)
|
|
||||||
|
|
||||||
switch level {
|
|
||||||
case "off":
|
|
||||||
return Off
|
|
||||||
case "trace":
|
|
||||||
return Trace
|
|
||||||
case "debug":
|
|
||||||
return Debug
|
|
||||||
case "info":
|
|
||||||
return Info
|
|
||||||
case "warn":
|
|
||||||
return Warn
|
|
||||||
case "error":
|
|
||||||
return Error
|
|
||||||
default:
|
|
||||||
return Info
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetLevel sets the logging level of a logger.
|
|
||||||
func (l *Logger) SetLevel(level string) {
|
|
||||||
l.level = getLevel(level)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsTraceEnabled determines whether the trace level is enabled.
|
|
||||||
func (l *Logger) IsTraceEnabled() bool {
|
|
||||||
return l.level <= Trace
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsDebugEnabled determines whether the debug level is enabled.
|
|
||||||
func (l *Logger) IsDebugEnabled() bool {
|
|
||||||
return l.level <= Debug
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsWarnEnabled determines whether the debug level is enabled.
|
|
||||||
func (l *Logger) IsWarnEnabled() bool {
|
|
||||||
return l.level <= Warn
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trace prints trace level message.
|
|
||||||
func (l *Logger) Trace(v ...interface{}) {
|
|
||||||
if Trace < l.level {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l.logger.SetPrefix("T ")
|
|
||||||
l.logger.Output(2, fmt.Sprint(v...))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tracef prints trace level message with format.
|
|
||||||
func (l *Logger) Tracef(format string, v ...interface{}) {
|
|
||||||
if Trace < l.level {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l.logger.SetPrefix("T ")
|
|
||||||
l.logger.Output(2, fmt.Sprintf(format, v...))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Debug prints debug level message.
|
|
||||||
func (l *Logger) Debug(v ...interface{}) {
|
|
||||||
if Debug < l.level {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l.logger.SetPrefix("D ")
|
|
||||||
l.logger.Output(2, fmt.Sprint(v...))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Debugf prints debug level message with format.
|
|
||||||
func (l *Logger) Debugf(format string, v ...interface{}) {
|
|
||||||
if Debug < l.level {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l.logger.SetPrefix("D ")
|
|
||||||
l.logger.Output(2, fmt.Sprintf(format, v...))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Info prints info level message.
|
|
||||||
func (l *Logger) Info(v ...interface{}) {
|
|
||||||
if Info < l.level {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l.logger.SetPrefix("I ")
|
|
||||||
l.logger.Output(2, fmt.Sprint(v...))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Infof prints info level message with format.
|
|
||||||
func (l *Logger) Infof(format string, v ...interface{}) {
|
|
||||||
if Info < l.level {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l.logger.SetPrefix("I ")
|
|
||||||
l.logger.Output(2, fmt.Sprintf(format, v...))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Warn prints warning level message.
|
|
||||||
func (l *Logger) Warn(v ...interface{}) {
|
|
||||||
if Warn < l.level {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l.logger.SetPrefix("W ")
|
|
||||||
l.logger.Output(2, fmt.Sprint(v...))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Warn prints warning level message with format.
|
|
||||||
func (l *Logger) Warnf(format string, v ...interface{}) {
|
|
||||||
if Warn < l.level {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l.logger.SetPrefix("W ")
|
|
||||||
l.logger.Output(2, fmt.Sprintf(format, v...))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error prints error level message.
|
|
||||||
func (l *Logger) Error(v ...interface{}) {
|
|
||||||
if Error < l.level {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l.logger.SetPrefix("E ")
|
|
||||||
l.logger.Output(2, fmt.Sprint(v...))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Errorf prints error level message with format.
|
|
||||||
func (l *Logger) Errorf(format string, v ...interface{}) {
|
|
||||||
if Error < l.level {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l.logger.SetPrefix("E ")
|
|
||||||
l.logger.Output(2, fmt.Sprintf(format, v...))
|
|
||||||
}
|
|
169
log/logs_test.go
169
log/logs_test.go
|
@ -1,169 +0,0 @@
|
||||||
// Copyright (c) 2014-present, b3log.org
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package log
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Logger.
|
|
||||||
var logger = NewLogger(os.Stdout)
|
|
||||||
|
|
||||||
func TestSetLevel(t *testing.T) {
|
|
||||||
SetLevel("trace")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTrace(t *testing.T) {
|
|
||||||
logger.SetLevel("trace")
|
|
||||||
logger.Trace("trace")
|
|
||||||
logger.SetLevel("off")
|
|
||||||
logger.Trace("trace")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTracef(t *testing.T) {
|
|
||||||
logger.SetLevel("trace")
|
|
||||||
logger.Tracef("tracef")
|
|
||||||
logger.SetLevel("off")
|
|
||||||
logger.Tracef("tracef")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDebug(t *testing.T) {
|
|
||||||
logger.SetLevel("debug")
|
|
||||||
logger.Debug("debug")
|
|
||||||
logger.SetLevel("off")
|
|
||||||
logger.Debug("debug")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDebugf(t *testing.T) {
|
|
||||||
logger.SetLevel("debug")
|
|
||||||
logger.Debugf("debugf")
|
|
||||||
logger.SetLevel("off")
|
|
||||||
logger.Debug("debug")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestInfo(t *testing.T) {
|
|
||||||
logger.SetLevel("info")
|
|
||||||
logger.Info("info")
|
|
||||||
logger.SetLevel("off")
|
|
||||||
logger.Info("info")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestInfof(t *testing.T) {
|
|
||||||
logger.SetLevel("info")
|
|
||||||
logger.Infof("infof")
|
|
||||||
logger.SetLevel("off")
|
|
||||||
logger.Infof("infof")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestWarn(t *testing.T) {
|
|
||||||
logger.SetLevel("warn")
|
|
||||||
logger.Warn("warn")
|
|
||||||
logger.SetLevel("off")
|
|
||||||
logger.Warn("warn")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestWarnf(t *testing.T) {
|
|
||||||
logger.SetLevel("warn")
|
|
||||||
logger.Warnf("warnf")
|
|
||||||
logger.SetLevel("off")
|
|
||||||
logger.Warnf("warnf")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestError(t *testing.T) {
|
|
||||||
logger.SetLevel("error")
|
|
||||||
logger.Error("error")
|
|
||||||
logger.SetLevel("off")
|
|
||||||
logger.Error("error")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestErrorf(t *testing.T) {
|
|
||||||
logger.SetLevel("error")
|
|
||||||
logger.Errorf("errorf")
|
|
||||||
logger.SetLevel("off")
|
|
||||||
logger.Errorf("errorf")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetLevel(t *testing.T) {
|
|
||||||
if getLevel("trace") != Trace {
|
|
||||||
t.FailNow()
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if getLevel("debug") != Debug {
|
|
||||||
t.FailNow()
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if getLevel("info") != Info {
|
|
||||||
t.FailNow()
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if getLevel("warn") != Warn {
|
|
||||||
t.FailNow()
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if getLevel("error") != Error {
|
|
||||||
t.FailNow()
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLoggerSetLevel(t *testing.T) {
|
|
||||||
logger.SetLevel("trace")
|
|
||||||
|
|
||||||
if logger.level != Trace {
|
|
||||||
t.FailNow()
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIsTraceEnabled(t *testing.T) {
|
|
||||||
logger.SetLevel("trace")
|
|
||||||
|
|
||||||
if !logger.IsTraceEnabled() {
|
|
||||||
t.FailNow()
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIsDebugEnabled(t *testing.T) {
|
|
||||||
logger.SetLevel("debug")
|
|
||||||
|
|
||||||
if !logger.IsDebugEnabled() {
|
|
||||||
t.FailNow()
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIsWarnEnabled(t *testing.T) {
|
|
||||||
logger.SetLevel("warn")
|
|
||||||
|
|
||||||
if !logger.IsWarnEnabled() {
|
|
||||||
t.FailNow()
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
17
main.go
17
main.go
|
@ -29,21 +29,20 @@ import (
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/b3log/gulu"
|
||||||
"github.com/b3log/wide/conf"
|
"github.com/b3log/wide/conf"
|
||||||
"github.com/b3log/wide/editor"
|
"github.com/b3log/wide/editor"
|
||||||
"github.com/b3log/wide/event"
|
"github.com/b3log/wide/event"
|
||||||
"github.com/b3log/wide/file"
|
"github.com/b3log/wide/file"
|
||||||
"github.com/b3log/wide/i18n"
|
"github.com/b3log/wide/i18n"
|
||||||
"github.com/b3log/wide/log"
|
|
||||||
"github.com/b3log/wide/notification"
|
"github.com/b3log/wide/notification"
|
||||||
"github.com/b3log/wide/output"
|
"github.com/b3log/wide/output"
|
||||||
"github.com/b3log/wide/playground"
|
"github.com/b3log/wide/playground"
|
||||||
"github.com/b3log/wide/session"
|
"github.com/b3log/wide/session"
|
||||||
"github.com/b3log/wide/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Logger
|
// Logger
|
||||||
var logger *log.Logger
|
var logger *gulu.Logger
|
||||||
|
|
||||||
// The only one init function in Wide.
|
// The only one init function in Wide.
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -55,10 +54,10 @@ func init() {
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
log.SetLevel("warn")
|
gulu.Log.SetLevel("warn")
|
||||||
logger = log.NewLogger(os.Stdout)
|
logger = gulu.Log.NewLogger(os.Stdout)
|
||||||
|
|
||||||
//wd := util.OS.Pwd()
|
//wd := gulu.OS.Pwd()
|
||||||
//if strings.HasPrefix(wd, os.TempDir()) {
|
//if strings.HasPrefix(wd, os.TempDir()) {
|
||||||
// logger.Error("Don't run Wide in OS' temp directory or with `go run`")
|
// logger.Error("Don't run Wide in OS' temp directory or with `go run`")
|
||||||
//
|
//
|
||||||
|
@ -74,7 +73,7 @@ func init() {
|
||||||
session.FixedTimeRelease()
|
session.FixedTimeRelease()
|
||||||
session.FixedTimeReport()
|
session.FixedTimeReport()
|
||||||
|
|
||||||
logger.Debug("host ["+runtime.Version()+", "+runtime.GOOS+"_"+runtime.GOARCH+"], cross-compilation ", util.Go.GetCrossPlatforms())
|
logger.Debug("host ["+runtime.Version()+", "+runtime.GOOS+"_"+runtime.GOARCH+"], cross-compilation ", gulu.Go.GetCrossPlatforms())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main.
|
// Main.
|
||||||
|
@ -204,7 +203,7 @@ func indexHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
model := map[string]interface{}{"conf": conf.Wide, "i18n": i18n.GetAll(locale), "locale": locale,
|
model := map[string]interface{}{"conf": conf.Wide, "i18n": i18n.GetAll(locale), "locale": locale,
|
||||||
"uid": uid, "sid": session.WideSessions.GenId(), "latestSessionContent": user.LatestSessionContent,
|
"uid": uid, "sid": session.WideSessions.GenId(), "latestSessionContent": user.LatestSessionContent,
|
||||||
"pathSeparator": conf.PathSeparator, "codeMirrorVer": conf.CodeMirrorVer,
|
"pathSeparator": conf.PathSeparator, "codeMirrorVer": conf.CodeMirrorVer,
|
||||||
"user": user, "editorThemes": conf.GetEditorThemes(), "crossPlatforms": util.Go.GetCrossPlatforms()}
|
"user": user, "editorThemes": conf.GetEditorThemes(), "crossPlatforms": gulu.Go.GetCrossPlatforms()}
|
||||||
|
|
||||||
logger.Debugf("User [%s] has [%d] sessions", uid, len(wideSessions))
|
logger.Debugf("User [%s] has [%d] sessions", uid, len(wideSessions))
|
||||||
|
|
||||||
|
@ -409,7 +408,7 @@ func stopwatch(handler func(w http.ResponseWriter, r *http.Request)) func(w http
|
||||||
// panicRecover wraps the panic recover process.
|
// panicRecover wraps the panic recover process.
|
||||||
func panicRecover(handler func(w http.ResponseWriter, r *http.Request)) func(w http.ResponseWriter, r *http.Request) {
|
func panicRecover(handler func(w http.ResponseWriter, r *http.Request)) func(w http.ResponseWriter, r *http.Request) {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
defer util.Recover()
|
defer gulu.Panic.Recover()
|
||||||
|
|
||||||
handler(w, r)
|
handler(w, r)
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,10 +21,10 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/b3log/gulu"
|
||||||
"github.com/b3log/wide/conf"
|
"github.com/b3log/wide/conf"
|
||||||
"github.com/b3log/wide/event"
|
"github.com/b3log/wide/event"
|
||||||
"github.com/b3log/wide/i18n"
|
"github.com/b3log/wide/i18n"
|
||||||
"github.com/b3log/wide/log"
|
|
||||||
"github.com/b3log/wide/session"
|
"github.com/b3log/wide/session"
|
||||||
"github.com/b3log/wide/util"
|
"github.com/b3log/wide/util"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
|
@ -40,7 +40,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Logger.
|
// Logger.
|
||||||
var logger = log.NewLogger(os.Stdout)
|
var logger = gulu.Log.NewLogger(os.Stdout)
|
||||||
|
|
||||||
// Notification represents a notification.
|
// Notification represents a notification.
|
||||||
type Notification struct {
|
type Notification struct {
|
||||||
|
|
|
@ -18,6 +18,7 @@ import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/b3log/gulu"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
@ -30,13 +31,12 @@ import (
|
||||||
"github.com/b3log/wide/conf"
|
"github.com/b3log/wide/conf"
|
||||||
"github.com/b3log/wide/i18n"
|
"github.com/b3log/wide/i18n"
|
||||||
"github.com/b3log/wide/session"
|
"github.com/b3log/wide/session"
|
||||||
"github.com/b3log/wide/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// BuildHandler handles request of building.
|
// BuildHandler handles request of building.
|
||||||
func BuildHandler(w http.ResponseWriter, r *http.Request) {
|
func BuildHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
result := util.NewResult()
|
result := gulu.Ret.NewResult()
|
||||||
defer util.RetResult(w, r, result)
|
defer gulu.Ret.RetResult(w, r, result)
|
||||||
|
|
||||||
httpSession, _ := session.HTTPSession.Get(r, session.CookieName)
|
httpSession, _ := session.HTTPSession.Get(r, session.CookieName)
|
||||||
if httpSession.IsNew {
|
if httpSession.IsNew {
|
||||||
|
@ -58,7 +58,7 @@ func BuildHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
sid := args["sid"].(string)
|
sid := args["sid"].(string)
|
||||||
filePath := args["file"].(string)
|
filePath := args["file"].(string)
|
||||||
if util.Go.IsAPI(filePath) || !session.CanAccess(uid, filePath) {
|
if gulu.Go.IsAPI(filePath) || !session.CanAccess(uid, filePath) {
|
||||||
http.Error(w, "Forbidden", http.StatusForbidden)
|
http.Error(w, "Forbidden", http.StatusForbidden)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -98,7 +98,7 @@ func BuildHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var goModCmd *exec.Cmd
|
var goModCmd *exec.Cmd
|
||||||
if !util.File.IsExist(filepath.Join(curDir, "go.mod")) {
|
if !gulu.File.IsExist(filepath.Join(curDir, "go.mod")) {
|
||||||
curDirName := filepath.Base(curDir)
|
curDirName := filepath.Base(curDir)
|
||||||
goModCmd = exec.Command("go", "mod", "init", curDirName)
|
goModCmd = exec.Command("go", "mod", "init", curDirName)
|
||||||
} else {
|
} else {
|
||||||
|
@ -118,7 +118,7 @@ func BuildHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
var goBuildArgs []string
|
var goBuildArgs []string
|
||||||
goBuildArgs = append(goBuildArgs, "build")
|
goBuildArgs = append(goBuildArgs, "build")
|
||||||
goBuildArgs = append(goBuildArgs, user.BuildArgs(runtime.GOOS)...)
|
goBuildArgs = append(goBuildArgs, user.BuildArgs(runtime.GOOS)...)
|
||||||
if !util.Str.Contains("-i", goBuildArgs) {
|
if !gulu.Str.Contains("-i", goBuildArgs) {
|
||||||
goBuildArgs = append(goBuildArgs, "-i")
|
goBuildArgs = append(goBuildArgs, "-i")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ func BuildHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
setCmdEnv(cmd, uid)
|
setCmdEnv(cmd, uid)
|
||||||
|
|
||||||
suffix := ""
|
suffix := ""
|
||||||
if util.OS.IsWindows() {
|
if gulu.OS.IsWindows() {
|
||||||
suffix = ".exe"
|
suffix = ".exe"
|
||||||
}
|
}
|
||||||
executable := filepath.Base(curDir) + suffix
|
executable := filepath.Base(curDir) + suffix
|
||||||
|
@ -167,7 +167,7 @@ func BuildHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
/////////
|
/////////
|
||||||
go func() {
|
go func() {
|
||||||
defer util.Recover()
|
defer gulu.Panic.Recover()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
wsChannel := session.OutputWS[sid]
|
wsChannel := session.OutputWS[sid]
|
||||||
|
|
|
@ -26,16 +26,16 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/b3log/gulu"
|
||||||
"github.com/b3log/wide/conf"
|
"github.com/b3log/wide/conf"
|
||||||
"github.com/b3log/wide/i18n"
|
"github.com/b3log/wide/i18n"
|
||||||
"github.com/b3log/wide/session"
|
"github.com/b3log/wide/session"
|
||||||
"github.com/b3log/wide/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// CrossCompilationHandler handles request of cross compilation.
|
// CrossCompilationHandler handles request of cross compilation.
|
||||||
func CrossCompilationHandler(w http.ResponseWriter, r *http.Request) {
|
func CrossCompilationHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
result := util.NewResult()
|
result := gulu.Ret.NewResult()
|
||||||
defer util.RetResult(w, r, result)
|
defer gulu.Ret.RetResult(w, r, result)
|
||||||
|
|
||||||
httpSession, _ := session.HTTPSession.Get(r, session.CookieName)
|
httpSession, _ := session.HTTPSession.Get(r, session.CookieName)
|
||||||
if httpSession.IsNew {
|
if httpSession.IsNew {
|
||||||
|
@ -58,7 +58,7 @@ func CrossCompilationHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
sid := args["sid"].(string)
|
sid := args["sid"].(string)
|
||||||
filePath := args["path"].(string)
|
filePath := args["path"].(string)
|
||||||
|
|
||||||
if util.Go.IsAPI(filePath) || !session.CanAccess(uid, filePath) {
|
if gulu.Go.IsAPI(filePath) || !session.CanAccess(uid, filePath) {
|
||||||
http.Error(w, "Forbidden", http.StatusForbidden)
|
http.Error(w, "Forbidden", http.StatusForbidden)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -152,7 +152,7 @@ func CrossCompilationHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
go func(runningId int) {
|
go func(runningId int) {
|
||||||
defer util.Recover()
|
defer gulu.Panic.Recover()
|
||||||
defer cmd.Wait()
|
defer cmd.Wait()
|
||||||
|
|
||||||
// read all
|
// read all
|
||||||
|
|
|
@ -26,16 +26,16 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/b3log/gulu"
|
||||||
"github.com/b3log/wide/conf"
|
"github.com/b3log/wide/conf"
|
||||||
"github.com/b3log/wide/i18n"
|
"github.com/b3log/wide/i18n"
|
||||||
"github.com/b3log/wide/session"
|
"github.com/b3log/wide/session"
|
||||||
"github.com/b3log/wide/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// GoInstallHandler handles request of go install.
|
// GoInstallHandler handles request of go install.
|
||||||
func GoInstallHandler(w http.ResponseWriter, r *http.Request) {
|
func GoInstallHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
result := util.NewResult()
|
result := gulu.Ret.NewResult()
|
||||||
defer util.RetResult(w, r, result)
|
defer gulu.Ret.RetResult(w, r, result)
|
||||||
|
|
||||||
httpSession, _ := session.HTTPSession.Get(r, session.CookieName)
|
httpSession, _ := session.HTTPSession.Get(r, session.CookieName)
|
||||||
if httpSession.IsNew {
|
if httpSession.IsNew {
|
||||||
|
@ -116,7 +116,7 @@ func GoInstallHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
go func(runningId int) {
|
go func(runningId int) {
|
||||||
defer util.Recover()
|
defer gulu.Panic.Recover()
|
||||||
defer cmd.Wait()
|
defer cmd.Wait()
|
||||||
|
|
||||||
logger.Debugf("User [%s, %s] is running [go install] [id=%d, dir=%s]", uid, sid, runningId, curDir)
|
logger.Debugf("User [%s, %s] is running [go install] [id=%d, dir=%s]", uid, sid, runningId, curDir)
|
||||||
|
|
|
@ -25,8 +25,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/b3log/gulu"
|
||||||
"github.com/b3log/wide/conf"
|
"github.com/b3log/wide/conf"
|
||||||
"github.com/b3log/wide/log"
|
|
||||||
"github.com/b3log/wide/session"
|
"github.com/b3log/wide/session"
|
||||||
"github.com/b3log/wide/util"
|
"github.com/b3log/wide/util"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
|
@ -38,7 +38,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Logger.
|
// Logger.
|
||||||
var logger = log.NewLogger(os.Stdout)
|
var logger = gulu.Log.NewLogger(os.Stdout)
|
||||||
|
|
||||||
// Lint represents a code lint.
|
// Lint represents a code lint.
|
||||||
type Lint struct {
|
type Lint struct {
|
||||||
|
@ -122,7 +122,7 @@ func setCmdEnv(cmd *exec.Cmd, uid string) {
|
||||||
"GOCACHE="+cache,
|
"GOCACHE="+cache,
|
||||||
"PATH="+os.Getenv("PATH"))
|
"PATH="+os.Getenv("PATH"))
|
||||||
|
|
||||||
if util.OS.IsWindows() {
|
if gulu.OS.IsWindows() {
|
||||||
// FIXME: for some weird issues on Windows, such as: The requested service provider could not be loaded or initialized.
|
// FIXME: for some weird issues on Windows, such as: The requested service provider could not be loaded or initialized.
|
||||||
cmd.Env = append(cmd.Env, os.Environ()...)
|
cmd.Env = append(cmd.Env, os.Environ()...)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -24,16 +24,16 @@ import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/b3log/gulu"
|
||||||
"github.com/b3log/wide/conf"
|
"github.com/b3log/wide/conf"
|
||||||
"github.com/b3log/wide/i18n"
|
"github.com/b3log/wide/i18n"
|
||||||
"github.com/b3log/wide/session"
|
"github.com/b3log/wide/session"
|
||||||
"github.com/b3log/wide/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// GoTestHandler handles request of go test.
|
// GoTestHandler handles request of go test.
|
||||||
func GoTestHandler(w http.ResponseWriter, r *http.Request) {
|
func GoTestHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
result := util.NewResult()
|
result := gulu.Ret.NewResult()
|
||||||
defer util.RetResult(w, r, result)
|
defer gulu.Ret.RetResult(w, r, result)
|
||||||
|
|
||||||
httpSession, _ := session.HTTPSession.Get(r, session.CookieName)
|
httpSession, _ := session.HTTPSession.Get(r, session.CookieName)
|
||||||
if httpSession.IsNew {
|
if httpSession.IsNew {
|
||||||
|
@ -112,7 +112,7 @@ func GoTestHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
go func(runningId int) {
|
go func(runningId int) {
|
||||||
defer util.Recover()
|
defer gulu.Panic.Recover()
|
||||||
|
|
||||||
logger.Debugf("User [%s, %s] is running [go test] [runningId=%d]", uid, sid, runningId)
|
logger.Debugf("User [%s, %s] is running [go test] [runningId=%d]", uid, sid, runningId)
|
||||||
|
|
||||||
|
|
|
@ -24,16 +24,16 @@ import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/b3log/gulu"
|
||||||
"github.com/b3log/wide/conf"
|
"github.com/b3log/wide/conf"
|
||||||
"github.com/b3log/wide/i18n"
|
"github.com/b3log/wide/i18n"
|
||||||
"github.com/b3log/wide/session"
|
"github.com/b3log/wide/session"
|
||||||
"github.com/b3log/wide/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// GoVetHandler handles request of go vet.
|
// GoVetHandler handles request of go vet.
|
||||||
func GoVetHandler(w http.ResponseWriter, r *http.Request) {
|
func GoVetHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
result := util.NewResult()
|
result := gulu.Ret.NewResult()
|
||||||
defer util.RetResult(w, r, result)
|
defer gulu.Ret.RetResult(w, r, result)
|
||||||
|
|
||||||
httpSession, _ := session.HTTPSession.Get(r, session.CookieName)
|
httpSession, _ := session.HTTPSession.Get(r, session.CookieName)
|
||||||
if httpSession.IsNew {
|
if httpSession.IsNew {
|
||||||
|
@ -112,7 +112,7 @@ func GoVetHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
go func(runningId int) {
|
go func(runningId int) {
|
||||||
defer util.Recover()
|
defer gulu.Panic.Recover()
|
||||||
|
|
||||||
logger.Debugf("User [%s, %s] is running [go vet] [runningId=%d]", uid, sid, runningId)
|
logger.Debugf("User [%s, %s] is running [go vet] [runningId=%d]", uid, sid, runningId)
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,8 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/b3log/gulu"
|
||||||
"github.com/b3log/wide/session"
|
"github.com/b3log/wide/session"
|
||||||
"github.com/b3log/wide/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AutocompleteHandler handles request of code autocompletion.
|
// AutocompleteHandler handles request of code autocompletion.
|
||||||
|
@ -51,7 +51,7 @@ func AutocompleteHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
offset := getCursorOffset(code, line, ch)
|
offset := getCursorOffset(code, line, ch)
|
||||||
|
|
||||||
argv := []string{"-f=json", "autocomplete", strconv.Itoa(offset)}
|
argv := []string{"-f=json", "autocomplete", strconv.Itoa(offset)}
|
||||||
gocode := util.Go.GetExecutableInGOBIN("gocode")
|
gocode := gulu.Go.GetExecutableInGOBIN("gocode")
|
||||||
cmd := exec.Command(gocode, argv...)
|
cmd := exec.Command(gocode, argv...)
|
||||||
|
|
||||||
stdin, _ := cmd.StdinPipe()
|
stdin, _ := cmd.StdinPipe()
|
||||||
|
|
|
@ -22,15 +22,15 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/b3log/gulu"
|
||||||
"github.com/b3log/wide/conf"
|
"github.com/b3log/wide/conf"
|
||||||
"github.com/b3log/wide/session"
|
"github.com/b3log/wide/session"
|
||||||
"github.com/b3log/wide/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// BuildHandler handles request of Playground building.
|
// BuildHandler handles request of Playground building.
|
||||||
func BuildHandler(w http.ResponseWriter, r *http.Request) {
|
func BuildHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
result := util.NewResult()
|
result := gulu.Ret.NewResult()
|
||||||
defer util.RetResult(w, r, result)
|
defer gulu.Ret.RetResult(w, r, result)
|
||||||
|
|
||||||
httpSession, _ := session.HTTPSession.Get(r, session.CookieName)
|
httpSession, _ := session.HTTPSession.Get(r, session.CookieName)
|
||||||
if httpSession.IsNew {
|
if httpSession.IsNew {
|
||||||
|
@ -51,7 +51,7 @@ func BuildHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
filePath := filepath.Clean(conf.Wide.Data + "/playground/" + fileName)
|
filePath := filepath.Clean(conf.Wide.Data + "/playground/" + fileName)
|
||||||
|
|
||||||
suffix := ""
|
suffix := ""
|
||||||
if util.OS.IsWindows() {
|
if gulu.OS.IsWindows() {
|
||||||
suffix = ".exe"
|
suffix = ".exe"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,15 +24,15 @@ import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/b3log/gulu"
|
||||||
"github.com/b3log/wide/conf"
|
"github.com/b3log/wide/conf"
|
||||||
"github.com/b3log/wide/session"
|
"github.com/b3log/wide/session"
|
||||||
"github.com/b3log/wide/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// SaveHandler handles request of Playground code save.
|
// SaveHandler handles request of Playground code save.
|
||||||
func SaveHandler(w http.ResponseWriter, r *http.Request) {
|
func SaveHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
result := util.NewResult()
|
result := gulu.Ret.NewResult()
|
||||||
defer util.RetResult(w, r, result)
|
defer gulu.Ret.RetResult(w, r, result)
|
||||||
|
|
||||||
session, _ := session.HTTPSession.Get(r, session.CookieName)
|
session, _ := session.HTTPSession.Get(r, session.CookieName)
|
||||||
if session.IsNew {
|
if session.IsNew {
|
||||||
|
|
|
@ -26,16 +26,16 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/b3log/gulu"
|
||||||
"github.com/b3log/wide/conf"
|
"github.com/b3log/wide/conf"
|
||||||
"github.com/b3log/wide/i18n"
|
"github.com/b3log/wide/i18n"
|
||||||
"github.com/b3log/wide/log"
|
|
||||||
"github.com/b3log/wide/session"
|
"github.com/b3log/wide/session"
|
||||||
"github.com/b3log/wide/util"
|
"github.com/b3log/wide/util"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Logger.
|
// Logger.
|
||||||
var logger = log.NewLogger(os.Stdout)
|
var logger = gulu.Log.NewLogger(os.Stdout)
|
||||||
|
|
||||||
// IndexHandler handles request of Playground index.
|
// IndexHandler handles request of Playground index.
|
||||||
func IndexHandler(w http.ResponseWriter, r *http.Request) {
|
func IndexHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -59,7 +59,7 @@ func IndexHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
if strings.HasSuffix(r.URL.Path, ".go") {
|
if strings.HasSuffix(r.URL.Path, ".go") {
|
||||||
fileNameArg := r.URL.Path[len("/playground/"):]
|
fileNameArg := r.URL.Path[len("/playground/"):]
|
||||||
filePath := filepath.Clean(conf.Wide.Data+ "/playground/" + fileNameArg)
|
filePath := filepath.Clean(conf.Wide.Data + "/playground/" + fileNameArg)
|
||||||
|
|
||||||
bytes, err := ioutil.ReadFile(filePath)
|
bytes, err := ioutil.ReadFile(filePath)
|
||||||
if nil != err {
|
if nil != err {
|
||||||
|
|
|
@ -25,9 +25,9 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/b3log/gulu"
|
||||||
"github.com/b3log/wide/conf"
|
"github.com/b3log/wide/conf"
|
||||||
"github.com/b3log/wide/i18n"
|
"github.com/b3log/wide/i18n"
|
||||||
"github.com/b3log/wide/util"
|
|
||||||
"github.com/parnurzeal/gorequest"
|
"github.com/parnurzeal/gorequest"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ var states = map[string]string{}
|
||||||
|
|
||||||
// RedirectGitHubHandler redirects to GitHub auth page.
|
// RedirectGitHubHandler redirects to GitHub auth page.
|
||||||
func RedirectGitHubHandler(w http.ResponseWriter, r *http.Request) {
|
func RedirectGitHubHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
requestResult := util.NewResult()
|
requestResult := gulu.Ret.NewResult()
|
||||||
_, _, errs := gorequest.New().TLSClientConfig(&tls.Config{InsecureSkipVerify: true}).
|
_, _, errs := gorequest.New().TLSClientConfig(&tls.Config{InsecureSkipVerify: true}).
|
||||||
Get("https://hacpai.com/oauth/wide/client").
|
Get("https://hacpai.com/oauth/wide/client").
|
||||||
Set("user-agent", conf.UserAgent).Timeout(10 * time.Second).EndStruct(requestResult)
|
Set("user-agent", conf.UserAgent).Timeout(10 * time.Second).EndStruct(requestResult)
|
||||||
|
@ -57,7 +57,7 @@ func RedirectGitHubHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
state := r.URL.Query().Get("state")
|
state := r.URL.Query().Get("state")
|
||||||
referer := conf.Wide.Server + "__" + state
|
referer := conf.Wide.Server + "__" + state
|
||||||
state = util.Rand.String(16) + referer
|
state = gulu.Rand.String(16) + referer
|
||||||
states[state] = state
|
states[state] = state
|
||||||
path := loginAuthURL + "?client_id=" + clientId + "&state=" + state + "&scope=public_repo,read:user,user:follow"
|
path := loginAuthURL + "?client_id=" + clientId + "&state=" + state + "&scope=public_repo,read:user,user:follow"
|
||||||
http.Redirect(w, r, path, http.StatusSeeOther)
|
http.Redirect(w, r, path, http.StatusSeeOther)
|
||||||
|
@ -93,10 +93,10 @@ func GithubCallbackHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
if nil == user {
|
if nil == user {
|
||||||
msg := addUser(githubId, userName, avatar)
|
msg := addUser(githubId, userName, avatar)
|
||||||
if userCreated != msg {
|
if userCreated != msg {
|
||||||
result := util.NewResult()
|
result := gulu.Ret.NewResult()
|
||||||
result.Succ = false
|
result.Succ = false
|
||||||
result.Msg = msg
|
result.Msg = msg
|
||||||
util.RetResult(w, r, result)
|
gulu.Ret.RetResult(w, r, result)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -149,8 +149,8 @@ func LoginHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
// LogoutHandler handles request of user logout (exit).
|
// LogoutHandler handles request of user logout (exit).
|
||||||
func LogoutHandler(w http.ResponseWriter, r *http.Request) {
|
func LogoutHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
result := util.NewResult()
|
result := gulu.Ret.NewResult()
|
||||||
defer util.RetResult(w, r, result)
|
defer gulu.Ret.RetResult(w, r, result)
|
||||||
|
|
||||||
httpSession, _ := HTTPSession.Get(r, CookieName)
|
httpSession, _ := HTTPSession.Get(r, CookieName)
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@ package session
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/b3log/wide/conf"
|
|
||||||
"github.com/b3log/wide/util"
|
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
@ -28,6 +26,10 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/b3log/gulu"
|
||||||
|
"github.com/b3log/wide/conf"
|
||||||
|
"github.com/b3log/wide/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Type of process set.
|
// Type of process set.
|
||||||
|
@ -43,8 +45,8 @@ var procMutex sync.Mutex
|
||||||
|
|
||||||
// RunHandler handles request of executing a binary file.
|
// RunHandler handles request of executing a binary file.
|
||||||
func RunHandler(w http.ResponseWriter, r *http.Request, channel map[string]*util.WSChannel) {
|
func RunHandler(w http.ResponseWriter, r *http.Request, channel map[string]*util.WSChannel) {
|
||||||
result := util.NewResult()
|
result := gulu.Ret.NewResult()
|
||||||
defer util.RetResult(w, r, result)
|
defer gulu.Ret.RetResult(w, r, result)
|
||||||
|
|
||||||
var args map[string]interface{}
|
var args map[string]interface{}
|
||||||
|
|
||||||
|
@ -120,12 +122,12 @@ func RunHandler(w http.ResponseWriter, r *http.Request, channel map[string]*util
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer util.Recover()
|
defer gulu.Panic.Recover()
|
||||||
|
|
||||||
logger.Debugf("User [%s, %s] is running [id=%s, file=%s]", wSession.UserId, sid, rid, filePath)
|
logger.Debugf("User [%s, %s] is running [id=%s, file=%s]", wSession.UserId, sid, rid, filePath)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer util.Recover()
|
defer gulu.Panic.Recover()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
r, _, err := outReader.ReadRune()
|
r, _, err := outReader.ReadRune()
|
||||||
|
@ -196,8 +198,8 @@ func RunHandler(w http.ResponseWriter, r *http.Request, channel map[string]*util
|
||||||
|
|
||||||
// StopHandler handles request of stopping a running process.
|
// StopHandler handles request of stopping a running process.
|
||||||
func StopHandler(w http.ResponseWriter, r *http.Request) {
|
func StopHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
result := util.NewResult()
|
result := gulu.Ret.NewResult()
|
||||||
defer util.RetResult(w, r, result)
|
defer gulu.Ret.RetResult(w, r, result)
|
||||||
|
|
||||||
var args map[string]interface{}
|
var args map[string]interface{}
|
||||||
if err := json.NewDecoder(r.Body).Decode(&args); err != nil {
|
if err := json.NewDecoder(r.Body).Decode(&args); err != nil {
|
||||||
|
|
|
@ -35,9 +35,9 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/b3log/gulu"
|
||||||
"github.com/b3log/wide/conf"
|
"github.com/b3log/wide/conf"
|
||||||
"github.com/b3log/wide/event"
|
"github.com/b3log/wide/event"
|
||||||
"github.com/b3log/wide/log"
|
|
||||||
"github.com/b3log/wide/util"
|
"github.com/b3log/wide/util"
|
||||||
"github.com/fsnotify/fsnotify"
|
"github.com/fsnotify/fsnotify"
|
||||||
"github.com/gorilla/sessions"
|
"github.com/gorilla/sessions"
|
||||||
|
@ -46,13 +46,13 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
sessionStateActive = iota
|
sessionStateActive = iota
|
||||||
sessionStateClosed // (not used so far)
|
sessionStateClosed // (not used so far)
|
||||||
|
|
||||||
CookieName = "wide-sess"
|
CookieName = "wide-sess"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Logger.
|
// Logger.
|
||||||
var logger = log.NewLogger(os.Stdout)
|
var logger = gulu.Log.NewLogger(os.Stdout)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// SessionWS holds all session channels. <sid, *util.WSChannel>
|
// SessionWS holds all session channels. <sid, *util.WSChannel>
|
||||||
|
@ -105,7 +105,7 @@ var mutex sync.Mutex
|
||||||
// Invalid sessions: sessions that not used within 30 minutes, refers to WideSession.Updated field.
|
// Invalid sessions: sessions that not used within 30 minutes, refers to WideSession.Updated field.
|
||||||
func FixedTimeRelease() {
|
func FixedTimeRelease() {
|
||||||
go func() {
|
go func() {
|
||||||
defer util.Recover()
|
defer gulu.Panic.Recover()
|
||||||
|
|
||||||
for _ = range time.Tick(time.Hour) {
|
for _ = range time.Tick(time.Hour) {
|
||||||
hour, _ := time.ParseDuration("-30m")
|
hour, _ := time.ParseDuration("-30m")
|
||||||
|
@ -139,9 +139,9 @@ func (u *userReport) report() string {
|
||||||
// FixedTimeReport reports the Wide sessions status periodically (10 minutes).
|
// FixedTimeReport reports the Wide sessions status periodically (10 minutes).
|
||||||
func FixedTimeReport() {
|
func FixedTimeReport() {
|
||||||
go func() {
|
go func() {
|
||||||
defer util.Recover()
|
defer gulu.Panic.Recover()
|
||||||
|
|
||||||
for _ = range time.Tick(10*time.Minute) {
|
for _ = range time.Tick(10 * time.Minute) {
|
||||||
users := userReports{}
|
users := userReports{}
|
||||||
processSum := 0
|
processSum := 0
|
||||||
|
|
||||||
|
@ -284,8 +284,8 @@ func WSHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
// SaveContentHandler handles request of session content string.
|
// SaveContentHandler handles request of session content string.
|
||||||
func SaveContentHandler(w http.ResponseWriter, r *http.Request) {
|
func SaveContentHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
result := util.NewResult()
|
result := gulu.Ret.NewResult()
|
||||||
defer util.RetResult(w, r, result)
|
defer gulu.Ret.RetResult(w, r, result)
|
||||||
|
|
||||||
args := struct {
|
args := struct {
|
||||||
Sid string
|
Sid string
|
||||||
|
@ -477,7 +477,7 @@ func (sessions *wSessions) new(httpSession *sessions.Session, sid string) *WideS
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer util.Recover()
|
defer gulu.Panic.Recover()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
ch := SessionWS[sid]
|
ch := SessionWS[sid]
|
||||||
|
@ -500,7 +500,7 @@ func (sessions *wSessions) new(httpSession *sessions.Session, sid string) *WideS
|
||||||
if event.Op&fsnotify.Create == fsnotify.Create {
|
if event.Op&fsnotify.Create == fsnotify.Create {
|
||||||
fileType := "f"
|
fileType := "f"
|
||||||
|
|
||||||
if util.File.IsDir(path) {
|
if gulu.File.IsDir(path) {
|
||||||
fileType = "d"
|
fileType = "d"
|
||||||
|
|
||||||
if err = watcher.Add(path); nil != err {
|
if err = watcher.Add(path); nil != err {
|
||||||
|
@ -526,7 +526,7 @@ func (sessions *wSessions) new(httpSession *sessions.Session, sid string) *WideS
|
||||||
}()
|
}()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer util.Recover()
|
defer gulu.Panic.Recover()
|
||||||
|
|
||||||
workspaces := filepath.SplitList(conf.GetUserWorkspace(uid))
|
workspaces := filepath.SplitList(conf.GetUserWorkspace(uid))
|
||||||
for _, workspace := range workspaces {
|
for _, workspace := range workspaces {
|
||||||
|
|
|
@ -24,17 +24,17 @@ import (
|
||||||
"text/template"
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/b3log/gulu"
|
||||||
"github.com/b3log/wide/conf"
|
"github.com/b3log/wide/conf"
|
||||||
"github.com/b3log/wide/i18n"
|
"github.com/b3log/wide/i18n"
|
||||||
"github.com/b3log/wide/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// TODO: i18n
|
// TODO: i18n
|
||||||
|
|
||||||
userExists = "user exists"
|
userExists = "user exists"
|
||||||
userCreated = "user created"
|
userCreated = "user created"
|
||||||
userCreateError = "user create error"
|
userCreateError = "user create error"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Exclusive lock for adding user.
|
// Exclusive lock for adding user.
|
||||||
|
@ -67,7 +67,7 @@ func PreferenceHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
model := map[string]interface{}{"conf": conf.Wide, "i18n": i18n.GetAll(user.Locale), "user": user,
|
model := map[string]interface{}{"conf": conf.Wide, "i18n": i18n.GetAll(user.Locale), "user": user,
|
||||||
"ver": conf.WideVersion, "goos": runtime.GOOS, "goarch": runtime.GOARCH, "gover": runtime.Version(),
|
"ver": conf.WideVersion, "goos": runtime.GOOS, "goarch": runtime.GOARCH, "gover": runtime.Version(),
|
||||||
"locales": i18n.GetLocalesNames(), "gofmts": util.Go.GetGoFormats(),
|
"locales": i18n.GetLocalesNames(), "gofmts": gulu.Go.GetGoFormats(),
|
||||||
"themes": conf.GetThemes(), "editorThemes": conf.GetEditorThemes()}
|
"themes": conf.GetThemes(), "editorThemes": conf.GetEditorThemes()}
|
||||||
|
|
||||||
t, err := template.ParseFiles("views/preference.html")
|
t, err := template.ParseFiles("views/preference.html")
|
||||||
|
@ -93,8 +93,8 @@ func PreferenceHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
// non-GET request as save request
|
// non-GET request as save request
|
||||||
|
|
||||||
result := util.NewResult()
|
result := gulu.Ret.NewResult()
|
||||||
defer util.RetResult(w, r, result)
|
defer gulu.Ret.RetResult(w, r, result)
|
||||||
|
|
||||||
args := struct {
|
args := struct {
|
||||||
FontFamily string
|
FontFamily string
|
||||||
|
@ -154,7 +154,7 @@ func PreferenceHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
// Main goal of this function is to save user session content, for restoring session content while user open Wide next time.
|
// Main goal of this function is to save user session content, for restoring session content while user open Wide next time.
|
||||||
func FixedTimeSave() {
|
func FixedTimeSave() {
|
||||||
go func() {
|
go func() {
|
||||||
defer util.Recover()
|
defer gulu.Panic.Recover()
|
||||||
|
|
||||||
for _ = range time.Tick(time.Minute) {
|
for _ = range time.Tick(time.Minute) {
|
||||||
SaveOnlineUsers()
|
SaveOnlineUsers()
|
||||||
|
|
163
util/file.go
163
util/file.go
|
@ -1,163 +0,0 @@
|
||||||
// Copyright (c) 2014-present, b3log.org
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package util
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/b3log/wide/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Logger.
|
|
||||||
var fileLogger = log.NewLogger(os.Stdout)
|
|
||||||
|
|
||||||
type myfile struct{}
|
|
||||||
|
|
||||||
// File utilities.
|
|
||||||
var File = myfile{}
|
|
||||||
|
|
||||||
// GetFileSize get the length in bytes of file of the specified path.
|
|
||||||
func (*myfile) GetFileSize(path string) int64 {
|
|
||||||
fi, err := os.Stat(path)
|
|
||||||
if nil != err {
|
|
||||||
fileLogger.Error(err)
|
|
||||||
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
return fi.Size()
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsExist determines whether the file spcified by the given path is exists.
|
|
||||||
func (*myfile) IsExist(path string) bool {
|
|
||||||
_, err := os.Stat(path)
|
|
||||||
|
|
||||||
return err == nil || os.IsExist(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsBinary determines whether the specified content is a binary file content.
|
|
||||||
func (*myfile) IsBinary(content string) bool {
|
|
||||||
for _, b := range content {
|
|
||||||
if 0 == b {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsImg determines whether the specified extension is a image.
|
|
||||||
func (*myfile) IsImg(extension string) bool {
|
|
||||||
ext := strings.ToLower(extension)
|
|
||||||
|
|
||||||
switch ext {
|
|
||||||
case ".jpg", ".jpeg", ".bmp", ".gif", ".png", ".svg", ".ico":
|
|
||||||
return true
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsDir determines whether the specified path is a directory.
|
|
||||||
func (*myfile) IsDir(path string) bool {
|
|
||||||
fio, err := os.Lstat(path)
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if nil != err {
|
|
||||||
fileLogger.Warnf("Determines whether [%s] is a directory failed: [%v]", path, err)
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return fio.IsDir()
|
|
||||||
}
|
|
||||||
|
|
||||||
// CopyFile copies the source file to the dest file.
|
|
||||||
func (*myfile) CopyFile(source string, dest string) (err error) {
|
|
||||||
sourcefile, err := os.Open(source)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
defer sourcefile.Close()
|
|
||||||
|
|
||||||
destfile, err := os.Create(dest)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
defer destfile.Close()
|
|
||||||
|
|
||||||
_, err = io.Copy(destfile, sourcefile)
|
|
||||||
if err == nil {
|
|
||||||
sourceinfo, err := os.Stat(source)
|
|
||||||
if err != nil {
|
|
||||||
err = os.Chmod(dest, sourceinfo.Mode())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CopyDir copies the source directory to the dest directory.
|
|
||||||
func (*myfile) CopyDir(source string, dest string) (err error) {
|
|
||||||
sourceinfo, err := os.Stat(source)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// create dest dir
|
|
||||||
err = os.MkdirAll(dest, sourceinfo.Mode())
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
directory, err := os.Open(source)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
defer directory.Close()
|
|
||||||
|
|
||||||
objects, err := directory.Readdir(-1)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, obj := range objects {
|
|
||||||
srcFilePath := filepath.Join(source, obj.Name())
|
|
||||||
destFilePath := filepath.Join(dest, obj.Name())
|
|
||||||
|
|
||||||
if obj.IsDir() {
|
|
||||||
// create sub-directories - recursively
|
|
||||||
err = File.CopyDir(srcFilePath, destFilePath)
|
|
||||||
if err != nil {
|
|
||||||
fileLogger.Error(err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = File.CopyFile(srcFilePath, destFilePath)
|
|
||||||
if err != nil {
|
|
||||||
fileLogger.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,81 +0,0 @@
|
||||||
// Copyright (c) 2014-present, b3log.org
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package util
|
|
||||||
|
|
||||||
import (
|
|
||||||
"path/filepath"
|
|
||||||
"strconv"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestGetFileSize(t *testing.T) {
|
|
||||||
size := File.GetFileSize(".")
|
|
||||||
|
|
||||||
t.Log("size of file [.] is [" + strconv.FormatInt(size, 10) + "]")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIsExist(t *testing.T) {
|
|
||||||
if !File.IsExist(".") {
|
|
||||||
t.Error(". must exist")
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIdBinary(t *testing.T) {
|
|
||||||
if File.IsBinary("not binary content") {
|
|
||||||
t.Error("The content should not be binary")
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIsImg(t *testing.T) {
|
|
||||||
if !File.IsImg(".jpg") {
|
|
||||||
t.Error(".jpg should be a valid extension of a image file")
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIsDir(t *testing.T) {
|
|
||||||
if !File.IsDir(".") {
|
|
||||||
t.Error(". should be a directory")
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCopyDir(t *testing.T) {
|
|
||||||
dest := filepath.Join(testDir, "util")
|
|
||||||
|
|
||||||
err := File.CopyDir(".", dest)
|
|
||||||
if nil != err {
|
|
||||||
t.Error("Copy dir error: ", err)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCopyFile(t *testing.T) {
|
|
||||||
dest := filepath.Join(testDir, "file.go")
|
|
||||||
|
|
||||||
err := File.CopyFile("./file.go", dest)
|
|
||||||
if nil != err {
|
|
||||||
t.Error("Copy file error: ", err)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
118
util/go.go
118
util/go.go
|
@ -1,118 +0,0 @@
|
||||||
// Copyright (c) 2014-present, b3log.org
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package util
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
"runtime"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
pathSeparator = string(os.PathSeparator) // OS-specific path separator
|
|
||||||
pathListSeparator = string(os.PathListSeparator) // OS-specific path list separator
|
|
||||||
)
|
|
||||||
|
|
||||||
type mygo struct{}
|
|
||||||
|
|
||||||
// Go utilities.
|
|
||||||
var Go = mygo{}
|
|
||||||
|
|
||||||
func (*mygo) GetCrossPlatforms() []string {
|
|
||||||
return []string{
|
|
||||||
"darwin_amd64", "linux_amd64", "windows_amd64",
|
|
||||||
"linux_arm", "darwin_386", "linux_386", "windows_386"}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetAPIPath gets the Go source code path.
|
|
||||||
//
|
|
||||||
// 1. before Go 1.4: $GOROOT/src/pkg
|
|
||||||
// 2. Go 1.4 and after: $GOROOT/src
|
|
||||||
func (*mygo) GetAPIPath() string {
|
|
||||||
ret := runtime.GOROOT() + "/src/pkg" // before Go 1.4
|
|
||||||
if !File.IsExist(ret) {
|
|
||||||
ret = runtime.GOROOT() + "/src" // Go 1.4 and after
|
|
||||||
}
|
|
||||||
|
|
||||||
return filepath.FromSlash(path.Clean(ret))
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsAPI determines whether the specified path belongs to Go API.
|
|
||||||
func (*mygo) IsAPI(path string) bool {
|
|
||||||
apiPath := Go.GetAPIPath()
|
|
||||||
|
|
||||||
return strings.HasPrefix(filepath.FromSlash(path), apiPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetGoFormats gets Go format tools. It may return ["gofmt", "goimports"].
|
|
||||||
func (*mygo) GetGoFormats() []string {
|
|
||||||
ret := []string{"gofmt"}
|
|
||||||
|
|
||||||
p := Go.GetExecutableInGOBIN("goimports")
|
|
||||||
if File.IsExist(p) {
|
|
||||||
ret = append(ret, "goimports")
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Strings(ret)
|
|
||||||
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetExecutableInGOBIN gets executable file under GOBIN path.
|
|
||||||
//
|
|
||||||
// The specified executable should not with extension, this function will append .exe if on Windows.
|
|
||||||
func (*mygo) GetExecutableInGOBIN(executable string) string {
|
|
||||||
if OS.IsWindows() {
|
|
||||||
executable += ".exe"
|
|
||||||
}
|
|
||||||
|
|
||||||
gopaths := filepath.SplitList(os.Getenv("GOPATH"))
|
|
||||||
|
|
||||||
for _, gopath := range gopaths {
|
|
||||||
// $GOPATH/bin/$GOOS_$GOARCH/executable
|
|
||||||
ret := gopath + pathSeparator + "bin" + pathSeparator +
|
|
||||||
os.Getenv("GOOS") + "_" + os.Getenv("GOARCH") + pathSeparator + executable
|
|
||||||
if File.IsExist(ret) {
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
// $GOPATH/bin/{runtime.GOOS}_{runtime.GOARCH}/executable
|
|
||||||
ret = gopath + pathSeparator + "bin" + pathSeparator +
|
|
||||||
runtime.GOOS + "_" + runtime.GOARCH + pathSeparator + executable
|
|
||||||
if File.IsExist(ret) {
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
// $GOPATH/bin/executable
|
|
||||||
ret = gopath + pathSeparator + "bin" + pathSeparator + executable
|
|
||||||
if File.IsExist(ret) {
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// $GOBIN/executable
|
|
||||||
gobin := os.Getenv("GOBIN")
|
|
||||||
if "" != gobin {
|
|
||||||
ret := gobin + pathSeparator + executable
|
|
||||||
if File.IsExist(ret) {
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "./" + executable
|
|
||||||
}
|
|
101
util/go_test.go
101
util/go_test.go
|
@ -1,101 +0,0 @@
|
||||||
// Copyright (c) 2014-present, b3log.org
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package util
|
|
||||||
|
|
||||||
import (
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/hashicorp/go-version"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestGetCrossPlatforms(t *testing.T) {
|
|
||||||
crossPlatforms := Go.GetCrossPlatforms()
|
|
||||||
|
|
||||||
if len(crossPlatforms) < 1 {
|
|
||||||
t.Error("should have one platform at least")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetAPIPath(t *testing.T) {
|
|
||||||
apiPath := Go.GetAPIPath()
|
|
||||||
|
|
||||||
v := runtime.Version()[2:]
|
|
||||||
|
|
||||||
ver, err := version.NewVersion(v)
|
|
||||||
if nil != err {
|
|
||||||
t.Error(err)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
constraints, err := version.NewConstraint(">= 1.4")
|
|
||||||
if nil != err {
|
|
||||||
t.Error(err)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if constraints.Check(ver) {
|
|
||||||
if !strings.HasSuffix(apiPath, "src") {
|
|
||||||
t.Error("api path should end with \"src\"")
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if !strings.HasSuffix(apiPath, "pkg") {
|
|
||||||
t.Error("api path should end with \"pkg\"")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIsAPI(t *testing.T) {
|
|
||||||
apiPath := Go.GetAPIPath()
|
|
||||||
|
|
||||||
if !Go.IsAPI(apiPath) {
|
|
||||||
t.Error("api path root should belong to api path")
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
root := "/root"
|
|
||||||
|
|
||||||
if Go.IsAPI(root) {
|
|
||||||
t.Error("root should not belong to api path")
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetGoFormats(t *testing.T) {
|
|
||||||
formats := Go.GetGoFormats()
|
|
||||||
|
|
||||||
if len(formats) < 1 {
|
|
||||||
t.Error("should have one go format tool [gofmt] at least")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetExecutableInGOBIN(t *testing.T) {
|
|
||||||
bin := Go.GetExecutableInGOBIN("test")
|
|
||||||
|
|
||||||
if OS.IsWindows() {
|
|
||||||
if !strings.HasSuffix(bin, ".exe") {
|
|
||||||
t.Error("Executable binary should end with .exe")
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
45
util/net.go
45
util/net.go
|
@ -1,45 +0,0 @@
|
||||||
// Copyright (c) 2014-present, b3log.org
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Package util includes common utilities.
|
|
||||||
package util
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"net"
|
|
||||||
)
|
|
||||||
|
|
||||||
type mynet struct{}
|
|
||||||
|
|
||||||
// Network utilities.
|
|
||||||
var Net = mynet{}
|
|
||||||
|
|
||||||
// LocalIP gets the first NIC's IP address.
|
|
||||||
func (*mynet) LocalIP() (string, error) {
|
|
||||||
addrs, err := net.InterfaceAddrs()
|
|
||||||
|
|
||||||
if nil != err {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, address := range addrs {
|
|
||||||
if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
|
|
||||||
if nil != ipnet.IP.To4() {
|
|
||||||
return ipnet.IP.String(), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "", errors.New("can't get local IP")
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
// Copyright (c) 2014-present, b3log.org
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package util
|
|
||||||
|
|
||||||
import "testing"
|
|
||||||
|
|
||||||
func TestLocalIP(t *testing.T) {
|
|
||||||
ip, err := Net.LocalIP()
|
|
||||||
|
|
||||||
if nil != err {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Log(ip)
|
|
||||||
}
|
|
100
util/os.go
100
util/os.go
|
@ -1,100 +0,0 @@
|
||||||
// Copyright (c) 2014-present, b3log.org
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package util
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"errors"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"os/user"
|
|
||||||
"path/filepath"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
type myos struct{}
|
|
||||||
|
|
||||||
// OS utilities.
|
|
||||||
var OS = myos{}
|
|
||||||
|
|
||||||
// IsWindows determines whether current OS is Windows.
|
|
||||||
func (*myos) IsWindows() bool {
|
|
||||||
return "windows" == runtime.GOOS
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pwd gets the path of current working directory.
|
|
||||||
func (*myos) Pwd() string {
|
|
||||||
file, _ := exec.LookPath(os.Args[0])
|
|
||||||
pwd, _ := filepath.Abs(file)
|
|
||||||
|
|
||||||
return filepath.Dir(pwd)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Home returns the home directory for the executing user.
|
|
||||||
//
|
|
||||||
// This uses an OS-specific method for discovering the home directory.
|
|
||||||
// An error is returned if a home directory cannot be detected.
|
|
||||||
func (*myos) Home() (string, error) {
|
|
||||||
user, err := user.Current()
|
|
||||||
if nil == err {
|
|
||||||
return user.HomeDir, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// cross compile support
|
|
||||||
|
|
||||||
if OS.IsWindows() {
|
|
||||||
return homeWindows()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unix-like system, so just assume Unix
|
|
||||||
return homeUnix()
|
|
||||||
}
|
|
||||||
|
|
||||||
func homeUnix() (string, error) {
|
|
||||||
// First prefer the HOME environmental variable
|
|
||||||
if home := os.Getenv("HOME"); home != "" {
|
|
||||||
return home, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// If that fails, try the shell
|
|
||||||
var stdout bytes.Buffer
|
|
||||||
cmd := exec.Command("sh", "-c", "eval echo ~$USER")
|
|
||||||
cmd.Stdout = &stdout
|
|
||||||
if err := cmd.Run(); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
result := strings.TrimSpace(stdout.String())
|
|
||||||
if result == "" {
|
|
||||||
return "", errors.New("blank output when reading home directory")
|
|
||||||
}
|
|
||||||
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func homeWindows() (string, error) {
|
|
||||||
drive := os.Getenv("HOMEDRIVE")
|
|
||||||
path := os.Getenv("HOMEPATH")
|
|
||||||
home := drive + path
|
|
||||||
if drive == "" || path == "" {
|
|
||||||
home = os.Getenv("USERPROFILE")
|
|
||||||
}
|
|
||||||
if home == "" {
|
|
||||||
return "", errors.New("HOMEDRIVE, HOMEPATH, and USERPROFILE are blank")
|
|
||||||
}
|
|
||||||
|
|
||||||
return home, nil
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
// Copyright (c) 2014-present, b3log.org
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package util
|
|
||||||
|
|
||||||
import (
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestIsWiindows(t *testing.T) {
|
|
||||||
goos := runtime.GOOS
|
|
||||||
|
|
||||||
if "windows" == goos && !OS.IsWindows() {
|
|
||||||
t.Error("runtime.GOOS returns [windows]")
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPwd(t *testing.T) {
|
|
||||||
if "" == OS.Pwd() {
|
|
||||||
t.Error("Working directory should not be empty")
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHome(t *testing.T) {
|
|
||||||
home, err := OS.Home()
|
|
||||||
if nil != err {
|
|
||||||
t.Error("Can not get user home")
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Log(home)
|
|
||||||
}
|
|
104
util/panic.go
104
util/panic.go
|
@ -1,104 +0,0 @@
|
||||||
// Copyright (c) 2014-present, b3log.org
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package util
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
|
|
||||||
"github.com/b3log/wide/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Logger.
|
|
||||||
var logger = log.NewLogger(os.Stdout)
|
|
||||||
|
|
||||||
var (
|
|
||||||
dunno = []byte("???")
|
|
||||||
centerDot = []byte("·")
|
|
||||||
dot = []byte(".")
|
|
||||||
slash = []byte("/")
|
|
||||||
)
|
|
||||||
|
|
||||||
// Recover recovers a panic.
|
|
||||||
func Recover() {
|
|
||||||
if re := recover(); nil != re {
|
|
||||||
stack := stack()
|
|
||||||
logger.Errorf("PANIC RECOVERED: %v\n\t%s\n", re, stack)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// stack implements Stack, skipping 2 frames.
|
|
||||||
func stack() []byte {
|
|
||||||
buf := &bytes.Buffer{} // the returned data
|
|
||||||
// As we loop, we open files and read them. These variables record the currently
|
|
||||||
// loaded file.
|
|
||||||
var lines [][]byte
|
|
||||||
var lastFile string
|
|
||||||
for i := 2; ; i++ { // Caller we care about is the user, 2 frames up
|
|
||||||
pc, file, line, ok := runtime.Caller(i)
|
|
||||||
if !ok {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
// Print this much at least. If we can't find the source, it won't show.
|
|
||||||
fmt.Fprintf(buf, "%s:%d (0x%x)\n", file, line, pc)
|
|
||||||
if file != lastFile {
|
|
||||||
data, err := ioutil.ReadFile(file)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
lines = bytes.Split(data, []byte{'\n'})
|
|
||||||
lastFile = file
|
|
||||||
}
|
|
||||||
line-- // in stack trace, lines are 1-indexed but our array is 0-indexed
|
|
||||||
fmt.Fprintf(buf, "\t%s: %s\n", function(pc), source(lines, line))
|
|
||||||
}
|
|
||||||
return buf.Bytes()
|
|
||||||
}
|
|
||||||
|
|
||||||
// source returns a space-trimmed slice of the n'th line.
|
|
||||||
func source(lines [][]byte, n int) []byte {
|
|
||||||
if n < 0 || n >= len(lines) {
|
|
||||||
return dunno
|
|
||||||
}
|
|
||||||
return bytes.Trim(lines[n], " \t")
|
|
||||||
}
|
|
||||||
|
|
||||||
// function returns, if possible, the name of the function containing the PC.
|
|
||||||
func function(pc uintptr) []byte {
|
|
||||||
fn := runtime.FuncForPC(pc)
|
|
||||||
if fn == nil {
|
|
||||||
return dunno
|
|
||||||
}
|
|
||||||
name := []byte(fn.Name())
|
|
||||||
// The name includes the path name to the package, which is unnecessary
|
|
||||||
// since the file name is already included. Plus, it has center dots.
|
|
||||||
// That is, we see
|
|
||||||
// runtime/debug.*T·ptrmethod
|
|
||||||
// and want
|
|
||||||
// *T.ptrmethod
|
|
||||||
// Since the package path might contains dots (e.g. code.google.com/...),
|
|
||||||
// we first remove the path prefix if there is one.
|
|
||||||
if lastslash := bytes.LastIndex(name, slash); lastslash >= 0 {
|
|
||||||
name = name[lastslash+1:]
|
|
||||||
}
|
|
||||||
if period := bytes.Index(name, dot); period >= 0 {
|
|
||||||
name = name[period+1:]
|
|
||||||
}
|
|
||||||
name = bytes.Replace(name, centerDot, dot, -1)
|
|
||||||
return name
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
// Copyright (c) 2014-present, b3log.org
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package util
|
|
||||||
|
|
||||||
import "testing"
|
|
||||||
|
|
||||||
func TestRecover(t *testing.T) {
|
|
||||||
defer Recover()
|
|
||||||
|
|
||||||
panic("test panic")
|
|
||||||
}
|
|
47
util/rand.go
47
util/rand.go
|
@ -1,47 +0,0 @@
|
||||||
// Copyright (c) 2014-present, b3log.org
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package util
|
|
||||||
|
|
||||||
import (
|
|
||||||
"math/rand"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type myrand struct{}
|
|
||||||
|
|
||||||
// Random utilities.
|
|
||||||
var Rand = myrand{}
|
|
||||||
|
|
||||||
// String returns a random string ['a', 'z'] in the specified length
|
|
||||||
func (*myrand) String(length int) string {
|
|
||||||
bytes := make([]byte, length)
|
|
||||||
|
|
||||||
for i := 0; i < length; i++ {
|
|
||||||
bytes[i] = byte(Rand.Int('a', 'z'))
|
|
||||||
|
|
||||||
time.Sleep(100 * time.Nanosecond)
|
|
||||||
}
|
|
||||||
|
|
||||||
return string(bytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int returns a random integer in range [min, max].
|
|
||||||
func (*myrand) Int(min int, max int) int {
|
|
||||||
rand.Seed(time.Now().UnixNano())
|
|
||||||
|
|
||||||
time.Sleep(100 * time.Nanosecond)
|
|
||||||
|
|
||||||
return min + rand.Intn(max-min)
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
// Copyright (c) 2014-present, b3log.org
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package util
|
|
||||||
|
|
||||||
import "testing"
|
|
||||||
|
|
||||||
func TestString(t *testing.T) {
|
|
||||||
r1 := Rand.String(16)
|
|
||||||
r2 := Rand.String(16)
|
|
||||||
|
|
||||||
if r1 == r2 {
|
|
||||||
t.Fail()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestInt(t *testing.T) {
|
|
||||||
r1 := Rand.Int(0, 65535)
|
|
||||||
r2 := Rand.Int(0, 65535)
|
|
||||||
|
|
||||||
if r1 == r2 {
|
|
||||||
t.Fail()
|
|
||||||
}
|
|
||||||
}
|
|
115
util/ret.go
115
util/ret.go
|
@ -1,115 +0,0 @@
|
||||||
// Copyright (c) 2014-present, b3log.org
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package util
|
|
||||||
|
|
||||||
import (
|
|
||||||
"compress/gzip"
|
|
||||||
"encoding/json"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/b3log/wide/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Logger.
|
|
||||||
var retLogger = log.NewLogger(os.Stdout)
|
|
||||||
|
|
||||||
// Result.
|
|
||||||
type Result struct {
|
|
||||||
Succ bool `json:"succ"` // successful or not
|
|
||||||
Code int `json:"code"` // return code
|
|
||||||
Msg string `json:"msg"` // message
|
|
||||||
Data interface{} `json:"data"` // data object
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewResult creates a result with Succ=true, Code=0, Msg="", Data=nil.
|
|
||||||
func NewResult() *Result {
|
|
||||||
return &Result{
|
|
||||||
Succ: true,
|
|
||||||
Code: 0,
|
|
||||||
Msg: "",
|
|
||||||
Data: nil,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// RetResult writes HTTP response with "Content-Type, application/json".
|
|
||||||
func RetResult(w http.ResponseWriter, r *http.Request, res *Result) {
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
|
||||||
|
|
||||||
data, err := json.Marshal(res)
|
|
||||||
if err != nil {
|
|
||||||
retLogger.Error(err)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
w.Write(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// RetGzResult writes HTTP response with "Content-Type, application/json" and "Content-Encoding, gzip".
|
|
||||||
func RetGzResult(w http.ResponseWriter, r *http.Request, res *Result) {
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
|
||||||
w.Header().Set("Content-Encoding", "gzip")
|
|
||||||
|
|
||||||
gz := gzip.NewWriter(w)
|
|
||||||
err := json.NewEncoder(gz).Encode(res)
|
|
||||||
if nil != err {
|
|
||||||
retLogger.Error(err)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = gz.Close()
|
|
||||||
if nil != err {
|
|
||||||
retLogger.Error(err)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// RetJSON writes HTTP response with "Content-Type, application/json".
|
|
||||||
func RetJSON(w http.ResponseWriter, r *http.Request, res map[string]interface{}) {
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
|
||||||
|
|
||||||
data, err := json.Marshal(res)
|
|
||||||
if err != nil {
|
|
||||||
retLogger.Error(err)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
w.Write(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// RetGzJSON writes HTTP response with "Content-Type, application/json" and "Content-Encoding, gzip".
|
|
||||||
func RetGzJSON(w http.ResponseWriter, r *http.Request, res map[string]interface{}) {
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
|
||||||
w.Header().Set("Content-Encoding", "gzip")
|
|
||||||
|
|
||||||
gz := gzip.NewWriter(w)
|
|
||||||
err := json.NewEncoder(gz).Encode(res)
|
|
||||||
if nil != err {
|
|
||||||
retLogger.Error(err)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = gz.Close()
|
|
||||||
if nil != err {
|
|
||||||
retLogger.Error(err)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,61 +0,0 @@
|
||||||
// Copyright (c) 2014-present, b3log.org
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package util
|
|
||||||
|
|
||||||
type str struct{}
|
|
||||||
|
|
||||||
// String utilities.
|
|
||||||
var Str = str{}
|
|
||||||
|
|
||||||
// Contains determines whether the str is in the strs.
|
|
||||||
func (*str) Contains(str string, strs []string) bool {
|
|
||||||
for _, v := range strs {
|
|
||||||
if v == str {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// LCS gets the longest common substring of s1 and s2.
|
|
||||||
//
|
|
||||||
// Refers to http://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Longest_common_substring.
|
|
||||||
func (*str) LCS(s1 string, s2 string) string {
|
|
||||||
var m = make([][]int, 1+len(s1))
|
|
||||||
|
|
||||||
for i := 0; i < len(m); i++ {
|
|
||||||
m[i] = make([]int, 1+len(s2))
|
|
||||||
}
|
|
||||||
|
|
||||||
longest := 0
|
|
||||||
xLongest := 0
|
|
||||||
|
|
||||||
for x := 1; x < 1+len(s1); x++ {
|
|
||||||
for y := 1; y < 1+len(s2); y++ {
|
|
||||||
if s1[x-1] == s2[y-1] {
|
|
||||||
m[x][y] = m[x-1][y-1] + 1
|
|
||||||
if m[x][y] > longest {
|
|
||||||
longest = m[x][y]
|
|
||||||
xLongest = x
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m[x][y] = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return s1[xLongest-longest : xLongest]
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
// Copyright (c) 2014-present, b3log.org
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package util
|
|
||||||
|
|
||||||
import "testing"
|
|
||||||
|
|
||||||
func TestContains(t *testing.T) {
|
|
||||||
if !Str.Contains("123", []string{"123", "345"}) {
|
|
||||||
t.Error("[\"123\", \"345\"] should contain \"123\"")
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLCS(t *testing.T) {
|
|
||||||
str := Str.LCS("123456", "abc34def")
|
|
||||||
|
|
||||||
if "34" != str {
|
|
||||||
t.Error("[\"123456\"] and [\"abc34def\"] should have the longest common substring [\"34\"]")
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
230
util/zip.go
230
util/zip.go
|
@ -1,230 +0,0 @@
|
||||||
// Copyright (c) 2014-present, b3log.org
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package util
|
|
||||||
|
|
||||||
import (
|
|
||||||
"archive/zip"
|
|
||||||
"bytes"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"unicode/utf8"
|
|
||||||
|
|
||||||
"golang.org/x/text/encoding/simplifiedchinese"
|
|
||||||
"golang.org/x/text/transform"
|
|
||||||
)
|
|
||||||
|
|
||||||
type myzip struct{}
|
|
||||||
|
|
||||||
// Zip utilities.
|
|
||||||
var Zip = myzip{}
|
|
||||||
|
|
||||||
// ZipFile represents a zip file.
|
|
||||||
type ZipFile struct {
|
|
||||||
zipFile *os.File
|
|
||||||
writer *zip.Writer
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create creates a zip file with the specified filename.
|
|
||||||
func (*myzip) Create(filename string) (*ZipFile, error) {
|
|
||||||
file, err := os.Create(filename)
|
|
||||||
if nil != err {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &ZipFile{zipFile: file, writer: zip.NewWriter(file)}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close closes the zip file writer.
|
|
||||||
func (z *ZipFile) Close() error {
|
|
||||||
err := z.writer.Close()
|
|
||||||
if nil != err {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return z.zipFile.Close() // close the underlying writer
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddEntryN adds entries.
|
|
||||||
func (z *ZipFile) AddEntryN(path string, names ...string) error {
|
|
||||||
for _, name := range names {
|
|
||||||
zipPath := filepath.Join(path, name)
|
|
||||||
err := z.AddEntry(zipPath, name)
|
|
||||||
if nil != err {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddEntry adds a entry.
|
|
||||||
func (z *ZipFile) AddEntry(path, name string) error {
|
|
||||||
fi, err := os.Stat(name)
|
|
||||||
if nil != err {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
fh, err := zip.FileInfoHeader(fi)
|
|
||||||
if nil != err {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
fh.Name = filepath.ToSlash(filepath.Clean(path))
|
|
||||||
fh.Method = zip.Deflate // data compression algorithm
|
|
||||||
|
|
||||||
if fi.IsDir() {
|
|
||||||
fh.Name = fh.Name + "/" // be care the ending separator
|
|
||||||
}
|
|
||||||
|
|
||||||
entry, err := z.writer.CreateHeader(fh)
|
|
||||||
if nil != err {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if fi.IsDir() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
file, err := os.Open(name)
|
|
||||||
if nil != err {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
_, err = io.Copy(entry, file)
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddDirectoryN adds directories.
|
|
||||||
func (z *ZipFile) AddDirectoryN(path string, names ...string) error {
|
|
||||||
for _, name := range names {
|
|
||||||
err := z.AddDirectory(path, name)
|
|
||||||
if nil != err {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddDirectory adds a directory.
|
|
||||||
func (z *ZipFile) AddDirectory(path, dirName string) error {
|
|
||||||
files, err := ioutil.ReadDir(dirName)
|
|
||||||
if nil != err {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if 0 == len(files) {
|
|
||||||
err := z.AddEntry(path, dirName)
|
|
||||||
if nil != err {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, file := range files {
|
|
||||||
localPath := filepath.Join(dirName, file.Name())
|
|
||||||
zipPath := filepath.Join(path, file.Name())
|
|
||||||
|
|
||||||
err = nil
|
|
||||||
if file.IsDir() {
|
|
||||||
err = z.AddDirectory(zipPath, localPath)
|
|
||||||
} else {
|
|
||||||
err = z.AddEntry(zipPath, localPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
if nil != err {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func cloneZipItem(f *zip.File, dest string) error {
|
|
||||||
// create full directory path
|
|
||||||
fileName := f.Name
|
|
||||||
|
|
||||||
if !utf8.ValidString(fileName) {
|
|
||||||
data, err := ioutil.ReadAll(transform.NewReader(bytes.NewReader([]byte(fileName)), simplifiedchinese.GB18030.NewDecoder()))
|
|
||||||
if nil == err {
|
|
||||||
fileName = string(data)
|
|
||||||
} else {
|
|
||||||
logger.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
path := filepath.Join(dest, fileName)
|
|
||||||
|
|
||||||
err := os.MkdirAll(filepath.Dir(path), os.ModeDir|os.ModePerm)
|
|
||||||
if nil != err {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if f.FileInfo().IsDir() {
|
|
||||||
err = os.Mkdir(path, os.ModeDir|os.ModePerm)
|
|
||||||
if nil != err {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// clone if item is a file
|
|
||||||
|
|
||||||
rc, err := f.Open()
|
|
||||||
if nil != err {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
defer rc.Close()
|
|
||||||
|
|
||||||
// use os.Create() since Zip don't store file permissions
|
|
||||||
fileCopy, err := os.Create(path)
|
|
||||||
if nil != err {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
defer fileCopy.Close()
|
|
||||||
|
|
||||||
_, err = io.Copy(fileCopy, rc)
|
|
||||||
if nil != err {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unzip extracts a zip file specified by the zipFilePath to the destination.
|
|
||||||
func (*myzip) Unzip(zipFilePath, destination string) error {
|
|
||||||
r, err := zip.OpenReader(zipFilePath)
|
|
||||||
|
|
||||||
if nil != err {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
defer r.Close()
|
|
||||||
|
|
||||||
for _, f := range r.File {
|
|
||||||
err = cloneZipItem(f, destination)
|
|
||||||
if nil != err {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
149
util/zip_test.go
149
util/zip_test.go
|
@ -1,149 +0,0 @@
|
||||||
// Copyright (c) 2014-present, b3log.org
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package util
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
var testDir = "../tmp"
|
|
||||||
var packageName = filepath.Join(testDir, "test_zip")
|
|
||||||
|
|
||||||
func TestCreate(t *testing.T) {
|
|
||||||
zipFile, err := Zip.Create(packageName + ".zip")
|
|
||||||
if nil != err {
|
|
||||||
t.Error(err)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
zipFile.AddDirectoryN(".", ".")
|
|
||||||
if nil != err {
|
|
||||||
t.Error(err)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = zipFile.Close()
|
|
||||||
if nil != err {
|
|
||||||
t.Error(err)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUnzip(t *testing.T) {
|
|
||||||
err := Zip.Unzip(packageName+".zip", packageName)
|
|
||||||
if nil != err {
|
|
||||||
t.Error(err)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func _TestEmptyDir(t *testing.T) {
|
|
||||||
dir1 := "/dir/subDir1"
|
|
||||||
dir2 := "/dir/subDir2"
|
|
||||||
|
|
||||||
err := os.MkdirAll(packageName+dir1, os.ModeDir)
|
|
||||||
if nil != err {
|
|
||||||
t.Error(err)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = os.MkdirAll(packageName+dir2, os.ModeDir)
|
|
||||||
if nil != err {
|
|
||||||
t.Error(err)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
f, err := os.Create(packageName + dir2 + "/file")
|
|
||||||
if nil != err {
|
|
||||||
t.Error(err)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
f.Close()
|
|
||||||
|
|
||||||
zipFile, err := Zip.Create(packageName + "/dir.zip")
|
|
||||||
if nil != err {
|
|
||||||
t.Error(err)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
zipFile.AddDirectoryN("dir", packageName+"/dir")
|
|
||||||
if nil != err {
|
|
||||||
t.Error(err)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = zipFile.Close()
|
|
||||||
if nil != err {
|
|
||||||
t.Error(err)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = Zip.Unzip(packageName+"/dir.zip", packageName+"/unzipDir")
|
|
||||||
if nil != err {
|
|
||||||
t.Error(err)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if !File.IsExist(packageName+"/unzipDir") || !File.IsDir(packageName+"/unzipDir") {
|
|
||||||
t.Error("Unzip failed")
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if !File.IsExist(packageName+"/unzipDir"+dir1) || !File.IsDir(packageName+"/unzipDir"+dir1) {
|
|
||||||
t.Error("Unzip failed")
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if !File.IsExist(packageName+"/unzipDir"+dir2) || !File.IsDir(packageName+"/unzipDir"+dir2) {
|
|
||||||
t.Error("Unzip failed")
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if !File.IsExist(packageName+"/unzipDir"+dir2+"/file") || File.IsDir(packageName+"/unzipDir"+dir2+"/file") {
|
|
||||||
t.Error("Unzip failed")
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
|
||||||
logger.Info(testDir)
|
|
||||||
|
|
||||||
retCode := m.Run()
|
|
||||||
|
|
||||||
// clean test data
|
|
||||||
os.RemoveAll(testDir + "/test_zip")
|
|
||||||
os.RemoveAll(testDir + "/util")
|
|
||||||
os.RemoveAll(testDir + "/file.go")
|
|
||||||
os.RemoveAll(testDir + "/test_zip.zip")
|
|
||||||
|
|
||||||
os.Exit(retCode)
|
|
||||||
}
|
|
Loading…
Reference in New Issue