2021-05-09 10:42:12 +00:00
|
|
|
package web
|
2020-08-05 15:08:59 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2021-05-25 07:11:16 +00:00
|
|
|
"github.com/bouncepaw/mycomarkup"
|
|
|
|
"github.com/bouncepaw/mycomarkup/mycocontext"
|
2020-08-05 15:08:59 +00:00
|
|
|
"log"
|
|
|
|
"net/http"
|
2020-08-10 19:58:02 +00:00
|
|
|
|
2021-02-17 18:41:35 +00:00
|
|
|
"github.com/bouncepaw/mycorrhiza/history"
|
|
|
|
"github.com/bouncepaw/mycorrhiza/hyphae"
|
2021-02-20 14:03:54 +00:00
|
|
|
"github.com/bouncepaw/mycorrhiza/shroom"
|
2020-11-15 12:58:13 +00:00
|
|
|
"github.com/bouncepaw/mycorrhiza/user"
|
2020-08-31 17:52:26 +00:00
|
|
|
"github.com/bouncepaw/mycorrhiza/util"
|
2021-02-22 17:38:41 +00:00
|
|
|
"github.com/bouncepaw/mycorrhiza/views"
|
2020-08-05 15:08:59 +00:00
|
|
|
)
|
|
|
|
|
2021-05-09 11:09:27 +00:00
|
|
|
func initMutators() {
|
2020-11-18 13:07:53 +00:00
|
|
|
// Those that do not actually mutate anything:
|
2020-08-05 15:08:59 +00:00
|
|
|
http.HandleFunc("/edit/", handlerEdit)
|
2020-09-29 15:04:22 +00:00
|
|
|
http.HandleFunc("/delete-ask/", handlerDeleteAsk)
|
2020-10-02 15:31:59 +00:00
|
|
|
http.HandleFunc("/rename-ask/", handlerRenameAsk)
|
2021-01-19 18:08:59 +00:00
|
|
|
http.HandleFunc("/unattach-ask/", handlerUnattachAsk)
|
2020-11-18 13:07:53 +00:00
|
|
|
// And those that do mutate something:
|
|
|
|
http.HandleFunc("/upload-binary/", handlerUploadBinary)
|
|
|
|
http.HandleFunc("/upload-text/", handlerUploadText)
|
|
|
|
http.HandleFunc("/delete-confirm/", handlerDeleteConfirm)
|
2020-10-02 15:31:59 +00:00
|
|
|
http.HandleFunc("/rename-confirm/", handlerRenameConfirm)
|
2021-01-19 18:08:59 +00:00
|
|
|
http.HandleFunc("/unattach-confirm/", handlerUnattachConfirm)
|
|
|
|
}
|
|
|
|
|
2021-02-17 18:41:35 +00:00
|
|
|
func factoryHandlerAsker(
|
|
|
|
actionPath string,
|
2021-02-20 14:03:54 +00:00
|
|
|
asker func(*user.User, *hyphae.Hypha) (error, string),
|
2021-02-17 18:41:35 +00:00
|
|
|
succTitleTemplate string,
|
|
|
|
succPageTemplate func(*http.Request, string, bool) string,
|
|
|
|
) func(http.ResponseWriter, *http.Request) {
|
|
|
|
return func(w http.ResponseWriter, rq *http.Request) {
|
2021-05-09 10:42:12 +00:00
|
|
|
util.PrepareRq(rq)
|
2021-02-17 18:41:35 +00:00
|
|
|
var (
|
2021-05-09 10:42:12 +00:00
|
|
|
hyphaName = util.HyphaNameFromRq(rq, actionPath)
|
2021-02-17 18:41:35 +00:00
|
|
|
h = hyphae.ByName(hyphaName)
|
|
|
|
u = user.FromRequest(rq)
|
|
|
|
)
|
2021-02-20 14:03:54 +00:00
|
|
|
if err, errtitle := asker(u, h); err != nil {
|
2021-05-09 11:09:27 +00:00
|
|
|
httpErr(
|
2021-02-17 18:41:35 +00:00
|
|
|
w,
|
|
|
|
http.StatusInternalServerError,
|
|
|
|
hyphaName,
|
|
|
|
errtitle,
|
|
|
|
err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
util.HTTP200Page(
|
|
|
|
w,
|
2021-05-09 10:42:12 +00:00
|
|
|
views.BaseHTML(
|
2021-02-17 18:41:35 +00:00
|
|
|
fmt.Sprintf(succTitleTemplate, hyphaName),
|
|
|
|
succPageTemplate(rq, hyphaName, h.Exists),
|
|
|
|
u))
|
2021-01-19 18:08:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-17 18:41:35 +00:00
|
|
|
var handlerUnattachAsk = factoryHandlerAsker(
|
|
|
|
"unattach-ask",
|
2021-02-20 14:03:54 +00:00
|
|
|
shroom.CanUnattach,
|
2021-02-17 18:41:35 +00:00
|
|
|
"Unattach %s?",
|
2021-02-22 17:38:41 +00:00
|
|
|
views.UnattachAskHTML,
|
2021-02-17 18:41:35 +00:00
|
|
|
)
|
2020-10-02 15:31:59 +00:00
|
|
|
|
2021-02-17 18:41:35 +00:00
|
|
|
var handlerDeleteAsk = factoryHandlerAsker(
|
|
|
|
"delete-ask",
|
2021-02-20 14:03:54 +00:00
|
|
|
shroom.CanDelete,
|
2021-02-17 18:41:35 +00:00
|
|
|
"Delete %s?",
|
2021-02-22 18:11:37 +00:00
|
|
|
views.DeleteAskHTML,
|
2021-02-17 18:41:35 +00:00
|
|
|
)
|
2020-10-02 15:31:59 +00:00
|
|
|
|
2021-02-17 18:41:35 +00:00
|
|
|
var handlerRenameAsk = factoryHandlerAsker(
|
|
|
|
"rename-ask",
|
2021-02-20 14:03:54 +00:00
|
|
|
shroom.CanRename,
|
2021-02-17 18:41:35 +00:00
|
|
|
"Rename %s?",
|
2021-02-22 18:11:37 +00:00
|
|
|
views.RenameAskHTML,
|
2021-02-17 18:41:35 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func factoryHandlerConfirmer(
|
|
|
|
actionPath string,
|
|
|
|
confirmer func(*hyphae.Hypha, *user.User, *http.Request) (*history.HistoryOp, string),
|
|
|
|
) func(http.ResponseWriter, *http.Request) {
|
|
|
|
return func(w http.ResponseWriter, rq *http.Request) {
|
2021-05-09 10:42:12 +00:00
|
|
|
util.PrepareRq(rq)
|
2021-02-17 18:41:35 +00:00
|
|
|
var (
|
2021-05-09 10:42:12 +00:00
|
|
|
hyphaName = util.HyphaNameFromRq(rq, actionPath)
|
2021-02-17 18:41:35 +00:00
|
|
|
h = hyphae.ByName(hyphaName)
|
|
|
|
u = user.FromRequest(rq)
|
|
|
|
)
|
|
|
|
if hop, errtitle := confirmer(h, u, rq); hop.HasErrors() {
|
2021-05-09 11:09:27 +00:00
|
|
|
httpErr(w, http.StatusInternalServerError, hyphaName,
|
2021-02-17 18:41:35 +00:00
|
|
|
errtitle,
|
|
|
|
hop.FirstErrorText())
|
|
|
|
return
|
2020-10-02 15:31:59 +00:00
|
|
|
}
|
2021-02-17 18:41:35 +00:00
|
|
|
http.Redirect(w, rq, "/hypha/"+hyphaName, http.StatusSeeOther)
|
2020-10-02 15:31:59 +00:00
|
|
|
}
|
2020-09-29 15:04:22 +00:00
|
|
|
}
|
|
|
|
|
2021-02-17 18:41:35 +00:00
|
|
|
var handlerUnattachConfirm = factoryHandlerConfirmer(
|
|
|
|
"unattach-confirm",
|
|
|
|
func(h *hyphae.Hypha, u *user.User, _ *http.Request) (*history.HistoryOp, string) {
|
2021-02-20 14:03:54 +00:00
|
|
|
return shroom.UnattachHypha(u, h)
|
2021-02-17 18:41:35 +00:00
|
|
|
},
|
|
|
|
)
|
2020-09-29 15:04:22 +00:00
|
|
|
|
2021-02-17 18:41:35 +00:00
|
|
|
var handlerDeleteConfirm = factoryHandlerConfirmer(
|
|
|
|
"delete-confirm",
|
|
|
|
func(h *hyphae.Hypha, u *user.User, _ *http.Request) (*history.HistoryOp, string) {
|
2021-02-20 14:03:54 +00:00
|
|
|
return shroom.DeleteHypha(u, h)
|
2021-02-17 18:41:35 +00:00
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
var handlerRenameConfirm = factoryHandlerConfirmer(
|
|
|
|
"rename-confirm",
|
|
|
|
func(oldHypha *hyphae.Hypha, u *user.User, rq *http.Request) (*history.HistoryOp, string) {
|
|
|
|
var (
|
|
|
|
newName = util.CanonicalName(rq.PostFormValue("new-name"))
|
|
|
|
recursive = rq.PostFormValue("recursive") == "true"
|
|
|
|
newHypha = hyphae.ByName(newName)
|
|
|
|
)
|
2021-02-20 14:03:54 +00:00
|
|
|
return shroom.RenameHypha(oldHypha, newHypha, recursive, u)
|
2021-02-17 18:41:35 +00:00
|
|
|
},
|
|
|
|
)
|
2020-08-05 15:08:59 +00:00
|
|
|
|
|
|
|
// handlerEdit shows the edit form. It doesn't edit anything actually.
|
|
|
|
func handlerEdit(w http.ResponseWriter, rq *http.Request) {
|
2021-05-09 10:42:12 +00:00
|
|
|
util.PrepareRq(rq)
|
2020-08-05 15:08:59 +00:00
|
|
|
var (
|
2021-05-09 10:42:12 +00:00
|
|
|
hyphaName = util.HyphaNameFromRq(rq, "edit")
|
2021-02-17 18:41:35 +00:00
|
|
|
h = hyphae.ByName(hyphaName)
|
|
|
|
warning string
|
|
|
|
textAreaFill string
|
|
|
|
err error
|
|
|
|
u = user.FromRequest(rq)
|
2020-08-05 15:08:59 +00:00
|
|
|
)
|
2021-02-20 14:03:54 +00:00
|
|
|
if err, errtitle := shroom.CanEdit(u, h); err != nil {
|
2021-05-09 11:09:27 +00:00
|
|
|
httpErr(w, http.StatusInternalServerError, hyphaName,
|
2021-02-17 18:41:35 +00:00
|
|
|
errtitle,
|
|
|
|
err.Error())
|
2020-11-15 12:58:13 +00:00
|
|
|
return
|
|
|
|
}
|
2021-02-17 18:41:35 +00:00
|
|
|
if h.Exists {
|
2021-02-20 14:03:54 +00:00
|
|
|
textAreaFill, err = shroom.FetchTextPart(h)
|
2020-08-05 15:08:59 +00:00
|
|
|
if err != nil {
|
|
|
|
log.Println(err)
|
2021-05-09 11:09:27 +00:00
|
|
|
httpErr(w, http.StatusInternalServerError, hyphaName,
|
2021-02-17 18:41:35 +00:00
|
|
|
"Error",
|
|
|
|
"Could not fetch text data")
|
2020-08-05 15:08:59 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
} else {
|
2021-02-17 18:41:35 +00:00
|
|
|
warning = `<p class="warning warning_new-hypha">You are creating a new hypha.</p>`
|
|
|
|
}
|
|
|
|
util.HTTP200Page(
|
|
|
|
w,
|
2021-05-09 10:42:12 +00:00
|
|
|
views.BaseHTML(
|
2021-02-17 18:41:35 +00:00
|
|
|
"Edit "+hyphaName,
|
2021-02-23 14:25:07 +00:00
|
|
|
views.EditHTML(rq, hyphaName, textAreaFill, warning),
|
2021-02-17 18:41:35 +00:00
|
|
|
u))
|
2020-08-05 15:08:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// handlerUploadText uploads a new text part for the hypha.
|
|
|
|
func handlerUploadText(w http.ResponseWriter, rq *http.Request) {
|
2021-05-09 10:42:12 +00:00
|
|
|
util.PrepareRq(rq)
|
2020-08-05 15:08:59 +00:00
|
|
|
var (
|
2021-05-09 10:42:12 +00:00
|
|
|
hyphaName = util.HyphaNameFromRq(rq, "upload-text")
|
2021-02-17 18:41:35 +00:00
|
|
|
h = hyphae.ByName(hyphaName)
|
2020-11-18 13:07:53 +00:00
|
|
|
textData = rq.PostFormValue("text")
|
2021-01-16 16:42:18 +00:00
|
|
|
action = rq.PostFormValue("action")
|
2021-06-14 00:38:43 +00:00
|
|
|
message = rq.PostFormValue("message")
|
2021-01-09 20:49:48 +00:00
|
|
|
u = user.FromRequest(rq)
|
2021-02-17 18:41:35 +00:00
|
|
|
hop *history.HistoryOp
|
|
|
|
errtitle string
|
2020-08-05 15:08:59 +00:00
|
|
|
)
|
2021-02-17 18:41:35 +00:00
|
|
|
|
|
|
|
if action != "Preview" {
|
2021-06-14 00:38:43 +00:00
|
|
|
hop, errtitle = shroom.UploadText(h, []byte(textData), message, u)
|
2021-02-20 16:21:10 +00:00
|
|
|
if hop.HasErrors() {
|
2021-05-09 11:09:27 +00:00
|
|
|
httpErr(w, http.StatusForbidden, hyphaName,
|
2021-02-20 16:21:10 +00:00
|
|
|
errtitle,
|
|
|
|
hop.FirstErrorText())
|
|
|
|
return
|
|
|
|
}
|
2020-08-05 15:08:59 +00:00
|
|
|
}
|
2021-02-17 18:41:35 +00:00
|
|
|
|
2021-01-16 16:42:18 +00:00
|
|
|
if action == "Preview" {
|
2021-05-25 07:11:16 +00:00
|
|
|
ctx, _ := mycocontext.ContextFromStringInput(hyphaName, textData)
|
|
|
|
|
2021-02-17 18:41:35 +00:00
|
|
|
util.HTTP200Page(
|
|
|
|
w,
|
2021-05-09 10:42:12 +00:00
|
|
|
views.BaseHTML(
|
2021-02-17 18:41:35 +00:00
|
|
|
"Preview "+hyphaName,
|
2021-02-23 14:25:07 +00:00
|
|
|
views.PreviewHTML(
|
2021-02-17 18:41:35 +00:00
|
|
|
rq,
|
|
|
|
hyphaName,
|
|
|
|
textData,
|
2021-06-14 00:38:43 +00:00
|
|
|
message,
|
2021-02-17 18:41:35 +00:00
|
|
|
"",
|
2021-05-25 07:11:16 +00:00
|
|
|
mycomarkup.BlocksToHTML(ctx, mycomarkup.BlockTree(ctx))),
|
2021-02-17 18:41:35 +00:00
|
|
|
u))
|
2020-08-05 15:08:59 +00:00
|
|
|
} else {
|
2021-02-17 18:41:35 +00:00
|
|
|
http.Redirect(w, rq, "/hypha/"+hyphaName, http.StatusSeeOther)
|
2020-08-05 15:08:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// handlerUploadBinary uploads a new binary part for the hypha.
|
|
|
|
func handlerUploadBinary(w http.ResponseWriter, rq *http.Request) {
|
2021-05-09 10:42:12 +00:00
|
|
|
util.PrepareRq(rq)
|
2021-02-17 18:41:35 +00:00
|
|
|
rq.ParseMultipartForm(10 << 20) // Set upload limit
|
2020-11-18 13:07:53 +00:00
|
|
|
var (
|
2021-05-09 10:42:12 +00:00
|
|
|
hyphaName = util.HyphaNameFromRq(rq, "upload-binary")
|
2021-02-17 18:41:35 +00:00
|
|
|
h = hyphae.ByName(hyphaName)
|
|
|
|
u = user.FromRequest(rq)
|
|
|
|
file, handler, err = rq.FormFile("binary")
|
2020-11-18 13:07:53 +00:00
|
|
|
)
|
2021-02-20 14:03:54 +00:00
|
|
|
if err != nil {
|
2021-05-09 11:09:27 +00:00
|
|
|
httpErr(w, http.StatusInternalServerError, hyphaName,
|
2021-02-20 14:03:54 +00:00
|
|
|
"Error",
|
|
|
|
err.Error())
|
|
|
|
}
|
|
|
|
if err, errtitle := shroom.CanAttach(u, h); err != nil {
|
2021-05-09 11:09:27 +00:00
|
|
|
httpErr(w, http.StatusInternalServerError, hyphaName,
|
2021-02-17 18:41:35 +00:00
|
|
|
errtitle,
|
|
|
|
err.Error())
|
2020-08-05 15:08:59 +00:00
|
|
|
}
|
2020-11-18 13:07:53 +00:00
|
|
|
|
2020-08-05 15:08:59 +00:00
|
|
|
// If file is not passed:
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
2020-11-18 13:07:53 +00:00
|
|
|
|
2020-08-05 15:08:59 +00:00
|
|
|
// If file is passed:
|
2021-02-17 18:41:35 +00:00
|
|
|
if file != nil {
|
|
|
|
defer file.Close()
|
|
|
|
}
|
2020-08-05 15:08:59 +00:00
|
|
|
var (
|
2021-02-17 18:41:35 +00:00
|
|
|
mime = handler.Header.Get("Content-Type")
|
2021-02-20 14:03:54 +00:00
|
|
|
hop, errtitle = shroom.UploadBinary(h, mime, file, u)
|
2020-08-05 15:08:59 +00:00
|
|
|
)
|
|
|
|
|
2021-02-17 18:41:35 +00:00
|
|
|
if hop.HasErrors() {
|
2021-05-09 11:09:27 +00:00
|
|
|
httpErr(w, http.StatusInternalServerError, hyphaName, errtitle, hop.FirstErrorText())
|
2020-11-18 13:07:53 +00:00
|
|
|
return
|
2020-08-19 18:54:23 +00:00
|
|
|
}
|
2021-02-17 18:41:35 +00:00
|
|
|
http.Redirect(w, rq, "/hypha/"+hyphaName, http.StatusSeeOther)
|
2020-08-05 15:08:59 +00:00
|
|
|
}
|