using Common.Configuration; using Common.Configuration.Arr; using Common.Configuration.DownloadCleaner; using Common.Configuration.DownloadClient; using Common.Configuration.DTOs.Arr; using Common.Configuration.DTOs.ContentBlocker; using Common.Configuration.DTOs.DownloadClient; using Common.Configuration.DTOs.General; using Common.Configuration.DTOs.Notification; using Common.Configuration.General; using Common.Configuration.Notification; using Common.Configuration.QueueCleaner; using Infrastructure.Configuration; using Infrastructure.Logging; using Infrastructure.Models; using Infrastructure.Services.Interfaces; using Mapster; using Microsoft.AspNetCore.Mvc; namespace Executable.Controllers; [ApiController] [Route("api/[controller]")] public class ConfigurationController : ControllerBase { private readonly ILogger _logger; private readonly IConfigManager _configManager; private readonly IJobManagementService _jobManagementService; private readonly LoggingConfigManager _loggingConfigManager; public ConfigurationController( ILogger logger, IConfigManager configManager, IJobManagementService jobManagementService, LoggingConfigManager loggingConfigManager ) { _logger = logger; _configManager = configManager; _jobManagementService = jobManagementService; _loggingConfigManager = loggingConfigManager; } [HttpGet("queue_cleaner")] public async Task GetQueueCleanerConfig() { var config = await _configManager.GetConfigurationAsync(); return Ok(config); } [HttpGet("download_cleaner")] public async Task GetDownloadCleanerConfig() { var config = await _configManager.GetConfigurationAsync(); return Ok(config); } [HttpGet("download_client")] public async Task GetDownloadClientConfig() { var config = await _configManager.GetConfigurationAsync(); var dto = config.Adapt(); return Ok(dto); } [HttpGet("general")] public async Task GetGeneralConfig() { var config = await _configManager.GetConfigurationAsync(); var dto = config.Adapt(); return Ok(dto); } [HttpGet("sonarr")] public async Task GetSonarrConfig() { var config = await _configManager.GetConfigurationAsync(); var dto = config.Adapt(); return Ok(dto); } [HttpGet("radarr")] public async Task GetRadarrConfig() { var config = await _configManager.GetConfigurationAsync(); var dto = config.Adapt(); return Ok(dto); } [HttpGet("lidarr")] public async Task GetLidarrConfig() { var config = await _configManager.GetConfigurationAsync(); var dto = config.Adapt(); return Ok(dto); } [HttpGet("notifications")] public async Task GetNotificationsConfig() { var config = await _configManager.GetConfigurationAsync(); var dto = config.Adapt(); return Ok(dto); } [HttpPut("queue_cleaner")] public async Task UpdateQueueCleanerConfig([FromBody] QueueCleanerConfig dto) { // Get existing config var oldConfig = await _configManager.GetConfigurationAsync(); // Apply updates from DTO, preserving sensitive data if not provided var newConfig = oldConfig.Adapt(); newConfig = dto.Adapt(newConfig); // Validate the configuration newConfig.Validate(); // Persist the configuration var result = await _configManager.SaveConfigurationAsync(newConfig); if (!result) { return StatusCode(500, "Failed to save QueueCleaner configuration"); } // Update the scheduler based on configuration changes await UpdateJobSchedule(oldConfig, JobType.QueueCleaner); return Ok(new { Message = "QueueCleaner configuration updated successfully" }); } /// /// Updates a job schedule based on configuration changes /// /// The job configuration /// The type of job to update private async Task UpdateJobSchedule(IJobConfig config, JobType jobType) { if (config.Enabled) { // Get the cron expression based on the specific config type if (!string.IsNullOrEmpty(config.CronExpression)) { // If the job is enabled, update its schedule with the configured cron expression _logger.LogInformation("{name} is enabled, updating job schedule with cron expression: {CronExpression}", jobType.ToString(), config.CronExpression); _logger.LogCritical("This is a random test log"); // Create a Quartz job schedule with the cron expression await _jobManagementService.StartJob(jobType, null, config.CronExpression); } else { _logger.LogWarning("{name} is enabled, but no cron expression was found in the configuration", jobType.ToString()); } return; } // If the job is disabled, stop it _logger.LogInformation("{name} is disabled, stopping the job", jobType.ToString()); await _jobManagementService.StopJob(jobType); } [HttpPut("content_blocker")] public async Task UpdateContentBlockerConfig([FromBody] ContentBlockerConfigUpdateDto dto) { // Get existing config var oldConfig = await _configManager.GetConfigurationAsync(); // Apply updates from DTO, preserving sensitive data if not provided var newConfig = oldConfig.Adapt(); newConfig = dto.Adapt(newConfig); // Validate the configuration newConfig.Validate(); // Persist the configuration var result = await _configManager.SaveConfigurationAsync(newConfig); if (!result) { return StatusCode(500, "Failed to save ContentBlocker configuration"); } return Ok(new { Message = "ContentBlocker configuration updated successfully" }); } [HttpPut("download_cleaner")] public async Task UpdateDownloadCleanerConfig([FromBody] DownloadCleanerConfig dto) { // Get existing config var oldConfig = await _configManager.GetConfigurationAsync(); // Apply updates from DTO, preserving sensitive data if not provided var newConfig = oldConfig.Adapt(); newConfig = dto.Adapt(newConfig); // Validate the configuration newConfig.Validate(); // Persist the configuration var result = await _configManager.SaveConfigurationAsync(newConfig); if (!result) { return StatusCode(500, "Failed to save DownloadCleaner configuration"); } // Update the scheduler based on configuration changes await UpdateJobSchedule(oldConfig, JobType.DownloadCleaner); return Ok(new { Message = "DownloadCleaner configuration updated successfully" }); } [HttpPut("download_client")] public async Task UpdateDownloadClientConfig(DownloadClientConfigUpdateDto dto) { // Get existing config to preserve sensitive data var oldConfig = await _configManager.GetConfigurationAsync(); // Apply updates from DTO, preserving sensitive data if not provided var newConfig = oldConfig.Adapt(); newConfig = dto.Adapt(newConfig); // Validate the configuration newConfig.Validate(); // Persist the configuration var result = await _configManager.SaveConfigurationAsync(newConfig); if (!result) { return StatusCode(500, "Failed to save DownloadClient configuration"); } return Ok(new { Message = "DownloadClient configuration updated successfully" }); } [HttpPut("general")] public async Task UpdateGeneralConfig([FromBody] GeneralConfig dto) { // Get existing config to preserve sensitive data var oldConfig = await _configManager.GetConfigurationAsync(); // Apply updates from DTO, preserving sensitive data if not provided var newConfig = oldConfig.Adapt(); newConfig = dto.Adapt(newConfig); // Validate the configuration newConfig.Validate(); // Persist the configuration var result = await _configManager.SaveConfigurationAsync(newConfig); if (!result) { return StatusCode(500, "Failed to save General configuration"); } _loggingConfigManager.SetLogLevel(oldConfig.LogLevel); return Ok(new { Message = "General configuration updated successfully" }); } [HttpPut("sonarr")] public async Task UpdateSonarrConfig([FromBody] SonarrConfigUpdateDto dto) { // Get existing config to preserve sensitive data var oldConfig = await _configManager.GetConfigurationAsync(); // Apply updates from DTO, preserving sensitive data if not provided var newConfig = oldConfig.Adapt(); newConfig = dto.Adapt(newConfig); // Validate the configuration newConfig.Validate(); // Persist the configuration var result = await _configManager.SaveConfigurationAsync(newConfig); if (!result) { return StatusCode(500, "Failed to save Sonarr configuration"); } return Ok(new { Message = "Sonarr configuration updated successfully" }); } [HttpPut("radarr")] public async Task UpdateRadarrConfig([FromBody] RadarrConfigUpdateDto dto) { // Get existing config to preserve sensitive data var oldConfig = await _configManager.GetConfigurationAsync(); // Apply updates from DTO, preserving sensitive data if not provided var newConfig = oldConfig.Adapt(); newConfig = dto.Adapt(newConfig); // Validate the configuration newConfig.Validate(); // Persist the configuration var result = await _configManager.SaveConfigurationAsync(newConfig); if (!result) { return StatusCode(500, "Failed to save Radarr configuration"); } return Ok(new { Message = "Radarr configuration updated successfully" }); } [HttpPut("lidarr")] public async Task UpdateLidarrConfig([FromBody] LidarrConfigUpdateDto dto) { // Get existing config to preserve sensitive data var oldConfig = await _configManager.GetConfigurationAsync(); // Apply updates from DTO, preserving sensitive data if not provided var newConfig = oldConfig.Adapt(); newConfig = dto.Adapt(newConfig); // Validate the configuration newConfig.Validate(); // Persist the configuration var result = await _configManager.SaveConfigurationAsync(newConfig); if (!result) { return StatusCode(500, "Failed to save Lidarr configuration"); } return Ok(new { Message = "Lidarr configuration updated successfully" }); } [HttpPut("notifications")] public async Task UpdateNotificationsConfig([FromBody] NotificationsConfigUpdateDto dto) { // Get existing config to preserve sensitive data var oldConfig = await _configManager.GetConfigurationAsync(); // Apply updates from DTO, preserving sensitive data if not provided var newConfig = oldConfig.Adapt(); newConfig = dto.Adapt(newConfig); // Validate the configuration // newConfig.Validate(); // Persist the configuration var result = await _configManager.SaveConfigurationAsync(newConfig); if (!result) { return StatusCode(500, "Failed to save Notifications configuration"); } return Ok(new { Message = "Notifications configuration updated successfully" }); } }