Use image API for resize images
Some jpeg images won't load correctly with it until Go 1.1
This commit is contained in:
parent
35fd980692
commit
cf773da9db
4 changed files with 146 additions and 96 deletions
5
README
5
README
|
@ -15,18 +15,17 @@ In order to run Trantor, you need to install the following packages:
|
||||||
* Go language
|
* Go language
|
||||||
* Epub development library
|
* Epub development library
|
||||||
* Mongodb
|
* Mongodb
|
||||||
* Imagemagick (for resize covers)
|
|
||||||
* Bazaar
|
* Bazaar
|
||||||
* Mercurial
|
* Mercurial
|
||||||
* Git (necessary only if you want to deal with the repository)
|
* Git (necessary only if you want to deal with the repository)
|
||||||
|
|
||||||
Under Debian Wheezy you can simply run:
|
Under Debian Wheezy you can simply run:
|
||||||
|
|
||||||
# aptitude install golang-go git mercurial bzr libepub-dev mongodb imagemagick
|
# aptitude install golang-go git mercurial bzr libepub-dev mongodb
|
||||||
|
|
||||||
Yo also need to install go dependences:
|
Yo also need to install go dependences:
|
||||||
|
|
||||||
# go get labix.org/v2/mgo/bson labix.org/v2/mgo/ github.com/gorilla/sessions github.com/gorilla/securecookie
|
# go get labix.org/v2/mgo/bson labix.org/v2/mgo/ github.com/gorilla/sessions github.com/gorilla/securecookie github.com/nfnt/resize
|
||||||
|
|
||||||
== Installation ==
|
== Installation ==
|
||||||
=== For admins ("for developers" below) ===
|
=== For admins ("for developers" below) ===
|
||||||
|
|
37
config.go
37
config.go
|
@ -1,25 +1,30 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
const (
|
const (
|
||||||
PORT = "8080"
|
PORT = "8080"
|
||||||
DB_IP = "127.0.0.1"
|
|
||||||
DB_NAME = "trantor"
|
DB_IP = "127.0.0.1"
|
||||||
META_COLL = "meta"
|
DB_NAME = "trantor"
|
||||||
BOOKS_COLL = "books"
|
META_COLL = "meta"
|
||||||
TAGS_COLL = "tags"
|
BOOKS_COLL = "books"
|
||||||
USERS_COLL = "users"
|
TAGS_COLL = "tags"
|
||||||
|
USERS_COLL = "users"
|
||||||
|
|
||||||
PASS_SALT = "ImperialLibSalt"
|
PASS_SALT = "ImperialLibSalt"
|
||||||
MINUTES_UPDATE_TAGS = 10
|
MINUTES_UPDATE_TAGS = 10
|
||||||
TAGS_DISPLAY = 50
|
TAGS_DISPLAY = 50
|
||||||
SEARCH_ITEMS_PAGE = 20
|
SEARCH_ITEMS_PAGE = 20
|
||||||
NEW_ITEMS_PAGE = 50
|
NEW_ITEMS_PAGE = 50
|
||||||
TEMPLATE_PATH = "templates/"
|
|
||||||
BOOKS_PATH = "books/"
|
TEMPLATE_PATH = "templates/"
|
||||||
COVER_PATH = "cover/"
|
BOOKS_PATH = "books/"
|
||||||
NEW_PATH = "new/"
|
COVER_PATH = "cover/"
|
||||||
CSS_PATH = "css/"
|
NEW_PATH = "new/"
|
||||||
JS_PATH = "js/"
|
CSS_PATH = "css/"
|
||||||
IMG_PATH = "img/"
|
JS_PATH = "js/"
|
||||||
RESIZE_CMD = "/usr/bin/convert -resize 300 -quality 60 "
|
IMG_PATH = "img/"
|
||||||
RESIZE_THUMB_CMD = "/usr/bin/convert -resize 60 -quality 60 "
|
|
||||||
|
IMG_WIDTH_BIG = 300
|
||||||
|
IMG_WIDTH_SMALL = 60
|
||||||
|
IMG_QUALITY = 80
|
||||||
)
|
)
|
||||||
|
|
122
cover.go
Normal file
122
cover.go
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"git.gitorious.org/go-pkg/epub.git"
|
||||||
|
"github.com/nfnt/resize"
|
||||||
|
"image"
|
||||||
|
"image/jpeg"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"unicode/utf8"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetCover(e *epub.Epub, title string) (string, string) {
|
||||||
|
/* Try first common names */
|
||||||
|
for _, p := range []string{"cover.jpg", "Images/cover.jpg", "cover.jpeg", "cover1.jpg", "cover1.jpeg"} {
|
||||||
|
img := e.Data(p)
|
||||||
|
if len(img) != 0 {
|
||||||
|
return storeImg(img, title, ".jpg")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* search for img on the text */
|
||||||
|
exp, _ := regexp.Compile("<ima?g.*[(src)(href)]=[\"']([^\"']*(\\.[^\\.\"']*))[\"']")
|
||||||
|
it := e.Iterator(epub.EITERATOR_SPINE)
|
||||||
|
defer it.Close()
|
||||||
|
var err error = nil
|
||||||
|
txt := it.Curr()
|
||||||
|
for err == nil {
|
||||||
|
res := exp.FindStringSubmatch(txt)
|
||||||
|
if res != nil {
|
||||||
|
urlPart := strings.Split(it.CurrUrl(), "/")
|
||||||
|
url := strings.Join(urlPart[:len(urlPart)-1], "/")
|
||||||
|
if res[1][:3] == "../" {
|
||||||
|
res[1] = res[1][3:]
|
||||||
|
url = strings.Join(urlPart[:len(urlPart)-2], "/")
|
||||||
|
}
|
||||||
|
res[1] = strings.Replace(res[1], "%20", " ", -1)
|
||||||
|
res[1] = strings.Replace(res[1], "%27", "'", -1)
|
||||||
|
res[1] = strings.Replace(res[1], "%28", "(", -1)
|
||||||
|
res[1] = strings.Replace(res[1], "%29", ")", -1)
|
||||||
|
if url == "" {
|
||||||
|
url = res[1]
|
||||||
|
} else {
|
||||||
|
url = url + "/" + res[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
img := e.Data(url)
|
||||||
|
if len(img) != 0 {
|
||||||
|
return storeImg(img, title, res[2])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
txt, err = it.Next()
|
||||||
|
}
|
||||||
|
return "", ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func storeImg(img []byte, title, extension string) (string, string) {
|
||||||
|
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 */
|
||||||
|
imgPath := validFileName(COVER_PATH, title, extension)
|
||||||
|
fBig, err := os.Create(COVER_PATH + imgPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Error creating", COVER_PATH+imgPath, ":", err.Error())
|
||||||
|
return "", ""
|
||||||
|
}
|
||||||
|
defer fBig.Close()
|
||||||
|
|
||||||
|
imgPathSmall := validFileName(COVER_PATH, title, "_small"+extension)
|
||||||
|
fSmall, err := os.Create(COVER_PATH + imgPathSmall)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Error creating", COVER_PATH+imgPathSmall, ":", err.Error())
|
||||||
|
return "", ""
|
||||||
|
}
|
||||||
|
defer fSmall.Close()
|
||||||
|
|
||||||
|
/* resize img */
|
||||||
|
jpgOptions := jpeg.Options{IMG_QUALITY}
|
||||||
|
imgResized, err := resizeImg(img, IMG_WIDTH_BIG)
|
||||||
|
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 "", ""
|
||||||
|
}
|
||||||
|
imgSmallResized, err := resizeImg(img, IMG_WIDTH_SMALL)
|
||||||
|
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 "", ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return imgPath, imgPathSmall
|
||||||
|
}
|
||||||
|
|
||||||
|
func resizeImg(imgBuff []byte, width uint) (image.Image, error) {
|
||||||
|
reader := bytes.NewReader(imgBuff)
|
||||||
|
img, _, err := image.Decode(reader)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resize.Resize(width, 0, img, resize.NearestNeighbor), nil
|
||||||
|
}
|
78
store.go
78
store.go
|
@ -38,7 +38,7 @@ func ParseFile(path string) (string, error) {
|
||||||
book["rights"] = strings.Join(e.Metadata(epub.EPUB_RIGHTS), ", ")
|
book["rights"] = strings.Join(e.Metadata(epub.EPUB_RIGHTS), ", ")
|
||||||
book["meta"] = strings.Join(e.Metadata(epub.EPUB_META), ", ")
|
book["meta"] = strings.Join(e.Metadata(epub.EPUB_META), ", ")
|
||||||
book["path"] = path
|
book["path"] = path
|
||||||
cover, coverSmall := getCover(e, title)
|
cover, coverSmall := GetCover(e, title)
|
||||||
book["cover"] = cover
|
book["cover"] = cover
|
||||||
book["coversmall"] = coverSmall
|
book["coversmall"] = coverSmall
|
||||||
book["keywords"] = keywords(book)
|
book["keywords"] = keywords(book)
|
||||||
|
@ -128,82 +128,6 @@ func cleanStr(str string) string {
|
||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
|
|
||||||
func storeImg(img []byte, title, extension string) (string, string) {
|
|
||||||
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 "", ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
imgPath := validFileName(COVER_PATH, title, extension)
|
|
||||||
|
|
||||||
/* store img on disk */
|
|
||||||
file, err := os.Create(COVER_PATH + imgPath)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("Error creating", COVER_PATH+imgPath, ":", err.Error())
|
|
||||||
return "", ""
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
file.Write(img)
|
|
||||||
|
|
||||||
/* resize img */
|
|
||||||
resize := append(strings.Split(RESIZE_CMD, " "), COVER_PATH+imgPath, COVER_PATH+imgPath)
|
|
||||||
cmd := exec.Command(resize[0], resize[1:]...)
|
|
||||||
cmd.Run()
|
|
||||||
imgPathSmall := validFileName(COVER_PATH, title, "_small"+extension)
|
|
||||||
resize = append(strings.Split(RESIZE_THUMB_CMD, " "), COVER_PATH+imgPath, COVER_PATH+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 */
|
|
||||||
for _, p := range []string{"cover.jpg", "Images/cover.jpg", "cover.jpeg", "cover1.jpg", "cover1.jpeg"} {
|
|
||||||
img := e.Data(p)
|
|
||||||
if len(img) != 0 {
|
|
||||||
return storeImg(img, title, ".jpg")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* search for img on the text */
|
|
||||||
exp, _ := regexp.Compile("<ima?g.*[(src)(href)]=[\"']([^\"']*(\\.[^\\.\"']*))[\"']")
|
|
||||||
it := e.Iterator(epub.EITERATOR_SPINE)
|
|
||||||
defer it.Close()
|
|
||||||
var err error = nil
|
|
||||||
txt := it.Curr()
|
|
||||||
for err == nil {
|
|
||||||
res := exp.FindStringSubmatch(txt)
|
|
||||||
if res != nil {
|
|
||||||
urlPart := strings.Split(it.CurrUrl(), "/")
|
|
||||||
url := strings.Join(urlPart[:len(urlPart)-1], "/")
|
|
||||||
if res[1][:3] == "../" {
|
|
||||||
res[1] = res[1][3:]
|
|
||||||
url = strings.Join(urlPart[:len(urlPart)-2], "/")
|
|
||||||
}
|
|
||||||
res[1] = strings.Replace(res[1], "%20", " ", -1)
|
|
||||||
res[1] = strings.Replace(res[1], "%27", "'", -1)
|
|
||||||
res[1] = strings.Replace(res[1], "%28", "(", -1)
|
|
||||||
res[1] = strings.Replace(res[1], "%29", ")", -1)
|
|
||||||
if url == "" {
|
|
||||||
url = res[1]
|
|
||||||
} else {
|
|
||||||
url = url + "/" + res[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
img := e.Data(url)
|
|
||||||
if len(img) != 0 {
|
|
||||||
return storeImg(img, title, res[2])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
txt, err = it.Next()
|
|
||||||
}
|
|
||||||
return "", ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseAuthr(creator []string) []string {
|
func parseAuthr(creator []string) []string {
|
||||||
exp1, _ := regexp.Compile("^(.*\\( *([^\\)]*) *\\))*$")
|
exp1, _ := regexp.Compile("^(.*\\( *([^\\)]*) *\\))*$")
|
||||||
exp2, _ := regexp.Compile("^[^:]*: *(.*)$")
|
exp2, _ := regexp.Compile("^[^:]*: *(.*)$")
|
||||||
|
|
Reference in a new issue