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 {
|
||||
Adapter Adapter // adapter for this instance
|
||||
Root string // root of the site data
|
||||
StaticRoot string // root of static files for StaticFileManager
|
||||
AssetRoot string // root of Nirvash dist files (CSS, images)
|
||||
Plugins map[string]interface{}
|
||||
Adapter Adapter // adapter for this instance
|
||||
Root string // root of the site data
|
||||
StaticRoot string // root of static files for StaticFileManager
|
||||
StaticShowHidden bool // whether to show hidden files in the StaticFileManager
|
||||
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 {
|
||||
|
|
|
@ -25,7 +25,7 @@ func (self *EurekaAdapter) Init(cfg *Config) {
|
|||
|
||||
self.Root = cfg.Root
|
||||
self.Config = make(map[ConfigOption]string)
|
||||
// TODO: read config.h and build self.Config
|
||||
|
||||
err = self.readCfg()
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
|
||||
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 {
|
||||
handlerFunc := func(w http.ResponseWriter, req *http.Request) {
|
||||
pageTitle := req.FormValue("title")
|
||||
|
|
20
nirvash.go
20
nirvash.go
|
@ -27,11 +27,15 @@ func main() {
|
|||
|
||||
cfg.Adapter.Init(cfg)
|
||||
|
||||
fileManager := &core.SimpleFileManager{}
|
||||
fileManager.Init(cfg)
|
||||
|
||||
pathConcat := filepath.Join
|
||||
|
||||
rtr := &router.Router{
|
||||
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,
|
||||
"/"))
|
||||
|
||||
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)
|
||||
}
|
||||
|
|
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] {
|
||||
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>
|
||||
<ul>
|
||||
<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="/config">Configuration</a></li>
|
||||
<li><a href="/logout">Logout</a></li>
|
||||
|
|
Loading…
Reference in a new issue