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
|
||||
all intermediate directories must exist, Molly Brown won't create
|
||||
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
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/BurntSushi/toml"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Port int
|
||||
Hostname string
|
||||
CertPath string
|
||||
KeyPath string
|
||||
DocBase string
|
||||
HomeDocBase string
|
||||
GeminiExt string
|
||||
DefaultLang string
|
||||
LogPath string
|
||||
TempRedirects map[string]string
|
||||
PermRedirects map[string]string
|
||||
CGIPaths []string
|
||||
SCGIPaths map[string]string
|
||||
Port int
|
||||
Hostname string
|
||||
CertPath string
|
||||
KeyPath string
|
||||
DocBase string
|
||||
HomeDocBase string
|
||||
GeminiExt string
|
||||
DefaultLang string
|
||||
LogPath string
|
||||
TempRedirects map[string]string
|
||||
PermRedirects map[string]string
|
||||
CGIPaths []string
|
||||
SCGIPaths map[string]string
|
||||
DirectorySort string
|
||||
DirectoryReverse bool
|
||||
}
|
||||
|
||||
type MollyFile struct {
|
||||
|
@ -43,6 +46,7 @@ func getConfig(filename string) (Config, error) {
|
|||
config.PermRedirects = make(map[string]string)
|
||||
config.CGIPaths = make([]string, 0)
|
||||
config.SCGIPaths = make(map[string]string)
|
||||
config.DirectorySort = "Name"
|
||||
|
||||
// Return defaults if no filename given
|
||||
if filename == "" {
|
||||
|
@ -54,5 +58,13 @@ func getConfig(filename string) (Config, error) {
|
|||
if err != nil {
|
||||
return config, err
|
||||
}
|
||||
|
||||
// Validate pseudo-enums
|
||||
switch config.DirectorySort {
|
||||
case "Name", "Size", "Time":
|
||||
default:
|
||||
return config, errors.New("Invalid DirectorySort value.")
|
||||
}
|
||||
|
||||
return config, nil
|
||||
}
|
||||
|
|
20
handler.go
20
handler.go
|
@ -14,6 +14,7 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
@ -154,7 +155,7 @@ func handleGeminiRequest(conn net.Conn, config Config, logEntries chan LogEntry)
|
|||
} else {
|
||||
conn.Write([]byte("20 text/gemini\r\n"))
|
||||
log.Status = 20
|
||||
conn.Write([]byte(generateDirectoryListing(URL, path)))
|
||||
conn.Write([]byte(generateDirectoryListing(URL, path, config)))
|
||||
}
|
||||
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
|
||||
files, err := ioutil.ReadDir(path)
|
||||
if err != nil {
|
||||
|
@ -287,6 +288,21 @@ func generateDirectoryListing(URL *url.URL, path string) string {
|
|||
up := filepath.Dir(URL.Path)
|
||||
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 {
|
||||
// Skip dotfiles
|
||||
if strings.HasPrefix(file.Name(), ".") {
|
||||
|
|
Loading…
Add table
Reference in a new issue