diff --git a/src/NzbDrone.Core/ImportLists/FetchAndParseImportListService.cs b/src/NzbDrone.Core/ImportLists/FetchAndParseImportListService.cs index 4092879f5..98eec4ee2 100644 --- a/src/NzbDrone.Core/ImportLists/FetchAndParseImportListService.cs +++ b/src/NzbDrone.Core/ImportLists/FetchAndParseImportListService.cs @@ -12,6 +12,7 @@ namespace NzbDrone.Core.ImportLists public interface IFetchAndParseImportList { List Fetch(); + List FetchSingleList(ImportListDefinition definition); } public class FetchAndParseImportListService : IFetchAndParseImportList @@ -76,5 +77,51 @@ namespace NzbDrone.Core.ImportLists return result; } + + public List FetchSingleList(ImportListDefinition definition) + { + var result = new List(); + + var importList = _importListFactory.GetInstance(definition); + + if (importList == null || !definition.EnableAutomaticAdd) + { + _logger.Warn("No available import lists. check your configuration."); + return result; + } + + var taskList = new List(); + var taskFactory = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.None); + + var importListLocal = importList; + + var task = taskFactory.StartNew(() => + { + try + { + var importListReports = importListLocal.Fetch(); + + lock (result) + { + _logger.Debug("Found {0} from {1}", importListReports.Count, importList.Name); + + result.AddRange(importListReports); + } + } + catch (Exception e) + { + _logger.Error(e, "Error during Import List Sync"); + } + }).LogExceptions(); + + taskList.Add(task); + + + Task.WaitAll(taskList.ToArray()); + + result = result.DistinctBy(r => new { r.Artist, r.Album }).ToList(); + + return result; + } } } diff --git a/src/NzbDrone.Core/ImportLists/ImportListSyncCommand.cs b/src/NzbDrone.Core/ImportLists/ImportListSyncCommand.cs index fafb73dde..d08820caf 100644 --- a/src/NzbDrone.Core/ImportLists/ImportListSyncCommand.cs +++ b/src/NzbDrone.Core/ImportLists/ImportListSyncCommand.cs @@ -4,6 +4,19 @@ namespace NzbDrone.Core.ImportLists { public class ImportListSyncCommand : Command { + public int? DefinitionId { get; set; } + + public ImportListSyncCommand() + { + } + + public ImportListSyncCommand(int? definition) + { + DefinitionId = definition; + } + public override bool SendUpdatesToClient => true; + + public override bool UpdateScheduledTask => !DefinitionId.HasValue; } } diff --git a/src/NzbDrone.Core/ImportLists/ImportListSyncService.cs b/src/NzbDrone.Core/ImportLists/ImportListSyncService.cs index db1c7d545..65211ec15 100644 --- a/src/NzbDrone.Core/ImportLists/ImportListSyncService.cs +++ b/src/NzbDrone.Core/ImportLists/ImportListSyncService.cs @@ -7,6 +7,7 @@ using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.MetadataSource; using NzbDrone.Core.Music; +using NzbDrone.Core.Parser.Model; namespace NzbDrone.Core.ImportLists { @@ -44,13 +45,32 @@ namespace NzbDrone.Core.ImportLists } - private List Sync() + private List SyncAll() { _logger.ProgressInfo("Starting Import List Sync"); var rssReleases = _listFetcherAndParser.Fetch(); var reports = rssReleases.ToList(); + + return ProcessReports(reports); + + } + + private List SyncList(ImportListDefinition definition) + { + _logger.ProgressInfo(string.Format("Starting Import List Refresh for List {0}", definition.Name)); + + var rssReleases = _listFetcherAndParser.FetchSingleList(definition); + + var reports = rssReleases.ToList(); + + return ProcessReports(reports); + + } + + private List ProcessReports(List reports) + { var processed = new List(); var artistsToAdd = new List(); @@ -106,19 +126,19 @@ namespace NzbDrone.Core.ImportLists LanguageProfileId = importList.LanguageProfileId, MetadataProfileId = importList.MetadataProfileId, AlbumFolder = true, - AddOptions = new AddArtistOptions{SearchForMissingAlbums = true, Monitored = importList.ShouldMonitor, SelectedOption = 0} + AddOptions = new AddArtistOptions { SearchForMissingAlbums = true, Monitored = importList.ShouldMonitor, SelectedOption = 0 } }); } // Add Album so we know what to monitor - if (report.AlbumMusicBrainzId.IsNotNullOrWhiteSpace() && artistsToAdd.Any(s=>s.ForeignArtistId == report.ArtistMusicBrainzId) && importList.ShouldMonitor) + if (report.AlbumMusicBrainzId.IsNotNullOrWhiteSpace() && artistsToAdd.Any(s => s.ForeignArtistId == report.ArtistMusicBrainzId) && importList.ShouldMonitor) { artistsToAdd.Find(s => s.ForeignArtistId == report.ArtistMusicBrainzId).AddOptions.AlbumsToMonitor.Add(report.AlbumMusicBrainzId); } } _addArtistService.AddArtists(artistsToAdd); - + var message = string.Format("Import List Sync Completed. Reports found: {0}, Reports grabbed: {1}", reports.Count, processed.Count); _logger.ProgressInfo(message); @@ -128,7 +148,16 @@ namespace NzbDrone.Core.ImportLists public void Execute(ImportListSyncCommand message) { - var processed = Sync(); + List processed; + + if (message.DefinitionId.HasValue) + { + processed = SyncList(_importListFactory.Get(message.DefinitionId.Value)); + } + else + { + processed = SyncAll(); + } _eventAggregator.PublishEvent(new ImportListSyncCompleteEvent(processed)); } diff --git a/src/NzbDrone.Core/ImportLists/ImportListUpdatedHandler.cs b/src/NzbDrone.Core/ImportLists/ImportListUpdatedHandler.cs new file mode 100644 index 000000000..64b126b18 --- /dev/null +++ b/src/NzbDrone.Core/ImportLists/ImportListUpdatedHandler.cs @@ -0,0 +1,26 @@ +using NzbDrone.Core.Messaging.Commands; +using NzbDrone.Core.Messaging.Events; +using NzbDrone.Core.ThingiProvider.Events; + +namespace NzbDrone.Core.ImportLists +{ + public class ImportListUpdatedHandler : IHandle>, IHandle> + { + private readonly IManageCommandQueue _commandQueueManager; + + public ImportListUpdatedHandler(IManageCommandQueue commandQueueManager) + { + _commandQueueManager = commandQueueManager; + } + + public void Handle(ProviderUpdatedEvent message) + { + _commandQueueManager.Push(new ImportListSyncCommand(message.Definition.Id)); + } + + public void Handle(ProviderAddedEvent message) + { + _commandQueueManager.Push(new ImportListSyncCommand(message.Definition.Id)); + } + } +} diff --git a/src/NzbDrone.Core/NzbDrone.Core.csproj b/src/NzbDrone.Core/NzbDrone.Core.csproj index f6655f6bd..e561e9af6 100644 --- a/src/NzbDrone.Core/NzbDrone.Core.csproj +++ b/src/NzbDrone.Core/NzbDrone.Core.csproj @@ -547,6 +547,7 @@ + @@ -1111,6 +1112,7 @@ + diff --git a/src/NzbDrone.Core/ThingiProvider/Events/ProviderAddedEvent.cs b/src/NzbDrone.Core/ThingiProvider/Events/ProviderAddedEvent.cs new file mode 100644 index 000000000..d1bc038b9 --- /dev/null +++ b/src/NzbDrone.Core/ThingiProvider/Events/ProviderAddedEvent.cs @@ -0,0 +1,14 @@ +using NzbDrone.Common.Messaging; + +namespace NzbDrone.Core.ThingiProvider.Events +{ + public class ProviderAddedEvent : IEvent + { + public ProviderDefinition Definition { get; private set; } + + public ProviderAddedEvent(ProviderDefinition definition) + { + Definition = definition; + } + } +} diff --git a/src/NzbDrone.Core/ThingiProvider/ProviderFactory.cs b/src/NzbDrone.Core/ThingiProvider/ProviderFactory.cs index 750f0cf3d..b37aefda9 100644 --- a/src/NzbDrone.Core/ThingiProvider/ProviderFactory.cs +++ b/src/NzbDrone.Core/ThingiProvider/ProviderFactory.cs @@ -98,7 +98,9 @@ namespace NzbDrone.Core.ThingiProvider public virtual TProviderDefinition Create(TProviderDefinition definition) { - return _providerRepository.Insert(definition); + var addedDefinition = _providerRepository.Insert(definition); + _eventAggregator.PublishEvent(new ProviderAddedEvent(definition)); + return addedDefinition; } public virtual void Update(TProviderDefinition definition)