2012-10-28 17:04:38 +01:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2013-04-01 14:05:04 +02:00
|
|
|
"git.gitorious.org/go-pkg/epubgo.git"
|
2012-10-28 17:04:38 +01:00
|
|
|
"io"
|
2013-04-12 01:05:40 +02:00
|
|
|
"labix.org/v2/mgo"
|
|
|
|
"labix.org/v2/mgo/bson"
|
2012-10-28 17:04:38 +01:00
|
|
|
"os"
|
|
|
|
"regexp"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
2012-10-28 23:19:22 +01:00
|
|
|
"unicode/utf8"
|
2012-10-28 17:04:38 +01:00
|
|
|
)
|
|
|
|
|
2013-04-12 01:05:40 +02:00
|
|
|
func ParseFile(id bson.ObjectId) (string, error) {
|
2012-10-28 17:04:38 +01:00
|
|
|
book := map[string]interface{}{}
|
|
|
|
|
2013-04-12 01:05:40 +02:00
|
|
|
e, err := OpenBook(id)
|
2012-10-28 17:04:38 +01:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
defer e.Close()
|
|
|
|
|
2013-04-01 14:05:04 +02:00
|
|
|
for _, m := range e.MetadataFields() {
|
|
|
|
data, err := e.Metadata(m)
|
|
|
|
if err != nil {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
switch m {
|
|
|
|
case "creator":
|
|
|
|
book["author"] = parseAuthr(data)
|
|
|
|
case "description":
|
|
|
|
book[m] = parseDescription(data)
|
|
|
|
case "subject":
|
|
|
|
book[m] = parseSubject(data)
|
|
|
|
case "date":
|
|
|
|
book[m] = parseDate(data)
|
|
|
|
case "language":
|
|
|
|
book["lang"] = data
|
|
|
|
case "title", "contributor", "publisher":
|
|
|
|
book[m] = cleanStr(strings.Join(data, ", "))
|
2013-04-08 01:41:46 +02:00
|
|
|
case "identifier":
|
|
|
|
attr, _ := e.MetadataAttr(m)
|
|
|
|
for i, d := range data {
|
|
|
|
if attr[i]["scheme"] == "ISBN" {
|
|
|
|
book["isbn"] = d
|
|
|
|
}
|
|
|
|
}
|
2013-04-01 14:05:04 +02:00
|
|
|
default:
|
|
|
|
book[m] = strings.Join(data, ", ")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
title, _ := book["title"].(string)
|
2013-04-12 01:05:40 +02:00
|
|
|
book["file"] = id
|
2013-03-20 21:25:53 +01:00
|
|
|
cover, coverSmall := GetCover(e, title)
|
2012-10-28 17:04:38 +01:00
|
|
|
book["cover"] = cover
|
|
|
|
book["coversmall"] = coverSmall
|
|
|
|
book["keywords"] = keywords(book)
|
|
|
|
|
|
|
|
db.InsertBook(book)
|
|
|
|
return title, nil
|
|
|
|
}
|
|
|
|
|
2013-04-12 01:05:40 +02:00
|
|
|
func OpenBook(id bson.ObjectId) (*epubgo.Epub, error) {
|
|
|
|
fs := db.GetFS(FS_BOOKS)
|
|
|
|
var reader readerGrid
|
|
|
|
var err error
|
|
|
|
reader.f, err = fs.OpenId(id)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer reader.f.Close()
|
|
|
|
return epubgo.Load(reader, reader.f.Size())
|
|
|
|
}
|
|
|
|
|
|
|
|
type readerGrid struct {
|
|
|
|
f *mgo.GridFile
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r readerGrid) ReadAt(p []byte, off int64) (n int, err error) {
|
|
|
|
_, err = r.f.Seek(off, 0)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
return r.f.Read(p)
|
|
|
|
}
|
|
|
|
|
|
|
|
func StoreNewFile(name string, file io.Reader) (bson.ObjectId, error) {
|
|
|
|
fs := db.GetFS(FS_BOOKS)
|
|
|
|
fw, err := fs.Create(name)
|
2012-10-28 17:04:38 +01:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
defer fw.Close()
|
|
|
|
|
2013-04-01 14:05:04 +02:00
|
|
|
_, err = io.Copy(fw, file)
|
2013-04-12 01:05:40 +02:00
|
|
|
id, _ := fw.Id().(bson.ObjectId)
|
|
|
|
return id, err
|
2012-10-28 17:04:38 +01:00
|
|
|
}
|
|
|
|
|
2013-04-12 01:05:40 +02:00
|
|
|
func DeleteFile(id bson.ObjectId) error {
|
|
|
|
fs := db.GetFS(FS_BOOKS)
|
|
|
|
return fs.RemoveId(id)
|
2012-10-28 17:22:23 +01:00
|
|
|
}
|
|
|
|
|
2012-10-28 17:27:01 +01:00
|
|
|
func DeleteBook(book Book) {
|
|
|
|
if book.Cover != "" {
|
|
|
|
os.RemoveAll(book.Cover[1:])
|
|
|
|
}
|
|
|
|
if book.CoverSmall != "" {
|
|
|
|
os.RemoveAll(book.CoverSmall[1:])
|
|
|
|
}
|
2013-04-12 01:05:40 +02:00
|
|
|
DeleteFile(book.File)
|
2012-10-28 17:27:01 +01:00
|
|
|
}
|
|
|
|
|
2012-10-28 17:22:23 +01:00
|
|
|
func validFileName(path string, title string, extension string) string {
|
2012-10-28 17:04:38 +01:00
|
|
|
title = strings.Replace(title, "/", "_", -1)
|
|
|
|
title = strings.Replace(title, "?", "_", -1)
|
|
|
|
title = strings.Replace(title, "#", "_", -1)
|
2012-10-29 19:18:57 +01:00
|
|
|
r, _ := utf8.DecodeRuneInString(title)
|
2012-10-28 23:19:22 +01:00
|
|
|
folder := string(r)
|
|
|
|
file := folder + "/" + title + extension
|
2012-10-28 20:21:46 +01:00
|
|
|
_, err := os.Stat(path + file)
|
2012-10-28 17:04:38 +01:00
|
|
|
for i := 0; err == nil; i++ {
|
2012-10-28 23:19:22 +01:00
|
|
|
file = folder + "/" + title + "_" + strconv.Itoa(i) + extension
|
2012-10-28 20:21:46 +01:00
|
|
|
_, err = os.Stat(path + file)
|
2012-10-28 17:04:38 +01:00
|
|
|
}
|
|
|
|
return file
|
|
|
|
}
|
|
|
|
|
|
|
|
func cleanStr(str string) string {
|
|
|
|
str = strings.Replace(str, "'", "'", -1)
|
|
|
|
exp, _ := regexp.Compile("&[^;]*;")
|
|
|
|
str = exp.ReplaceAllString(str, "")
|
|
|
|
exp, _ = regexp.Compile("[ ,]*$")
|
|
|
|
str = exp.ReplaceAllString(str, "")
|
|
|
|
return str
|
|
|
|
}
|
|
|
|
|
|
|
|
func parseAuthr(creator []string) []string {
|
|
|
|
exp1, _ := regexp.Compile("^(.*\\( *([^\\)]*) *\\))*$")
|
|
|
|
exp2, _ := regexp.Compile("^[^:]*: *(.*)$")
|
|
|
|
res := make([]string, len(creator))
|
|
|
|
for i, s := range creator {
|
|
|
|
auth := exp1.FindStringSubmatch(s)
|
|
|
|
if auth != nil {
|
|
|
|
res[i] = cleanStr(strings.Join(auth[2:], ", "))
|
|
|
|
} else {
|
|
|
|
auth := exp2.FindStringSubmatch(s)
|
|
|
|
if auth != nil {
|
|
|
|
res[i] = cleanStr(auth[1])
|
|
|
|
} else {
|
|
|
|
res[i] = cleanStr(s)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return res
|
|
|
|
}
|
|
|
|
|
|
|
|
func parseDescription(description []string) string {
|
|
|
|
str := cleanStr(strings.Join(description, ", "))
|
|
|
|
exp, _ := regexp.Compile("<[^>]*>")
|
|
|
|
str = exp.ReplaceAllString(str, "")
|
|
|
|
str = strings.Replace(str, "&", "&", -1)
|
|
|
|
str = strings.Replace(str, "<", "<", -1)
|
|
|
|
str = strings.Replace(str, ">", ">", -1)
|
|
|
|
str = strings.Replace(str, "\\n", "\n", -1)
|
|
|
|
return str
|
|
|
|
}
|
|
|
|
|
|
|
|
func parseSubject(subject []string) []string {
|
|
|
|
var res []string
|
|
|
|
for _, s := range subject {
|
|
|
|
res = append(res, strings.Split(s, " / ")...)
|
|
|
|
}
|
|
|
|
return res
|
|
|
|
}
|
|
|
|
|
|
|
|
func parseDate(date []string) string {
|
|
|
|
if len(date) == 0 {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
return strings.Replace(date[0], "Unspecified: ", "", -1)
|
|
|
|
}
|
|
|
|
|
|
|
|
func keywords(b map[string]interface{}) (k []string) {
|
|
|
|
title, _ := b["title"].(string)
|
|
|
|
k = strings.Split(title, " ")
|
|
|
|
author, _ := b["author"].([]string)
|
|
|
|
for _, a := range author {
|
|
|
|
k = append(k, strings.Split(a, " ")...)
|
|
|
|
}
|
|
|
|
publisher, _ := b["publisher"].(string)
|
|
|
|
k = append(k, strings.Split(publisher, " ")...)
|
|
|
|
subject, _ := b["subject"].([]string)
|
|
|
|
k = append(k, subject...)
|
|
|
|
return
|
|
|
|
}
|