Add notifications
This commit is contained in:
parent
6545cbdff8
commit
e68f41445e
8 changed files with 114 additions and 63 deletions
6
admin.go
6
admin.go
|
@ -9,7 +9,8 @@ import (
|
|||
|
||||
func deleteHandler(coll *mgo.Collection) func(http.ResponseWriter, *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
if SessionUser(r) == "" {
|
||||
sess := GetSession(r)
|
||||
if sess.User == "" {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
|
@ -24,7 +25,8 @@ func deleteHandler(coll *mgo.Collection) func(http.ResponseWriter, *http.Request
|
|||
os.RemoveAll(book.Cover[1:])
|
||||
os.RemoveAll(book.CoverSmall[1:])
|
||||
coll.Remove(bson.M{"_id": id})
|
||||
sess.Notify("Removed book!", "The book '"+book.Title+"' it's completly removed", "success")
|
||||
sess.Save(w, r)
|
||||
http.Redirect(w, r, "/", 307)
|
||||
//TODO: notify deleted
|
||||
}
|
||||
}
|
||||
|
|
17
database.go
17
database.go
|
@ -1,7 +1,12 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"labix.org/v2/mgo"
|
||||
"labix.org/v2/mgo/bson"
|
||||
)
|
||||
|
||||
type Book struct {
|
||||
Id string `bson:"_id"`
|
||||
Id string `bson:"_id"`
|
||||
Title string
|
||||
Author []string
|
||||
Contributor string
|
||||
|
@ -22,3 +27,13 @@ type Book struct {
|
|||
CoverSmall string
|
||||
Keywords []string
|
||||
}
|
||||
|
||||
func GetBook(coll *mgo.Collection, query bson.M) ([]Book, error) {
|
||||
var books []Book
|
||||
err := coll.Find(query).All(&books)
|
||||
for i, b := range books {
|
||||
books[i].Id = bson.ObjectId(b.Id).Hex()
|
||||
}
|
||||
return books, err
|
||||
|
||||
}
|
||||
|
|
17
search.go
17
search.go
|
@ -31,12 +31,12 @@ func buildQuery(q string) bson.M {
|
|||
}
|
||||
|
||||
type searchData struct {
|
||||
S Status
|
||||
Found int
|
||||
Books []Book
|
||||
Page int
|
||||
Next string
|
||||
Prev string
|
||||
S Status
|
||||
Found int
|
||||
Books []Book
|
||||
Page int
|
||||
Next string
|
||||
Prev string
|
||||
}
|
||||
|
||||
func searchHandler(coll *mgo.Collection) func(http.ResponseWriter, *http.Request) {
|
||||
|
@ -47,8 +47,7 @@ func searchHandler(coll *mgo.Collection) func(http.ResponseWriter, *http.Request
|
|||
return
|
||||
}
|
||||
req := strings.Join(r.Form["q"], " ")
|
||||
var res []Book
|
||||
coll.Find(buildQuery(req)).All(&res)
|
||||
res, _ := GetBook(coll, buildQuery(req))
|
||||
|
||||
page := 0
|
||||
if len(r.Form["p"]) != 0 {
|
||||
|
@ -59,7 +58,7 @@ func searchHandler(coll *mgo.Collection) func(http.ResponseWriter, *http.Request
|
|||
}
|
||||
|
||||
var data searchData
|
||||
data.S.User = SessionUser(r)
|
||||
data.S = GetStatus(w, r)
|
||||
data.S.Search = req
|
||||
data.Found = len(res)
|
||||
if len(res) > ITEMS_PAGE*(page+1) {
|
||||
|
|
82
session.go
82
session.go
|
@ -1,43 +1,65 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"code.google.com/p/gorilla/sessions"
|
||||
"code.google.com/p/gorilla/securecookie"
|
||||
"code.google.com/p/gorilla/securecookie"
|
||||
"code.google.com/p/gorilla/sessions"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
var sesStore = sessions.NewCookieStore(securecookie.GenerateRandomKey(64))
|
||||
|
||||
func CreateSession(user string, w http.ResponseWriter, r *http.Request) {
|
||||
session, _ := sesStore.Get(r, "admin")
|
||||
session.Values["user"] = user
|
||||
session.Save(r, w)
|
||||
type Notification struct {
|
||||
Title string
|
||||
Msg string
|
||||
Type string /* error, info or success */
|
||||
}
|
||||
|
||||
func SessionUser(r *http.Request) string {
|
||||
session, err := sesStore.New(r, "admin")
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
if session.IsNew {
|
||||
return ""
|
||||
}
|
||||
user, ok := session.Values["user"].(string)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
return user
|
||||
type Session struct {
|
||||
User string
|
||||
Notif []Notification
|
||||
S *sessions.Session
|
||||
}
|
||||
|
||||
func LogOut(w http.ResponseWriter, r *http.Request) {
|
||||
session, err := sesStore.Get(r, "admin")
|
||||
if err != nil {
|
||||
return
|
||||
func getNotif(session *sessions.Session) []Notification {
|
||||
msgs := session.Flashes("nMsg")
|
||||
titles := session.Flashes("nTitle")
|
||||
tpes := session.Flashes("nType")
|
||||
notif := make([]Notification, len(msgs))
|
||||
for i, m := range msgs {
|
||||
msg, _ := m.(string)
|
||||
title, _ := titles[i].(string)
|
||||
tpe, _ := tpes[i].(string)
|
||||
notif[i] = Notification{title, msg, tpe}
|
||||
}
|
||||
if session.IsNew {
|
||||
return
|
||||
}
|
||||
session.Values["user"] = ""
|
||||
session.Options.MaxAge = -1
|
||||
session.Save(r, w)
|
||||
return notif
|
||||
}
|
||||
|
||||
func GetSession(r *http.Request) (s *Session) {
|
||||
s = new(Session)
|
||||
var err error
|
||||
s.S, err = sesStore.Get(r, "session")
|
||||
if err == nil && !s.S.IsNew {
|
||||
s.User, _ = s.S.Values["user"].(string)
|
||||
s.Notif = getNotif(s.S)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Session) LogIn(user string) {
|
||||
s.User = user
|
||||
s.S.Values["user"] = user
|
||||
}
|
||||
|
||||
func (s *Session) LogOut() {
|
||||
s.S.Values["user"] = ""
|
||||
}
|
||||
|
||||
func (s *Session) Notify(title, msg, tpe string) {
|
||||
s.S.AddFlash(msg, "nMsg")
|
||||
s.S.AddFlash(title, "nTitle")
|
||||
s.S.AddFlash(tpe, "nType")
|
||||
}
|
||||
|
||||
func (s *Session) Save(w http.ResponseWriter, r *http.Request) {
|
||||
sesStore.Save(r, w, s.S)
|
||||
}
|
||||
|
|
10
template.go
10
template.go
|
@ -12,11 +12,21 @@ const (
|
|||
type Status struct {
|
||||
Search string
|
||||
User string
|
||||
Notif []Notification
|
||||
Home bool
|
||||
About bool
|
||||
Upload bool
|
||||
}
|
||||
|
||||
func GetStatus(w http.ResponseWriter, r *http.Request) Status {
|
||||
var s Status
|
||||
sess := GetSession(r)
|
||||
sess.Save(w, r)
|
||||
s.User = sess.User
|
||||
s.Notif = sess.Notif
|
||||
return s
|
||||
}
|
||||
|
||||
func loadTemplate(w http.ResponseWriter, tmpl string, data interface{}) {
|
||||
// TODO: when finish devel conver to global:
|
||||
var templates = template.Must(template.ParseFiles(TEMPLATE_DIR+"header.html",
|
||||
|
|
|
@ -78,11 +78,9 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
{{with .Notif}}
|
||||
{{if .Msg}}
|
||||
<div class="alert alert-{{.Tpe}}">
|
||||
{{range .Notif}}
|
||||
<div class="alert alert-{{.Type}}">
|
||||
<button class="close" data-dismiss="alert">×</button>
|
||||
<strong>{{.Title}}</strong> {{.Msg}}
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
|
33
trantor.go
33
trantor.go
|
@ -21,13 +21,15 @@ type aboutData struct {
|
|||
|
||||
func aboutHandler(w http.ResponseWriter, r *http.Request) {
|
||||
var data aboutData
|
||||
data.S.User = SessionUser(r)
|
||||
data.S.About = true
|
||||
data.S = GetStatus(w, r)
|
||||
loadTemplate(w, "about", data)
|
||||
}
|
||||
|
||||
func logoutHandler(w http.ResponseWriter, r *http.Request) {
|
||||
LogOut(w, r)
|
||||
sess := GetSession(r)
|
||||
sess.LogOut()
|
||||
sess.Notify("Log out!", "Bye bye "+sess.User, "success")
|
||||
sess.Save(w, r)
|
||||
http.Redirect(w, r, "/", 307)
|
||||
}
|
||||
|
||||
|
@ -38,32 +40,35 @@ func loginHandler(coll *mgo.Collection) func(http.ResponseWriter, *http.Request)
|
|||
pass := r.FormValue("pass")
|
||||
h := md5.New()
|
||||
hash := h.Sum(([]byte)(PASS_SALT + pass))
|
||||
n, _ := coll.Find(bson.M{"user":user, "pass":hash}).Count()
|
||||
n, _ := coll.Find(bson.M{"user": user, "pass": hash}).Count()
|
||||
sess := GetSession(r)
|
||||
if n != 0 {
|
||||
// TODO: display success
|
||||
CreateSession(user, w, r)
|
||||
sess.LogIn(user)
|
||||
sess.Notify("Successful login!", "Welcome "+user, "success")
|
||||
} else {
|
||||
// TODO: display error
|
||||
sess.Notify("Invalid login!", "user or password invalid", "error")
|
||||
}
|
||||
sess.Save(w, r)
|
||||
}
|
||||
http.Redirect(w, r, "/", 307)
|
||||
http.Redirect(w, r, r.Referer(), 307)
|
||||
}
|
||||
}
|
||||
|
||||
type bookData struct {
|
||||
S Status
|
||||
Book Book
|
||||
S Status
|
||||
Book Book
|
||||
}
|
||||
|
||||
func bookHandler(coll *mgo.Collection) func(http.ResponseWriter, *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var data bookData
|
||||
data.S.User = SessionUser(r)
|
||||
if coll.Find(bson.M{"title": r.URL.Path[len("/book/"):]}).One(&data.Book) != nil {
|
||||
data.S = GetStatus(w, r)
|
||||
books, err := GetBook(coll, bson.M{"title": r.URL.Path[len("/book/"):]})
|
||||
if err != nil || len(books) == 0 {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
data.Book.Id = bson.ObjectId(data.Book.Id).Hex()
|
||||
data.Book = books[0]
|
||||
loadTemplate(w, "book", data)
|
||||
}
|
||||
}
|
||||
|
@ -82,7 +87,7 @@ type indexData struct {
|
|||
func indexHandler(coll *mgo.Collection) func(http.ResponseWriter, *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var data indexData
|
||||
data.S.User = SessionUser(r)
|
||||
data.S = GetStatus(w, r)
|
||||
data.S.Home = true
|
||||
data.Count, _ = coll.Count()
|
||||
coll.Find(bson.M{}).Sort("-_id").Limit(6).All(&data.Books)
|
||||
|
|
|
@ -43,14 +43,14 @@ func storeFile(r *http.Request) error {
|
|||
}
|
||||
|
||||
type uploadData struct {
|
||||
S Status
|
||||
Msg string
|
||||
S Status
|
||||
Msg string
|
||||
}
|
||||
|
||||
func uploadHandler(coll *mgo.Collection) func(http.ResponseWriter, *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var data uploadData
|
||||
data.S.User = SessionUser(r)
|
||||
data.S = GetStatus(w, r)
|
||||
data.S.Upload = true
|
||||
data.Msg = ""
|
||||
if r.Method == "POST" {
|
||||
|
|
Reference in a new issue