fix style and implement basic static file tree browsing

This commit is contained in:
Iris Lightshard 2022-06-10 00:38:29 -06:00
parent 034d325ae3
commit 59954b94d8
Signed by: nilix
GPG key ID: 3B7FBC22144E6398
11 changed files with 193 additions and 24 deletions

View file

@ -9,11 +9,13 @@ import (
) )
type Config struct { type Config struct {
Adapter Adapter // adapter for this instance Adapter Adapter // adapter for this instance
Root string // root of the site data Root string // root of the site data
StaticRoot string // root of static files for StaticFileManager StaticRoot string // root of static files for StaticFileManager
AssetRoot string // root of Nirvash dist files (CSS, images) StaticShowHidden bool // whether to show hidden files in the StaticFileManager
Plugins map[string]interface{} StaticShowHtml bool // whether to show html files in the StaticFileManager
AssetRoot string // root of Nirvash dist files (CSS, images)
Plugins map[string]interface{}
} }
func GetConfigLocation() string { func GetConfigLocation() string {

View file

@ -25,7 +25,7 @@ func (self *EurekaAdapter) Init(cfg *Config) {
self.Root = cfg.Root self.Root = cfg.Root
self.Config = make(map[ConfigOption]string) self.Config = make(map[ConfigOption]string)
// TODO: read config.h and build self.Config
err = self.readCfg() err = self.readCfg()
if err != nil { if err != nil {
panic("config.h is malformed!") panic("config.h is malformed!")

88
archetype/fileManager.go Normal file
View file

@ -0,0 +1,88 @@
package archetype
import (
"io/ioutil"
"path/filepath"
"strings"
)
type SimpleFileManager struct {
Root string
ShowHtml bool
ShowHidden bool
}
type FileListing struct {
Error string
Root string
Up string
SubDirs []string
Files []string
}
type FileManager interface {
Init(cfg *Config) error
// ListTree() FileListing
ListSubTree(root string) FileListing
// AddFile(path string, file multipart.FileHeader) error
// MkDir(path string) error
// Remove(path string) error
// Rename(old, new string) error
}
func (self *SimpleFileManager) Init(cfg *Config) error {
self.Root = cfg.StaticRoot
self.ShowHtml = cfg.StaticShowHtml
self.ShowHidden = cfg.StaticShowHidden
return nil
}
func (self *SimpleFileManager) ListSubTree(root string) FileListing {
list := FileListing{}
if strings.Contains(root, "../") || strings.Contains(root, "..\\") {
list.Error = "You cannot escape!"
return list
}
fullPath := filepath.Join(self.Root, root)
files, err := ioutil.ReadDir(fullPath)
if err != nil {
list.Error = err.Error()
return list
}
list.Root = root
if !strings.HasSuffix(list.Root, "/") {
list.Root += "/"
}
if !strings.HasPrefix(list.Root, "/") {
list.Root = "/" + list.Root
}
levels := strings.Split(root, "/")
if list.Root != "/" {
list.Up = "/"
}
if len(levels) >= 2 {
list.Up = "/" + strings.Join(levels[:len(levels)-1], "/")
}
for _, file := range files {
if !self.ShowHidden && strings.HasPrefix(file.Name(), ".") {
continue
}
if file.IsDir() {
list.SubDirs = append(list.SubDirs, file.Name())
} else {
if !self.ShowHtml && strings.HasSuffix(file.Name(), ".html") {
continue
}
list.Files = append(list.Files, file.Name())
}
}
return list
}

View file

@ -1,16 +0,0 @@
package archetype
type StaticFileManager struct {
Root string
ShowHtml bool
ShowHidden bool
}
type FileManager interface {
Init(cfg Config) error
ListTree() []string
ListSubTree(root string) []string
AddFile(path string, file interface{}) error
MkDir(path string) error
Remove(path string) error
}

View file

@ -16,6 +16,15 @@ func WithAdapter(next http.Handler, adapter core.Adapter) http.Handler {
return http.HandlerFunc(handlerFunc) return http.HandlerFunc(handlerFunc)
} }
func WithFileManager(next http.Handler, fileManager core.FileManager) http.Handler {
handlerFunc := func(w http.ResponseWriter, req *http.Request) {
*req = *req.WithContext(context.WithValue(req.Context(), "file-manager", fileManager))
next.ServeHTTP(w, req)
}
return http.HandlerFunc(handlerFunc)
}
func EnsurePageData(next http.Handler, adapter core.Adapter) http.Handler { func EnsurePageData(next http.Handler, adapter core.Adapter) http.Handler {
handlerFunc := func(w http.ResponseWriter, req *http.Request) { handlerFunc := func(w http.ResponseWriter, req *http.Request) {
pageTitle := req.FormValue("title") pageTitle := req.FormValue("title")

View file

@ -27,11 +27,15 @@ func main() {
cfg.Adapter.Init(cfg) cfg.Adapter.Init(cfg)
fileManager := &core.SimpleFileManager{}
fileManager.Init(cfg)
pathConcat := filepath.Join pathConcat := filepath.Join
rtr := &router.Router{ rtr := &router.Router{
StaticPaths: map[string]string{ StaticPaths: map[string]string{
"/static": filepath.Join(cfg.AssetRoot, "static"), "/static/": filepath.Join(cfg.AssetRoot, "static"),
"/files/": cfg.StaticRoot,
}, },
} }
@ -201,5 +205,19 @@ func main() {
udb, udb,
"/")) "/"))
rtr.Get(
`/static-mgr/(?P<Slug>.*)`,
Fortify(
Protected(
WithFileManager(
renderer.Template(
pathConcat(templateRoot, "file_list.html"),
pathConcat(templateRoot, "header.html"),
pathConcat(templateRoot, "footer.html")),
fileManager),
http.MethodGet,
udb,
"/login")))
http.ListenAndServe(":8080", rtr) http.ListenAndServe(":8080", rtr)
} }

23
static/delete.svg Normal file
View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.0"
width="100"
height="100"
id="svg8978">
<defs
id="defs8980" />
<g
id="layer1">
<path
d="M 6.3895625,6.4195626 C 93.580437,93.610437 93.580437,93.610437 93.580437,93.610437"
style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:18.05195999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path8986" />
<path
d="M 6.3894001,93.6106 C 93.830213,6.4194003 93.830213,6.4194003 93.830213,6.4194003"
style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:17.80202103;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path8988" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 954 B

6
static/move.svg Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500">
<path stroke="#000" stroke-width="55" fill="none"
stroke-linecap="round" stroke-linejoin="round"
d="m249,30a220,220 0 1,0 2,0zm-10,75 140,145-140,145M110,250H350"/>
</svg>

After

Width:  |  Height:  |  Size: 276 B

View file

@ -292,3 +292,8 @@ form input[hidden] {
form input[readonly] { form input[readonly] {
border: none; border: none;
} }
.edit-error {
display: block;
border-bottom: solid 2px crimson;
}

34
templates/file_list.html Normal file
View file

@ -0,0 +1,34 @@
{{ $slug := ((.Context).Value "params").Slug }}
{{ $fileList := ((.Context).Value "file-manager").ListSubTree $slug }}
{{ template "header" .}}
{{ if ($fileList).Error }}
<h2>File Listing Error</h2>
<span class="adapter-error">{{($fileList).Error}}</span>
{{ else }}
<h2>Files: {{($fileList).Root}}</h2>
<div class="new-page-button-wrapper">
<a class="new-page-button" href="/upload{{($fileList).Root}}">Upload File</a>
</div>
<div class="page-list">
<ul>
{{ if ($fileList).Up }}
<li><a href="/static-mgr{{$fileList.Up}}">..</a></li>
{{ end }}
{{ range $dir := ($fileList).SubDirs }}
<li><a href="/static-mgr{{($fileList).Root}}{{$dir}}">{{$dir}}/</a></li>
{{ end }}
{{ range $file := ($fileList).Files }}
<li><a href="/files{{($fileList).Root}}{{$file}}">{{$file}}</a></li>
{{ end }}
</ul>
</div>
{{ end }}
{{ template "footer" .}}

View file

@ -13,7 +13,7 @@
<nav> <nav>
<ul> <ul>
<li><a href="/">Pages</a></li> <li><a href="/">Pages</a></li>
<li><a href="/static-mgr">Static Files</a></li> <li><a href="/static-mgr/">Static Files</a></li>
<li><a href="/build">Build</a></li> <li><a href="/build">Build</a></li>
<li><a href="/config">Configuration</a></li> <li><a href="/config">Configuration</a></li>
<li><a href="/logout">Logout</a></li> <li><a href="/logout">Logout</a></li>