This repository has been archived on 2025-03-01. You can view files and clone it, but cannot push or open issues or pull requests.
trantor/upload.go
2016-01-28 18:13:26 -05:00

118 lines
2.6 KiB
Go

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)
}