From 840fd3ed470a483e16b7a7ed3cd0a4ba6f1adfd7 Mon Sep 17 00:00:00 2001
From: Las Zenow
Date: Wed, 12 Sep 2012 00:19:19 +0200
Subject: [PATCH] New database squema
The collection new is removed, now the books have a field "active" set to true
if the book was aproved.
For update the database:
db.books.update({}, {$set: {active: true}}, true, true)
---
admin.go | 261 +++++++++++++++++++++------------------------
database.go | 76 ++++++++++++-
reader.go | 113 +++++++++-----------
search.go | 61 +++++------
templates/new.html | 11 +-
trantor.go | 135 ++++++++++-------------
upload.go | 55 +++++-----
7 files changed, 366 insertions(+), 346 deletions(-)
diff --git a/admin.go b/admin.go
index f8e7047..47ead93 100644
--- a/admin.go
+++ b/admin.go
@@ -1,7 +1,6 @@
package main
import (
- "labix.org/v2/mgo"
"labix.org/v2/mgo/bson"
"net/http"
"os"
@@ -10,55 +9,51 @@ import (
"strings"
)
-func deleteHandler(coll *mgo.Collection, url string) func(http.ResponseWriter, *http.Request) {
- return func(w http.ResponseWriter, r *http.Request) {
- sess := GetSession(r)
- if sess.User == "" {
- http.NotFound(w, r)
- return
- }
-
- // cutre hack: /delete/ and /delnew/ have the same lenght:
- id := bson.ObjectIdHex(r.URL.Path[len("/delete/"):])
- books, _, err := GetBook(coll, bson.M{"_id": id})
- if err != nil {
- http.NotFound(w, r)
- return
- }
- book := books[0]
- if book.Cover != "" {
- os.RemoveAll(book.Cover[1:])
- }
- if book.CoverSmall != "" {
- os.RemoveAll(book.CoverSmall[1:])
- }
- os.RemoveAll(book.Path)
- 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, url, 307)
+func deleteHandler(w http.ResponseWriter, r *http.Request) {
+ sess := GetSession(r)
+ if sess.User == "" {
+ http.NotFound(w, r)
+ return
}
+
+ // cutre hack: /delete/ and /delnew/ have the same lenght:
+ id := bson.ObjectIdHex(r.URL.Path[len("/delete/"):])
+ books, _, err := db.GetBooks(bson.M{"_id": id})
+ if err != nil {
+ http.NotFound(w, r)
+ return
+ }
+ book := books[0]
+ if book.Cover != "" {
+ os.RemoveAll(book.Cover[1:])
+ }
+ if book.CoverSmall != "" {
+ os.RemoveAll(book.CoverSmall[1:])
+ }
+ os.RemoveAll(book.Path)
+ db.RemoveBook(id)
+ sess.Notify("Removed book!", "The book '"+book.Title+"' it's completly removed", "success")
+ sess.Save(w, r)
+ http.Redirect(w, r, "/", 307) //FIXME: if new return to /new/
}
-func editHandler(coll *mgo.Collection) func(http.ResponseWriter, *http.Request) {
- return func(w http.ResponseWriter, r *http.Request) {
- sess := GetSession(r)
- if sess.User == "" {
- http.NotFound(w, r)
- return
- }
- id := bson.ObjectIdHex(r.URL.Path[len("/edit/"):])
- books, _, err := GetBook(coll, bson.M{"_id": id})
- if err != nil {
- http.NotFound(w, r)
- return
- }
-
- var data bookData
- data.Book = books[0]
- data.S = GetStatus(w, r)
- loadTemplate(w, "edit", data)
+func editHandler(w http.ResponseWriter, r *http.Request) {
+ sess := GetSession(r)
+ if sess.User == "" {
+ http.NotFound(w, r)
+ return
}
+ id := bson.ObjectIdHex(r.URL.Path[len("/edit/"):])
+ books, _, err := db.GetBooks(bson.M{"_id": id})
+ if err != nil {
+ http.NotFound(w, r)
+ return
+ }
+
+ var data bookData
+ data.Book = books[0]
+ data.S = GetStatus(w, r)
+ loadTemplate(w, "edit", data)
}
func cleanEmptyStr(s []string) []string {
@@ -71,45 +66,43 @@ func cleanEmptyStr(s []string) []string {
return res
}
-func saveHandler(coll *mgo.Collection) func(http.ResponseWriter, *http.Request) {
- return func(w http.ResponseWriter, r *http.Request) {
- if r.Method != "POST" {
- http.NotFound(w, r)
- return
- }
- sess := GetSession(r)
- if sess.User == "" {
- http.NotFound(w, r)
- return
- }
-
- idStr := r.URL.Path[len("/save/"):]
- id := bson.ObjectIdHex(idStr)
- title := r.FormValue("title")
- publisher := r.FormValue("publisher")
- date := r.FormValue("date")
- description := r.FormValue("description")
- author := cleanEmptyStr(r.Form["author"])
- subject := cleanEmptyStr(r.Form["subject"])
- lang := cleanEmptyStr(r.Form["lang"])
- book := map[string]interface{}{"title": title,
- "publisher": publisher,
- "date": date,
- "description": description,
- "author": author,
- "subject": subject,
- "lang": lang}
- book["keywords"] = keywords(book)
- err := coll.Update(bson.M{"_id": id}, bson.M{"$set": book})
- if err != nil {
- http.NotFound(w, r)
- return
- }
-
- sess.Notify("Book Modified!", "", "success")
- sess.Save(w, r)
- http.Redirect(w, r, "/book/"+idStr, 307)
+func saveHandler(w http.ResponseWriter, r *http.Request) {
+ if r.Method != "POST" {
+ http.NotFound(w, r)
+ return
}
+ sess := GetSession(r)
+ if sess.User == "" {
+ http.NotFound(w, r)
+ return
+ }
+
+ idStr := r.URL.Path[len("/save/"):]
+ id := bson.ObjectIdHex(idStr)
+ title := r.FormValue("title")
+ publisher := r.FormValue("publisher")
+ date := r.FormValue("date")
+ description := r.FormValue("description")
+ author := cleanEmptyStr(r.Form["author"])
+ subject := cleanEmptyStr(r.Form["subject"])
+ lang := cleanEmptyStr(r.Form["lang"])
+ book := map[string]interface{}{"title": title,
+ "publisher": publisher,
+ "date": date,
+ "description": description,
+ "author": author,
+ "subject": subject,
+ "lang": lang}
+ book["keywords"] = keywords(book)
+ err := db.UpdateBook(id, book)
+ if err != nil {
+ http.NotFound(w, r)
+ return
+ }
+
+ sess.Notify("Book Modified!", "", "success")
+ sess.Save(w, r)
+ http.Redirect(w, r, "/book/"+idStr, 307)
}
type newBook struct {
@@ -123,31 +116,29 @@ type newData struct {
Books []newBook
}
-func newHandler(coll *mgo.Collection, booksColl *mgo.Collection) func(http.ResponseWriter, *http.Request) {
- return func(w http.ResponseWriter, r *http.Request) {
- if len(r.URL.Path) > len("/new/") {
- http.ServeFile(w, r, r.URL.Path[1:])
- return
- }
-
- sess := GetSession(r)
- if sess.User == "" {
- http.NotFound(w, r)
- return
- }
-
- res, num, _ := GetBook(coll, bson.M{})
- var data newData
- data.S = GetStatus(w, r)
- data.Found = num
- data.Books = make([]newBook, num)
- for i, b := range res {
- data.Books[i].B = b
- _, data.Books[i].TitleFound, _ = GetBook(booksColl, buildQuery("title:" + b.Title), 1)
- _, data.Books[i].AuthorFound, _ = GetBook(booksColl, buildQuery("author:" + strings.Join(b.Author, " author:")), 1)
- }
- loadTemplate(w, "new", data)
+func newHandler(w http.ResponseWriter, r *http.Request) {
+ sess := GetSession(r)
+ if sess.User == "" {
+ http.NotFound(w, r)
+ return
}
+
+ if len(r.URL.Path) > len("/new/") {
+ http.ServeFile(w, r, r.URL.Path[1:])
+ return
+ }
+
+ res, num, _ := db.GetNewBooks()
+ var data newData
+ data.S = GetStatus(w, r)
+ data.Found = num
+ data.Books = make([]newBook, num)
+ for i, b := range res {
+ data.Books[i].B = b
+ _, data.Books[i].TitleFound, _ = db.GetBooks(buildQuery("title:" + b.Title), 1)
+ _, data.Books[i].AuthorFound, _ = db.GetBooks(buildQuery("author:" + strings.Join(b.Author, " author:")), 1)
+ }
+ loadTemplate(w, "new", data)
}
func ValidFileName(path string, title string, extension string) string {
@@ -162,34 +153,30 @@ func ValidFileName(path string, title string, extension string) string {
return file
}
-func storeHandler(newColl, coll *mgo.Collection) func(http.ResponseWriter, *http.Request) {
- return func(w http.ResponseWriter, r *http.Request) {
- sess := GetSession(r)
- if sess.User == "" {
- http.NotFound(w, r)
- return
- }
-
- id := bson.ObjectIdHex(r.URL.Path[len("/store/"):])
- var book bson.M
- err := newColl.Find(bson.M{"_id": id}).One(&book)
- if err != nil {
- http.NotFound(w, r)
- return
- }
-
- title, _ := book["title"].(string)
- path := ValidFileName(BOOKS_PATH + title[:1], title, ".epub")
-
- oldPath, _ := book["path"].(string)
- os.Mkdir(BOOKS_PATH+title[:1], os.ModePerm)
- cmd := exec.Command("mv", oldPath, path)
- cmd.Run()
- book["path"] = path
- coll.Insert(book)
- newColl.Remove(bson.M{"_id": id})
- sess.Notify("Store book!", "The book '"+title+"' it's stored for public download", "success")
- sess.Save(w, r)
- http.Redirect(w, r, "/new/", 307)
+func storeHandler(w http.ResponseWriter, r *http.Request) {
+ sess := GetSession(r)
+ if sess.User == "" {
+ http.NotFound(w, r)
+ return
}
+
+ id := bson.ObjectIdHex(r.URL.Path[len("/store/"):])
+ books, _, err := db.GetBooks(bson.M{"_id": id})
+ if err != nil {
+ http.NotFound(w, r)
+ return
+ }
+ book := books[0]
+
+ title := book.Title
+ path := ValidFileName(BOOKS_PATH + title[:1], title, ".epub")
+
+ oldPath := book.Path
+ os.Mkdir(BOOKS_PATH+title[:1], os.ModePerm)
+ cmd := exec.Command("mv", oldPath, path)
+ cmd.Run()
+ db.UpdateBook(id, bson.M{"active": true, "path": path})
+ sess.Notify("Store book!", "The book '"+title+"' it's stored for public download", "success")
+ sess.Save(w, r)
+ http.Redirect(w, r, "/new/", 307)
}
diff --git a/database.go b/database.go
index 2fff90b..f4b9459 100644
--- a/database.go
+++ b/database.go
@@ -1,11 +1,15 @@
package main
import (
+ "crypto/md5"
"labix.org/v2/mgo"
"labix.org/v2/mgo/bson"
"sort"
)
+var db *DB
+
+
type Book struct {
Id string `bson:"_id"`
Title string
@@ -26,14 +30,60 @@ type Book struct {
Path string
Cover string
CoverSmall string
+ Active bool
Keywords []string
}
+type DB struct {
+ session *mgo.Session
+ books *mgo.Collection
+ user *mgo.Collection
+}
+
+func initDB() *DB {
+ var err error
+ d := new(DB)
+ d.session, err = mgo.Dial(DB_IP)
+ if err != nil {
+ panic(err)
+ }
+
+ d.books = d.session.DB(DB_NAME).C(BOOKS_COLL)
+ d.user = d.session.DB(DB_NAME).C(USERS_COLL)
+ return d
+}
+
+func (d *DB) Close() {
+ d.session.Close()
+}
+
+func (d *DB) UserValid(user string, pass string) bool {
+ h := md5.New()
+ hash := h.Sum(([]byte)(PASS_SALT + pass))
+ n, err := d.user.Find(bson.M{"user": user, "pass": hash}).Count()
+ if err != nil {
+ return false
+ }
+ return n != 0
+}
+
+func (d *DB) InsertBook(book interface{}) error {
+ return d.books.Insert(book)
+}
+
+func (d *DB) RemoveBook(id bson.ObjectId) error {
+ return d.books.Remove(bson.M{"_id": id})
+}
+
+func (d *DB) UpdateBook(id bson.ObjectId, book interface{}) error {
+ return d.books.Update(bson.M{"_id": id}, bson.M{"$set": book})
+}
+
/* optional parameters: length and start index
*
* Returns: list of books, number found and err
*/
-func GetBook(coll *mgo.Collection, query bson.M, r ...int) (books []Book, num int, err error) {
+func (d *DB) GetBooks(query bson.M, r ...int) (books []Book, num int, err error) {
var start, length int
if len(r) > 0 {
length = r[0]
@@ -41,7 +91,7 @@ func GetBook(coll *mgo.Collection, query bson.M, r ...int) (books []Book, num in
start = r[1]
}
}
- q := coll.Find(query).Sort("-_id")
+ q := d.books.Find(query).Sort("-_id")
num, err = q.Count()
if err != nil {
return
@@ -58,7 +108,23 @@ func GetBook(coll *mgo.Collection, query bson.M, r ...int) (books []Book, num in
books[i].Id = bson.ObjectId(b.Id).Hex()
}
return
+}
+/* Returns: list of books, number found and err
+ */
+func (d *DB) GetNewBooks()(books []Book, num int, err error) {
+ var q *mgo.Query
+ q = d.books.Find(bson.M{"$nor": []bson.M{{"active": true}}}).Sort("-_id")
+ num, err = q.Count()
+ if err != nil {
+ return
+ }
+
+ err = q.All(&books)
+ for i, b := range books {
+ books[i].Id = bson.ObjectId(b.Id).Hex()
+ }
+ return
}
type tagsList []struct {
@@ -78,11 +144,11 @@ func (t tagsList) Swap(i, j int) {
t[j] = aux
}
-func GetTags(coll *mgo.Collection) (tagsList, error) {
+func (d *DB) GetTags() (tagsList, error) {
// TODO: cache the tags
var mr mgo.MapReduce
mr.Map = "function() { " +
- "this.subject.forEach(function(s) { emit(s, 1); });" +
+ "if (this.active) { this.subject.forEach(function(s) { emit(s, 1); }); }" +
"}"
mr.Reduce = "function(tag, vals) { " +
"var count = 0;" +
@@ -90,7 +156,7 @@ func GetTags(coll *mgo.Collection) (tagsList, error) {
"return count;" +
"}"
var result tagsList
- _, err := coll.Find(nil).MapReduce(&mr, &result)
+ _, err := d.books.Find(nil).MapReduce(&mr, &result)
if err == nil {
sort.Sort(result)
}
diff --git a/reader.go b/reader.go
index e1bea21..71884a7 100644
--- a/reader.go
+++ b/reader.go
@@ -2,7 +2,6 @@ package main
import (
"git.gitorious.org/go-pkg/epub.git"
- "labix.org/v2/mgo"
"labix.org/v2/mgo/bson"
"net/http"
"regexp"
@@ -116,72 +115,62 @@ func chapterList(e *epub.Epub, file string, id string, base string) (string, str
return next, prev, chapters
}
-func readHandler(coll *mgo.Collection) func(http.ResponseWriter, *http.Request) {
- return func(w http.ResponseWriter, r *http.Request) {
- base, id, file := parseUrl(r.URL.Path)
- if base == "/readnew/" {
- sess := GetSession(r)
- if sess.User == "" {
- http.NotFound(w, r)
- return
- }
- }
- books, _, err := GetBook(coll, bson.M{"_id": bson.ObjectIdHex(id)})
- if err != nil || len(books) == 0 {
+func readHandler(w http.ResponseWriter, r *http.Request) {
+ base, id, file := parseUrl(r.URL.Path)
+ books, _, err := db.GetBooks(bson.M{"_id": bson.ObjectIdHex(id)})
+ if err != nil || len(books) == 0 {
+ http.NotFound(w, r)
+ return
+ }
+
+ var data readData
+ data.Book = books[0]
+ if ! data.Book.Active {
+ sess := GetSession(r)
+ if sess.User == "" {
http.NotFound(w, r)
return
}
- book := books[0]
- e, _ := epub.Open(book.Path, 0)
- defer e.Close()
- if file == "" {
- it := e.Iterator(epub.EITERATOR_LINEAR)
- defer it.Close()
- http.Redirect(w, r, base+id+"/"+it.CurrUrl(), 307)
- return
- }
-
- var data readData
- data.S = GetStatus(w, r)
- data.Book = book
- data.Next, data.Prev, data.Chapters = chapterList(e, file, id, base)
- if base == "/readnew/" {
- data.Back = "/new/"
- } else {
- data.Back = "/book/" + id
- }
- baseContent := "/content/"
- if base == "/readnew/" {
- baseContent = "/contentnew/"
- }
- data.Content = genLink(id, baseContent, file)
- loadTemplate(w, "read", data)
+ data.Back = "/new/"
+ } else {
+ data.Back = "/book/" + id
}
+ e, _ := epub.Open(data.Book.Path, 0)
+ defer e.Close()
+ if file == "" {
+ it := e.Iterator(epub.EITERATOR_LINEAR)
+ defer it.Close()
+ http.Redirect(w, r, base+id+"/"+it.CurrUrl(), 307)
+ return
+ }
+
+ data.S = GetStatus(w, r)
+ data.Next, data.Prev, data.Chapters = chapterList(e, file, id, base)
+ data.Content = genLink(id, "/content/", file)
+ loadTemplate(w, "read", data)
}
-func contentHandler(coll *mgo.Collection) func(http.ResponseWriter, *http.Request) {
- return func(w http.ResponseWriter, r *http.Request) {
- base, id, file := parseUrl(r.URL.Path)
- if base == "/contentnew/" {
- sess := GetSession(r)
- if sess.User == "" {
- http.NotFound(w, r)
- return
- }
- }
- books, _, err := GetBook(coll, bson.M{"_id": bson.ObjectIdHex(id)})
- if err != nil || len(books) == 0 {
- http.NotFound(w, r)
- return
- }
- book := books[0]
- e, _ := epub.Open(book.Path, 0)
- defer e.Close()
- if file == "" {
- http.NotFound(w, r)
- return
- }
-
- w.Write(e.Data(file))
+func contentHandler(w http.ResponseWriter, r *http.Request) {
+ _, id, file := parseUrl(r.URL.Path)
+ books, _, err := db.GetBooks(bson.M{"_id": bson.ObjectIdHex(id)})
+ if err != nil || len(books) == 0 {
+ http.NotFound(w, r)
+ return
}
+ book := books[0]
+ if ! book.Active {
+ sess := GetSession(r)
+ if sess.User == "" {
+ http.NotFound(w, r)
+ return
+ }
+ }
+ e, _ := epub.Open(book.Path, 0)
+ defer e.Close()
+ if file == "" {
+ http.NotFound(w, r)
+ return
+ }
+
+ w.Write(e.Data(file))
}
diff --git a/search.go b/search.go
index b245e98..02fdaa1 100644
--- a/search.go
+++ b/search.go
@@ -1,7 +1,6 @@
package main
import (
- "labix.org/v2/mgo"
"labix.org/v2/mgo/bson"
"net/http"
"strconv"
@@ -10,7 +9,7 @@ import (
func buildQuery(q string) bson.M {
var reg []bson.RegEx
- query := bson.M{}
+ query := bson.M{"active": true}
words := strings.Split(q, " ")
for _, w := range words {
tag := strings.SplitN(w, ":", 2)
@@ -35,35 +34,33 @@ type searchData struct {
Prev string
}
-func searchHandler(coll *mgo.Collection) func(http.ResponseWriter, *http.Request) {
- return func(w http.ResponseWriter, r *http.Request) {
- err := r.ParseForm()
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
- req := strings.Join(r.Form["q"], " ")
- page := 0
- if len(r.Form["p"]) != 0 {
- page, err = strconv.Atoi(r.Form["p"][0])
- if err != nil {
- page = 0
- }
- }
- res, num, _ := GetBook(coll, buildQuery(req), SEARCH_ITEMS_PAGE, page*SEARCH_ITEMS_PAGE)
-
- var data searchData
- data.S = GetStatus(w, r)
- data.S.Search = req
- data.Books = res
- data.Found = num
- data.Page = page + 1
- if num > (page+1)*SEARCH_ITEMS_PAGE {
- data.Next = "/search/?q=" + req + "&p=" + strconv.Itoa(page+1)
- }
- if page > 0 {
- data.Prev = "/search/?q=" + req + "&p=" + strconv.Itoa(page-1)
- }
- loadTemplate(w, "search", data)
+func searchHandler(w http.ResponseWriter, r *http.Request) {
+ err := r.ParseForm()
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
}
+ req := strings.Join(r.Form["q"], " ")
+ page := 0
+ if len(r.Form["p"]) != 0 {
+ page, err = strconv.Atoi(r.Form["p"][0])
+ if err != nil {
+ page = 0
+ }
+ }
+ res, num, _ := db.GetBooks(buildQuery(req), SEARCH_ITEMS_PAGE, page*SEARCH_ITEMS_PAGE)
+
+ var data searchData
+ data.S = GetStatus(w, r)
+ data.S.Search = req
+ data.Books = res
+ data.Found = num
+ data.Page = page + 1
+ if num > (page+1)*SEARCH_ITEMS_PAGE {
+ data.Next = "/search/?q=" + req + "&p=" + strconv.Itoa(page+1)
+ }
+ if page > 0 {
+ data.Prev = "/search/?q=" + req + "&p=" + strconv.Itoa(page-1)
+ }
+ loadTemplate(w, "search", data)
}
diff --git a/templates/new.html b/templates/new.html
index 9e771d7..301e875 100644
--- a/templates/new.html
+++ b/templates/new.html
@@ -21,14 +21,15 @@
diff --git a/trantor.go b/trantor.go
index 457a45f..1be19e6 100644
--- a/trantor.go
+++ b/trantor.go
@@ -1,8 +1,6 @@
package main
import (
- "crypto/md5"
- "labix.org/v2/mgo"
"labix.org/v2/mgo/bson"
"net/http"
"os"
@@ -27,25 +25,20 @@ func logoutHandler(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/", 307)
}
-func loginHandler(coll *mgo.Collection) func(http.ResponseWriter, *http.Request) {
- return func(w http.ResponseWriter, r *http.Request) {
- if r.Method == "POST" {
- user := r.FormValue("user")
- pass := r.FormValue("pass")
- h := md5.New()
- hash := h.Sum(([]byte)(PASS_SALT + pass))
- n, _ := coll.Find(bson.M{"user": user, "pass": hash}).Count()
- sess := GetSession(r)
- if n != 0 {
- sess.LogIn(user)
- sess.Notify("Successful login!", "Welcome "+user, "success")
- } else {
- sess.Notify("Invalid login!", "user or password invalid", "error")
- }
- sess.Save(w, r)
+func loginHandler(w http.ResponseWriter, r *http.Request) {
+ if r.Method == "POST" {
+ user := r.FormValue("user")
+ pass := r.FormValue("pass")
+ sess := GetSession(r)
+ if db.UserValid(user, pass) {
+ sess.LogIn(user)
+ sess.Notify("Successful login!", "Welcome "+user, "success")
+ } else {
+ sess.Notify("Invalid login!", "user or password invalid", "error")
}
- http.Redirect(w, r, r.Referer(), 307)
+ sess.Save(w, r)
}
+ http.Redirect(w, r, r.Referer(), 307)
}
type bookData struct {
@@ -53,19 +46,17 @@ type bookData struct {
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 = GetStatus(w, r)
- id := bson.ObjectIdHex(r.URL.Path[len("/book/"):])
- books, _, err := GetBook(coll, bson.M{"_id": id})
- if err != nil || len(books) == 0 {
- http.NotFound(w, r)
- return
- }
- data.Book = books[0]
- loadTemplate(w, "book", data)
+func bookHandler(w http.ResponseWriter, r *http.Request) {
+ var data bookData
+ data.S = GetStatus(w, r)
+ id := bson.ObjectIdHex(r.URL.Path[len("/book/"):])
+ books, _, err := db.GetBooks(bson.M{"_id": id})
+ if err != nil || len(books) == 0 {
+ http.NotFound(w, r)
+ return
}
+ data.Book = books[0]
+ loadTemplate(w, "book", data)
}
func fileHandler(path string) {
@@ -80,45 +71,39 @@ type indexData struct {
Tags []string
}
-func indexHandler(coll *mgo.Collection) func(http.ResponseWriter, *http.Request) {
- return func(w http.ResponseWriter, r *http.Request) {
- var data indexData
+func indexHandler(w http.ResponseWriter, r *http.Request) {
+ var data indexData
- /* get the tags */
- tags, err := GetTags(coll)
- if err == nil {
- length := len(tags)
- if length > TAGS_DISPLAY {
- length = TAGS_DISPLAY
+ /* get the tags */
+ tags, err := db.GetTags()
+ if err == nil {
+ length := len(tags)
+ if length > TAGS_DISPLAY {
+ length = TAGS_DISPLAY
+ }
+ data.Tags = make([]string, length)
+ for i, tag := range tags {
+ if i == TAGS_DISPLAY {
+ break /* display only 50 */
}
- data.Tags = make([]string, length)
- for i, tag := range tags {
- if i == TAGS_DISPLAY {
- break /* display only 50 */
- }
- if tag.Subject != "" {
- data.Tags[i] = tag.Subject
- }
+ if tag.Subject != "" {
+ data.Tags[i] = tag.Subject
}
}
-
- data.S = GetStatus(w, r)
- data.S.Home = true
- data.Books, data.Count, _ = GetBook(coll, bson.M{}, 6)
- loadTemplate(w, "index", data)
}
+
+ data.S = GetStatus(w, r)
+ data.S.Home = true
+ data.Books, data.Count, _ = db.GetBooks(bson.M{"active": true}, 6)
+ loadTemplate(w, "index", data)
}
func main() {
- session, err := mgo.Dial(DB_IP)
- if err != nil {
- panic(err)
- }
- defer session.Close()
- coll := session.DB(DB_NAME).C(BOOKS_COLL)
- userColl := session.DB(DB_NAME).C(USERS_COLL)
- newColl := session.DB(DB_NAME).C(NEW_BOOKS_COLL)
+ db = initDB()
+ defer db.Close()
+ /* create the needed folders */
+ var err error
_, err = os.Stat(BOOKS_PATH)
if err != nil {
os.Mkdir(BOOKS_PATH, os.ModePerm)
@@ -132,27 +117,25 @@ func main() {
os.Mkdir(NEW_PATH, os.ModePerm)
}
- http.HandleFunc("/book/", bookHandler(coll))
- http.HandleFunc("/search/", searchHandler(coll))
- http.HandleFunc("/upload/", uploadHandler(newColl))
- http.HandleFunc("/login/", loginHandler(userColl))
+ /* set up web handlers */
+ http.HandleFunc("/book/", bookHandler)
+ http.HandleFunc("/search/", searchHandler)
+ http.HandleFunc("/upload/", uploadHandler)
+ http.HandleFunc("/login/", loginHandler)
http.HandleFunc("/logout/", logoutHandler)
- http.HandleFunc("/new/", newHandler(newColl, coll))
- http.HandleFunc("/delnew/", deleteHandler(newColl, "/new/"))
- http.HandleFunc("/store/", storeHandler(newColl, coll))
- http.HandleFunc("/read/", readHandler(coll))
- http.HandleFunc("/content/", contentHandler(coll))
- http.HandleFunc("/readnew/", readHandler(newColl))
- http.HandleFunc("/contentnew/", contentHandler(newColl))
- http.HandleFunc("/edit/", editHandler(coll))
- http.HandleFunc("/save/", saveHandler(coll))
- http.HandleFunc("/delete/", deleteHandler(coll, "/"))
+ http.HandleFunc("/new/", newHandler)
+ http.HandleFunc("/store/", storeHandler)
+ http.HandleFunc("/read/", readHandler)
+ http.HandleFunc("/content/", contentHandler)
+ http.HandleFunc("/edit/", editHandler)
+ http.HandleFunc("/save/", saveHandler)
+ http.HandleFunc("/delete/", deleteHandler)
http.HandleFunc("/about/", aboutHandler)
fileHandler("/img/")
fileHandler("/cover/")
fileHandler("/books/")
fileHandler("/css/")
fileHandler("/js/")
- http.HandleFunc("/", indexHandler(coll))
+ http.HandleFunc("/", indexHandler)
panic(http.ListenAndServe(":"+PORT, nil))
}
diff --git a/upload.go b/upload.go
index a799df9..1540cb6 100644
--- a/upload.go
+++ b/upload.go
@@ -2,7 +2,6 @@ package main
import (
"git.gitorious.org/go-pkg/epub.git"
- "labix.org/v2/mgo"
"net/http"
"os"
"os/exec"
@@ -198,7 +197,7 @@ func keywords(b map[string]interface{}) (k []string) {
return
}
-func parseFile(coll *mgo.Collection, path string) (string, error) {
+func parseFile(path string) (string, error) {
book := map[string]interface{}{}
e, err := epub.Open(path, 0)
@@ -229,7 +228,7 @@ func parseFile(coll *mgo.Collection, path string) (string, error) {
book["coversmall"] = coverSmall
book["keywords"] = keywords(book)
- coll.Insert(book)
+ db.InsertBook(book)
return title, nil
}
@@ -237,33 +236,31 @@ type uploadData struct {
S Status
}
-func uploadHandler(coll *mgo.Collection) func(http.ResponseWriter, *http.Request) {
- return func(w http.ResponseWriter, r *http.Request) {
- if r.Method == "POST" {
- sess := GetSession(r)
- paths, err := storeFiles(r)
- if err != nil {
- sess.Notify("Problem uploading!", "Some files were not stored. Try again or contact us if it keeps happening", "error")
- }
-
- uploaded := ""
- for _, path := range paths {
- title, err := parseFile(coll, path)
- if err != nil {
- os.Remove(path)
- sess.Notify("Problem uploading!", "The file '"+path[len("new/"):]+"' is not a well formed epub", "error")
- } else {
- uploaded = uploaded + " '" + title + "'"
- }
- }
- if uploaded != "" {
- sess.Notify("Upload successful!", "Added the books:"+uploaded+". Thank you for your contribution", "success")
- }
+func uploadHandler(w http.ResponseWriter, r *http.Request) {
+ if r.Method == "POST" {
+ sess := GetSession(r)
+ paths, err := storeFiles(r)
+ if err != nil {
+ sess.Notify("Problem uploading!", "Some files were not stored. Try again or contact us if it keeps happening", "error")
}
- var data uploadData
- data.S = GetStatus(w, r)
- data.S.Upload = true
- loadTemplate(w, "upload", data)
+ uploaded := ""
+ for _, path := range paths {
+ title, err := parseFile(path)
+ if err != nil {
+ os.Remove(path)
+ sess.Notify("Problem uploading!", "The file '"+path[len("new/"):]+"' is not a well formed epub", "error")
+ } else {
+ uploaded = uploaded + " '" + title + "'"
+ }
+ }
+ if uploaded != "" {
+ sess.Notify("Upload successful!", "Added the books:"+uploaded+". Thank you for your contribution", "success")
+ }
}
+
+ var data uploadData
+ data.S = GetStatus(w, r)
+ data.S.Upload = true
+ loadTemplate(w, "upload", data)
}