mirror of
https://tildegit.org/solderpunk/molly-brown.git
synced 2025-04-13 09:29:46 +00:00
Permit sorting of files in automatic directory listings by various factors.
This commit is contained in:
parent
6da5ec79dd
commit
3f98a9edf1
3 changed files with 45 additions and 15 deletions
|
@ -92,3 +92,5 @@ The following options can be set in `/etc/molly.conf`:
|
||||||
* `LogPath`: Path to log file (default value `molly.log`). Note that
|
* `LogPath`: Path to log file (default value `molly.log`). Note that
|
||||||
all intermediate directories must exist, Molly Brown won't create
|
all intermediate directories must exist, Molly Brown won't create
|
||||||
them for you.
|
them for you.
|
||||||
|
* `DirectorySort`: A string specifying how to sort files in automatically generated directory listings. Must be one of "Name", "Size" or "Time" (default value "Name").
|
||||||
|
* `DirectoryReverse`: Boolean, if true automatically generated directory listings will list files in descending order of whatever `DirectorySort` is set to (default value false).
|
||||||
|
|
38
config.go
38
config.go
|
@ -1,23 +1,26 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"github.com/BurntSushi/toml"
|
"github.com/BurntSushi/toml"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Port int
|
Port int
|
||||||
Hostname string
|
Hostname string
|
||||||
CertPath string
|
CertPath string
|
||||||
KeyPath string
|
KeyPath string
|
||||||
DocBase string
|
DocBase string
|
||||||
HomeDocBase string
|
HomeDocBase string
|
||||||
GeminiExt string
|
GeminiExt string
|
||||||
DefaultLang string
|
DefaultLang string
|
||||||
LogPath string
|
LogPath string
|
||||||
TempRedirects map[string]string
|
TempRedirects map[string]string
|
||||||
PermRedirects map[string]string
|
PermRedirects map[string]string
|
||||||
CGIPaths []string
|
CGIPaths []string
|
||||||
SCGIPaths map[string]string
|
SCGIPaths map[string]string
|
||||||
|
DirectorySort string
|
||||||
|
DirectoryReverse bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type MollyFile struct {
|
type MollyFile struct {
|
||||||
|
@ -43,6 +46,7 @@ func getConfig(filename string) (Config, error) {
|
||||||
config.PermRedirects = make(map[string]string)
|
config.PermRedirects = make(map[string]string)
|
||||||
config.CGIPaths = make([]string, 0)
|
config.CGIPaths = make([]string, 0)
|
||||||
config.SCGIPaths = make(map[string]string)
|
config.SCGIPaths = make(map[string]string)
|
||||||
|
config.DirectorySort = "Name"
|
||||||
|
|
||||||
// Return defaults if no filename given
|
// Return defaults if no filename given
|
||||||
if filename == "" {
|
if filename == "" {
|
||||||
|
@ -54,5 +58,13 @@ func getConfig(filename string) (Config, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return config, err
|
return config, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate pseudo-enums
|
||||||
|
switch config.DirectorySort {
|
||||||
|
case "Name", "Size", "Time":
|
||||||
|
default:
|
||||||
|
return config, errors.New("Invalid DirectorySort value.")
|
||||||
|
}
|
||||||
|
|
||||||
return config, nil
|
return config, nil
|
||||||
}
|
}
|
||||||
|
|
20
handler.go
20
handler.go
|
@ -14,6 +14,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -154,7 +155,7 @@ func handleGeminiRequest(conn net.Conn, config Config, logEntries chan LogEntry)
|
||||||
} else {
|
} else {
|
||||||
conn.Write([]byte("20 text/gemini\r\n"))
|
conn.Write([]byte("20 text/gemini\r\n"))
|
||||||
log.Status = 20
|
log.Status = 20
|
||||||
conn.Write([]byte(generateDirectoryListing(URL, path)))
|
conn.Write([]byte(generateDirectoryListing(URL, path, config)))
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -263,7 +264,7 @@ func parseMollyFiles(path string, info os.FileInfo, config *Config) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateDirectoryListing(URL *url.URL, path string) string {
|
func generateDirectoryListing(URL *url.URL, path string, config Config) string {
|
||||||
var listing string
|
var listing string
|
||||||
files, err := ioutil.ReadDir(path)
|
files, err := ioutil.ReadDir(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -287,6 +288,21 @@ func generateDirectoryListing(URL *url.URL, path string) string {
|
||||||
up := filepath.Dir(URL.Path)
|
up := filepath.Dir(URL.Path)
|
||||||
listing += fmt.Sprintf("=> %s %s\n", up, "..")
|
listing += fmt.Sprintf("=> %s %s\n", up, "..")
|
||||||
}
|
}
|
||||||
|
// Sort files
|
||||||
|
sort.SliceStable(files, func(i, j int) bool {
|
||||||
|
if config.DirectoryReverse {
|
||||||
|
i, j = j, i
|
||||||
|
}
|
||||||
|
if config.DirectorySort == "Name" {
|
||||||
|
return files[i].Name() < files[j].Name()
|
||||||
|
} else if config.DirectorySort == "Size" {
|
||||||
|
return files[i].Size() < files[j].Size()
|
||||||
|
} else if config.DirectorySort == "Time" {
|
||||||
|
return files[i].ModTime().Before(files[j].ModTime())
|
||||||
|
}
|
||||||
|
return false // Should not happen
|
||||||
|
})
|
||||||
|
// Format lines
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
// Skip dotfiles
|
// Skip dotfiles
|
||||||
if strings.HasPrefix(file.Name(), ".") {
|
if strings.HasPrefix(file.Name(), ".") {
|
||||||
|
|
Loading…
Add table
Reference in a new issue