1
0
mirror of https://github.com/Sonarr/Sonarr.git synced 2026-04-18 21:35:27 -04:00
Files
Sonarr/src/NzbDrone.Core/DiskSpace/DiskSpaceService.cs
T
2025-06-09 17:14:13 -07:00

113 lines
3.9 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using NLog;
using NzbDrone.Common.Disk;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.RootFolders;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.DiskSpace
{
public interface IDiskSpaceService
{
List<DiskSpace> GetFreeSpace();
}
public class DiskSpaceService : IDiskSpaceService
{
private readonly ISeriesService _seriesService;
private readonly IRootFolderService _rootFolderService;
private readonly IDiskProvider _diskProvider;
private readonly Logger _logger;
private static readonly Regex _regexSpecialDrive = new Regex(@"^/var/lib/(docker|rancher|kubelet)(/|$)|^/(boot|etc)(/|$)|/docker(/var)?/aufs(/|$)|/\.timemachine", RegexOptions.Compiled);
public DiskSpaceService(ISeriesService seriesService, IRootFolderService rootFolderService, IDiskProvider diskProvider, Logger logger)
{
_seriesService = seriesService;
_rootFolderService = rootFolderService;
_diskProvider = diskProvider;
_logger = logger;
}
public List<DiskSpace> GetFreeSpace()
{
var importantRootFolders = GetSeriesRootPaths().Distinct().ToList();
var optionalRootFolders = GetFixedDisksRootPaths().Except(importantRootFolders).Distinct().ToList();
var diskSpace = GetDiskSpace(importantRootFolders)
.Concat(GetDiskSpace(optionalRootFolders, true))
.OrderBy(d => d.Path, StringComparer.OrdinalIgnoreCase)
.ToList();
return diskSpace;
}
private IEnumerable<string> GetSeriesRootPaths()
{
// Get all series paths and find the correct root folder for each. For each unique root folder path,
// ensure the path exists and get its path root and return all unique path roots.
return _seriesService.GetAllSeriesPaths()
.Where(s => s.Value.IsPathValid(PathValidationType.CurrentOs))
.Select(s => _rootFolderService.GetBestRootFolderPath(s.Value))
.Distinct()
.Where(r => _diskProvider.FolderExists(r))
.Select(r => _diskProvider.GetPathRoot(r))
.Distinct();
}
private IEnumerable<string> GetFixedDisksRootPaths()
{
return _diskProvider.GetMounts()
.Where(d => d.DriveType is DriveType.Fixed or DriveType.Network)
.Where(d => !_regexSpecialDrive.IsMatch(d.RootDirectory))
.Select(d => d.RootDirectory);
}
private IEnumerable<DiskSpace> GetDiskSpace(IEnumerable<string> paths, bool suppressWarnings = false)
{
foreach (var path in paths)
{
DiskSpace diskSpace = null;
try
{
var freeSpace = _diskProvider.GetAvailableSpace(path);
var totalSpace = _diskProvider.GetTotalSize(path);
if (!freeSpace.HasValue || !totalSpace.HasValue)
{
continue;
}
diskSpace = new DiskSpace
{
Path = path,
FreeSpace = freeSpace.Value,
TotalSpace = totalSpace.Value
};
diskSpace.Label = _diskProvider.GetVolumeLabel(path);
}
catch (Exception ex)
{
if (!suppressWarnings)
{
_logger.Warn(ex, "Unable to get free space for: " + path);
}
}
if (diskSpace != null)
{
yield return diskSpace;
}
}
}
}
}