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.
Lidarr/src/NzbDrone.Common/Disk/FileSystemLookupService.cs

196 lines
7.2 KiB

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using NLog;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Extensions;
namespace NzbDrone.Common.Disk
{
public interface IFileSystemLookupService
{
FileSystemResult LookupContents(string query, bool includeFiles);
}
public class FileSystemLookupService : IFileSystemLookupService
{
private readonly IDiskProvider _diskProvider;
private readonly Logger _logger;
private readonly HashSet<string> _setToRemove = new HashSet<string>
{
//Windows
"boot",
"bootmgr",
"cache",
"msocache",
"recovery",
"$recycle.bin",
"recycler",
"system volume information",
"temporary internet files",
"windows",
//OS X
".fseventd",
".spotlight",
".trashes",
".vol",
"cachedmessages",
"caches",
"trash"
};
public FileSystemLookupService(IDiskProvider diskProvider, Logger logger)
{
_diskProvider = diskProvider;
_logger = logger;
}
public FileSystemResult LookupContents(string query, bool includeFiles)
{
var result = new FileSystemResult();
if (query.IsNullOrWhiteSpace())
{
if (OsInfo.IsWindows)
{
result.Directories = GetDrives();
return result;
}
query = "/";
}
var lastSeparatorIndex = query.LastIndexOf(Path.DirectorySeparatorChar);
var path = query.Substring(0, lastSeparatorIndex + 1);
if (lastSeparatorIndex != -1)
{
try
{
result.Parent = GetParent(path);
result.Directories = GetDirectories(path);
if (includeFiles)
{
result.Files = GetFiles(path);
}
}
catch (DirectoryNotFoundException)
{
return new FileSystemResult { Parent = GetParent(path) };
}
catch (ArgumentException)
{
return new FileSystemResult();
}
catch (IOException)
{
return new FileSystemResult { Parent = GetParent(path) };
}
catch (UnauthorizedAccessException)
{
return new FileSystemResult { Parent = GetParent(path) };
}
}
return result;
}
private List<FileSystemModel> GetDrives()
{
return _diskProvider.GetDrives()
.Select(d => new FileSystemModel
{
Type = FileSystemEntityType.Drive,
Name = GetVolumeName(d),
Path = d.Name,
LastModified = null
})
.ToList();
}
private List<FileSystemModel> GetDirectories(string path)
{
var directories = _diskProvider.GetDirectoryInfos(path)
.OrderBy(d => d.Name)
.Select(d => new FileSystemModel
{
Name = d.Name,
Path = GetDirectoryPath(d.FullName.GetActualCasing()),
LastModified = d.LastWriteTimeUtc,
Type = FileSystemEntityType.Folder
})
.ToList();
directories.RemoveAll(d => _setToRemove.Contains(d.Name.ToLowerInvariant()));
return directories;
}
private List<FileSystemModel> GetFiles(string path)
{
return _diskProvider.GetFileInfos(path)
.OrderBy(d => d.Name)
.Select(d => new FileSystemModel
{
Name = d.Name,
Path = d.FullName.GetActualCasing(),
LastModified = d.LastWriteTimeUtc,
Extension = d.Extension,
Size = d.Length,
Type = FileSystemEntityType.File
})
.ToList();
}
private string GetDirectoryPath(string path)
{
if (path.Last() != Path.DirectorySeparatorChar)
{
path += Path.DirectorySeparatorChar;
}
return path;
}
private string GetVolumeName(DriveInfo driveInfo)
{
if (driveInfo.VolumeLabel.IsNullOrWhiteSpace())
{
return driveInfo.Name;
}
return string.Format("{0} ({1})", driveInfo.Name, driveInfo.VolumeLabel);
}
private string GetParent(string path)
{
var di = new DirectoryInfo(path);
if (di.Parent != null)
{
var parent = di.Parent.FullName;
if (parent.Last() != Path.DirectorySeparatorChar)
{
parent += Path.DirectorySeparatorChar;
}
return parent;
}
if (!path.Equals("/"))
{
return string.Empty;
}
return null;
}
}
}