mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-12-16 22:13:06 +03:00
Migrate to file-scoped namespaces
This commit is contained in:
@@ -20,204 +20,203 @@ using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Jellyfin.Api.Controllers
|
||||
namespace Jellyfin.Api.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// The system controller.
|
||||
/// </summary>
|
||||
public class SystemController : BaseJellyfinApiController
|
||||
{
|
||||
private readonly IServerApplicationHost _appHost;
|
||||
private readonly IApplicationPaths _appPaths;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly INetworkManager _network;
|
||||
private readonly ILogger<SystemController> _logger;
|
||||
|
||||
/// <summary>
|
||||
/// The system controller.
|
||||
/// Initializes a new instance of the <see cref="SystemController"/> class.
|
||||
/// </summary>
|
||||
public class SystemController : BaseJellyfinApiController
|
||||
/// <param name="serverConfigurationManager">Instance of <see cref="IServerConfigurationManager"/> interface.</param>
|
||||
/// <param name="appHost">Instance of <see cref="IServerApplicationHost"/> interface.</param>
|
||||
/// <param name="fileSystem">Instance of <see cref="IFileSystem"/> interface.</param>
|
||||
/// <param name="network">Instance of <see cref="INetworkManager"/> interface.</param>
|
||||
/// <param name="logger">Instance of <see cref="ILogger{SystemController}"/> interface.</param>
|
||||
public SystemController(
|
||||
IServerConfigurationManager serverConfigurationManager,
|
||||
IServerApplicationHost appHost,
|
||||
IFileSystem fileSystem,
|
||||
INetworkManager network,
|
||||
ILogger<SystemController> logger)
|
||||
{
|
||||
private readonly IServerApplicationHost _appHost;
|
||||
private readonly IApplicationPaths _appPaths;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly INetworkManager _network;
|
||||
private readonly ILogger<SystemController> _logger;
|
||||
_appPaths = serverConfigurationManager.ApplicationPaths;
|
||||
_appHost = appHost;
|
||||
_fileSystem = fileSystem;
|
||||
_network = network;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SystemController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="serverConfigurationManager">Instance of <see cref="IServerConfigurationManager"/> interface.</param>
|
||||
/// <param name="appHost">Instance of <see cref="IServerApplicationHost"/> interface.</param>
|
||||
/// <param name="fileSystem">Instance of <see cref="IFileSystem"/> interface.</param>
|
||||
/// <param name="network">Instance of <see cref="INetworkManager"/> interface.</param>
|
||||
/// <param name="logger">Instance of <see cref="ILogger{SystemController}"/> interface.</param>
|
||||
public SystemController(
|
||||
IServerConfigurationManager serverConfigurationManager,
|
||||
IServerApplicationHost appHost,
|
||||
IFileSystem fileSystem,
|
||||
INetworkManager network,
|
||||
ILogger<SystemController> logger)
|
||||
/// <summary>
|
||||
/// Gets information about the server.
|
||||
/// </summary>
|
||||
/// <response code="200">Information retrieved.</response>
|
||||
/// <returns>A <see cref="SystemInfo"/> with info about the system.</returns>
|
||||
[HttpGet("Info")]
|
||||
[Authorize(Policy = Policies.FirstTimeSetupOrIgnoreParentalControl)]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public ActionResult<SystemInfo> GetSystemInfo()
|
||||
{
|
||||
return _appHost.GetSystemInfo(Request);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets public information about the server.
|
||||
/// </summary>
|
||||
/// <response code="200">Information retrieved.</response>
|
||||
/// <returns>A <see cref="PublicSystemInfo"/> with public info about the system.</returns>
|
||||
[HttpGet("Info/Public")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public ActionResult<PublicSystemInfo> GetPublicSystemInfo()
|
||||
{
|
||||
return _appHost.GetPublicSystemInfo(Request);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pings the system.
|
||||
/// </summary>
|
||||
/// <response code="200">Information retrieved.</response>
|
||||
/// <returns>The server name.</returns>
|
||||
[HttpGet("Ping", Name = "GetPingSystem")]
|
||||
[HttpPost("Ping", Name = "PostPingSystem")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public ActionResult<string> PingSystem()
|
||||
{
|
||||
return _appHost.Name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restarts the application.
|
||||
/// </summary>
|
||||
/// <response code="204">Server restarted.</response>
|
||||
/// <returns>No content. Server restarted.</returns>
|
||||
[HttpPost("Restart")]
|
||||
[Authorize(Policy = Policies.LocalAccessOrRequiresElevation)]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public ActionResult RestartApplication()
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
_appPaths = serverConfigurationManager.ApplicationPaths;
|
||||
_appHost = appHost;
|
||||
_fileSystem = fileSystem;
|
||||
_network = network;
|
||||
_logger = logger;
|
||||
await Task.Delay(100).ConfigureAwait(false);
|
||||
_appHost.Restart();
|
||||
});
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shuts down the application.
|
||||
/// </summary>
|
||||
/// <response code="204">Server shut down.</response>
|
||||
/// <returns>No content. Server shut down.</returns>
|
||||
[HttpPost("Shutdown")]
|
||||
[Authorize(Policy = Policies.RequiresElevation)]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public ActionResult ShutdownApplication()
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(100).ConfigureAwait(false);
|
||||
await _appHost.Shutdown().ConfigureAwait(false);
|
||||
});
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of available server log files.
|
||||
/// </summary>
|
||||
/// <response code="200">Information retrieved.</response>
|
||||
/// <returns>An array of <see cref="LogFile"/> with the available log files.</returns>
|
||||
[HttpGet("Logs")]
|
||||
[Authorize(Policy = Policies.RequiresElevation)]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public ActionResult<LogFile[]> GetServerLogs()
|
||||
{
|
||||
IEnumerable<FileSystemMetadata> files;
|
||||
|
||||
try
|
||||
{
|
||||
files = _fileSystem.GetFiles(_appPaths.LogDirectoryPath, new[] { ".txt", ".log" }, true, false);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error getting logs");
|
||||
files = Enumerable.Empty<FileSystemMetadata>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets information about the server.
|
||||
/// </summary>
|
||||
/// <response code="200">Information retrieved.</response>
|
||||
/// <returns>A <see cref="SystemInfo"/> with info about the system.</returns>
|
||||
[HttpGet("Info")]
|
||||
[Authorize(Policy = Policies.FirstTimeSetupOrIgnoreParentalControl)]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public ActionResult<SystemInfo> GetSystemInfo()
|
||||
var result = files.Select(i => new LogFile
|
||||
{
|
||||
return _appHost.GetSystemInfo(Request);
|
||||
}
|
||||
DateCreated = _fileSystem.GetCreationTimeUtc(i),
|
||||
DateModified = _fileSystem.GetLastWriteTimeUtc(i),
|
||||
Name = i.Name,
|
||||
Size = i.Length
|
||||
})
|
||||
.OrderByDescending(i => i.DateModified)
|
||||
.ThenByDescending(i => i.DateCreated)
|
||||
.ThenBy(i => i.Name)
|
||||
.ToArray();
|
||||
|
||||
/// <summary>
|
||||
/// Gets public information about the server.
|
||||
/// </summary>
|
||||
/// <response code="200">Information retrieved.</response>
|
||||
/// <returns>A <see cref="PublicSystemInfo"/> with public info about the system.</returns>
|
||||
[HttpGet("Info/Public")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public ActionResult<PublicSystemInfo> GetPublicSystemInfo()
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets information about the request endpoint.
|
||||
/// </summary>
|
||||
/// <response code="200">Information retrieved.</response>
|
||||
/// <returns><see cref="EndPointInfo"/> with information about the endpoint.</returns>
|
||||
[HttpGet("Endpoint")]
|
||||
[Authorize(Policy = Policies.DefaultAuthorization)]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public ActionResult<EndPointInfo> GetEndpointInfo()
|
||||
{
|
||||
return new EndPointInfo
|
||||
{
|
||||
return _appHost.GetPublicSystemInfo(Request);
|
||||
}
|
||||
IsLocal = HttpContext.IsLocal(),
|
||||
IsInNetwork = _network.IsInLocalNetwork(HttpContext.GetNormalizedRemoteIp())
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pings the system.
|
||||
/// </summary>
|
||||
/// <response code="200">Information retrieved.</response>
|
||||
/// <returns>The server name.</returns>
|
||||
[HttpGet("Ping", Name = "GetPingSystem")]
|
||||
[HttpPost("Ping", Name = "PostPingSystem")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public ActionResult<string> PingSystem()
|
||||
{
|
||||
return _appHost.Name;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets a log file.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the log file to get.</param>
|
||||
/// <response code="200">Log file retrieved.</response>
|
||||
/// <returns>The log file.</returns>
|
||||
[HttpGet("Logs/Log")]
|
||||
[Authorize(Policy = Policies.RequiresElevation)]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesFile(MediaTypeNames.Text.Plain)]
|
||||
public ActionResult GetLogFile([FromQuery, Required] string name)
|
||||
{
|
||||
var file = _fileSystem.GetFiles(_appPaths.LogDirectoryPath)
|
||||
.First(i => string.Equals(i.Name, name, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
/// <summary>
|
||||
/// Restarts the application.
|
||||
/// </summary>
|
||||
/// <response code="204">Server restarted.</response>
|
||||
/// <returns>No content. Server restarted.</returns>
|
||||
[HttpPost("Restart")]
|
||||
[Authorize(Policy = Policies.LocalAccessOrRequiresElevation)]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public ActionResult RestartApplication()
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(100).ConfigureAwait(false);
|
||||
_appHost.Restart();
|
||||
});
|
||||
return NoContent();
|
||||
}
|
||||
// For older files, assume fully static
|
||||
var fileShare = file.LastWriteTimeUtc < DateTime.UtcNow.AddHours(-1) ? FileShare.Read : FileShare.ReadWrite;
|
||||
FileStream stream = new FileStream(file.FullName, FileMode.Open, FileAccess.Read, fileShare, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous);
|
||||
return File(stream, "text/plain; charset=utf-8");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shuts down the application.
|
||||
/// </summary>
|
||||
/// <response code="204">Server shut down.</response>
|
||||
/// <returns>No content. Server shut down.</returns>
|
||||
[HttpPost("Shutdown")]
|
||||
[Authorize(Policy = Policies.RequiresElevation)]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public ActionResult ShutdownApplication()
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(100).ConfigureAwait(false);
|
||||
await _appHost.Shutdown().ConfigureAwait(false);
|
||||
});
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of available server log files.
|
||||
/// </summary>
|
||||
/// <response code="200">Information retrieved.</response>
|
||||
/// <returns>An array of <see cref="LogFile"/> with the available log files.</returns>
|
||||
[HttpGet("Logs")]
|
||||
[Authorize(Policy = Policies.RequiresElevation)]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public ActionResult<LogFile[]> GetServerLogs()
|
||||
{
|
||||
IEnumerable<FileSystemMetadata> files;
|
||||
|
||||
try
|
||||
{
|
||||
files = _fileSystem.GetFiles(_appPaths.LogDirectoryPath, new[] { ".txt", ".log" }, true, false);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error getting logs");
|
||||
files = Enumerable.Empty<FileSystemMetadata>();
|
||||
}
|
||||
|
||||
var result = files.Select(i => new LogFile
|
||||
{
|
||||
DateCreated = _fileSystem.GetCreationTimeUtc(i),
|
||||
DateModified = _fileSystem.GetLastWriteTimeUtc(i),
|
||||
Name = i.Name,
|
||||
Size = i.Length
|
||||
})
|
||||
.OrderByDescending(i => i.DateModified)
|
||||
.ThenByDescending(i => i.DateCreated)
|
||||
.ThenBy(i => i.Name)
|
||||
.ToArray();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets information about the request endpoint.
|
||||
/// </summary>
|
||||
/// <response code="200">Information retrieved.</response>
|
||||
/// <returns><see cref="EndPointInfo"/> with information about the endpoint.</returns>
|
||||
[HttpGet("Endpoint")]
|
||||
[Authorize(Policy = Policies.DefaultAuthorization)]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public ActionResult<EndPointInfo> GetEndpointInfo()
|
||||
{
|
||||
return new EndPointInfo
|
||||
{
|
||||
IsLocal = HttpContext.IsLocal(),
|
||||
IsInNetwork = _network.IsInLocalNetwork(HttpContext.GetNormalizedRemoteIp())
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a log file.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the log file to get.</param>
|
||||
/// <response code="200">Log file retrieved.</response>
|
||||
/// <returns>The log file.</returns>
|
||||
[HttpGet("Logs/Log")]
|
||||
[Authorize(Policy = Policies.RequiresElevation)]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesFile(MediaTypeNames.Text.Plain)]
|
||||
public ActionResult GetLogFile([FromQuery, Required] string name)
|
||||
{
|
||||
var file = _fileSystem.GetFiles(_appPaths.LogDirectoryPath)
|
||||
.First(i => string.Equals(i.Name, name, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
// For older files, assume fully static
|
||||
var fileShare = file.LastWriteTimeUtc < DateTime.UtcNow.AddHours(-1) ? FileShare.Read : FileShare.ReadWrite;
|
||||
FileStream stream = new FileStream(file.FullName, FileMode.Open, FileAccess.Read, fileShare, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous);
|
||||
return File(stream, "text/plain; charset=utf-8");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets wake on lan information.
|
||||
/// </summary>
|
||||
/// <response code="200">Information retrieved.</response>
|
||||
/// <returns>An <see cref="IEnumerable{WakeOnLanInfo}"/> with the WakeOnLan infos.</returns>
|
||||
[HttpGet("WakeOnLanInfo")]
|
||||
[Authorize(Policy = Policies.DefaultAuthorization)]
|
||||
[Obsolete("This endpoint is obsolete.")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public ActionResult<IEnumerable<WakeOnLanInfo>> GetWakeOnLanInfo()
|
||||
{
|
||||
var result = _network.GetMacAddresses()
|
||||
.Select(i => new WakeOnLanInfo(i));
|
||||
return Ok(result);
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets wake on lan information.
|
||||
/// </summary>
|
||||
/// <response code="200">Information retrieved.</response>
|
||||
/// <returns>An <see cref="IEnumerable{WakeOnLanInfo}"/> with the WakeOnLan infos.</returns>
|
||||
[HttpGet("WakeOnLanInfo")]
|
||||
[Authorize(Policy = Policies.DefaultAuthorization)]
|
||||
[Obsolete("This endpoint is obsolete.")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public ActionResult<IEnumerable<WakeOnLanInfo>> GetWakeOnLanInfo()
|
||||
{
|
||||
var result = _network.GetMacAddresses()
|
||||
.Select(i => new WakeOnLanInfo(i));
|
||||
return Ok(result);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user