2013-03-20 21:25:53 +01:00
|
|
|
package main
|
|
|
|
|
2013-04-25 14:33:50 +02:00
|
|
|
import _ "image/png"
|
|
|
|
import _ "image/jpeg"
|
|
|
|
import _ "image/gif"
|
|
|
|
|
2013-03-20 21:25:53 +01:00
|
|
|
import (
|
|
|
|
"bytes"
|
2013-04-01 14:05:04 +02:00
|
|
|
"git.gitorious.org/go-pkg/epubgo.git"
|
2013-04-15 22:10:48 +02:00
|
|
|
"github.com/gorilla/mux"
|
2013-03-20 21:25:53 +01:00
|
|
|
"github.com/nfnt/resize"
|
|
|
|
"image"
|
|
|
|
"image/jpeg"
|
2013-04-01 14:05:04 +02:00
|
|
|
"io"
|
|
|
|
"io/ioutil"
|
2013-04-15 22:10:48 +02:00
|
|
|
"labix.org/v2/mgo"
|
|
|
|
"labix.org/v2/mgo/bson"
|
2013-03-20 21:25:53 +01:00
|
|
|
"log"
|
2013-04-15 22:10:48 +02:00
|
|
|
"net/http"
|
2013-03-20 21:25:53 +01:00
|
|
|
"regexp"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
2013-04-15 22:10:48 +02:00
|
|
|
func coverHandler(w http.ResponseWriter, r *http.Request) {
|
|
|
|
vars := mux.Vars(r)
|
2013-05-09 09:42:58 +02:00
|
|
|
if !bson.IsObjectIdHex(vars["id"]) {
|
2013-06-01 20:51:21 +02:00
|
|
|
notFound(w, r)
|
2013-05-09 09:42:58 +02:00
|
|
|
return
|
|
|
|
}
|
2013-04-15 22:10:48 +02:00
|
|
|
id := bson.ObjectIdHex(vars["id"])
|
|
|
|
books, _, err := db.GetBooks(bson.M{"_id": id})
|
|
|
|
if err != nil || len(books) == 0 {
|
2013-06-01 20:51:21 +02:00
|
|
|
notFound(w, r)
|
2013-04-15 22:10:48 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
book := books[0]
|
|
|
|
|
|
|
|
if !book.Active {
|
|
|
|
sess := GetSession(r)
|
2013-06-01 20:43:23 +02:00
|
|
|
if !sess.IsAdmin() {
|
2013-06-01 20:51:21 +02:00
|
|
|
notFound(w, r)
|
2013-04-15 22:10:48 +02:00
|
|
|
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)
|
2013-06-01 20:51:21 +02:00
|
|
|
notFound(w, r)
|
2013-04-15 22:10:48 +02:00
|
|
|
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) {
|
2013-07-18 21:08:22 +02:00
|
|
|
imgId, smallId := coverFromMetadata(e, title)
|
|
|
|
if imgId != "" {
|
|
|
|
return imgId, smallId
|
|
|
|
}
|
|
|
|
|
|
|
|
imgId, smallId = searchCommonCoverNames(e, title)
|
2013-04-23 01:04:47 +02:00
|
|
|
if imgId != "" {
|
|
|
|
return imgId, smallId
|
2013-03-20 21:25:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* search for img on the text */
|
2013-07-18 20:28:35 +02:00
|
|
|
exp, _ := regexp.Compile("<.*ima?g.*[(src)(href)]=[\"']([^\"']*(\\.[^\\.\"']*))[\"']")
|
2013-04-01 14:05:04 +02:00
|
|
|
it, errNext := e.Spine()
|
|
|
|
for errNext == nil {
|
|
|
|
file, err := it.Open()
|
|
|
|
if err != nil {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
defer file.Close()
|
|
|
|
|
|
|
|
txt, err := ioutil.ReadAll(file)
|
|
|
|
if err != nil {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
res := exp.FindSubmatch(txt)
|
2013-03-20 21:25:53 +01:00
|
|
|
if res != nil {
|
2013-04-01 14:05:04 +02:00
|
|
|
href := string(res[1])
|
2013-06-04 21:30:37 +02:00
|
|
|
urlPart := strings.Split(it.URL(), "/")
|
2013-03-20 21:25:53 +01:00
|
|
|
url := strings.Join(urlPart[:len(urlPart)-1], "/")
|
2013-04-01 14:05:04 +02:00
|
|
|
if href[:3] == "../" {
|
|
|
|
href = href[3:]
|
2013-03-20 21:25:53 +01:00
|
|
|
url = strings.Join(urlPart[:len(urlPart)-2], "/")
|
|
|
|
}
|
2013-04-01 14:05:04 +02:00
|
|
|
href = strings.Replace(href, "%20", " ", -1)
|
|
|
|
href = strings.Replace(href, "%27", "'", -1)
|
|
|
|
href = strings.Replace(href, "%28", "(", -1)
|
|
|
|
href = strings.Replace(href, "%29", ")", -1)
|
2013-03-20 21:25:53 +01:00
|
|
|
if url == "" {
|
2013-04-01 14:05:04 +02:00
|
|
|
url = href
|
2013-03-20 21:25:53 +01:00
|
|
|
} else {
|
2013-04-01 14:05:04 +02:00
|
|
|
url = url + "/" + href
|
2013-03-20 21:25:53 +01:00
|
|
|
}
|
|
|
|
|
2013-04-01 14:05:04 +02:00
|
|
|
img, err := e.OpenFile(url)
|
|
|
|
if err == nil {
|
|
|
|
defer img.Close()
|
2013-04-23 01:04:47 +02:00
|
|
|
return storeImg(img, title)
|
2013-03-20 21:25:53 +01:00
|
|
|
}
|
|
|
|
}
|
2013-04-01 14:05:04 +02:00
|
|
|
errNext = it.Next()
|
|
|
|
}
|
|
|
|
return "", ""
|
|
|
|
}
|
|
|
|
|
2013-07-18 21:08:22 +02:00
|
|
|
func coverFromMetadata(e *epubgo.Epub, title string) (bson.ObjectId, bson.ObjectId) {
|
|
|
|
metaList, _ := e.MetadataAttr("meta")
|
|
|
|
for _, meta := range metaList {
|
|
|
|
if meta["name"] == "cover" {
|
|
|
|
img, err := e.OpenFileId(meta["content"])
|
|
|
|
if err == nil {
|
|
|
|
defer img.Close()
|
|
|
|
return storeImg(img, title)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return "", ""
|
|
|
|
}
|
|
|
|
|
2013-04-15 22:10:48 +02:00
|
|
|
func searchCommonCoverNames(e *epubgo.Epub, title string) (bson.ObjectId, bson.ObjectId) {
|
2013-07-18 21:08:22 +02:00
|
|
|
for _, p := range []string{"cover.jpg", "Images/cover.jpg", "images/cover.jpg", "cover.jpeg", "cover1.jpg", "cover1.jpeg"} {
|
2013-04-01 14:05:04 +02:00
|
|
|
img, err := e.OpenFile(p)
|
|
|
|
if err == nil {
|
|
|
|
defer img.Close()
|
2013-04-23 01:04:47 +02:00
|
|
|
return storeImg(img, title)
|
2013-04-01 14:05:04 +02:00
|
|
|
}
|
2013-03-20 21:25:53 +01:00
|
|
|
}
|
|
|
|
return "", ""
|
|
|
|
}
|
|
|
|
|
2013-04-23 01:04:47 +02:00
|
|
|
func storeImg(img io.Reader, title string) (bson.ObjectId, bson.ObjectId) {
|
2013-03-20 21:25:53 +01:00
|
|
|
/* open the files */
|
2013-04-23 01:04:47 +02:00
|
|
|
fBig, err := createCoverFile(title)
|
2013-03-20 21:25:53 +01:00
|
|
|
if err != nil {
|
2013-04-23 01:04:47 +02:00
|
|
|
log.Println("Error creating", title, ":", err.Error())
|
2013-03-20 21:25:53 +01:00
|
|
|
return "", ""
|
|
|
|
}
|
|
|
|
defer fBig.Close()
|
|
|
|
|
2013-04-23 01:04:47 +02:00
|
|
|
fSmall, err := createCoverFile(title + "_small")
|
2013-03-20 21:25:53 +01:00
|
|
|
if err != nil {
|
2013-04-23 01:04:47 +02:00
|
|
|
log.Println("Error creating", title+"_small", ":", err.Error())
|
2013-03-20 21:25:53 +01:00
|
|
|
return "", ""
|
|
|
|
}
|
|
|
|
defer fSmall.Close()
|
|
|
|
|
|
|
|
/* resize img */
|
2013-04-01 14:05:04 +02:00
|
|
|
var img2 bytes.Buffer
|
|
|
|
img1 := io.TeeReader(img, &img2)
|
2013-03-20 21:25:53 +01:00
|
|
|
jpgOptions := jpeg.Options{IMG_QUALITY}
|
2013-04-01 14:05:04 +02:00
|
|
|
imgResized, err := resizeImg(img1, IMG_WIDTH_BIG)
|
2013-03-20 21:25:53 +01:00
|
|
|
if err != nil {
|
|
|
|
log.Println("Error resizing big image:", err.Error())
|
|
|
|
return "", ""
|
|
|
|
}
|
|
|
|
err = jpeg.Encode(fBig, imgResized, &jpgOptions)
|
|
|
|
if err != nil {
|
|
|
|
log.Println("Error encoding big image:", err.Error())
|
|
|
|
return "", ""
|
|
|
|
}
|
2013-04-01 14:05:04 +02:00
|
|
|
imgSmallResized, err := resizeImg(&img2, IMG_WIDTH_SMALL)
|
2013-03-20 21:25:53 +01:00
|
|
|
if err != nil {
|
|
|
|
log.Println("Error resizing small image:", err.Error())
|
|
|
|
return "", ""
|
|
|
|
}
|
|
|
|
err = jpeg.Encode(fSmall, imgSmallResized, &jpgOptions)
|
|
|
|
if err != nil {
|
|
|
|
log.Println("Error encoding small image:", err.Error())
|
|
|
|
return "", ""
|
|
|
|
}
|
|
|
|
|
2013-04-15 22:10:48 +02:00
|
|
|
idBig, _ := fBig.Id().(bson.ObjectId)
|
|
|
|
idSmall, _ := fSmall.Id().(bson.ObjectId)
|
|
|
|
return idBig, idSmall
|
|
|
|
}
|
|
|
|
|
2013-04-23 01:04:47 +02:00
|
|
|
func createCoverFile(title string) (*mgo.GridFile, error) {
|
2013-04-15 22:10:48 +02:00
|
|
|
fs := db.GetFS(FS_IMGS)
|
2013-04-23 01:04:47 +02:00
|
|
|
return fs.Create(title + ".jpg")
|
2013-03-20 21:25:53 +01:00
|
|
|
}
|
|
|
|
|
2013-04-01 14:05:04 +02:00
|
|
|
func resizeImg(imgReader io.Reader, width uint) (image.Image, error) {
|
|
|
|
img, _, err := image.Decode(imgReader)
|
2013-03-20 21:25:53 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return resize.Resize(width, 0, img, resize.NearestNeighbor), nil
|
|
|
|
}
|