Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2840e4e

Browse files
author
studygolang
committed
wiki功能;表单验证;支持登录后跳转到原页面;
采用另外的方式获得可执行文件目录,以兼容各个系统; 保存pid 增加windows启动/停止脚本
1 parent 098fdab commit 2840e4e

File tree

17 files changed

+168
-138
lines changed

17 files changed

+168
-138
lines changed

websites/code/studygolang/conf/config.json.example

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@
88
"smtp_password": "example_password",
99
"smtp_host": "smtp.example.com",
1010
"smtp_addr": "smtp.example.com:25",
11-
"from_email": "[email protected]"
11+
"from_email": "[email protected]",
12+
"pid": "pid/studygolang.pid"
1213
}

websites/code/studygolang/src/controller/account.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,14 @@ func LoginHandler(rw http.ResponseWriter, req *http.Request) {
7272
// 登录成功,种cookie
7373
setCookie(rw, req, userLogin.Username)
7474

75-
util.Redirect(rw, req, "/")
75+
// 支持跳转到源页面
76+
uri := "/"
77+
values := filter.NewFlash(rw, req).Flashes("uri")
78+
if values != nil {
79+
uri = values[0].(string)
80+
}
81+
logger.Debugln("uri===", uri)
82+
util.Redirect(rw, req, uri)
7683
}
7784

7885
// 用户编辑个人信息

websites/code/studygolang/src/controller/admin/user.go

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
"html/template"
1313
"net/http"
1414
"service"
15-
"util"
1615
)
1716

1817
// 所有用户(分页)
@@ -40,34 +39,6 @@ func NewUserHandler(rw http.ResponseWriter, req *http.Request) {
4039

4140
// 执行添加新用户(异步请求,返回json)
4241
func AddUserHandler(rw http.ResponseWriter, req *http.Request) {
43-
rules := map[string]map[string]map[string]string{
44-
"username": {
45-
"require": {"error": "用户名不能为空!"},
46-
"length": {"range": "4,20", "error": "用户名长度必须在%d个字符和%d个字符之间"},
47-
},
48-
"email": {
49-
"require": {"error": "邮箱不能为空!"},
50-
"email": {"error": "邮箱格式不正确!"},
51-
},
52-
"passwd": {
53-
"require": {"error": "密码不能为空!"},
54-
"length": {"range": "6,32", "error": "密码长度必须在%d个字符和%d个字符之间"},
55-
},
56-
"pass2": {
57-
"require": {"error": "确认密码不能为空!"},
58-
"compare": {"field": "passwd", "rule": "=", "error": "两次密码不一致"},
59-
},
60-
}
61-
req.ParseForm()
62-
errMsg := util.Validate(req.Form, rules)
63-
64-
header := rw.Header()
65-
header.Set("Content-Type", "application/json; charset=utf-8")
66-
if errMsg != "" {
67-
fmt.Fprint(rw, `{"errno": 1,"error":"`, errMsg, `"}`)
68-
return
69-
}
70-
7142
// 入库
7243
errMsg, err := service.CreateUser(req.Form)
7344
if err != nil {

websites/code/studygolang/src/controller/topic.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ func TopicDetailHandler(rw http.ResponseWriter, req *http.Request) {
9090
}
9191

9292
// 新建帖子
93-
// uri: /topics/new
93+
// uri: /topics/new{json:(|.json)}
9494
func NewTopicHandler(rw http.ResponseWriter, req *http.Request) {
9595
nodes := genNodes()
9696
vars := mux.Vars(req)

websites/code/studygolang/src/filter/login.go

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,46 @@ func (this *LoginFilter) PreFilter(rw http.ResponseWriter, req *http.Request) bo
2626
logger.Debugln("LoginFilter PreFilter...")
2727
if _, ok := CurrentUser(req); !ok {
2828
logger.Debugln("需要登录")
29-
// 没有登录
29+
// 支持跳转回原来访问的页面
30+
NewFlash(rw, req).AddFlash(req.RequestURI, "uri")
3031
util.Redirect(rw, req, "/account/login")
3132
return false
3233
}
3334
return true
3435
}
3536

37+
// flash messages
38+
type Flash struct {
39+
rw http.ResponseWriter
40+
req *http.Request
41+
42+
session *sessions.Session
43+
}
44+
45+
func NewFlash(rw http.ResponseWriter, req *http.Request) *Flash {
46+
session, _ := Store.Get(req, "sg_flash")
47+
return &Flash{rw: rw, req: req, session: session}
48+
}
49+
50+
func (this *Flash) AddFlash(value interface{}, vars ...string) {
51+
this.session.AddFlash(value, vars...)
52+
this.session.Save(this.req, this.rw)
53+
}
54+
55+
func (this *Flash) Flashes(vars ...string) []interface{} {
56+
defer this.session.Save(this.req, this.rw)
57+
if flashes := this.session.Flashes(vars...); len(flashes) > 0 {
58+
return flashes
59+
}
60+
return nil
61+
}
62+
3663
// 如果没登陆但有Cookie时,自动登录
3764
type CookieFilter struct {
3865
*mux.EmptyFilter
3966
}
4067

4168
func (this *CookieFilter) PreFilter(rw http.ResponseWriter, req *http.Request) bool {
42-
// 避免req.Form为nil
43-
req.ParseForm()
44-
45-
logger.Debugln("CookieFilter PreFilter...")
4669
user, _ := CurrentUser(req)
4770
// 已登录且请求登录页面
4871
if user != nil && req.RequestURI == "/account/login" {

websites/code/studygolang/src/filter/rules.go

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,23 @@
66

77
package filter
88

9+
import (
10+
"regexp"
11+
)
12+
13+
func Rule(uri string) map[string]map[string]map[string]string {
14+
if rule, ok := rules[uri]; ok {
15+
return rule
16+
}
17+
for key, rule := range rules {
18+
reg := regexp.MustCompile(key)
19+
if reg.MatchString(uri) {
20+
return rule
21+
}
22+
}
23+
return nil
24+
}
25+
926
// 定义所有表单验证规则
1027
var rules = map[string]map[string]map[string]map[string]string{
1128
// 用户注册验证规则
@@ -31,8 +48,7 @@ var rules = map[string]map[string]map[string]map[string]string{
3148
// 发新帖
3249
"/topics/new.json": {
3350
"nid": {
34-
"require": {"error": "请选择节点"},
35-
"int": {},
51+
"int": {"range": "0,", "error": "请选择节点"},
3652
},
3753
"title": {
3854
"require": {"error": "标题不能为空"},
@@ -43,4 +59,25 @@ var rules = map[string]map[string]map[string]map[string]string{
4359
"length": {"range": "2,", "error": "话题内容长度必不能少于%d个字符"},
4460
},
4561
},
62+
// 发回复
63+
`/comment/\d+\.json`: {
64+
"content": {
65+
"require": {"error": "内容不能为空!"},
66+
"length": {"range": "2,", "error": "回复内容长度必不能少于%d个字符"},
67+
},
68+
},
69+
// 发wiki
70+
"/wiki/new.json": {
71+
"title": {
72+
"require": {"error": "标题不能为空"},
73+
"length": {"range": "3,", "error": "标题长度必不能少于%d个字符"},
74+
},
75+
"uri": {
76+
"require": {"error": "URL不能为空"},
77+
},
78+
"content": {
79+
"require": {"error": "内容不能为空!"},
80+
"length": {"range": "2,", "error": "内容长度必不能少于%d个字符"},
81+
},
82+
},
4683
}

websites/code/studygolang/src/filter/validate.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func (this *FormValidateFilter) PreFilter(rw http.ResponseWriter, req *http.Requ
3030
uri = "/account/register.json"
3131
}
3232
// 验证表单
33-
errMsg := Validate(req.Form, rules[uri])
33+
errMsg := Validate(req.Form, Rule(uri))
3434
logger.Debugln("validate:", errMsg)
3535
// 验证失败
3636
// TODO:暂时规定,要验证的表单提交都采用异步方式,期望返回json数据
@@ -84,7 +84,7 @@ func Validate(data url.Values, rules map[string]map[string]map[string]string) (e
8484
}
8585
// 检查【邮箱】
8686
if emailInfo, ok := rule["email"]; ok {
87-
validEmail := regexp.MustCompile(`^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\.[a-zA-Z0-9_-]{2,3}){1,2})$`)
87+
validEmail := regexp.MustCompile(`^(\w)+([\w\.-])*@([\w-])+((\.[\w-]{2,3}){1,2})$`)
8888
if !validEmail.MatchString(val) {
8989
errMsg = emailInfo["error"]
9090
return
@@ -129,15 +129,15 @@ func checkRange(src int, destRange string, msg string) (errMsg string) {
129129
max = util.MustInt(parts[1])
130130
if src > max {
131131
errMsg = fmt.Sprintf(msg, max)
132-
return
133132
}
133+
return
134134
}
135135
if parts[1] == "" {
136136
min = util.MustInt(parts[0])
137137
if src < min {
138138
errMsg = fmt.Sprintf(msg, min)
139-
return
140139
}
140+
return
141141
}
142142
if min == 0 {
143143
min = util.MustInt(parts[0])

websites/code/studygolang/src/process/path_linux.go

Lines changed: 0 additions & 30 deletions
This file was deleted.

websites/code/studygolang/src/process/path_windows.go

Lines changed: 0 additions & 60 deletions
This file was deleted.

websites/code/studygolang/src/process/pid.go renamed to websites/code/studygolang/src/process/process.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,24 @@ package process
99
import (
1010
"io/ioutil"
1111
"os"
12+
"path/filepath"
1213
"strconv"
1314
)
1415

16+
// 保存pid
1517
func SavePidTo(pidFile string) error {
18+
pidPath := filepath.Dir(pidFile)
19+
if err := os.MkdirAll(pidPath, 0777); err != nil {
20+
return err
21+
}
1622
return ioutil.WriteFile(pidFile, []byte(strconv.Itoa(os.Getpid())), 0777)
1723
}
24+
25+
// 获得可执行程序所在目录
26+
func ExecutableDir() (string, error) {
27+
pathAbs, err := filepath.Abs(os.Args[0])
28+
if err != nil {
29+
return "", err
30+
}
31+
return filepath.Dir(pathAbs), nil
32+
}

websites/code/studygolang/src/service/wiki.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"logger"
1111
"model"
1212
"net/url"
13+
"strconv"
1314
"strings"
1415
"util"
1516
)

websites/code/studygolang/src/studygolang/main.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import (
1111
"log"
1212
"math/rand"
1313
"net/http"
14+
"path/filepath"
15+
"process"
1416
"runtime"
1517
"time"
1618
)
@@ -22,10 +24,21 @@ func init() {
2224
}
2325

2426
func main() {
27+
SavePid()
2528
// 服务静态文件
2629
http.Handle("/static/", http.FileServer(http.Dir(ROOT)))
2730

2831
router := initRouter()
2932
http.Handle("/", router)
3033
log.Fatal(http.ListenAndServe(Config["host"], nil))
3134
}
35+
36+
// 保存PID
37+
func SavePid() {
38+
pidFile := Config["pid"]
39+
if !filepath.IsAbs(Config["pid"]) {
40+
pidFile = ROOT + "/" + pidFile
41+
}
42+
// TODO:错误不处理
43+
process.SavePidTo(pidFile)
44+
}

0 commit comments

Comments
 (0)