Skip to content

Commit

Permalink
Make it possible to ignore files in the directory listing, ref #149
Browse files Browse the repository at this point in the history
  • Loading branch information
xyproto committed May 26, 2024
1 parent d7ebf0c commit 9aa48d3
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 8 deletions.
42 changes: 34 additions & 8 deletions engine/dirhandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"bytes"
"net/http"
"path/filepath"
"runtime"
"strings"

"github.com/go-gcfg/gcfg"
Expand All @@ -14,13 +15,22 @@ import (
"github.com/xyproto/algernon/utils"
)

const (
dotSlash = "." + utils.Pathsep /* ./ */
doubleP = utils.Pathsep + utils.Pathsep /* // */
)

// List of filenames that should be displayed instead of a directory listing
var indexFilenames = []string{"index.lua", "index.html", "index.md", "index.txt", "index.pongo2", "index.tmpl", "index.po2", "index.amber", "index.happ", "index.hyper", "index.hyper.js", "index.hyper.jsx", "index.tl", "index.prompt"}
var (
indexFilenames = []string{"index.lua", "index.html", "index.md", "index.txt", "index.pongo2", "index.tmpl", "index.po2", "index.amber", "index.happ", "index.hyper", "index.hyper.js", "index.hyper.jsx", "index.tl", "index.prompt"}

const (
dotSlash = "." + utils.Pathsep /* ./ */
doubleP = utils.Pathsep + utils.Pathsep /* // */
dirconfFilename = ".algernon"
// TODO: Use build tags instead of checking runtime.GOOS!
dirConfFilename, ignoreFilename = func() (string, string) {
if runtime.GOOS == "windows" {
return "algernon.txt", "ignore.txt"
}
return ".algernon", ".ignore"
}()
)

// DirConfig keeps a directory listing configuration
Expand All @@ -43,14 +53,31 @@ func (ac *Config) DirectoryListing(w http.ResponseWriter, req *http.Request, roo
// Remove a trailing slash after the root directory, if present
rootdir = strings.TrimSuffix(rootdir, "/")

// Read ignore patterns if ignore.txt is present
var ignorePatterns []string
ignoreFilePath := filepath.Join(dirname, ignoreFilename)
if ac.fs.Exists(ignoreFilePath) {
patterns, err := ReadIgnoreFile(ignoreFilePath)
if err != nil {
log.Warn("Could not read ignore.txt: ", err)
} else {
ignorePatterns = patterns
}
}

// Fill the coming HTML body with a list of all the filenames in `dirname`
for _, filename := range utils.GetFilenames(dirname) {

if filename == dirconfFilename {
if filename == dirConfFilename || filename == ignoreFilename {
// Skip
continue
}

// Check if the filename matches any of the ignore patterns
if ShouldIgnore(filename, ignorePatterns) {
continue
}

// Find the full name
fullFilename = dirname

Expand All @@ -70,8 +97,7 @@ func (ac *Config) DirectoryListing(w http.ResponseWriter, req *http.Request, roo
}

// Read directory configuration, if present
fullDirConfFilename := filepath.Join(dirname, dirconfFilename)
if ac.fs.Exists(fullDirConfFilename) {
if fullDirConfFilename := filepath.Join(dirname, dirConfFilename); ac.fs.Exists(fullDirConfFilename) {
var dirConf DirConfig
if err := gcfg.ReadFileInto(&dirConf, fullDirConfFilename); err == nil { // if no error
if dirConf.Main.Title != "" {
Expand Down
43 changes: 43 additions & 0 deletions engine/ignore.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package engine

import (
"bufio"
"fmt"
"os"
"path/filepath"
"strings"
)

// ReadIgnoreFile reads the ignore patterns from the ignore.txt file.
func ReadIgnoreFile(ignoreFilePath string) ([]string, error) {
var patterns []string
file, err := os.Open(ignoreFilePath)
if err != nil {
return nil, err
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
if line != "" && !strings.HasPrefix(line, "#") {
patterns = append(patterns, line)
}
}
return patterns, scanner.Err()
}

// ShouldIgnore checks if a given filename should be ignored based on the provided patterns.
// A warning will be printed if there are errors with an ignore pattern.
func ShouldIgnore(filename string, patterns []string) bool {
for _, pattern := range patterns {
matched, err := filepath.Match(pattern, filename)
if err != nil {
fmt.Fprintf(os.Stderr, "warning: %s contains an unmatchable pattern %s: %v\n", filename, pattern, err)
continue
}
if matched {
return true
}
}
return false
}

0 comments on commit 9aa48d3

Please sign in to comment.