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