Add collation to directory listings (#1823)

* Add collation to directory listings. Closes #1806

Introduce a new `locale` arg to the `Query.directory` field. Set "en"
as the default for the field for backward compatibility. Use the given
locale, sending it through a language matcher, and use `x/text` as the
collation engine for the matched language.

Augment the file `ListDirs` call to optionally take a Collator. If the
Collator is given, sort file listings according to the collators rules.

While here, document the GraphQL schema a bit more.

Add matchers by looking at the current front-end locales, and make sure
each of these occur in the matcher list.

* Language matcher touchups

* Avoid having `en-US` twice.
* Introduce `en-AU`.

* Pass IgnoreCase and Numeric collation

Allow the collator to be configured with options. Pass the options
IgnoreCase and Numeric to the collator.
This commit is contained in:
SmallCoccinelle
2021-10-14 06:16:45 +02:00
committed by GitHub
parent 4eeef22c15
commit 41a1fb8aec
20 changed files with 76116 additions and 9 deletions

View File

@@ -4,6 +4,7 @@ import (
"archive/zip"
"fmt"
"io"
"io/fs"
"net/http"
"os"
"os/user"
@@ -14,6 +15,7 @@ import (
"github.com/h2non/filetype"
"github.com/h2non/filetype/types"
"github.com/stashapp/stash/pkg/logger"
"golang.org/x/text/collate"
)
// FileType uses the filetype package to determine the given file path's type
@@ -104,8 +106,22 @@ func EmptyDir(path string) error {
return nil
}
type dirSorter []fs.DirEntry
func (s dirSorter) Len() int {
return len(s)
}
func (s dirSorter) Swap(i, j int) {
s[j], s[i] = s[i], s[j]
}
func (s dirSorter) Bytes(i int) []byte {
return []byte(s[i].Name())
}
// ListDir will return the contents of a given directory path as a string slice
func ListDir(path string) ([]string, error) {
func ListDir(col *collate.Collator, path string) ([]string, error) {
var dirPaths []string
files, err := os.ReadDir(path)
if err != nil {
@@ -115,6 +131,11 @@ func ListDir(path string) ([]string, error) {
return dirPaths, err
}
}
if col != nil {
col.Sort(dirSorter(files))
}
for _, file := range files {
if !file.IsDir() {
continue