1
0
Fork 0
mirror of https://github.com/documize/community.git synced 2025-07-19 13:19:43 +02:00
documize/core/api/endpoint/conversion_endpoint.go

252 lines
6 KiB
Go
Raw Normal View History

2016-07-07 18:54:16 -07:00
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
2016-10-17 14:00:06 -07:00
// This software (Documize Community Edition) is licensed under
2016-07-07 18:54:16 -07:00
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
2016-10-17 14:00:06 -07:00
// by contacting <sales@documize.com>.
2016-07-07 18:54:16 -07:00
//
// https://documize.com
package endpoint
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"strings"
2016-07-20 15:58:37 +01:00
"github.com/documize/community/core/api/endpoint/models"
"github.com/documize/community/core/api/entity"
"github.com/documize/community/core/api/request"
"github.com/documize/community/core/api/store"
"github.com/documize/community/core/api/util"
2016-10-17 14:00:06 -07:00
api "github.com/documize/community/core/convapi"
2016-07-20 15:58:37 +01:00
"github.com/documize/community/core/log"
2016-07-07 18:54:16 -07:00
uuid "github.com/nu7hatch/gouuid"
"github.com/gorilla/mux"
)
func uploadDocument(w http.ResponseWriter, r *http.Request) (string, string, string) {
method := "uploadDocument"
p := request.GetPersister(r)
params := mux.Vars(r)
folderID := params["folderID"]
if !p.CanUploadDocument(folderID) {
writeForbiddenError(w)
return "", "", ""
}
// grab file
filedata, filename, err := r.FormFile("attachment")
if err != nil {
writeMissingDataError(w, method, "attachment")
return "", "", ""
}
b := new(bytes.Buffer)
_, err = io.Copy(b, filedata)
if err != nil {
writeServerError(w, method, err)
return "", "", ""
}
// generate job id
newUUID, err := uuid.NewV4()
if err != nil {
writeServerError(w, method, err)
return "", "", ""
}
2017-01-28 20:38:56 -08:00
job := newUUID.String()
2016-07-07 18:54:16 -07:00
err = storageProvider.Upload(job, filename.Filename, b.Bytes())
if err != nil {
writeServerError(w, method, err)
return "", "", ""
}
log.Info(fmt.Sprintf("Org %s (%s) [Uploaded] %s", p.Context.OrgName, p.Context.OrgID, filename.Filename))
return job, folderID, p.Context.OrgID
}
func convertDocument(w http.ResponseWriter, r *http.Request, job, folderID string, conversion api.ConversionJobRequest) {
method := "convertDocument"
p := request.GetPersister(r)
var fileResult *api.DocumentConversionResponse
var filename string
var err error
filename, fileResult, err = storageProvider.Convert(conversion)
if err != nil {
writePayloadError(w, method, err)
return
}
if fileResult.Err != "" {
writeGeneralSQLError(w, method, errors.New(fileResult.Err))
return
}
// NOTE: empty .docx documents trigger this error
if len(fileResult.Pages) == 0 {
writeMissingDataError(w, method, "no pages in document")
return
}
// All the commented-out code below should be in following function call
newDocument, err := processDocument(p, filename, job, folderID, fileResult)
if err != nil {
writeServerError(w, method, err)
return
}
json, err := json.Marshal(newDocument)
if err != nil {
writeJSONMarshalError(w, method, "conversion", err)
return
}
writeSuccessBytes(w, json)
}
// UploadConvertDocument is an endpoint to both upload and convert a document
func UploadConvertDocument(w http.ResponseWriter, r *http.Request) {
job, folderID, orgID := uploadDocument(w, r)
if job == "" {
return // error already handled
}
convertDocument(w, r, job, folderID, api.ConversionJobRequest{
Job: job,
IndexDepth: 4,
OrgID: orgID,
})
}
func processDocument(p request.Persister, filename, job, folderID string, fileResult *api.DocumentConversionResponse) (newDocument entity.Document, err error) {
// Convert into database objects
document := store.ConvertFileResult(filename, fileResult)
document.Job = job
document.OrgID = p.Context.OrgID
document.LabelID = folderID
document.UserID = p.Context.UserID
documentID := util.UniqueID()
document.RefID = documentID
tx, err := request.Db.Beginx()
log.IfErr(err)
p.Context.Transaction = tx
err = p.AddDocument(document)
if err != nil {
log.IfErr(tx.Rollback())
log.Error("Cannot insert new document", err)
return
}
//err = processPage(documentID, fileResult.PageFiles, fileResult.Pages.Children[0], 1, p)
for k, v := range fileResult.Pages {
var page entity.Page
page.OrgID = p.Context.OrgID
page.DocumentID = documentID
page.Level = v.Level
page.Title = v.Title
page.Body = string(v.Body)
page.Sequence = float64(k+1) * 1024.0 // need to start above 0 to allow insertion before the first item
pageID := util.UniqueID()
page.RefID = pageID
2016-11-10 15:06:59 -08:00
page.ContentType = "wysiwyg"
page.PageType = "section"
2016-07-07 18:54:16 -07:00
meta := entity.PageMeta{}
meta.PageID = pageID
meta.RawBody = page.Body
2016-12-04 18:27:22 -08:00
meta.Config = "{}"
2016-07-07 18:54:16 -07:00
model := models.PageModel{}
model.Page = page
model.Meta = meta
err = p.AddPage(model)
if err != nil {
log.IfErr(tx.Rollback())
log.Error("Cannot process page newly added document", err)
return
}
}
for _, e := range fileResult.EmbeddedFiles {
//fmt.Println("DEBUG embedded file info", document.OrgId, document.Job, e.Name, len(e.Data), e.ID)
var a entity.Attachment
a.DocumentID = documentID
a.Job = document.Job
a.FileID = e.ID
a.Filename = strings.Replace(e.Name, "embeddings/", "", 1)
a.Data = e.Data
refID := util.UniqueID()
a.RefID = refID
err = p.AddAttachment(a)
if err != nil {
log.IfErr(tx.Rollback())
log.Error("Cannot add attachment for newly added document", err)
return
}
}
log.IfErr(tx.Commit())
newDocument, err = p.GetDocument(documentID)
if err != nil {
log.Error("Cannot fetch newly added document", err)
return
}
tx, err = request.Db.Beginx()
if err != nil {
log.Error("Cannot begin a transatcion", err)
return
}
p.Context.Transaction = tx
err = p.UpdateDocument(newDocument) // TODO review - this seems to write-back an unaltered record from that read above, but within that it calls searches.UpdateDocument() to reindex the doc.
if err != nil {
log.IfErr(tx.Rollback())
log.Error("Cannot update an imported document", err)
return
}
2017-01-28 20:38:56 -08:00
p.RecordUserActivity(entity.UserActivity{
LabelID: newDocument.LabelID,
SourceID: newDocument.RefID,
SourceType: entity.ActivitySourceTypeDocument,
ActivityType: entity.ActivityTypeCreated})
2016-07-07 18:54:16 -07:00
2017-01-28 20:38:56 -08:00
log.IfErr(tx.Commit())
2016-07-07 18:54:16 -07:00
return
}