2022-11-08 19:49:19 +08:00
|
|
|
package http
|
|
|
|
|
|
|
|
import (
|
2023-01-11 13:05:44 +08:00
|
|
|
"bytes"
|
2022-11-08 19:49:19 +08:00
|
|
|
"embed"
|
|
|
|
"html/template"
|
2023-01-11 13:05:44 +08:00
|
|
|
"log"
|
2022-11-08 19:49:19 +08:00
|
|
|
"os"
|
2023-10-17 02:46:19 +08:00
|
|
|
"strings"
|
2022-11-08 19:49:19 +08:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/spf13/pflag"
|
|
|
|
|
|
|
|
"github.com/rclone/rclone/fs/config/flags"
|
|
|
|
)
|
|
|
|
|
2023-01-11 13:05:44 +08:00
|
|
|
// TemplateHelp returns a string that describes how to use a custom template
|
|
|
|
func TemplateHelp(prefix string) string {
|
2024-04-05 19:27:33 +08:00
|
|
|
help := `#### Template
|
2022-11-08 19:49:19 +08:00
|
|
|
|
2023-01-11 13:05:44 +08:00
|
|
|
` + "`--{{ .Prefix }}template`" + ` allows a user to specify a custom markup template for HTTP
|
2022-11-08 19:49:19 +08:00
|
|
|
and WebDAV serve functions. The server exports the following markup
|
|
|
|
to be used within the template to server pages:
|
|
|
|
|
|
|
|
| Parameter | Description |
|
|
|
|
| :---------- | :---------- |
|
|
|
|
| .Name | The full path of a file/directory. |
|
|
|
|
| .Title | Directory listing of .Name |
|
|
|
|
| .Sort | The current sort used. This is changeable via ?sort= parameter |
|
|
|
|
| | Sort Options: namedirfirst,name,size,time (default namedirfirst) |
|
|
|
|
| .Order | The current ordering used. This is changeable via ?order= parameter |
|
|
|
|
| | Order Options: asc,desc (default asc) |
|
|
|
|
| .Query | Currently unused. |
|
|
|
|
| .Breadcrumb | Allows for creating a relative navigation |
|
|
|
|
|-- .Link | The relative to the root link of the Text. |
|
|
|
|
|-- .Text | The Name of the directory. |
|
|
|
|
| .Entries | Information about a specific file/directory. |
|
|
|
|
|-- .URL | The 'url' of an entry. |
|
|
|
|
|-- .Leaf | Currently same as 'URL' but intended to be 'just' the name. |
|
|
|
|
|-- .IsDir | Boolean for if an entry is a directory or not. |
|
|
|
|
|-- .Size | Size in Bytes of the entry. |
|
|
|
|
|-- .ModTime | The UTC timestamp of an entry. |
|
2023-10-17 02:46:19 +08:00
|
|
|
|
|
|
|
The server also makes the following functions available so that they can be used within the
|
|
|
|
template. These functions help extend the options for dynamic rendering of HTML. They can
|
|
|
|
be used to render HTML based on specific conditions.
|
|
|
|
|
|
|
|
| Function | Description |
|
|
|
|
| :---------- | :---------- |
|
|
|
|
| afterEpoch | Returns the time since the epoch for the given time. |
|
|
|
|
| contains | Checks whether a given substring is present or not in a given string. |
|
|
|
|
| hasPrefix | Checks whether the given string begins with the specified prefix. |
|
|
|
|
| hasSuffix | Checks whether the given string end with the specified suffix. |
|
2024-04-05 19:27:33 +08:00
|
|
|
|
2022-11-08 19:49:19 +08:00
|
|
|
`
|
|
|
|
|
2023-01-11 13:05:44 +08:00
|
|
|
tmpl, err := template.New("template help").Parse(help)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal("Fatal error parsing template", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
data := struct {
|
|
|
|
Prefix string
|
|
|
|
}{
|
|
|
|
Prefix: prefix,
|
|
|
|
}
|
|
|
|
buf := &bytes.Buffer{}
|
|
|
|
err = tmpl.Execute(buf, data)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal("Fatal error executing template", err)
|
|
|
|
}
|
|
|
|
return buf.String()
|
|
|
|
}
|
|
|
|
|
2022-11-08 19:49:19 +08:00
|
|
|
// TemplateConfig for the templating functionality
|
|
|
|
type TemplateConfig struct {
|
|
|
|
Path string
|
|
|
|
}
|
|
|
|
|
|
|
|
// AddFlagsPrefix for the templating functionality
|
|
|
|
func (cfg *TemplateConfig) AddFlagsPrefix(flagSet *pflag.FlagSet, prefix string) {
|
2023-07-11 01:34:10 +08:00
|
|
|
flags.StringVarP(flagSet, &cfg.Path, prefix+"template", "", cfg.Path, "User-specified template", prefix)
|
2022-11-08 19:49:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// AddTemplateFlagsPrefix for the templating functionality
|
|
|
|
func AddTemplateFlagsPrefix(flagSet *pflag.FlagSet, prefix string, cfg *TemplateConfig) {
|
|
|
|
cfg.AddFlagsPrefix(flagSet, prefix)
|
|
|
|
}
|
|
|
|
|
|
|
|
// DefaultTemplateCfg returns a new config which can be customized by command line flags
|
|
|
|
func DefaultTemplateCfg() TemplateConfig {
|
|
|
|
return TemplateConfig{}
|
|
|
|
}
|
|
|
|
|
|
|
|
// AfterEpoch returns the time since the epoch for the given time
|
|
|
|
func AfterEpoch(t time.Time) bool {
|
|
|
|
return t.After(time.Time{})
|
|
|
|
}
|
|
|
|
|
|
|
|
// Assets holds the embedded filesystem for the default template
|
|
|
|
//
|
|
|
|
//go:embed templates
|
|
|
|
var Assets embed.FS
|
|
|
|
|
|
|
|
// GetTemplate returns the HTML template for serving directories via HTTP/WebDAV
|
|
|
|
func GetTemplate(tmpl string) (*template.Template, error) {
|
|
|
|
var readFile = os.ReadFile
|
|
|
|
if tmpl == "" {
|
|
|
|
tmpl = "templates/index.html"
|
|
|
|
readFile = Assets.ReadFile
|
|
|
|
}
|
|
|
|
|
|
|
|
data, err := readFile(tmpl)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
funcMap := template.FuncMap{
|
|
|
|
"afterEpoch": AfterEpoch,
|
2023-10-17 02:46:19 +08:00
|
|
|
"contains": strings.Contains,
|
|
|
|
"hasPrefix": strings.HasPrefix,
|
|
|
|
"hasSuffix": strings.HasSuffix,
|
2022-11-08 19:49:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
tpl, err := template.New("index").Funcs(funcMap).Parse(string(data))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return tpl, nil
|
|
|
|
}
|