diff --git a/src/NzbDrone.Core/IndexerSearch/ArtistSearchCommand.cs b/src/NzbDrone.Core/IndexerSearch/ArtistSearchCommand.cs new file mode 100644 index 0000000000..ed506d681d --- /dev/null +++ b/src/NzbDrone.Core/IndexerSearch/ArtistSearchCommand.cs @@ -0,0 +1,11 @@ +using NzbDrone.Core.Messaging.Commands; + +namespace NzbDrone.Core.IndexerSearch +{ + class ArtistSearchCommand : Command + { + public int ArtistId { get; set; } + + public override bool SendUpdatesToClient => true; + } +} diff --git a/src/NzbDrone.Core/IndexerSearch/ArtistSearchService.cs b/src/NzbDrone.Core/IndexerSearch/ArtistSearchService.cs new file mode 100644 index 0000000000..4a88c7b7b6 --- /dev/null +++ b/src/NzbDrone.Core/IndexerSearch/ArtistSearchService.cs @@ -0,0 +1,31 @@ +using NLog; +using NzbDrone.Common.Instrumentation.Extensions; +using NzbDrone.Core.Download; +using NzbDrone.Core.Messaging.Commands; + +namespace NzbDrone.Core.IndexerSearch +{ + class ArtistSearchService : IExecute + { + private readonly ISearchForNzb _nzbSearchService; + private readonly IProcessDownloadDecisions _processDownloadDecisions; + private readonly Logger _logger; + + public ArtistSearchService(ISearchForNzb nzbSearchService, + IProcessDownloadDecisions processDownloadDecisions, + Logger logger) + { + _nzbSearchService = nzbSearchService; + _processDownloadDecisions = processDownloadDecisions; + _logger = logger; + } + + public void Execute(ArtistSearchCommand message) + { + var decisions = _nzbSearchService.ArtistSearch(message.ArtistId, false, message.Trigger == CommandTrigger.Manual); + var processed = _processDownloadDecisions.ProcessDecisions(decisions); + + _logger.ProgressInfo("Artist search completed. {0} reports downloaded.", processed.Grabbed.Count); + } + } +} diff --git a/src/NzbDrone.Core/IndexerSearch/Definitions/ArtistSearchCriteria.cs b/src/NzbDrone.Core/IndexerSearch/Definitions/ArtistSearchCriteria.cs new file mode 100644 index 0000000000..6de6dd3b11 --- /dev/null +++ b/src/NzbDrone.Core/IndexerSearch/Definitions/ArtistSearchCriteria.cs @@ -0,0 +1,12 @@ +using System; + +namespace NzbDrone.Core.IndexerSearch.Definitions +{ + public class ArtistSearchCriteria : SearchCriteriaBase + { + public override string ToString() + { + return $"[{Artist.Name}]"; + } + } +} diff --git a/src/NzbDrone.Core/IndexerSearch/NzbSearchService.cs b/src/NzbDrone.Core/IndexerSearch/NzbSearchService.cs index 692f560022..921e04164f 100644 --- a/src/NzbDrone.Core/IndexerSearch/NzbSearchService.cs +++ b/src/NzbDrone.Core/IndexerSearch/NzbSearchService.cs @@ -22,6 +22,7 @@ public interface ISearchForNzb List EpisodeSearch(Episode episode, bool userInvokedSearch); List SeasonSearch(int seriesId, int seasonNumber, bool missingOnly, bool userInvokedSearch); List AlbumSearch(int albumId, bool missingOnly, bool userInvokedSearch); + List ArtistSearch(int artistId, bool missingOnly, bool userInvokedSearch); } public class NzbSearchService : ISearchForNzb @@ -175,6 +176,18 @@ public List AlbumSearch(int albumId, bool missingOnly, bool us return AlbumSearch(album, missingOnly, userInvokedSearch); } + public List ArtistSearch(int artistId, bool missingOnly, bool userInvokedSearch) + { + var artist = _artistService.GetArtist(artistId); + return ArtistSearch(artist, missingOnly, userInvokedSearch); + } + + public List ArtistSearch(Artist artist, bool missingOnly, bool userInvokedSearch) + { + var searchSpec = Get(artist, userInvokedSearch); + return Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec); + } + public List AlbumSearch(Album album, bool missingOnly, bool userInvokedSearch) { var searchSpec = Get(album, userInvokedSearch); @@ -280,6 +293,16 @@ private List SearchAnimeSeason(Series series, List ep return spec; } + private TSpec Get(Artist artist, bool userInvokedSearch) where TSpec : SearchCriteriaBase, new() + { + var spec = new TSpec(); +; + spec.Artist = artist; + spec.UserInvokedSearch = userInvokedSearch; + + return spec; + } + private List Dispatch(Func> searchAction, SearchCriteriaBase criteriaBase) { var indexers = _indexerFactory.SearchEnabled(); diff --git a/src/NzbDrone.Core/Indexers/BitMeTv/BitMeTvRequestGenerator.cs b/src/NzbDrone.Core/Indexers/BitMeTv/BitMeTvRequestGenerator.cs index 0bae81fee6..40eef04240 100644 --- a/src/NzbDrone.Core/Indexers/BitMeTv/BitMeTvRequestGenerator.cs +++ b/src/NzbDrone.Core/Indexers/BitMeTv/BitMeTvRequestGenerator.cs @@ -47,6 +47,11 @@ public IndexerPageableRequestChain GetSearchRequests(AlbumSearchCriteria searchC throw new System.NotImplementedException(); } + public IndexerPageableRequestChain GetSearchRequests(ArtistSearchCriteria searchCriteria) + { + throw new System.NotImplementedException(); + } + private IEnumerable GetRssRequests() { var request = new IndexerRequest(string.Format("{0}/rss.php?uid={1}&passkey={2}", Settings.BaseUrl.Trim().TrimEnd('/'), Settings.UserId, Settings.RssPasskey), HttpAccept.Html); diff --git a/src/NzbDrone.Core/Indexers/BroadcastheNet/BroadcastheNetRequestGenerator.cs b/src/NzbDrone.Core/Indexers/BroadcastheNet/BroadcastheNetRequestGenerator.cs index ce63db668c..3f603837ee 100644 --- a/src/NzbDrone.Core/Indexers/BroadcastheNet/BroadcastheNetRequestGenerator.cs +++ b/src/NzbDrone.Core/Indexers/BroadcastheNet/BroadcastheNetRequestGenerator.cs @@ -165,6 +165,11 @@ public IndexerPageableRequestChain GetSearchRequests(AlbumSearchCriteria searchC throw new System.NotImplementedException(); } + public IndexerPageableRequestChain GetSearchRequests(ArtistSearchCriteria searchCriteria) + { + throw new System.NotImplementedException(); + } + private bool AddSeriesSearchParameters(BroadcastheNetTorrentQuery parameters, SearchCriteriaBase searchCriteria) { if (searchCriteria.Series.TvdbId != 0) diff --git a/src/NzbDrone.Core/Indexers/Fanzub/FanzubRequestGenerator.cs b/src/NzbDrone.Core/Indexers/Fanzub/FanzubRequestGenerator.cs index 519a31da20..0327d31e50 100644 --- a/src/NzbDrone.Core/Indexers/Fanzub/FanzubRequestGenerator.cs +++ b/src/NzbDrone.Core/Indexers/Fanzub/FanzubRequestGenerator.cs @@ -65,6 +65,11 @@ public IndexerPageableRequestChain GetSearchRequests(AlbumSearchCriteria searchC throw new System.NotImplementedException(); } + public IndexerPageableRequestChain GetSearchRequests(ArtistSearchCriteria searchCriteria) + { + throw new System.NotImplementedException(); + } + private IEnumerable GetPagedRequests(string query) { var url = new StringBuilder(); diff --git a/src/NzbDrone.Core/Indexers/HDBits/HDBitsRequestGenerator.cs b/src/NzbDrone.Core/Indexers/HDBits/HDBitsRequestGenerator.cs index d2ab10be37..c9a7ba702a 100644 --- a/src/NzbDrone.Core/Indexers/HDBits/HDBitsRequestGenerator.cs +++ b/src/NzbDrone.Core/Indexers/HDBits/HDBitsRequestGenerator.cs @@ -48,6 +48,11 @@ public IndexerPageableRequestChain GetSearchRequests(AlbumSearchCriteria searchC throw new System.NotImplementedException(); } + public IndexerPageableRequestChain GetSearchRequests(ArtistSearchCriteria searchCriteria) + { + throw new System.NotImplementedException(); + } + public virtual IndexerPageableRequestChain GetSearchRequests(DailyEpisodeSearchCriteria searchCriteria) { var pageableRequests = new IndexerPageableRequestChain(); diff --git a/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs b/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs index 8ac5fac321..3ff24d1f44 100644 --- a/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs +++ b/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs @@ -128,6 +128,18 @@ public override IList Fetch(AlbumSearchCriteria searchCriteria) return FetchReleases(generator.GetSearchRequests(searchCriteria)); } + public override IList Fetch(ArtistSearchCriteria searchCriteria) + { + if (!SupportsSearch) + { + return new List(); + } + + var generator = GetRequestGenerator(); + + return FetchReleases(generator.GetSearchRequests(searchCriteria)); + } + protected virtual IList FetchReleases(IndexerPageableRequestChain pageableRequestChain, bool isRecent = false) { var releases = new List(); diff --git a/src/NzbDrone.Core/Indexers/IIndexer.cs b/src/NzbDrone.Core/Indexers/IIndexer.cs index 658cfaf3c0..b8985a1e3d 100644 --- a/src/NzbDrone.Core/Indexers/IIndexer.cs +++ b/src/NzbDrone.Core/Indexers/IIndexer.cs @@ -23,5 +23,6 @@ public interface IIndexer : IProvider [System.Obsolete("Sonarr TV Stuff -- Shouldn't be needed for Lidarr")] IList Fetch(SpecialEpisodeSearchCriteria searchCriteria); IList Fetch(AlbumSearchCriteria searchCriteria); + IList Fetch(ArtistSearchCriteria searchCriteria); } } \ No newline at end of file diff --git a/src/NzbDrone.Core/Indexers/IIndexerRequestGenerator.cs b/src/NzbDrone.Core/Indexers/IIndexerRequestGenerator.cs index 5c660fd60b..20dcb77374 100644 --- a/src/NzbDrone.Core/Indexers/IIndexerRequestGenerator.cs +++ b/src/NzbDrone.Core/Indexers/IIndexerRequestGenerator.cs @@ -11,5 +11,6 @@ public interface IIndexerRequestGenerator IndexerPageableRequestChain GetSearchRequests(AnimeEpisodeSearchCriteria searchCriteria); IndexerPageableRequestChain GetSearchRequests(SpecialEpisodeSearchCriteria searchCriteria); IndexerPageableRequestChain GetSearchRequests(AlbumSearchCriteria searchCriteria); + IndexerPageableRequestChain GetSearchRequests(ArtistSearchCriteria searchCriteria); } } \ No newline at end of file diff --git a/src/NzbDrone.Core/Indexers/IPTorrents/IPTorrentsRequestGenerator.cs b/src/NzbDrone.Core/Indexers/IPTorrents/IPTorrentsRequestGenerator.cs index 7257965968..20af9f2420 100644 --- a/src/NzbDrone.Core/Indexers/IPTorrents/IPTorrentsRequestGenerator.cs +++ b/src/NzbDrone.Core/Indexers/IPTorrents/IPTorrentsRequestGenerator.cs @@ -47,6 +47,11 @@ public IndexerPageableRequestChain GetSearchRequests(AlbumSearchCriteria searchC throw new System.NotImplementedException(); } + public IndexerPageableRequestChain GetSearchRequests(ArtistSearchCriteria searchCriteria) + { + throw new System.NotImplementedException(); + } + private IEnumerable GetRssRequests() { yield return new IndexerRequest(Settings.Url, HttpAccept.Rss); diff --git a/src/NzbDrone.Core/Indexers/IndexerBase.cs b/src/NzbDrone.Core/Indexers/IndexerBase.cs index 2a58f94d44..bc15ce0863 100644 --- a/src/NzbDrone.Core/Indexers/IndexerBase.cs +++ b/src/NzbDrone.Core/Indexers/IndexerBase.cs @@ -74,6 +74,7 @@ public virtual IEnumerable DefaultDefinitions [System.Obsolete("Sonarr TV Stuff -- Shouldn't be needed for Lidarr")] public abstract IList Fetch(SpecialEpisodeSearchCriteria searchCriteria); public abstract IList Fetch(AlbumSearchCriteria searchCriteria); + public abstract IList Fetch(ArtistSearchCriteria searchCriteria); protected virtual IList CleanupReleases(IEnumerable releases) { diff --git a/src/NzbDrone.Core/Indexers/Newznab/NewznabRequestGenerator.cs b/src/NzbDrone.Core/Indexers/Newznab/NewznabRequestGenerator.cs index 875490211f..69a393d46b 100644 --- a/src/NzbDrone.Core/Indexers/Newznab/NewznabRequestGenerator.cs +++ b/src/NzbDrone.Core/Indexers/Newznab/NewznabRequestGenerator.cs @@ -185,6 +185,11 @@ public IndexerPageableRequestChain GetSearchRequests(AlbumSearchCriteria searchC throw new System.NotImplementedException(); } + public IndexerPageableRequestChain GetSearchRequests(ArtistSearchCriteria searchCriteria) + { + throw new System.NotImplementedException(); + } + private void AddTvIdPageableRequests(IndexerPageableRequestChain chain, int maxPages, IEnumerable categories, SearchCriteriaBase searchCriteria, string parameters) { var includeTvdbSearch = SupportsTvdbSearch && searchCriteria.Series.TvdbId > 0; diff --git a/src/NzbDrone.Core/Indexers/Nyaa/NyaaRequestGenerator.cs b/src/NzbDrone.Core/Indexers/Nyaa/NyaaRequestGenerator.cs index b5a9654248..d375fb5526 100644 --- a/src/NzbDrone.Core/Indexers/Nyaa/NyaaRequestGenerator.cs +++ b/src/NzbDrone.Core/Indexers/Nyaa/NyaaRequestGenerator.cs @@ -79,6 +79,11 @@ public IndexerPageableRequestChain GetSearchRequests(AlbumSearchCriteria searchC throw new System.NotImplementedException(); } + public IndexerPageableRequestChain GetSearchRequests(ArtistSearchCriteria searchCriteria) + { + throw new System.NotImplementedException(); + } + private IEnumerable GetPagedRequests(int maxPages, string term) { var baseUrl = string.Format("{0}/?page=rss{1}", Settings.BaseUrl.TrimEnd('/'), Settings.AdditionalParameters); diff --git a/src/NzbDrone.Core/Indexers/Omgwtfnzbs/OmgwtfnzbsRequestGenerator.cs b/src/NzbDrone.Core/Indexers/Omgwtfnzbs/OmgwtfnzbsRequestGenerator.cs index d509f031d8..594d9cf78e 100644 --- a/src/NzbDrone.Core/Indexers/Omgwtfnzbs/OmgwtfnzbsRequestGenerator.cs +++ b/src/NzbDrone.Core/Indexers/Omgwtfnzbs/OmgwtfnzbsRequestGenerator.cs @@ -93,6 +93,11 @@ public IndexerPageableRequestChain GetSearchRequests(AlbumSearchCriteria searchC throw new System.NotImplementedException(); } + public IndexerPageableRequestChain GetSearchRequests(ArtistSearchCriteria searchCriteria) + { + throw new System.NotImplementedException(); + } + private IEnumerable GetPagedRequests(string query) { var url = new StringBuilder(); diff --git a/src/NzbDrone.Core/Indexers/Rarbg/RarbgRequestGenerator.cs b/src/NzbDrone.Core/Indexers/Rarbg/RarbgRequestGenerator.cs index 2586118d86..eb126c11ec 100644 --- a/src/NzbDrone.Core/Indexers/Rarbg/RarbgRequestGenerator.cs +++ b/src/NzbDrone.Core/Indexers/Rarbg/RarbgRequestGenerator.cs @@ -86,6 +86,15 @@ public IndexerPageableRequestChain GetSearchRequests(AlbumSearchCriteria searchC return pageableRequests; } + public IndexerPageableRequestChain GetSearchRequests(ArtistSearchCriteria searchCriteria) + { + var pageableRequests = new IndexerPageableRequestChain(); + + pageableRequests.Add(GetPagedRequests("search", null, "{0}", searchCriteria.Artist.Name)); + + return pageableRequests; + } + private IEnumerable GetPagedRequests(string mode, int? tvdbId, string query, params object[] args) { var requestBuilder = new HttpRequestBuilder(Settings.BaseUrl) diff --git a/src/NzbDrone.Core/Indexers/RssIndexerRequestGenerator.cs b/src/NzbDrone.Core/Indexers/RssIndexerRequestGenerator.cs index d14e1fb398..5a157d3a9d 100644 --- a/src/NzbDrone.Core/Indexers/RssIndexerRequestGenerator.cs +++ b/src/NzbDrone.Core/Indexers/RssIndexerRequestGenerator.cs @@ -51,5 +51,10 @@ public IndexerPageableRequestChain GetSearchRequests(AlbumSearchCriteria searchC { throw new System.NotImplementedException(); } + + public IndexerPageableRequestChain GetSearchRequests(ArtistSearchCriteria searchCriteria) + { + throw new System.NotImplementedException(); + } } } diff --git a/src/NzbDrone.Core/Indexers/TorrentRss/TorrentRssIndexerRequestGenerator.cs b/src/NzbDrone.Core/Indexers/TorrentRss/TorrentRssIndexerRequestGenerator.cs index 62f165d91a..0995ffdd77 100644 --- a/src/NzbDrone.Core/Indexers/TorrentRss/TorrentRssIndexerRequestGenerator.cs +++ b/src/NzbDrone.Core/Indexers/TorrentRss/TorrentRssIndexerRequestGenerator.cs @@ -48,6 +48,11 @@ public IndexerPageableRequestChain GetSearchRequests(AlbumSearchCriteria searchC throw new System.NotImplementedException(); } + public IndexerPageableRequestChain GetSearchRequests(ArtistSearchCriteria searchCriteria) + { + throw new System.NotImplementedException(); + } + private IEnumerable GetRssRequests(string searchParameters) { var request = new IndexerRequest(Settings.BaseUrl.Trim().TrimEnd('/'), HttpAccept.Rss); diff --git a/src/NzbDrone.Core/Indexers/Torrentleech/TorrentleechRequestGenerator.cs b/src/NzbDrone.Core/Indexers/Torrentleech/TorrentleechRequestGenerator.cs index 9d1d98ed46..b676a313ce 100644 --- a/src/NzbDrone.Core/Indexers/Torrentleech/TorrentleechRequestGenerator.cs +++ b/src/NzbDrone.Core/Indexers/Torrentleech/TorrentleechRequestGenerator.cs @@ -47,6 +47,11 @@ public IndexerPageableRequestChain GetSearchRequests(AlbumSearchCriteria searchC throw new System.NotImplementedException(); } + public IndexerPageableRequestChain GetSearchRequests(ArtistSearchCriteria searchCriteria) + { + throw new System.NotImplementedException(); + } + private IEnumerable GetRssRequests(string searchParameters) { yield return new IndexerRequest(string.Format("{0}/{1}{2}", Settings.BaseUrl.Trim().TrimEnd('/'), Settings.ApiKey, searchParameters), HttpAccept.Rss); diff --git a/src/NzbDrone.Core/NzbDrone.Core.csproj b/src/NzbDrone.Core/NzbDrone.Core.csproj index 967c70d062..1e5c0751ec 100644 --- a/src/NzbDrone.Core/NzbDrone.Core.csproj +++ b/src/NzbDrone.Core/NzbDrone.Core.csproj @@ -607,7 +607,10 @@ + + +