You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

86 lines
2.9 KiB

  1. package filer
  2. import (
  3. "context"
  4. "github.com/chrislusf/seaweedfs/weed/util"
  5. "path/filepath"
  6. "strings"
  7. )
  8. func splitPattern(pattern string) (prefix string, restPattern string) {
  9. position := strings.Index(pattern, "*")
  10. if position >= 0 {
  11. return pattern[:position], pattern[position:]
  12. }
  13. position = strings.Index(pattern, "?")
  14. if position >= 0 {
  15. return pattern[:position], pattern[position:]
  16. }
  17. return "", restPattern
  18. }
  19. func (f *Filer) ListDirectoryEntries(ctx context.Context, p util.FullPath, startFileName string, inclusive bool, limit int, namePattern string) (entries []*Entry, err error) {
  20. if strings.HasSuffix(string(p), "/") && len(p) > 1 {
  21. p = p[0 : len(p)-1]
  22. }
  23. prefix, restNamePattern := splitPattern(namePattern)
  24. var missedCount int
  25. var lastFileName string
  26. entries, missedCount, lastFileName, err = f.doListPatternMatchedEntries(ctx, p, startFileName, inclusive, limit, prefix, restNamePattern)
  27. for missedCount > 0 && err == nil {
  28. var makeupEntries []*Entry
  29. makeupEntries, missedCount, lastFileName, err = f.doListPatternMatchedEntries(ctx, p, lastFileName, false, missedCount, prefix, restNamePattern)
  30. for _, entry := range makeupEntries {
  31. entries = append(entries, entry)
  32. }
  33. }
  34. //Distinguish between folders and common files, folders are listed first
  35. var folderEntries, commonEntries []*Entry
  36. for i, _ := range entries {
  37. if entries[i].IsDirectory() {
  38. folderEntries = append(folderEntries, entries[i])
  39. } else {
  40. commonEntries = append(commonEntries, entries[i])
  41. }
  42. }
  43. folderEntries = append(folderEntries, commonEntries...)
  44. return folderEntries, err
  45. }
  46. func (f *Filer) doListPatternMatchedEntries(ctx context.Context, p util.FullPath, startFileName string, inclusive bool, limit int, prefix, restNamePattern string) (matchedEntries []*Entry, missedCount int, lastFileName string, err error) {
  47. var foundEntries []*Entry
  48. foundEntries, lastFileName, err = f.doListValidEntries(ctx, p, startFileName, inclusive, limit, prefix)
  49. if err != nil {
  50. return
  51. }
  52. if len(restNamePattern) == 0 {
  53. return foundEntries, 0, lastFileName, nil
  54. }
  55. for _, entry := range foundEntries {
  56. nameToTest := strings.ToLower(entry.Name())
  57. if matched, matchErr := filepath.Match(restNamePattern, nameToTest[len(prefix):]); matchErr == nil && matched {
  58. matchedEntries = append(matchedEntries, entry)
  59. } else {
  60. missedCount++
  61. }
  62. }
  63. return
  64. }
  65. func (f *Filer) doListValidEntries(ctx context.Context, p util.FullPath, startFileName string, inclusive bool, limit int, prefix string) (entries []*Entry, lastFileName string, err error) {
  66. var makeupEntries []*Entry
  67. var expiredCount int
  68. entries, expiredCount, lastFileName, err = f.doListDirectoryEntries(ctx, p, startFileName, inclusive, limit, prefix)
  69. for expiredCount > 0 && err == nil {
  70. makeupEntries, expiredCount, lastFileName, err = f.doListDirectoryEntries(ctx, p, lastFileName, false, expiredCount, prefix)
  71. if err == nil {
  72. entries = append(entries, makeupEntries...)
  73. }
  74. }
  75. return
  76. }