2016-05-02 21:36:49 -04:00
|
|
|
package trantor
|
2012-08-15 11:40:19 +02:00
|
|
|
|
|
|
|
import (
|
2018-04-07 22:58:59 +00:00
|
|
|
"net/http"
|
|
|
|
|
2014-08-30 13:17:50 -05:00
|
|
|
log "github.com/cihub/seelog"
|
|
|
|
|
2014-08-21 19:24:23 -05:00
|
|
|
"crypto/rand"
|
|
|
|
"encoding/base64"
|
2013-04-16 02:33:40 +02:00
|
|
|
"mime/multipart"
|
2014-08-30 01:25:16 -05:00
|
|
|
|
2017-09-21 12:09:04 +00:00
|
|
|
"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
|
|
|
)
|
|
|
|
|
2016-05-03 01:03:23 -04:00
|
|
|
const (
|
|
|
|
uploadChanSize = 100
|
|
|
|
)
|
|
|
|
|
2017-05-21 10:16:16 +00:00
|
|
|
func InitUpload(database database.DB, store storage.Store) {
|
2016-05-03 01:03:23 -04:00
|
|
|
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 {
|
2017-09-26 23:46:03 +00:00
|
|
|
file multipart.File
|
|
|
|
header *multipart.FileHeader
|
|
|
|
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 {
|
2017-09-26 23:46:03 +00:00
|
|
|
req.processFile(database, store)
|
2013-07-16 22:56:48 +02:00
|
|
|
}
|
|
|
|
}
|
2013-05-03 00:43:26 +02:00
|
|
|
|
2017-09-26 23:46:03 +00:00
|
|
|
func (req uploadRequest) processFile(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
|
|
|
|
2017-09-26 23:46:03 +00:00
|
|
|
epub, err := epubgo.Load(req.file, req.header.Size)
|
2013-07-16 22:56:48 +02:00
|
|
|
if err != nil {
|
2017-09-26 23:46:03 +00:00
|
|
|
log.Warn("Not valid epub uploaded file ", req.header.Filename, ": ", err)
|
2017-09-21 12:09:04 +00:00
|
|
|
db.UpdateSubmission(req.id, "It is not a valid epub file", nil)
|
2013-07-16 22:56:48 +02:00
|
|
|
}
|
|
|
|
defer epub.Close()
|
2013-05-03 00:43:26 +02:00
|
|
|
|
2016-07-30 07:10:33 -04:00
|
|
|
book := parser.EpubMetadata(epub)
|
2016-07-30 07:59:30 -04:00
|
|
|
book.ID = genID()
|
2015-01-25 23:37:52 -05:00
|
|
|
|
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)
|
2017-09-21 12:09:04 +00:00
|
|
|
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
|
|
|
|
2016-07-30 07:10:33 -04:00
|
|
|
book.FileSize = int(size)
|
2016-07-30 07:59:30 -04:00
|
|
|
book.Cover = GetCover(epub, book.ID, store)
|
2016-07-30 07:10:33 -04:00
|
|
|
|
|
|
|
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)
|
2017-09-21 12:09:04 +00:00
|
|
|
db.UpdateSubmission(req.id, "There was a problem in our server", nil)
|
2013-07-23 22:40:35 +02:00
|
|
|
return
|
|
|
|
}
|
2017-09-26 23:46:03 +00:00
|
|
|
log.Info("File uploaded: ", req.header.Filename)
|
2017-09-21 12:09:04 +00:00
|
|
|
db.UpdateSubmission(req.id, "Waiting for moderation", &book)
|
2013-05-03 00:43:26 +02:00
|
|
|
}
|
2012-09-12 00:19:19 +02:00
|
|
|
|
2013-09-23 16:27:31 +02:00
|
|
|
func uploadPostHandler(h handler) {
|
2017-09-26 23:46:03 +00:00
|
|
|
const _2M int64 = (1 << 20) * 2
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2017-09-26 23:46:03 +00:00
|
|
|
if err := h.r.ParseMultipartForm(_2M); nil != err {
|
|
|
|
log.Error("Can't parse form: ", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
defer h.r.MultipartForm.RemoveAll()
|
|
|
|
|
2013-09-23 16:27:31 +02:00
|
|
|
filesForm := h.r.MultipartForm.File["epub"]
|
2017-09-21 12:09:04 +00:00
|
|
|
submissionID := genID()
|
2013-07-16 22:56:48 +02:00
|
|
|
for _, f := range filesForm {
|
2017-09-21 12:09:04 +00:00
|
|
|
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)
|
2013-09-23 16:27:31 +02:00
|
|
|
h.sess.Notify("Upload problem!", "There was a problem with book "+f.Filename, "error")
|
2017-09-21 12:09:04 +00:00
|
|
|
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
|
|
|
|
2017-09-21 12:09:04 +00: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
|
|
|
}
|
2017-09-26 23:46:03 +00:00
|
|
|
uploadChannel <- uploadRequest{file, f, id}
|
2013-05-03 00:43:26 +02:00
|
|
|
}
|
2018-04-07 22:58:59 +00:00
|
|
|
http.Redirect(h.w, h.r, "/submission/"+submissionID, http.StatusFound)
|
2013-04-16 02:34:15 +02:00
|
|
|
}
|
|
|
|
|
2013-09-23 16:27:31 +02:00
|
|
|
func uploadHandler(h handler) {
|
2018-04-07 22:58:59 +00:00
|
|
|
var data struct{ S Status }
|
2013-09-23 16:27:31 +02:00
|
|
|
data.S = GetStatus(h)
|
2016-01-28 18:13:26 -05:00
|
|
|
data.S.Title = "Upload -- " + data.S.Title
|
2012-09-12 00:19:19 +02:00
|
|
|
data.S.Upload = true
|
2017-06-06 14:18:47 +00:00
|
|
|
h.load("upload", data)
|
2012-08-15 11:40:19 +02:00
|
|
|
}
|
2013-04-16 02:33:40 +02:00
|
|
|
|
2017-09-21 12:09:04 +00:00
|
|
|
func submissionHandler(h handler) {
|
|
|
|
var data submissionData
|
|
|
|
var err error
|
|
|
|
|
2018-04-07 22:58:59 +00:00
|
|
|
submissionID := mux.Vars(h.r)["submissionID"]
|
|
|
|
data.SubmissionID = submissionID
|
2017-09-21 12:09:04 +00:00
|
|
|
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 {
|
2018-04-07 22:58:59 +00:00
|
|
|
S Status
|
|
|
|
SubmissionID string
|
|
|
|
Submissions []database.Submission
|
2013-04-16 02:33:40 +02:00
|
|
|
}
|
|
|
|
|
2018-04-07 23:42:41 +00:00
|
|
|
func submissionCommentHandler(h handler) {
|
|
|
|
submissionID := mux.Vars(h.r)["submissionID"]
|
|
|
|
bookID := mux.Vars(h.r)["id"]
|
|
|
|
comment := h.r.FormValue("comment")
|
|
|
|
|
|
|
|
err := h.db.UpdateSubmissionComment(submissionID, bookID, comment)
|
|
|
|
if err != nil {
|
|
|
|
log.Error("Adding comment (submission: ", submissionID, ", book: ", bookID, ") <", comment, ">: ", err)
|
|
|
|
h.sess.Notify("Error adding a comment!", "Can't add the comment rigt now. Try again later or report it to the site admins", "error")
|
|
|
|
} else {
|
|
|
|
h.sess.Notify("Comment added!", "", "success")
|
|
|
|
}
|
|
|
|
http.Redirect(h.w, h.r, "/submission/"+submissionID, http.StatusFound)
|
|
|
|
}
|
|
|
|
|
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)
|
|
|
|
}
|