package main import ( "git.gitorious.org/go-pkg/epub.git" "io" "log" "os" "os/exec" "regexp" "strconv" "strings" "unicode/utf8" ) func ParseFile(path string) (string, error) { book := map[string]interface{}{} e, err := epub.Open(NEW_PATH+path, 0) if err != nil { return "", err } defer e.Close() title := cleanStr(strings.Join(e.Metadata(epub.EPUB_TITLE), ", ")) book["title"] = title book["author"] = parseAuthr(e.Metadata(epub.EPUB_CREATOR)) book["contributor"] = cleanStr(strings.Join(e.Metadata(epub.EPUB_CONTRIB), ", ")) book["publisher"] = cleanStr(strings.Join(e.Metadata(epub.EPUB_PUBLISHER), ", ")) book["description"] = parseDescription(e.Metadata(epub.EPUB_DESCRIPTION)) book["subject"] = parseSubject(e.Metadata(epub.EPUB_SUBJECT)) book["date"] = parseDate(e.Metadata(epub.EPUB_DATE)) book["lang"] = e.Metadata(epub.EPUB_LANG) book["type"] = strings.Join(e.Metadata(epub.EPUB_TYPE), ", ") book["format"] = strings.Join(e.Metadata(epub.EPUB_FORMAT), ", ") book["source"] = strings.Join(e.Metadata(epub.EPUB_SOURCE), ", ") book["relation"] = strings.Join(e.Metadata(epub.EPUB_RELATION), ", ") book["coverage"] = strings.Join(e.Metadata(epub.EPUB_COVERAGE), ", ") book["rights"] = strings.Join(e.Metadata(epub.EPUB_RIGHTS), ", ") book["meta"] = strings.Join(e.Metadata(epub.EPUB_META), ", ") book["path"] = path cover, coverSmall := getCover(e, title) book["cover"] = cover book["coversmall"] = coverSmall book["keywords"] = keywords(book) db.InsertBook(book) return title, nil } func StoreNewFile(name string, file io.Reader) (string, error) { path := storePath(name) fw, err := os.Create(NEW_PATH + path) if err != nil { return "", err } defer fw.Close() const size = 1024 var n int = size buff := make([]byte, size) for n == size { n, err = file.Read(buff) fw.Write(buff) } return path, nil } func StoreBook(book Book) (path string, err error) { title := book.Title path = validFileName(BOOKS_PATH, title, ".epub") oldPath := NEW_PATH + book.Path r, _ := utf8.DecodeRuneInString(title) folder := string(r) if _, err = os.Stat(BOOKS_PATH + folder); err != nil { err = os.Mkdir(BOOKS_PATH+folder, os.ModePerm) if err != nil { log.Println("Error creating", BOOKS_PATH+folder, ":", err.Error()) return } } cmd := exec.Command("mv", oldPath, BOOKS_PATH+path) err = cmd.Run() return } func DeleteBook(book Book) { if book.Cover != "" { os.RemoveAll(book.Cover[1:]) } if book.CoverSmall != "" { os.RemoveAll(book.CoverSmall[1:]) } os.RemoveAll(book.Path) } func validFileName(path string, title string, extension string) string { title = strings.Replace(title, "/", "_", -1) title = strings.Replace(title, "?", "_", -1) 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 } func storePath(name string) string { path := name _, err := os.Stat(NEW_PATH + path) for i := 0; err == nil; i++ { path = strconv.Itoa(i) + "_" + name _, err = os.Stat(NEW_PATH + path) } return path } 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 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("]*>") 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 }