Free space will show shared drives and show drive label

pull/4/head
Mark McDowall 11 years ago
parent 741279b596
commit d4fd731b34

@ -1,47 +1,22 @@
using System; using System.Collections.Generic;
using System.Collections.Generic; using NzbDrone.Core.DiskSpace;
using System.IO;
using System.Linq;
using System.Text;
using NzbDrone.Common;
namespace NzbDrone.Api.DiskSpace namespace NzbDrone.Api.DiskSpace
{ {
public class DiskSpaceModule :NzbDroneRestModule<DiskSpaceResource> public class DiskSpaceModule :NzbDroneRestModule<DiskSpaceResource>
{ {
private readonly IDiskProvider _diskProvider; private readonly IDiskSpaceService _diskSpaceService;
public DiskSpaceModule(IDiskProvider diskProvider):base("diskspace") public DiskSpaceModule(IDiskSpaceService diskSpaceService)
:base("diskspace")
{ {
_diskProvider = diskProvider; _diskSpaceService = diskSpaceService;
GetResourceAll = GetFreeSpace; GetResourceAll = GetFreeSpace;
} }
public List<DiskSpaceResource> GetFreeSpace() public List<DiskSpaceResource> GetFreeSpace()
{ {
return (_diskProvider.GetFixedDrives() return ToListResource(_diskSpaceService.GetFreeSpace);
.Select(
x =>
new DiskSpaceResource()
{
DriveLetter = x,
FreeSpace = _diskProvider.GetAvailableSpace(x).Value,
TotalSpace = _diskProvider.GetTotalSize(x).Value
})).ToList();
}
static string SizeSuffix(Int64 value)
{
string[] suffixes = { "bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
int i = 0;
decimal dValue = (decimal)value;
while (Math.Round(dValue / 1024) >= 1)
{
dValue /= 1024;
i++;
}
return string.Format("{0:n1}{1}", dValue, suffixes[i]);
} }
} }
} }

@ -8,7 +8,8 @@ namespace NzbDrone.Api.DiskSpace
{ {
public class DiskSpaceResource : RestResource public class DiskSpaceResource : RestResource
{ {
public string DriveLetter { get; set; } public string Path { get; set; }
public string Label { get; set; }
public Int64 FreeSpace { get; set; } public Int64 FreeSpace { get; set; }
public Int64 TotalSpace { get; set; } public Int64 TotalSpace { get; set; }
} }

@ -44,6 +44,7 @@ namespace NzbDrone.Common
void EmptyFolder(string path); void EmptyFolder(string path);
string[] GetFixedDrives(); string[] GetFixedDrives();
long? GetTotalSize(string path); long? GetTotalSize(string path);
string GetVolumeLabel(string path);
} }
public class DiskProvider : IDiskProvider public class DiskProvider : IDiskProvider
@ -324,30 +325,6 @@ namespace NzbDrone.Common
return DriveFreeSpaceEx(root); return DriveFreeSpaceEx(root);
} }
private static long DriveFreeSpaceEx(string folderName)
{
if (string.IsNullOrEmpty(folderName))
{
throw new ArgumentNullException("folderName");
}
if (!folderName.EndsWith("\\"))
{
folderName += '\\';
}
ulong free = 0;
ulong dummy1 = 0;
ulong dummy2 = 0;
if (GetDiskFreeSpaceEx(folderName, out free, out dummy1, out dummy2))
{
return (long)free;
}
return 0;
}
public string ReadAllText(string filePath) public string ReadAllText(string filePath)
{ {
Ensure.That(() => filePath).IsValidPath(); Ensure.That(() => filePath).IsValidPath();
@ -485,7 +462,97 @@ namespace NzbDrone.Common
public long? GetTotalSize(string path) public long? GetTotalSize(string path)
{ {
return (DriveInfo.GetDrives().Single(x => x.Name == path)).TotalSize; Ensure.That(() => path).IsValidPath();
var root = GetPathRoot(path);
if (!FolderExists(root))
throw new DirectoryNotFoundException(root);
if (OsInfo.IsLinux)
{
var drives = DriveInfo.GetDrives();
foreach (var drive in drives)
{
try
{
if (drive.IsReady && path.StartsWith(drive.Name, StringComparison.CurrentCultureIgnoreCase))
{
return drive.TotalSize;
}
}
catch (InvalidOperationException e)
{
Logger.ErrorException("Couldn't get total space for " + path, e);
}
}
return null;
}
return DriveTotalSizeEx(root);
}
public string GetVolumeLabel(string path)
{
var driveInfo = DriveInfo.GetDrives().SingleOrDefault(d => d.Name == path);
if (driveInfo == null)
{
return null;
}
return driveInfo.VolumeLabel;
}
private static long DriveFreeSpaceEx(string folderName)
{
if (string.IsNullOrEmpty(folderName))
{
throw new ArgumentNullException("folderName");
}
if (!folderName.EndsWith("\\"))
{
folderName += '\\';
}
ulong free = 0;
ulong dummy1 = 0;
ulong dummy2 = 0;
if (GetDiskFreeSpaceEx(folderName, out free, out dummy1, out dummy2))
{
return (long)free;
}
return 0;
}
private static long DriveTotalSizeEx(string folderName)
{
if (string.IsNullOrEmpty(folderName))
{
throw new ArgumentNullException("folderName");
}
if (!folderName.EndsWith("\\"))
{
folderName += '\\';
}
ulong total = 0;
ulong dummy1 = 0;
ulong dummy2 = 0;
if (GetDiskFreeSpaceEx(folderName, out dummy1, out total, out dummy2))
{
return (long)total;
}
return 0;
} }
} }
} }

@ -0,0 +1,12 @@
using System;
namespace NzbDrone.Core.DiskSpace
{
public class DiskSpace
{
public String Path { get; set; }
public String Label { get; set; }
public long FreeSpace { get; set; }
public long TotalSpace { get; set; }
}
}

@ -0,0 +1,96 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using NLog;
using NzbDrone.Common;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.DiskSpace
{
public interface IDiskSpaceService
{
List<DiskSpace> GetFreeSpace();
}
public class DiskSpaceService : IDiskSpaceService
{
private readonly ISeriesService _seriesService;
private readonly IConfigService _configService;
private readonly IDiskProvider _diskProvider;
private readonly Logger _logger;
public DiskSpaceService(ISeriesService seriesService, IConfigService configService, IDiskProvider diskProvider, Logger logger)
{
_seriesService = seriesService;
_configService = configService;
_diskProvider = diskProvider;
_logger = logger;
}
public List<DiskSpace> GetFreeSpace()
{
var diskSpace = new List<DiskSpace>();
diskSpace.AddRange(GetSeriesFreeSpace());
diskSpace.AddRange(GetDroneFactoryFreeSpace());
diskSpace.AddRange(GetFixedDisksFreeSpace());
return diskSpace.DistinctBy(d => d.Path).ToList();
}
private IEnumerable<DiskSpace> GetSeriesFreeSpace()
{
var seriesRootPaths = _seriesService.GetAllSeries().Select(s => _diskProvider.GetPathRoot(s.Path)).Distinct();
return GetDiskSpace(seriesRootPaths);
}
private IEnumerable<DiskSpace> GetDroneFactoryFreeSpace()
{
if (!String.IsNullOrWhiteSpace(_configService.DownloadedEpisodesFolder))
{
return GetDiskSpace(new[] { _configService.DownloadedEpisodesFolder });
}
return new List<DiskSpace>();
}
private IEnumerable<DiskSpace> GetFixedDisksFreeSpace()
{
return GetDiskSpace(_diskProvider.GetFixedDrives());
}
private IEnumerable<DiskSpace> GetDiskSpace(IEnumerable<String> paths)
{
foreach (var path in paths)
{
DiskSpace diskSpace = null;
try
{
var freeSpace = _diskProvider.GetAvailableSpace(path).Value;
var totalSpace = _diskProvider.GetTotalSize(path).Value;
diskSpace = new DiskSpace
{
Path = path,
FreeSpace = freeSpace,
TotalSpace = totalSpace
};
diskSpace.Label = _diskProvider.GetVolumeLabel(path);
}
catch (Exception ex)
{
_logger.WarnException("Unable to get free space for: " + path, ex);
}
if (diskSpace != null)
{
yield return diskSpace;
}
}
}
}
}

@ -219,6 +219,8 @@
<Compile Include="DecisionEngine\Specifications\Search\SingleEpisodeSearchMatchSpecification.cs" /> <Compile Include="DecisionEngine\Specifications\Search\SingleEpisodeSearchMatchSpecification.cs" />
<Compile Include="DecisionEngine\Specifications\UpgradeDiskSpecification.cs" /> <Compile Include="DecisionEngine\Specifications\UpgradeDiskSpecification.cs" />
<Compile Include="DecisionEngine\Specifications\RssSync\UpgradeHistorySpecification.cs" /> <Compile Include="DecisionEngine\Specifications\RssSync\UpgradeHistorySpecification.cs" />
<Compile Include="DiskSpace\DiskSpace.cs" />
<Compile Include="DiskSpace\DiskSpaceService.cs" />
<Compile Include="Download\Clients\Sabnzbd\ConnectionInfoModel.cs" /> <Compile Include="Download\Clients\Sabnzbd\ConnectionInfoModel.cs" />
<Compile Include="Download\Clients\Sabnzbd\JsonConverters\SabnzbdPriorityTypeConverter.cs" /> <Compile Include="Download\Clients\Sabnzbd\JsonConverters\SabnzbdPriorityTypeConverter.cs" />
<Compile Include="Download\Clients\Sabnzbd\JsonConverters\SabnzbdQueueTimeConverter.cs" /> <Compile Include="Download\Clients\Sabnzbd\JsonConverters\SabnzbdQueueTimeConverter.cs" />

@ -5,8 +5,9 @@ define([
'backgrid', 'backgrid',
'System/Info/DiskSpace/DiskSpaceCollection', 'System/Info/DiskSpace/DiskSpaceCollection',
'Shared/LoadingView', 'Shared/LoadingView',
'System/Info/DiskSpace/DiskSpacePathCell',
'Cells/FileSizeCell' 'Cells/FileSizeCell'
], function (vent,Marionette,Backgrid,DiskSpaceCollection,LoadingView,FileSizeCell) { ], function (vent,Marionette,Backgrid,DiskSpaceCollection,LoadingView, DiskSpacePathCell, FileSizeCell) {
return Marionette.Layout.extend({ return Marionette.Layout.extend({
template: 'System/Info/DiskSpace/DiskSpaceLayoutTemplate', template: 'System/Info/DiskSpace/DiskSpaceLayoutTemplate',
@ -16,21 +17,19 @@ define([
columns: columns:
[ [
{ {
name: 'driveLetter', name: 'path',
label: 'Drive', label: 'Location',
cell: 'string' cell: DiskSpacePathCell
}, },
{ {
name: 'freeSpace', name: 'freeSpace',
label: 'Free Space', label: 'Free Space',
cell: FileSizeCell, cell: FileSizeCell
sortable:true
}, },
{ {
name: 'totalSpace', name: 'totalSpace',
label: 'Total Space', label: 'Total Space',
cell: FileSizeCell, cell: FileSizeCell
sortable:true
} }
], ],

@ -0,0 +1,28 @@
'use strict';
define(
[
'backgrid'
], function (Backgrid) {
return Backgrid.Cell.extend({
className: 'disk-space-path-cell',
render: function () {
this.$el.empty();
var path = this.model.get('path');
var label = this.model.get('label');
var contents = path;
if (label) {
contents += ' ({0})'.format(label);
}
this.$el.html(contents);
return this;
}
});
});
Loading…
Cancel
Save