diff --git a/admin.go b/admin.go index a52298f..451f631 100644 --- a/admin.go +++ b/admin.go @@ -5,7 +5,6 @@ import ( "net/http" "os" "os/exec" - "strconv" "strings" ) @@ -162,19 +161,6 @@ func newHandler(w http.ResponseWriter, r *http.Request) { loadTemplate(w, "new", data) } -func ValidFileName(path string, title string, extension string) string { - title = strings.Replace(title, "/", "_", -1) - title = strings.Replace(title, "?", "_", -1) - title = strings.Replace(title, "#", "_", -1) - file := path + "/" + title + extension - _, err := os.Stat(file) - for i := 0; err == nil; i++ { - file = path + "/" + title + "_" + strconv.Itoa(i) + extension - _, err = os.Stat(file) - } - return file -} - func storeHandler(w http.ResponseWriter, r *http.Request) { sess := GetSession(r) if sess.User == "" { diff --git a/store.go b/store.go new file mode 100644 index 0000000..300f844 --- /dev/null +++ b/store.go @@ -0,0 +1,224 @@ +package main + +import ( + "git.gitorious.org/go-pkg/epub.git" + "io" + "os" + "os/exec" + "regexp" + "strconv" + "strings" +) + +func ParseFile(path string) (string, error) { + book := map[string]interface{}{} + + e, err := epub.Open(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 StoreFile(name string, file io.Reader) (string, error) { + path := storePath(name) + fw, err := os.Create(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 ValidFileName(path string, title string, extension string) string { + title = strings.Replace(title, "/", "_", -1) + title = strings.Replace(title, "?", "_", -1) + title = strings.Replace(title, "#", "_", -1) + file := path + "/" + title + extension + _, err := os.Stat(file) + for i := 0; err == nil; i++ { + file = path + "/" + title + "_" + strconv.Itoa(i) + extension + _, err = os.Stat(file) + } + return file +} + +func storePath(name string) string { + path := NEW_PATH + name + _, err := os.Stat(path) + for i := 0; err == nil; i++ { + path = NEW_PATH + strconv.Itoa(i) + "_" + name + _, err = os.Stat(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) { + folder := COVER_PATH + title[:1] + os.Mkdir(folder, os.ModePerm) + imgPath := ValidFileName(folder, title, extension) + + /* store img on disk */ + file, err := os.Create(imgPath) + if err != nil { + return "", "" + } + defer file.Close() + file.Write(img) + + /* resize img */ + resize := append(strings.Split(RESIZE_CMD, " "), imgPath, imgPath) + cmd := exec.Command(resize[0], resize[1:]...) + cmd.Run() + imgPathSmall := ValidFileName(folder, title, "_small"+extension) + resize = append(strings.Split(RESIZE_THUMB_CMD, " "), imgPath, 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 +} diff --git a/upload.go b/upload.go index 53761c8..d0a873e 100644 --- a/upload.go +++ b/upload.go @@ -1,26 +1,11 @@ package main import ( - "git.gitorious.org/go-pkg/epub.git" "log" "net/http" "os" - "os/exec" - "regexp" - "strconv" - "strings" ) -func storePath(name string) string { - path := NEW_PATH + name - _, err := os.Stat(path) - for i := 0; err == nil; i++ { - path = NEW_PATH + strconv.Itoa(i) + "_" + name - _, err = os.Stat(path) - } - return path -} - func storeFiles(r *http.Request) ([]string, error) { r.ParseMultipartForm(20000000) filesForm := r.MultipartForm.File["epub"] @@ -33,197 +18,15 @@ func storeFiles(r *http.Request) ([]string, error) { } defer file.Close() - path := storePath(f.Filename) - fw, err := os.Create(path) + path, err := StoreFile(f.Filename, file) if err != nil { return paths, 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) - } paths = append(paths, path) } return paths, nil } -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) { - folder := COVER_PATH + title[:1] - os.Mkdir(folder, os.ModePerm) - imgPath := ValidFileName(folder, title, extension) - - /* store img on disk */ - file, err := os.Create(imgPath) - if err != nil { - return "", "" - } - defer file.Close() - file.Write(img) - - /* resize img */ - resize := append(strings.Split(RESIZE_CMD, " "), imgPath, imgPath) - cmd := exec.Command(resize[0], resize[1:]...) - cmd.Run() - imgPathSmall := ValidFileName(folder, title, "_small"+extension) - resize = append(strings.Split(RESIZE_THUMB_CMD, " "), imgPath, 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 -} - -func parseFile(path string) (string, error) { - book := map[string]interface{}{} - - e, err := epub.Open(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 -} - type uploadData struct { S Status } @@ -238,7 +41,7 @@ func uploadHandler(w http.ResponseWriter, r *http.Request) { uploaded := "" for _, path := range paths { - title, err := parseFile(path) + title, err := ParseFile(path) if err != nil { os.Remove(path) sess.Notify("Problem uploading!", "The file '"+path[len("new/"):]+"' is not a well formed epub", "error")