mirror of
https://github.com/osmarks/mycorrhiza.git
synced 2024-12-12 05:20:26 +00:00
85c936d94a
'I do as the golint guides'
112 lines
3.2 KiB
Go
112 lines
3.2 KiB
Go
package shroom
|
||
|
||
import (
|
||
"bytes"
|
||
"errors"
|
||
"fmt"
|
||
"io"
|
||
"log"
|
||
"mime/multipart"
|
||
"os"
|
||
"path/filepath"
|
||
"strings"
|
||
|
||
"github.com/bouncepaw/mycorrhiza/files"
|
||
"github.com/bouncepaw/mycorrhiza/history"
|
||
"github.com/bouncepaw/mycorrhiza/hyphae"
|
||
"github.com/bouncepaw/mycorrhiza/mimetype"
|
||
"github.com/bouncepaw/mycorrhiza/user"
|
||
)
|
||
|
||
// UploadText edits a hypha' text part and makes a history record about that.
|
||
func UploadText(h *hyphae.Hypha, data []byte, message string, u *user.User) (hop *history.Op, errtitle string) {
|
||
hop = history.Operation(history.TypeEditText)
|
||
var action string
|
||
if h.Exists {
|
||
action = "Edit"
|
||
} else {
|
||
action = "Create"
|
||
}
|
||
|
||
if message == "" {
|
||
hop.WithMsg(fmt.Sprintf("%s ‘%s’", action, h.Name))
|
||
} else {
|
||
hop.WithMsg(fmt.Sprintf("%s ‘%s’: %s", action, h.Name, message))
|
||
}
|
||
|
||
if errtitle, err := CanEdit(u, h); err != nil {
|
||
return hop.WithErrAbort(err), errtitle
|
||
}
|
||
if len(bytes.TrimSpace(data)) == 0 && h.BinaryPath == "" {
|
||
return hop.WithErrAbort(errors.New("No data passed")), "Empty"
|
||
}
|
||
|
||
return uploadHelp(h, hop, ".myco", data, u)
|
||
}
|
||
|
||
// UploadBinary edits a hypha' attachment and makes a history record about that.
|
||
func UploadBinary(h *hyphae.Hypha, mime string, file multipart.File, u *user.User) (*history.Op, string) {
|
||
var (
|
||
hop = history.Operation(history.TypeEditBinary).WithMsg(fmt.Sprintf("Upload attachment for ‘%s’ with type ‘%s’", h.Name, mime))
|
||
data, err = io.ReadAll(file)
|
||
)
|
||
|
||
if err != nil {
|
||
return hop.WithErrAbort(err), err.Error()
|
||
}
|
||
if errtitle, err := CanAttach(u, h); err != nil {
|
||
return hop.WithErrAbort(err), errtitle
|
||
}
|
||
if len(data) == 0 {
|
||
return hop.WithErrAbort(errors.New("No data passed")), "Empty"
|
||
}
|
||
|
||
return uploadHelp(h, hop, mimetype.ToExtension(mime), data, u)
|
||
}
|
||
|
||
// uploadHelp is a helper function for UploadText and UploadBinary
|
||
func uploadHelp(h *hyphae.Hypha, hop *history.Op, ext string, data []byte, u *user.User) (*history.Op, string) {
|
||
var (
|
||
fullPath = filepath.Join(files.HyphaeDir(), h.Name+ext)
|
||
originalFullPath = &h.TextPath
|
||
originalText = "" // for backlink update
|
||
)
|
||
// Reject if the path is outside the hyphae dir
|
||
if !strings.HasPrefix(fullPath, files.HyphaeDir()) {
|
||
err := errors.New("bad path")
|
||
return hop.WithErrAbort(err), err.Error()
|
||
}
|
||
if hop.Type == history.TypeEditBinary {
|
||
originalFullPath = &h.BinaryPath
|
||
}
|
||
|
||
if err := os.MkdirAll(filepath.Dir(fullPath), 0777); err != nil {
|
||
return hop.WithErrAbort(err), err.Error()
|
||
}
|
||
|
||
if hop.Type == history.TypeEditText {
|
||
originalText, _ = FetchTextPart(h)
|
||
}
|
||
|
||
if err := os.WriteFile(fullPath, data, 0666); err != nil {
|
||
return hop.WithErrAbort(err), err.Error()
|
||
}
|
||
|
||
if h.Exists && *originalFullPath != fullPath && *originalFullPath != "" {
|
||
if err := history.Rename(*originalFullPath, fullPath); err != nil {
|
||
return hop.WithErrAbort(err), err.Error()
|
||
}
|
||
log.Println("Move", *originalFullPath, "to", fullPath)
|
||
}
|
||
|
||
h.InsertIfNew()
|
||
if h.Exists && h.TextPath != "" && hop.Type == history.TypeEditText && !history.FileChanged(fullPath) {
|
||
return hop.Abort(), "No changes"
|
||
}
|
||
*originalFullPath = fullPath
|
||
if hop.Type == history.TypeEditText {
|
||
hyphae.BacklinksOnEdit(h, originalText)
|
||
}
|
||
return hop.WithFiles(fullPath).WithUser(u).Apply(), ""
|
||
}
|