Directory lookup will not include some folders at base of drive

This commit is contained in:
Mark McDowall 2013-08-02 20:01:16 -07:00
parent 485f05d4b9
commit 1c5e30bbd0
8 changed files with 202 additions and 57 deletions

View File

@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Nancy;
using NzbDrone.Api.Extensions;
using NzbDrone.Common;
@ -8,12 +10,12 @@ namespace NzbDrone.Api.Directories
{
public class DirectoryModule : NzbDroneApiModule
{
private readonly IDiskProvider _diskProvider;
private readonly IDirectoryLookupService _directoryLookupService;
public DirectoryModule(IDiskProvider diskProvider)
public DirectoryModule(IDirectoryLookupService directoryLookupService)
: base("/directories")
{
_diskProvider = diskProvider;
_directoryLookupService = directoryLookupService;
Get["/"] = x => GetDirectories();
}
@ -24,30 +26,7 @@ namespace NzbDrone.Api.Directories
string query = Request.Query.query.Value;
IEnumerable<String> dirs = null;
try
{
//Windows (Including UNC)
var windowsSep = query.LastIndexOf('\\');
if (windowsSep > -1)
{
dirs = _diskProvider.GetDirectories(query.Substring(0, windowsSep + 1));
}
//Unix
var index = query.LastIndexOf('/');
if (index > -1)
{
dirs = _diskProvider.GetDirectories(query.Substring(0, index + 1));
}
}
catch (Exception)
{
//Swallow the exceptions so proper JSON is returned to the client (Empty results)
return new List<string>().AsResponse();
}
var dirs = _directoryLookupService.LookupSubDirectories(query);
if (dirs == null)
throw new Exception("A valid path was not provided");

View File

@ -0,0 +1,102 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Test.Common;
namespace NzbDrone.Common.Test
{
[TestFixture]
public class DirectoryLookupServiceFixture :TestBase<DirectoryLookupService>
{
private const string RECYCLING_BIN = "$Recycle.Bin";
private const string SYSTEM_VOLUME_INFORMATION = "System Volume Information";
private List<String> _folders;
[SetUp]
public void Setup()
{
_folders = new List<String>
{
RECYCLING_BIN,
"Chocolatey",
"Documents and Settings",
"Dropbox",
"Intel",
"PerfLogs",
"Program Files",
"Program Files (x86)",
"ProgramData",
SYSTEM_VOLUME_INFORMATION,
"Test",
"Users",
"Windows"
};
}
private void SetupFolders(string root)
{
_folders.ForEach(e =>
{
e = Path.Combine(root, e);
});
}
[Test]
public void should_get_all_folder_for_none_root_path()
{
const string root = @"C:\Test\";
SetupFolders(root);
Mocker.GetMock<IDiskProvider>()
.Setup(s => s.GetDirectories(It.IsAny<String>()))
.Returns(_folders.ToArray());
Subject.LookupSubDirectories(root).Should()
.HaveCount(_folders.Count);
}
[Test]
public void should_not_contain_recycling_bin_for_root_of_drive()
{
const string root = @"C:\";
SetupFolders(root);
Mocker.GetMock<IDiskProvider>()
.Setup(s => s.GetDirectories(It.IsAny<String>()))
.Returns(_folders.ToArray());
Subject.LookupSubDirectories(root).Should().NotContain(Path.Combine(root, RECYCLING_BIN));
}
[Test]
public void should_not_contain_system_volume_information_for_root_of_drive()
{
const string root = @"C:\";
SetupFolders(root);
Mocker.GetMock<IDiskProvider>()
.Setup(s => s.GetDirectories(It.IsAny<String>()))
.Returns(_folders.ToArray());
Subject.LookupSubDirectories(root).Should().NotContain(Path.Combine(root, SYSTEM_VOLUME_INFORMATION));
}
[Test]
public void should_not_contain_recycling_bin_or_system_volume_information_for_root_of_drive()
{
const string root = @"C:\";
SetupFolders(root);
Mocker.GetMock<IDiskProvider>()
.Setup(s => s.GetDirectories(It.IsAny<String>()))
.Returns(_folders.ToArray());
Subject.LookupSubDirectories(root).Should().HaveCount(_folders.Count - 2);
}
}
}

View File

@ -62,6 +62,7 @@
<Compile Include="CacheTests\CachedManagerFixture.cs" />
<Compile Include="CacheTests\CachedFixture.cs" />
<Compile Include="ConfigFileProviderTest.cs" />
<Compile Include="DirectoryLookupServiceFixture.cs" />
<Compile Include="EnsureTest\PathExtensionFixture.cs" />
<Compile Include="EnvironmentTests\StartupArgumentsFixture.cs" />
<Compile Include="EnvironmentTests\EnviromentProviderTest.cs" />

View File

@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace NzbDrone.Common
{
public interface IDirectoryLookupService
{
List<String> LookupSubDirectories(string query);
}
public class DirectoryLookupService : IDirectoryLookupService
{
private readonly IDiskProvider _diskProvider;
public DirectoryLookupService(IDiskProvider diskProvider)
{
_diskProvider = diskProvider;
}
public List<String> LookupSubDirectories(string query)
{
List<String> dirs = null;
try
{
//Windows (Including UNC)
var windowsSep = query.LastIndexOf('\\');
if (windowsSep > -1)
{
var path = query.Substring(0, windowsSep + 1);
var dirsList = _diskProvider.GetDirectories(path).ToList();
if (Path.GetPathRoot(path).Equals(path, StringComparison.InvariantCultureIgnoreCase))
{
var setToRemove = new HashSet<string> { "$Recycle.Bin", "System Volume Information" };
dirsList.RemoveAll(x => setToRemove.Contains(new DirectoryInfo(x).Name));
}
dirs = dirsList;
}
//Unix
var index = query.LastIndexOf('/');
if (index > -1)
{
dirs = _diskProvider.GetDirectories(query.Substring(0, index + 1)).ToList();
}
}
catch (Exception)
{
//Swallow the exceptions so proper JSON is returned to the client (Empty results)
return new List<string>();
}
return dirs;
}
}
}

View File

@ -58,7 +58,7 @@ namespace NzbDrone.Common
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public virtual DateTime GetLastFolderWrite(string path)
public DateTime GetLastFolderWrite(string path)
{
Ensure.That(() => path).IsValidPath();
@ -78,7 +78,7 @@ namespace NzbDrone.Common
.Max(c => c.LastWriteTimeUtc);
}
public virtual DateTime GetLastFileWrite(string path)
public DateTime GetLastFileWrite(string path)
{
Ensure.That(() => path).IsValidPath();
@ -89,7 +89,7 @@ namespace NzbDrone.Common
return new FileInfo(path).LastWriteTimeUtc;
}
public virtual void EnsureFolder(string path)
public void EnsureFolder(string path)
{
if (!FolderExists(path))
{
@ -97,13 +97,13 @@ namespace NzbDrone.Common
}
}
public virtual bool FolderExists(string path)
public bool FolderExists(string path)
{
Ensure.That(() => path).IsValidPath();
return Directory.Exists(path);
}
public virtual bool FolderExists(string path, bool caseSensitive)
public bool FolderExists(string path, bool caseSensitive)
{
if (caseSensitive)
{
@ -113,13 +113,13 @@ namespace NzbDrone.Common
return FolderExists(path);
}
public virtual bool FileExists(string path)
public bool FileExists(string path)
{
Ensure.That(() => path).IsValidPath();
return File.Exists(path);
}
public virtual bool FileExists(string path, bool caseSensitive)
public bool FileExists(string path, bool caseSensitive)
{
if (caseSensitive)
{
@ -129,28 +129,28 @@ namespace NzbDrone.Common
return FileExists(path);
}
public virtual string[] GetDirectories(string path)
public string[] GetDirectories(string path)
{
Ensure.That(() => path).IsValidPath();
return Directory.GetDirectories(path);
}
public virtual string[] GetFiles(string path, SearchOption searchOption)
public string[] GetFiles(string path, SearchOption searchOption)
{
Ensure.That(() => path).IsValidPath();
return Directory.GetFiles(path, "*.*", searchOption);
}
public virtual long GetFolderSize(string path)
public long GetFolderSize(string path)
{
Ensure.That(() => path).IsValidPath();
return GetFiles(path, SearchOption.AllDirectories).Sum(e => new FileInfo(e).Length);
}
public virtual long GetFileSize(string path)
public long GetFileSize(string path)
{
Ensure.That(() => path).IsValidPath();
@ -161,14 +161,14 @@ namespace NzbDrone.Common
return fi.Length;
}
public virtual String CreateFolder(string path)
public String CreateFolder(string path)
{
Ensure.That(() => path).IsValidPath();
return Directory.CreateDirectory(path).FullName;
}
public virtual void CopyFolder(string source, string target)
public void CopyFolder(string source, string target)
{
Ensure.That(() => source).IsValidPath();
Ensure.That(() => target).IsValidPath();
@ -176,7 +176,7 @@ namespace NzbDrone.Common
TransferFolder(source, target, TransferAction.Copy);
}
public virtual void MoveFolder(string source, string destination)
public void MoveFolder(string source, string destination)
{
Ensure.That(() => source).IsValidPath();
Ensure.That(() => destination).IsValidPath();
@ -237,7 +237,7 @@ namespace NzbDrone.Common
}
}
public virtual void DeleteFile(string path)
public void DeleteFile(string path)
{
Ensure.That(() => path).IsValidPath();
@ -245,7 +245,7 @@ namespace NzbDrone.Common
File.Delete(path);
}
public virtual void MoveFile(string source, string destination)
public void MoveFile(string source, string destination)
{
Ensure.That(() => source).IsValidPath();
Ensure.That(() => destination).IsValidPath();
@ -264,14 +264,14 @@ namespace NzbDrone.Common
File.Move(source, destination);
}
public virtual void DeleteFolder(string path, bool recursive)
public void DeleteFolder(string path, bool recursive)
{
Ensure.That(() => path).IsValidPath();
Directory.Delete(path, recursive);
}
public virtual void InheritFolderPermissions(string filename)
public void InheritFolderPermissions(string filename)
{
Ensure.That(() => filename).IsValidPath();
@ -280,7 +280,7 @@ namespace NzbDrone.Common
File.SetAccessControl(filename, fs);
}
public virtual long GetAvilableSpace(string path)
public long GetAvilableSpace(string path)
{
Ensure.That(() => path).IsValidPath();
@ -327,14 +327,14 @@ namespace NzbDrone.Common
return 0;
}
public virtual string ReadAllText(string filePath)
public string ReadAllText(string filePath)
{
Ensure.That(() => filePath).IsValidPath();
return File.ReadAllText(filePath);
}
public virtual void WriteAllText(string filename, string contents)
public void WriteAllText(string filename, string contents)
{
Ensure.That(() => filename).IsValidPath();
@ -349,21 +349,21 @@ namespace NzbDrone.Common
return String.Equals(firstPath.CleanFilePath(), secondPath.CleanFilePath(), StringComparison.InvariantCultureIgnoreCase);
}
public virtual void FileSetLastWriteTimeUtc(string path, DateTime dateTime)
public void FileSetLastWriteTimeUtc(string path, DateTime dateTime)
{
Ensure.That(() => path).IsValidPath();
File.SetLastWriteTimeUtc(path, dateTime);
}
public virtual void FolderSetLastWriteTimeUtc(string path, DateTime dateTime)
public void FolderSetLastWriteTimeUtc(string path, DateTime dateTime)
{
Ensure.That(() => path).IsValidPath();
Directory.SetLastWriteTimeUtc(path, dateTime);
}
public virtual bool IsFileLocked(FileInfo file)
public bool IsFileLocked(FileInfo file)
{
FileStream stream = null;
@ -385,7 +385,7 @@ namespace NzbDrone.Common
return false;
}
public virtual string GetPathRoot(string path)
public string GetPathRoot(string path)
{
Ensure.That(() => path).IsValidPath();

View File

@ -66,6 +66,7 @@
<Compile Include="Composition\Container.cs" />
<Compile Include="Composition\IContainer.cs" />
<Compile Include="Composition\ContainerBuilderBase.cs" />
<Compile Include="DirectoryLookupService.cs" />
<Compile Include="EnsureThat\Ensure.cs" />
<Compile Include="EnsureThat\EnsureBoolExtensions.cs" />
<Compile Include="EnsureThat\EnsureCollectionExtensions.cs" />

View File

@ -109,7 +109,7 @@ namespace NzbDrone.Core.Test.MediaFileTests
Subject.Execute(new DownloadedEpisodesScanCommand());
Mocker.GetMock<DiskProvider>()
Mocker.GetMock<IDiskProvider>()
.Verify(v => v.GetFolderSize(It.IsAny<String>()), Times.Never());
}

View File

@ -85,13 +85,13 @@ namespace NzbDrone.Core.Datastore
public IEnumerable<TModel> Get(IEnumerable<int> ids)
{
var query = String.Format("Id IN ({0})", String.Join(",", ids));
var idList = ids.ToList();
var query = String.Format("Id IN ({0})", String.Join(",", idList));
var result = Query.Where(query).ToList();
if (result.Count != ids.Count())
if (result.Count != idList.Count())
{
throw new ApplicationException("Expected query to return {0} rows but returned {1}".Inject(ids.Count(), result.Count));
throw new ApplicationException("Expected query to return {0} rows but returned {1}".Inject(idList.Count(), result.Count));
}
return result;