Sorting now supports arbitrary numbering length, so long as it is sequential
This commit is contained in:
parent
abe3dbb54f
commit
c57bb9c4c2
|
@ -38,7 +38,7 @@ You can also provide a comma-delimited string of alphanumeric patterns to exclud
|
||||||
|
|
||||||
Filenames matching any of these patterns will not be served.
|
Filenames matching any of these patterns will not be served.
|
||||||
|
|
||||||
You can also combine these two parameters, with exclusions taking priority over inclusions.
|
You can combine these two parameters, with exclusions taking priority over inclusions.
|
||||||
|
|
||||||
Both filtering parameters ignore the file extension and full path; they only compare against the bare filename.
|
Both filtering parameters ignore the file extension and full path; they only compare against the bare filename.
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ Enjoy!
|
||||||
|
|
||||||
## Sorting
|
## Sorting
|
||||||
|
|
||||||
You can specify a sorting pattern via the `sort=` query parameter, assuming the `-s|--sort` flag is enabled.
|
You can specify a sorting direction via the `sort=` query parameter, assuming the `-s|--sort` flag is enabled.
|
||||||
|
|
||||||
A value of `sort=asc` means files will be served in ascending order (lowest-numbered to highest).
|
A value of `sort=asc` means files will be served in ascending order (lowest-numbered to highest).
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ For `sort=desc`, the highest-numbered file will be served instead.
|
||||||
|
|
||||||
If any other (or no) value is provided, the selected file will be random.
|
If any other (or no) value is provided, the selected file will be random.
|
||||||
|
|
||||||
Note: These patterns require sequentially-numbered files matching the following pattern: `filename###.extension`.
|
Note: These options require sequentially-numbered files matching the following pattern: `filename[0-9]*.extension`.
|
||||||
|
|
||||||
## Themes
|
## Themes
|
||||||
The `--code` handler provides syntax highlighting via [alecthomas/chroma](https://github.com/alecthomas/chroma).
|
The `--code` handler provides syntax highlighting via [alecthomas/chroma](https://github.com/alecthomas/chroma).
|
||||||
|
|
72
cmd/files.go
72
cmd/files.go
|
@ -42,16 +42,30 @@ type scanStatsChannels struct {
|
||||||
|
|
||||||
type splitPath struct {
|
type splitPath struct {
|
||||||
base string
|
base string
|
||||||
number int
|
number string
|
||||||
extension string
|
extension string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (splitPath *splitPath) increment() {
|
func (splitPath *splitPath) increment() {
|
||||||
splitPath.number = splitPath.number + 1
|
length := len(splitPath.number)
|
||||||
|
|
||||||
|
asInt, err := strconv.Atoi(splitPath.number)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
splitPath.number = fmt.Sprintf("%0*d", length, asInt+1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (splitPath *splitPath) decrement() {
|
func (splitPath *splitPath) decrement() {
|
||||||
splitPath.number = splitPath.number - 1
|
length := len(splitPath.number)
|
||||||
|
|
||||||
|
asInt, err := strconv.Atoi(splitPath.number)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
splitPath.number = fmt.Sprintf("%0*d", length, asInt-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func humanReadableSize(bytes int) string {
|
func humanReadableSize(bytes int) string {
|
||||||
|
@ -85,26 +99,22 @@ func kill(path string, cache *fileCache) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func split(path string, regexes *regexes) (*splitPath, error) {
|
func split(path string, regexes *regexes) (*splitPath, int, error) {
|
||||||
p := splitPath{}
|
p := splitPath{}
|
||||||
var err error
|
|
||||||
|
|
||||||
split := regexes.filename.FindAllStringSubmatch(path, -1)
|
split := regexes.filename.FindAllStringSubmatch(path, -1)
|
||||||
|
|
||||||
if len(split) < 1 || len(split[0]) < 3 {
|
if len(split) < 1 || len(split[0]) < 3 {
|
||||||
return &splitPath{}, nil
|
return &splitPath{}, 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
p.base = split[0][1]
|
p.base = split[0][1]
|
||||||
|
|
||||||
p.number, err = strconv.Atoi(split[0][2])
|
p.number = split[0][2]
|
||||||
if err != nil {
|
|
||||||
return &splitPath{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
p.extension = split[0][3]
|
p.extension = split[0][3]
|
||||||
|
|
||||||
return &p, nil
|
return &p, len(p.number), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFile(list []string, sortOrder string, regexes *regexes, formats *types.Types) (string, error) {
|
func newFile(list []string, sortOrder string, regexes *regexes, formats *types.Types) (string, error) {
|
||||||
|
@ -113,37 +123,39 @@ func newFile(list []string, sortOrder string, regexes *regexes, formats *types.T
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
splitPath, err := split(path, regexes)
|
if sortOrder == "asc" || sortOrder == "desc" {
|
||||||
if err != nil {
|
splitPath, length, err := split(path, regexes)
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
splitPath.number = 1
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case sortOrder == "asc":
|
|
||||||
path, err = tryExtensions(splitPath, formats)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
case sortOrder == "desc":
|
|
||||||
for {
|
switch {
|
||||||
splitPath.increment()
|
case sortOrder == "asc":
|
||||||
|
splitPath.number = fmt.Sprintf("%0*d", length, 1)
|
||||||
|
|
||||||
path, err = tryExtensions(splitPath, formats)
|
path, err = tryExtensions(splitPath, formats)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
case sortOrder == "desc":
|
||||||
if path == "" {
|
for {
|
||||||
splitPath.decrement()
|
splitPath.increment()
|
||||||
|
|
||||||
path, err = tryExtensions(splitPath, formats)
|
path, err = tryExtensions(splitPath, formats)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
break
|
if path == "" {
|
||||||
|
splitPath.decrement()
|
||||||
|
|
||||||
|
path, err = tryExtensions(splitPath, formats)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,7 +164,7 @@ func newFile(list []string, sortOrder string, regexes *regexes, formats *types.T
|
||||||
}
|
}
|
||||||
|
|
||||||
func nextFile(filePath, sortOrder string, regexes *regexes, formats *types.Types) (string, error) {
|
func nextFile(filePath, sortOrder string, regexes *regexes, formats *types.Types) (string, error) {
|
||||||
splitPath, err := split(filePath, regexes)
|
splitPath, _, err := split(filePath, regexes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -178,7 +190,7 @@ func tryExtensions(splitPath *splitPath, formats *types.Types) (string, error) {
|
||||||
var path string
|
var path string
|
||||||
|
|
||||||
for extension := range formats.Extensions {
|
for extension := range formats.Extensions {
|
||||||
path = fmt.Sprintf("%s%.3d%s", splitPath.base, splitPath.number, extension)
|
path = fmt.Sprintf("%s%s%s", splitPath.base, splitPath.number, extension)
|
||||||
|
|
||||||
exists, err := fileExists(path)
|
exists, err := fileExists(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ReleaseVersion string = "0.96.5"
|
ReleaseVersion string = "0.97.0"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -460,7 +460,7 @@ func ServePage(args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
regexes := ®exes{
|
regexes := ®exes{
|
||||||
filename: regexp.MustCompile(`(.+)([0-9]{3})(\..+)`),
|
filename: regexp.MustCompile(`(.+?)([0-9]*)(\..+)`),
|
||||||
alphanumeric: regexp.MustCompile(`^[A-z0-9]*$`),
|
alphanumeric: regexp.MustCompile(`^[A-z0-9]*$`),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue