1
0
mirror of https://github.com/osmarks/mycorrhiza.git synced 2024-12-12 13:30:26 +00:00
mycorrhiza/web/mutators.go

254 lines
7.4 KiB
Go
Raw Normal View History

package web
import (
"fmt"
2022-08-19 19:24:59 +00:00
"html/template"
"log"
"net/http"
"github.com/bouncepaw/mycomarkup/v5"
2022-08-19 19:24:59 +00:00
2022-06-16 11:05:30 +00:00
"github.com/bouncepaw/mycorrhiza/hypview"
2022-06-10 15:45:27 +00:00
"github.com/bouncepaw/mycorrhiza/mycoopts"
2022-04-01 19:51:15 +00:00
"github.com/bouncepaw/mycorrhiza/viewutil"
"github.com/bouncepaw/mycomarkup/v5/mycocontext"
"github.com/gorilla/mux"
2021-02-17 18:41:35 +00:00
"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"
)
func initMutators(r *mux.Router) {
r.PathPrefix("/edit/").HandlerFunc(handlerEdit)
r.PathPrefix("/rename/").HandlerFunc(handlerRename).Methods("GET", "POST")
r.PathPrefix("/delete/").HandlerFunc(handlerDelete).Methods("GET", "POST")
r.PathPrefix("/remove-media/").HandlerFunc(handlerRemoveMedia).Methods("GET", "POST")
r.PathPrefix("/upload-binary/").HandlerFunc(handlerUploadBinary)
r.PathPrefix("/upload-text/").HandlerFunc(handlerUploadText)
2021-01-19 18:08:59 +00:00
}
/// TODO: this is no longer ridiculous, but is now ugly. Gotta make it at least bearable to look at :-/
func handlerRemoveMedia(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq)
var (
2022-04-01 19:51:15 +00:00
u = user.FromRequest(rq)
lc = l18n.FromRequest(rq)
2022-06-14 19:40:15 +00:00
h = hyphae.ByName(util.HyphaNameFromRq(rq, "remove-media"))
2022-04-01 19:51:15 +00:00
meta = viewutil.MetaFrom(w, rq)
)
if !u.CanProceed("remove-media") {
2022-04-02 07:22:26 +00:00
viewutil.HttpErr(meta, http.StatusForbidden, h.CanonicalName(), "no rights")
return
}
if rq.Method == "GET" {
2021-02-17 18:41:35 +00:00
util.HTTP200Page(
w,
viewutil.Base(
2022-04-01 19:51:15 +00:00
meta,
fmt.Sprintf(lc.Get("ui.ask_remove_media"), util.BeautifulName(h.CanonicalName())),
hypview.RemoveMediaAsk(rq, h.CanonicalName()),
map[string]string{},
2022-08-14 22:43:19 +00:00
))
return
}
switch h := h.(type) {
case *hyphae.EmptyHypha, *hyphae.TextualHypha:
2022-04-02 07:22:26 +00:00
viewutil.HttpErr(meta, http.StatusForbidden, h.CanonicalName(), "no media to remove")
return
case *hyphae.MediaHypha:
2022-02-20 09:27:30 +00:00
if err := shroom.RemoveMedia(u, h); err != nil {
2022-04-02 07:22:26 +00:00
viewutil.HttpErr(meta, http.StatusInternalServerError, h.CanonicalName(), err.Error())
return
}
2021-01-19 18:08:59 +00:00
}
2022-06-14 19:40:15 +00:00
http.Redirect(w, rq, "/hypha/"+h.CanonicalName(), http.StatusSeeOther)
2021-01-19 18:08:59 +00:00
}
func handlerDelete(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq)
var (
2022-04-01 19:51:15 +00:00
u = user.FromRequest(rq)
h = hyphae.ByName(util.HyphaNameFromRq(rq, "delete"))
meta = viewutil.MetaFrom(w, rq)
)
2020-10-02 15:31:59 +00:00
2022-02-20 09:27:30 +00:00
if !u.CanProceed("delete") {
log.Printf("%s has no rights to delete %s\n", u.Name, h.CanonicalName())
2022-04-02 07:22:26 +00:00
viewutil.HttpErr(meta, http.StatusForbidden, h.CanonicalName(), "No rights")
2022-02-20 09:27:30 +00:00
return
}
switch h.(type) {
case *hyphae.EmptyHypha:
2022-02-20 09:27:30 +00:00
log.Printf("%s tries to delete empty hypha %s\n", u.Name, h.CanonicalName())
// TODO: localize
2022-04-02 07:22:26 +00:00
viewutil.HttpErr(meta, http.StatusForbidden, h.CanonicalName(), "Cannot delete an empty hypha")
return
}
2020-10-02 15:31:59 +00:00
if rq.Method == "GET" {
2022-06-16 11:05:30 +00:00
hypview.DeleteHypha(meta, h.CanonicalName())
return
}
2020-09-29 15:04:22 +00:00
2022-02-20 09:27:30 +00:00
if err := shroom.Delete(u, h.(hyphae.ExistingHypha)); err != nil {
log.Println(err)
2022-04-02 07:22:26 +00:00
viewutil.HttpErr(meta, http.StatusInternalServerError, h.CanonicalName(), err.Error())
2022-02-20 09:27:30 +00:00
return
}
http.Redirect(w, rq, "/hypha/"+h.CanonicalName(), http.StatusSeeOther)
}
2021-02-17 18:41:35 +00:00
func handlerRename(w http.ResponseWriter, rq *http.Request) {
2021-08-23 08:17:14 +00:00
util.PrepareRq(rq)
var (
2022-04-01 19:51:15 +00:00
u = user.FromRequest(rq)
lc = l18n.FromRequest(rq)
h = hyphae.ByName(util.HyphaNameFromRq(rq, "rename"))
meta = viewutil.MetaFrom(w, rq)
)
switch h.(type) {
case *hyphae.EmptyHypha:
log.Printf("%s tries to rename empty hypha %s", u.Name, h.CanonicalName())
2022-04-02 07:22:26 +00:00
viewutil.HttpErr(meta, http.StatusForbidden, h.CanonicalName(), "Cannot rename an empty hypha") // TODO: localize
return
}
if !u.CanProceed("rename") {
log.Printf("%s has no rights to rename %s\n", u.Name, h.CanonicalName())
2022-04-02 07:22:26 +00:00
viewutil.HttpErr(meta, http.StatusForbidden, h.CanonicalName(), "No rights")
return
}
var (
2022-07-01 15:51:22 +00:00
oldHypha = h.(hyphae.ExistingHypha)
newName = util.CanonicalName(rq.PostFormValue("new-name"))
recursive = rq.PostFormValue("recursive") == "true"
leaveRedirections = rq.PostFormValue("redirection") == "true"
2021-08-23 08:17:14 +00:00
)
if rq.Method == "GET" {
2022-06-16 11:19:42 +00:00
hypview.RenameHypha(meta, h.CanonicalName())
return
}
2022-07-01 15:51:22 +00:00
if err := shroom.Rename(oldHypha, newName, recursive, leaveRedirections, u); err != nil {
log.Printf("%s tries to rename %s: %s", u.Name, oldHypha.CanonicalName(), err.Error())
2022-04-02 07:22:26 +00:00
viewutil.HttpErr(meta, http.StatusForbidden, oldHypha.CanonicalName(), lc.Get(err.Error())) // TODO: localize
2021-08-23 08:17:14 +00:00
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 (
2022-08-19 19:24:59 +00:00
u = user.FromRequest(rq)
lc = l18n.FromRequest(rq)
meta = viewutil.MetaFrom(w, rq)
hyphaName = util.HyphaNameFromRq(rq, "edit")
h = hyphae.ByName(hyphaName)
isNew bool
content string
err error
)
2022-08-19 19:24:59 +00:00
if err := shroom.CanEdit(u, h, lc); err != nil {
2022-04-02 07:22:26 +00:00
viewutil.HttpErr(meta, http.StatusInternalServerError, hyphaName, err.Error())
return
}
2022-08-19 19:24:59 +00:00
switch h.(type) {
case *hyphae.EmptyHypha:
2022-08-19 19:24:59 +00:00
isNew = true
default:
2022-08-19 19:24:59 +00:00
content, err = hyphae.FetchMycomarkupFile(h)
if err != nil {
log.Println(err)
2022-04-02 07:22:26 +00:00
viewutil.HttpErr(meta, http.StatusInternalServerError, hyphaName, lc.Get("ui.error_text_fetch"))
return
}
2021-02-17 18:41:35 +00:00
}
2022-08-19 19:24:59 +00:00
hypview.EditHypha(meta, hyphaName, isNew, content, "", "")
}
// handlerUploadText uploads a new text part for the hypha.
func handlerUploadText(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq)
var (
2022-08-19 19:24:59 +00:00
u = user.FromRequest(rq)
meta = viewutil.MetaFrom(w, rq)
hyphaName = util.HyphaNameFromRq(rq, "upload-text")
2021-02-17 18:41:35 +00:00
h = hyphae.ByName(hyphaName)
2022-08-19 19:24:59 +00:00
_, isNew = h.(*hyphae.EmptyHypha)
2021-02-17 18:41:35 +00:00
2022-08-19 19:24:59 +00:00
textData = rq.PostFormValue("text")
action = rq.PostFormValue("action")
message = rq.PostFormValue("message")
)
2021-02-17 18:41:35 +00:00
2022-08-19 19:24:59 +00:00
if action == "preview" {
2022-06-10 15:45:27 +00:00
ctx, _ := mycocontext.ContextFromStringInput(textData, mycoopts.MarkupOptions(hyphaName))
2022-08-19 19:24:59 +00:00
preview := template.HTML(mycomarkup.BlocksToHTML(ctx, mycomarkup.BlockTree(ctx)))
hypview.EditHypha(meta, hyphaName, isNew, textData, message, preview)
return
}
2021-05-25 07:11:16 +00:00
2022-08-19 19:24:59 +00:00
if err := shroom.UploadText(h, []byte(textData), message, u); err != nil {
viewutil.HttpErr(meta, http.StatusForbidden, hyphaName, err.Error())
return
}
2022-08-19 19:24:59 +00:00
http.Redirect(w, rq, "/hypha/"+hyphaName, http.StatusSeeOther)
}
2022-02-26 07:33:09 +00:00
// handlerUploadBinary uploads a new media 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")
2022-04-01 19:51:15 +00:00
meta = viewutil.MetaFrom(w, rq)
)
2021-02-20 14:03:54 +00:00
if err != nil {
2022-04-02 07:22:26 +00:00
viewutil.HttpErr(meta, http.StatusInternalServerError, hyphaName, err.Error())
2021-02-20 14:03:54 +00:00
}
if err := shroom.CanAttach(u, h, lc); err != nil {
2022-04-02 07:22:26 +00:00
viewutil.HttpErr(meta, http.StatusInternalServerError, hyphaName, 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 (
mime = handler.Header.Get("Content-Type")
)
2022-02-20 09:27:30 +00:00
if err := shroom.UploadBinary(h, mime, file, u); err != nil {
2022-04-02 07:22:26 +00:00
viewutil.HttpErr(meta, http.StatusInternalServerError, hyphaName, err.Error())
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)
}