1
0
mirror of https://github.com/osmarks/mycorrhiza.git synced 2024-10-30 11:46:16 +00:00
mycorrhiza/web/mutators.go

286 lines
7.7 KiB
Go
Raw Normal View History

package web
import (
"fmt"
"log"
"net/http"
"github.com/bouncepaw/mycomarkup/v3"
"github.com/bouncepaw/mycomarkup/v3/mycocontext"
"github.com/gorilla/mux"
2021-02-17 18:41:35 +00:00
"github.com/bouncepaw/mycorrhiza/history"
"github.com/bouncepaw/mycorrhiza/hyphae"
2021-09-06 17:46:34 +00:00
"github.com/bouncepaw/mycorrhiza/l18n"
2021-02-20 14:03:54 +00:00
"github.com/bouncepaw/mycorrhiza/shroom"
"github.com/bouncepaw/mycorrhiza/user"
2020-08-31 17:52:26 +00:00
"github.com/bouncepaw/mycorrhiza/util"
"github.com/bouncepaw/mycorrhiza/views"
)
func initMutators(r *mux.Router) {
// Those that do not actually mutate anything:
r.PathPrefix("/edit/").HandlerFunc(handlerEdit)
r.PathPrefix("/delete-ask/").HandlerFunc(handlerDeleteAsk)
r.PathPrefix("/rename-ask/").HandlerFunc(handlerRenameAsk)
r.PathPrefix("/unattach-ask/").HandlerFunc(handlerUnattachAsk)
// And those that do mutate something:
r.PathPrefix("/upload-binary/").HandlerFunc(handlerUploadBinary)
r.PathPrefix("/upload-text/").HandlerFunc(handlerUploadText)
r.PathPrefix("/delete-confirm/").HandlerFunc(handlerDeleteConfirm)
r.PathPrefix("/rename-confirm/").HandlerFunc(handlerRenameConfirm)
r.PathPrefix("/unattach-confirm/").HandlerFunc(handlerUnattachConfirm)
2021-01-19 18:08:59 +00:00
}
/// TODO: this is ridiculous, refactor heavily:
2021-02-17 18:41:35 +00:00
func factoryHandlerAsker(
actionPath string,
2022-02-19 08:26:38 +00:00
asker func(*user.User, hyphae.Hypha, *l18n.Localizer) (string, error),
2021-09-06 17:46:34 +00:00
succTitleKey string,
2021-02-17 18:41:35 +00:00
succPageTemplate func(*http.Request, string, bool) string,
) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq)
2021-02-17 18:41:35 +00:00
var (
hyphaName = util.HyphaNameFromRq(rq, actionPath)
2021-02-17 18:41:35 +00:00
h = hyphae.ByName(hyphaName)
u = user.FromRequest(rq)
2021-09-06 17:46:34 +00:00
lc = l18n.FromRequest(rq)
2021-02-17 18:41:35 +00:00
)
if errtitle, err := asker(u, h, lc); err != nil {
httpErr(
2021-02-17 18:41:35 +00:00
w,
2021-09-06 17:46:34 +00:00
lc,
2021-02-17 18:41:35 +00:00
http.StatusInternalServerError,
hyphaName,
errtitle,
err.Error())
return
}
util.HTTP200Page(
w,
views.BaseHTML(
2021-09-06 17:46:34 +00:00
fmt.Sprintf(lc.Get(succTitleKey), util.BeautifulName(hyphaName)),
2022-02-19 08:26:38 +00:00
succPageTemplate(rq, hyphaName, func(h hyphae.Hypha) bool {
switch h.(type) {
case *hyphae.EmptyHypha:
return false
default:
return true
}
}(h)),
2021-09-06 17:46:34 +00:00
lc,
2021-02-17 18:41:35 +00:00
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-09-06 17:46:34 +00:00
"ui.ask_unattach",
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-09-06 17:46:34 +00:00
"ui.ask_delete",
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-09-06 17:46:34 +00:00
"ui.ask_rename",
views.RenameAskHTML,
2021-02-17 18:41:35 +00:00
)
func factoryHandlerConfirmer(
actionPath string,
2022-02-19 08:26:38 +00:00
confirmer func(hyphae.Hypha, *user.User, *http.Request) (*history.Op, string),
2021-02-17 18:41:35 +00:00
) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq)
2021-02-17 18:41:35 +00:00
var (
hyphaName = util.HyphaNameFromRq(rq, actionPath)
2021-02-17 18:41:35 +00:00
h = hyphae.ByName(hyphaName)
u = user.FromRequest(rq)
2021-09-06 17:46:34 +00:00
lc = l18n.FromRequest(rq)
2021-02-17 18:41:35 +00:00
)
if hop, errtitle := confirmer(h, u, rq); hop.HasErrors() {
2021-09-06 17:46:34 +00:00
httpErr(w, lc, 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",
2022-02-19 08:26:38 +00:00
func(h hyphae.Hypha, u *user.User, rq *http.Request) (*history.Op, string) {
return shroom.UnattachHypha(u, h, l18n.FromRequest(rq))
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",
2022-02-19 08:26:38 +00:00
func(h hyphae.Hypha, u *user.User, rq *http.Request) (*history.Op, string) {
return shroom.DeleteHypha(u, h, l18n.FromRequest(rq))
2021-02-17 18:41:35 +00:00
},
)
2021-08-23 08:17:14 +00:00
// handlerRenameConfirm should redirect to the new hypha, thus it's out of factory
func handlerRenameConfirm(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq)
var (
u = user.FromRequest(rq)
2021-09-06 17:46:34 +00:00
lc = l18n.FromRequest(rq)
2021-08-23 08:17:14 +00:00
hyphaName = util.HyphaNameFromRq(rq, "rename-confirm")
oldHypha = hyphae.ByName(hyphaName)
newName = util.CanonicalName(rq.PostFormValue("new-name"))
newHypha = hyphae.ByName(newName)
recursive = rq.PostFormValue("recursive") == "true"
)
hop, errtitle := shroom.RenameHypha(oldHypha, newHypha, recursive, u, lc)
2021-08-23 08:17:14 +00:00
if hop.HasErrors() {
2021-09-06 17:46:34 +00:00
httpErr(w, lc, http.StatusInternalServerError, hyphaName,
2021-08-23 08:17:14 +00:00
errtitle,
hop.FirstErrorText())
return
}
http.Redirect(w, rq, "/hypha/"+newName, http.StatusSeeOther)
}
// handlerEdit shows the edit form. It doesn't edit anything actually.
func handlerEdit(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq)
var (
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)
2021-09-06 17:46:34 +00:00
lc = l18n.FromRequest(rq)
)
if errtitle, err := shroom.CanEdit(u, h, lc); err != nil {
2021-09-06 17:46:34 +00:00
httpErr(w, lc, http.StatusInternalServerError, hyphaName,
2021-02-17 18:41:35 +00:00
errtitle,
err.Error())
return
}
switch h.(type) {
case *hyphae.EmptyHypha:
warning = fmt.Sprintf(`<p class="warning warning_new-hypha">%s</p>`, lc.Get("edit.new_hypha"))
default:
2022-02-19 08:26:38 +00:00
textAreaFill, err = shroom.FetchTextFile(h)
if err != nil {
log.Println(err)
2021-09-06 17:46:34 +00:00
httpErr(w, lc, http.StatusInternalServerError, hyphaName,
lc.Get("ui.error"),
lc.Get("ui.error_text_fetch"))
return
}
2021-02-17 18:41:35 +00:00
}
util.HTTP200Page(
w,
views.BaseHTML(
2021-09-06 17:46:34 +00:00
fmt.Sprintf(lc.Get("edit.title"), util.BeautifulName(hyphaName)),
views.EditHTML(rq, hyphaName, textAreaFill, warning),
2021-09-06 17:46:34 +00:00
lc,
2021-02-17 18:41:35 +00:00
u))
}
// handlerUploadText uploads a new text part for the hypha.
func handlerUploadText(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq)
var (
hyphaName = util.HyphaNameFromRq(rq, "upload-text")
2021-02-17 18:41:35 +00:00
h = hyphae.ByName(hyphaName)
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")
u = user.FromRequest(rq)
2021-09-06 17:46:34 +00:00
lc = l18n.FromRequest(rq)
hop *history.Op
2021-02-17 18:41:35 +00:00
errtitle string
)
2021-02-17 18:41:35 +00:00
if action != "Preview" {
hop, errtitle = shroom.UploadText(h, []byte(textData), message, u, lc)
2021-02-20 16:21:10 +00:00
if hop.HasErrors() {
2021-09-06 17:46:34 +00:00
httpErr(w, lc, http.StatusForbidden, hyphaName,
2021-02-20 16:21:10 +00:00
errtitle,
hop.FirstErrorText())
return
}
}
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,
views.BaseHTML(
2021-09-06 17:46:34 +00:00
fmt.Sprintf(lc.Get("edit.preview_title"), util.BeautifulName(hyphaName)),
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-09-06 17:46:34 +00:00
lc,
2021-02-17 18:41:35 +00:00
u))
} else {
2021-02-17 18:41:35 +00:00
http.Redirect(w, rq, "/hypha/"+hyphaName, http.StatusSeeOther)
}
}
// handlerUploadBinary uploads a new attachment for the hypha.
func handlerUploadBinary(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq)
2021-02-17 18:41:35 +00:00
rq.ParseMultipartForm(10 << 20) // Set upload limit
var (
hyphaName = util.HyphaNameFromRq(rq, "upload-binary")
2021-02-17 18:41:35 +00:00
h = hyphae.ByName(hyphaName)
u = user.FromRequest(rq)
2021-09-06 17:46:34 +00:00
lc = l18n.FromRequest(rq)
2021-02-17 18:41:35 +00:00
file, handler, err = rq.FormFile("binary")
)
2021-02-20 14:03:54 +00:00
if err != nil {
2021-09-06 17:46:34 +00:00
httpErr(w, lc, http.StatusInternalServerError, hyphaName,
lc.Get("ui.error"),
2021-02-20 14:03:54 +00:00
err.Error())
}
if errtitle, err := shroom.CanAttach(u, h, lc); err != nil {
2021-09-06 17:46:34 +00:00
httpErr(w, lc, http.StatusInternalServerError, hyphaName,
2021-02-17 18:41:35 +00:00
errtitle,
err.Error())
}
// If file is not passed:
if err != nil {
return
}
// If file is passed:
2021-02-17 18:41:35 +00:00
if file != nil {
defer file.Close()
}
var (
2021-02-17 18:41:35 +00:00
mime = handler.Header.Get("Content-Type")
hop, errtitle = shroom.UploadBinary(h, mime, file, u, lc)
)
2021-02-17 18:41:35 +00:00
if hop.HasErrors() {
2021-09-06 17:46:34 +00:00
httpErr(w, lc, http.StatusInternalServerError, hyphaName, errtitle, hop.FirstErrorText())
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)
}