Put the covers on the database

This commit is contained in:
Las Zenow 2013-04-15 22:10:48 +02:00
parent 402dbabdbd
commit 986f834f46
10 changed files with 79 additions and 64 deletions

View file

@ -19,7 +19,6 @@ const (
NEW_ITEMS_PAGE = 50 NEW_ITEMS_PAGE = 50
TEMPLATE_PATH = "templates/" TEMPLATE_PATH = "templates/"
COVER_PATH = "cover/"
CSS_PATH = "css/" CSS_PATH = "css/"
JS_PATH = "js/" JS_PATH = "js/"
IMG_PATH = "img/" IMG_PATH = "img/"

View file

@ -3,19 +3,59 @@ package main
import ( import (
"bytes" "bytes"
"git.gitorious.org/go-pkg/epubgo.git" "git.gitorious.org/go-pkg/epubgo.git"
"github.com/gorilla/mux"
"github.com/nfnt/resize" "github.com/nfnt/resize"
"image" "image"
"image/jpeg" "image/jpeg"
"io" "io"
"io/ioutil" "io/ioutil"
"labix.org/v2/mgo"
"labix.org/v2/mgo/bson"
"log" "log"
"os" "net/http"
"regexp" "regexp"
"strings" "strings"
"unicode/utf8"
) )
func GetCover(e *epubgo.Epub, title string) (string, string) { func coverHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id := bson.ObjectIdHex(vars["id"])
books, _, err := db.GetBooks(bson.M{"_id": 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
}
}
fs := db.GetFS(FS_IMGS)
var f *mgo.GridFile
if vars["size"] == "small" {
f, err = fs.OpenId(book.CoverSmall)
} else {
f, err = fs.OpenId(book.Cover)
}
if err != nil {
log.Println("Error while opening image:", err)
http.NotFound(w, r)
return
}
defer f.Close()
headers := w.Header()
headers["Content-Type"] = []string{"image/jpeg"}
io.Copy(w, f)
}
func GetCover(e *epubgo.Epub, title string) (bson.ObjectId, bson.ObjectId) {
imgPath, smallPath := searchCommonCoverNames(e, title) imgPath, smallPath := searchCommonCoverNames(e, title)
if imgPath != "" { if imgPath != "" {
return imgPath, smallPath return imgPath, smallPath
@ -65,7 +105,7 @@ func GetCover(e *epubgo.Epub, title string) (string, string) {
return "", "" return "", ""
} }
func searchCommonCoverNames(e *epubgo.Epub, title string) (string, string) { func searchCommonCoverNames(e *epubgo.Epub, title string) (bson.ObjectId, bson.ObjectId) {
for _, p := range []string{"cover.jpg", "Images/cover.jpg", "cover.jpeg", "cover1.jpg", "cover1.jpeg"} { for _, p := range []string{"cover.jpg", "Images/cover.jpg", "cover.jpeg", "cover1.jpg", "cover1.jpeg"} {
img, err := e.OpenFile(p) img, err := e.OpenFile(p)
if err == nil { if err == nil {
@ -76,30 +116,20 @@ func searchCommonCoverNames(e *epubgo.Epub, title string) (string, string) {
return "", "" return "", ""
} }
func storeImg(img io.Reader, title, extension string) (string, string) { func storeImg(img io.Reader, title, extension string) (bson.ObjectId, bson.ObjectId) {
r, _ := utf8.DecodeRuneInString(title)
folder := string(r)
if _, err := os.Stat(COVER_PATH + folder); err != nil {
err = os.Mkdir(COVER_PATH+folder, os.ModePerm)
if err != nil {
log.Println("Error creating", COVER_PATH+folder, ":", err.Error())
return "", ""
}
}
/* open the files */ /* open the files */
imgPath := validFileName(COVER_PATH, title, extension) imgPath := title + extension
fBig, err := os.Create(COVER_PATH + imgPath) fBig, err := createCoverFile(imgPath)
if err != nil { if err != nil {
log.Println("Error creating", COVER_PATH+imgPath, ":", err.Error()) log.Println("Error creating", imgPath, ":", err.Error())
return "", "" return "", ""
} }
defer fBig.Close() defer fBig.Close()
imgPathSmall := validFileName(COVER_PATH, title, "_small"+extension) imgPathSmall := title + "_small" + extension
fSmall, err := os.Create(COVER_PATH + imgPathSmall) fSmall, err := createCoverFile(imgPathSmall)
if err != nil { if err != nil {
log.Println("Error creating", COVER_PATH+imgPathSmall, ":", err.Error()) log.Println("Error creating", imgPathSmall, ":", err.Error())
return "", "" return "", ""
} }
defer fSmall.Close() defer fSmall.Close()
@ -129,7 +159,14 @@ func storeImg(img io.Reader, title, extension string) (string, string) {
return "", "" return "", ""
} }
return imgPath, imgPathSmall idBig, _ := fBig.Id().(bson.ObjectId)
idSmall, _ := fSmall.Id().(bson.ObjectId)
return idBig, idSmall
}
func createCoverFile(name string) (*mgo.GridFile, error) {
fs := db.GetFS(FS_IMGS)
return fs.Create(name)
} }
func resizeImg(imgReader io.Reader, width uint) (image.Image, error) { func resizeImg(imgReader io.Reader, width uint) (image.Image, error) {

View file

@ -32,8 +32,8 @@ type Book struct {
Rights string Rights string
Meta string Meta string
File bson.ObjectId File bson.ObjectId
Cover string Cover bson.ObjectId
CoverSmall string CoverSmall bson.ObjectId
Active bool Active bool
Keywords []string Keywords []string
} }

View file

@ -6,11 +6,8 @@ import (
"io" "io"
"io/ioutil" "io/ioutil"
"labix.org/v2/mgo/bson" "labix.org/v2/mgo/bson"
"os"
"regexp" "regexp"
"strconv"
"strings" "strings"
"unicode/utf8"
) )
func ParseFile(id bson.ObjectId) (string, error) { func ParseFile(id bson.ObjectId) (string, error) {
@ -94,29 +91,19 @@ func DeleteFile(id bson.ObjectId) error {
return fs.RemoveId(id) return fs.RemoveId(id)
} }
func DeleteBook(book Book) { func DeleteCover(id bson.ObjectId) error {
if book.Cover != "" { fs := db.GetFS(FS_IMGS)
os.RemoveAll(book.Cover[1:]) return fs.RemoveId(id)
}
if book.CoverSmall != "" {
os.RemoveAll(book.CoverSmall[1:])
}
DeleteFile(book.File)
} }
func validFileName(path string, title string, extension string) string { func DeleteBook(book Book) {
title = strings.Replace(title, "/", "_", -1) if book.Cover != "" {
title = strings.Replace(title, "?", "_", -1) DeleteCover(book.Cover)
title = strings.Replace(title, "#", "_", -1)
r, _ := utf8.DecodeRuneInString(title)
folder := string(r)
file := folder + "/" + title + extension
_, err := os.Stat(path + file)
for i := 0; err == nil; i++ {
file = folder + "/" + title + "_" + strconv.Itoa(i) + extension
_, err = os.Stat(path + file)
} }
return file if book.CoverSmall != "" {
DeleteCover(book.CoverSmall)
}
DeleteFile(book.File)
} }
func cleanStr(str string) string { func cleanStr(str string) string {

View file

@ -25,7 +25,7 @@ function delBook(){
<div class="row"> <div class="row">
{{if .Cover}} {{if .Cover}}
<div class="span4"> <div class="span4">
<img src="/cover/{{.Cover}}" alt="{{.Title}}" class="pull-right" /> <img src="/cover/{{.Id}}/big/{{.Title}}.jpg" alt="{{.Title}}" class="pull-right" />
</div> </div>
{{end}} {{end}}

View file

@ -4,7 +4,7 @@
<div class="row"> <div class="row">
{{if .Cover}} {{if .Cover}}
<div class="span4"> <div class="span4">
<img src="/cover/{{.Cover}}" alt="{{.Title}}" class="pull-right" /> <img src="/cover/{{.Id}}/big/{{.Title}}.jpg" alt="{{.Title}}" class="pull-right" />
</div> </div>
{{end}} {{end}}

View file

@ -15,7 +15,7 @@
<li class="span2"> <li class="span2">
<div class="thumbnail centered" style="border:none;"> <div class="thumbnail centered" style="border:none;">
<a href="/book/{{.Id}}"> <a href="/book/{{.Id}}">
{{if .CoverSmall}}<div class="down"><img class="img-rounded" src="/cover/{{.CoverSmall}}" alt="{{.Title}}" /></div>{{end}} {{if .CoverSmall}}<div class="down"><img class="img-rounded" src="/cover/{{.Id}}/small/{{.Title}}.jpg" alt="{{.Title}}" /></div>{{end}}
<p><strong>{{.Title}}</strong></p> <p><strong>{{.Title}}</strong></p>
</a> </a>
</div> </div>
@ -35,7 +35,7 @@
<li class="span2"> <li class="span2">
<div class="thumbnail centered" style="border:none;"> <div class="thumbnail centered" style="border:none;">
<a href="/book/{{.Id}}"> <a href="/book/{{.Id}}">
{{if .CoverSmall}}<div class="down"><img class="img-rounded" src="/cover/{{.CoverSmall}}" alt="{{.Title}}" /></div>{{end}} {{if .CoverSmall}}<div class="down"><img class="img-rounded" src="/cover/{{.Id}}/small/{{.Title}}.jpg" alt="{{.Title}}" /></div>{{end}}
<p><strong>{{.Title}}</strong></p> <p><strong>{{.Title}}</strong></p>
</a> </a>
</div> </div>
@ -55,7 +55,7 @@
<li class="span2"> <li class="span2">
<div class="thumbnail centered" style="border:none;"> <div class="thumbnail centered" style="border:none;">
<a href="/book/{{.Id}}"> <a href="/book/{{.Id}}">
{{if .CoverSmall}}<div class="down"><img class="img-rounded" src="/cover/{{.CoverSmall}}" alt="{{.Title}}" /></div>{{end}} {{if .CoverSmall}}<div class="down"><img class="img-rounded" src="/cover/{{.Id}}/small/{{.Title}}.jpg" alt="{{.Title}}" /></div>{{end}}
<p><strong>{{.Title}}</strong></p> <p><strong>{{.Title}}</strong></p>
</a> </a>
</div> </div>

View file

@ -26,7 +26,7 @@
{{with .B}} {{with .B}}
<div class="row"> <div class="row">
<div class="span1"> <div class="span1">
<p class="pull-right">{{if .CoverSmall}}<img src="/cover/{{.CoverSmall}}" alt="{{.Title}}" />{{end}}</p> <p class="pull-right">{{if .CoverSmall}}<img src="/cover/{{.Id}}/small/{{.Title}}.jpg" alt="{{.Title}}" />{{end}}</p>
</div> </div>
<div class="span9"> <div class="span9">
<p><a href="/search/?q=title:{{.Title}}"><strong>{{.Title}}</strong></a> <small>({{$titleFound}})</small><br /> <p><a href="/search/?q=title:{{.Title}}"><strong>{{.Title}}</strong></a> <small>({{$titleFound}})</small><br />

View file

@ -19,7 +19,7 @@
{{range .}} {{range .}}
<div class="row"> <div class="row">
<div class="span1"> <div class="span1">
<p class="pull-right"><a href="/book/{{.Id}}">{{if .CoverSmall}}<img class="img-rounded" src="/cover/{{.CoverSmall}}" alt="{{.Title}}" />{{end}}</a></p> <p class="pull-right"><a href="/book/{{.Id}}">{{if .CoverSmall}}<img class="img-rounded" src="/cover/{{.Id}}/small/{{.Title}}.jpg" alt="{{.Title}}" />{{end}}</a></p>
</div> </div>
<div class="span10 well"> <div class="span10 well">
<div class="row"> <div class="row">

View file

@ -6,7 +6,6 @@ import (
"labix.org/v2/mgo/bson" "labix.org/v2/mgo/bson"
"log" "log"
"net/http" "net/http"
"os"
) )
type aboutData struct { type aboutData struct {
@ -122,12 +121,6 @@ func main() {
db = initDB() db = initDB()
defer db.Close() defer db.Close()
/* create the needed folders */
_, err := os.Stat(COVER_PATH)
if err != nil {
os.Mkdir(COVER_PATH, os.ModePerm)
}
/* set up web handlers */ /* set up web handlers */
r := mux.NewRouter() r := mux.NewRouter()
r.HandleFunc("/", indexHandler) r.HandleFunc("/", indexHandler)
@ -146,11 +139,10 @@ func main() {
r.HandleFunc("/save/{id:[0-9a-fA-F]+}", saveHandler).Methods("POST") r.HandleFunc("/save/{id:[0-9a-fA-F]+}", saveHandler).Methods("POST")
r.HandleFunc("/about/", aboutHandler) r.HandleFunc("/about/", aboutHandler)
r.HandleFunc("/books/{id:[0-9a-fA-F]+}", downloadHandler) r.HandleFunc("/books/{id:[0-9a-fA-F]+}", downloadHandler)
r.HandleFunc("/cover/{id:[0-9a-fA-F]+}/{size}/{img:.*}", coverHandler)
r.HandleFunc("/settings/", settingsHandler) r.HandleFunc("/settings/", settingsHandler)
h := http.FileServer(http.Dir(IMG_PATH)) h := http.FileServer(http.Dir(IMG_PATH))
r.Handle("/img/{img}", http.StripPrefix("/img/", h)) r.Handle("/img/{img}", http.StripPrefix("/img/", h))
h = http.FileServer(http.Dir(COVER_PATH))
r.Handle("/cover/{c}/{img}", http.StripPrefix("/cover/", h))
h = http.FileServer(http.Dir(CSS_PATH)) h = http.FileServer(http.Dir(CSS_PATH))
r.Handle("/css/{css}", http.StripPrefix("/css/", h)) r.Handle("/css/{css}", http.StripPrefix("/css/", h))
h = http.FileServer(http.Dir(JS_PATH)) h = http.FileServer(http.Dir(JS_PATH))