From e68f41445e768d0ad962d819bdf02d26e0900a72 Mon Sep 17 00:00:00 2001 From: Las Zenow Date: Sun, 19 Aug 2012 02:29:34 +0200 Subject: [PATCH] Add notifications --- admin.go | 6 ++-- database.go | 17 ++++++++- search.go | 17 +++++---- session.go | 82 +++++++++++++++++++++++++++---------------- template.go | 10 ++++++ templates/header.html | 6 ++-- trantor.go | 33 +++++++++-------- upload.go | 6 ++-- 8 files changed, 114 insertions(+), 63 deletions(-) diff --git a/admin.go b/admin.go index b4631b2..c3661a2 100644 --- a/admin.go +++ b/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 } } diff --git a/database.go b/database.go index cec0b25..a956b6b 100644 --- a/database.go +++ b/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 + +} diff --git a/search.go b/search.go index a48a834..4f0a1af 100644 --- a/search.go +++ b/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) { diff --git a/session.go b/session.go index 0616615..c311110 100644 --- a/session.go +++ b/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) } diff --git a/template.go b/template.go index 54d55e3..77f619d 100644 --- a/template.go +++ b/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", diff --git a/templates/header.html b/templates/header.html index 5d1d08d..c36bbde 100644 --- a/templates/header.html +++ b/templates/header.html @@ -78,11 +78,9 @@
-{{with .Notif}} -{{if .Msg}} -
+{{range .Notif}} +
{{.Title}} {{.Msg}}
{{end}} -{{end}} diff --git a/trantor.go b/trantor.go index 449ca14..6fbb3be 100644 --- a/trantor.go +++ b/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) diff --git a/upload.go b/upload.go index 1d7c1b6..5f629fd 100644 --- a/upload.go +++ b/upload.go @@ -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" {