Add notifications

This commit is contained in:
Las Zenow 2012-08-19 02:29:34 +02:00
parent 6545cbdff8
commit e68f41445e
8 changed files with 114 additions and 63 deletions

View file

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

View file

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

View file

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

View file

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

View file

@ -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",

View file

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

View file

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

View file

@ -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" {