♻️ 引入 Gulu 工具库

This commit is contained in:
Liang Ding 2019-05-24 21:04:25 +08:00
parent 1405d7482a
commit 4930408b17
No known key found for this signature in database
GPG Key ID: 136F30F901A2231D
45 changed files with 185 additions and 2045 deletions

View File

@ -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");
// you may not use this file except in compliance with the License.
@ -27,9 +27,8 @@ import (
"strings"
"time"
"github.com/b3log/gulu"
"github.com/b3log/wide/event"
"github.com/b3log/wide/log"
"github.com/b3log/wide/util"
)
const (
@ -69,7 +68,7 @@ type conf struct {
}
// Logger.
var logger = log.NewLogger(os.Stdout)
var logger = gulu.Log.NewLogger(os.Stdout)
// Wide configurations.
var Wide *conf
@ -91,7 +90,7 @@ func Load(confPath, confData, confServer, confLogLevel string, confSiteStatCode
cmd := exec.Command("docker", "version")
_, err := cmd.CombinedOutput()
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")
os.Exit(-1)
@ -179,16 +178,16 @@ func initWide(confPath, confData, confServer, confLogLevel string, confSiteStatC
Wide.Autocomplete = true // default to true
// Logging Level
log.SetLevel(Wide.LogLevel)
gulu.Log.SetLevel(Wide.LogLevel)
if "" != confLogLevel {
Wide.LogLevel = confLogLevel
log.SetLevel(confLogLevel)
gulu.Log.SetLevel(confLogLevel)
}
logger.Debug("Conf: \n" + string(bytes))
// User Home
home, err := util.OS.Home()
home, err := gulu.OS.Home()
if nil != 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
go func() {
for _ = range time.Tick(time.Minute * 7) {
for _ = range time.Tick(time.Minute*7) {
checkEnv()
}
}()
}
func checkEnv() {
defer util.Recover()
defer gulu.Panic.Recover()
cmd := exec.Command("go", "version")
buf, err := cmd.CombinedOutput()
@ -265,7 +264,7 @@ func checkEnv() {
os.Exit(-1)
}
gocode := util.Go.GetExecutableInGOBIN("gocode")
gocode := gulu.Go.GetExecutableInGOBIN("gocode")
cmd = exec.Command(gocode)
_, err = cmd.Output()
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)
}
ideStub := util.Go.GetExecutableInGOBIN("gotools")
ideStub := gulu.Go.GetExecutableInGOBIN("gotools")
cmd = exec.Command(ideStub, "version")
_, err = cmd.Output()
if nil != err {
@ -303,7 +302,7 @@ func GetGoFmt(userId string) string {
case "gofmt":
return "gofmt"
case "goimports":
return util.Go.GetExecutableInGOBIN("goimports")
return gulu.Go.GetExecutableInGOBIN("goimports")
default:
logger.Errorf("Unsupported Go Format tool [%s]", user.GoFormat)
return "gofmt"
@ -413,7 +412,7 @@ func CreateWorkspaceDir(path string) {
// createDir creates a directory on the path if it not exists.
func createDir(path string) {
if !util.File.IsExist(path) {
if !gulu.File.IsExist(path) {
if err := os.MkdirAll(path, 0775); nil != err {
logger.Error(err)

View File

@ -27,16 +27,16 @@ import (
"strings"
"time"
"github.com/b3log/gulu"
"github.com/b3log/wide/conf"
"github.com/b3log/wide/file"
"github.com/b3log/wide/log"
"github.com/b3log/wide/session"
"github.com/b3log/wide/util"
"github.com/gorilla/websocket"
)
// Logger.
var logger = log.NewLogger(os.Stdout)
var logger = gulu.Log.NewLogger(os.Stdout)
// WSHandler handles request of creating editor channel.
// XXX: NOT used at present
@ -77,7 +77,7 @@ func WSHandler(w http.ResponseWriter, r *http.Request) {
logger.Tracef("offset: %d", offset)
gocode := util.Go.GetExecutableInGOBIN("gocode")
gocode := gulu.Go.GetExecutableInGOBIN("gocode")
argv := []string{"-f=json", "autocomplete", strconv.Itoa(offset)}
var output bytes.Buffer
@ -159,7 +159,7 @@ func AutocompleteHandler(w http.ResponseWriter, r *http.Request) {
logger.Tracef("gocode set lib-path [%s]", libPath)
// 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()
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.
func GetExprInfoHandler(w http.ResponseWriter, r *http.Request) {
result := util.NewResult()
defer util.RetResult(w, r, result)
result := gulu.Ret.NewResult()
defer gulu.Ret.RetResult(w, r, result)
session, _ := session.HTTPSession.Get(r, session.CookieName)
uid := session.Values["uid"].(string)
@ -223,7 +223,7 @@ func GetExprInfoHandler(w http.ResponseWriter, r *http.Request) {
logger.Tracef("offset [%d]", offset)
ideStub := util.Go.GetExecutableInGOBIN("gotools")
ideStub := gulu.Go.GetExecutableInGOBIN("gotools")
argv := []string{"types", "-pos", filename + ":" + strconv.Itoa(offset), "-info", "."}
cmd := exec.Command(ideStub, argv...)
cmd.Dir = curDir
@ -250,8 +250,8 @@ func GetExprInfoHandler(w http.ResponseWriter, r *http.Request) {
// FindDeclarationHandler handles request of finding declaration.
func FindDeclarationHandler(w http.ResponseWriter, r *http.Request) {
result := util.NewResult()
defer util.RetResult(w, r, result)
result := gulu.Ret.NewResult()
defer gulu.Ret.RetResult(w, r, result)
session, _ := session.HTTPSession.Get(r, session.CookieName)
if session.IsNew {
@ -299,7 +299,7 @@ func FindDeclarationHandler(w http.ResponseWriter, r *http.Request) {
logger.Tracef("offset [%d]", offset)
ideStub := util.Go.GetExecutableInGOBIN("gotools")
ideStub := gulu.Go.GetExecutableInGOBIN("gotools")
argv := []string{"types", "-pos", filename + ":" + strconv.Itoa(offset), "-def", "."}
cmd := exec.Command(ideStub, argv...)
cmd.Dir = curDir
@ -338,8 +338,8 @@ func FindDeclarationHandler(w http.ResponseWriter, r *http.Request) {
// FindUsagesHandler handles request of finding usages.
func FindUsagesHandler(w http.ResponseWriter, r *http.Request) {
result := util.NewResult()
defer util.RetResult(w, r, result)
result := gulu.Ret.NewResult()
defer gulu.Ret.RetResult(w, r, result)
session, _ := session.HTTPSession.Get(r, session.CookieName)
if session.IsNew {
@ -387,7 +387,7 @@ func FindUsagesHandler(w http.ResponseWriter, r *http.Request) {
offset := getCursorOffset(code, line, ch)
logger.Tracef("offset [%d]", offset)
ideStub := util.Go.GetExecutableInGOBIN("gotools")
ideStub := gulu.Go.GetExecutableInGOBIN("gotools")
argv := []string{"types", "-pos", filename + ":" + strconv.Itoa(offset), "-use", "."}
cmd := exec.Command(ideStub, argv...)
cmd.Dir = curDir

View File

@ -20,9 +20,9 @@ import (
"os"
"os/exec"
"github.com/b3log/gulu"
"github.com/b3log/wide/conf"
"github.com/b3log/wide/session"
"github.com/b3log/wide/util"
)
// GoFmtHandler handles request of formatting Go source code.
@ -31,8 +31,8 @@ import (
// 1. gofmt
// 2. goimports
func GoFmtHandler(w http.ResponseWriter, r *http.Request) {
result := util.NewResult()
defer util.RetResult(w, r, result)
result := gulu.Ret.NewResult()
defer gulu.Ret.RetResult(w, r, result)
session, _ := session.HTTPSession.Get(r, session.CookieName)
if session.IsNew {
@ -53,7 +53,7 @@ func GoFmtHandler(w http.ResponseWriter, r *http.Request) {
filePath := args["file"].(string)
if util.Go.IsAPI(filePath) {
if gulu.Go.IsAPI(filePath) {
result.Succ = false
return

View File

@ -18,8 +18,7 @@ package event
import (
"os"
"github.com/b3log/wide/log"
"github.com/b3log/wide/util"
"github.com/b3log/gulu"
)
const (
@ -39,7 +38,7 @@ const (
const maxQueueLength = 10
// Logger.
var logger = log.NewLogger(os.Stdout)
var logger = gulu.Log.NewLogger(os.Stdout)
// Event represents an event.
type Event struct {
@ -70,7 +69,7 @@ var UserEventQueues = queues{}
// Load initializes the event handling.
func Load() {
go func() {
defer util.Recover()
defer gulu.Panic.Recover()
for event := range EventQueue {
logger.Debugf("Received a global event [code=%d]", event.Code)
@ -107,7 +106,7 @@ func (ueqs queues) New(sid string) *UserEventQueue {
ueqs[sid] = q
go func() { // start listening
defer util.Recover()
defer gulu.Panic.Recover()
for evt := range q.Queue {
logger.Debugf("Session [%s] received an event [%d]", sid, evt.Code)

View File

@ -20,7 +20,7 @@ import (
"os"
"path/filepath"
"github.com/b3log/wide/util"
"github.com/b3log/gulu"
)
// GetZipHandler handles request of retrieving zip file.
@ -34,7 +34,7 @@ func GetZipHandler(w http.ResponseWriter, r *http.Request) {
return
}
if !util.File.IsExist(path) {
if !gulu.File.IsExist(path) {
http.Error(w, "Not Found", 404)
return
@ -51,8 +51,8 @@ func GetZipHandler(w http.ResponseWriter, r *http.Request) {
// CreateZipHandler handles request of creating zip.
func CreateZipHandler(w http.ResponseWriter, r *http.Request) {
data := util.NewResult()
defer util.RetResult(w, r, data)
data := gulu.Ret.NewResult()
defer gulu.Ret.RetResult(w, r, data)
var args map[string]interface{}
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)
if !util.File.IsExist(path) {
if !gulu.File.IsExist(path) {
data.Succ = false
data.Msg = "Can't find file [" + path + "]"
@ -83,7 +83,7 @@ func CreateZipHandler(w http.ResponseWriter, r *http.Request) {
}
zipPath := filepath.Join(dir, name)
zipFile, err := util.Zip.Create(zipPath + ".zip")
zipFile, err := gulu.Zip.Create(zipPath + ".zip")
if nil != err {
logger.Error(err)
data.Succ = false
@ -92,7 +92,7 @@ func CreateZipHandler(w http.ResponseWriter, r *http.Request) {
}
defer zipFile.Close()
if util.File.IsDir(path) {
if gulu.File.IsDir(path) {
zipFile.AddDirectory(base, path)
} else {
zipFile.AddEntry(base, path)

View File

@ -24,15 +24,14 @@ import (
"sort"
"strings"
"github.com/b3log/gulu"
"github.com/b3log/wide/conf"
"github.com/b3log/wide/event"
"github.com/b3log/wide/log"
"github.com/b3log/wide/session"
"github.com/b3log/wide/util"
)
// Logger.
var logger = log.NewLogger(os.Stdout)
var logger = gulu.Log.NewLogger(os.Stdout)
// Node represents a file node in file tree.
type Node struct {
@ -61,7 +60,7 @@ var apiNode *Node
// initAPINode builds the Go API file node.
func initAPINode() {
apiPath := util.Go.GetAPIPath()
apiPath := gulu.Go.GetAPIPath()
apiNode = &Node{Name: "Go API", Path: apiPath, IconSkin: "ico-ztree-dir-api ", Type: "d",
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)
result := util.NewResult()
defer util.RetGzResult(w, r, result)
result := gulu.Ret.NewResult()
defer gulu.Ret.RetGzResult(w, r, result)
userWorkspace := conf.GetUserWorkspace(uid)
workspaces := filepath.SplitList(userWorkspace)
@ -134,7 +133,7 @@ func RefreshDirectoryHandler(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
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)
return
@ -164,8 +163,8 @@ func GetFileHandler(w http.ResponseWriter, r *http.Request) {
}
uid := httpSession.Values["uid"].(string)
result := util.NewResult()
defer util.RetResult(w, r, result)
result := gulu.Ret.NewResult()
defer gulu.Ret.RetResult(w, r, result)
var args map[string]interface{}
@ -178,13 +177,13 @@ func GetFileHandler(w http.ResponseWriter, r *http.Request) {
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)
return
}
size := util.File.GetFileSize(path)
size := gulu.File.GetFileSize(path)
if size > 5242880 { // 5M
result.Succ = false
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)
if util.File.IsImg(extension) {
if gulu.File.IsImg(extension) {
// image file will be open in a browser tab
data["mode"] = "img"
@ -221,7 +220,7 @@ func GetFileHandler(w http.ResponseWriter, r *http.Request) {
content := string(buf)
if util.File.IsBinary(content) {
if gulu.File.IsBinary(content) {
result.Succ = false
result.Msg = "Can't open a binary file :("
} else {
@ -240,8 +239,8 @@ func SaveFileHandler(w http.ResponseWriter, r *http.Request) {
}
uid := httpSession.Values["uid"].(string)
result := util.NewResult()
defer util.RetResult(w, r, result)
result := gulu.Ret.NewResult()
defer gulu.Ret.RetResult(w, r, result)
var args map[string]interface{}
@ -255,7 +254,7 @@ func SaveFileHandler(w http.ResponseWriter, r *http.Request) {
filePath := args["file"].(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)
return
@ -296,8 +295,8 @@ func NewFileHandler(w http.ResponseWriter, r *http.Request) {
}
uid := httpSession.Values["uid"].(string)
result := util.NewResult()
defer util.RetResult(w, r, result)
result := gulu.Ret.NewResult()
defer gulu.Ret.RetResult(w, r, result)
var args map[string]interface{}
@ -310,7 +309,7 @@ func NewFileHandler(w http.ResponseWriter, r *http.Request) {
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)
return
@ -348,8 +347,8 @@ func RemoveFileHandler(w http.ResponseWriter, r *http.Request) {
}
uid := httpSession.Values["uid"].(string)
result := util.NewResult()
defer util.RetResult(w, r, result)
result := gulu.Ret.NewResult()
defer gulu.Ret.RetResult(w, r, result)
var args map[string]interface{}
@ -362,7 +361,7 @@ func RemoveFileHandler(w http.ResponseWriter, r *http.Request) {
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)
return
@ -394,8 +393,8 @@ func RenameFileHandler(w http.ResponseWriter, r *http.Request) {
}
uid := httpSession.Values["uid"].(string)
result := util.NewResult()
defer util.RetResult(w, r, result)
result := gulu.Ret.NewResult()
defer gulu.Ret.RetResult(w, r, result)
var args map[string]interface{}
@ -407,7 +406,7 @@ func RenameFileHandler(w http.ResponseWriter, r *http.Request) {
}
oldPath := args["oldPath"].(string)
if util.Go.IsAPI(oldPath) ||
if gulu.Go.IsAPI(oldPath) ||
!session.CanAccess(uid, oldPath) {
http.Error(w, "Forbidden", http.StatusForbidden)
@ -415,7 +414,7 @@ func RenameFileHandler(w http.ResponseWriter, r *http.Request) {
}
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)
return
@ -459,8 +458,8 @@ func FindHandler(w http.ResponseWriter, r *http.Request) {
}
uid := httpSession.Values["uid"].(string)
result := util.NewResult()
defer util.RetResult(w, r, result)
result := gulu.Ret.NewResult()
defer gulu.Ret.RetResult(w, r, result)
var args map[string]interface{}
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
if !util.Go.IsAPI(path) && !session.CanAccess(uid, path) {
if !gulu.Go.IsAPI(path) && !session.CanAccess(uid, path) {
http.Error(w, "Forbidden", http.StatusForbidden)
return
@ -482,7 +481,7 @@ func FindHandler(w http.ResponseWriter, r *http.Request) {
userWorkspace := conf.GetUserWorkspace(uid)
workspaces := filepath.SplitList(userWorkspace)
if "" != path && !util.File.IsDir(path) {
if "" != path && !gulu.File.IsDir(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{})
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)})
}
@ -512,8 +511,8 @@ func SearchTextHandler(w http.ResponseWriter, r *http.Request) {
return
}
result := util.NewResult()
defer util.RetResult(w, r, result)
result := gulu.Ret.NewResult()
defer gulu.Ret.RetResult(w, r, result)
var args map[string]interface{}
@ -545,7 +544,7 @@ func SearchTextHandler(w http.ResponseWriter, r *http.Request) {
text := args["text"].(string)
founds := []*Snippet{}
if util.File.IsDir(dir) {
if gulu.File.IsDir(dir) {
founds = search(dir, extension, text, []*Snippet{})
} else {
founds = searchInFile(dir, text)
@ -644,7 +643,7 @@ func listFiles(dirname string) []string {
//
// Refers to the zTree document for CSS class names.
func getIconSkin(filenameExtension string) string {
if util.File.IsImg(filenameExtension) {
if gulu.File.IsImg(filenameExtension) {
return "ico-ztree-img "
}
@ -763,7 +762,7 @@ func find(dir, name string, results []*string) []*string {
path := dir + fname
if fileInfo.IsDir() {
if util.Str.Contains(fname, defaultExcludesFind) {
if gulu.Str.Contains(fname, defaultExcludesFind) {
continue
}
@ -836,7 +835,7 @@ func searchInFile(path string, text string) []*Snippet {
}
content := string(bytes)
if util.File.IsBinary(content) {
if gulu.File.IsBinary(content) {
return ret
}

View File

@ -23,7 +23,7 @@ import (
"net/http"
"strings"
"github.com/b3log/wide/util"
"github.com/b3log/gulu"
)
type element struct {
@ -34,8 +34,8 @@ type element struct {
// GetOutlineHandler gets outfile of a go file.
func GetOutlineHandler(w http.ResponseWriter, r *http.Request) {
result := util.NewResult()
defer util.RetResult(w, r, result)
result := gulu.Ret.NewResult()
defer gulu.Ret.RetResult(w, r, result)
var args map[string]interface{}

9
go.mod
View File

@ -3,6 +3,7 @@ module github.com/b3log/wide
go 1.12
require (
github.com/b3log/gulu v0.0.0-20190524125155-0ed03084217c
github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f // indirect
github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f // indirect
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/sessions v0.0.0-20150417174705-f61c3ec2cf65
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/parnurzeal/gorequest v0.2.15
github.com/pkg/errors v0.8.1 // indirect
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a // indirect
golang.org/x/net v0.0.0-20190514140710-3ec191127204 // indirect
golang.org/x/sys v0.0.0-20190515190549-87c872767d25 // indirect
golang.org/x/text v0.3.2
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f // indirect
golang.org/x/net v0.0.0-20190522155817-f3200d17e092 // indirect
golang.org/x/sys v0.0.0-20190524122548-abf6ff778158 // indirect
golang.org/x/tools v0.0.0-20190523174634-38d8bcfa38af // indirect
)

14
go.sum
View File

@ -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/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
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/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/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/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
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/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-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-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/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-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/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.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
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-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190523174634-38d8bcfa38af/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=

View File

@ -22,11 +22,11 @@ import (
"sort"
"strings"
"github.com/b3log/wide/log"
"github.com/b3log/gulu"
)
// Logger.
var logger = log.NewLogger(os.Stdout)
var logger = gulu.Log.NewLogger(os.Stdout)
// Locale.
type locale struct {

View File

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

View File

@ -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
View File

@ -29,21 +29,20 @@ import (
"syscall"
"time"
"github.com/b3log/gulu"
"github.com/b3log/wide/conf"
"github.com/b3log/wide/editor"
"github.com/b3log/wide/event"
"github.com/b3log/wide/file"
"github.com/b3log/wide/i18n"
"github.com/b3log/wide/log"
"github.com/b3log/wide/notification"
"github.com/b3log/wide/output"
"github.com/b3log/wide/playground"
"github.com/b3log/wide/session"
"github.com/b3log/wide/util"
)
// Logger
var logger *log.Logger
var logger *gulu.Logger
// The only one init function in Wide.
func init() {
@ -55,10 +54,10 @@ func init() {
flag.Parse()
log.SetLevel("warn")
logger = log.NewLogger(os.Stdout)
gulu.Log.SetLevel("warn")
logger = gulu.Log.NewLogger(os.Stdout)
//wd := util.OS.Pwd()
//wd := gulu.OS.Pwd()
//if strings.HasPrefix(wd, os.TempDir()) {
// logger.Error("Don't run Wide in OS' temp directory or with `go run`")
//
@ -74,7 +73,7 @@ func init() {
session.FixedTimeRelease()
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.
@ -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,
"uid": uid, "sid": session.WideSessions.GenId(), "latestSessionContent": user.LatestSessionContent,
"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))
@ -409,7 +408,7 @@ func stopwatch(handler func(w http.ResponseWriter, r *http.Request)) func(w http
// panicRecover wraps the panic recover process.
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) {
defer util.Recover()
defer gulu.Panic.Recover()
handler(w, r)
}

View File

@ -21,10 +21,10 @@ import (
"strconv"
"time"
"github.com/b3log/gulu"
"github.com/b3log/wide/conf"
"github.com/b3log/wide/event"
"github.com/b3log/wide/i18n"
"github.com/b3log/wide/log"
"github.com/b3log/wide/session"
"github.com/b3log/wide/util"
"github.com/gorilla/websocket"
@ -40,7 +40,7 @@ const (
)
// Logger.
var logger = log.NewLogger(os.Stdout)
var logger = gulu.Log.NewLogger(os.Stdout)
// Notification represents a notification.
type Notification struct {

View File

@ -18,6 +18,7 @@ import (
"bufio"
"encoding/json"
"fmt"
"github.com/b3log/gulu"
"io"
"net/http"
"os"
@ -30,13 +31,12 @@ import (
"github.com/b3log/wide/conf"
"github.com/b3log/wide/i18n"
"github.com/b3log/wide/session"
"github.com/b3log/wide/util"
)
// BuildHandler handles request of building.
func BuildHandler(w http.ResponseWriter, r *http.Request) {
result := util.NewResult()
defer util.RetResult(w, r, result)
result := gulu.Ret.NewResult()
defer gulu.Ret.RetResult(w, r, result)
httpSession, _ := session.HTTPSession.Get(r, session.CookieName)
if httpSession.IsNew {
@ -58,7 +58,7 @@ func BuildHandler(w http.ResponseWriter, r *http.Request) {
sid := args["sid"].(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)
return
@ -98,7 +98,7 @@ func BuildHandler(w http.ResponseWriter, r *http.Request) {
}
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)
goModCmd = exec.Command("go", "mod", "init", curDirName)
} else {
@ -118,7 +118,7 @@ func BuildHandler(w http.ResponseWriter, r *http.Request) {
var goBuildArgs []string
goBuildArgs = append(goBuildArgs, "build")
goBuildArgs = append(goBuildArgs, user.BuildArgs(runtime.GOOS)...)
if !util.Str.Contains("-i", goBuildArgs) {
if !gulu.Str.Contains("-i", goBuildArgs) {
goBuildArgs = append(goBuildArgs, "-i")
}
@ -127,7 +127,7 @@ func BuildHandler(w http.ResponseWriter, r *http.Request) {
setCmdEnv(cmd, uid)
suffix := ""
if util.OS.IsWindows() {
if gulu.OS.IsWindows() {
suffix = ".exe"
}
executable := filepath.Base(curDir) + suffix
@ -167,7 +167,7 @@ func BuildHandler(w http.ResponseWriter, r *http.Request) {
/////////
go func() {
defer util.Recover()
defer gulu.Panic.Recover()
for {
wsChannel := session.OutputWS[sid]

View File

@ -26,16 +26,16 @@ import (
"strconv"
"strings"
"github.com/b3log/gulu"
"github.com/b3log/wide/conf"
"github.com/b3log/wide/i18n"
"github.com/b3log/wide/session"
"github.com/b3log/wide/util"
)
// CrossCompilationHandler handles request of cross compilation.
func CrossCompilationHandler(w http.ResponseWriter, r *http.Request) {
result := util.NewResult()
defer util.RetResult(w, r, result)
result := gulu.Ret.NewResult()
defer gulu.Ret.RetResult(w, r, result)
httpSession, _ := session.HTTPSession.Get(r, session.CookieName)
if httpSession.IsNew {
@ -58,7 +58,7 @@ func CrossCompilationHandler(w http.ResponseWriter, r *http.Request) {
sid := args["sid"].(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)
return
@ -152,7 +152,7 @@ func CrossCompilationHandler(w http.ResponseWriter, r *http.Request) {
}
go func(runningId int) {
defer util.Recover()
defer gulu.Panic.Recover()
defer cmd.Wait()
// read all

View File

@ -26,16 +26,16 @@ import (
"strconv"
"strings"
"github.com/b3log/gulu"
"github.com/b3log/wide/conf"
"github.com/b3log/wide/i18n"
"github.com/b3log/wide/session"
"github.com/b3log/wide/util"
)
// GoInstallHandler handles request of go install.
func GoInstallHandler(w http.ResponseWriter, r *http.Request) {
result := util.NewResult()
defer util.RetResult(w, r, result)
result := gulu.Ret.NewResult()
defer gulu.Ret.RetResult(w, r, result)
httpSession, _ := session.HTTPSession.Get(r, session.CookieName)
if httpSession.IsNew {
@ -116,7 +116,7 @@ func GoInstallHandler(w http.ResponseWriter, r *http.Request) {
}
go func(runningId int) {
defer util.Recover()
defer gulu.Panic.Recover()
defer cmd.Wait()
logger.Debugf("User [%s, %s] is running [go install] [id=%d, dir=%s]", uid, sid, runningId, curDir)

View File

@ -25,8 +25,8 @@ import (
"strings"
"time"
"github.com/b3log/gulu"
"github.com/b3log/wide/conf"
"github.com/b3log/wide/log"
"github.com/b3log/wide/session"
"github.com/b3log/wide/util"
"github.com/gorilla/websocket"
@ -38,7 +38,7 @@ const (
)
// Logger.
var logger = log.NewLogger(os.Stdout)
var logger = gulu.Log.NewLogger(os.Stdout)
// Lint represents a code lint.
type Lint struct {
@ -122,7 +122,7 @@ func setCmdEnv(cmd *exec.Cmd, uid string) {
"GOCACHE="+cache,
"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.
cmd.Env = append(cmd.Env, os.Environ()...)
} else {

View File

@ -24,16 +24,16 @@ import (
"os/exec"
"path/filepath"
"github.com/b3log/gulu"
"github.com/b3log/wide/conf"
"github.com/b3log/wide/i18n"
"github.com/b3log/wide/session"
"github.com/b3log/wide/util"
)
// GoTestHandler handles request of go test.
func GoTestHandler(w http.ResponseWriter, r *http.Request) {
result := util.NewResult()
defer util.RetResult(w, r, result)
result := gulu.Ret.NewResult()
defer gulu.Ret.RetResult(w, r, result)
httpSession, _ := session.HTTPSession.Get(r, session.CookieName)
if httpSession.IsNew {
@ -112,7 +112,7 @@ func GoTestHandler(w http.ResponseWriter, r *http.Request) {
}
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)

View File

@ -24,16 +24,16 @@ import (
"os/exec"
"path/filepath"
"github.com/b3log/gulu"
"github.com/b3log/wide/conf"
"github.com/b3log/wide/i18n"
"github.com/b3log/wide/session"
"github.com/b3log/wide/util"
)
// GoVetHandler handles request of go vet.
func GoVetHandler(w http.ResponseWriter, r *http.Request) {
result := util.NewResult()
defer util.RetResult(w, r, result)
result := gulu.Ret.NewResult()
defer gulu.Ret.RetResult(w, r, result)
httpSession, _ := session.HTTPSession.Get(r, session.CookieName)
if httpSession.IsNew {
@ -112,7 +112,7 @@ func GoVetHandler(w http.ResponseWriter, r *http.Request) {
}
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)

View File

@ -22,8 +22,8 @@ import (
"strconv"
"strings"
"github.com/b3log/gulu"
"github.com/b3log/wide/session"
"github.com/b3log/wide/util"
)
// AutocompleteHandler handles request of code autocompletion.
@ -51,7 +51,7 @@ func AutocompleteHandler(w http.ResponseWriter, r *http.Request) {
offset := getCursorOffset(code, line, ch)
argv := []string{"-f=json", "autocomplete", strconv.Itoa(offset)}
gocode := util.Go.GetExecutableInGOBIN("gocode")
gocode := gulu.Go.GetExecutableInGOBIN("gocode")
cmd := exec.Command(gocode, argv...)
stdin, _ := cmd.StdinPipe()

View File

@ -22,15 +22,15 @@ import (
"path/filepath"
"strings"
"github.com/b3log/gulu"
"github.com/b3log/wide/conf"
"github.com/b3log/wide/session"
"github.com/b3log/wide/util"
)
// BuildHandler handles request of Playground building.
func BuildHandler(w http.ResponseWriter, r *http.Request) {
result := util.NewResult()
defer util.RetResult(w, r, result)
result := gulu.Ret.NewResult()
defer gulu.Ret.RetResult(w, r, result)
httpSession, _ := session.HTTPSession.Get(r, session.CookieName)
if httpSession.IsNew {
@ -51,7 +51,7 @@ func BuildHandler(w http.ResponseWriter, r *http.Request) {
filePath := filepath.Clean(conf.Wide.Data + "/playground/" + fileName)
suffix := ""
if util.OS.IsWindows() {
if gulu.OS.IsWindows() {
suffix = ".exe"
}

View File

@ -24,15 +24,15 @@ import (
"os/exec"
"path/filepath"
"github.com/b3log/gulu"
"github.com/b3log/wide/conf"
"github.com/b3log/wide/session"
"github.com/b3log/wide/util"
)
// SaveHandler handles request of Playground code save.
func SaveHandler(w http.ResponseWriter, r *http.Request) {
result := util.NewResult()
defer util.RetResult(w, r, result)
result := gulu.Ret.NewResult()
defer gulu.Ret.RetResult(w, r, result)
session, _ := session.HTTPSession.Get(r, session.CookieName)
if session.IsNew {

View File

@ -26,16 +26,16 @@ import (
"strings"
"time"
"github.com/b3log/gulu"
"github.com/b3log/wide/conf"
"github.com/b3log/wide/i18n"
"github.com/b3log/wide/log"
"github.com/b3log/wide/session"
"github.com/b3log/wide/util"
"github.com/gorilla/websocket"
)
// Logger.
var logger = log.NewLogger(os.Stdout)
var logger = gulu.Log.NewLogger(os.Stdout)
// IndexHandler handles request of Playground index.
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") {
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)
if nil != err {

View File

@ -25,9 +25,9 @@ import (
"strings"
"time"
"github.com/b3log/gulu"
"github.com/b3log/wide/conf"
"github.com/b3log/wide/i18n"
"github.com/b3log/wide/util"
"github.com/parnurzeal/gorequest"
)
@ -35,7 +35,7 @@ var states = map[string]string{}
// RedirectGitHubHandler redirects to GitHub auth page.
func RedirectGitHubHandler(w http.ResponseWriter, r *http.Request) {
requestResult := util.NewResult()
requestResult := gulu.Ret.NewResult()
_, _, errs := gorequest.New().TLSClientConfig(&tls.Config{InsecureSkipVerify: true}).
Get("https://hacpai.com/oauth/wide/client").
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")
referer := conf.Wide.Server + "__" + state
state = util.Rand.String(16) + referer
state = gulu.Rand.String(16) + referer
states[state] = state
path := loginAuthURL + "?client_id=" + clientId + "&state=" + state + "&scope=public_repo,read:user,user:follow"
http.Redirect(w, r, path, http.StatusSeeOther)
@ -93,10 +93,10 @@ func GithubCallbackHandler(w http.ResponseWriter, r *http.Request) {
if nil == user {
msg := addUser(githubId, userName, avatar)
if userCreated != msg {
result := util.NewResult()
result := gulu.Ret.NewResult()
result.Succ = false
result.Msg = msg
util.RetResult(w, r, result)
gulu.Ret.RetResult(w, r, result)
return
}
@ -149,8 +149,8 @@ func LoginHandler(w http.ResponseWriter, r *http.Request) {
// LogoutHandler handles request of user logout (exit).
func LogoutHandler(w http.ResponseWriter, r *http.Request) {
result := util.NewResult()
defer util.RetResult(w, r, result)
result := gulu.Ret.NewResult()
defer gulu.Ret.RetResult(w, r, result)
httpSession, _ := HTTPSession.Get(r, CookieName)

View File

@ -17,8 +17,6 @@ package session
import (
"bufio"
"encoding/json"
"github.com/b3log/wide/conf"
"github.com/b3log/wide/util"
"math/rand"
"net/http"
"os"
@ -28,6 +26,10 @@ import (
"strings"
"sync"
"time"
"github.com/b3log/gulu"
"github.com/b3log/wide/conf"
"github.com/b3log/wide/util"
)
// Type of process set.
@ -43,8 +45,8 @@ var procMutex sync.Mutex
// RunHandler handles request of executing a binary file.
func RunHandler(w http.ResponseWriter, r *http.Request, channel map[string]*util.WSChannel) {
result := util.NewResult()
defer util.RetResult(w, r, result)
result := gulu.Ret.NewResult()
defer gulu.Ret.RetResult(w, r, result)
var args map[string]interface{}
@ -120,12 +122,12 @@ func RunHandler(w http.ResponseWriter, r *http.Request, channel map[string]*util
}
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)
go func() {
defer util.Recover()
defer gulu.Panic.Recover()
for {
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.
func StopHandler(w http.ResponseWriter, r *http.Request) {
result := util.NewResult()
defer util.RetResult(w, r, result)
result := gulu.Ret.NewResult()
defer gulu.Ret.RetResult(w, r, result)
var args map[string]interface{}
if err := json.NewDecoder(r.Body).Decode(&args); err != nil {

View File

@ -35,9 +35,9 @@ import (
"sync"
"time"
"github.com/b3log/gulu"
"github.com/b3log/wide/conf"
"github.com/b3log/wide/event"
"github.com/b3log/wide/log"
"github.com/b3log/wide/util"
"github.com/fsnotify/fsnotify"
"github.com/gorilla/sessions"
@ -46,13 +46,13 @@ import (
const (
sessionStateActive = iota
sessionStateClosed // (not used so far)
sessionStateClosed // (not used so far)
CookieName = "wide-sess"
)
// Logger.
var logger = log.NewLogger(os.Stdout)
var logger = gulu.Log.NewLogger(os.Stdout)
var (
// 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.
func FixedTimeRelease() {
go func() {
defer util.Recover()
defer gulu.Panic.Recover()
for _ = range time.Tick(time.Hour) {
hour, _ := time.ParseDuration("-30m")
@ -139,9 +139,9 @@ func (u *userReport) report() string {
// FixedTimeReport reports the Wide sessions status periodically (10 minutes).
func FixedTimeReport() {
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{}
processSum := 0
@ -284,8 +284,8 @@ func WSHandler(w http.ResponseWriter, r *http.Request) {
// SaveContentHandler handles request of session content string.
func SaveContentHandler(w http.ResponseWriter, r *http.Request) {
result := util.NewResult()
defer util.RetResult(w, r, result)
result := gulu.Ret.NewResult()
defer gulu.Ret.RetResult(w, r, result)
args := struct {
Sid string
@ -477,7 +477,7 @@ func (sessions *wSessions) new(httpSession *sessions.Session, sid string) *WideS
}
go func() {
defer util.Recover()
defer gulu.Panic.Recover()
for {
ch := SessionWS[sid]
@ -500,7 +500,7 @@ func (sessions *wSessions) new(httpSession *sessions.Session, sid string) *WideS
if event.Op&fsnotify.Create == fsnotify.Create {
fileType := "f"
if util.File.IsDir(path) {
if gulu.File.IsDir(path) {
fileType = "d"
if err = watcher.Add(path); nil != err {
@ -526,7 +526,7 @@ func (sessions *wSessions) new(httpSession *sessions.Session, sid string) *WideS
}()
go func() {
defer util.Recover()
defer gulu.Panic.Recover()
workspaces := filepath.SplitList(conf.GetUserWorkspace(uid))
for _, workspace := range workspaces {

View File

@ -24,17 +24,17 @@ import (
"text/template"
"time"
"github.com/b3log/gulu"
"github.com/b3log/wide/conf"
"github.com/b3log/wide/i18n"
"github.com/b3log/wide/util"
)
const (
// TODO: i18n
userExists = "user exists"
userCreated = "user created"
userCreateError = "user create error"
userExists = "user exists"
userCreated = "user created"
userCreateError = "user create error"
)
// 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,
"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()}
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
result := util.NewResult()
defer util.RetResult(w, r, result)
result := gulu.Ret.NewResult()
defer gulu.Ret.RetResult(w, r, result)
args := struct {
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.
func FixedTimeSave() {
go func() {
defer util.Recover()
defer gulu.Panic.Recover()
for _ = range time.Tick(time.Minute) {
SaveOnlineUsers()

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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