package main import ( log "github.com/cihub/seelog" "bytes" "crypto/rand" "encoding/base64" "io/ioutil" "mime/multipart" "github.com/meskio/epubgo" "gitlab.com/trantor/trantor/database" "gitlab.com/trantor/trantor/parser" "gitlab.com/trantor/trantor/storage" ) func InitUpload(database *database.DB, store *storage.Store) { uploadChannel = make(chan uploadRequest, CHAN_SIZE) go uploadWorker(database, store) } var uploadChannel chan uploadRequest type uploadRequest struct { file multipart.File filename string } func uploadWorker(database *database.DB, store *storage.Store) { db := database.Copy() defer db.Close() for req := range uploadChannel { processFile(req, db, store) } } func processFile(req uploadRequest, db *database.DB, store *storage.Store) { defer req.file.Close() epub, err := openMultipartEpub(req.file) if err != nil { log.Warn("Not valid epub uploaded file ", req.filename, ": ", err) return } defer epub.Close() id := genId() metadata := parser.EpubMetadata(epub) metadata["id"] = id metadata["cover"] = GetCover(epub, id, store) req.file.Seek(0, 0) size, err := store.Store(id, req.file, EPUB_FILE) if err != nil { log.Error("Error storing book (", id, "): ", err) return } metadata["filesize"] = size err = db.AddBook(metadata) if err != nil { log.Error("Error storing metadata (", id, "): ", err) return } log.Info("File uploaded: ", req.filename) } func uploadPostHandler(h handler) { problem := false h.r.ParseMultipartForm(20000000) filesForm := h.r.MultipartForm.File["epub"] for _, f := range filesForm { file, err := f.Open() if err != nil { log.Error("Can not open uploaded file ", f.Filename, ": ", err) h.sess.Notify("Upload problem!", "There was a problem with book "+f.Filename, "error") problem = true continue } uploadChannel <- uploadRequest{file, f.Filename} } if !problem { if len(filesForm) > 0 { h.sess.Notify("Upload successful!", "Thank you for your contribution", "success") } else { h.sess.Notify("Upload problem!", "No books where uploaded.", "error") } } uploadHandler(h) } func uploadHandler(h handler) { var data uploadData data.S = GetStatus(h) data.S.Title = "Upload -- " + data.S.Title data.S.Upload = true loadTemplate(h, "upload", data) } type uploadData struct { S Status } func openMultipartEpub(file multipart.File) (*epubgo.Epub, error) { buff, _ := ioutil.ReadAll(file) reader := bytes.NewReader(buff) return epubgo.Load(reader, int64(len(buff))) } func genId() string { b := make([]byte, 12) rand.Read(b) return base64.URLEncoding.EncodeToString(b) }