fix style and implement basic static file tree browsing
This commit is contained in:
parent
034d325ae3
commit
59954b94d8
11 changed files with 193 additions and 24 deletions
|
@ -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 {
|
||||||
|
|
|
@ -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
88
archetype/fileManager.go
Normal 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
|
||||||
|
}
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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")
|
||||||
|
|
20
nirvash.go
20
nirvash.go
|
@ -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
23
static/delete.svg
Normal 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
6
static/move.svg
Normal 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 |
|
@ -291,4 +291,9 @@ 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
34
templates/file_list.html
Normal 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" .}}
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in a new issue