All the remaining QTPL files were spread across the codebase. The plan is to get rid of them step by step and migrate to the new l10n approach, all based on Go std templates.
178 lines
5.2 KiB
Go
178 lines
5.2 KiB
Go
// Package misc provides miscellaneous informative views.
|
|
package misc
|
|
|
|
import (
|
|
"github.com/bouncepaw/mycorrhiza/backlinks"
|
|
"github.com/bouncepaw/mycorrhiza/cfg"
|
|
"github.com/bouncepaw/mycorrhiza/files"
|
|
"github.com/bouncepaw/mycorrhiza/hyphae"
|
|
"github.com/bouncepaw/mycorrhiza/l18n"
|
|
"github.com/bouncepaw/mycorrhiza/shroom"
|
|
"github.com/bouncepaw/mycorrhiza/static"
|
|
"github.com/bouncepaw/mycorrhiza/user"
|
|
"github.com/bouncepaw/mycorrhiza/util"
|
|
"github.com/bouncepaw/mycorrhiza/viewutil"
|
|
"github.com/gorilla/mux"
|
|
"io"
|
|
"log"
|
|
"math/rand"
|
|
"mime"
|
|
"net/http"
|
|
"path/filepath"
|
|
)
|
|
|
|
func InitHandlers(rtr *mux.Router) {
|
|
rtr.HandleFunc("/robots.txt", handlerRobotsTxt)
|
|
rtr.HandleFunc("/static/style.css", handlerStyle)
|
|
rtr.PathPrefix("/static/").
|
|
Handler(http.StripPrefix("/static/", http.FileServer(http.FS(static.FS))))
|
|
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)
|
|
})
|
|
rtr.HandleFunc("/title-search/", handlerTitleSearch)
|
|
initViews()
|
|
}
|
|
|
|
// handlerList shows a list of all hyphae in the wiki in random order.
|
|
func handlerList(w http.ResponseWriter, rq *http.Request) {
|
|
util.PrepareRq(rq)
|
|
// TODO: make this more effective, there are too many loops and vars
|
|
var (
|
|
hyphaNames = make(chan string)
|
|
sortedHypha = hyphae.PathographicSort(hyphaNames)
|
|
entries []listDatum
|
|
)
|
|
for hypha := range hyphae.YieldExistingHyphae() {
|
|
hyphaNames <- hypha.CanonicalName()
|
|
}
|
|
close(hyphaNames)
|
|
for hyphaName := range sortedHypha {
|
|
switch h := hyphae.ByName(hyphaName).(type) {
|
|
case *hyphae.TextualHypha:
|
|
entries = append(entries, listDatum{h.CanonicalName(), ""})
|
|
case *hyphae.MediaHypha:
|
|
entries = append(entries, listDatum{h.CanonicalName(), filepath.Ext(h.MediaFilePath())[1:]})
|
|
}
|
|
}
|
|
viewList(viewutil.MetaFrom(w, rq), entries)
|
|
}
|
|
|
|
// 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), 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), 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), 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, viewutil.Base(
|
|
viewutil.MetaFrom(w, rq),
|
|
title,
|
|
AboutHTML(lc),
|
|
))
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
}
|
|
|
|
var stylesheets = []string{"default.css", "custom.css"}
|
|
|
|
func handlerStyle(w http.ResponseWriter, rq *http.Request) {
|
|
w.Header().Set("Content-Type", mime.TypeByExtension(".css"))
|
|
for _, name := range stylesheets {
|
|
file, err := static.FS.Open(name)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
_, err = io.Copy(w, file)
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
_ = file.Close()
|
|
}
|
|
}
|
|
|
|
func handlerRobotsTxt(w http.ResponseWriter, rq *http.Request) {
|
|
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
|
|
|
file, err := static.FS.Open("robots.txt")
|
|
if err != nil {
|
|
return
|
|
}
|
|
_, err = io.Copy(w, file)
|
|
if err != nil {
|
|
log.Println()
|
|
}
|
|
_ = file.Close()
|
|
}
|
|
|
|
func handlerTitleSearch(w http.ResponseWriter, rq *http.Request) {
|
|
util.PrepareRq(rq)
|
|
_ = rq.ParseForm()
|
|
var (
|
|
query = rq.FormValue("q")
|
|
results []string
|
|
)
|
|
for hyphaName := range shroom.YieldHyphaNamesContainingString(query) {
|
|
results = append(results, hyphaName)
|
|
}
|
|
w.WriteHeader(http.StatusOK)
|
|
viewTitleSearch(viewutil.MetaFrom(w, rq), query, results)
|
|
}
|