Split into packages only manually tested
This commit is contained in:
19
filetree/dirs.go
Executable file
19
filetree/dirs.go
Executable file
@@ -0,0 +1,19 @@
|
||||
package filetree
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
)
|
||||
|
||||
type Dirs []Path
|
||||
|
||||
func NewDirs() *Dirs {
|
||||
d := Dirs([]Path{})
|
||||
return &d
|
||||
}
|
||||
|
||||
func (d *Dirs) Push(p Path, f os.FileInfo) {
|
||||
if f.IsDir() {
|
||||
*d = append(*d, NewPathFromLocal(path.Join(p.Local, f.Name())))
|
||||
}
|
||||
}
|
||||
1
filetree/dirs_test.go
Executable file
1
filetree/dirs_test.go
Executable file
@@ -0,0 +1 @@
|
||||
package filetree
|
||||
19
filetree/files.go
Executable file
19
filetree/files.go
Executable file
@@ -0,0 +1,19 @@
|
||||
package filetree
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
)
|
||||
|
||||
type Files []Path
|
||||
|
||||
func NewFiles() *Files {
|
||||
d := Files([]Path{})
|
||||
return &d
|
||||
}
|
||||
|
||||
func (d *Files) Push(p Path, f os.FileInfo) {
|
||||
if !f.IsDir() {
|
||||
*d = append(*d, NewPathFromLocal(path.Join(p.Local, f.Name())))
|
||||
}
|
||||
}
|
||||
1
filetree/files_test.go
Executable file
1
filetree/files_test.go
Executable file
@@ -0,0 +1 @@
|
||||
package filetree
|
||||
92
filetree/path.go
Executable file
92
filetree/path.go
Executable file
@@ -0,0 +1,92 @@
|
||||
package filetree
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"local/notes-server/config"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Path struct {
|
||||
Local string
|
||||
HREF string
|
||||
Base string
|
||||
BaseHREF string
|
||||
}
|
||||
|
||||
func NewPathFromLocal(p string) Path {
|
||||
if !strings.HasPrefix(p, "/") {
|
||||
cwd, _ := os.Getwd()
|
||||
p = path.Clean(path.Join(cwd, p))
|
||||
}
|
||||
splits := strings.SplitN(p, path.Base(config.Root), 2)
|
||||
href := splits[0]
|
||||
if len(splits) > 1 && (splits[0] == "" || splits[0] == "/") {
|
||||
href = splits[1]
|
||||
} else {
|
||||
href = strings.Join(splits, path.Base(config.Root))
|
||||
}
|
||||
href = path.Join("/notes", href)
|
||||
return NewPathFromURL(href)
|
||||
}
|
||||
|
||||
func NewPathFromURL(p string) Path {
|
||||
p = path.Clean(p)
|
||||
base := path.Base(p)
|
||||
href := p
|
||||
local := strings.TrimPrefix(p, "/")
|
||||
locals := strings.SplitN(local, "/", 2)
|
||||
local = locals[0]
|
||||
if len(locals) > 1 {
|
||||
local = locals[1]
|
||||
}
|
||||
baseHREF := local
|
||||
local = path.Join(config.Root, local)
|
||||
if strings.Trim(p, "/") == base {
|
||||
local = config.Root
|
||||
baseHREF = "/"
|
||||
}
|
||||
return Path{
|
||||
Base: base,
|
||||
HREF: href,
|
||||
Local: local,
|
||||
BaseHREF: baseHREF,
|
||||
}
|
||||
}
|
||||
|
||||
func (p Path) MultiLink() string {
|
||||
href := p.BaseHREF
|
||||
href = strings.TrimPrefix(href, "/")
|
||||
href = strings.TrimSuffix(href, "/")
|
||||
href = path.Join("notes/", href)
|
||||
segments := strings.Split(href, "/")
|
||||
full := ""
|
||||
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) LI() string {
|
||||
return fmt.Sprintf(`<li><a href=%q>%s</a></li>`, p.HREF, p.Base)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
71
filetree/path_test.go
Executable file
71
filetree/path_test.go
Executable file
@@ -0,0 +1,71 @@
|
||||
package filetree
|
||||
|
||||
import (
|
||||
"local/notes-server/config"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPathIs(t *testing.T) {
|
||||
p := Path{Local: "/dev/null"}
|
||||
if ok := p.IsDir(); ok {
|
||||
t.Fatal(ok, p)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewPathFromLocal(t *testing.T) {
|
||||
cases := []struct {
|
||||
in string
|
||||
root string
|
||||
href string
|
||||
local string
|
||||
}{
|
||||
{
|
||||
in: "/wiki/b/a.md",
|
||||
root: "/wiki",
|
||||
href: "/notes/b/a.md",
|
||||
local: "/wiki/b/a.md",
|
||||
},
|
||||
{
|
||||
in: "/wiki/a.md",
|
||||
root: "/wiki",
|
||||
href: "/notes/a.md",
|
||||
local: "/wiki/a.md",
|
||||
},
|
||||
{
|
||||
in: "/b/a.md",
|
||||
root: "/",
|
||||
href: "/notes/b/a.md",
|
||||
local: "/b/a.md",
|
||||
},
|
||||
{
|
||||
in: "/a.md",
|
||||
root: "/",
|
||||
href: "/notes/a.md",
|
||||
local: "/a.md",
|
||||
},
|
||||
}
|
||||
|
||||
for i, c := range cases {
|
||||
config.Root = c.root
|
||||
p := NewPathFromLocal(c.in)
|
||||
if p.HREF != c.href {
|
||||
t.Fatal(i, "href", p.HREF, c.href, c, p)
|
||||
}
|
||||
if p.Local != c.local {
|
||||
t.Fatal(i, "local", p.Local, c.local, c, p)
|
||||
}
|
||||
}
|
||||
}
|
||||
12
filetree/paths.go
Executable file
12
filetree/paths.go
Executable file
@@ -0,0 +1,12 @@
|
||||
package filetree
|
||||
|
||||
type Paths []Path
|
||||
|
||||
func (p Paths) List() string {
|
||||
content := "<ul>\n"
|
||||
for _, path := range p {
|
||||
content += path.LI() + "\n"
|
||||
}
|
||||
content += "</ul>\n"
|
||||
return content
|
||||
}
|
||||
1
filetree/paths_test.go
Executable file
1
filetree/paths_test.go
Executable file
@@ -0,0 +1 @@
|
||||
package filetree
|
||||
Reference in New Issue
Block a user