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/lib/upload.go

160 lines
3.8 KiB
Go
Raw Normal View History

2016-05-02 21:36:49 -04:00
package trantor
2012-08-15 11:40:19 +02:00
import (
2014-08-30 13:17:50 -05:00
log "github.com/cihub/seelog"
2013-04-16 02:33:40 +02:00
"bytes"
2014-08-21 19:24:23 -05:00
"crypto/rand"
"encoding/base64"
2013-04-16 02:33:40 +02:00
"io/ioutil"
"mime/multipart"
"github.com/gorilla/mux"
2015-04-21 21:32:01 -04:00
"github.com/meskio/epubgo"
2016-05-02 21:36:49 -04:00
"gitlab.com/trantor/trantor/lib/database"
"gitlab.com/trantor/trantor/lib/parser"
"gitlab.com/trantor/trantor/lib/storage"
2012-08-20 14:25:18 +02:00
)
const (
uploadChanSize = 100
)
2017-05-21 10:16:16 +00:00
func InitUpload(database database.DB, store storage.Store) {
uploadChannel = make(chan uploadRequest, uploadChanSize)
2014-08-21 19:24:23 -05:00
go uploadWorker(database, store)
2013-05-03 00:43:26 +02:00
}
2013-04-16 02:33:40 +02:00
2013-05-03 00:43:26 +02:00
var uploadChannel chan uploadRequest
2013-04-16 02:34:15 +02:00
2013-05-03 00:43:26 +02:00
type uploadRequest struct {
2013-07-16 22:56:48 +02:00
file multipart.File
filename string
id int
2013-05-03 00:43:26 +02:00
}
2013-04-16 02:34:15 +02:00
2017-05-21 10:16:16 +00:00
func uploadWorker(database database.DB, store storage.Store) {
2013-05-03 00:43:26 +02:00
for req := range uploadChannel {
processFile(req, database, store)
2013-07-16 22:56:48 +02:00
}
}
2013-05-03 00:43:26 +02:00
2017-05-21 10:16:16 +00:00
func processFile(req uploadRequest, db database.DB, store storage.Store) {
2013-07-16 22:56:48 +02:00
defer req.file.Close()
2013-05-03 00:43:26 +02:00
2013-07-16 22:56:48 +02:00
epub, err := openMultipartEpub(req.file)
if err != nil {
2014-02-11 13:13:43 +01:00
log.Warn("Not valid epub uploaded file ", req.filename, ": ", err)
db.UpdateSubmission(req.id, "It is not a valid epub file", nil)
2013-07-16 22:56:48 +02:00
return
}
defer epub.Close()
2013-05-03 00:43:26 +02:00
book := parser.EpubMetadata(epub)
2016-07-30 07:59:30 -04:00
book.ID = genID()
2013-07-16 22:56:48 +02:00
req.file.Seek(0, 0)
2016-07-30 07:59:30 -04:00
size, err := store.Store(book.ID, req.file, epubFile)
2013-07-16 22:56:48 +02:00
if err != nil {
2016-07-30 07:59:30 -04:00
log.Error("Error storing book (", book.ID, "): ", err)
db.UpdateSubmission(req.id, "There was a problem in our server", nil)
2013-07-16 22:56:48 +02:00
return
2012-08-15 13:58:16 +02:00
}
2013-07-16 22:56:48 +02:00
book.FileSize = int(size)
2016-07-30 07:59:30 -04:00
book.Cover = GetCover(epub, book.ID, store)
err = db.AddBook(book)
2013-07-23 22:40:35 +02:00
if err != nil {
2016-07-30 07:59:30 -04:00
log.Error("Error storing metadata (", book.ID, "): ", err)
db.UpdateSubmission(req.id, "There was a problem in our server", nil)
2013-07-23 22:40:35 +02:00
return
}
2014-02-11 13:13:43 +01:00
log.Info("File uploaded: ", req.filename)
db.UpdateSubmission(req.id, "Waiting for moderation", &book)
2013-05-03 00:43:26 +02:00
}
func uploadPostHandler(h handler) {
2017-05-21 10:16:16 +00:00
if h.ro {
h.sess.Notify("Upload failed!", "The library is in Read Only mode, no books can be uploaded", "error")
uploadHandler(h)
return
}
h.r.ParseMultipartForm(20000000)
filesForm := h.r.MultipartForm.File["epub"]
submissionID := genID()
2013-07-16 22:56:48 +02:00
for _, f := range filesForm {
submission := database.Submission{
SubmissionID: submissionID,
Filename: f.Filename,
Status: "Waiting to be processed",
}
2013-07-16 22:56:48 +02:00
file, err := f.Open()
if err != nil {
2014-02-11 13:13:43 +01:00
log.Error("Can not open uploaded file ", f.Filename, ": ", err)
h.sess.Notify("Upload problem!", "There was a problem with book "+f.Filename, "error")
submission.Status = "It was not possible to read the book"
h.db.AddSubmission(submission)
2013-07-16 22:56:48 +02:00
continue
}
2013-05-03 00:43:26 +02:00
id, err := h.db.AddSubmission(submission)
if err != nil {
log.Error("Can add submission to db for ", f.Filename, ": ", err)
2013-07-16 22:56:48 +02:00
}
uploadChannel <- uploadRequest{file, f.Filename, id}
2013-05-03 00:43:26 +02:00
}
_uploadHandler(h, submissionID)
2013-04-16 02:34:15 +02:00
}
func uploadHandler(h handler) {
_uploadHandler(h, "")
}
func _uploadHandler(h handler, submissionID string) {
var data uploadData
data.SubmissionID = submissionID
data.S = GetStatus(h)
data.S.Title = "Upload -- " + data.S.Title
data.S.Upload = true
h.load("upload", data)
2012-08-15 11:40:19 +02:00
}
2013-04-16 02:33:40 +02:00
type uploadData struct {
S Status
SubmissionID string
}
func submissionHandler(h handler) {
var data submissionData
var err error
submissionID := mux.Vars(h.r)["id"]
data.Submissions, err = h.db.GetSubmission(submissionID)
if err != nil {
log.Error("Can get submission ", submissionID, ": ", err)
}
data.S = GetStatus(h)
data.S.Title = "Submission -- " + data.S.Title
h.load("submission", data)
}
type submissionData struct {
S Status
Submissions []database.Submission
2013-04-16 02:33:40 +02:00
}
func openMultipartEpub(file multipart.File) (*epubgo.Epub, error) {
buff, _ := ioutil.ReadAll(file)
reader := bytes.NewReader(buff)
return epubgo.Load(reader, int64(len(buff)))
}
2016-07-30 07:59:30 -04:00
func genID() string {
2014-08-21 19:24:23 -05:00
b := make([]byte, 12)
rand.Read(b)
return base64.URLEncoding.EncodeToString(b)
}