From f8fbc23202bd7a543f70cbe24be943b9b7b4c494 Mon Sep 17 00:00:00 2001 From: Timur Ismagilov Date: Sat, 2 Apr 2022 09:38:16 +0300 Subject: [PATCH] Misc: Make the new package It contains things like hypha list or about wiki pages --- misc/misc.go | 111 ++++++++++++++++++++++++++++++++++++++++++++++++ viewutil/err.go | 28 ++++++++++++ web/mutators.go | 30 ++++++------- web/stuff.go | 99 ------------------------------------------ web/web.go | 23 +--------- 5 files changed, 156 insertions(+), 135 deletions(-) create mode 100644 misc/misc.go create mode 100644 viewutil/err.go diff --git a/misc/misc.go b/misc/misc.go new file mode 100644 index 0000000..2f9b44e --- /dev/null +++ b/misc/misc.go @@ -0,0 +1,111 @@ +// Package misc provides miscellaneous informative views. +package misc + +import ( + "github.com/bouncepaw/mycorrhiza/cfg" + "github.com/bouncepaw/mycorrhiza/files" + "github.com/bouncepaw/mycorrhiza/hyphae" + "github.com/bouncepaw/mycorrhiza/hyphae/backlinks" + "github.com/bouncepaw/mycorrhiza/l18n" + "github.com/bouncepaw/mycorrhiza/shroom" + "github.com/bouncepaw/mycorrhiza/user" + "github.com/bouncepaw/mycorrhiza/util" + "github.com/bouncepaw/mycorrhiza/views" + "github.com/bouncepaw/mycorrhiza/viewutil" + "github.com/gorilla/mux" + "io" + "log" + "math/rand" + "net/http" +) + +func InitHandlers(rtr *mux.Router) { + rtr.HandleFunc("/list", handlerList) + rtr.HandleFunc("/reindex", handlerReindex) + rtr.HandleFunc("/update-header-links", handlerUpdateHeaderLinks) + rtr.HandleFunc("/random", handlerRandom) + rtr.HandleFunc("/about", handlerAbout) + rtr.HandleFunc("/favicon.ico", func(w http.ResponseWriter, rq *http.Request) { + http.Redirect(w, rq, "/static/favicon.ico", http.StatusSeeOther) + }) +} + +// handlerList shows a list of all hyphae in the wiki in random order. +func handlerList(w http.ResponseWriter, rq *http.Request) { + var lc = l18n.FromRequest(rq) + util.PrepareRq(rq) + util.HTTP200Page(w, views.Base( + viewutil.MetaFrom(w, rq), + lc.Get("ui.list_title"), + views.HyphaList(lc), + )) +} + +// handlerReindex reindexes all hyphae by checking the wiki storage directory anew. +func handlerReindex(w http.ResponseWriter, rq *http.Request) { + util.PrepareRq(rq) + if ok := user.CanProceed(rq, "reindex"); !ok { + var lc = l18n.FromRequest(rq) + viewutil.HttpErr(viewutil.MetaFrom(w, rq), lc, http.StatusForbidden, cfg.HomeHypha, lc.Get("ui.reindex_no_rights")) + log.Println("Rejected", rq.URL) + return + } + hyphae.ResetCount() + log.Println("Reindexing hyphae in", files.HyphaeDir()) + hyphae.Index(files.HyphaeDir()) + backlinks.IndexBacklinks() + http.Redirect(w, rq, "/", http.StatusSeeOther) +} + +// handlerUpdateHeaderLinks updates header links by reading the configured hypha, if there is any, or resorting to default values. +func handlerUpdateHeaderLinks(w http.ResponseWriter, rq *http.Request) { + util.PrepareRq(rq) + if ok := user.CanProceed(rq, "update-header-links"); !ok { + var lc = l18n.FromRequest(rq) + viewutil.HttpErr(viewutil.MetaFrom(w, rq), lc, http.StatusForbidden, cfg.HomeHypha, lc.Get("ui.header_no_rights")) + log.Println("Rejected", rq.URL) + return + } + shroom.SetHeaderLinks() + http.Redirect(w, rq, "/", http.StatusSeeOther) +} + +// handlerRandom redirects to a random hypha. +func handlerRandom(w http.ResponseWriter, rq *http.Request) { + util.PrepareRq(rq) + var ( + randomHyphaName string + amountOfHyphae = hyphae.Count() + ) + if amountOfHyphae == 0 { + var lc = l18n.FromRequest(rq) + viewutil.HttpErr(viewutil.MetaFrom(w, rq), lc, http.StatusNotFound, cfg.HomeHypha, lc.Get("ui.random_no_hyphae_tip")) + return + } + i := rand.Intn(amountOfHyphae) + for h := range hyphae.YieldExistingHyphae() { + if i == 0 { + randomHyphaName = h.CanonicalName() + } + i-- + } + http.Redirect(w, rq, "/hypha/"+randomHyphaName, http.StatusSeeOther) +} + +// handlerAbout shows a summary of wiki's software. +func handlerAbout(w http.ResponseWriter, rq *http.Request) { + w.Header().Set("Content-Type", "text/html;charset=utf-8") + w.WriteHeader(http.StatusOK) + var ( + lc = l18n.FromRequest(rq) + title = lc.Get("ui.about_title", &l18n.Replacements{"name": cfg.WikiName}) + ) + _, err := io.WriteString(w, views.Base( + viewutil.MetaFrom(w, rq), + title, + views.AboutHTML(lc), + )) + if err != nil { + log.Println(err) + } +} diff --git a/viewutil/err.go b/viewutil/err.go new file mode 100644 index 0000000..200233e --- /dev/null +++ b/viewutil/err.go @@ -0,0 +1,28 @@ +package viewutil + +import ( + "fmt" + "github.com/bouncepaw/mycorrhiza/l18n" + "mime" + "net/http" +) + +// HttpErr is used by many handlers to signal errors in a compact way. +// TODO: get rid of this abomination +func HttpErr(meta Meta, lc *l18n.Localizer, status int, name, errMsg string) { + meta.W.(http.ResponseWriter).Header().Set("Content-Type", mime.TypeByExtension(".html")) + meta.W.(http.ResponseWriter).WriteHeader(status) + fmt.Fprint( + meta.W, + Base( + meta, + "Error", + fmt.Sprintf( + `

%s. %s

`, + errMsg, + name, + lc.Get("ui.error_go_back"), + ), + ), + ) +} diff --git a/web/mutators.go b/web/mutators.go index d14cb4c..0737e69 100644 --- a/web/mutators.go +++ b/web/mutators.go @@ -39,7 +39,7 @@ func handlerRemoveMedia(w http.ResponseWriter, rq *http.Request) { meta = viewutil.MetaFrom(w, rq) ) if !u.CanProceed("remove-media") { - httpErr(meta, lc, http.StatusForbidden, h.CanonicalName(), "no rights") + viewutil.HttpErr(meta, lc, http.StatusForbidden, h.CanonicalName(), "no rights") return } if rq.Method == "GET" { @@ -53,11 +53,11 @@ func handlerRemoveMedia(w http.ResponseWriter, rq *http.Request) { } switch h := h.(type) { case *hyphae.EmptyHypha, *hyphae.TextualHypha: - httpErr(meta, lc, http.StatusForbidden, h.CanonicalName(), "no media to remove") + viewutil.HttpErr(meta, lc, http.StatusForbidden, h.CanonicalName(), "no media to remove") return case *hyphae.MediaHypha: if err := shroom.RemoveMedia(u, h); err != nil { - httpErr(meta, lc, http.StatusInternalServerError, h.CanonicalName(), err.Error()) + viewutil.HttpErr(meta, lc, http.StatusInternalServerError, h.CanonicalName(), err.Error()) return } } @@ -74,7 +74,7 @@ func handlerDelete(w http.ResponseWriter, rq *http.Request) { if !u.CanProceed("delete") { log.Printf("%s has no rights to delete ‘%s’\n", u.Name, h.CanonicalName()) - httpErr(meta, lc, http.StatusForbidden, h.CanonicalName(), "No rights") + viewutil.HttpErr(meta, lc, http.StatusForbidden, h.CanonicalName(), "No rights") return } @@ -82,7 +82,7 @@ func handlerDelete(w http.ResponseWriter, rq *http.Request) { case *hyphae.EmptyHypha: log.Printf("%s tries to delete empty hypha ‘%s’\n", u.Name, h.CanonicalName()) // TODO: localize - httpErr(meta, lc, http.StatusForbidden, h.CanonicalName(), "Cannot delete an empty hypha") + viewutil.HttpErr(meta, lc, http.StatusForbidden, h.CanonicalName(), "Cannot delete an empty hypha") return } @@ -98,7 +98,7 @@ func handlerDelete(w http.ResponseWriter, rq *http.Request) { if err := shroom.Delete(u, h.(hyphae.ExistingHypha)); err != nil { log.Println(err) - httpErr(meta, lc, http.StatusInternalServerError, h.CanonicalName(), err.Error()) + viewutil.HttpErr(meta, lc, http.StatusInternalServerError, h.CanonicalName(), err.Error()) return } http.Redirect(w, rq, "/hypha/"+h.CanonicalName(), http.StatusSeeOther) @@ -116,13 +116,13 @@ func handlerRename(w http.ResponseWriter, rq *http.Request) { switch h.(type) { case *hyphae.EmptyHypha: log.Printf("%s tries to rename empty hypha ‘%s’", u.Name, h.CanonicalName()) - httpErr(meta, lc, http.StatusForbidden, h.CanonicalName(), "Cannot rename an empty hypha") // TODO: localize + viewutil.HttpErr(meta, lc, 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()) - httpErr(meta, lc, http.StatusForbidden, h.CanonicalName(), "No rights") + viewutil.HttpErr(meta, lc, http.StatusForbidden, h.CanonicalName(), "No rights") return } @@ -144,7 +144,7 @@ func handlerRename(w http.ResponseWriter, rq *http.Request) { if err := shroom.Rename(oldHypha, newName, recursive, u); err != nil { log.Printf("%s tries to rename ‘%s’: %s", u.Name, oldHypha.CanonicalName(), err.Error()) - httpErr(meta, lc, http.StatusForbidden, oldHypha.CanonicalName(), lc.Get(err.Error())) // TODO: localize + viewutil.HttpErr(meta, lc, http.StatusForbidden, oldHypha.CanonicalName(), lc.Get(err.Error())) // TODO: localize return } http.Redirect(w, rq, "/hypha/"+newName, http.StatusSeeOther) @@ -164,7 +164,7 @@ func handlerEdit(w http.ResponseWriter, rq *http.Request) { meta = viewutil.MetaFrom(w, rq) ) if err := shroom.CanEdit(u, h, lc); err != nil { - httpErr(meta, lc, http.StatusInternalServerError, hyphaName, + viewutil.HttpErr(meta, lc, http.StatusInternalServerError, hyphaName, err.Error()) return } @@ -175,7 +175,7 @@ func handlerEdit(w http.ResponseWriter, rq *http.Request) { textAreaFill, err = shroom.FetchTextFile(h) if err != nil { log.Println(err) - httpErr(meta, lc, http.StatusInternalServerError, hyphaName, + viewutil.HttpErr(meta, lc, http.StatusInternalServerError, hyphaName, lc.Get("ui.error_text_fetch")) return } @@ -204,7 +204,7 @@ func handlerUploadText(w http.ResponseWriter, rq *http.Request) { if action != "Preview" { if err := shroom.UploadText(h, []byte(textData), message, u); err != nil { - httpErr(meta, lc, http.StatusForbidden, hyphaName, err.Error()) + viewutil.HttpErr(meta, lc, http.StatusForbidden, hyphaName, err.Error()) return } } @@ -242,11 +242,11 @@ func handlerUploadBinary(w http.ResponseWriter, rq *http.Request) { meta = viewutil.MetaFrom(w, rq) ) if err != nil { - httpErr(meta, lc, http.StatusInternalServerError, hyphaName, + viewutil.HttpErr(meta, lc, http.StatusInternalServerError, hyphaName, err.Error()) } if err := shroom.CanAttach(u, h, lc); err != nil { - httpErr(meta, lc, http.StatusInternalServerError, hyphaName, + viewutil.HttpErr(meta, lc, http.StatusInternalServerError, hyphaName, err.Error()) } @@ -265,7 +265,7 @@ func handlerUploadBinary(w http.ResponseWriter, rq *http.Request) { ) if err := shroom.UploadBinary(h, mime, file, u); err != nil { - httpErr(meta, lc, http.StatusInternalServerError, hyphaName, err.Error()) + viewutil.HttpErr(meta, lc, http.StatusInternalServerError, hyphaName, err.Error()) return } http.Redirect(w, rq, "/hypha/"+hyphaName, http.StatusSeeOther) diff --git a/web/stuff.go b/web/stuff.go index f43c387..71eb1f7 100644 --- a/web/stuff.go +++ b/web/stuff.go @@ -2,24 +2,15 @@ package web // stuff.go is used for meta stuff about the wiki or all hyphae at once. import ( - "github.com/bouncepaw/mycorrhiza/hyphae/backlinks" "github.com/bouncepaw/mycorrhiza/viewutil" "io" - "log" - "math/rand" "net/http" "strings" "github.com/gorilla/mux" - "github.com/bouncepaw/mycorrhiza/cfg" - "github.com/bouncepaw/mycorrhiza/files" "github.com/bouncepaw/mycorrhiza/help" - "github.com/bouncepaw/mycorrhiza/hyphae" "github.com/bouncepaw/mycorrhiza/l18n" - "github.com/bouncepaw/mycorrhiza/shroom" - "github.com/bouncepaw/mycorrhiza/user" - "github.com/bouncepaw/mycorrhiza/util" "github.com/bouncepaw/mycorrhiza/views" "github.com/bouncepaw/mycomarkup/v3" @@ -28,14 +19,6 @@ import ( func initStuff(r *mux.Router) { r.PathPrefix("/help").HandlerFunc(handlerHelp) - r.HandleFunc("/list", handlerList) - r.HandleFunc("/reindex", handlerReindex) - r.HandleFunc("/update-header-links", handlerUpdateHeaderLinks) - r.HandleFunc("/random", handlerRandom) - r.HandleFunc("/about", handlerAbout) - r.HandleFunc("/favicon.ico", func(w http.ResponseWriter, rq *http.Request) { - http.Redirect(w, rq, "/static/favicon.ico", http.StatusSeeOther) - }) } // handlerHelp gets the appropriate documentation or tells you where you (personally) have failed. @@ -94,85 +77,3 @@ func handlerHelp(w http.ResponseWriter, rq *http.Request) { ), ) } - -// handlerList shows a list of all hyphae in the wiki in random order. -func handlerList(w http.ResponseWriter, rq *http.Request) { - var lc = l18n.FromRequest(rq) - util.PrepareRq(rq) - util.HTTP200Page(w, views.Base( - viewutil.MetaFrom(w, rq), - lc.Get("ui.list_title"), - views.HyphaList(lc), - )) -} - -// handlerReindex reindexes all hyphae by checking the wiki storage directory anew. -func handlerReindex(w http.ResponseWriter, rq *http.Request) { - util.PrepareRq(rq) - if ok := user.CanProceed(rq, "reindex"); !ok { - var lc = l18n.FromRequest(rq) - httpErr(viewutil.MetaFrom(w, rq), lc, http.StatusForbidden, cfg.HomeHypha, lc.Get("ui.reindex_no_rights")) - log.Println("Rejected", rq.URL) - return - } - hyphae.ResetCount() - log.Println("Reindexing hyphae in", files.HyphaeDir()) - hyphae.Index(files.HyphaeDir()) - backlinks.IndexBacklinks() - http.Redirect(w, rq, "/", http.StatusSeeOther) -} - -// handlerUpdateHeaderLinks updates header links by reading the configured hypha, if there is any, or resorting to default values. -// -// See https://mycorrhiza.wiki/hypha/configuration/header -func handlerUpdateHeaderLinks(w http.ResponseWriter, rq *http.Request) { - util.PrepareRq(rq) - if ok := user.CanProceed(rq, "update-header-links"); !ok { - var lc = l18n.FromRequest(rq) - httpErr(viewutil.MetaFrom(w, rq), lc, http.StatusForbidden, cfg.HomeHypha, lc.Get("ui.header_no_rights")) - log.Println("Rejected", rq.URL) - return - } - shroom.SetHeaderLinks() - http.Redirect(w, rq, "/", http.StatusSeeOther) -} - -// handlerRandom redirects to a random hypha. -func handlerRandom(w http.ResponseWriter, rq *http.Request) { - util.PrepareRq(rq) - var ( - randomHyphaName string - amountOfHyphae = hyphae.Count() - ) - if amountOfHyphae == 0 { - var lc = l18n.FromRequest(rq) - httpErr(viewutil.MetaFrom(w, rq), lc, http.StatusNotFound, cfg.HomeHypha, lc.Get("ui.random_no_hyphae_tip")) - return - } - i := rand.Intn(amountOfHyphae) - for h := range hyphae.YieldExistingHyphae() { - if i == 0 { - randomHyphaName = h.CanonicalName() - } - i-- - } - http.Redirect(w, rq, "/hypha/"+randomHyphaName, http.StatusSeeOther) -} - -// handlerAbout shows a summary of wiki's software. -func handlerAbout(w http.ResponseWriter, rq *http.Request) { - w.Header().Set("Content-Type", "text/html;charset=utf-8") - w.WriteHeader(http.StatusOK) - var ( - lc = l18n.FromRequest(rq) - title = lc.Get("ui.about_title", &l18n.Replacements{"name": cfg.WikiName}) - ) - _, err := io.WriteString(w, views.Base( - viewutil.MetaFrom(w, rq), - title, - views.AboutHTML(lc), - )) - if err != nil { - log.Println(err) - } -} diff --git a/web/web.go b/web/web.go index 04a1cbd..0686cb2 100644 --- a/web/web.go +++ b/web/web.go @@ -2,8 +2,8 @@ package web import ( - "fmt" "github.com/bouncepaw/mycorrhiza/categories" + "github.com/bouncepaw/mycorrhiza/misc" "github.com/bouncepaw/mycorrhiza/viewutil" "io" "mime" @@ -22,26 +22,6 @@ import ( var stylesheets = []string{"default.css", "custom.css"} -// httpErr is used by many handlers to signal errors in a compact way. -// TODO: get rid of this abomination -func httpErr(meta viewutil.Meta, lc *l18n.Localizer, status int, name, errMsg string) { - meta.W.(http.ResponseWriter).Header().Set("Content-Type", mime.TypeByExtension(".html")) - meta.W.(http.ResponseWriter).WriteHeader(status) - fmt.Fprint( - meta.W, - views.Base( - meta, - "Error", - fmt.Sprintf( - `

%s. %s

`, - errMsg, - name, - lc.Get("ui.error_go_back"), - ), - ), - ) -} - func handlerStyle(w http.ResponseWriter, rq *http.Request) { w.Header().Set("Content-Type", mime.TypeByExtension(".css")) for _, name := range stylesheets { @@ -111,6 +91,7 @@ func Handler() http.Handler { initSearch(wikiRouter) initBacklinks(wikiRouter) categories.InitHandlers(wikiRouter) + misc.InitHandlers(wikiRouter) // Admin routes. if cfg.UseAuth {