Top nav works

master
scratch 2019-10-19 05:46:55 +00:00
parent a8ee907a0f
commit a6325abca3
10 changed files with 81 additions and 131 deletions

View File

@ -4,29 +4,23 @@ import (
"fmt"
"io/ioutil"
"net/http"
"os"
)
func isDir(path string) bool {
stat, err := os.Stat(path)
return err == nil && stat.IsDir()
}
func notesDir(path string, w http.ResponseWriter, r *http.Request) {
func notesDir(path Path, w http.ResponseWriter, r *http.Request) {
dirs, files := lsDir(path)
content := dirs.List()
block(content, w)
fmt.Fprintln(w, files.List())
}
func lsDir(p string) (Paths, Paths) {
func lsDir(path Path) (Paths, Paths) {
dirs := newDirs()
files := newFiles()
found, _ := ioutil.ReadDir(p)
found, _ := ioutil.ReadDir(path.Local)
for _, f := range found {
dirs.Push(p, f)
files.Push(p, f)
dirs.Push(path, f)
files.Push(path, f)
}
return Paths(*dirs), Paths(*files)
}

View File

@ -5,20 +5,9 @@ import (
"testing"
)
func TestIsDir(t *testing.T) {
if ok := isDir("/tmp"); !ok {
t.Fatal(ok)
}
if ok := isDir("/dev/null"); ok {
t.Fatal(ok)
}
if ok := isDir("/proc/not/real/tho"); ok {
t.Fatal(ok)
}
}
func TestLsDir(t *testing.T) {
dirs, files := lsDir("/usr/local")
p := Path{Local: "/usr/local"}
dirs, files := lsDir(p)
if len(dirs) == 0 {
t.Fatal(len(dirs))
}
@ -30,7 +19,7 @@ func TestLsDir(t *testing.T) {
}
func TestNotesDir(t *testing.T) {
path := "/usr/local"
path := Path{Local: "/usr/local"}
w := httptest.NewRecorder()
notesDir(path, w, nil)
t.Logf("%s", w.Body.Bytes())

View File

@ -2,6 +2,7 @@ package server
import (
"os"
"path"
)
type Dirs []Path
@ -11,11 +12,8 @@ func newDirs() *Dirs {
return &d
}
func (d *Dirs) Push(p string, f os.FileInfo) {
func (d *Dirs) Push(p Path, f os.FileInfo) {
if f.IsDir() {
*d = append(*d, Path{
dir: p,
base: f.Name(),
})
*d = append(*d, NewPathFromLocal(path.Join(p.Local, f.Name())))
}
}

View File

@ -4,20 +4,12 @@ import (
"fmt"
"io/ioutil"
"net/http"
"os"
"github.com/gomarkdown/markdown"
)
func isFile(path string) bool {
stat, err := os.Stat(path)
return err == nil && !stat.IsDir()
}
func notesFile(path string, w http.ResponseWriter, r *http.Request) {
title := h1(path)
block(title, w)
b, _ := ioutil.ReadFile(path)
func notesFile(path Path, w http.ResponseWriter, r *http.Request) {
b, _ := ioutil.ReadFile(path.Local)
content := markdown.ToHTML(b, nil, nil)
fmt.Fprintf(w, "%s\n", content)
}

View File

@ -9,18 +9,6 @@ import (
"testing"
)
func TestIsFile(t *testing.T) {
if ok := isFile("/tmp"); ok {
t.Fatal(ok)
}
if ok := isFile("/dev/null"); !ok {
t.Fatal(ok)
}
if ok := isFile("/proc/not/real/tho"); ok {
t.Fatal(ok)
}
}
func TestNotesFile(t *testing.T) {
f, err := ioutil.TempFile(os.TempDir(), "until*")
if err != nil {
@ -41,7 +29,8 @@ func TestNotesFile(t *testing.T) {
`)
f.Close()
w := httptest.NewRecorder()
notesFile(f.Name(), w, nil)
p := Path{Local: f.Name()}
notesFile(p, w, nil)
s := string(w.Body.Bytes())
shouldContain := []string{
"tbody",

View File

@ -2,6 +2,7 @@ package server
import (
"os"
"path"
)
type Files []Path
@ -11,11 +12,8 @@ func newFiles() *Files {
return &d
}
func (d *Files) Push(p string, f os.FileInfo) {
func (d *Files) Push(p Path, f os.FileInfo) {
if !f.IsDir() {
*d = append(*d, Path{
dir: p,
base: f.Name(),
})
*d = append(*d, NewPathFromLocal(path.Join(p.Local, f.Name())))
}
}

View File

@ -2,20 +2,17 @@ package server
import (
"fmt"
"local/notes-server/config"
"net/http"
"path"
"strings"
)
func (s *Server) notes(w http.ResponseWriter, r *http.Request) {
p := resolvePath(r.URL.Path)
if isDir(p) {
p := NewPath(r.URL.Path)
if p.IsDir() {
head(w, r)
notesHead(w, p)
notesDir(p, w, r)
foot(w, r)
} else if isFile(p) {
} else if p.IsFile() {
head(w, r)
notesHead(w, p)
notesFile(p, w, r)
@ -25,18 +22,6 @@ func (s *Server) notes(w http.ResponseWriter, r *http.Request) {
}
}
func resolvePath(p string) string {
p = strings.TrimPrefix(p, "/")
p = strings.TrimPrefix(p, "notes")
p = strings.TrimPrefix(p, "/")
p = path.Join(config.Root, p)
return p
}
func notesHead(w http.ResponseWriter, p string) {
path := Path{
dir: path.Dir(p),
base: path.Base(p),
}
fmt.Fprintln(w, h2(path.MultiLink()))
func notesHead(w http.ResponseWriter, p Path) {
fmt.Fprintln(w, h2(p.MultiLink()))
}

View File

@ -1,13 +1 @@
package server
import (
"local/notes-server/config"
"testing"
)
func TestResolvePath(t *testing.T) {
config.Root = "ROOT"
if p := resolvePath("/notes/a/b/c"); p != "ROOT/a/b/c" {
t.Fatal(p)
}
}

View File

@ -3,6 +3,7 @@ package server
import (
"fmt"
"local/notes-server/config"
"os"
"path"
"strings"
)
@ -13,12 +14,23 @@ type Path struct {
Base string
}
func NewPathFromLocal(p string) Path {
splits := strings.SplitN(p, path.Base(config.Root), 2)
href := splits[0]
if len(splits) > 1 {
href = splits[1]
}
href = path.Join("/notes", href)
return NewPath(href)
}
func NewPath(p string) Path {
base := path.Base(p)
href := path.Join("/notes", p)
local := strings.TrimPrefix(p, "/")
local = strings.TrimPrefix(p, "notes")
local = strings.TrimPrefix(p, "/")
href := p
local := strings.TrimPrefix(p, "/notes")
if len(local) != len(p) {
local = strings.TrimPrefix(local, "/")
}
local = path.Join(config.Root, local)
return Path{
Base: base,
@ -28,31 +40,36 @@ func NewPath(p string) Path {
}
func (p Path) MultiLink() string {
pa := path.Join("/notes", p.String())
href := p.HREF
href = strings.TrimPrefix(href, "/")
href = strings.TrimSuffix(href, "/")
segments := strings.Split(href, "/")
full := ""
for pa != "/" {
base := path.Base(pa)
full = fmt.Sprintf(`/<a href=%q>%s</a>`, pa, base) + full
pa = path.Dir(pa)
for i := range segments {
href := "/" + strings.Join(segments[:i], "/") + "/"
href += segments[i]
href = path.Clean(href)
base := segments[i]
add := fmt.Sprintf(`/<a href=%q>%s</a>`, href, base)
full += add
}
return full
}
func (p Path) String() string {
root := path.Base(config.Root)
dir := p.dir
dirs := strings.SplitN(dir, root, 2)
dir = dirs[0]
if len(dirs) > 1 {
dir = dirs[1]
}
base := p.base
return path.Join(dir, base)
func (p Path) LI() string {
return fmt.Sprintf(`<li><a href=%q>%s</a></li>`, p.HREF, p.Base)
}
func (p Path) LI() string {
content := fmt.Sprintf(`<li><a href="%s">`, path.Join("/notes", p.String()))
content += p.base
content += "</li>"
return content
func (p Path) IsDir() bool {
stat, err := os.Stat(p.Local)
return err == nil && stat.IsDir()
}
func (p Path) IsFile() bool {
stat, err := os.Stat(p.Local)
return err == nil && !stat.IsDir()
}
func (p Path) String() string {
return fmt.Sprintf(`[Local:%s HREF:%s Base:%s]`, p.Local, p.HREF, p.Base)
}

View File

@ -1,23 +1,23 @@
package server
import (
"regexp"
"testing"
)
import "testing"
func TestPathLI(t *testing.T) {
p := Path{
dir: "a/b/c",
base: "d",
}
link := p.LI()
ok, err := regexp.MatchString(`li.*a.*href="a/b/c/d".d..li`, link)
if err != nil {
t.Fatal(err, link)
}
if !ok {
t.Fatal(ok, link)
func TestPathIs(t *testing.T) {
p := Path{Local: "/dev/null"}
if ok := p.IsDir(); ok {
t.Fatal(ok, p)
}
t.Log(p, link)
if ok := p.IsFile(); !ok {
t.Fatal(ok, p)
}
p = Path{Local: "/tmp"}
if ok := p.IsDir(); !ok {
t.Fatal(ok, p)
}
if ok := p.IsFile(); ok {
t.Fatal(ok, p)
}
}