diff options
Diffstat (limited to 'site.go')
| -rw-r--r-- | site.go | 149 |
1 files changed, 149 insertions, 0 deletions
@@ -0,0 +1,149 @@ +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 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 := "<ul>" + for _, s := range children { + u, d := s.Render() + ul += u + deleg += d + } + ul += "</ul>" + ul += deleg + return ul +} + +func (v *NavTree) Render() (string, string) { + li := "<li><a href=\"" + stripPath(v.path) + "\">" + if v.selected { + li += "<span class=\"nav-intended\">" + } else { + li += "<span class=\"nav-not-intended\">" + } + li += v.name + li += "</span></a></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) +}
\ No newline at end of file |
