This commit is contained in:
Deluan Quintão 2026-10-06 14:48:51 -07:00 • committed by GitHub
commit 6b2e9924f9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 32 additions and 5 deletions

View file

@ -90,6 +90,7 @@ const (
I18nFolder = "i18n"
ScanIgnoreFile = ".ndignore"
NoMediaFile = ".nomedia"
ArtworkFolder = "artwork"
// HashedArtworkFolder is a subtree of ArtworkFolder, kept apart from the name-addressed
// upload folders beside it so Prune's sweep never reaches them.

View file

@ -175,7 +175,7 @@ flowchart TD
1. **Folder Traversal**
- Uses `walkDirTree` to traverse the directory structure
- Handles symbolic links and hidden files
- Processes `.ndignore` files for exclusions
- Processes `.ndignore` files for exclusions, and skips folders containing a `.nomedia` file
- Maps files to appropriate types (audio, image, playlist)
2. **Metadata Extraction**

View file

@ -12,6 +12,8 @@ import (
ignore "github.com/sabhiram/go-gitignore"
)
const ignoreAllPattern = "**/*"
// IgnoreChecker manages .ndignore patterns using a stack-based approach.
// Use Push() to add patterns when entering a folder, Pop() when leaving,
// and ShouldIgnore() to check if a path should be ignored.
@ -102,8 +104,13 @@ func (ic *IgnoreChecker) ShouldIgnore(ctx context.Context, relPath string) bool
// loadPatternsFromFolder reads the .ndignore file in the specified folder and returns the patterns.
// If the file doesn't exist, returns an empty slice.
// If the file exists but is empty, returns a pattern to ignore everything ("**/*").
// If the file exists but is empty, or a .nomedia file exists, returns a pattern to ignore everything.
func (ic *IgnoreChecker) loadPatternsFromFolder(ctx context.Context, folder string) []string {
if _, err := fs.Stat(ic.fsys, path.Join(folder, consts.NoMediaFile)); err == nil {
log.Trace(ctx, "Scanner: .nomedia file found, ignoring everything", "path", folder)
return []string{ignoreAllPattern}
}
ignoreFilePath := path.Join(folder, consts.ScanIgnoreFile)
var patterns []string
@ -138,7 +145,7 @@ func (ic *IgnoreChecker) loadPatternsFromFolder(ctx context.Context, folder stri
// If the .ndignore file is empty, ignore everything
if len(patterns) == 0 {
log.Trace(ctx, "Scanner: .ndignore file is empty, ignoring everything", "path", folder)
patterns = []string{"**/*"}
patterns = []string{ignoreAllPattern}
}
return patterns

View file

@ -37,6 +37,20 @@ var _ = Describe("IgnoreChecker", func() {
})
})
DescribeTable("when .nomedia file exists",
func(files fstest.MapFS) {
ic = newIgnoreChecker(files)
patterns := ic.loadPatternsFromFolder(ctx, ".")
Expect(patterns).To(Equal([]string{"**/*"}))
},
Entry("empty", fstest.MapFS{".nomedia": &fstest.MapFile{}}),
Entry("with content", fstest.MapFS{".nomedia": &fstest.MapFile{Data: []byte("*.txt")}}),
Entry("alongside .ndignore", fstest.MapFS{
".nomedia": &fstest.MapFile{},
".ndignore": &fstest.MapFile{Data: []byte("*.txt")},
}),
)
DescribeTable("parsing .ndignore content",
func(content string, expectedPatterns []string) {
fsys := fstest.MapFS{

View file

@ -53,6 +53,9 @@ var _ = Describe("walk_dir_tree", func() {
"root/h/.hidden.mp3": {},
"root/i/.git/config": {},
"root/i/.streams/stream.mp3": {},
"root/j/.nomedia": {},
"root/j/f1.mp3": {},
"root/j/sub/f2.mp3": {},
},
}
job = &scanJob{
@ -100,6 +103,8 @@ var _ = Describe("walk_dir_tree", func() {
Expect(folders["root/c"].audioFiles).To(BeEmpty())
Expect(folders["root/c"].imageFiles).To(BeEmpty())
Expect(folders).ToNot(HaveKey("root/d"))
Expect(folders["root/j"].audioFiles).To(BeEmpty())
Expect(folders).ToNot(HaveKey("root/j/sub"))
// By default (Scanner.IgnoreDotFolders == true), dot-prefixed
// folders are skipped, dot-prefixed files are not indexed, and
@ -122,8 +127,8 @@ var _ = Describe("walk_dir_tree", func() {
Expect(folders["root/f"].audioFiles).ToNot(HaveKey("evil.mp3"))
}
},
Entry("with symlinks enabled", true, 11),
Entry("with symlinks disabled", false, 10),
Entry("with symlinks enabled", true, 12),
Entry("with symlinks disabled", false, 11),
)
DescribeTable("dot-prefixed folders with IgnoreDotFolders disabled",