196 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			196 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Go
		
	
	
	
package filemanager
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"encoding/json"
 | 
						|
	"html/template"
 | 
						|
	"net/http"
 | 
						|
	"strconv"
 | 
						|
	"strings"
 | 
						|
)
 | 
						|
 | 
						|
// functions contains the non-standard functions that are available
 | 
						|
// to use on the HTML templates.
 | 
						|
var functions = template.FuncMap{
 | 
						|
	"CSS": func(s string) template.CSS {
 | 
						|
		return template.CSS(s)
 | 
						|
	},
 | 
						|
	"Marshal": func(v interface{}) template.JS {
 | 
						|
		a, _ := json.Marshal(v)
 | 
						|
		return template.JS(a)
 | 
						|
	},
 | 
						|
}
 | 
						|
 | 
						|
// page contains the information needed to fill a page template.
 | 
						|
type page struct {
 | 
						|
	User      *User  `json:"-"`
 | 
						|
	BaseURL   string `json:"-"`
 | 
						|
	WebDavURL string `json:"-"`
 | 
						|
	Kind      string `json:"kind"`
 | 
						|
	Data      *file  `json:"data"`
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
// breadcrumbItem contains the Name and the URL of a breadcrumb piece.
 | 
						|
type breadcrumbItem struct {
 | 
						|
	Name string
 | 
						|
	URL  string
 | 
						|
}
 | 
						|
 | 
						|
// BreadcrumbMap returns p.Path where every element is a map
 | 
						|
// of URLs and path segment names.
 | 
						|
func (p page) BreadcrumbMap() []breadcrumbItem {
 | 
						|
	// TODO: when it is preview alongside with listing!!!!!!!!!!
 | 
						|
	result := []breadcrumbItem{}
 | 
						|
 | 
						|
	if len(p.Path) == 0 {
 | 
						|
		return result
 | 
						|
	}
 | 
						|
 | 
						|
	// skip trailing slash
 | 
						|
	lpath := p.Path
 | 
						|
	if lpath[len(lpath)-1] == '/' {
 | 
						|
		lpath = lpath[:len(lpath)-1]
 | 
						|
	}
 | 
						|
 | 
						|
	parts := strings.Split(lpath, "/")
 | 
						|
	for i, part := range parts {
 | 
						|
		if i == len(parts)-1 {
 | 
						|
			continue
 | 
						|
		}
 | 
						|
 | 
						|
		if i == 0 && part == "" {
 | 
						|
			result = append([]breadcrumbItem{{
 | 
						|
				Name: "/",
 | 
						|
				URL:  "/",
 | 
						|
			}}, result...)
 | 
						|
			continue
 | 
						|
		}
 | 
						|
 | 
						|
		result = append([]breadcrumbItem{{
 | 
						|
			Name: part,
 | 
						|
			URL:  strings.Join(parts[:i+1], "/") + "/",
 | 
						|
		}}, result...)
 | 
						|
	}
 | 
						|
 | 
						|
	return result
 | 
						|
}
 | 
						|
 | 
						|
// PreviousLink returns the URL of the previous folder.
 | 
						|
func (p page) PreviousLink() string {
 | 
						|
	path := strings.TrimSuffix(p.Path, "/")
 | 
						|
	path = strings.TrimPrefix(path, "/")
 | 
						|
	path = p.BaseURL + "/" + path
 | 
						|
	path = path[0 : len(path)-len(p.Name)]
 | 
						|
 | 
						|
	if len(path) < len(p.BaseURL+"/") {
 | 
						|
		return ""
 | 
						|
	}
 | 
						|
 | 
						|
	return path
 | 
						|
} */
 | 
						|
 | 
						|
func (p page) Render(c *requestContext, w http.ResponseWriter, r *http.Request) (int, error) {
 | 
						|
	if strings.Contains(r.Header.Get("Accept"), "application/json") {
 | 
						|
		marsh, err := json.MarshalIndent(p, "", "    ")
 | 
						|
		if err != nil {
 | 
						|
			return http.StatusInternalServerError, err
 | 
						|
		}
 | 
						|
 | 
						|
		w.Header().Set("Content-Type", "application/json; charset=utf-8")
 | 
						|
		if _, err := w.Write(marsh); err != nil {
 | 
						|
			return http.StatusInternalServerError, err
 | 
						|
		}
 | 
						|
 | 
						|
		return 0, nil
 | 
						|
	}
 | 
						|
 | 
						|
	var tpl *template.Template
 | 
						|
 | 
						|
	// Get the template from the assets
 | 
						|
	file, err := c.fm.templates.String("index.html")
 | 
						|
 | 
						|
	// Check if there is some error. If so, the template doesn't exist
 | 
						|
	if err != nil {
 | 
						|
		return http.StatusInternalServerError, err
 | 
						|
	}
 | 
						|
 | 
						|
	tpl, err = template.New("index").Funcs(functions).Parse(file)
 | 
						|
	if err != nil {
 | 
						|
		return http.StatusInternalServerError, err
 | 
						|
	}
 | 
						|
 | 
						|
	buf := &bytes.Buffer{}
 | 
						|
	err = tpl.Execute(buf, p)
 | 
						|
	if err != nil {
 | 
						|
		return http.StatusInternalServerError, err
 | 
						|
	}
 | 
						|
 | 
						|
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
 | 
						|
	_, err = buf.WriteTo(w)
 | 
						|
 | 
						|
	if err != nil {
 | 
						|
		return http.StatusInternalServerError, err
 | 
						|
	}
 | 
						|
 | 
						|
	return 0, nil
 | 
						|
}
 | 
						|
 | 
						|
// htmlError prints the error page
 | 
						|
func htmlError(w http.ResponseWriter, code int, err error) (int, error) {
 | 
						|
	tpl := errTemplate
 | 
						|
	tpl = strings.Replace(tpl, "TITLE", strconv.Itoa(code)+" "+http.StatusText(code), -1)
 | 
						|
	tpl = strings.Replace(tpl, "CODE", err.Error(), -1)
 | 
						|
 | 
						|
	_, err = w.Write([]byte(tpl))
 | 
						|
 | 
						|
	if err != nil {
 | 
						|
		return http.StatusInternalServerError, err
 | 
						|
	}
 | 
						|
	return 0, nil
 | 
						|
}
 | 
						|
 | 
						|
const errTemplate = `<!DOCTYPE html>
 | 
						|
<html>
 | 
						|
<head>
 | 
						|
    <title>TITLE</title>
 | 
						|
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
						|
    <meta charset="utf-8">
 | 
						|
    <style>
 | 
						|
    html {
 | 
						|
        background-color: #2196f3;
 | 
						|
        color: #fff;
 | 
						|
        font-family: sans-serif;
 | 
						|
    }
 | 
						|
    code {
 | 
						|
        background-color: rgba(0,0,0,0.1);
 | 
						|
        border-radius: 5px;
 | 
						|
        padding: 1em;
 | 
						|
        display: block;
 | 
						|
        box-sizing: border-box;
 | 
						|
    }
 | 
						|
    .center {
 | 
						|
        max-width: 40em;
 | 
						|
        margin: 2em auto 0;
 | 
						|
    }
 | 
						|
    a {
 | 
						|
        text-decoration: none;
 | 
						|
        color: #eee;
 | 
						|
        font-weight: bold;
 | 
						|
    }
 | 
						|
	p {
 | 
						|
		line-height: 1.3;
 | 
						|
	}
 | 
						|
    </style>
 | 
						|
</head>
 | 
						|
 | 
						|
<body>
 | 
						|
    <div class="center">
 | 
						|
        <h1>TITLE</h1>
 | 
						|
 | 
						|
        <p>Try reloading the page or hitting the back button. If this error persists, it seems that you may have found a bug! Please create an issue at <a href="https://github.com/hacdias/caddy-filemanager/issues">hacdias/caddy-filemanager</a> repository on GitHub with the code below.</p>
 | 
						|
 | 
						|
        <code>CODE</code>
 | 
						|
    </div>
 | 
						|
</html>`
 |