diff --git a/src/Sonarr.Api.V5/Logs/LogFileController.cs b/src/Sonarr.Api.V5/Logs/LogFileController.cs new file mode 100644 index 000000000..036005962 --- /dev/null +++ b/src/Sonarr.Api.V5/Logs/LogFileController.cs @@ -0,0 +1,41 @@ +using NzbDrone.Common.Disk; +using NzbDrone.Common.EnvironmentInfo; +using NzbDrone.Common.Extensions; +using NzbDrone.Core.Configuration; +using Sonarr.Http; + +namespace Sonarr.Api.V5.Logs; + +[V5ApiController("log/file")] +public class LogFileController : LogFileControllerBase +{ + private readonly IAppFolderInfo _appFolderInfo; + private readonly IDiskProvider _diskProvider; + + public LogFileController(IAppFolderInfo appFolderInfo, + IDiskProvider diskProvider, + IConfigFileProvider configFileProvider) + : base(diskProvider, configFileProvider, "") + { + _appFolderInfo = appFolderInfo; + _diskProvider = diskProvider; + } + + protected override IEnumerable GetLogFiles() + { + return _diskProvider.GetFiles(_appFolderInfo.GetLogFolder(), false); + } + + protected override string GetLogFilePath(string filename) + { + return Path.Combine(_appFolderInfo.GetLogFolder(), filename); + } + + protected override string DownloadUrlRoot + { + get + { + return "logfile"; + } + } +} diff --git a/src/Sonarr.Api.V5/Logs/LogFileControllerBase.cs b/src/Sonarr.Api.V5/Logs/LogFileControllerBase.cs new file mode 100644 index 000000000..01fed3b7e --- /dev/null +++ b/src/Sonarr.Api.V5/Logs/LogFileControllerBase.cs @@ -0,0 +1,71 @@ +using Microsoft.AspNetCore.Mvc; +using NLog; +using NzbDrone.Common.Disk; +using NzbDrone.Core.Configuration; + +namespace Sonarr.Api.V5.Logs; + +public abstract class LogFileControllerBase : Controller +{ + protected const string LOGFILE_ROUTE = @"/(?[-.a-zA-Z0-9]+?\.txt)"; + protected string _resource; + + private readonly IDiskProvider _diskProvider; + private readonly IConfigFileProvider _configFileProvider; + + public LogFileControllerBase(IDiskProvider diskProvider, + IConfigFileProvider configFileProvider, + string resource) + { + _diskProvider = diskProvider; + _configFileProvider = configFileProvider; + _resource = resource; + } + + [HttpGet] + [Produces("application/json")] + public List GetLogFilesResponse() + { + var result = new List(); + + var files = GetLogFiles().ToList(); + + for (var i = 0; i < files.Count; i++) + { + var file = files[i]; + var filename = Path.GetFileName(file); + + result.Add(new LogFileResource + { + Id = i + 1, + Filename = filename, + LastWriteTime = _diskProvider.FileGetLastWrite(file), + ContentsUrl = string.Format("{0}/api/v1/{1}/{2}", _configFileProvider.UrlBase, _resource, filename), + DownloadUrl = string.Format("{0}/{1}/{2}", _configFileProvider.UrlBase, DownloadUrlRoot, filename) + }); + } + + return result.OrderByDescending(l => l.LastWriteTime).ToList(); + } + + [HttpGet(@"{filename:regex([[-.a-zA-Z0-9]]+?\.txt)}")] + [Produces("text/plain")] + public IActionResult GetLogFileResponse(string filename) + { + LogManager.Flush(); + + var filePath = GetLogFilePath(filename); + + if (!_diskProvider.FileExists(filePath)) + { + return NotFound(); + } + + return PhysicalFile(filePath, "text/plain"); + } + + protected abstract IEnumerable GetLogFiles(); + protected abstract string GetLogFilePath(string filename); + + protected abstract string DownloadUrlRoot { get; } +} diff --git a/src/Sonarr.Api.V5/Logs/LogFileResource.cs b/src/Sonarr.Api.V5/Logs/LogFileResource.cs new file mode 100644 index 000000000..301f659fc --- /dev/null +++ b/src/Sonarr.Api.V5/Logs/LogFileResource.cs @@ -0,0 +1,11 @@ +using Sonarr.Http.REST; + +namespace Sonarr.Api.V5.Logs; + +public class LogFileResource : RestResource +{ + public required string Filename { get; set; } + public required DateTime LastWriteTime { get; set; } + public required string ContentsUrl { get; set; } + public required string DownloadUrl { get; set; } +} diff --git a/src/Sonarr.Api.V5/Logs/UpdateLogFileController.cs b/src/Sonarr.Api.V5/Logs/UpdateLogFileController.cs new file mode 100644 index 000000000..9d5a9e63f --- /dev/null +++ b/src/Sonarr.Api.V5/Logs/UpdateLogFileController.cs @@ -0,0 +1,49 @@ +using System.Text.RegularExpressions; +using NzbDrone.Common.Disk; +using NzbDrone.Common.EnvironmentInfo; +using NzbDrone.Common.Extensions; +using NzbDrone.Core.Configuration; +using Sonarr.Http; + +namespace Sonarr.Api.V5.Logs; + +[V5ApiController("log/file/update")] +public class UpdateLogFileController : LogFileControllerBase +{ + private readonly IAppFolderInfo _appFolderInfo; + private readonly IDiskProvider _diskProvider; + + public UpdateLogFileController(IAppFolderInfo appFolderInfo, + IDiskProvider diskProvider, + IConfigFileProvider configFileProvider) + : base(diskProvider, configFileProvider, "update") + { + _appFolderInfo = appFolderInfo; + _diskProvider = diskProvider; + } + + protected override IEnumerable GetLogFiles() + { + if (!_diskProvider.FolderExists(_appFolderInfo.GetUpdateLogFolder())) + { + return Enumerable.Empty(); + } + + return _diskProvider.GetFiles(_appFolderInfo.GetUpdateLogFolder(), false) + .Where(f => Regex.IsMatch(Path.GetFileName(f), LOGFILE_ROUTE.TrimStart('/'), RegexOptions.IgnoreCase)) + .ToList(); + } + + protected override string GetLogFilePath(string filename) + { + return Path.Combine(_appFolderInfo.GetUpdateLogFolder(), filename); + } + + protected override string DownloadUrlRoot + { + get + { + return "updatelogfile"; + } + } +}