2021-02-20 14:03:54 +00:00
|
|
|
|
package shroom
|
|
|
|
|
|
|
|
|
|
import (
|
2021-09-29 14:56:17 +00:00
|
|
|
|
"bytes"
|
2021-02-20 14:03:54 +00:00
|
|
|
|
"errors"
|
|
|
|
|
"fmt"
|
2021-12-20 21:08:21 +00:00
|
|
|
|
"github.com/bouncepaw/mycorrhiza/hyphae/backlinks"
|
2021-07-02 08:29:55 +00:00
|
|
|
|
"io"
|
2021-02-20 14:03:54 +00:00
|
|
|
|
"log"
|
|
|
|
|
"mime/multipart"
|
|
|
|
|
"os"
|
|
|
|
|
"path/filepath"
|
2021-06-14 20:27:25 +00:00
|
|
|
|
"strings"
|
2021-02-20 14:03:54 +00:00
|
|
|
|
|
2021-06-19 04:51:10 +00:00
|
|
|
|
"github.com/bouncepaw/mycorrhiza/files"
|
2021-02-20 14:03:54 +00:00
|
|
|
|
"github.com/bouncepaw/mycorrhiza/history"
|
|
|
|
|
"github.com/bouncepaw/mycorrhiza/hyphae"
|
2021-10-10 03:51:34 +00:00
|
|
|
|
"github.com/bouncepaw/mycorrhiza/l18n"
|
2021-02-20 14:03:54 +00:00
|
|
|
|
"github.com/bouncepaw/mycorrhiza/mimetype"
|
|
|
|
|
"github.com/bouncepaw/mycorrhiza/user"
|
|
|
|
|
)
|
|
|
|
|
|
2021-10-01 17:12:16 +00:00
|
|
|
|
// UploadText edits a hypha' text part and makes a history record about that.
|
2022-02-04 10:50:50 +00:00
|
|
|
|
func UploadText(h hyphae.Hypher, data []byte, message string, u *user.User, lc *l18n.Localizer) (hop *history.Op, errtitle string) {
|
2021-02-20 14:03:54 +00:00
|
|
|
|
hop = history.Operation(history.TypeEditText)
|
2021-06-14 00:38:43 +00:00
|
|
|
|
var action string
|
2022-02-04 10:50:50 +00:00
|
|
|
|
if h.DoesExist() {
|
2021-06-14 00:38:43 +00:00
|
|
|
|
action = "Edit"
|
2021-02-20 14:03:54 +00:00
|
|
|
|
} else {
|
2021-06-14 00:38:43 +00:00
|
|
|
|
action = "Create"
|
2021-02-20 14:03:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-06-14 00:38:43 +00:00
|
|
|
|
if message == "" {
|
2022-02-03 22:29:01 +00:00
|
|
|
|
hop.WithMsg(fmt.Sprintf("%s ‘%s’", action, h.CanonicalName()))
|
2021-06-14 00:38:43 +00:00
|
|
|
|
} else {
|
2022-02-03 22:29:01 +00:00
|
|
|
|
hop.WithMsg(fmt.Sprintf("%s ‘%s’: %s", action, h.CanonicalName(), message))
|
2021-06-14 00:38:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-10-10 03:51:34 +00:00
|
|
|
|
if errtitle, err := CanEdit(u, h, lc); err != nil {
|
2021-02-26 16:43:45 +00:00
|
|
|
|
return hop.WithErrAbort(err), errtitle
|
2021-02-20 14:03:54 +00:00
|
|
|
|
}
|
2022-02-04 10:50:50 +00:00
|
|
|
|
if len(bytes.TrimSpace(data)) == 0 && h.Kind() != hyphae.HyphaMedia {
|
2021-02-26 16:43:45 +00:00
|
|
|
|
return hop.WithErrAbort(errors.New("No data passed")), "Empty"
|
2021-02-20 14:03:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return uploadHelp(h, hop, ".myco", data, u)
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-01 17:12:16 +00:00
|
|
|
|
// UploadBinary edits a hypha' attachment and makes a history record about that.
|
2022-02-04 10:50:50 +00:00
|
|
|
|
func UploadBinary(h hyphae.Hypher, mime string, file multipart.File, u *user.User, lc *l18n.Localizer) (*history.Op, string) {
|
2021-02-20 14:03:54 +00:00
|
|
|
|
var (
|
2022-02-03 22:29:01 +00:00
|
|
|
|
hop = history.Operation(history.TypeEditBinary).WithMsg(fmt.Sprintf("Upload attachment for ‘%s’ with type ‘%s’", h.CanonicalName(), mime))
|
2021-07-02 08:29:55 +00:00
|
|
|
|
data, err = io.ReadAll(file)
|
2021-02-20 14:03:54 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
2021-02-26 16:43:45 +00:00
|
|
|
|
return hop.WithErrAbort(err), err.Error()
|
2021-02-20 14:03:54 +00:00
|
|
|
|
}
|
2021-10-10 03:51:34 +00:00
|
|
|
|
if errtitle, err := CanAttach(u, h, lc); err != nil {
|
2021-02-26 16:43:45 +00:00
|
|
|
|
return hop.WithErrAbort(err), errtitle
|
2021-02-20 14:03:54 +00:00
|
|
|
|
}
|
|
|
|
|
if len(data) == 0 {
|
2021-02-26 16:43:45 +00:00
|
|
|
|
return hop.WithErrAbort(errors.New("No data passed")), "Empty"
|
2021-02-20 14:03:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return uploadHelp(h, hop, mimetype.ToExtension(mime), data, u)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// uploadHelp is a helper function for UploadText and UploadBinary
|
2022-02-04 10:50:50 +00:00
|
|
|
|
func uploadHelp(h hyphae.Hypher, hop *history.Op, ext string, data []byte, u *user.User) (*history.Op, string) {
|
2021-02-20 14:03:54 +00:00
|
|
|
|
var (
|
2022-02-03 22:29:01 +00:00
|
|
|
|
fullPath = filepath.Join(files.HyphaeDir(), h.CanonicalName()+ext)
|
2022-02-03 22:04:01 +00:00
|
|
|
|
sourceFullPath = h.TextPartPath()
|
|
|
|
|
originalText = "" // for backlink update
|
2021-02-20 14:03:54 +00:00
|
|
|
|
)
|
2022-02-03 22:29:01 +00:00
|
|
|
|
if !isValidPath(fullPath) || !hyphae.IsValidName(h.CanonicalName()) {
|
2021-06-15 21:00:29 +00:00
|
|
|
|
err := errors.New("bad path")
|
2021-06-14 20:27:25 +00:00
|
|
|
|
return hop.WithErrAbort(err), err.Error()
|
|
|
|
|
}
|
2022-02-04 10:50:50 +00:00
|
|
|
|
if h := h.(*hyphae.Hypha); hop.Type == history.TypeEditBinary {
|
2022-02-03 22:04:01 +00:00
|
|
|
|
sourceFullPath = h.BinaryPath()
|
2021-02-20 14:03:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := os.MkdirAll(filepath.Dir(fullPath), 0777); err != nil {
|
2021-02-26 16:43:45 +00:00
|
|
|
|
return hop.WithErrAbort(err), err.Error()
|
2021-02-20 14:03:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-08-31 19:28:12 +00:00
|
|
|
|
if hop.Type == history.TypeEditText {
|
|
|
|
|
originalText, _ = FetchTextPart(h)
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-02 08:29:55 +00:00
|
|
|
|
if err := os.WriteFile(fullPath, data, 0666); err != nil {
|
2021-02-26 16:43:45 +00:00
|
|
|
|
return hop.WithErrAbort(err), err.Error()
|
2021-02-20 14:03:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-04 10:50:50 +00:00
|
|
|
|
if h.DoesExist() && sourceFullPath != fullPath && sourceFullPath != "" {
|
2022-02-03 22:04:01 +00:00
|
|
|
|
if err := history.Rename(sourceFullPath, fullPath); err != nil {
|
2021-02-26 16:43:45 +00:00
|
|
|
|
return hop.WithErrAbort(err), err.Error()
|
2021-02-20 14:03:54 +00:00
|
|
|
|
}
|
2022-02-03 22:04:01 +00:00
|
|
|
|
log.Println("Move", sourceFullPath, "to", fullPath)
|
2021-02-20 14:03:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-03 22:39:21 +00:00
|
|
|
|
hyphae.InsertIfNew(h)
|
2022-02-04 10:50:50 +00:00
|
|
|
|
if h.DoesExist() && h.HasTextPart() && hop.Type == history.TypeEditText && !history.FileChanged(fullPath) {
|
2021-02-20 14:03:54 +00:00
|
|
|
|
return hop.Abort(), "No changes"
|
|
|
|
|
}
|
2022-02-03 22:04:01 +00:00
|
|
|
|
// TODO: test
|
2022-02-04 10:50:50 +00:00
|
|
|
|
if h := h.(*hyphae.Hypha); hop.Type == history.TypeEditBinary {
|
2022-02-03 22:04:01 +00:00
|
|
|
|
h.SetBinaryPath(fullPath)
|
|
|
|
|
} else {
|
|
|
|
|
h.TextPath = fullPath
|
|
|
|
|
}
|
2021-08-31 19:28:12 +00:00
|
|
|
|
if hop.Type == history.TypeEditText {
|
2021-12-30 19:59:28 +00:00
|
|
|
|
backlinks.UpdateBacklinksAfterEdit(h, originalText)
|
2021-08-31 19:28:12 +00:00
|
|
|
|
}
|
2021-02-20 14:03:54 +00:00
|
|
|
|
return hop.WithFiles(fullPath).WithUser(u).Apply(), ""
|
|
|
|
|
}
|
2021-10-27 05:43:36 +00:00
|
|
|
|
|
2021-10-27 06:43:01 +00:00
|
|
|
|
func isValidPath(pathname string) bool {
|
|
|
|
|
return strings.HasPrefix(pathname, files.HyphaeDir())
|
2021-10-27 05:43:36 +00:00
|
|
|
|
}
|