From 3e742e99a5951bb75c77f65f6f095affcb705982 Mon Sep 17 00:00:00 2001
From: Anthony Lavado <anthony@lavado.ca>
Date: Sun, 26 Jul 2020 15:34:15 -0700
Subject: [PATCH] Merge pull request #3704 from oddstr13/pr-dotdir-sample-1

Don't ignore dot directories or movies/episodes with sample in their name.

(cherry picked from commit 6eb3e736c61d787fd3d6b98001916f0d9afe9719)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
---
 .../Library/IgnorePatterns.cs                 | 23 ++++++++++++++++---
 .../Library/IgnorePatternsTests.cs            | 14 ++++++++++-
 2 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/Emby.Server.Implementations/Library/IgnorePatterns.cs b/Emby.Server.Implementations/Library/IgnorePatterns.cs
index 6e6ef1359a..e30a675931 100644
--- a/Emby.Server.Implementations/Library/IgnorePatterns.cs
+++ b/Emby.Server.Implementations/Library/IgnorePatterns.cs
@@ -18,7 +18,21 @@ namespace Emby.Server.Implementations.Library
         {
             "**/small.jpg",
             "**/albumart.jpg",
-            "**/*sample*",
+
+            // We have neither non-greedy matching or character group repetitions, working around that here.
+            // https://github.com/dazinator/DotNet.Glob#patterns
+            // .*/sample\..{1,5}
+            "**/sample.?",
+            "**/sample.??",
+            "**/sample.???", // Matches sample.mkv
+            "**/sample.????", // Matches sample.webm
+            "**/sample.?????",
+            "**/*.sample.?",
+            "**/*.sample.??",
+            "**/*.sample.???",
+            "**/*.sample.????",
+            "**/*.sample.?????",
+            "**/sample/*",
 
             // Directories
             "**/metadata/**",
@@ -64,10 +78,13 @@ namespace Emby.Server.Implementations.Library
             "**/.grab/**",
             "**/.grab",
 
-            // Unix hidden files and directories
-            "**/.*/**",
+            // Unix hidden files
             "**/.*",
 
+            // Mac - if you ever remove the above.
+            // "**/._*",
+            // "**/.DS_Store",
+
             // thumbs.db
             "**/thumbs.db",
 
diff --git a/tests/Jellyfin.Server.Implementations.Tests/Library/IgnorePatternsTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Library/IgnorePatternsTests.cs
index c145ddc9d7..b4e6db8f30 100644
--- a/tests/Jellyfin.Server.Implementations.Tests/Library/IgnorePatternsTests.cs
+++ b/tests/Jellyfin.Server.Implementations.Tests/Library/IgnorePatternsTests.cs
@@ -9,17 +9,29 @@ namespace Jellyfin.Server.Implementations.Tests.Library
         [InlineData("/media/small.jpg", true)]
         [InlineData("/media/albumart.jpg", true)]
         [InlineData("/media/movie.sample.mp4", true)]
+        [InlineData("/media/movie/sample.mp4", true)]
+        [InlineData("/media/movie/sample/movie.mp4", true)]
+        [InlineData("/foo/sample/bar/baz.mkv", false)]
+        [InlineData("/media/movies/the sample/the sample.mkv", false)]
+        [InlineData("/media/movies/sampler.mkv", false)]
         [InlineData("/media/movies/#Recycle/test.txt", true)]
         [InlineData("/media/movies/#recycle/", true)]
         [InlineData("/media/movies/#recycle", true)]
         [InlineData("thumbs.db", true)]
         [InlineData(@"C:\media\movies\movie.avi", false)]
-        [InlineData("/media/.hiddendir/file.mp4", true)]
+        [InlineData("/media/.hiddendir/file.mp4", false)]
         [InlineData("/media/dir/.hiddenfile.mp4", true)]
+        [InlineData("/media/dir/._macjunk.mp4", true)]
         [InlineData("/volume1/video/Series/@eaDir", true)]
         [InlineData("/volume1/video/Series/@eaDir/file.txt", true)]
         [InlineData("/directory/@Recycle", true)]
         [InlineData("/directory/@Recycle/file.mp3", true)]
+        [InlineData("/media/movies/.@__thumb", true)]
+        [InlineData("/media/movies/.@__thumb/foo-bar-thumbnail.png", true)]
+        [InlineData("/media/music/Foo B.A.R./epic.flac", false)]
+        [InlineData("/media/music/Foo B.A.R", false)]
+        // This test is pending an upstream fix: https://github.com/dazinator/DotNet.Glob/issues/78
+        // [InlineData("/media/music/Foo B.A.R.", false)]
         public void PathIgnored(string path, bool expected)
         {
             Assert.Equal(expected, IgnorePatterns.ShouldIgnore(path));