mirror of
https://github.com/lidarr/lidarr.git
synced 2025-07-30 03:38:26 -07:00
New: Index priority
This commit is contained in:
parent
c913194fdf
commit
2655430c98
11 changed files with 93 additions and 4 deletions
|
@ -42,7 +42,8 @@ function EditIndexerModalContent(props) {
|
||||||
enableInteractiveSearch,
|
enableInteractiveSearch,
|
||||||
supportsRss,
|
supportsRss,
|
||||||
supportsSearch,
|
supportsSearch,
|
||||||
fields
|
fields,
|
||||||
|
priority
|
||||||
} = item;
|
} = item;
|
||||||
|
|
||||||
return (
|
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>
|
</Form>
|
||||||
}
|
}
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
|
|
|
@ -68,7 +68,9 @@ class Indexer extends Component {
|
||||||
enableAutomaticSearch,
|
enableAutomaticSearch,
|
||||||
enableInteractiveSearch,
|
enableInteractiveSearch,
|
||||||
supportsRss,
|
supportsRss,
|
||||||
supportsSearch
|
supportsSearch,
|
||||||
|
priority,
|
||||||
|
showPriority
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -112,7 +114,13 @@ class Indexer extends Component {
|
||||||
Interactive Search
|
Interactive Search
|
||||||
</Label>
|
</Label>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
showPriority &&
|
||||||
|
<Label kind={kinds.DEFAULT}>
|
||||||
|
Priority: {priority}
|
||||||
|
</Label>
|
||||||
|
}
|
||||||
{
|
{
|
||||||
!enableRss && !enableAutomaticSearch && !enableInteractiveSearch &&
|
!enableRss && !enableAutomaticSearch && !enableInteractiveSearch &&
|
||||||
<Label
|
<Label
|
||||||
|
|
|
@ -62,6 +62,8 @@ class Indexers extends Component {
|
||||||
isAddIndexerModalOpen,
|
isAddIndexerModalOpen,
|
||||||
isEditIndexerModalOpen
|
isEditIndexerModalOpen
|
||||||
} = this.state;
|
} = this.state;
|
||||||
|
|
||||||
|
const showPriority = items.some((index) => index.priority != 25);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FieldSet legend="Indexers">
|
<FieldSet legend="Indexers">
|
||||||
|
@ -76,6 +78,7 @@ class Indexers extends Component {
|
||||||
<Indexer
|
<Indexer
|
||||||
key={item.id}
|
key={item.id}
|
||||||
{...item}
|
{...item}
|
||||||
|
showPriority={showPriority}
|
||||||
onCloneIndexerPress={this.onCloneIndexerPress}
|
onCloneIndexerPress={this.onCloneIndexerPress}
|
||||||
onConfirmDeleteIndexer={onConfirmDeleteIndexer}
|
onConfirmDeleteIndexer={onConfirmDeleteIndexer}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -10,6 +10,7 @@ namespace Lidarr.Api.V1.Indexers
|
||||||
public bool SupportsRss { get; set; }
|
public bool SupportsRss { get; set; }
|
||||||
public bool SupportsSearch { get; set; }
|
public bool SupportsSearch { get; set; }
|
||||||
public DownloadProtocol Protocol { get; set; }
|
public DownloadProtocol Protocol { get; set; }
|
||||||
|
public int Priority { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class IndexerResourceMapper : ProviderResourceMapper<IndexerResource, IndexerDefinition>
|
public class IndexerResourceMapper : ProviderResourceMapper<IndexerResource, IndexerDefinition>
|
||||||
|
@ -29,6 +30,7 @@ namespace Lidarr.Api.V1.Indexers
|
||||||
resource.SupportsRss = definition.SupportsRss;
|
resource.SupportsRss = definition.SupportsRss;
|
||||||
resource.SupportsSearch = definition.SupportsSearch;
|
resource.SupportsSearch = definition.SupportsSearch;
|
||||||
resource.Protocol = definition.Protocol;
|
resource.Protocol = definition.Protocol;
|
||||||
|
resource.Priority = definition.Priority;
|
||||||
|
|
||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
|
@ -45,6 +47,7 @@ namespace Lidarr.Api.V1.Indexers
|
||||||
definition.EnableRss = resource.EnableRss;
|
definition.EnableRss = resource.EnableRss;
|
||||||
definition.EnableAutomaticSearch = resource.EnableAutomaticSearch;
|
definition.EnableAutomaticSearch = resource.EnableAutomaticSearch;
|
||||||
definition.EnableInteractiveSearch = resource.EnableInteractiveSearch;
|
definition.EnableInteractiveSearch = resource.EnableInteractiveSearch;
|
||||||
|
definition.Priority = resource.Priority;
|
||||||
|
|
||||||
return definition;
|
return definition;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
.Build();
|
.Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private RemoteAlbum GivenRemoteAlbum(List<Album> albums, QualityModel quality, int age = 0, long size = 0, DownloadProtocol downloadProtocol = DownloadProtocol.Usenet)
|
private RemoteAlbum GivenRemoteAlbum(List<Album> albums, QualityModel quality, int age = 0, long size = 0, DownloadProtocol downloadProtocol = DownloadProtocol.Usenet, int indexerPriority = 25)
|
||||||
{
|
{
|
||||||
var remoteAlbum = new RemoteAlbum();
|
var remoteAlbum = new RemoteAlbum();
|
||||||
remoteAlbum.ParsedAlbumInfo = new ParsedAlbumInfo();
|
remoteAlbum.ParsedAlbumInfo = new ParsedAlbumInfo();
|
||||||
|
@ -47,6 +47,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
remoteAlbum.Release.PublishDate = DateTime.Now.AddDays(-age);
|
remoteAlbum.Release.PublishDate = DateTime.Now.AddDays(-age);
|
||||||
remoteAlbum.Release.Size = size;
|
remoteAlbum.Release.Size = size;
|
||||||
remoteAlbum.Release.DownloadProtocol = downloadProtocol;
|
remoteAlbum.Release.DownloadProtocol = downloadProtocol;
|
||||||
|
remoteAlbum.Release.IndexerPriority = indexerPriority;
|
||||||
|
|
||||||
remoteAlbum.Artist = Builder<Artist>.CreateNew()
|
remoteAlbum.Artist = Builder<Artist>.CreateNew()
|
||||||
.With(e => e.QualityProfile = new QualityProfile
|
.With(e => e.QualityProfile = new QualityProfile
|
||||||
|
@ -514,5 +515,39 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
qualifiedReports.First().RemoteAlbum.ParsedAlbumInfo.Quality.Revision.Real.Should().Be(0);
|
qualifiedReports.First().RemoteAlbum.ParsedAlbumInfo.Quality.Revision.Real.Should().Be(0);
|
||||||
qualifiedReports.First().RemoteAlbum.PreferredWordScore.Should().Be(10);
|
qualifiedReports.First().RemoteAlbum.PreferredWordScore.Should().Be(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void sort_download_decisions_based_on_indexer_priority()
|
||||||
|
{
|
||||||
|
var remoteAlbum1 = GivenRemoteAlbum(new List<Album> { GivenAlbum(1) }, new QualityModel(Quality.FLAC, new Revision(1)), indexerPriority: 25);
|
||||||
|
var remoteAlbum2 = GivenRemoteAlbum(new List<Album> { GivenAlbum(1) }, new QualityModel(Quality.FLAC, new Revision(1)), indexerPriority: 50);
|
||||||
|
var remoteAlbum3 = GivenRemoteAlbum(new List<Album> { GivenAlbum(1) }, new QualityModel(Quality.FLAC, 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().RemoteAlbum.Should().Be(remoteAlbum3);
|
||||||
|
qualifiedReports.Skip(1).First().RemoteAlbum.Should().Be(remoteAlbum1);
|
||||||
|
qualifiedReports.Last().RemoteAlbum.Should().Be(remoteAlbum2);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ensure_download_decisions_indexer_priority_is_not_perfered_over_quality()
|
||||||
|
{
|
||||||
|
var remoteAlbum1 = GivenRemoteAlbum(new List<Album> { GivenAlbum(1) }, new QualityModel(Quality.MP3_320, new Revision(1)), indexerPriority: 25);
|
||||||
|
var remoteAlbum2 = GivenRemoteAlbum(new List<Album> { GivenAlbum(1) }, new QualityModel(Quality.FLAC, new Revision(1)), indexerPriority: 50);
|
||||||
|
var remoteAlbum3 = GivenRemoteAlbum(new List<Album> { GivenAlbum(1) }, new QualityModel(Quality.MP3_128, new Revision(1)), indexerPriority: 1);
|
||||||
|
var remoteAlbum4 = GivenRemoteAlbum(new List<Album> { GivenAlbum(1) }, new QualityModel(Quality.FLAC, 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().RemoteAlbum.Should().Be(remoteAlbum4);
|
||||||
|
qualifiedReports.Skip(1).First().RemoteAlbum.Should().Be(remoteAlbum2);
|
||||||
|
qualifiedReports.Skip(2).First().RemoteAlbum.Should().Be(remoteAlbum1);
|
||||||
|
qualifiedReports.Last().RemoteAlbum.Should().Be(remoteAlbum3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(044)]
|
||||||
|
public class add_priority_to_indexers : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Alter.Table("Indexers").AddColumn("Priority").AsInt32().NotNullable().WithDefaultValue(25);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,6 +30,7 @@ namespace NzbDrone.Core.DecisionEngine
|
||||||
CompareQuality,
|
CompareQuality,
|
||||||
ComparePreferredWordScore,
|
ComparePreferredWordScore,
|
||||||
CompareProtocol,
|
CompareProtocol,
|
||||||
|
CompareIndexerPriority,
|
||||||
ComparePeersIfTorrent,
|
ComparePeersIfTorrent,
|
||||||
CompareAlbumCount,
|
CompareAlbumCount,
|
||||||
CompareAgeIfUsenet,
|
CompareAgeIfUsenet,
|
||||||
|
@ -59,6 +60,11 @@ namespace NzbDrone.Core.DecisionEngine
|
||||||
return comparers.Select(comparer => comparer).FirstOrDefault(result => result != 0);
|
return comparers.Select(comparer => comparer).FirstOrDefault(result => result != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int CompareIndexerPriority(DownloadDecision x, DownloadDecision y)
|
||||||
|
{
|
||||||
|
return CompareByReverse(x.RemoteAlbum.Release, y.RemoteAlbum.Release, release => release.IndexerPriority);
|
||||||
|
}
|
||||||
|
|
||||||
private int CompareQuality(DownloadDecision x, DownloadDecision y)
|
private int CompareQuality(DownloadDecision x, DownloadDecision y)
|
||||||
{
|
{
|
||||||
if (_configService.DownloadPropersAndRepacks == ProperDownloadTypes.DoNotPrefer)
|
if (_configService.DownloadPropersAndRepacks == ProperDownloadTypes.DoNotPrefer)
|
||||||
|
|
|
@ -74,6 +74,7 @@ namespace NzbDrone.Core.Download
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
_logger.Trace("Grabbing from Indexer {0} at priority {1}.", remoteAlbum.Release.Indexer, remoteAlbum.Release.IndexerPriority);
|
||||||
_downloadService.DownloadReport(remoteAlbum);
|
_downloadService.DownloadReport(remoteAlbum);
|
||||||
grabbed.Add(report);
|
grabbed.Add(report);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ namespace NzbDrone.Core.Indexers
|
||||||
|
|
||||||
public abstract string Name { get; }
|
public abstract string Name { get; }
|
||||||
public abstract DownloadProtocol Protocol { get; }
|
public abstract DownloadProtocol Protocol { get; }
|
||||||
|
public int Priority { get; set; }
|
||||||
|
|
||||||
public abstract bool SupportsRss { get; }
|
public abstract bool SupportsRss { get; }
|
||||||
public abstract bool SupportsSearch { get; }
|
public abstract bool SupportsSearch { get; }
|
||||||
|
@ -80,6 +81,7 @@ namespace NzbDrone.Core.Indexers
|
||||||
c.IndexerId = Definition.Id;
|
c.IndexerId = Definition.Id;
|
||||||
c.Indexer = Definition.Name;
|
c.Indexer = Definition.Name;
|
||||||
c.DownloadProtocol = Protocol;
|
c.DownloadProtocol = Protocol;
|
||||||
|
c.IndexerPriority = ((IndexerDefinition)Definition).Priority;
|
||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -10,6 +10,7 @@ namespace NzbDrone.Core.Indexers
|
||||||
public DownloadProtocol Protocol { get; set; }
|
public DownloadProtocol Protocol { get; set; }
|
||||||
public bool SupportsRss { get; set; }
|
public bool SupportsRss { get; set; }
|
||||||
public bool SupportsSearch { get; set; }
|
public bool SupportsSearch { get; set; }
|
||||||
|
public int Priority { get; set; } = 25;
|
||||||
|
|
||||||
public override bool Enable => EnableRss || EnableAutomaticSearch || EnableInteractiveSearch;
|
public override bool Enable => EnableRss || EnableAutomaticSearch || EnableInteractiveSearch;
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ namespace NzbDrone.Core.Parser.Model
|
||||||
public string Indexer { get; set; }
|
public string Indexer { get; set; }
|
||||||
public string Artist { get; set; }
|
public string Artist { get; set; }
|
||||||
public string Album { get; set; }
|
public string Album { get; set; }
|
||||||
|
public int IndexerPriority { get; set; }
|
||||||
public DownloadProtocol DownloadProtocol { get; set; }
|
public DownloadProtocol DownloadProtocol { get; set; }
|
||||||
public DateTime PublishDate { get; set; }
|
public DateTime PublishDate { get; set; }
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue