diff --git a/Emby.Server.Implementations/SystemManager.cs b/Emby.Server.Implementations/SystemManager.cs
index 5936df7f1a..92b59b23cd 100644
--- a/Emby.Server.Implementations/SystemManager.cs
+++ b/Emby.Server.Implementations/SystemManager.cs
@@ -1,9 +1,12 @@
+using System;
using System.Linq;
using System.Threading.Tasks;
+using Jellyfin.Server.Implementations.StorageHelpers;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Updates;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Library;
using MediaBrowser.Model.System;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Hosting;
@@ -19,6 +22,7 @@ public class SystemManager : ISystemManager
private readonly IServerConfigurationManager _configurationManager;
private readonly IStartupOptions _startupOptions;
private readonly IInstallationManager _installationManager;
+ private readonly ILibraryManager _libraryManager;
///
/// Initializes a new instance of the class.
@@ -29,13 +33,15 @@ public class SystemManager : ISystemManager
/// Instance of .
/// Instance of .
/// Instance of .
+ /// Instance of .
public SystemManager(
IHostApplicationLifetime applicationLifetime,
IServerApplicationHost applicationHost,
IServerApplicationPaths applicationPaths,
IServerConfigurationManager configurationManager,
IStartupOptions startupOptions,
- IInstallationManager installationManager)
+ IInstallationManager installationManager,
+ ILibraryManager libraryManager)
{
_applicationLifetime = applicationLifetime;
_applicationHost = applicationHost;
@@ -43,6 +49,7 @@ public class SystemManager : ISystemManager
_configurationManager = configurationManager;
_startupOptions = startupOptions;
_installationManager = installationManager;
+ _libraryManager = libraryManager;
}
///
@@ -57,6 +64,7 @@ public class SystemManager : ISystemManager
WebSocketPortNumber = _applicationHost.HttpPort,
CompletedInstallations = _installationManager.CompletedInstallations.ToArray(),
Id = _applicationHost.SystemId,
+#pragma warning disable CS0618 // Type or member is obsolete
ProgramDataPath = _applicationPaths.ProgramDataPath,
WebPath = _applicationPaths.WebPath,
LogPath = _applicationPaths.LogDirectoryPath,
@@ -64,6 +72,7 @@ public class SystemManager : ISystemManager
InternalMetadataPath = _applicationPaths.InternalMetadataPath,
CachePath = _applicationPaths.CachePath,
TranscodingTempPath = _configurationManager.GetTranscodePath(),
+#pragma warning restore CS0618 // Type or member is obsolete
ServerName = _applicationHost.FriendlyName,
LocalAddress = _applicationHost.GetSmartApiUrl(request),
StartupWizardCompleted = _configurationManager.CommonConfiguration.IsStartupWizardCompleted,
@@ -73,6 +82,29 @@ public class SystemManager : ISystemManager
};
}
+ ///
+ public SystemStorageInfo GetSystemStorageInfo()
+ {
+ var virtualFolderInfos = _libraryManager.GetVirtualFolders().Select(e => new LibraryStorageInfo()
+ {
+ Id = Guid.Parse(e.ItemId),
+ Name = e.Name,
+ Folders = e.Locations.Select(f => StorageHelper.GetFreeSpaceOf(f)).ToArray()
+ });
+
+ return new SystemStorageInfo()
+ {
+ ProgramDataFolder = StorageHelper.GetFreeSpaceOf(_applicationPaths.ProgramDataPath),
+ WebFolder = StorageHelper.GetFreeSpaceOf(_applicationPaths.WebPath),
+ LogFolder = StorageHelper.GetFreeSpaceOf(_applicationPaths.LogDirectoryPath),
+ ImageCacheFolder = StorageHelper.GetFreeSpaceOf(_applicationPaths.ImageCachePath),
+ InternalMetadataFolder = StorageHelper.GetFreeSpaceOf(_applicationPaths.InternalMetadataPath),
+ CacheFolder = StorageHelper.GetFreeSpaceOf(_applicationPaths.CachePath),
+ TranscodingTempFolder = StorageHelper.GetFreeSpaceOf(_configurationManager.GetTranscodePath()),
+ Libraries = virtualFolderInfos.ToArray()
+ };
+ }
+
///
public PublicSystemInfo GetPublicSystemInfo(HttpRequest request)
{
diff --git a/Jellyfin.Api/Controllers/SystemController.cs b/Jellyfin.Api/Controllers/SystemController.cs
index 0ee11c0704..07a1f76503 100644
--- a/Jellyfin.Api/Controllers/SystemController.cs
+++ b/Jellyfin.Api/Controllers/SystemController.cs
@@ -6,6 +6,7 @@ using System.Linq;
using System.Net.Mime;
using Jellyfin.Api.Attributes;
using Jellyfin.Api.Constants;
+using Jellyfin.Api.Models.SystemInfoDtos;
using MediaBrowser.Common.Api;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;
@@ -71,6 +72,19 @@ public class SystemController : BaseJellyfinApiController
public ActionResult GetSystemInfo()
=> _systemManager.GetSystemInfo(Request);
+ ///
+ /// Gets information about the server.
+ ///
+ /// Information retrieved.
+ /// User does not have permission to retrieve information.
+ /// A with info about the system.
+ [HttpGet("Info/Storage")]
+ [Authorize(Policy = Policies.RequiresElevation)]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status403Forbidden)]
+ public ActionResult GetSystemStorage()
+ => Ok(SystemStorageDto.FromSystemStorageInfo(_systemManager.GetSystemStorageInfo()));
+
///
/// Gets public information about the server.
///
diff --git a/Jellyfin.Api/Models/SystemInfoDtos/FolderStorageDto.cs b/Jellyfin.Api/Models/SystemInfoDtos/FolderStorageDto.cs
new file mode 100644
index 0000000000..00a965898c
--- /dev/null
+++ b/Jellyfin.Api/Models/SystemInfoDtos/FolderStorageDto.cs
@@ -0,0 +1,46 @@
+using MediaBrowser.Model.System;
+
+namespace Jellyfin.Api.Models.SystemInfoDtos;
+
+///
+/// Contains information about a specific folder.
+///
+public record FolderStorageDto
+{
+ ///
+ /// Gets the path of the folder in question.
+ ///
+ public required string Path { get; init; }
+
+ ///
+ /// Gets the free space of the underlying storage device of the .
+ ///
+ public long FreeSpace { get; init; }
+
+ ///
+ /// Gets the used space of the underlying storage device of the .
+ ///
+ public long UsedSpace { get; init; }
+
+ ///
+ /// Gets the kind of storage device of the .
+ ///
+ public string? StorageType { get; init; }
+
+ ///
+ /// Gets the Device Identifier.
+ ///
+ public string? DeviceId { get; init; }
+
+ internal static FolderStorageDto FromFolderStorageInfo(FolderStorageInfo model)
+ {
+ return new()
+ {
+ Path = model.Path,
+ FreeSpace = model.FreeSpace,
+ UsedSpace = model.UsedSpace,
+ StorageType = model.StorageType,
+ DeviceId = model.DeviceId
+ };
+ }
+}
diff --git a/Jellyfin.Api/Models/SystemInfoDtos/LibraryStorageDto.cs b/Jellyfin.Api/Models/SystemInfoDtos/LibraryStorageDto.cs
new file mode 100644
index 0000000000..c138324d2e
--- /dev/null
+++ b/Jellyfin.Api/Models/SystemInfoDtos/LibraryStorageDto.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using MediaBrowser.Model.System;
+
+namespace Jellyfin.Api.Models.SystemInfoDtos;
+
+///
+/// Contains informations about a libraries storage informations.
+///
+public record LibraryStorageDto
+{
+ ///
+ /// Gets or sets the Library Id.
+ ///
+ public required Guid Id { get; set; }
+
+ ///
+ /// Gets or sets the name of the library.
+ ///
+ public required string Name { get; set; }
+
+ ///
+ /// Gets or sets the storage informations about the folders used in a library.
+ ///
+ public required IReadOnlyCollection Folders { get; set; }
+
+ internal static LibraryStorageDto FromLibraryStorageModel(LibraryStorageInfo model)
+ {
+ return new()
+ {
+ Id = model.Id,
+ Name = model.Name,
+ Folders = model.Folders.Select(FolderStorageDto.FromFolderStorageInfo).ToArray()
+ };
+ }
+}
diff --git a/Jellyfin.Api/Models/SystemInfoDtos/SystemStorageDto.cs b/Jellyfin.Api/Models/SystemInfoDtos/SystemStorageDto.cs
new file mode 100644
index 0000000000..a09042439a
--- /dev/null
+++ b/Jellyfin.Api/Models/SystemInfoDtos/SystemStorageDto.cs
@@ -0,0 +1,67 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using MediaBrowser.Model.System;
+
+namespace Jellyfin.Api.Models.SystemInfoDtos;
+
+///
+/// Contains informations about the systems storage.
+///
+public record SystemStorageDto
+{
+ ///
+ /// Gets or sets the Storage information of the program data folder.
+ ///
+ public required FolderStorageDto ProgramDataFolder { get; set; }
+
+ ///
+ /// Gets or sets the Storage information of the web UI resources folder.
+ ///
+ public required FolderStorageDto WebFolder { get; set; }
+
+ ///
+ /// Gets or sets the Storage information of the folder where images are cached.
+ ///
+ public required FolderStorageDto ImageCacheFolder { get; set; }
+
+ ///
+ /// Gets or sets the Storage information of the cache folder.
+ ///
+ public required FolderStorageDto CacheFolder { get; set; }
+
+ ///
+ /// Gets or sets the Storage information of the folder where logfiles are saved to.
+ ///
+ public required FolderStorageDto LogFolder { get; set; }
+
+ ///
+ /// Gets or sets the Storage information of the folder where metadata is stored.
+ ///
+ public required FolderStorageDto InternalMetadataFolder { get; set; }
+
+ ///
+ /// Gets or sets the Storage information of the transcoding cache.
+ ///
+ public required FolderStorageDto TranscodingTempFolder { get; set; }
+
+ ///
+ /// Gets or sets the storage informations of all libraries.
+ ///
+ public required IReadOnlyCollection Libraries { get; set; }
+
+ internal static SystemStorageDto FromSystemStorageInfo(SystemStorageInfo model)
+ {
+ return new SystemStorageDto()
+ {
+ ProgramDataFolder = FolderStorageDto.FromFolderStorageInfo(model.ProgramDataFolder),
+ WebFolder = FolderStorageDto.FromFolderStorageInfo(model.WebFolder),
+ ImageCacheFolder = FolderStorageDto.FromFolderStorageInfo(model.ImageCacheFolder),
+ CacheFolder = FolderStorageDto.FromFolderStorageInfo(model.CacheFolder),
+ LogFolder = FolderStorageDto.FromFolderStorageInfo(model.LogFolder),
+ InternalMetadataFolder = FolderStorageDto.FromFolderStorageInfo(model.InternalMetadataFolder),
+ TranscodingTempFolder = FolderStorageDto.FromFolderStorageInfo(model.TranscodingTempFolder),
+ Libraries = model.Libraries.Select(LibraryStorageDto.FromLibraryStorageModel).ToArray()
+ };
+ }
+}
diff --git a/Jellyfin.Server.Implementations/StorageHelpers/StorageHelper.cs b/Jellyfin.Server.Implementations/StorageHelpers/StorageHelper.cs
new file mode 100644
index 0000000000..635644179f
--- /dev/null
+++ b/Jellyfin.Server.Implementations/StorageHelpers/StorageHelper.cs
@@ -0,0 +1,109 @@
+using System;
+using System.Globalization;
+using System.IO;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Model.System;
+using Microsoft.Extensions.Logging;
+
+namespace Jellyfin.Server.Implementations.StorageHelpers;
+
+///
+/// Contains methods to help with checking for storage and returning storage data for jellyfin folders.
+///
+public static class StorageHelper
+{
+ private const long TwoGigabyte = 2_147_483_647L;
+ private const long FiveHundredAndTwelveMegaByte = 536_870_911L;
+ private static readonly string[] _byteHumanizedSuffixes = ["B", "KB", "MB", "GB", "TB", "PB", "EB"];
+
+ ///
+ /// Tests the available storage capacity on the jellyfin paths with estimated minimum values.
+ ///
+ /// The application paths.
+ /// Logger.
+ public static void TestCommonPathsForStorageCapacity(IApplicationPaths applicationPaths, ILogger logger)
+ {
+ TestDataDirectorySize(applicationPaths.DataPath, logger, TwoGigabyte);
+ TestDataDirectorySize(applicationPaths.LogDirectoryPath, logger, FiveHundredAndTwelveMegaByte);
+ TestDataDirectorySize(applicationPaths.CachePath, logger, TwoGigabyte);
+ TestDataDirectorySize(applicationPaths.ProgramDataPath, logger, TwoGigabyte);
+ TestDataDirectorySize(applicationPaths.TempDirectory, logger, TwoGigabyte);
+ }
+
+ ///
+ /// Gets the free space of a specific directory.
+ ///
+ /// Path to a folder.
+ /// The number of bytes available space.
+ public static FolderStorageInfo GetFreeSpaceOf(string path)
+ {
+ try
+ {
+ var driveInfo = new DriveInfo(path);
+ return new FolderStorageInfo()
+ {
+ Path = path,
+ FreeSpace = driveInfo.AvailableFreeSpace,
+ UsedSpace = driveInfo.TotalSize - driveInfo.AvailableFreeSpace,
+ StorageType = driveInfo.DriveType.ToString(),
+ DeviceId = driveInfo.Name,
+ };
+ }
+ catch
+ {
+ return new FolderStorageInfo()
+ {
+ Path = path,
+ FreeSpace = -1,
+ UsedSpace = -1,
+ StorageType = null,
+ DeviceId = null
+ };
+ }
+ }
+
+ ///
+ /// Gets the underlying drive data from a given path and checks if the available storage capacity matches the threshold.
+ ///
+ /// The path to a folder to evaluate.
+ /// The logger.
+ /// The threshold to check for or -1 to just log the data.
+ /// Thrown when the threshold is not available on the underlying storage.
+ private static void TestDataDirectorySize(string path, ILogger logger, long threshold = -1)
+ {
+ logger.LogDebug("Check path {TestPath} for storage capacity", path);
+ var drive = new DriveInfo(path);
+ if (threshold != -1 && drive.AvailableFreeSpace < threshold)
+ {
+ throw new InvalidOperationException($"The path `{path}` has insufficient free space. Required: at least {HumanizeStorageSize(threshold)}.");
+ }
+
+ logger.LogInformation(
+ "Storage path `{TestPath}` ({StorageType}) successfully checked with {FreeSpace} free which is over the minimum of {MinFree}.",
+ path,
+ drive.DriveType,
+ HumanizeStorageSize(drive.AvailableFreeSpace),
+ HumanizeStorageSize(threshold));
+ }
+
+ ///
+ /// Formats a size in bytes into a common human readable form.
+ ///
+ ///
+ /// Taken and slightly modified from https://stackoverflow.com/a/4975942/1786007 .
+ ///
+ /// The size in bytes.
+ /// A human readable approximate representation of the argument.
+ public static string HumanizeStorageSize(long byteCount)
+ {
+ if (byteCount == 0)
+ {
+ return $"0{_byteHumanizedSuffixes[0]}";
+ }
+
+ var bytes = Math.Abs(byteCount);
+ var place = Convert.ToInt32(Math.Floor(Math.Log(bytes, 1024)));
+ var num = Math.Round(bytes / Math.Pow(1024, place), 1);
+ return (Math.Sign(byteCount) * num).ToString(CultureInfo.InvariantCulture) + _byteHumanizedSuffixes[place];
+ }
+}
diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs
index 55a4a00878..8d0bf73f6a 100644
--- a/Jellyfin.Server/Program.cs
+++ b/Jellyfin.Server/Program.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
@@ -11,6 +12,7 @@ using Emby.Server.Implementations;
using Jellyfin.Database.Implementations;
using Jellyfin.Server.Extensions;
using Jellyfin.Server.Helpers;
+using Jellyfin.Server.Implementations.StorageHelpers;
using Jellyfin.Server.ServerSetupApp;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Net;
@@ -120,6 +122,8 @@ namespace Jellyfin.Server
}
}
+ StorageHelper.TestCommonPathsForStorageCapacity(appPaths, _loggerFactory.CreateLogger());
+
StartupHelpers.PerformStaticInitialization();
await Migrations.MigrationRunner.RunPreStartup(appPaths, _loggerFactory).ConfigureAwait(false);
diff --git a/MediaBrowser.Controller/ISystemManager.cs b/MediaBrowser.Controller/ISystemManager.cs
index ef3034d2f5..08344a1e51 100644
--- a/MediaBrowser.Controller/ISystemManager.cs
+++ b/MediaBrowser.Controller/ISystemManager.cs
@@ -1,5 +1,6 @@
using MediaBrowser.Model.System;
using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
namespace MediaBrowser.Controller;
@@ -31,4 +32,10 @@ public interface ISystemManager
/// Starts the application shutdown process.
///
void Shutdown();
+
+ ///
+ /// Gets the systems storage resources.
+ ///
+ /// The .
+ SystemStorageInfo GetSystemStorageInfo();
}
diff --git a/MediaBrowser.Model/System/FolderStorageInfo.cs b/MediaBrowser.Model/System/FolderStorageInfo.cs
new file mode 100644
index 0000000000..7b10e4ea58
--- /dev/null
+++ b/MediaBrowser.Model/System/FolderStorageInfo.cs
@@ -0,0 +1,32 @@
+namespace MediaBrowser.Model.System;
+
+///
+/// Contains information about a specific folder.
+///
+public record FolderStorageInfo
+{
+ ///
+ /// Gets the path of the folder in question.
+ ///
+ public required string Path { get; init; }
+
+ ///
+ /// Gets the free space of the underlying storage device of the .
+ ///
+ public long FreeSpace { get; init; }
+
+ ///
+ /// Gets the used space of the underlying storage device of the .
+ ///
+ public long UsedSpace { get; init; }
+
+ ///
+ /// Gets the kind of storage device of the .
+ ///
+ public string? StorageType { get; init; }
+
+ ///
+ /// Gets the Device Identifier.
+ ///
+ public string? DeviceId { get; init; }
+}
diff --git a/MediaBrowser.Model/System/LibraryStorageInfo.cs b/MediaBrowser.Model/System/LibraryStorageInfo.cs
new file mode 100644
index 0000000000..d4111b29c7
--- /dev/null
+++ b/MediaBrowser.Model/System/LibraryStorageInfo.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+
+namespace MediaBrowser.Model.System;
+
+///
+/// Contains informations about a libraries storage informations.
+///
+public class LibraryStorageInfo
+{
+ ///
+ /// Gets or sets the Library Id.
+ ///
+ public required Guid Id { get; set; }
+
+ ///
+ /// Gets or sets the name of the library.
+ ///
+ public required string Name { get; set; }
+
+ ///
+ /// Gets or sets the storage informations about the folders used in a library.
+ ///
+ public required IReadOnlyCollection Folders { get; set; }
+}
diff --git a/MediaBrowser.Model/System/SystemInfo.cs b/MediaBrowser.Model/System/SystemInfo.cs
index f37ac6a147..232a2a6bc8 100644
--- a/MediaBrowser.Model/System/SystemInfo.cs
+++ b/MediaBrowser.Model/System/SystemInfo.cs
@@ -6,133 +6,139 @@ using System.Collections.Generic;
using System.ComponentModel;
using MediaBrowser.Model.Updates;
-namespace MediaBrowser.Model.System
+namespace MediaBrowser.Model.System;
+
+///
+/// Class SystemInfo.
+///
+public class SystemInfo : PublicSystemInfo
{
///
- /// Class SystemInfo.
+ /// Initializes a new instance of the class.
///
- public class SystemInfo : PublicSystemInfo
+ public SystemInfo()
{
- ///
- /// Initializes a new instance of the class.
- ///
- public SystemInfo()
- {
- CompletedInstallations = Array.Empty();
- }
-
- ///
- /// Gets or sets the display name of the operating system.
- ///
- /// The display name of the operating system.
- [Obsolete("This is no longer set")]
- public string OperatingSystemDisplayName { get; set; } = string.Empty;
-
- ///
- /// Gets or sets the package name.
- ///
- /// The value of the '-package' command line argument.
- public string PackageName { get; set; }
-
- ///
- /// Gets or sets a value indicating whether this instance has pending restart.
- ///
- /// true if this instance has pending restart; otherwise, false.
- public bool HasPendingRestart { get; set; }
-
- public bool IsShuttingDown { get; set; }
-
- ///
- /// Gets or sets a value indicating whether [supports library monitor].
- ///
- /// true if [supports library monitor]; otherwise, false.
- public bool SupportsLibraryMonitor { get; set; }
-
- ///
- /// Gets or sets the web socket port number.
- ///
- /// The web socket port number.
- public int WebSocketPortNumber { get; set; }
-
- ///
- /// Gets or sets the completed installations.
- ///
- /// The completed installations.
- public InstallationInfo[] CompletedInstallations { get; set; }
-
- ///
- /// Gets or sets a value indicating whether this instance can self restart.
- ///
- /// true.
- [Obsolete("This is always true")]
- [DefaultValue(true)]
- public bool CanSelfRestart { get; set; } = true;
-
- [Obsolete("This is always false")]
- [DefaultValue(false)]
- public bool CanLaunchWebBrowser { get; set; } = false;
-
- ///
- /// Gets or sets the program data path.
- ///
- /// The program data path.
- public string ProgramDataPath { get; set; }
-
- ///
- /// Gets or sets the web UI resources path.
- ///
- /// The web UI resources path.
- public string WebPath { get; set; }
-
- ///
- /// Gets or sets the items by name path.
- ///
- /// The items by name path.
- public string ItemsByNamePath { get; set; }
-
- ///
- /// Gets or sets the cache path.
- ///
- /// The cache path.
- public string CachePath { get; set; }
-
- ///
- /// Gets or sets the log path.
- ///
- /// The log path.
- public string LogPath { get; set; }
-
- ///
- /// Gets or sets the internal metadata path.
- ///
- /// The internal metadata path.
- public string InternalMetadataPath { get; set; }
-
- ///
- /// Gets or sets the transcode path.
- ///
- /// The transcode path.
- public string TranscodingTempPath { get; set; }
-
- ///
- /// Gets or sets the list of cast receiver applications.
- ///
- public IReadOnlyList CastReceiverApplications { get; set; }
-
- ///
- /// Gets or sets a value indicating whether this instance has update available.
- ///
- /// true if this instance has update available; otherwise, false.
- [Obsolete("This should be handled by the package manager")]
- [DefaultValue(false)]
- public bool HasUpdateAvailable { get; set; }
-
- [Obsolete("This isn't set correctly anymore")]
- [DefaultValue("System")]
- public string EncoderLocation { get; set; } = "System";
-
- [Obsolete("This is no longer set")]
- [DefaultValue("X64")]
- public string SystemArchitecture { get; set; } = "X64";
+ CompletedInstallations = Array.Empty();
}
+
+ ///
+ /// Gets or sets the display name of the operating system.
+ ///
+ /// The display name of the operating system.
+ [Obsolete("This is no longer set")]
+ public string OperatingSystemDisplayName { get; set; } = string.Empty;
+
+ ///
+ /// Gets or sets the package name.
+ ///
+ /// The value of the '-package' command line argument.
+ public string PackageName { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether this instance has pending restart.
+ ///
+ /// true if this instance has pending restart; otherwise, false.
+ public bool HasPendingRestart { get; set; }
+
+ public bool IsShuttingDown { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether [supports library monitor].
+ ///
+ /// true if [supports library monitor]; otherwise, false.
+ public bool SupportsLibraryMonitor { get; set; }
+
+ ///
+ /// Gets or sets the web socket port number.
+ ///
+ /// The web socket port number.
+ public int WebSocketPortNumber { get; set; }
+
+ ///
+ /// Gets or sets the completed installations.
+ ///
+ /// The completed installations.
+ public InstallationInfo[] CompletedInstallations { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether this instance can self restart.
+ ///
+ /// true.
+ [Obsolete("This is always true")]
+ [DefaultValue(true)]
+ public bool CanSelfRestart { get; set; } = true;
+
+ [Obsolete("This is always false")]
+ [DefaultValue(false)]
+ public bool CanLaunchWebBrowser { get; set; } = false;
+
+ ///
+ /// Gets or sets the program data path.
+ ///
+ /// The program data path.
+ [Obsolete("Use the newer SystemStorageDto instead")]
+ public string ProgramDataPath { get; set; }
+
+ ///
+ /// Gets or sets the web UI resources path.
+ ///
+ /// The web UI resources path.
+ [Obsolete("Use the newer SystemStorageDto instead")]
+ public string WebPath { get; set; }
+
+ ///
+ /// Gets or sets the items by name path.
+ ///
+ /// The items by name path.
+ [Obsolete("Use the newer SystemStorageDto instead")]
+ public string ItemsByNamePath { get; set; }
+
+ ///
+ /// Gets or sets the cache path.
+ ///
+ /// The cache path.
+ [Obsolete("Use the newer SystemStorageDto instead")]
+ public string CachePath { get; set; }
+
+ ///
+ /// Gets or sets the log path.
+ ///
+ /// The log path.
+ [Obsolete("Use the newer SystemStorageDto instead")]
+ public string LogPath { get; set; }
+
+ ///
+ /// Gets or sets the internal metadata path.
+ ///
+ /// The internal metadata path.
+ [Obsolete("Use the newer SystemStorageDto instead")]
+ public string InternalMetadataPath { get; set; }
+
+ ///
+ /// Gets or sets the transcode path.
+ ///
+ /// The transcode path.
+ [Obsolete("Use the newer SystemStorageDto instead")]
+ public string TranscodingTempPath { get; set; }
+
+ ///
+ /// Gets or sets the list of cast receiver applications.
+ ///
+ public IReadOnlyList CastReceiverApplications { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether this instance has update available.
+ ///
+ /// true if this instance has update available; otherwise, false.
+ [Obsolete("This should be handled by the package manager")]
+ [DefaultValue(false)]
+ public bool HasUpdateAvailable { get; set; }
+
+ [Obsolete("This isn't set correctly anymore")]
+ [DefaultValue("System")]
+ public string EncoderLocation { get; set; } = "System";
+
+ [Obsolete("This is no longer set")]
+ [DefaultValue("X64")]
+ public string SystemArchitecture { get; set; } = "X64";
}
diff --git a/MediaBrowser.Model/System/SystemStorageInfo.cs b/MediaBrowser.Model/System/SystemStorageInfo.cs
new file mode 100644
index 0000000000..42e7a37e02
--- /dev/null
+++ b/MediaBrowser.Model/System/SystemStorageInfo.cs
@@ -0,0 +1,56 @@
+using System.Collections.Generic;
+
+namespace MediaBrowser.Model.System;
+
+///
+/// Contains informations about the systems storage.
+///
+public class SystemStorageInfo
+{
+ ///
+ /// Gets or sets the program data path.
+ ///
+ /// The program data path.
+ public required FolderStorageInfo ProgramDataFolder { get; set; }
+
+ ///
+ /// Gets or sets the web UI resources path.
+ ///
+ /// The web UI resources path.
+ public required FolderStorageInfo WebFolder { get; set; }
+
+ ///
+ /// Gets or sets the items by name path.
+ ///
+ /// The items by name path.
+ public required FolderStorageInfo ImageCacheFolder { get; set; }
+
+ ///
+ /// Gets or sets the cache path.
+ ///
+ /// The cache path.
+ public required FolderStorageInfo CacheFolder { get; set; }
+
+ ///
+ /// Gets or sets the log path.
+ ///
+ /// The log path.
+ public required FolderStorageInfo LogFolder { get; set; }
+
+ ///
+ /// Gets or sets the internal metadata path.
+ ///
+ /// The internal metadata path.
+ public required FolderStorageInfo InternalMetadataFolder { get; set; }
+
+ ///
+ /// Gets or sets the transcode path.
+ ///
+ /// The transcode path.
+ public required FolderStorageInfo TranscodingTempFolder { get; set; }
+
+ ///
+ /// Gets or sets the storage informations of all libraries.
+ ///
+ public required IReadOnlyCollection Libraries { get; set; }
+}