// Package histview provides web stuff for history package histview import ( "embed" "encoding/hex" "github.com/bouncepaw/mycorrhiza/cfg" "github.com/bouncepaw/mycorrhiza/history" "github.com/bouncepaw/mycorrhiza/hyphae" "github.com/bouncepaw/mycorrhiza/util" "github.com/bouncepaw/mycorrhiza/viewutil" "github.com/gorilla/mux" "log" "net/http" "strconv" "strings" "text/template" ) func InitHandlers(rtr *mux.Router) { rtr.PathPrefix("/primitive-diff/").HandlerFunc(handlerPrimitiveDiff) rtr.HandleFunc("/recent-changes/{count:[0-9]+}", handlerRecentChanges) rtr.HandleFunc("/recent-changes/", func(w http.ResponseWriter, rq *http.Request) { http.Redirect(w, rq, "/recent-changes/20", http.StatusSeeOther) }) chainPrimitiveDiff = viewutil. En(viewutil.CopyEnWith(fs, "view_primitive_diff.html")). Ru(template.Must(viewutil.CopyRuWith(fs, "view_primitive_diff.html").Parse(ruTranslation))) chainRecentChanges = viewutil. En(viewutil.CopyEnWith(fs, "view_recent_changes.html")). Ru(template.Must(viewutil.CopyRuWith(fs, "view_recent_changes.html").Parse(ruTranslation))) } func handlerPrimitiveDiff(w http.ResponseWriter, rq *http.Request) { util.PrepareRq(rq) shorterURL := strings.TrimPrefix(rq.URL.Path, "/primitive-diff/") revHash, slug, found := strings.Cut(shorterURL, "/") if !found || len(revHash) < 7 || len(slug) < 1 { http.Error(w, "403 bad request", http.StatusBadRequest) return } paddedRevHash := revHash if len(paddedRevHash)%2 != 0 { paddedRevHash = paddedRevHash[:len(paddedRevHash)-1] } if _, err := hex.DecodeString(paddedRevHash); err != nil { http.Error(w, "403 bad request", http.StatusBadRequest) return } switch h := hyphae.ByName(util.CanonicalName(slug)).(type) { case *hyphae.EmptyHypha: http.Error(w, "404 not found", http.StatusNotFound) case hyphae.ExistingHypha: text, err := history.PrimitiveDiffAtRevision(h.TextFilePath(), revHash) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } primitiveDiff(viewutil.MetaFrom(w, rq), h, revHash, text) } } // handlerRecentChanges displays the /recent-changes/ page. func handlerRecentChanges(w http.ResponseWriter, rq *http.Request) { // Error ignored: filtered by regex editCount, _ := strconv.Atoi(mux.Vars(rq)["count"]) if editCount > 100 { return } recentChanges(viewutil.MetaFrom(w, rq), editCount, history.RecentChanges(editCount)) } var ( //go:embed *.html fs embed.FS ruTranslation = ` {{define "diff for at title"}}Разница для {{beautifulName .HyphaName}} для {{.Hash}}{{end}} {{define "diff for at heading"}}Разница для {{beautifulName .HyphaName}} для {{.Hash}}{{end}} ` chainPrimitiveDiff viewutil.Chain chainRecentChanges viewutil.Chain ) type recentChangesData struct { viewutil.BaseData EditCount int Changes []history.Revision UserHypha string Stops []int } func recentChanges(meta viewutil.Meta, editCount int, changes []history.Revision) { if err := chainRecentChanges.Get(meta).ExecuteTemplate(meta.W, "page", recentChangesData{ BaseData: viewutil.BaseData{ Meta: meta, Addr: "/recent-changes/" + strconv.Itoa(editCount), HeaderLinks: cfg.HeaderLinks, CommonScripts: cfg.CommonScripts, }, EditCount: editCount, Changes: changes, UserHypha: cfg.UserHypha, Stops: []int{20, 50, 100}, }); err != nil { log.Println(err) } } type primitiveDiffData struct { viewutil.BaseData HyphaName string Hash string Text string } func primitiveDiff(meta viewutil.Meta, h hyphae.ExistingHypha, hash, text string) { if err := chainPrimitiveDiff.Get(meta).ExecuteTemplate(meta.W, "page", primitiveDiffData{ BaseData: viewutil.BaseData{ Meta: meta, Addr: "/primitive-diff/" + hash + "/" + h.CanonicalName(), HeaderLinks: cfg.HeaderLinks, CommonScripts: cfg.CommonScripts, }, HyphaName: h.CanonicalName(), Hash: hash, Text: text, }); err != nil { log.Println(err) } }