using System; using System.Collections.Generic; using System.Linq; using NLog; using NzbDrone.Common.Cache; using NzbDrone.Core.Lifecycle; using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Qualities.Commands; namespace NzbDrone.Core.Qualities { public interface IQualityDefinitionService { void Update(QualityDefinition qualityDefinition); void UpdateMany(List qualityDefinitions); List All(); QualityDefinition GetById(int id); QualityDefinition Get(Quality quality); } public class QualityDefinitionService : IQualityDefinitionService, IExecute, IHandle { private readonly IQualityDefinitionRepository _repo; private readonly ICached> _cache; private readonly Logger _logger; public QualityDefinitionService(IQualityDefinitionRepository repo, ICacheManager cacheManager, Logger logger) { _repo = repo; _cache = cacheManager.GetCache>(GetType()); _logger = logger; } private Dictionary GetAll() { return _cache.Get("all", () => _repo.All().Select(WithWeight).ToDictionary(v => v.Quality), TimeSpan.FromSeconds(5.0)); } public void Update(QualityDefinition qualityDefinition) { _repo.Update(qualityDefinition); _cache.Clear(); } public void UpdateMany(List qualityDefinitions) { _repo.UpdateMany(qualityDefinitions); } public List All() { return GetAll().Values.OrderBy(d => d.Weight).ToList(); } public QualityDefinition GetById(int id) { return GetAll().Values.Single(v => v.Id == id); } public QualityDefinition Get(Quality quality) { return GetAll()[quality]; } private void InsertMissingDefinitions() { var insertList = new List(); var updateList = new List(); var allDefinitions = Quality.DefaultQualityDefinitions.OrderBy(d => d.Weight).ToList(); var existingDefinitions = _repo.All().ToList(); foreach (var definition in allDefinitions) { var existing = existingDefinitions.SingleOrDefault(d => d.Quality == definition.Quality); if (existing == null) { insertList.Add(definition); } else { updateList.Add(existing); existingDefinitions.Remove(existing); } } _repo.InsertMany(insertList); _repo.UpdateMany(updateList); _repo.DeleteMany(existingDefinitions); _cache.Clear(); } private static QualityDefinition WithWeight(QualityDefinition definition) { definition.Weight = Quality.DefaultQualityDefinitions.Single(d => d.Quality == definition.Quality).Weight; return definition; } public void Handle(ApplicationStartedEvent message) { _logger.Debug("Setting up default quality config"); InsertMissingDefinitions(); } public void Execute(ResetQualityDefinitionsCommand message) { var updateList = new List(); var allDefinitions = Quality.DefaultQualityDefinitions.OrderBy(d => d.Weight).ToList(); var existingDefinitions = _repo.All().ToList(); foreach (var definition in allDefinitions) { var existing = existingDefinitions.SingleOrDefault(d => d.Quality == definition.Quality); existing.MinSize = definition.MinSize; existing.MaxSize = definition.MaxSize; existing.Title = message.ResetTitles ? definition.Title : existing.Title; updateList.Add(existing); } _repo.UpdateMany(updateList); _cache.Clear(); } } }