Skip to content

Commit 17902f7

Browse files
committed
创建群组和主题
1 parent a7e23cb commit 17902f7

File tree

13 files changed

+439
-5
lines changed

13 files changed

+439
-5
lines changed

handlers/auth.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package handlers
2+
3+
import (
4+
"fmt"
5+
"github.com/xueyuanjun/chitchat/models"
6+
"net/http"
7+
)
8+
9+
// GET /login
10+
// 登录页面
11+
func Login(writer http.ResponseWriter, request *http.Request) {
12+
t := parseTemplateFiles("auth.layout", "navbar", "login")
13+
t.Execute(writer, nil)
14+
}
15+
16+
// GET /signup
17+
// 注册页面
18+
func Signup(writer http.ResponseWriter, request *http.Request) {
19+
generateHTML(writer, nil, "auth.layout", "navbar", "signup")
20+
}
21+
22+
// POST /signup
23+
// 注册新用户
24+
func SignupAccount(writer http.ResponseWriter, request *http.Request) {
25+
err := request.ParseForm()
26+
if err != nil {
27+
fmt.Println("Cannot parse form")
28+
}
29+
user := models.User{
30+
Name: request.PostFormValue("name"),
31+
Email: request.PostFormValue("email"),
32+
Password: request.PostFormValue("password"),
33+
}
34+
if err := user.Create(); err != nil {
35+
fmt.Println("Cannot create user")
36+
}
37+
http.Redirect(writer, request, "/login", 302)
38+
}
39+
40+
// POST /authenticate
41+
// 通过邮箱和密码字段对用户进行认证
42+
func Authenticate(writer http.ResponseWriter, request *http.Request) {
43+
err := request.ParseForm()
44+
user, err := models.UserByEmail(request.PostFormValue("email"))
45+
if err != nil {
46+
fmt.Println("Cannot find user")
47+
}
48+
if user.Password == models.Encrypt(request.PostFormValue("password")) {
49+
session, err := user.CreateSession()
50+
if err != nil {
51+
fmt.Println("Cannot create session")
52+
}
53+
cookie := http.Cookie{
54+
Name: "_cookie",
55+
Value: session.Uuid,
56+
HttpOnly: true,
57+
}
58+
http.SetCookie(writer, &cookie)
59+
http.Redirect(writer, request, "/", 302)
60+
} else {
61+
http.Redirect(writer, request, "/login", 302)
62+
}
63+
}
64+
65+
// GET /logout
66+
// 用户退出
67+
func Logout(writer http.ResponseWriter, request *http.Request) {
68+
cookie, err := request.Cookie("_cookie")
69+
if err != http.ErrNoCookie {
70+
fmt.Println("Failed to get cookie")
71+
session := models.Session{Uuid: cookie.Value}
72+
session.DeleteByUUID()
73+
}
74+
http.Redirect(writer, request, "/", 302)
75+
}

handlers/helper.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package handlers
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"github.com/xueyuanjun/chitchat/models"
7+
"html/template"
8+
"net/http"
9+
)
10+
11+
// Checks if the user is logged in and has a session, if not err is not nil
12+
func session(writer http.ResponseWriter, request *http.Request) (sess models.Session, err error) {
13+
cookie, err := request.Cookie("_cookie")
14+
if err == nil {
15+
sess = models.Session{Uuid: cookie.Value}
16+
if ok, _ := sess.Check(); !ok {
17+
err = errors.New("Invalid session")
18+
}
19+
}
20+
return
21+
}
22+
23+
// parse HTML templates
24+
// pass in a list of file names, and get a template
25+
func parseTemplateFiles(filenames ...string) (t *template.Template) {
26+
var files []string
27+
t = template.New("layout")
28+
for _, file := range filenames {
29+
files = append(files, fmt.Sprintf("views/%s.html", file))
30+
}
31+
t = template.Must(t.ParseFiles(files...))
32+
return
33+
}
34+
35+
func generateHTML(writer http.ResponseWriter, data interface{}, filenames ...string) {
36+
var files []string
37+
for _, file := range filenames {
38+
files = append(files, fmt.Sprintf("views/%s.html", file))
39+
}
40+
41+
templates := template.Must(template.ParseFiles(files...))
42+
templates.ExecuteTemplate(writer, "layout", data)
43+
}
44+
45+
// version
46+
func Version() string {
47+
return "0.1"
48+
}

handlers/index.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,17 @@ package handlers
22

33
import (
44
"github.com/xueyuanjun/chitchat/models"
5-
"html/template"
65
"net/http"
76
)
87

9-
func Index(w http.ResponseWriter, r *http.Request) {
10-
files := []string{"views/layout.html", "views/navbar.html", "views/index.html",}
11-
templates := template.Must(template.ParseFiles(files...))
8+
func Index(writer http.ResponseWriter, request *http.Request) {
129
threads, err := models.Threads();
1310
if err == nil {
14-
templates.ExecuteTemplate(w, "layout", threads)
11+
_, err := session(writer, request)
12+
if err != nil {
13+
generateHTML(writer, threads, "layout", "navbar", "index")
14+
} else {
15+
generateHTML(writer, threads, "layout", "auth.navbar", "index")
16+
}
1517
}
1618
}

handlers/post.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package handlers
2+
3+
import (
4+
"fmt"
5+
"github.com/xueyuanjun/chitchat/models"
6+
"net/http"
7+
)
8+
9+
// POST /thread/post
10+
// 在指定群组下创建新主题
11+
func PostThread(writer http.ResponseWriter, request *http.Request) {
12+
sess, err := session(writer, request)
13+
if err != nil {
14+
http.Redirect(writer, request, "/login", 302)
15+
} else {
16+
err = request.ParseForm()
17+
if err != nil {
18+
fmt.Println("Cannot parse form")
19+
}
20+
user, err := sess.User()
21+
if err != nil {
22+
fmt.Println("Cannot get user from session")
23+
}
24+
body := request.PostFormValue("body")
25+
uuid := request.PostFormValue("uuid")
26+
thread, err := models.ThreadByUUID(uuid)
27+
if err != nil {
28+
fmt.Println("Cannot read thread")
29+
}
30+
if _, err := user.CreatePost(thread, body); err != nil {
31+
fmt.Println("Cannot create post")
32+
}
33+
url := fmt.Sprint("/thread/read?id=", uuid)
34+
http.Redirect(writer, request, url, 302)
35+
}
36+
}

handlers/thread.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package handlers
2+
3+
import (
4+
"fmt"
5+
"github.com/xueyuanjun/chitchat/models"
6+
"net/http"
7+
)
8+
9+
// GET /threads/new
10+
// 创建群组页面
11+
func NewThread(writer http.ResponseWriter, request *http.Request) {
12+
_, err := session(writer, request)
13+
if err != nil {
14+
http.Redirect(writer, request, "/login", 302)
15+
} else {
16+
generateHTML(writer, nil, "layout", "auth.navbar", "new.thread")
17+
}
18+
}
19+
20+
// POST /thread/create
21+
// 执行群组创建逻辑
22+
func CreateThread(writer http.ResponseWriter, request *http.Request) {
23+
sess, err := session(writer, request)
24+
if err != nil {
25+
http.Redirect(writer, request, "/login", 302)
26+
} else {
27+
err = request.ParseForm()
28+
if err != nil {
29+
fmt.Println("Cannot parse form")
30+
}
31+
user, err := sess.User()
32+
if err != nil {
33+
fmt.Println("Cannot get user from session")
34+
}
35+
topic := request.PostFormValue("topic")
36+
if _, err := user.CreateThread(topic); err != nil {
37+
fmt.Println("Cannot create thread")
38+
}
39+
http.Redirect(writer, request, "/", 302)
40+
}
41+
}
42+
43+
// GET /thread/read
44+
// 通过 ID 渲染指定群组页面
45+
func ReadThread(writer http.ResponseWriter, request *http.Request) {
46+
vals := request.URL.Query()
47+
uuid := vals.Get("id")
48+
thread, err := models.ThreadByUUID(uuid)
49+
if err != nil {
50+
fmt.Println("Cannot read thread")
51+
} else {
52+
_, err := session(writer, request)
53+
if err != nil {
54+
generateHTML(writer, &thread, "layout", "navbar", "thread")
55+
} else {
56+
generateHTML(writer, &thread, "layout", "auth.navbar", "auth.thread")
57+
}
58+
}
59+
}

routes/routes.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,58 @@ var webRoutes = WebRoutes{
2424
"/",
2525
handlers.Index,
2626
},
27+
{
28+
"signup",
29+
"GET",
30+
"/signup",
31+
handlers.Signup,
32+
},
33+
{
34+
"signupAccount",
35+
"POST",
36+
"/signup_account",
37+
handlers.SignupAccount,
38+
},
39+
{
40+
"login",
41+
"GET",
42+
"/login",
43+
handlers.Login,
44+
},
45+
{
46+
"auth",
47+
"POST",
48+
"/authenticate",
49+
handlers.Authenticate,
50+
},
51+
{
52+
"logout",
53+
"GET",
54+
"/logout",
55+
handlers.Logout,
56+
},
57+
{
58+
"newThread",
59+
"GET",
60+
"/thread/new",
61+
handlers.NewThread,
62+
},
63+
{
64+
"createThread",
65+
"POST",
66+
"/thread/create",
67+
handlers.CreateThread,
68+
},
69+
{
70+
"readThread",
71+
"GET",
72+
"/thread/read",
73+
handlers.ReadThread,
74+
},
75+
{
76+
"postThread",
77+
"POST",
78+
"/thread/post",
79+
handlers.PostThread,
80+
},
2781
}

views/auth.layout.html

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{{ define "layout" }}
2+
3+
<!DOCTYPE html>
4+
<html lang="en">
5+
<head>
6+
<meta charset="utf-8">
7+
<meta http-equiv="X-UA-Compatible" content="IE=9">
8+
<meta name="viewport" content="width=device-width, initial-scale=1">
9+
<title>ChitChat</title>
10+
<link href="/static/css/bootstrap.min.css" rel="stylesheet">
11+
<link href="/static/css/font-awesome.min.css" rel="stylesheet">
12+
<link href="/static/css/login.css" rel="stylesheet">
13+
</head>
14+
<body>
15+
<div class="container">
16+
17+
{{ template "content" . }}
18+
19+
</div> <!-- /container -->
20+
21+
<script src="/static/js/jquery-2.1.1.min.js"></script>
22+
<script src="/static/js/bootstrap.min.js"></script>
23+
</body>
24+
</html>
25+
26+
{{ end }}

views/auth.navbar.html

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{{ define "navbar" }}
2+
<div class="navbar navbar-default navbar-static-top" role="navigation">
3+
<div class="container">
4+
<div class="navbar-header">
5+
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target=".navbar-collapse">
6+
<span class="sr-only">Toggle navigation</span>
7+
<span class="icon-bar"></span>
8+
<span class="icon-bar"></span>
9+
<span class="icon-bar"></span>
10+
</button>
11+
<a class="navbar-brand" href="/">
12+
<i class="fa fa-comments-o"></i>
13+
ChitChat
14+
</a>
15+
</div>
16+
<div class="navbar-collapse collapse">
17+
<ul class="nav navbar-nav">
18+
<li><a href="/">Home</a></li>
19+
</ul>
20+
<ul class="nav navbar-nav navbar-right">
21+
<li><a href="/logout">Logout</a></li>
22+
</ul>
23+
</div>
24+
</div>
25+
</div>
26+
{{ end }}

0 commit comments

Comments
 (0)