New: Index priority

This commit is contained in:
Dtaggart 2020-09-10 18:04:53 -04:00 committed by ta264
parent 2f8ac793ff
commit 916acdb81a
11 changed files with 93 additions and 4 deletions

View file

@ -42,7 +42,8 @@ function EditIndexerModalContent(props) {
enableInteractiveSearch,
supportsRss,
supportsSearch,
fields
fields,
priority
} = item;
return (
@ -131,7 +132,21 @@ function EditIndexerModalContent(props) {
);
})
}
<FormGroup
advancedSettings={advancedSettings}
isAdvanced={true}>
<FormLabel>Indexer Priority</FormLabel>
<FormInputGroup
type={inputTypes.NUMBER}
name="priority"
helpText="Indexer Priority from 1 (Highest) to 50 (Lowest). Default: 25."
min={1}
max={50}
{...priority}
onChange={onInputChange}
/>
</FormGroup>
</Form>
}
</ModalBody>

View file

@ -58,7 +58,9 @@ class Indexer extends Component {
enableAutomaticSearch,
enableInteractiveSearch,
supportsRss,
supportsSearch
supportsSearch,
priority,
showPriority
} = this.props;
return (
@ -93,7 +95,13 @@ class Indexer extends Component {
Interactive Search
</Label>
}
{
showPriority &&
<Label kind={kinds.DEFAULT}>
Priority: {priority}
</Label>
}
{
!enableRss && !enableAutomaticSearch && !enableInteractiveSearch &&
<Label

View file

@ -56,6 +56,8 @@ class Indexers extends Component {
isAddIndexerModalOpen,
isEditIndexerModalOpen
} = this.state;
const showPriority = items.some((index) => index.priority != 25);
return (
<FieldSet legend="Indexers">
@ -70,6 +72,7 @@ class Indexers extends Component {
<Indexer
key={item.id}
{...item}
showPriority={showPriority}
onConfirmDeleteIndexer={onConfirmDeleteIndexer}
/>
);

View file

@ -34,7 +34,7 @@ private Book GivenAlbum(int id)
.Build();
}
private RemoteBook GivenRemoteAlbum(List<Book> albums, QualityModel quality, int age = 0, long size = 0, DownloadProtocol downloadProtocol = DownloadProtocol.Usenet)
private RemoteBook GivenRemoteAlbum(List<Book> albums, QualityModel quality, int age = 0, long size = 0, DownloadProtocol downloadProtocol = DownloadProtocol.Usenet, int indexerPriority = 25)
{
var remoteBook = new RemoteBook();
remoteBook.ParsedBookInfo = new ParsedBookInfo();
@ -47,6 +47,7 @@ private RemoteBook GivenRemoteAlbum(List<Book> albums, QualityModel quality, int
remoteBook.Release.PublishDate = DateTime.Now.AddDays(-age);
remoteBook.Release.Size = size;
remoteBook.Release.DownloadProtocol = downloadProtocol;
remoteBook.Release.IndexerPriority = indexerPriority;
remoteBook.Author = Builder<Author>.CreateNew()
.With(e => e.QualityProfile = new QualityProfile
@ -476,5 +477,39 @@ public void should_prefer_score_over_proper_when_download_propers_is_do_not_pref
qualifiedReports.First().RemoteBook.ParsedBookInfo.Quality.Revision.Version.Should().Be(1);
qualifiedReports.First().RemoteBook.PreferredWordScore.Should().Be(10);
}
[Test]
public void sort_download_decisions_based_on_indexer_priority()
{
var remoteAlbum1 = GivenRemoteAlbum(new List<Book> { GivenAlbum(1) }, new QualityModel(Quality.AZW3, new Revision(1)), indexerPriority: 25);
var remoteAlbum2 = GivenRemoteAlbum(new List<Book> { GivenAlbum(1) }, new QualityModel(Quality.AZW3, new Revision(1)), indexerPriority: 50);
var remoteAlbum3 = GivenRemoteAlbum(new List<Book> { GivenAlbum(1) }, new QualityModel(Quality.AZW3, new Revision(1)), indexerPriority: 1);
var decisions = new List<DownloadDecision>();
decisions.AddRange(new[] { new DownloadDecision(remoteAlbum1), new DownloadDecision(remoteAlbum2), new DownloadDecision(remoteAlbum3) });
var qualifiedReports = Subject.PrioritizeDecisions(decisions);
qualifiedReports.First().RemoteBook.Should().Be(remoteAlbum3);
qualifiedReports.Skip(1).First().RemoteBook.Should().Be(remoteAlbum1);
qualifiedReports.Last().RemoteBook.Should().Be(remoteAlbum2);
}
[Test]
public void ensure_download_decisions_indexer_priority_is_not_perfered_over_quality()
{
var remoteAlbum1 = GivenRemoteAlbum(new List<Book> { GivenAlbum(1) }, new QualityModel(Quality.EPUB, new Revision(1)), indexerPriority: 25);
var remoteAlbum2 = GivenRemoteAlbum(new List<Book> { GivenAlbum(1) }, new QualityModel(Quality.AZW3, new Revision(1)), indexerPriority: 50);
var remoteAlbum3 = GivenRemoteAlbum(new List<Book> { GivenAlbum(1) }, new QualityModel(Quality.PDF, new Revision(1)), indexerPriority: 1);
var remoteAlbum4 = GivenRemoteAlbum(new List<Book> { GivenAlbum(1) }, new QualityModel(Quality.AZW3, new Revision(1)), indexerPriority: 25);
var decisions = new List<DownloadDecision>();
decisions.AddRange(new[] { new DownloadDecision(remoteAlbum1), new DownloadDecision(remoteAlbum2), new DownloadDecision(remoteAlbum3), new DownloadDecision(remoteAlbum4) });
var qualifiedReports = Subject.PrioritizeDecisions(decisions);
qualifiedReports.First().RemoteBook.Should().Be(remoteAlbum4);
qualifiedReports.Skip(1).First().RemoteBook.Should().Be(remoteAlbum2);
qualifiedReports.Skip(2).First().RemoteBook.Should().Be(remoteAlbum1);
qualifiedReports.Last().RemoteBook.Should().Be(remoteAlbum3);
}
}
}

View file

@ -0,0 +1,14 @@
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(003)]
public class add_priority_to_indexers : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Alter.Table("Indexers").AddColumn("Priority").AsInt32().NotNullable().WithDefaultValue(25);
}
}
}

View file

@ -30,6 +30,7 @@ public int Compare(DownloadDecision x, DownloadDecision y)
CompareQuality,
ComparePreferredWordScore,
CompareProtocol,
CompareIndexerPriority,
ComparePeersIfTorrent,
CompareBookCount,
CompareAgeIfUsenet,
@ -59,6 +60,11 @@ private int CompareAll(params int[] comparers)
return comparers.Select(comparer => comparer).FirstOrDefault(result => result != 0);
}
private int CompareIndexerPriority(DownloadDecision x, DownloadDecision y)
{
return CompareByReverse(x.RemoteBook.Release, y.RemoteBook.Release, release => release.IndexerPriority);
}
private int CompareQuality(DownloadDecision x, DownloadDecision y)
{
if (_configService.DownloadPropersAndRepacks == ProperDownloadTypes.DoNotPrefer)

View file

@ -74,6 +74,7 @@ public ProcessedDecisions ProcessDecisions(List<DownloadDecision> decisions)
try
{
_logger.Trace("Grabbing from Indexer {0} at priority {1}.", remoteBook.Release.Indexer, remoteBook.Release.IndexerPriority);
_downloadService.DownloadReport(remoteBook);
grabbed.Add(report);
}

View file

@ -22,6 +22,7 @@ public abstract class IndexerBase<TSettings> : IIndexer
public abstract string Name { get; }
public abstract DownloadProtocol Protocol { get; }
public int Priority { get; set; }
public abstract bool SupportsRss { get; }
public abstract bool SupportsSearch { get; }
@ -80,6 +81,7 @@ protected virtual IList<ReleaseInfo> CleanupReleases(IEnumerable<ReleaseInfo> re
c.IndexerId = Definition.Id;
c.Indexer = Definition.Name;
c.DownloadProtocol = Protocol;
c.IndexerPriority = ((IndexerDefinition)Definition).Priority;
});
return result;

View file

@ -10,6 +10,7 @@ public class IndexerDefinition : ProviderDefinition
public DownloadProtocol Protocol { get; set; }
public bool SupportsRss { get; set; }
public bool SupportsSearch { get; set; }
public int Priority { get; set; } = 25;
public override bool Enable => EnableRss || EnableAutomaticSearch || EnableInteractiveSearch;

View file

@ -17,6 +17,7 @@ public class ReleaseInfo
public string Indexer { get; set; }
public string Author { get; set; }
public string Book { get; set; }
public int IndexerPriority { get; set; }
public DownloadProtocol DownloadProtocol { get; set; }
public DateTime PublishDate { get; set; }

View file

@ -10,6 +10,7 @@ public class IndexerResource : ProviderResource
public bool SupportsRss { get; set; }
public bool SupportsSearch { get; set; }
public DownloadProtocol Protocol { get; set; }
public int Priority { get; set; }
}
public class IndexerResourceMapper : ProviderResourceMapper<IndexerResource, IndexerDefinition>
@ -29,6 +30,7 @@ public override IndexerResource ToResource(IndexerDefinition definition)
resource.SupportsRss = definition.SupportsRss;
resource.SupportsSearch = definition.SupportsSearch;
resource.Protocol = definition.Protocol;
resource.Priority = definition.Priority;
return resource;
}
@ -45,6 +47,7 @@ public override IndexerDefinition ToModel(IndexerResource resource)
definition.EnableRss = resource.EnableRss;
definition.EnableAutomaticSearch = resource.EnableAutomaticSearch;
definition.EnableInteractiveSearch = resource.EnableInteractiveSearch;
definition.Priority = resource.Priority;
return definition;
}