diff options
| -rw-r--r-- | Emby.Server.Implementations/SystemManager.cs | 34 | ||||
| -rw-r--r-- | Jellyfin.Api/Controllers/SystemController.cs | 14 | ||||
| -rw-r--r-- | Jellyfin.Api/Models/SystemInfoDtos/FolderStorageDto.cs | 46 | ||||
| -rw-r--r-- | Jellyfin.Api/Models/SystemInfoDtos/LibraryStorageDto.cs | 37 | ||||
| -rw-r--r-- | Jellyfin.Api/Models/SystemInfoDtos/SystemStorageDto.cs | 67 | ||||
| -rw-r--r-- | Jellyfin.Server.Implementations/StorageHelpers/StorageHelper.cs | 109 | ||||
| -rw-r--r-- | Jellyfin.Server/Program.cs | 4 | ||||
| -rw-r--r-- | MediaBrowser.Controller/ISystemManager.cs | 7 | ||||
| -rw-r--r-- | MediaBrowser.Model/System/FolderStorageInfo.cs | 32 | ||||
| -rw-r--r-- | MediaBrowser.Model/System/LibraryStorageInfo.cs | 25 | ||||
| -rw-r--r-- | MediaBrowser.Model/System/SystemInfo.cs | 254 | ||||
| -rw-r--r-- | MediaBrowser.Model/System/SystemStorageInfo.cs | 56 |
12 files changed, 560 insertions, 125 deletions
diff --git a/Emby.Server.Implementations/SystemManager.cs b/Emby.Server.Implementations/SystemManager.cs index 5936df7f1..92b59b23c 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; /// <summary> /// Initializes a new instance of the <see cref="SystemManager"/> class. @@ -29,13 +33,15 @@ public class SystemManager : ISystemManager /// <param name="configurationManager">Instance of <see cref="IServerConfigurationManager"/>.</param> /// <param name="startupOptions">Instance of <see cref="IStartupOptions"/>.</param> /// <param name="installationManager">Instance of <see cref="IInstallationManager"/>.</param> + /// <param name="libraryManager">Instance of <see cref="ILibraryManager"/>.</param> 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; } /// <inheritdoc /> @@ -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 }; } + /// <inheritdoc/> + 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() + }; + } + /// <inheritdoc /> public PublicSystemInfo GetPublicSystemInfo(HttpRequest request) { diff --git a/Jellyfin.Api/Controllers/SystemController.cs b/Jellyfin.Api/Controllers/SystemController.cs index 0ee11c070..07a1f7650 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; @@ -72,6 +73,19 @@ public class SystemController : BaseJellyfinApiController => _systemManager.GetSystemInfo(Request); /// <summary> + /// Gets information about the server. + /// </summary> + /// <response code="200">Information retrieved.</response> + /// <response code="403">User does not have permission to retrieve information.</response> + /// <returns>A <see cref="SystemInfo"/> with info about the system.</returns> + [HttpGet("Info/Storage")] + [Authorize(Policy = Policies.RequiresElevation)] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + public ActionResult<SystemStorageDto> GetSystemStorage() + => Ok(SystemStorageDto.FromSystemStorageInfo(_systemManager.GetSystemStorageInfo())); + + /// <summary> /// Gets public information about the server. /// </summary> /// <response code="200">Information retrieved.</response> diff --git a/Jellyfin.Api/Models/SystemInfoDtos/FolderStorageDto.cs b/Jellyfin.Api/Models/SystemInfoDtos/FolderStorageDto.cs new file mode 100644 index 000000000..00a965898 --- /dev/null +++ b/Jellyfin.Api/Models/SystemInfoDtos/FolderStorageDto.cs @@ -0,0 +1,46 @@ +using MediaBrowser.Model.System; + +namespace Jellyfin.Api.Models.SystemInfoDtos; + +/// <summary> +/// Contains information about a specific folder. +/// </summary> +public record FolderStorageDto +{ + /// <summary> + /// Gets the path of the folder in question. + /// </summary> + public required string Path { get; init; } + + /// <summary> + /// Gets the free space of the underlying storage device of the <see cref="Path"/>. + /// </summary> + public long FreeSpace { get; init; } + + /// <summary> + /// Gets the used space of the underlying storage device of the <see cref="Path"/>. + /// </summary> + public long UsedSpace { get; init; } + + /// <summary> + /// Gets the kind of storage device of the <see cref="Path"/>. + /// </summary> + public string? StorageType { get; init; } + + /// <summary> + /// Gets the Device Identifier. + /// </summary> + 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 000000000..c138324d2 --- /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; + +/// <summary> +/// Contains informations about a libraries storage informations. +/// </summary> +public record LibraryStorageDto +{ + /// <summary> + /// Gets or sets the Library Id. + /// </summary> + public required Guid Id { get; set; } + + /// <summary> + /// Gets or sets the name of the library. + /// </summary> + public required string Name { get; set; } + + /// <summary> + /// Gets or sets the storage informations about the folders used in a library. + /// </summary> + public required IReadOnlyCollection<FolderStorageDto> 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 000000000..a09042439 --- /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; + +/// <summary> +/// Contains informations about the systems storage. +/// </summary> +public record SystemStorageDto +{ + /// <summary> + /// Gets or sets the Storage information of the program data folder. + /// </summary> + public required FolderStorageDto ProgramDataFolder { get; set; } + + /// <summary> + /// Gets or sets the Storage information of the web UI resources folder. + /// </summary> + public required FolderStorageDto WebFolder { get; set; } + + /// <summary> + /// Gets or sets the Storage information of the folder where images are cached. + /// </summary> + public required FolderStorageDto ImageCacheFolder { get; set; } + + /// <summary> + /// Gets or sets the Storage information of the cache folder. + /// </summary> + public required FolderStorageDto CacheFolder { get; set; } + + /// <summary> + /// Gets or sets the Storage information of the folder where logfiles are saved to. + /// </summary> + public required FolderStorageDto LogFolder { get; set; } + + /// <summary> + /// Gets or sets the Storage information of the folder where metadata is stored. + /// </summary> + public required FolderStorageDto InternalMetadataFolder { get; set; } + + /// <summary> + /// Gets or sets the Storage information of the transcoding cache. + /// </summary> + public required FolderStorageDto TranscodingTempFolder { get; set; } + + /// <summary> + /// Gets or sets the storage informations of all libraries. + /// </summary> + public required IReadOnlyCollection<LibraryStorageDto> 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 000000000..635644179 --- /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; + +/// <summary> +/// Contains methods to help with checking for storage and returning storage data for jellyfin folders. +/// </summary> +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"]; + + /// <summary> + /// Tests the available storage capacity on the jellyfin paths with estimated minimum values. + /// </summary> + /// <param name="applicationPaths">The application paths.</param> + /// <param name="logger">Logger.</param> + 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); + } + + /// <summary> + /// Gets the free space of a specific directory. + /// </summary> + /// <param name="path">Path to a folder.</param> + /// <returns>The number of bytes available space.</returns> + 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 + }; + } + } + + /// <summary> + /// Gets the underlying drive data from a given path and checks if the available storage capacity matches the threshold. + /// </summary> + /// <param name="path">The path to a folder to evaluate.</param> + /// <param name="logger">The logger.</param> + /// <param name="threshold">The threshold to check for or -1 to just log the data.</param> + /// <exception cref="InvalidOperationException">Thrown when the threshold is not available on the underlying storage.</exception> + 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)); + } + + /// <summary> + /// Formats a size in bytes into a common human readable form. + /// </summary> + /// <remarks> + /// Taken and slightly modified from https://stackoverflow.com/a/4975942/1786007 . + /// </remarks> + /// <param name="byteCount">The size in bytes.</param> + /// <returns>A human readable approximate representation of the argument.</returns> + 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 55a4a0087..8d0bf73f6 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<Startup>()); + StartupHelpers.PerformStaticInitialization(); await Migrations.MigrationRunner.RunPreStartup(appPaths, _loggerFactory).ConfigureAwait(false); diff --git a/MediaBrowser.Controller/ISystemManager.cs b/MediaBrowser.Controller/ISystemManager.cs index ef3034d2f..08344a1e5 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. /// </summary> void Shutdown(); + + /// <summary> + /// Gets the systems storage resources. + /// </summary> + /// <returns>The <see cref="SystemStorageInfo"/>.</returns> + SystemStorageInfo GetSystemStorageInfo(); } diff --git a/MediaBrowser.Model/System/FolderStorageInfo.cs b/MediaBrowser.Model/System/FolderStorageInfo.cs new file mode 100644 index 000000000..7b10e4ea5 --- /dev/null +++ b/MediaBrowser.Model/System/FolderStorageInfo.cs @@ -0,0 +1,32 @@ +namespace MediaBrowser.Model.System; + +/// <summary> +/// Contains information about a specific folder. +/// </summary> +public record FolderStorageInfo +{ + /// <summary> + /// Gets the path of the folder in question. + /// </summary> + public required string Path { get; init; } + + /// <summary> + /// Gets the free space of the underlying storage device of the <see cref="Path"/>. + /// </summary> + public long FreeSpace { get; init; } + + /// <summary> + /// Gets the used space of the underlying storage device of the <see cref="Path"/>. + /// </summary> + public long UsedSpace { get; init; } + + /// <summary> + /// Gets the kind of storage device of the <see cref="Path"/>. + /// </summary> + public string? StorageType { get; init; } + + /// <summary> + /// Gets the Device Identifier. + /// </summary> + public string? DeviceId { get; init; } +} diff --git a/MediaBrowser.Model/System/LibraryStorageInfo.cs b/MediaBrowser.Model/System/LibraryStorageInfo.cs new file mode 100644 index 000000000..d4111b29c --- /dev/null +++ b/MediaBrowser.Model/System/LibraryStorageInfo.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; + +namespace MediaBrowser.Model.System; + +/// <summary> +/// Contains informations about a libraries storage informations. +/// </summary> +public class LibraryStorageInfo +{ + /// <summary> + /// Gets or sets the Library Id. + /// </summary> + public required Guid Id { get; set; } + + /// <summary> + /// Gets or sets the name of the library. + /// </summary> + public required string Name { get; set; } + + /// <summary> + /// Gets or sets the storage informations about the folders used in a library. + /// </summary> + public required IReadOnlyCollection<FolderStorageInfo> Folders { get; set; } +} diff --git a/MediaBrowser.Model/System/SystemInfo.cs b/MediaBrowser.Model/System/SystemInfo.cs index f37ac6a14..232a2a6bc 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; + +/// <summary> +/// Class SystemInfo. +/// </summary> +public class SystemInfo : PublicSystemInfo { /// <summary> - /// Class SystemInfo. + /// Initializes a new instance of the <see cref="SystemInfo" /> class. /// </summary> - public class SystemInfo : PublicSystemInfo + public SystemInfo() { - /// <summary> - /// Initializes a new instance of the <see cref="SystemInfo" /> class. - /// </summary> - public SystemInfo() - { - CompletedInstallations = Array.Empty<InstallationInfo>(); - } - - /// <summary> - /// Gets or sets the display name of the operating system. - /// </summary> - /// <value>The display name of the operating system.</value> - [Obsolete("This is no longer set")] - public string OperatingSystemDisplayName { get; set; } = string.Empty; - - /// <summary> - /// Gets or sets the package name. - /// </summary> - /// <value>The value of the '-package' command line argument.</value> - public string PackageName { get; set; } - - /// <summary> - /// Gets or sets a value indicating whether this instance has pending restart. - /// </summary> - /// <value><c>true</c> if this instance has pending restart; otherwise, <c>false</c>.</value> - public bool HasPendingRestart { get; set; } - - public bool IsShuttingDown { get; set; } - - /// <summary> - /// Gets or sets a value indicating whether [supports library monitor]. - /// </summary> - /// <value><c>true</c> if [supports library monitor]; otherwise, <c>false</c>.</value> - public bool SupportsLibraryMonitor { get; set; } - - /// <summary> - /// Gets or sets the web socket port number. - /// </summary> - /// <value>The web socket port number.</value> - public int WebSocketPortNumber { get; set; } - - /// <summary> - /// Gets or sets the completed installations. - /// </summary> - /// <value>The completed installations.</value> - public InstallationInfo[] CompletedInstallations { get; set; } - - /// <summary> - /// Gets or sets a value indicating whether this instance can self restart. - /// </summary> - /// <value><c>true</c>.</value> - [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; - - /// <summary> - /// Gets or sets the program data path. - /// </summary> - /// <value>The program data path.</value> - public string ProgramDataPath { get; set; } - - /// <summary> - /// Gets or sets the web UI resources path. - /// </summary> - /// <value>The web UI resources path.</value> - public string WebPath { get; set; } - - /// <summary> - /// Gets or sets the items by name path. - /// </summary> - /// <value>The items by name path.</value> - public string ItemsByNamePath { get; set; } - - /// <summary> - /// Gets or sets the cache path. - /// </summary> - /// <value>The cache path.</value> - public string CachePath { get; set; } - - /// <summary> - /// Gets or sets the log path. - /// </summary> - /// <value>The log path.</value> - public string LogPath { get; set; } - - /// <summary> - /// Gets or sets the internal metadata path. - /// </summary> - /// <value>The internal metadata path.</value> - public string InternalMetadataPath { get; set; } - - /// <summary> - /// Gets or sets the transcode path. - /// </summary> - /// <value>The transcode path.</value> - public string TranscodingTempPath { get; set; } - - /// <summary> - /// Gets or sets the list of cast receiver applications. - /// </summary> - public IReadOnlyList<CastReceiverApplication> CastReceiverApplications { get; set; } - - /// <summary> - /// Gets or sets a value indicating whether this instance has update available. - /// </summary> - /// <value><c>true</c> if this instance has update available; otherwise, <c>false</c>.</value> - [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<InstallationInfo>(); } + + /// <summary> + /// Gets or sets the display name of the operating system. + /// </summary> + /// <value>The display name of the operating system.</value> + [Obsolete("This is no longer set")] + public string OperatingSystemDisplayName { get; set; } = string.Empty; + + /// <summary> + /// Gets or sets the package name. + /// </summary> + /// <value>The value of the '-package' command line argument.</value> + public string PackageName { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance has pending restart. + /// </summary> + /// <value><c>true</c> if this instance has pending restart; otherwise, <c>false</c>.</value> + public bool HasPendingRestart { get; set; } + + public bool IsShuttingDown { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether [supports library monitor]. + /// </summary> + /// <value><c>true</c> if [supports library monitor]; otherwise, <c>false</c>.</value> + public bool SupportsLibraryMonitor { get; set; } + + /// <summary> + /// Gets or sets the web socket port number. + /// </summary> + /// <value>The web socket port number.</value> + public int WebSocketPortNumber { get; set; } + + /// <summary> + /// Gets or sets the completed installations. + /// </summary> + /// <value>The completed installations.</value> + public InstallationInfo[] CompletedInstallations { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance can self restart. + /// </summary> + /// <value><c>true</c>.</value> + [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; + + /// <summary> + /// Gets or sets the program data path. + /// </summary> + /// <value>The program data path.</value> + [Obsolete("Use the newer SystemStorageDto instead")] + public string ProgramDataPath { get; set; } + + /// <summary> + /// Gets or sets the web UI resources path. + /// </summary> + /// <value>The web UI resources path.</value> + [Obsolete("Use the newer SystemStorageDto instead")] + public string WebPath { get; set; } + + /// <summary> + /// Gets or sets the items by name path. + /// </summary> + /// <value>The items by name path.</value> + [Obsolete("Use the newer SystemStorageDto instead")] + public string ItemsByNamePath { get; set; } + + /// <summary> + /// Gets or sets the cache path. + /// </summary> + /// <value>The cache path.</value> + [Obsolete("Use the newer SystemStorageDto instead")] + public string CachePath { get; set; } + + /// <summary> + /// Gets or sets the log path. + /// </summary> + /// <value>The log path.</value> + [Obsolete("Use the newer SystemStorageDto instead")] + public string LogPath { get; set; } + + /// <summary> + /// Gets or sets the internal metadata path. + /// </summary> + /// <value>The internal metadata path.</value> + [Obsolete("Use the newer SystemStorageDto instead")] + public string InternalMetadataPath { get; set; } + + /// <summary> + /// Gets or sets the transcode path. + /// </summary> + /// <value>The transcode path.</value> + [Obsolete("Use the newer SystemStorageDto instead")] + public string TranscodingTempPath { get; set; } + + /// <summary> + /// Gets or sets the list of cast receiver applications. + /// </summary> + public IReadOnlyList<CastReceiverApplication> CastReceiverApplications { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance has update available. + /// </summary> + /// <value><c>true</c> if this instance has update available; otherwise, <c>false</c>.</value> + [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 000000000..42e7a37e0 --- /dev/null +++ b/MediaBrowser.Model/System/SystemStorageInfo.cs @@ -0,0 +1,56 @@ +using System.Collections.Generic; + +namespace MediaBrowser.Model.System; + +/// <summary> +/// Contains informations about the systems storage. +/// </summary> +public class SystemStorageInfo +{ + /// <summary> + /// Gets or sets the program data path. + /// </summary> + /// <value>The program data path.</value> + public required FolderStorageInfo ProgramDataFolder { get; set; } + + /// <summary> + /// Gets or sets the web UI resources path. + /// </summary> + /// <value>The web UI resources path.</value> + public required FolderStorageInfo WebFolder { get; set; } + + /// <summary> + /// Gets or sets the items by name path. + /// </summary> + /// <value>The items by name path.</value> + public required FolderStorageInfo ImageCacheFolder { get; set; } + + /// <summary> + /// Gets or sets the cache path. + /// </summary> + /// <value>The cache path.</value> + public required FolderStorageInfo CacheFolder { get; set; } + + /// <summary> + /// Gets or sets the log path. + /// </summary> + /// <value>The log path.</value> + public required FolderStorageInfo LogFolder { get; set; } + + /// <summary> + /// Gets or sets the internal metadata path. + /// </summary> + /// <value>The internal metadata path.</value> + public required FolderStorageInfo InternalMetadataFolder { get; set; } + + /// <summary> + /// Gets or sets the transcode path. + /// </summary> + /// <value>The transcode path.</value> + public required FolderStorageInfo TranscodingTempFolder { get; set; } + + /// <summary> + /// Gets or sets the storage informations of all libraries. + /// </summary> + public required IReadOnlyCollection<LibraryStorageInfo> Libraries { get; set; } +} |
