using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Net; using MediaBrowser.Common.Security; using MediaBrowser.Controller; using MediaBrowser.Controller.Net; using MediaBrowser.Model.IO; using MediaBrowser.Model.Net; using MediaBrowser.Model.Services; using MediaBrowser.Model.System; using Microsoft.Extensions.Logging; namespace MediaBrowser.Api.System { /// /// Class GetSystemInfo /// [Route("/System/Info", "GET", Summary = "Gets information about the server")] [Authenticated(EscapeParentalControl = true, AllowBeforeStartupWizard = true)] public class GetSystemInfo : IReturn { } [Route("/System/Info/Public", "GET", Summary = "Gets public information about the server")] public class GetPublicSystemInfo : IReturn { } [Route("/System/Ping", "POST")] [Route("/System/Ping", "GET")] public class PingSystem : IReturnVoid { } /// /// Class RestartApplication /// [Route("/System/Restart", "POST", Summary = "Restarts the application, if needed")] [Authenticated(Roles = "Admin", AllowLocal = true)] public class RestartApplication { } /// /// This is currently not authenticated because the uninstaller needs to be able to shutdown the server. /// [Route("/System/Shutdown", "POST", Summary = "Shuts down the application")] [Authenticated(Roles = "Admin", AllowLocal = true)] public class ShutdownApplication { } [Route("/System/Logs", "GET", Summary = "Gets a list of available server log files")] [Authenticated(Roles = "Admin")] public class GetServerLogs : IReturn { } [Route("/System/Endpoint", "GET", Summary = "Gets information about the request endpoint")] [Authenticated] public class GetEndpointInfo : IReturn { public string Endpoint { get; set; } } [Route("/System/Logs/Log", "GET", Summary = "Gets a log file")] [Authenticated(Roles = "Admin")] public class GetLogFile { [ApiMember(Name = "Name", Description = "The log file name.", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] public string Name { get; set; } } [Route("/System/WakeOnLanInfo", "GET", Summary = "Gets wake on lan information")] [Authenticated] public class GetWakeOnLanInfo : IReturn { } /// /// Class SystemInfoService /// public class SystemService : BaseApiService { /// /// The _app host /// private readonly IServerApplicationHost _appHost; private readonly IApplicationPaths _appPaths; private readonly IFileSystem _fileSystem; private readonly INetworkManager _network; /// /// Initializes a new instance of the class. /// /// The app host. /// The application paths. /// The file system. /// jsonSerializer public SystemService(IServerApplicationHost appHost, IApplicationPaths appPaths, IFileSystem fileSystem, INetworkManager network) { _appHost = appHost; _appPaths = appPaths; _fileSystem = fileSystem; _network = network; } public object Post(PingSystem request) { return _appHost.Name; } public object Get(GetWakeOnLanInfo request) { var result = _appHost.GetWakeOnLanInfo(); return ToOptimizedResult(result); } public object Get(GetServerLogs request) { IEnumerable files; try { files = _fileSystem.GetFiles(_appPaths.LogDirectoryPath, new[] { ".txt", ".log" }, true, false); } catch (IOException ex) { Logger.LogError(ex, "Error getting logs"); files = Enumerable.Empty(); } 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 ToOptimizedResult(result); } public Task Get(GetLogFile request) { var file = _fileSystem.GetFiles(_appPaths.LogDirectoryPath) .First(i => string.Equals(i.Name, request.Name, StringComparison.OrdinalIgnoreCase)); // For older files, assume fully static if (file.LastWriteTimeUtc < DateTime.UtcNow.AddHours(-1)) { return ResultFactory.GetStaticFileResult(Request, file.FullName, FileShareMode.Read); } return ResultFactory.GetStaticFileResult(Request, file.FullName, FileShareMode.ReadWrite); } /// /// Gets the specified request. /// /// The request. /// System.Object. public async Task Get(GetSystemInfo request) { var result = await _appHost.GetSystemInfo(CancellationToken.None).ConfigureAwait(false); return ToOptimizedResult(result); } public async Task Get(GetPublicSystemInfo request) { var result = await _appHost.GetPublicSystemInfo(CancellationToken.None).ConfigureAwait(false); return ToOptimizedResult(result); } /// /// Posts the specified request. /// /// The request. public void Post(RestartApplication request) { _appHost.Restart(); } /// /// Posts the specified request. /// /// The request. public void Post(ShutdownApplication request) { Task.Run(async () => { await Task.Delay(100).ConfigureAwait(false); await _appHost.Shutdown().ConfigureAwait(false); }); } public object Get(GetEndpointInfo request) { return ToOptimizedResult(new EndPointInfo { IsLocal = Request.IsLocal, IsInNetwork = _network.IsInLocalNetwork(request.Endpoint ?? Request.RemoteIp) }); } } }