package main
import (
"os"
"io/ioutil"
"net/http"
"path"
"path/filepath"
"strings"
)
const staticPrefix = "/static/"
type NavTree struct {
name string
path string
children []NavTree
hasIndex bool
selected bool
}
func stripPath(caminho string) string {
caminho = path.Clean(caminho)
return "/" + path.Join(strings.Split(caminho, "/")[1:]...)
}
func rootTree(root string, goal string) (NavTree, string) {
nav := NavTree{}
nav.name = path.Base(root)
nav.path = root
nav.selected = false
index := ""
if !strings.HasPrefix(goal, root) {
return nav, index
}
nav.selected = true
filepath.Walk(root, func(current string, info os.FileInfo, err error) error {
if info.Name() == ".index" {
index = current
}
if info.IsDir() && info.Name()[0] == '.' {
return filepath.SkipDir
}
if current == root || info.Name()[0] == '.' {
return nil
}
rec, idx := rootTree(current, goal)
if idx != "" {
index = idx
}
nav.children = append(nav.children, rec)
if info.IsDir() {
return filepath.SkipDir
} else {
return nil
}
})
return nav, index
}
func RenderList(children []NavTree) string {
deleg := ""
ul := "
"
for _, s := range children {
u, d := s.Render()
ul += u
deleg += d
}
ul += "
"
ul += deleg
return ul
}
func (v *NavTree) Render() (string, string) {
li := ""
if v.selected {
li += ""
} else {
li += ""
}
li += v.name
li += ""
deleg := ""
if len(v.children) > 0 {
deleg += RenderList(v.children)
}
return li, deleg
}
func build(request *http.Request) (string, int) {
code := 200
root := request.Host
postLoc := path.Join(root, request.URL.Path)
if strings.HasPrefix(request.URL.Path, staticPrefix) {
staticLoc := path.Join(root, request.URL.Path[len(staticPrefix):])
static, err0 := ioutil.ReadFile(staticLoc)
if err0 != nil {
return "Path not found", 404
}
return string(static), 200
}
tr, idx := rootTree(root, postLoc)
template, err0 := ioutil.ReadFile(idx)
if err0 != nil {
return "No template in tree", 500
}
final := string(template)
post, err1 := ioutil.ReadFile(postLoc)
if err1 != nil {
viewLoc := path.Join(root, request.URL.Path, ".view")
view, err1_0 := ioutil.ReadFile(viewLoc)
if err1_0 != nil {
return "Path not found", 404
}
post = view
}
final = strings.Replace(string(template), "{{ post }}", string(post), -1)
final = strings.Replace(string(final), "{{ nav }}", RenderList(tr.children), -1)
return final, code
}
func handler(w http.ResponseWriter, r *http.Request) {
content, code := build(r)
w.WriteHeader(code)
w.Write([]byte(content))
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}