diff --git a/admin.go b/admin.go index acf9d32..af9f325 100644 --- a/admin.go +++ b/admin.go @@ -5,9 +5,15 @@ import ( "labix.org/v2/mgo/bson" "net/http" "os" + "os/exec" + "strconv" ) -func deleteHandler(coll *mgo.Collection) func(http.ResponseWriter, *http.Request) { +const ( + PATH = "books/" +) + +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 == "" { @@ -15,6 +21,7 @@ func deleteHandler(coll *mgo.Collection) func(http.ResponseWriter, *http.Request 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 { @@ -28,7 +35,7 @@ func deleteHandler(coll *mgo.Collection) func(http.ResponseWriter, *http.Request 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, url, 307) } } @@ -101,6 +108,12 @@ func saveHandler(coll *mgo.Collection) func(http.ResponseWriter, *http.Request) } } +type newData struct { + S Status + Found int + Books []Book +} + func newHandler(coll *mgo.Collection) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { sess := GetSession(r) @@ -108,5 +121,47 @@ func newHandler(coll *mgo.Collection) func(http.ResponseWriter, *http.Request) { http.NotFound(w, r) return } + + res, _ := GetBook(coll, bson.M{}) + var data newData + data.S = GetStatus(w, r) + data.Found = len(res) + data.Books = res + loadTemplate(w, "new", data) + } +} + +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/"):]) + books, err := GetBook(newColl, bson.M{"_id": id}) + if err != nil { + http.NotFound(w, r) + return + } + book := books[0] + + path := PATH + book.Title[:1] + "/" + book.Title + ".epub" + _, err = os.Stat(path) + for i := 0; err == nil; i++ { + path := PATH + book.Title[:1] + "/" + book.Title + "_" + strconv.Itoa(i) + ".epub" + _, err = os.Stat(path) + } + + os.Mkdir(PATH+book.Title[:1], os.ModePerm) + cmd := exec.Command("mv", book.Path, path) + cmd.Run() + book.Path = path + coll.Insert(book) + newColl.Remove(bson.M{"_id": id}) + sess.Notify("Store book!", "The book '"+book.Title+"' it's stored for public download", "success") + sess.Save(w, r) + http.Redirect(w, r, "/new/", 307) } } diff --git a/template.go b/template.go index 12648b0..ea0848b 100644 --- a/template.go +++ b/template.go @@ -36,6 +36,7 @@ func loadTemplate(w http.ResponseWriter, tmpl string, data interface{}) { TEMPLATE_DIR+"book.html", TEMPLATE_DIR+"search.html", TEMPLATE_DIR+"upload.html", + TEMPLATE_DIR+"new.html", TEMPLATE_DIR+"edit.html", )) diff --git a/templates/new.html b/templates/new.html new file mode 100644 index 0000000..e8f1535 --- /dev/null +++ b/templates/new.html @@ -0,0 +1,41 @@ +{{template "header.html" .S}} + +
Found {{.Found}} books.
+ +{{with .Books}} + {{range .}} +{{if .CoverSmall}}{{end}}
{{.Title}}
+ {{if .Author}}Author: {{range .Author}}{{.}}, {{end}}
{{end}}
+ {{if .Publisher}}Publisher: {{.Publisher}}
{{end}}
+ {{if .Subject}}Tags: {{range .Subject}}{{.}}, {{end}}
{{end}}
+ {{if .Date}}Date: {{.Date}}
{{end}}
+ {{if .Lang}}Lang: {{range .Lang}}{{.}} {{end}}
{{end}}
+ {{.Description}}
+
{{.Msg}}
{{end}} +Upload your epubs to help the library.
- {{template "footer.html"}} diff --git a/trantor.go b/trantor.go index 1f0916b..2c9f70f 100644 --- a/trantor.go +++ b/trantor.go @@ -108,13 +108,15 @@ func main() { http.HandleFunc("/book/", bookHandler(coll)) http.HandleFunc("/search/", searchHandler(coll)) - http.HandleFunc("/upload/", uploadHandler(coll)) + http.HandleFunc("/upload/", uploadHandler(newColl)) http.HandleFunc("/login/", loginHandler(userColl)) http.HandleFunc("/logout/", logoutHandler) http.HandleFunc("/new/", newHandler(newColl)) + http.HandleFunc("/delnew/", deleteHandler(newColl, "/new/")) + http.HandleFunc("/store/", storeHandler(newColl, coll)) http.HandleFunc("/edit/", editHandler(coll)) http.HandleFunc("/save/", saveHandler(coll)) - http.HandleFunc("/delete/", deleteHandler(coll)) + http.HandleFunc("/delete/", deleteHandler(coll, "/")) http.HandleFunc("/about/", aboutHandler) fileHandler("/img/") fileHandler("/cover/") diff --git a/upload.go b/upload.go index 5f629fd..08faa3d 100644 --- a/upload.go +++ b/upload.go @@ -1,11 +1,21 @@ package main import ( + "git.gitorious.org/go-pkg/epub.git" "labix.org/v2/mgo" - "os" - "strconv" //"labix.org/v2/mgo/bson" "net/http" + "os" + "os/exec" + "regexp" + "strconv" + "strings" +) + +const ( + COVER_PATH = "cover/" + RESIZE = "/usr/bin/convert -resize 300 -quality 60 " + RESIZE_THUMB = "/usr/bin/convert -resize 60 -quality 60 " ) func storePath(name string) string { @@ -18,16 +28,17 @@ func storePath(name string) string { return path } -func storeFile(r *http.Request) error { +func storeFile(r *http.Request) (string, error) { f, header, err := r.FormFile("epub") if err != nil { - return err + return "", err } defer f.Close() - fw, err := os.Create(storePath(header.Filename)) + path := storePath(header.Filename) + fw, err := os.Create(path) if err != nil { - return err + return "", err } defer fw.Close() @@ -39,29 +50,218 @@ func storeFile(r *http.Request) error { fw.Write(buff) } - return nil + return path, nil +} + +func cleanStr(str string) string { + str = strings.Replace(str, "'", "'", -1) + exp, _ := regexp.Compile("[ ,]*$") + str = exp.ReplaceAllString(str, "") + return str +} + +func storeImg(img []byte, title, extension string) (string, string) { + name := title + folder := COVER_PATH + name[:1] + "/" + os.Mkdir(folder, os.ModePerm) + imgPath := folder + name + extension + _, err := os.Stat(imgPath) + for i := 0; err == nil; i++ { + name = title + "_" + strconv.Itoa(i) + imgPath = folder + name + extension + _, err = os.Stat(imgPath) + } + + /* store img on disk */ + file, _ := os.Create(imgPath) + defer file.Close() + file.Write(img) + + /* resize img */ + resize := append(strings.Split(RESIZE, " "), imgPath, imgPath) + cmd := exec.Command(resize[0], resize[1:]...) + cmd.Run() + imgPathSmall := folder + name + "_small" + extension + resize = append(strings.Split(RESIZE_THUMB, " "), imgPath, imgPathSmall) + cmd = exec.Command(resize[0], resize[1:]...) + cmd.Run() + return "/" + imgPath, "/" + imgPathSmall +} + +func getCover(e *epub.Epub, title string) (string, string) { + /* Try first common names */ + img := e.Data("cover.jpg") + if len(img) != 0 { + return storeImg(img, title, ".jpg") + } + img = e.Data("cover.jpeg") + if len(img) != 0 { + return storeImg(img, title, ".jpg") + } + img = e.Data("cover1.jpg") + if len(img) != 0 { + return storeImg(img, title, ".jpg") + } + img = e.Data("cover1.jpeg") + if len(img) != 0 { + return storeImg(img, title, ".jpg") + } + + /* search for img on the text */ + exp, _ := regexp.Compile("