1
0
mirror of https://github.com/astaxie/beego.git synced 2024-11-25 21:01:31 +00:00

move utils to utils libs & func move to templatefunc

This commit is contained in:
astaxie 2013-12-12 22:25:08 +08:00
parent d603a6714d
commit 19119e99f7
7 changed files with 555 additions and 591 deletions

View File

@ -3,6 +3,7 @@ package beego
import ( import (
"bytes" "bytes"
"crypto/hmac" "crypto/hmac"
"crypto/rand"
"crypto/sha1" "crypto/sha1"
"encoding/base64" "encoding/base64"
"errors" "errors"
@ -370,7 +371,7 @@ func (c *Controller) XsrfToken() string {
} else { } else {
expire = int64(XSRFExpire) expire = int64(XSRFExpire)
} }
token = GetRandomString(15) token = getRandomString(15)
c.SetSecureCookie(XSRFKEY, "_xsrf", token, expire) c.SetSecureCookie(XSRFKEY, "_xsrf", token, expire)
} }
c._xsrf_token = token c._xsrf_token = token
@ -405,3 +406,14 @@ func (c *Controller) GoToFunc(funcname string) {
} }
c.gotofunc = funcname c.gotofunc = funcname
} }
//utils func for controller internal
func getRandomString(n int) string {
const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
var bytes = make([]byte, n)
rand.Read(bytes)
for i, b := range bytes {
bytes[i] = alphanum[b%byte(len(alphanum))]
}
return string(bytes)
}

View File

@ -15,6 +15,7 @@ import (
beecontext "github.com/astaxie/beego/context" beecontext "github.com/astaxie/beego/context"
"github.com/astaxie/beego/middleware" "github.com/astaxie/beego/middleware"
"github.com/astaxie/beego/toolbox" "github.com/astaxie/beego/toolbox"
"github.com/astaxie/beego/utils"
) )
const ( const (
@ -159,7 +160,7 @@ func (p *ControllerRegistor) Add(pattern string, c ControllerInterface, mappingM
} }
comma := strings.Split(colon[0], ",") comma := strings.Split(colon[0], ",")
for _, m := range comma { for _, m := range comma {
if m == "*" || inSlice(strings.ToLower(m), HTTPMETHOD) { if m == "*" || utils.InSlice(strings.ToLower(m), HTTPMETHOD) {
if val := reflectVal.MethodByName(colon[1]); val.IsValid() { if val := reflectVal.MethodByName(colon[1]); val.IsValid() {
methods[strings.ToLower(m)] = colon[1] methods[strings.ToLower(m)] = colon[1]
} else { } else {
@ -272,7 +273,7 @@ func (p *ControllerRegistor) UrlFor(endpoint string, values ...string) string {
for _, route := range p.fixrouters { for _, route := range p.fixrouters {
if route.controllerType.Name() == controllName { if route.controllerType.Name() == controllName {
var finded bool var finded bool
if inSlice(strings.ToLower(methodName), HTTPMETHOD) { if utils.InSlice(strings.ToLower(methodName), HTTPMETHOD) {
if route.hasMethod { if route.hasMethod {
if m, ok := route.methods[strings.ToLower(methodName)]; ok && m != methodName { if m, ok := route.methods[strings.ToLower(methodName)]; ok && m != methodName {
finded = false finded = false
@ -303,7 +304,7 @@ func (p *ControllerRegistor) UrlFor(endpoint string, values ...string) string {
for _, route := range p.routers { for _, route := range p.routers {
if route.controllerType.Name() == controllName { if route.controllerType.Name() == controllName {
var finded bool var finded bool
if inSlice(strings.ToLower(methodName), HTTPMETHOD) { if utils.InSlice(strings.ToLower(methodName), HTTPMETHOD) {
if route.hasMethod { if route.hasMethod {
if m, ok := route.methods[strings.ToLower(methodName)]; ok && m != methodName { if m, ok := route.methods[strings.ToLower(methodName)]; ok && m != methodName {
finded = false finded = false
@ -419,7 +420,7 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request)
context.Output = beecontext.NewOutput(rw) context.Output = beecontext.NewOutput(rw)
} }
if !inSlice(strings.ToLower(r.Method), HTTPMETHOD) { if !utils.InSlice(strings.ToLower(r.Method), HTTPMETHOD) {
http.Error(w, "Method Not Allowed", 405) http.Error(w, "Method Not Allowed", 405)
goto Admin goto Admin
} }

View File

@ -9,9 +9,10 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"reflect"
"regexp" "regexp"
"strings" "strings"
"github.com/astaxie/beego/utils"
) )
var ( var (
@ -144,7 +145,7 @@ func getTplDeep(root, file, parent string, t *template.Template) (*template.Temp
} else { } else {
fileabspath = filepath.Join(root, file) fileabspath = filepath.Join(root, file)
} }
if e, _ := FileExists(fileabspath); !e { if e := utils.FileExists(fileabspath); !e {
panic("can't find template file" + file) panic("can't find template file" + file)
} }
data, err := ioutil.ReadFile(fileabspath) data, err := ioutil.ReadFile(fileabspath)
@ -238,156 +239,3 @@ func _getTemplate(t0 *template.Template, root string, submods [][]string, others
} }
return return
} }
// go1.2 added template funcs. begin
var (
errBadComparisonType = errors.New("invalid type for comparison")
errBadComparison = errors.New("incompatible types for comparison")
errNoComparison = errors.New("missing argument for comparison")
)
type kind int
const (
invalidKind kind = iota
boolKind
complexKind
intKind
floatKind
integerKind
stringKind
uintKind
)
func basicKind(v reflect.Value) (kind, error) {
switch v.Kind() {
case reflect.Bool:
return boolKind, nil
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return intKind, nil
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return uintKind, nil
case reflect.Float32, reflect.Float64:
return floatKind, nil
case reflect.Complex64, reflect.Complex128:
return complexKind, nil
case reflect.String:
return stringKind, nil
}
return invalidKind, errBadComparisonType
}
// eq evaluates the comparison a == b || a == c || ...
func eq(arg1 interface{}, arg2 ...interface{}) (bool, error) {
v1 := reflect.ValueOf(arg1)
k1, err := basicKind(v1)
if err != nil {
return false, err
}
if len(arg2) == 0 {
return false, errNoComparison
}
for _, arg := range arg2 {
v2 := reflect.ValueOf(arg)
k2, err := basicKind(v2)
if err != nil {
return false, err
}
if k1 != k2 {
return false, errBadComparison
}
truth := false
switch k1 {
case boolKind:
truth = v1.Bool() == v2.Bool()
case complexKind:
truth = v1.Complex() == v2.Complex()
case floatKind:
truth = v1.Float() == v2.Float()
case intKind:
truth = v1.Int() == v2.Int()
case stringKind:
truth = v1.String() == v2.String()
case uintKind:
truth = v1.Uint() == v2.Uint()
default:
panic("invalid kind")
}
if truth {
return true, nil
}
}
return false, nil
}
// ne evaluates the comparison a != b.
func ne(arg1, arg2 interface{}) (bool, error) {
// != is the inverse of ==.
equal, err := eq(arg1, arg2)
return !equal, err
}
// lt evaluates the comparison a < b.
func lt(arg1, arg2 interface{}) (bool, error) {
v1 := reflect.ValueOf(arg1)
k1, err := basicKind(v1)
if err != nil {
return false, err
}
v2 := reflect.ValueOf(arg2)
k2, err := basicKind(v2)
if err != nil {
return false, err
}
if k1 != k2 {
return false, errBadComparison
}
truth := false
switch k1 {
case boolKind, complexKind:
return false, errBadComparisonType
case floatKind:
truth = v1.Float() < v2.Float()
case intKind:
truth = v1.Int() < v2.Int()
case stringKind:
truth = v1.String() < v2.String()
case uintKind:
truth = v1.Uint() < v2.Uint()
default:
panic("invalid kind")
}
return truth, nil
}
// le evaluates the comparison <= b.
func le(arg1, arg2 interface{}) (bool, error) {
// <= is < or ==.
lessThan, err := lt(arg1, arg2)
if lessThan || err != nil {
return lessThan, err
}
return eq(arg1, arg2)
}
// gt evaluates the comparison a > b.
func gt(arg1, arg2 interface{}) (bool, error) {
// > is the inverse of <=.
lessOrEqual, err := le(arg1, arg2)
if err != nil {
return false, err
}
return !lessOrEqual, nil
}
// ge evaluates the comparison a >= b.
func ge(arg1, arg2 interface{}) (bool, error) {
// >= is the inverse of <.
lessThan, err := lt(arg1, arg2)
if err != nil {
return false, err
}
return !lessThan, nil
}
// go1.2 added template funcs. end

View File

@ -1,11 +1,10 @@
package beego package beego
import ( import (
"crypto/rand" "errors"
"fmt" "fmt"
"html/template" "html/template"
"net/url" "net/url"
"os"
"reflect" "reflect"
"regexp" "regexp"
"strconv" "strconv"
@ -13,14 +12,7 @@ import (
"time" "time"
) )
func webTime(t time.Time) string { // Substr() return the substr from start to length
ftime := t.Format(time.RFC1123)
if strings.HasSuffix(ftime, "UTC") {
ftime = ftime[0:len(ftime)-3] + "GMT"
}
return ftime
}
func Substr(s string, start, length int) string { func Substr(s string, start, length int) string {
bt := []rune(s) bt := []rune(s)
if start < 0 { if start < 0 {
@ -182,13 +174,37 @@ func Htmlunquote(src string) string {
return strings.TrimSpace(text) return strings.TrimSpace(text)
} }
func inSlice(v string, sl []string) bool { // This will reference the index function local to the current blueprint:
for _, vv := range sl { // UrlFor(".index")
if vv == v { // ... print UrlFor("index")
return true // ... print UrlFor("login")
} // ... print UrlFor("login", "next","/"")
} // ... print UrlFor("profile", "username","John Doe")
return false // ...
// /
// /login
// /login?next=/
// /user/John%20Doe
func UrlFor(endpoint string, values ...string) string {
return BeeApp.UrlFor(endpoint, values...)
}
//This can be changed to a better name
func AssetsJs(src string) template.HTML {
text := string(src)
text = "<script src=\"" + src + "\"></script>"
return template.HTML(text)
}
//This can be changed to a better name
func AssetsCss(src string) template.HTML {
text := string(src)
text = "<link href=\"" + src + "\" rel=\"stylesheet\" />"
return template.HTML(text)
} }
// parse form values to struct via tag // parse form values to struct via tag
@ -339,71 +355,155 @@ func isStructPtr(t reflect.Type) bool {
return t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct return t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct
} }
func stringsToJson(str string) string { // go1.2 added template funcs. begin
rs := []rune(str) var (
jsons := "" errBadComparisonType = errors.New("invalid type for comparison")
for _, r := range rs { errBadComparison = errors.New("incompatible types for comparison")
rint := int(r) errNoComparison = errors.New("missing argument for comparison")
if rint < 128 { )
jsons += string(r)
} else { type kind int
jsons += "\\u" + strconv.FormatInt(int64(rint), 16) // json
const (
invalidKind kind = iota
boolKind
complexKind
intKind
floatKind
integerKind
stringKind
uintKind
)
func basicKind(v reflect.Value) (kind, error) {
switch v.Kind() {
case reflect.Bool:
return boolKind, nil
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return intKind, nil
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return uintKind, nil
case reflect.Float32, reflect.Float64:
return floatKind, nil
case reflect.Complex64, reflect.Complex128:
return complexKind, nil
case reflect.String:
return stringKind, nil
}
return invalidKind, errBadComparisonType
}
// eq evaluates the comparison a == b || a == c || ...
func eq(arg1 interface{}, arg2 ...interface{}) (bool, error) {
v1 := reflect.ValueOf(arg1)
k1, err := basicKind(v1)
if err != nil {
return false, err
}
if len(arg2) == 0 {
return false, errNoComparison
}
for _, arg := range arg2 {
v2 := reflect.ValueOf(arg)
k2, err := basicKind(v2)
if err != nil {
return false, err
}
if k1 != k2 {
return false, errBadComparison
}
truth := false
switch k1 {
case boolKind:
truth = v1.Bool() == v2.Bool()
case complexKind:
truth = v1.Complex() == v2.Complex()
case floatKind:
truth = v1.Float() == v2.Float()
case intKind:
truth = v1.Int() == v2.Int()
case stringKind:
truth = v1.String() == v2.String()
case uintKind:
truth = v1.Uint() == v2.Uint()
default:
panic("invalid kind")
}
if truth {
return true, nil
} }
} }
return jsons return false, nil
} }
func FileExists(path string) (bool, error) { // ne evaluates the comparison a != b.
_, err := os.Stat(path) func ne(arg1, arg2 interface{}) (bool, error) {
if err == nil { // != is the inverse of ==.
return true, nil equal, err := eq(arg1, arg2)
return !equal, err
}
// lt evaluates the comparison a < b.
func lt(arg1, arg2 interface{}) (bool, error) {
v1 := reflect.ValueOf(arg1)
k1, err := basicKind(v1)
if err != nil {
return false, err
} }
if os.IsNotExist(err) { v2 := reflect.ValueOf(arg2)
return false, nil k2, err := basicKind(v2)
if err != nil {
return false, err
} }
return false, err if k1 != k2 {
} return false, errBadComparison
func GetRandomString(n int) string {
const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
var bytes = make([]byte, n)
rand.Read(bytes)
for i, b := range bytes {
bytes[i] = alphanum[b%byte(len(alphanum))]
} }
return string(bytes) truth := false
switch k1 {
case boolKind, complexKind:
return false, errBadComparisonType
case floatKind:
truth = v1.Float() < v2.Float()
case intKind:
truth = v1.Int() < v2.Int()
case stringKind:
truth = v1.String() < v2.String()
case uintKind:
truth = v1.Uint() < v2.Uint()
default:
panic("invalid kind")
}
return truth, nil
} }
// This will reference the index function local to the current blueprint: // le evaluates the comparison <= b.
// UrlFor(".index") func le(arg1, arg2 interface{}) (bool, error) {
// ... print UrlFor("index") // <= is < or ==.
// ... print UrlFor("login") lessThan, err := lt(arg1, arg2)
// ... print UrlFor("login", "next","/"") if lessThan || err != nil {
// ... print UrlFor("profile", "username","John Doe") return lessThan, err
// ... }
// / return eq(arg1, arg2)
// /login
// /login?next=/
// /user/John%20Doe
func UrlFor(endpoint string, values ...string) string {
return BeeApp.UrlFor(endpoint, values...)
} }
// gt evaluates the comparison a > b.
//This can be changed to a better name func gt(arg1, arg2 interface{}) (bool, error) {
func AssetsJs(src string) template.HTML { // > is the inverse of <=.
text := string(src) lessOrEqual, err := le(arg1, arg2)
if err != nil {
text = "<script src=\""+src+"\"></script>" return false, err
}
return template.HTML(text) return !lessOrEqual, nil
} }
//This can be changed to a better name // ge evaluates the comparison a >= b.
func AssetsCss(src string) template.HTML { func ge(arg1, arg2 interface{}) (bool, error) {
text := string(src) // >= is the inverse of <.
lessThan, err := lt(arg1, arg2)
text = "<link href=\""+src+"\" rel=\"stylesheet\" />" if err != nil {
return false, err
return template.HTML(text) }
return !lessThan, nil
} }
// go1.2 added template funcs. end

View File

@ -7,18 +7,6 @@ import (
"time" "time"
) )
func TestWebTime(t *testing.T) {
ts := "Fri, 26 Jul 2013 12:27:42 CST"
l, _ := time.LoadLocation("GST")
tt, _ := time.ParseInLocation(time.RFC1123, ts, l)
if ts != webTime(tt) {
t.Error("should be equal")
}
if "Fri, 26 Jul 2013 12:27:42 GMT" != webTime(tt.UTC()) {
t.Error("should be equal")
}
}
func TestSubstr(t *testing.T) { func TestSubstr(t *testing.T) {
s := `012345` s := `012345`
if Substr(s, 0, 2) != "01" { if Substr(s, 0, 2) != "01" {
@ -92,16 +80,6 @@ func TestHtmlunquote(t *testing.T) {
} }
} }
func TestInSlice(t *testing.T) {
sl := []string{"A", "b"}
if !inSlice("A", sl) {
t.Error("should be true")
}
if inSlice("B", sl) {
t.Error("should be false")
}
}
func TestParseForm(t *testing.T) { func TestParseForm(t *testing.T) {
type user struct { type user struct {
Id int `form:"-"` Id int `form:"-"`

10
utils/slice.go Normal file
View File

@ -0,0 +1,10 @@
package utils
func InSlice(v string, sl []string) bool {
for _, vv := range sl {
if vv == v {
return true
}
}
return false
}

15
utils/slice_test.go Normal file
View File

@ -0,0 +1,15 @@
package utils
import (
"testing"
)
func TestInSlice(t *testing.T) {
sl := []string{"A", "b"}
if !InSlice("A", sl) {
t.Error("should be true")
}
if InSlice("B", sl) {
t.Error("should be false")
}
}