indexers
+ createTagsSelector(),
+ (indexers, tagList) => {
+ return {
+ ...indexers,
+ tagList
+ };
+ }
);
}
diff --git a/frontend/src/Settings/Tags/Details/TagDetailsModalContent.js b/frontend/src/Settings/Tags/Details/TagDetailsModalContent.js
index a8a08d719..0168d9ae3 100644
--- a/frontend/src/Settings/Tags/Details/TagDetailsModalContent.js
+++ b/frontend/src/Settings/Tags/Details/TagDetailsModalContent.js
@@ -22,6 +22,7 @@ function TagDetailsModalContent(props) {
importLists,
notifications,
releaseProfiles,
+ indexers,
onModalClose,
onDeleteTagPress
} = props;
@@ -41,7 +42,7 @@ function TagDetailsModalContent(props) {
}
{
- !!artist.length &&
+ artist.length ?
+ :
+ null
}
{
- !!delayProfiles.length &&
+ delayProfiles.length ?
+ :
+ null
}
{
- !!notifications.length &&
+ notifications.length ?
+ :
+ null
}
{
- !!importLists.length &&
+ importLists.length ?
+ :
+ null
}
{
- !!releaseProfiles.length &&
+ releaseProfiles.length ?
+ :
+ null
+ }
+
+ {
+ indexers.length ?
+ :
+ null
}
@@ -192,6 +214,7 @@ TagDetailsModalContent.propTypes = {
importLists: PropTypes.arrayOf(PropTypes.object).isRequired,
notifications: PropTypes.arrayOf(PropTypes.object).isRequired,
releaseProfiles: PropTypes.arrayOf(PropTypes.object).isRequired,
+ indexers: PropTypes.arrayOf(PropTypes.object).isRequired,
onModalClose: PropTypes.func.isRequired,
onDeleteTagPress: PropTypes.func.isRequired
};
diff --git a/frontend/src/Settings/Tags/Details/TagDetailsModalContentConnector.js b/frontend/src/Settings/Tags/Details/TagDetailsModalContentConnector.js
index 39c68d5f9..5a92c89ed 100644
--- a/frontend/src/Settings/Tags/Details/TagDetailsModalContentConnector.js
+++ b/frontend/src/Settings/Tags/Details/TagDetailsModalContentConnector.js
@@ -69,6 +69,14 @@ function createMatchingReleaseProfilesSelector() {
);
}
+function createMatchingIndexersSelector() {
+ return createSelector(
+ (state, { indexerIds }) => indexerIds,
+ (state) => state.settings.indexers.items,
+ findMatchingItems
+ );
+}
+
function createMapStateToProps() {
return createSelector(
createMatchingArtistSelector(),
@@ -76,13 +84,15 @@ function createMapStateToProps() {
createMatchingImportListsSelector(),
createMatchingNotificationsSelector(),
createMatchingReleaseProfilesSelector(),
- (artist, delayProfiles, importLists, notifications, releaseProfiles) => {
+ createMatchingIndexersSelector(),
+ (artist, delayProfiles, importLists, notifications, releaseProfiles, indexers) => {
return {
artist,
delayProfiles,
importLists,
notifications,
- releaseProfiles
+ releaseProfiles,
+ indexers
};
}
);
diff --git a/frontend/src/Settings/Tags/Tag.js b/frontend/src/Settings/Tags/Tag.js
index a73175ed2..983cb6637 100644
--- a/frontend/src/Settings/Tags/Tag.js
+++ b/frontend/src/Settings/Tags/Tag.js
@@ -57,6 +57,7 @@ class Tag extends Component {
importListIds,
notificationIds,
restrictionIds,
+ indexerIds,
artistIds
} = this.props;
@@ -70,6 +71,7 @@ class Tag extends Component {
importListIds.length ||
notificationIds.length ||
restrictionIds.length ||
+ indexerIds.length ||
artistIds.length
);
@@ -87,38 +89,50 @@ class Tag extends Component {
isTagUsed &&
{
- !!artistIds.length &&
+ artistIds.length ?
{artistIds.length} artists
-
+
:
+ null
}
{
- !!delayProfileIds.length &&
+ delayProfileIds.length ?
{delayProfileIds.length} delay profile{delayProfileIds.length > 1 && 's'}
-
+ :
+ null
}
{
- !!importListIds.length &&
+ importListIds.length ?
{importListIds.length} import list{importListIds.length > 1 && 's'}
-
+ :
+ null
}
{
- !!notificationIds.length &&
+ notificationIds.length ?
{notificationIds.length} connection{notificationIds.length > 1 && 's'}
-
+ :
+ null
}
{
- !!restrictionIds.length &&
+ restrictionIds.length ?
{restrictionIds.length} restriction{restrictionIds.length > 1 && 's'}
-
+ :
+ null
+ }
+ {
+ indexerIds.length ?
+
+ {indexerIds.length} indexer{indexerIds.length > 1 && 's'}
+
:
+ null
}
}
@@ -138,6 +152,7 @@ class Tag extends Component {
importListIds={importListIds}
notificationIds={notificationIds}
restrictionIds={restrictionIds}
+ indexerIds={indexerIds}
isOpen={isDetailsModalOpen}
onModalClose={this.onDetailsModalClose}
onDeleteTagPress={this.onDeleteTagPress}
@@ -164,6 +179,7 @@ Tag.propTypes = {
importListIds: PropTypes.arrayOf(PropTypes.number).isRequired,
notificationIds: PropTypes.arrayOf(PropTypes.number).isRequired,
restrictionIds: PropTypes.arrayOf(PropTypes.number).isRequired,
+ indexerIds: PropTypes.arrayOf(PropTypes.number).isRequired,
artistIds: PropTypes.arrayOf(PropTypes.number).isRequired,
onConfirmDeleteTag: PropTypes.func.isRequired
};
@@ -173,6 +189,7 @@ Tag.defaultProps = {
importListIds: [],
notificationIds: [],
restrictionIds: [],
+ indexerIds: [],
artistIds: []
};
diff --git a/frontend/src/Settings/Tags/TagsConnector.js b/frontend/src/Settings/Tags/TagsConnector.js
index bbfa5d27e..241ee260a 100644
--- a/frontend/src/Settings/Tags/TagsConnector.js
+++ b/frontend/src/Settings/Tags/TagsConnector.js
@@ -2,7 +2,7 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
-import { fetchDelayProfiles, fetchImportLists, fetchNotifications, fetchReleaseProfiles } from 'Store/Actions/settingsActions';
+import { fetchDelayProfiles, fetchImportLists, fetchIndexers, fetchNotifications, fetchReleaseProfiles } from 'Store/Actions/settingsActions';
import { fetchTagDetails } from 'Store/Actions/tagActions';
import Tags from './Tags';
@@ -29,7 +29,8 @@ const mapDispatchToProps = {
dispatchFetchDelayProfiles: fetchDelayProfiles,
dispatchFetchImportLists: fetchImportLists,
dispatchFetchNotifications: fetchNotifications,
- dispatchFetchReleaseProfiles: fetchReleaseProfiles
+ dispatchFetchReleaseProfiles: fetchReleaseProfiles,
+ dispatchFetchIndexers: fetchIndexers
};
class MetadatasConnector extends Component {
@@ -43,7 +44,8 @@ class MetadatasConnector extends Component {
dispatchFetchDelayProfiles,
dispatchFetchImportLists,
dispatchFetchNotifications,
- dispatchFetchReleaseProfiles
+ dispatchFetchReleaseProfiles,
+ dispatchFetchIndexers
} = this.props;
dispatchFetchTagDetails();
@@ -51,6 +53,7 @@ class MetadatasConnector extends Component {
dispatchFetchImportLists();
dispatchFetchNotifications();
dispatchFetchReleaseProfiles();
+ dispatchFetchIndexers();
}
//
@@ -70,7 +73,8 @@ MetadatasConnector.propTypes = {
dispatchFetchDelayProfiles: PropTypes.func.isRequired,
dispatchFetchImportLists: PropTypes.func.isRequired,
dispatchFetchNotifications: PropTypes.func.isRequired,
- dispatchFetchReleaseProfiles: PropTypes.func.isRequired
+ dispatchFetchReleaseProfiles: PropTypes.func.isRequired,
+ dispatchFetchIndexers: PropTypes.func.isRequired
};
export default connect(createMapStateToProps, mapDispatchToProps)(MetadatasConnector);
diff --git a/src/Lidarr.Api.V1/Tags/TagDetailsResource.cs b/src/Lidarr.Api.V1/Tags/TagDetailsResource.cs
index c22b4e07e..1f59e47b0 100644
--- a/src/Lidarr.Api.V1/Tags/TagDetailsResource.cs
+++ b/src/Lidarr.Api.V1/Tags/TagDetailsResource.cs
@@ -12,6 +12,7 @@ namespace Lidarr.Api.V1.Tags
public List ImportListIds { get; set; }
public List NotificationIds { get; set; }
public List RestrictionIds { get; set; }
+ public List IndexerIds { get; set; }
public List ArtistIds { get; set; }
}
@@ -32,6 +33,7 @@ namespace Lidarr.Api.V1.Tags
ImportListIds = model.ImportListIds,
NotificationIds = model.NotificationIds,
RestrictionIds = model.RestrictionIds,
+ IndexerIds = model.IndexerIds,
ArtistIds = model.ArtistIds
};
}
diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/IndexerTagSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/IndexerTagSpecificationFixture.cs
new file mode 100644
index 000000000..135409b88
--- /dev/null
+++ b/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/IndexerTagSpecificationFixture.cs
@@ -0,0 +1,136 @@
+using System.Collections.Generic;
+using FizzWare.NBuilder;
+using FluentAssertions;
+using Moq;
+using NUnit.Framework;
+using NzbDrone.Core.Datastore;
+using NzbDrone.Core.DecisionEngine.Specifications.RssSync;
+using NzbDrone.Core.Indexers;
+using NzbDrone.Core.IndexerSearch.Definitions;
+using NzbDrone.Core.Music;
+using NzbDrone.Core.Parser.Model;
+using NzbDrone.Core.Test.Framework;
+
+namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
+{
+ [TestFixture]
+ public class IndexerTagSpecificationFixture : CoreTest
+ {
+ private IndexerTagSpecification _specification;
+
+ private RemoteAlbum _parseResultMulti;
+ private IndexerDefinition _fakeIndexerDefinition;
+ private Artist _fakeArtist;
+ private Album _firstAlbum;
+ private Album _secondAlbum;
+ private ReleaseInfo _fakeRelease;
+
+ [SetUp]
+ public void Setup()
+ {
+ _fakeIndexerDefinition = new IndexerDefinition
+ {
+ Tags = new HashSet()
+ };
+
+ Mocker
+ .GetMock()
+ .Setup(m => m.Get(It.IsAny()))
+ .Throws(new ModelNotFoundException(typeof(IndexerDefinition), -1));
+
+ Mocker
+ .GetMock()
+ .Setup(m => m.Get(1))
+ .Returns(_fakeIndexerDefinition);
+
+ _specification = Mocker.Resolve();
+
+ _fakeArtist = Builder.CreateNew()
+ .With(c => c.Monitored = true)
+ .With(c => c.Tags = new HashSet())
+ .Build();
+
+ _fakeRelease = new ReleaseInfo
+ {
+ IndexerId = 1
+ };
+
+ _firstAlbum = new Album { Monitored = true };
+ _secondAlbum = new Album { Monitored = true };
+
+ var doubleEpisodeList = new List { _firstAlbum, _secondAlbum };
+
+ _parseResultMulti = new RemoteAlbum
+ {
+ Artist = _fakeArtist,
+ Albums = doubleEpisodeList,
+ Release = _fakeRelease
+ };
+ }
+
+ [Test]
+ public void indexer_and_series_without_tags_should_return_true()
+ {
+ _fakeIndexerDefinition.Tags = new HashSet();
+ _fakeArtist.Tags = new HashSet();
+
+ _specification.IsSatisfiedBy(_parseResultMulti, new AlbumSearchCriteria { MonitoredEpisodesOnly = true }).Accepted.Should().BeTrue();
+ }
+
+ [Test]
+ public void indexer_with_tags_series_without_tags_should_return_false()
+ {
+ _fakeIndexerDefinition.Tags = new HashSet { 123 };
+ _fakeArtist.Tags = new HashSet();
+
+ _specification.IsSatisfiedBy(_parseResultMulti, new AlbumSearchCriteria { MonitoredEpisodesOnly = true }).Accepted.Should().BeFalse();
+ }
+
+ [Test]
+ public void indexer_without_tags_series_with_tags_should_return_true()
+ {
+ _fakeIndexerDefinition.Tags = new HashSet();
+ _fakeArtist.Tags = new HashSet { 123 };
+
+ _specification.IsSatisfiedBy(_parseResultMulti, new AlbumSearchCriteria { MonitoredEpisodesOnly = true }).Accepted.Should().BeTrue();
+ }
+
+ [Test]
+ public void indexer_with_tags_series_with_matching_tags_should_return_true()
+ {
+ _fakeIndexerDefinition.Tags = new HashSet { 123, 456 };
+ _fakeArtist.Tags = new HashSet { 123, 789 };
+
+ _specification.IsSatisfiedBy(_parseResultMulti, new AlbumSearchCriteria { MonitoredEpisodesOnly = true }).Accepted.Should().BeTrue();
+ }
+
+ [Test]
+ public void indexer_with_tags_series_with_different_tags_should_return_false()
+ {
+ _fakeIndexerDefinition.Tags = new HashSet { 456 };
+ _fakeArtist.Tags = new HashSet { 123, 789 };
+
+ _specification.IsSatisfiedBy(_parseResultMulti, new AlbumSearchCriteria { MonitoredEpisodesOnly = true }).Accepted.Should().BeFalse();
+ }
+
+ [Test]
+ public void release_without_indexerid_should_return_true()
+ {
+ _fakeIndexerDefinition.Tags = new HashSet { 456 };
+ _fakeArtist.Tags = new HashSet { 123, 789 };
+ _fakeRelease.IndexerId = 0;
+
+ _specification.IsSatisfiedBy(_parseResultMulti, new AlbumSearchCriteria { MonitoredEpisodesOnly = true }).Accepted.Should().BeTrue();
+ }
+
+ [Test]
+ public void release_with_invalid_indexerid_should_return_true()
+ {
+ _fakeIndexerDefinition.Tags = new HashSet { 456 };
+ _fakeArtist.Tags = new HashSet { 123, 789 };
+ _fakeRelease.IndexerId = 2;
+
+ _specification.IsSatisfiedBy(_parseResultMulti, new AlbumSearchCriteria { MonitoredEpisodesOnly = true }).Accepted.Should().BeTrue();
+ }
+ }
+}
diff --git a/src/NzbDrone.Core.Test/IndexerTests/IndexerServiceFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/IndexerServiceFixture.cs
index 4cc12f77b..4ade676d9 100644
--- a/src/NzbDrone.Core.Test/IndexerTests/IndexerServiceFixture.cs
+++ b/src/NzbDrone.Core.Test/IndexerTests/IndexerServiceFixture.cs
@@ -1,10 +1,10 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
using FizzWare.NBuilder;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Indexers;
+using NzbDrone.Core.Indexers.FileList;
using NzbDrone.Core.Indexers.Newznab;
-using NzbDrone.Core.Indexers.Omgwtfnzbs;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Test.Framework;
@@ -20,7 +20,7 @@ namespace NzbDrone.Core.Test.IndexerTests
_indexers = new List();
_indexers.Add(Mocker.Resolve());
- _indexers.Add(Mocker.Resolve());
+ _indexers.Add(Mocker.Resolve());
Mocker.SetConstant>(_indexers);
}
diff --git a/src/NzbDrone.Core.Test/IndexerTests/OmgwtfnzbsTests/OmgwtfnzbsFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/OmgwtfnzbsTests/OmgwtfnzbsFixture.cs
deleted file mode 100644
index 1b19fd7f1..000000000
--- a/src/NzbDrone.Core.Test/IndexerTests/OmgwtfnzbsTests/OmgwtfnzbsFixture.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-using System;
-using System.Linq;
-using FluentAssertions;
-using Moq;
-using NUnit.Framework;
-using NzbDrone.Common.Http;
-using NzbDrone.Core.Indexers;
-using NzbDrone.Core.Indexers.Omgwtfnzbs;
-using NzbDrone.Core.Test.Framework;
-
-namespace NzbDrone.Core.Test.IndexerTests.OmgwtfnzbsTests
-{
- [TestFixture]
- public class OmgwtfnzbsFixture : CoreTest
- {
- [SetUp]
- public void Setup()
- {
- Subject.Definition = new IndexerDefinition()
- {
- Name = "Omgwtfnzbs",
- Settings = new OmgwtfnzbsSettings()
- {
- ApiKey = "xxx",
- Username = "me@my.domain"
- }
- };
- }
-
- [Test]
- public void should_parse_recent_feed_from_omgwtfnzbs()
- {
- var recentFeed = ReadAllText(@"Files/Indexers/Omgwtfnzbs/Omgwtfnzbs.xml");
-
- Mocker.GetMock()
- .Setup(o => o.Execute(It.Is(v => v.Method == HttpMethod.GET)))
- .Returns(r => new HttpResponse(r, new HttpHeader(), recentFeed));
-
- var releases = Subject.FetchRecent();
-
- releases.Should().HaveCount(100);
-
- var releaseInfo = releases.First();
-
- releaseInfo.Title.Should().Be("Stephen.Fry.Gadget.Man.S01E05.HDTV.x264-C4TV");
- releaseInfo.DownloadProtocol.Should().Be(DownloadProtocol.Usenet);
- releaseInfo.DownloadUrl.Should().Be("http://api.omgwtfnzbs.org/sn.php?id=OAl4g&user=nzbdrone&api=nzbdrone");
- releaseInfo.InfoUrl.Should().Be("http://omgwtfnzbs.org/details.php?id=OAl4g");
- releaseInfo.CommentUrl.Should().BeNullOrEmpty();
- releaseInfo.Indexer.Should().Be(Subject.Definition.Name);
- releaseInfo.PublishDate.Should().Be(DateTime.Parse("2012/12/17 23:30:13"));
- releaseInfo.Size.Should().Be(236822906);
- }
- }
-}
diff --git a/src/NzbDrone.Core.Test/IndexerTests/WafflesTests/WafflesFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/WafflesTests/WafflesFixture.cs
deleted file mode 100644
index eb313b1ef..000000000
--- a/src/NzbDrone.Core.Test/IndexerTests/WafflesTests/WafflesFixture.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-using System;
-using System.Linq;
-using FluentAssertions;
-using Moq;
-using NUnit.Framework;
-using NzbDrone.Common.Http;
-using NzbDrone.Core.Indexers;
-using NzbDrone.Core.Indexers.Waffles;
-using NzbDrone.Core.Test.Framework;
-
-namespace NzbDrone.Core.Test.IndexerTests.WafflesTests
-{
- [TestFixture]
- public class WafflesFixture : CoreTest
- {
- [SetUp]
- public void Setup()
- {
- Subject.Definition = new IndexerDefinition()
- {
- Name = "Waffles",
- Settings = new WafflesSettings()
- {
- UserId = "xxx",
- RssPasskey = "123456789"
- }
- };
- }
-
- [Test]
- public void should_parse_recent_feed_from_waffles()
- {
- var recentFeed = ReadAllText(@"Files/Indexers/Waffles/waffles.xml");
-
- Mocker.GetMock()
- .Setup(o => o.Execute(It.Is(v => v.Method == HttpMethod.GET)))
- .Returns(r => new HttpResponse(r, new HttpHeader(), recentFeed));
-
- var releases = Subject.FetchRecent();
-
- releases.Should().HaveCount(15);
-
- var releaseInfo = releases.First();
-
- releaseInfo.Title.Should().Be("Coldplay - Kaleidoscope EP (FLAC HD) [2017-Web-FLAC-Lossless]");
- releaseInfo.DownloadProtocol.Should().Be(DownloadProtocol.Torrent);
- releaseInfo.DownloadUrl.Should().Be("https://waffles.ch/download.php/xxx/1166992/" +
- "Coldplay%20-%20Kaleidoscope%20EP%20%28FLAC%20HD%29%20%5B2017-Web-FLAC-Lossless%5D.torrent?passkey=123456789&uid=xxx&rss=1");
- releaseInfo.InfoUrl.Should().Be("https://waffles.ch/details.php?id=1166992&hit=1");
- releaseInfo.CommentUrl.Should().Be("https://waffles.ch/details.php?id=1166992&hit=1");
- releaseInfo.Indexer.Should().Be(Subject.Definition.Name);
- releaseInfo.PublishDate.Should().Be(DateTime.Parse("2017-07-16 09:51:54"));
- releaseInfo.Size.Should().Be(552668227);
- }
- }
-}
diff --git a/src/NzbDrone.Core/Datastore/Migration/059_indexer_tags.cs b/src/NzbDrone.Core/Datastore/Migration/059_indexer_tags.cs
new file mode 100644
index 000000000..e45340a3c
--- /dev/null
+++ b/src/NzbDrone.Core/Datastore/Migration/059_indexer_tags.cs
@@ -0,0 +1,17 @@
+using FluentMigrator;
+using NzbDrone.Core.Datastore.Migration.Framework;
+
+namespace NzbDrone.Core.Datastore.Migration
+{
+ [Migration(059)]
+ public class add_indexer_tags : NzbDroneMigrationBase
+ {
+ protected override void MainDbUpgrade()
+ {
+ Execute.Sql("DELETE FROM Indexers WHERE Implementation = 'Omgwtfnzbs'");
+ Execute.Sql("DELETE FROM Indexers WHERE Implementation = 'Waffles'");
+
+ Alter.Table("Indexers").AddColumn("Tags").AsString().Nullable();
+ }
+ }
+}
diff --git a/src/NzbDrone.Core/Datastore/TableMapping.cs b/src/NzbDrone.Core/Datastore/TableMapping.cs
index f1554484d..096ec53b1 100644
--- a/src/NzbDrone.Core/Datastore/TableMapping.cs
+++ b/src/NzbDrone.Core/Datastore/TableMapping.cs
@@ -68,8 +68,7 @@ namespace NzbDrone.Core.Datastore
.Ignore(i => i.Enable)
.Ignore(i => i.Protocol)
.Ignore(i => i.SupportsRss)
- .Ignore(i => i.SupportsSearch)
- .Ignore(d => d.Tags);
+ .Ignore(i => i.SupportsSearch);
Mapper.Entity("ImportLists").RegisterModel()
.Ignore(x => x.ImplementationName)
diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/IndexerTagSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/IndexerTagSpecification.cs
new file mode 100644
index 000000000..68d6b0277
--- /dev/null
+++ b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/IndexerTagSpecification.cs
@@ -0,0 +1,56 @@
+using System.Linq;
+using NLog;
+using NzbDrone.Common.Extensions;
+using NzbDrone.Core.Datastore;
+using NzbDrone.Core.Indexers;
+using NzbDrone.Core.IndexerSearch.Definitions;
+using NzbDrone.Core.Parser.Model;
+
+namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync
+{
+ public class IndexerTagSpecification : IDecisionEngineSpecification
+ {
+ private readonly Logger _logger;
+ private readonly IIndexerFactory _indexerFactory;
+
+ public IndexerTagSpecification(Logger logger, IIndexerFactory indexerFactory)
+ {
+ _logger = logger;
+ _indexerFactory = indexerFactory;
+ }
+
+ public SpecificationPriority Priority => SpecificationPriority.Default;
+ public RejectionType Type => RejectionType.Permanent;
+
+ public virtual Decision IsSatisfiedBy(RemoteAlbum subject, SearchCriteriaBase searchCriteria)
+ {
+ if (subject.Release == null || subject.Artist?.Tags == null || subject.Release.IndexerId == 0)
+ {
+ return Decision.Accept();
+ }
+
+ IndexerDefinition indexer;
+ try
+ {
+ indexer = _indexerFactory.Get(subject.Release.IndexerId);
+ }
+ catch (ModelNotFoundException)
+ {
+ _logger.Debug("Indexer with id {0} does not exist, skipping indexer tags check", subject.Release.IndexerId);
+ return Decision.Accept();
+ }
+
+ // If indexer has tags, check that at least one of them is present on the series
+ var indexerTags = indexer.Tags;
+
+ if (indexerTags.Any() && indexerTags.Intersect(subject.Artist.Tags).Empty())
+ {
+ _logger.Debug("Indexer {0} has tags. None of these are present on artist {1}. Rejecting", subject.Release.Indexer, subject.Artist);
+
+ return Decision.Reject("Artist tags do not match any of the indexer tags");
+ }
+
+ return Decision.Accept();
+ }
+ }
+}
diff --git a/src/NzbDrone.Core/IndexerSearch/NzbSearchService.cs b/src/NzbDrone.Core/IndexerSearch/NzbSearchService.cs
index 89ff4e779..a3c3644af 100644
--- a/src/NzbDrone.Core/IndexerSearch/NzbSearchService.cs
+++ b/src/NzbDrone.Core/IndexerSearch/NzbSearchService.cs
@@ -125,6 +125,9 @@ namespace NzbDrone.Core.IndexerSearch
_indexerFactory.InteractiveSearchEnabled() :
_indexerFactory.AutomaticSearchEnabled();
+ // Filter indexers to untagged indexers and indexers with intersecting tags
+ indexers = indexers.Where(i => i.Definition.Tags.Empty() || i.Definition.Tags.Intersect(criteriaBase.Artist.Tags).Any()).ToList();
+
var reports = new List();
_logger.ProgressInfo("Searching indexers for {0}. {1} active indexers", criteriaBase, indexers.Count);
diff --git a/src/NzbDrone.Core/Indexers/Newznab/Newznab.cs b/src/NzbDrone.Core/Indexers/Newznab/Newznab.cs
index a0109a5fe..5e49f5b18 100644
--- a/src/NzbDrone.Core/Indexers/Newznab/Newznab.cs
+++ b/src/NzbDrone.Core/Indexers/Newznab/Newznab.cs
@@ -47,7 +47,6 @@ namespace NzbDrone.Core.Indexers.Newznab
yield return GetDefinition("NZBFinder.ws", GetSettings("https://nzbfinder.ws"));
yield return GetDefinition("NZBgeek", GetSettings("https://api.nzbgeek.info"));
yield return GetDefinition("nzbplanet.net", GetSettings("https://api.nzbplanet.net"));
- yield return GetDefinition("omgwtfnzbs", GetSettings("https://api.omgwtfnzbs.me"));
yield return GetDefinition("OZnzb.com", GetSettings("https://api.oznzb.com"));
yield return GetDefinition("SimplyNZBs", GetSettings("https://simplynzbs.com"));
yield return GetDefinition("Tabula Rasa", GetSettings("https://www.tabula-rasa.pw", apiPath: @"/api/v1/api"));
diff --git a/src/NzbDrone.Core/Indexers/Omgwtfnzbs/Omgwtfnzbs.cs b/src/NzbDrone.Core/Indexers/Omgwtfnzbs/Omgwtfnzbs.cs
deleted file mode 100644
index e4f1bb56b..000000000
--- a/src/NzbDrone.Core/Indexers/Omgwtfnzbs/Omgwtfnzbs.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using NLog;
-using NzbDrone.Common.Http;
-using NzbDrone.Core.Configuration;
-using NzbDrone.Core.Parser;
-
-namespace NzbDrone.Core.Indexers.Omgwtfnzbs
-{
- public class Omgwtfnzbs : HttpIndexerBase
- {
- public override string Name => "omgwtfnzbs";
-
- public override DownloadProtocol Protocol => DownloadProtocol.Usenet;
-
- public Omgwtfnzbs(IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger)
- : base(httpClient, indexerStatusService, configService, parsingService, logger)
- {
- }
-
- public override IIndexerRequestGenerator GetRequestGenerator()
- {
- return new OmgwtfnzbsRequestGenerator() { Settings = Settings };
- }
-
- public override IParseIndexerResponse GetParser()
- {
- return new OmgwtfnzbsRssParser();
- }
- }
-}
diff --git a/src/NzbDrone.Core/Indexers/Omgwtfnzbs/OmgwtfnzbsRequestGenerator.cs b/src/NzbDrone.Core/Indexers/Omgwtfnzbs/OmgwtfnzbsRequestGenerator.cs
deleted file mode 100644
index 80e73e276..000000000
--- a/src/NzbDrone.Core/Indexers/Omgwtfnzbs/OmgwtfnzbsRequestGenerator.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-using System.Collections.Generic;
-using System.Text;
-using NzbDrone.Common.Extensions;
-using NzbDrone.Common.Http;
-using NzbDrone.Core.IndexerSearch.Definitions;
-
-namespace NzbDrone.Core.Indexers.Omgwtfnzbs
-{
- public class OmgwtfnzbsRequestGenerator : IIndexerRequestGenerator
- {
- public string BaseUrl { get; set; }
- public OmgwtfnzbsSettings Settings { get; set; }
-
- public OmgwtfnzbsRequestGenerator()
- {
- BaseUrl = "https://rss.omgwtfnzbs.me/rss-download.php";
- }
-
- public virtual IndexerPageableRequestChain GetRecentRequests()
- {
- var pageableRequests = new IndexerPageableRequestChain();
-
- pageableRequests.Add(GetPagedRequests(null));
-
- return pageableRequests;
- }
-
- public virtual IndexerPageableRequestChain GetSearchRequests(AlbumSearchCriteria searchCriteria)
- {
- var pageableRequests = new IndexerPageableRequestChain();
-
- pageableRequests.Add(GetPagedRequests(string.Format("{0}+{1}",
- searchCriteria.ArtistQuery,
- searchCriteria.AlbumQuery)));
-
- return pageableRequests;
- }
-
- public virtual IndexerPageableRequestChain GetSearchRequests(ArtistSearchCriteria searchCriteria)
- {
- var pageableRequests = new IndexerPageableRequestChain();
-
- pageableRequests.Add(GetPagedRequests(string.Format("{0}",
- searchCriteria.ArtistQuery)));
-
- return pageableRequests;
- }
-
- private IEnumerable GetPagedRequests(string query)
- {
- var url = new StringBuilder();
-
- // Category 22 is Music-FLAC, category 7 is Music-MP3
- url.AppendFormat("{0}?catid=22,7&user={1}&api={2}&eng=1&delay={3}", BaseUrl, Settings.Username, Settings.ApiKey, Settings.Delay);
-
- if (query.IsNotNullOrWhiteSpace())
- {
- url = url.Replace("rss-download.php", "rss-search.php");
- url.AppendFormat("&search={0}", query);
- }
-
- yield return new IndexerRequest(url.ToString(), HttpAccept.Rss);
- }
- }
-}
diff --git a/src/NzbDrone.Core/Indexers/Omgwtfnzbs/OmgwtfnzbsRssParser.cs b/src/NzbDrone.Core/Indexers/Omgwtfnzbs/OmgwtfnzbsRssParser.cs
deleted file mode 100644
index 5ff9174e3..000000000
--- a/src/NzbDrone.Core/Indexers/Omgwtfnzbs/OmgwtfnzbsRssParser.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-using System.Linq;
-using System.Text.RegularExpressions;
-using System.Xml.Linq;
-using NzbDrone.Common.Extensions;
-using NzbDrone.Core.Indexers.Exceptions;
-
-namespace NzbDrone.Core.Indexers.Omgwtfnzbs
-{
- public class OmgwtfnzbsRssParser : RssParser
- {
- public OmgwtfnzbsRssParser()
- {
- UseEnclosureUrl = true;
- UseEnclosureLength = true;
- }
-
- protected override bool PreProcess(IndexerResponse indexerResponse)
- {
- var xdoc = LoadXmlDocument(indexerResponse);
- var notice = xdoc.Descendants("notice").FirstOrDefault();
-
- if (notice == null)
- {
- return true;
- }
-
- if (!notice.Value.ContainsIgnoreCase("api"))
- {
- return true;
- }
-
- throw new ApiKeyException(notice.Value);
- }
-
- protected override string GetInfoUrl(XElement item)
- {
- //Todo: Me thinks I need to parse details to get this...
- var match = Regex.Match(item.Description(),
- @"(?:\View NZB\:\<\/b\>\s\.+)(?:\""\starget)",
- RegexOptions.IgnoreCase | RegexOptions.Compiled);
-
- if (match.Success)
- {
- return match.Groups["URL"].Value;
- }
-
- return string.Empty;
- }
- }
-}
diff --git a/src/NzbDrone.Core/Indexers/Omgwtfnzbs/OmgwtfnzbsSettings.cs b/src/NzbDrone.Core/Indexers/Omgwtfnzbs/OmgwtfnzbsSettings.cs
deleted file mode 100644
index ff5eeb02e..000000000
--- a/src/NzbDrone.Core/Indexers/Omgwtfnzbs/OmgwtfnzbsSettings.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-using FluentValidation;
-using NzbDrone.Core.Annotations;
-using NzbDrone.Core.Validation;
-
-namespace NzbDrone.Core.Indexers.Omgwtfnzbs
-{
- public class OmgwtfnzbsSettingsValidator : AbstractValidator
- {
- public OmgwtfnzbsSettingsValidator()
- {
- RuleFor(c => c.Username).NotEmpty();
- RuleFor(c => c.ApiKey).NotEmpty();
- RuleFor(c => c.Delay).GreaterThanOrEqualTo(0);
- }
- }
-
- public class OmgwtfnzbsSettings : IIndexerSettings
- {
- private static readonly OmgwtfnzbsSettingsValidator Validator = new OmgwtfnzbsSettingsValidator();
-
- public OmgwtfnzbsSettings()
- {
- Delay = 30;
- }
-
- // Unused since Omg has a hardcoded url.
- public string BaseUrl { get; set; }
-
- [FieldDefinition(0, Label = "Username", Privacy = PrivacyLevel.UserName)]
- public string Username { get; set; }
-
- [FieldDefinition(1, Label = "API Key", Privacy = PrivacyLevel.ApiKey)]
- public string ApiKey { get; set; }
-
- [FieldDefinition(2, Label = "Delay", HelpText = "Time in minutes to delay new nzbs before they appear on the RSS feed", Advanced = true)]
- public int Delay { get; set; }
-
- [FieldDefinition(3, Type = FieldType.Number, Label = "Early Download Limit", Unit = "days", HelpText = "Time before release date Lidarr will download from this indexer, empty is no limit", Advanced = true)]
- public int? EarlyReleaseLimit { get; set; }
-
- public NzbDroneValidationResult Validate()
- {
- return new NzbDroneValidationResult(Validator.Validate(this));
- }
- }
-}
diff --git a/src/NzbDrone.Core/Indexers/Waffles/Waffles.cs b/src/NzbDrone.Core/Indexers/Waffles/Waffles.cs
deleted file mode 100644
index 9f2377fb2..000000000
--- a/src/NzbDrone.Core/Indexers/Waffles/Waffles.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using NLog;
-using NzbDrone.Common.Http;
-using NzbDrone.Core.Configuration;
-using NzbDrone.Core.Parser;
-
-namespace NzbDrone.Core.Indexers.Waffles
-{
- public class Waffles : HttpIndexerBase
- {
- public override string Name => "Waffles";
-
- public override DownloadProtocol Protocol => DownloadProtocol.Torrent;
- public override int PageSize => 15;
-
- public Waffles(IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger)
- : base(httpClient, indexerStatusService, configService, parsingService, logger)
- {
- }
-
- public override IIndexerRequestGenerator GetRequestGenerator()
- {
- return new WafflesRequestGenerator() { Settings = Settings };
- }
-
- public override IParseIndexerResponse GetParser()
- {
- return new WafflesRssParser() { ParseSizeInDescription = true, ParseSeedersInDescription = true };
- }
- }
-}
diff --git a/src/NzbDrone.Core/Indexers/Waffles/WafflesRequestGenerator.cs b/src/NzbDrone.Core/Indexers/Waffles/WafflesRequestGenerator.cs
deleted file mode 100644
index fa39d562b..000000000
--- a/src/NzbDrone.Core/Indexers/Waffles/WafflesRequestGenerator.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-using System.Collections.Generic;
-using System.Text;
-using NzbDrone.Common.Extensions;
-using NzbDrone.Common.Http;
-using NzbDrone.Core.IndexerSearch.Definitions;
-
-namespace NzbDrone.Core.Indexers.Waffles
-{
- public class WafflesRequestGenerator : IIndexerRequestGenerator
- {
- public WafflesSettings Settings { get; set; }
- public int MaxPages { get; set; }
-
- public WafflesRequestGenerator()
- {
- MaxPages = 5;
- }
-
- public virtual IndexerPageableRequestChain GetRecentRequests()
- {
- var pageableRequests = new IndexerPageableRequestChain();
-
- pageableRequests.Add(GetPagedRequests(MaxPages, null));
-
- return pageableRequests;
- }
-
- public IndexerPageableRequestChain GetSearchRequests(AlbumSearchCriteria searchCriteria)
- {
- var pageableRequests = new IndexerPageableRequestChain();
-
- pageableRequests.Add(GetPagedRequests(MaxPages, string.Format("&q=artist:{0} album:{1}", searchCriteria.ArtistQuery, searchCriteria.AlbumQuery)));
-
- return pageableRequests;
- }
-
- public IndexerPageableRequestChain GetSearchRequests(ArtistSearchCriteria searchCriteria)
- {
- var pageableRequests = new IndexerPageableRequestChain();
-
- pageableRequests.Add(GetPagedRequests(MaxPages, string.Format("&q=artist:{0}", searchCriteria.ArtistQuery)));
-
- return pageableRequests;
- }
-
- private IEnumerable GetPagedRequests(int maxPages, string query)
- {
- var url = new StringBuilder();
-
- url.AppendFormat("{0}/browse.php?rss=1&c0=1&uid={1}&passkey={2}", Settings.BaseUrl.Trim().TrimEnd('/'), Settings.UserId, Settings.RssPasskey);
-
- if (query.IsNotNullOrWhiteSpace())
- {
- url.AppendFormat(query);
- }
-
- for (var page = 0; page < maxPages; page++)
- {
- yield return new IndexerRequest(string.Format("{0}&p={1}", url, page), HttpAccept.Rss);
- }
- }
- }
-}
diff --git a/src/NzbDrone.Core/Indexers/Waffles/WafflesRssParser.cs b/src/NzbDrone.Core/Indexers/Waffles/WafflesRssParser.cs
deleted file mode 100644
index a5744d141..000000000
--- a/src/NzbDrone.Core/Indexers/Waffles/WafflesRssParser.cs
+++ /dev/null
@@ -1,93 +0,0 @@
-using System;
-using System.Globalization;
-using System.Linq;
-using System.Text.RegularExpressions;
-using System.Xml.Linq;
-using NzbDrone.Common.Extensions;
-using NzbDrone.Core.Indexers.Exceptions;
-using NzbDrone.Core.Parser.Model;
-
-namespace NzbDrone.Core.Indexers.Waffles
-{
- public class WafflesRssParser : TorrentRssParser
- {
- public const string ns = "{http://purl.org/rss/1.0/}";
- public const string dc = "{http://purl.org/dc/elements/1.1/}";
-
- protected override bool PreProcess(IndexerResponse indexerResponse)
- {
- var xdoc = LoadXmlDocument(indexerResponse);
- var error = xdoc.Descendants("error").FirstOrDefault();
-
- if (error == null)
- {
- return true;
- }
-
- var code = Convert.ToInt32(error.Attribute("code").Value);
- var errorMessage = error.Attribute("description").Value;
-
- if (code >= 100 && code <= 199)
- {
- throw new ApiKeyException("Invalid Pass key");
- }
-
- if (!indexerResponse.Request.Url.FullUri.Contains("passkey=") && errorMessage == "Missing parameter")
- {
- throw new ApiKeyException("Indexer requires an Pass key");
- }
-
- if (errorMessage == "Request limit reached")
- {
- throw new RequestLimitReachedException("API limit reached");
- }
-
- throw new IndexerException(indexerResponse, errorMessage);
- }
-
- protected override ReleaseInfo ProcessItem(XElement item, ReleaseInfo releaseInfo)
- {
- var torrentInfo = base.ProcessItem(item, releaseInfo) as TorrentInfo;
-
- return torrentInfo;
- }
-
- protected override string GetInfoUrl(XElement item)
- {
- return ParseUrl(item.TryGetValue("comments").TrimEnd("#comments"));
- }
-
- protected override string GetCommentUrl(XElement item)
- {
- return ParseUrl(item.TryGetValue("comments"));
- }
-
- private static readonly Regex ParseSizeRegex = new Regex(@"(?:Size: )(?\d+)<",
- RegexOptions.IgnoreCase | RegexOptions.Compiled);
-
- protected override long GetSize(XElement item)
- {
- var match = ParseSizeRegex.Matches(item.Element("description").Value);
-
- if (match.Count != 0)
- {
- var value = decimal.Parse(Regex.Replace(match[0].Groups["value"].Value, "\\,", ""), CultureInfo.InvariantCulture);
- return (long)value;
- }
-
- return 0;
- }
-
- protected override DateTime GetPublishDate(XElement item)
- {
- var dateString = item.TryGetValue(dc + "date");
-
- if (dateString.IsNullOrWhiteSpace())
- {
- throw new UnsupportedFeedException("Rss feed must have a pubDate element with a valid publish date.");
- }
-
- return XElementExtensions.ParseDate(dateString);
- }
- }
-}
diff --git a/src/NzbDrone.Core/Indexers/Waffles/WafflesSettings.cs b/src/NzbDrone.Core/Indexers/Waffles/WafflesSettings.cs
deleted file mode 100644
index 410cc204c..000000000
--- a/src/NzbDrone.Core/Indexers/Waffles/WafflesSettings.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-using FluentValidation;
-using NzbDrone.Core.Annotations;
-using NzbDrone.Core.Validation;
-
-namespace NzbDrone.Core.Indexers.Waffles
-{
- public class WafflesSettingsValidator : AbstractValidator
- {
- public WafflesSettingsValidator()
- {
- RuleFor(c => c.BaseUrl).ValidRootUrl();
- RuleFor(c => c.UserId).NotEmpty();
- RuleFor(c => c.RssPasskey).NotEmpty();
- }
- }
-
- public class WafflesSettings : ITorrentIndexerSettings
- {
- private static readonly WafflesSettingsValidator Validator = new WafflesSettingsValidator();
-
- public WafflesSettings()
- {
- BaseUrl = "https://www.waffles.ch";
- MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
- }
-
- [FieldDefinition(0, Label = "Website URL")]
- public string BaseUrl { get; set; }
-
- [FieldDefinition(1, Label = "UserId", Privacy = PrivacyLevel.UserName)]
- public string UserId { get; set; }
-
- [FieldDefinition(2, Label = "RSS Passkey", Privacy = PrivacyLevel.ApiKey)]
- public string RssPasskey { get; set; }
-
- [FieldDefinition(3, Type = FieldType.Textbox, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
- public int MinimumSeeders { get; set; }
-
- [FieldDefinition(4)]
- public SeedCriteriaSettings SeedCriteria { get; set; } = new SeedCriteriaSettings();
-
- [FieldDefinition(5, Type = FieldType.Number, Label = "Early Download Limit", Unit = "days", HelpText = "Time before release date Lidarr will download from this indexer, empty is no limit", Advanced = true)]
- public int? EarlyReleaseLimit { get; set; }
-
- public NzbDroneValidationResult Validate()
- {
- return new NzbDroneValidationResult(Validator.Validate(this));
- }
- }
-}
diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json
index ca43a4485..230ce6453 100644
--- a/src/NzbDrone.Core/Localization/Core/en.json
+++ b/src/NzbDrone.Core/Localization/Core/en.json
@@ -269,6 +269,7 @@
"IncludeUnknownArtistItemsHelpText": "Show items without a artist in the queue, this could include removed artists, movies or anything else in Lidarr's category",
"IncludeUnmonitored": "Include Unmonitored",
"Indexer": "Indexer",
+ "IndexerDownloadClientHelpText": "Specify which download client is used for grabs from this indexer",
"IndexerIdHelpText": "Specify what indexer the profile applies to",
"IndexerIdHelpTextWarning": "Using a specific indexer with preferred words can lead to duplicate releases being grabbed",
"IndexerIdvalue0IncludeInPreferredWordsRenamingFormat": "Include in {Preferred Words} renaming format",
@@ -276,6 +277,7 @@
"IndexerPriority": "Indexer Priority",
"Indexers": "Indexers",
"IndexerSettings": "Indexer Settings",
+ "IndexerTagHelpText": "Only use this indexer for artist with at least one matching tag. Leave blank to use with all artists.",
"InstanceName": "Instance Name",
"InstanceNameHelpText": "Instance name in tab and for Syslog app name",
"InteractiveSearch": "Interactive Search",
@@ -321,8 +323,8 @@
"ManualImport": "Manual Import",
"MarkAsFailed": "Mark as Failed",
"MarkAsFailedMessageText": "Are you sure you want to mark '{0}' as failed?",
- "MassAlbumsSearchWarning": "Are you sure you want to search for all '{0}' missing albums?",
"MassAlbumsCutoffUnmetWarning": "Are you sure you want to search for all '{0}' Cutoff Unmet albums?",
+ "MassAlbumsSearchWarning": "Are you sure you want to search for all '{0}' missing albums?",
"MaximumLimits": "Maximum Limits",
"MaximumSize": "Maximum Size",
"MaximumSizeHelpText": "Maximum size for a release to be grabbed in MB. Set to zero to set to unlimited.",
@@ -550,9 +552,9 @@
"SetPermissionsLinuxHelpTextWarning": "If you're unsure what these settings do, do not alter them.",
"Settings": "Settings",
"ShortDateFormat": "Short Date Format",
- "ShouldMonitorHelpText": "Monitor artists and albums added from this list",
"ShouldMonitorExisting": "Monitor existing albums",
"ShouldMonitorExistingHelpText": "Automatically monitor albums on this list which are already in Lidarr",
+ "ShouldMonitorHelpText": "Monitor artists and albums added from this list",
"ShouldSearch": "Search for New Items",
"ShouldSearchHelpText": "Search indexers for newly added items. Use with caution for large lists.",
"ShowAlbumCount": "Show Album Count",
diff --git a/src/NzbDrone.Core/Tags/TagDetails.cs b/src/NzbDrone.Core/Tags/TagDetails.cs
index 1730ce760..f11fc802e 100644
--- a/src/NzbDrone.Core/Tags/TagDetails.cs
+++ b/src/NzbDrone.Core/Tags/TagDetails.cs
@@ -13,12 +13,13 @@ namespace NzbDrone.Core.Tags
public List DelayProfileIds { get; set; }
public List ImportListIds { get; set; }
public List RootFolderIds { get; set; }
+ public List IndexerIds { get; set; }
public bool InUse
{
get
{
- return ArtistIds.Any() || NotificationIds.Any() || RestrictionIds.Any() || DelayProfileIds.Any() || ImportListIds.Any() || RootFolderIds.Any();
+ return ArtistIds.Any() || NotificationIds.Any() || RestrictionIds.Any() || DelayProfileIds.Any() || ImportListIds.Any() || RootFolderIds.Any() || IndexerIds.Any();
}
}
}
diff --git a/src/NzbDrone.Core/Tags/TagService.cs b/src/NzbDrone.Core/Tags/TagService.cs
index 7ef08df3c..328e3f251 100644
--- a/src/NzbDrone.Core/Tags/TagService.cs
+++ b/src/NzbDrone.Core/Tags/TagService.cs
@@ -2,6 +2,7 @@ using System.Collections.Generic;
using System.Linq;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.ImportLists;
+using NzbDrone.Core.Indexers;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Music;
using NzbDrone.Core.Notifications;
@@ -33,6 +34,7 @@ namespace NzbDrone.Core.Tags
private readonly IReleaseProfileService _releaseProfileService;
private readonly IArtistService _artistService;
private readonly IRootFolderService _rootFolderService;
+ private readonly IIndexerFactory _indexerService;
public TagService(ITagRepository repo,
IEventAggregator eventAggregator,
@@ -41,7 +43,8 @@ namespace NzbDrone.Core.Tags
INotificationFactory notificationFactory,
IReleaseProfileService releaseProfileService,
IArtistService artistService,
- IRootFolderService rootFolderService)
+ IRootFolderService rootFolderService,
+ IIndexerFactory indexerService)
{
_repo = repo;
_eventAggregator = eventAggregator;
@@ -51,6 +54,7 @@ namespace NzbDrone.Core.Tags
_releaseProfileService = releaseProfileService;
_artistService = artistService;
_rootFolderService = rootFolderService;
+ _indexerService = indexerService;
}
public Tag GetTag(int tagId)
@@ -79,6 +83,7 @@ namespace NzbDrone.Core.Tags
var restrictions = _releaseProfileService.AllForTag(tagId);
var artist = _artistService.AllForTag(tagId);
var rootFolders = _rootFolderService.AllForTag(tagId);
+ var indexers = _indexerService.AllForTag(tagId);
return new TagDetails
{
@@ -89,7 +94,8 @@ namespace NzbDrone.Core.Tags
NotificationIds = notifications.Select(c => c.Id).ToList(),
RestrictionIds = restrictions.Select(c => c.Id).ToList(),
ArtistIds = artist.Select(c => c.Id).ToList(),
- RootFolderIds = rootFolders.Select(c => c.Id).ToList()
+ RootFolderIds = rootFolders.Select(c => c.Id).ToList(),
+ IndexerIds = indexers.Select(c => c.Id).ToList()
};
}
@@ -102,6 +108,7 @@ namespace NzbDrone.Core.Tags
var restrictions = _releaseProfileService.All();
var artists = _artistService.GetAllArtists();
var rootFolders = _rootFolderService.All();
+ var indexers = _indexerService.All();
var details = new List();
@@ -116,7 +123,8 @@ namespace NzbDrone.Core.Tags
NotificationIds = notifications.Where(c => c.Tags.Contains(tag.Id)).Select(c => c.Id).ToList(),
RestrictionIds = restrictions.Where(c => c.Tags.Contains(tag.Id)).Select(c => c.Id).ToList(),
ArtistIds = artists.Where(c => c.Tags.Contains(tag.Id)).Select(c => c.Id).ToList(),
- RootFolderIds = rootFolders.Where(c => c.DefaultTags.Contains(tag.Id)).Select(c => c.Id).ToList()
+ RootFolderIds = rootFolders.Where(c => c.DefaultTags.Contains(tag.Id)).Select(c => c.Id).ToList(),
+ IndexerIds = indexers.Where(c => c.Tags.Contains(tag.Id)).Select(c => c.Id).ToList()
});
}