From c3acfe34fe9654eb80e9e82cb100c69a73f8fc28 Mon Sep 17 00:00:00 2001
From: Mark McDowall <markus.mcd5@gmail.com>
Date: Mon, 11 May 2015 17:23:55 -0700
Subject: [PATCH] Fixed: Exclude OS X Metadata files when scanning for files

Fixes #533
---
 .../GetVideoFilesFixture.cs                   | 19 ++++++++++++++++++-
 .../MediaFiles/DiskScanService.cs             |  8 ++++++--
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/src/NzbDrone.Core.Test/ProviderTests/DiskScanProviderTests/GetVideoFilesFixture.cs b/src/NzbDrone.Core.Test/ProviderTests/DiskScanProviderTests/GetVideoFilesFixture.cs
index 449c251e6..e8c3fa104 100644
--- a/src/NzbDrone.Core.Test/ProviderTests/DiskScanProviderTests/GetVideoFilesFixture.cs
+++ b/src/NzbDrone.Core.Test/ProviderTests/DiskScanProviderTests/GetVideoFilesFixture.cs
@@ -27,6 +27,11 @@ public void Setup()
                             @"C:\Test\movie"
                         };
 
+            GivenFiles();
+        }
+
+        private void GivenFiles()
+        {
             Mocker.GetMock<IDiskProvider>()
                 .Setup(s => s.GetFiles(It.IsAny<String>(), SearchOption.AllDirectories))
                 .Returns(_files);
@@ -69,8 +74,20 @@ public void should_check_top_level_directory_only_when_allDirectories_is_false()
         public void should_return_video_files_only()
         {
             var path = @"C:\Test\";
-            var test = Subject.GetVideoFiles(path);
+
             Subject.GetVideoFiles(path).Should().HaveCount(4);
         }
+
+        [Test]
+        public void should_exclude_osx_metadata_files()
+        {
+            var path = @"C:\Test\";
+
+            _files = new [] { "._24 The Status Quo Combustion.mp4", "24 The Status Quo Combustion.mp4" };
+            
+            GivenFiles();
+            
+            Subject.GetVideoFiles(path).Should().HaveCount(1);
+        }
     }
 }
diff --git a/src/NzbDrone.Core/MediaFiles/DiskScanService.cs b/src/NzbDrone.Core/MediaFiles/DiskScanService.cs
index 23daed588..b30c4b70e 100644
--- a/src/NzbDrone.Core/MediaFiles/DiskScanService.cs
+++ b/src/NzbDrone.Core/MediaFiles/DiskScanService.cs
@@ -60,6 +60,7 @@ public DiskScanService(IDiskProvider diskProvider,
 
         private static readonly Regex ExcludedSubFoldersRegex = new Regex(@"(extras|@eadir)(?:\\|\/)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
         private static readonly Regex ExcludedFoldersRegex = new Regex(@"(?:\\|\/)(\..+)(?:\\|\/)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
+        private static readonly Regex ExcludedFilesRegex = new Regex(@"^\._", RegexOptions.Compiled | RegexOptions.IgnoreCase);
 
         public void Scan(Series series)
         {
@@ -124,7 +125,9 @@ public string[] GetVideoFiles(string path, bool allDirectories = true)
             var searchOption = allDirectories ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
             var filesOnDisk = _diskProvider.GetFiles(path, searchOption);
 
-            var mediaFileList = filesOnDisk.Where(c => MediaFileExtensions.Extensions.Contains(Path.GetExtension(c).ToLower())).ToList();
+            var mediaFileList = filesOnDisk.Where(file => MediaFileExtensions.Extensions.Contains(Path.GetExtension(file).ToLower()))
+                                           .Where(file => !ExcludedFilesRegex.IsMatch(Path.GetFileName(file)))
+                                           .ToList();
 
             _logger.Debug("{0} video files were found in {1}", mediaFileList.Count, path);
             return mediaFileList.ToArray();
@@ -133,7 +136,8 @@ public string[] GetVideoFiles(string path, bool allDirectories = true)
         private IEnumerable<string> FilterFiles(Series series, IEnumerable<string> videoFiles)
         {
             return videoFiles.Where(file => !ExcludedSubFoldersRegex.IsMatch(series.Path.GetRelativePath(file)))
-                             .Where(file => !ExcludedFoldersRegex.IsMatch(file));
+                             .Where(file => !ExcludedFoldersRegex.IsMatch(file))
+                             .Where(file => !ExcludedFilesRegex.IsMatch(Path.GetFileName(file)));
         }
 
         private void SetPermissions(String path)