Free space will show shared drives and show drive label
This commit is contained in:
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…
Reference in New Issue