Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2f78a9d80b | |||
| 75140f716d |
@@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"cmp"
|
||||||
"embed"
|
"embed"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@@ -16,6 +17,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
|
"unicode"
|
||||||
|
"unicode/utf8"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -114,6 +117,54 @@ func getEntryIcon(name string, isDir bool) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseNumber(s string) (num int, chars int) {
|
||||||
|
for chars < len(s) && s[chars] >= '0' && s[chars] <= '9' {
|
||||||
|
num = num*10 + int(s[chars]-'0')
|
||||||
|
chars++
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func naturalCompare(a, b string) int {
|
||||||
|
|
||||||
|
for len(a) > 0 && len(b) > 0 {
|
||||||
|
|
||||||
|
if unicode.IsDigit(rune(a[0])) && unicode.IsDigit(rune(b[0])) {
|
||||||
|
|
||||||
|
aValue, aSize := parseNumber(a)
|
||||||
|
bValue, bSize := parseNumber(b)
|
||||||
|
|
||||||
|
if aValue != bValue {
|
||||||
|
if aValue < bValue {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
a = a[aSize:]
|
||||||
|
b = b[bSize:]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
aRune, aSize := utf8.DecodeRuneInString(a)
|
||||||
|
bRune, bSize := utf8.DecodeRuneInString(b)
|
||||||
|
aRuneLower := unicode.ToLower(aRune)
|
||||||
|
bRuneLower := unicode.ToLower(bRune)
|
||||||
|
|
||||||
|
if aRuneLower != bRuneLower {
|
||||||
|
if aRuneLower < bRuneLower {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
a = a[aSize:]
|
||||||
|
b = b[bSize:]
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmp.Compare(len(a), len(b))
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
if serveAddress == "" {
|
if serveAddress == "" {
|
||||||
serveAddress = "127.0.0.1:8080"
|
serveAddress = "127.0.0.1:8080"
|
||||||
@@ -152,6 +203,13 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Append trailing slash to directories so rendered HTML has proper paths
|
||||||
|
if filestat.IsDir() && !strings.HasSuffix(r.URL.Path, "/") {
|
||||||
|
r.URL.Path += "/"
|
||||||
|
http.Redirect(w, r, r.URL.String(), http.StatusMovedPermanently)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Use Browser Cache (if possible)
|
// Use Browser Cache (if possible)
|
||||||
modtime := filestat.ModTime().UTC()
|
modtime := filestat.ModTime().UTC()
|
||||||
modhash := fmt.Sprint(modtime.Unix())
|
modhash := fmt.Sprint(modtime.Unix())
|
||||||
@@ -233,14 +291,14 @@ func main() {
|
|||||||
// Use
|
// Use
|
||||||
if sortOrder == "modified" {
|
if sortOrder == "modified" {
|
||||||
if a.ModTime.Equal(b.ModTime) {
|
if a.ModTime.Equal(b.ModTime) {
|
||||||
return strings.Compare(a.Name, b.Name)
|
return naturalCompare(a.Name, b.Name)
|
||||||
}
|
}
|
||||||
if a.ModTime.After(b.ModTime) {
|
if a.ModTime.After(b.ModTime) {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
return strings.Compare(a.Name, b.Name)
|
return naturalCompare(a.Name, b.Name)
|
||||||
})
|
})
|
||||||
|
|
||||||
// Directory Listing
|
// Directory Listing
|
||||||
|
|||||||
Reference in New Issue
Block a user