109 lines
2 KiB
Go
109 lines
2 KiB
Go
|
package server
|
||
|
|
||
|
import (
|
||
|
"github.com/gomarkdown/markdown"
|
||
|
"vultras.su/core/bond"
|
||
|
"vultras.su/core/bond/contents"
|
||
|
"vultras.su/util/pp"
|
||
|
"path/filepath"
|
||
|
"os"
|
||
|
)
|
||
|
|
||
|
type ServerOptions struct {
|
||
|
WikiPath string
|
||
|
WebPath string
|
||
|
}
|
||
|
|
||
|
type Server struct {
|
||
|
handler bond.Handler
|
||
|
options ServerOptions
|
||
|
prep *pp.Preprocessor
|
||
|
}
|
||
|
|
||
|
func New(opts ServerOptions) *Server {
|
||
|
srv := &Server{}
|
||
|
srv.handler = makeRootHandler(opts)
|
||
|
srv.options = opts
|
||
|
srv.prep = pp.NewPp(pp.NewTengo())
|
||
|
return srv
|
||
|
}
|
||
|
|
||
|
func (srv *Server) Handle(c *bond.Context) {
|
||
|
c.Data = ContextData{
|
||
|
Server: srv,
|
||
|
}
|
||
|
srv.handler.Handle(c)
|
||
|
}
|
||
|
|
||
|
func (srv *Server) ProcessPmd(pth string, bts []byte) ([]byte, error) {
|
||
|
prep, err := srv.prep.Process(pth, string(bts))
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
return []byte(prep), nil
|
||
|
}
|
||
|
|
||
|
func (srv *Server) ProcessToHtml(bts []byte) ([]byte, error) {
|
||
|
html := markdown.ToHTML(bts, nil, nil)
|
||
|
ret := append([]byte(htmlHead), html...)
|
||
|
return append(ret, []byte(htmlFooter)...), nil
|
||
|
}
|
||
|
|
||
|
func (srv *Server) wikiFilePath(pth string) string {
|
||
|
if pth == "/" || pth == "" {
|
||
|
return srv.options.WikiPath + "/index.pmd"
|
||
|
}
|
||
|
if pth[len(pth)-1] == '/' {
|
||
|
pth += "index"
|
||
|
}
|
||
|
return filepath.FromSlash(
|
||
|
srv.options.WikiPath + "/" + pth + ".pmd",
|
||
|
)
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
const htmlHead = `
|
||
|
<!doctype html>
|
||
|
<html><head>
|
||
|
<title>Title</title>
|
||
|
<link rel="stylesheet" href="/web/main.css">
|
||
|
</head><body>
|
||
|
<main>
|
||
|
`
|
||
|
|
||
|
const htmlFooter = `
|
||
|
</main>
|
||
|
</body></html>
|
||
|
`
|
||
|
|
||
|
var makeRootHandler = func(opts ServerOptions) bond.Handler {
|
||
|
return bond.Root(bond.Path().
|
||
|
Case(
|
||
|
"web",
|
||
|
bond.StaticDir(opts.WebPath),
|
||
|
).Case(
|
||
|
"api",
|
||
|
nil,
|
||
|
).Default(
|
||
|
Func(func(c *Context){
|
||
|
pth := c.wikiFilePath(c.Path())
|
||
|
bts, err := os.ReadFile(pth)
|
||
|
if err != nil {
|
||
|
c.NotFound()
|
||
|
return
|
||
|
}
|
||
|
prep, err := c.ProcessPmd(pth, bts)
|
||
|
if err != nil {
|
||
|
c.InternalServerError(err)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
bts, _ = c.ProcessToHtml(prep)
|
||
|
c.SetContentType(contents.Html, contents.Utf8)
|
||
|
c.W.Write(bts)
|
||
|
}),
|
||
|
))
|
||
|
}
|