package web import ( "fmt" "github.com/bouncepaw/mycomarkup/mycocontext" "github.com/bouncepaw/mycorrhiza/cfg" "log" "net/http" "os" "path/filepath" "strings" "github.com/bouncepaw/mycorrhiza/history" "github.com/bouncepaw/mycorrhiza/hyphae" "github.com/bouncepaw/mycorrhiza/mimetype" "github.com/bouncepaw/mycorrhiza/user" "github.com/bouncepaw/mycorrhiza/util" "github.com/bouncepaw/mycorrhiza/views" "github.com/bouncepaw/mycomarkup" ) func initReaders() { http.HandleFunc("/page/", handlerHypha) http.HandleFunc("/hypha/", handlerHypha) http.HandleFunc("/text/", handlerText) http.HandleFunc("/binary/", handlerBinary) http.HandleFunc("/rev/", handlerRevision) http.HandleFunc("/primitive-diff/", handlerPrimitiveDiff) http.HandleFunc("/attachment/", handlerAttachment) } func handlerAttachment(w http.ResponseWriter, rq *http.Request) { util.PrepareRq(rq) var ( hyphaName = util.HyphaNameFromRq(rq, "attachment") h = hyphae.ByName(hyphaName) u = user.FromRequest(rq) ) if shown := u.ShowLockMaybe(w, rq); shown { return } util.HTTP200Page(w, views.BaseHTML( fmt.Sprintf("Attachment of %s", util.BeautifulName(hyphaName)), views.AttachmentMenuHTML(rq, h, u), u)) } func handlerPrimitiveDiff(w http.ResponseWriter, rq *http.Request) { util.PrepareRq(rq) var ( shorterUrl = strings.TrimPrefix(rq.URL.Path, "/primitive-diff/") firstSlashIndex = strings.IndexRune(shorterUrl, '/') revHash = shorterUrl[:firstSlashIndex] hyphaName = util.CanonicalName(shorterUrl[firstSlashIndex+1:]) h = hyphae.ByName(hyphaName) u = user.FromRequest(rq) ) if shown := u.ShowLockMaybe(w, rq); shown { return } util.HTTP200Page(w, views.BaseHTML( fmt.Sprintf("Diff of %s at %s", hyphaName, revHash), views.PrimitiveDiffHTML(rq, h, u, revHash), u)) } // handlerRevision displays a specific revision of text part a page func handlerRevision(w http.ResponseWriter, rq *http.Request) { util.PrepareRq(rq) var ( shorterUrl = strings.TrimPrefix(rq.URL.Path, "/rev/") firstSlashIndex = strings.IndexRune(shorterUrl, '/') revHash = shorterUrl[:firstSlashIndex] hyphaName = util.CanonicalName(shorterUrl[firstSlashIndex+1:]) h = hyphae.ByName(hyphaName) contents = fmt.Sprintf(`
This hypha had no text at this revision.
`) textContents, err = history.FileAtRevision(h.TextPath, revHash) u = user.FromRequest(rq) ) if shown := u.ShowLockMaybe(w, rq); shown { return } if err == nil { ctx, _ := mycocontext.ContextFromStringInput(hyphaName, textContents) contents = mycomarkup.BlocksToHTML(ctx, mycomarkup.BlockTree(ctx)) } page := views.RevisionHTML( rq, h, contents, revHash, ) w.Header().Set("Content-Type", "text/html;charset=utf-8") w.WriteHeader(http.StatusOK) _, _ = fmt.Fprint(w, views.BaseHTML(util.BeautifulName(hyphaName), page, u)) } // handlerText serves raw source text of the hypha. func handlerText(w http.ResponseWriter, rq *http.Request) { util.PrepareRq(rq) if shown := user.FromRequest(rq).ShowLockMaybe(w, rq); shown { return } hyphaName := util.HyphaNameFromRq(rq, "text") if h := hyphae.ByName(hyphaName); h.Exists { log.Println("Serving", h.TextPath) w.Header().Set("Content-Type", "text/plain; charset=utf-8") http.ServeFile(w, rq, h.TextPath) } } // handlerBinary serves binary part of the hypha. func handlerBinary(w http.ResponseWriter, rq *http.Request) { util.PrepareRq(rq) if shown := user.FromRequest(rq).ShowLockMaybe(w, rq); shown { return } hyphaName := util.HyphaNameFromRq(rq, "binary") if h := hyphae.ByName(hyphaName); h.Exists { log.Println("Serving", h.BinaryPath) w.Header().Set("Content-Type", mimetype.FromExtension(filepath.Ext(h.BinaryPath))) http.ServeFile(w, rq, h.BinaryPath) } } // handlerHypha is the main hypha action that displays the hypha and the binary upload form along with some navigation. func handlerHypha(w http.ResponseWriter, rq *http.Request) { util.PrepareRq(rq) var ( hyphaName = util.HyphaNameFromRq(rq, "page", "hypha") h = hyphae.ByName(hyphaName) contents string openGraph string u = user.FromRequest(rq) ) if shown := u.ShowLockMaybe(w, rq); shown { return } if h.Exists { fileContentsT, errT := os.ReadFile(h.TextPath) _, errB := os.Stat(h.BinaryPath) if errT == nil { ctx, _ := mycocontext.ContextFromStringInput(hyphaName, string(fileContentsT)) ctx = mycocontext.WithWebSiteURL(ctx, cfg.URL) getOpenGraph, descVisitor, imgVisitor := mycomarkup.OpenGraphVisitors(ctx) ast := mycomarkup.BlockTree(ctx, descVisitor, imgVisitor) contents = mycomarkup.BlocksToHTML(ctx, ast) openGraph = getOpenGraph() } if !os.IsNotExist(errB) { contents = views.AttachmentHTML(h) + contents } } if contents == "" { util.HTTP404Page(w, views.BaseHTML( util.BeautifulName(hyphaName), views.HyphaHTML(rq, h, contents), u, openGraph)) } else { util.HTTP200Page(w, views.BaseHTML( util.BeautifulName(hyphaName), views.HyphaHTML(rq, h, contents), u, openGraph)) } }