New: Seed Settings Sync

pull/993/head
Qstick 2 years ago
parent af50a1d3a8
commit e90a796b27

@ -112,7 +112,7 @@ function EditIndexerModalContent(props) {
</FormGroup>
<FormGroup>
<FormLabel>{translate('AppProfile')}</FormLabel>
<FormLabel>{translate('SyncProfile')}</FormLabel>
<FormInputGroup
type={inputTypes.APP_PROFILE_SELECT}

@ -133,7 +133,7 @@ class IndexerEditorFooter extends Component {
<div className={styles.inputContainer}>
<IndexerEditorFooterLabel
label={translate('AppProfile')}
label={translate('SyncProfile')}
isSaving={isSaving && appProfileId !== NO_CHANGE}
/>

@ -53,7 +53,7 @@ function IndexerIndexSortMenu(props) {
sortDirection={sortDirection}
onPress={onSortSelect}
>
{translate('AppProfile')}
{translate('SyncProfile')}
</SortMenuItem>
<SortMenuItem

@ -52,7 +52,7 @@ class AppProfiles extends Component {
} = this.props;
return (
<FieldSet legend={translate('AppProfiles')}>
<FieldSet legend={translate('SyncProfiles')}>
<PageSectionContent
errorMessage={translate('UnableToLoadAppProfiles')}
{...otherProps}c={true}

@ -40,14 +40,15 @@ class EditAppProfileModalContent extends Component {
name,
enableRss,
enableInteractiveSearch,
enableAutomaticSearch
enableAutomaticSearch,
minimumSeeders
} = item;
return (
<ModalContent onModalClose={onModalClose}>
<ModalHeader>
{id ? translate('EditAppProfile') : translate('AddAppProfile')}
{id ? translate('EditSyncProfile') : translate('AddSyncProfile')}
</ModalHeader>
<ModalBody>
@ -123,6 +124,20 @@ class EditAppProfileModalContent extends Component {
onChange={onInputChange}
/>
</FormGroup>
<FormGroup>
<FormLabel>
{translate('MinimumSeeders')}
</FormLabel>
<FormInputGroup
type={inputTypes.NUMBER}
name="minimumSeeders"
{...minimumSeeders}
helpText={translate('MinimumSeedersHelpText')}
onChange={onInputChange}
/>
</FormGroup>
</Form>
}
</div>

@ -76,7 +76,7 @@ export const defaultState = {
},
{
name: 'appProfileId',
label: translate('AppProfile'),
label: translate('SyncProfile'),
isSortable: true,
isVisible: true
},
@ -152,7 +152,7 @@ export const defaultState = {
},
{
name: 'appProfileId',
label: translate('AppProfile'),
label: translate('SyncProfile'),
type: filterBuilderTypes.EXACT,
valueType: filterBuilderValueTypes.APP_PROFILE
},

@ -5,6 +5,7 @@ namespace NzbDrone.Common.Cloud
public interface IProwlarrCloudRequestBuilder
{
IHttpRequestBuilderFactory Services { get; }
IHttpRequestBuilderFactory Releases { get; }
}
public class ProwlarrCloudRequestBuilder : IProwlarrCloudRequestBuilder
@ -13,8 +14,13 @@ namespace NzbDrone.Common.Cloud
{
Services = new HttpRequestBuilder("https://prowlarr.servarr.com/v1/")
.CreateFactory();
Releases = new HttpRequestBuilder("https://releases.servarr.com/v1/")
.CreateFactory();
}
public IHttpRequestBuilderFactory Services { get; private set; }
public IHttpRequestBuilderFactory Releases { get; private set; }
}
}

@ -183,6 +183,13 @@ namespace NzbDrone.Core.Applications.Lidarr
lidarrIndexer.Fields.FirstOrDefault(x => x.Name == "apiKey").Value = _configFileProvider.ApiKey;
lidarrIndexer.Fields.FirstOrDefault(x => x.Name == "categories").Value = JArray.FromObject(indexer.Capabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()));
if (indexer.Protocol == DownloadProtocol.Torrent)
{
lidarrIndexer.Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value = indexer.AppProfile.Value.MinimumSeeders;
lidarrIndexer.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio").Value = ((ITorrentIndexerSettings)indexer.Settings).TorrentBaseSettings.SeedRatio;
lidarrIndexer.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime").Value = ((ITorrentIndexerSettings)indexer.Settings).TorrentBaseSettings.SeedTime;
}
return lidarrIndexer;
}
}

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
@ -31,6 +32,18 @@ namespace NzbDrone.Core.Applications.Lidarr
var apiKey = (string)Fields.FirstOrDefault(x => x.Name == "apiKey").Value == (string)other.Fields.FirstOrDefault(x => x.Name == "apiKey").Value;
var cats = JToken.DeepEquals((JArray)Fields.FirstOrDefault(x => x.Name == "categories").Value, (JArray)other.Fields.FirstOrDefault(x => x.Name == "categories").Value);
var minimumSeeders = Fields.FirstOrDefault(x => x.Name == "minimumSeeders")?.Value == null ? null : (int?)Convert.ToInt32(Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value);
var otherMinimumSeeders = other.Fields.FirstOrDefault(x => x.Name == "minimumSeeders")?.Value == null ? null : (int?)Convert.ToInt32(other.Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value);
var minimumSeedersCompare = minimumSeeders == otherMinimumSeeders;
var seedTime = Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime")?.Value == null ? null : (int?)Convert.ToInt32(Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime").Value);
var otherSeedTime = other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime")?.Value == null ? null : (int?)Convert.ToInt32(other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime").Value);
var seedTimeCompare = seedTime == otherSeedTime;
var seedRatio = Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio")?.Value == null ? null : (double?)Convert.ToDouble(Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio").Value);
var otherSeedRatio = other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio")?.Value == null ? null : (double?)Convert.ToDouble(other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio").Value);
var seedRatioCompare = seedRatio == otherSeedRatio;
return other.EnableRss == EnableRss &&
other.EnableAutomaticSearch == EnableAutomaticSearch &&
other.EnableInteractiveSearch == EnableInteractiveSearch &&
@ -38,7 +51,7 @@ namespace NzbDrone.Core.Applications.Lidarr
other.Implementation == Implementation &&
other.Priority == Priority &&
other.Id == Id &&
apiKey && apiPath && baseUrl && cats;
apiKey && apiPath && baseUrl && cats && minimumSeedersCompare && seedRatioCompare && seedTimeCompare;
}
}
}

@ -183,6 +183,13 @@ namespace NzbDrone.Core.Applications.Radarr
radarrIndexer.Fields.FirstOrDefault(x => x.Name == "apiKey").Value = _configFileProvider.ApiKey;
radarrIndexer.Fields.FirstOrDefault(x => x.Name == "categories").Value = JArray.FromObject(indexer.Capabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()));
if (indexer.Protocol == DownloadProtocol.Torrent)
{
radarrIndexer.Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value = indexer.AppProfile.Value.MinimumSeeders;
radarrIndexer.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio").Value = ((ITorrentIndexerSettings)indexer.Settings).TorrentBaseSettings.SeedRatio;
radarrIndexer.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime").Value = ((ITorrentIndexerSettings)indexer.Settings).TorrentBaseSettings.SeedTime;
}
return radarrIndexer;
}
}

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
@ -31,6 +32,18 @@ namespace NzbDrone.Core.Applications.Radarr
var apiKey = (string)Fields.FirstOrDefault(x => x.Name == "apiKey").Value == (string)other.Fields.FirstOrDefault(x => x.Name == "apiKey").Value;
var cats = JToken.DeepEquals((JArray)Fields.FirstOrDefault(x => x.Name == "categories").Value, (JArray)other.Fields.FirstOrDefault(x => x.Name == "categories").Value);
var minimumSeeders = Fields.FirstOrDefault(x => x.Name == "minimumSeeders")?.Value == null ? null : (int?)Convert.ToInt32(Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value);
var otherMinimumSeeders = other.Fields.FirstOrDefault(x => x.Name == "minimumSeeders")?.Value == null ? null : (int?)Convert.ToInt32(other.Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value);
var minimumSeedersCompare = minimumSeeders == otherMinimumSeeders;
var seedTime = Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime")?.Value == null ? null : (int?)Convert.ToInt32(Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime").Value);
var otherSeedTime = other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime")?.Value == null ? null : (int?)Convert.ToInt32(other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime").Value);
var seedTimeCompare = seedTime == otherSeedTime;
var seedRatio = Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio")?.Value == null ? null : (double?)Convert.ToDouble(Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio").Value);
var otherSeedRatio = other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio")?.Value == null ? null : (double?)Convert.ToDouble(other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio").Value);
var seedRatioCompare = seedRatio == otherSeedRatio;
return other.EnableRss == EnableRss &&
other.EnableAutomaticSearch == EnableAutomaticSearch &&
other.EnableInteractiveSearch == EnableInteractiveSearch &&
@ -38,7 +51,7 @@ namespace NzbDrone.Core.Applications.Radarr
other.Implementation == Implementation &&
other.Priority == Priority &&
other.Id == Id &&
apiKey && apiPath && baseUrl && cats;
apiKey && apiPath && baseUrl && cats && minimumSeedersCompare && seedRatioCompare && seedTimeCompare;
}
}
}

@ -183,6 +183,13 @@ namespace NzbDrone.Core.Applications.Readarr
readarrIndexer.Fields.FirstOrDefault(x => x.Name == "apiKey").Value = _configFileProvider.ApiKey;
readarrIndexer.Fields.FirstOrDefault(x => x.Name == "categories").Value = JArray.FromObject(indexer.Capabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()));
if (indexer.Protocol == DownloadProtocol.Torrent)
{
readarrIndexer.Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value = indexer.AppProfile.Value.MinimumSeeders;
readarrIndexer.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio").Value = ((ITorrentIndexerSettings)indexer.Settings).TorrentBaseSettings.SeedRatio;
readarrIndexer.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime").Value = ((ITorrentIndexerSettings)indexer.Settings).TorrentBaseSettings.SeedTime;
}
return readarrIndexer;
}
}

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
@ -31,6 +32,18 @@ namespace NzbDrone.Core.Applications.Readarr
var apiKey = (string)Fields.FirstOrDefault(x => x.Name == "apiKey").Value == (string)other.Fields.FirstOrDefault(x => x.Name == "apiKey").Value;
var cats = JToken.DeepEquals((JArray)Fields.FirstOrDefault(x => x.Name == "categories").Value, (JArray)other.Fields.FirstOrDefault(x => x.Name == "categories").Value);
var minimumSeeders = Fields.FirstOrDefault(x => x.Name == "minimumSeeders")?.Value == null ? null : (int?)Convert.ToInt32(Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value);
var otherMinimumSeeders = other.Fields.FirstOrDefault(x => x.Name == "minimumSeeders")?.Value == null ? null : (int?)Convert.ToInt32(other.Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value);
var minimumSeedersCompare = minimumSeeders == otherMinimumSeeders;
var seedTime = Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime")?.Value == null ? null : (int?)Convert.ToInt32(Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime").Value);
var otherSeedTime = other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime")?.Value == null ? null : (int?)Convert.ToInt32(other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime").Value);
var seedTimeCompare = seedTime == otherSeedTime;
var seedRatio = Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio")?.Value == null ? null : (double?)Convert.ToDouble(Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio").Value);
var otherSeedRatio = other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio")?.Value == null ? null : (double?)Convert.ToDouble(other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio").Value);
var seedRatioCompare = seedRatio == otherSeedRatio;
return other.EnableRss == EnableRss &&
other.EnableAutomaticSearch == EnableAutomaticSearch &&
other.EnableInteractiveSearch == EnableInteractiveSearch &&
@ -38,7 +51,7 @@ namespace NzbDrone.Core.Applications.Readarr
other.Implementation == Implementation &&
other.Priority == Priority &&
other.Id == Id &&
apiKey && apiPath && baseUrl && cats;
apiKey && apiPath && baseUrl && cats && minimumSeedersCompare && seedRatioCompare && seedTimeCompare;
}
}
}

@ -184,6 +184,13 @@ namespace NzbDrone.Core.Applications.Sonarr
sonarrIndexer.Fields.FirstOrDefault(x => x.Name == "categories").Value = JArray.FromObject(indexer.Capabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()));
sonarrIndexer.Fields.FirstOrDefault(x => x.Name == "animeCategories").Value = JArray.FromObject(indexer.Capabilities.Categories.SupportedCategories(Settings.AnimeSyncCategories.ToArray()));
if (indexer.Protocol == DownloadProtocol.Torrent)
{
sonarrIndexer.Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value = indexer.AppProfile.Value.MinimumSeeders;
sonarrIndexer.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio").Value = ((ITorrentIndexerSettings)indexer.Settings).TorrentBaseSettings.SeedRatio;
sonarrIndexer.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime").Value = ((ITorrentIndexerSettings)indexer.Settings).TorrentBaseSettings.SeedTime;
}
return sonarrIndexer;
}
}

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
@ -32,6 +33,18 @@ namespace NzbDrone.Core.Applications.Sonarr
var cats = JToken.DeepEquals((JArray)Fields.FirstOrDefault(x => x.Name == "categories").Value, (JArray)other.Fields.FirstOrDefault(x => x.Name == "categories").Value);
var animeCats = JToken.DeepEquals((JArray)Fields.FirstOrDefault(x => x.Name == "animeCategories").Value, (JArray)other.Fields.FirstOrDefault(x => x.Name == "animeCategories").Value);
var minimumSeeders = Fields.FirstOrDefault(x => x.Name == "minimumSeeders")?.Value == null ? null : (int?)Convert.ToInt32(Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value);
var otherMinimumSeeders = other.Fields.FirstOrDefault(x => x.Name == "minimumSeeders")?.Value == null ? null : (int?)Convert.ToInt32(other.Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value);
var minimumSeedersCompare = minimumSeeders == otherMinimumSeeders;
var seedTime = Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime")?.Value == null ? null : (int?)Convert.ToInt32(Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime").Value);
var otherSeedTime = other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime")?.Value == null ? null : (int?)Convert.ToInt32(other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime").Value);
var seedTimeCompare = seedTime == otherSeedTime;
var seedRatio = Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio")?.Value == null ? null : (double?)Convert.ToDouble(Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio").Value);
var otherSeedRatio = other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio")?.Value == null ? null : (double?)Convert.ToDouble(other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio").Value);
var seedRatioCompare = seedRatio == otherSeedRatio;
return other.EnableRss == EnableRss &&
other.EnableAutomaticSearch == EnableAutomaticSearch &&
other.EnableInteractiveSearch == EnableInteractiveSearch &&
@ -39,7 +52,7 @@ namespace NzbDrone.Core.Applications.Sonarr
other.Implementation == Implementation &&
other.Priority == Priority &&
other.Id == Id &&
apiKey && apiPath && baseUrl && cats && animeCats;
apiKey && apiPath && baseUrl && cats && animeCats && minimumSeedersCompare && seedRatioCompare && seedTimeCompare;
}
}
}

@ -183,6 +183,13 @@ namespace NzbDrone.Core.Applications.Whisparr
whisparrIndexer.Fields.FirstOrDefault(x => x.Name == "apiKey").Value = _configFileProvider.ApiKey;
whisparrIndexer.Fields.FirstOrDefault(x => x.Name == "categories").Value = JArray.FromObject(indexer.Capabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()));
if (indexer.Protocol == DownloadProtocol.Torrent)
{
whisparrIndexer.Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value = indexer.AppProfile.Value.MinimumSeeders;
whisparrIndexer.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio").Value = ((ITorrentIndexerSettings)indexer.Settings).TorrentBaseSettings.SeedRatio;
whisparrIndexer.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime").Value = ((ITorrentIndexerSettings)indexer.Settings).TorrentBaseSettings.SeedTime;
}
return whisparrIndexer;
}
}

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
@ -31,6 +32,18 @@ namespace NzbDrone.Core.Applications.Whisparr
var apiKey = (string)Fields.FirstOrDefault(x => x.Name == "apiKey").Value == (string)other.Fields.FirstOrDefault(x => x.Name == "apiKey").Value;
var cats = JToken.DeepEquals((JArray)Fields.FirstOrDefault(x => x.Name == "categories").Value, (JArray)other.Fields.FirstOrDefault(x => x.Name == "categories").Value);
var minimumSeeders = Fields.FirstOrDefault(x => x.Name == "minimumSeeders")?.Value == null ? null : (int?)Convert.ToInt32(Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value);
var otherMinimumSeeders = other.Fields.FirstOrDefault(x => x.Name == "minimumSeeders")?.Value == null ? null : (int?)Convert.ToInt32(other.Fields.FirstOrDefault(x => x.Name == "minimumSeeders").Value);
var minimumSeedersCompare = minimumSeeders == otherMinimumSeeders;
var seedTime = Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime")?.Value == null ? null : (int?)Convert.ToInt32(Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime").Value);
var otherSeedTime = other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime")?.Value == null ? null : (int?)Convert.ToInt32(other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedTime").Value);
var seedTimeCompare = seedTime == otherSeedTime;
var seedRatio = Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio")?.Value == null ? null : (double?)Convert.ToDouble(Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio").Value);
var otherSeedRatio = other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio")?.Value == null ? null : (double?)Convert.ToDouble(other.Fields.FirstOrDefault(x => x.Name == "seedCriteria.seedRatio").Value);
var seedRatioCompare = seedRatio == otherSeedRatio;
return other.EnableRss == EnableRss &&
other.EnableAutomaticSearch == EnableAutomaticSearch &&
other.EnableInteractiveSearch == EnableInteractiveSearch &&
@ -38,7 +51,7 @@ namespace NzbDrone.Core.Applications.Whisparr
other.Implementation == Implementation &&
other.Priority == Priority &&
other.Id == Id &&
apiKey && apiPath && baseUrl && cats;
apiKey && apiPath && baseUrl && cats && minimumSeedersCompare && seedRatioCompare && seedTimeCompare;
}
}
}

@ -0,0 +1,15 @@
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(18)]
public class minimum_seeders : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Alter.Table("AppSyncProfiles")
.AddColumn("MinimumSeeders").AsInt32().NotNullable().WithDefaultValue(1);
}
}
}

@ -0,0 +1,48 @@
using System.Linq;
using System.Net.Http;
using NzbDrone.Common.Cloud;
using NzbDrone.Common.Http;
using NzbDrone.Common.Serializer;
using NzbDrone.Core.Analytics;
using NzbDrone.Core.Indexers.Events;
using NzbDrone.Core.Messaging.Events;
namespace NzbDrone.Core.IndexerSearch
{
public class ReleaseAnalyticsService : IHandleAsync<IndexerQueryEvent>
{
private readonly IHttpClient _httpClient;
private readonly IHttpRequestBuilderFactory _requestBuilder;
private readonly IAnalyticsService _analyticsService;
public ReleaseAnalyticsService(IHttpClient httpClient, IProwlarrCloudRequestBuilder requestBuilder, IAnalyticsService analyticsService)
{
_analyticsService = analyticsService;
_requestBuilder = requestBuilder.Releases;
_httpClient = httpClient;
}
public void HandleAsync(IndexerQueryEvent message)
{
if (_analyticsService.IsEnabled)
{
var request = _requestBuilder.Create().Resource("release/push").Build();
request.Method = HttpMethod.Post;
request.Headers.ContentType = "application/json";
request.SuppressHttpError = true;
var body = message.QueryResult.Releases.Select(x => new
{
Title = x.Title,
Categories = x.Categories.Where(c => c.Id < 10000).Select(c => c.Id),
Protocol = x.DownloadProtocol.ToString(),
Size = x.Size,
PublishDate = x.PublishDate
});
request.SetContent(body.ToJson());
_httpClient.Post(request);
}
}
}
}

@ -2,6 +2,7 @@ using System.Linq;
using System.Text.RegularExpressions;
using FluentValidation;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Indexers.Newznab;
using NzbDrone.Core.Validation;
@ -36,7 +37,7 @@ namespace NzbDrone.Core.Indexers.Torznab
}
}
public class TorznabSettings : NewznabSettings
public class TorznabSettings : NewznabSettings, ITorrentIndexerSettings
{
private static readonly TorznabSettingsValidator Validator = new TorznabSettingsValidator();
@ -44,6 +45,9 @@ namespace NzbDrone.Core.Indexers.Torznab
{
}
[FieldDefinition(3)]
public IndexerTorrentBaseSettings TorrentBaseSettings { get; set; } = new IndexerTorrentBaseSettings();
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NzbDrone.Core.Indexers
{
public interface ITorrentIndexerSettings : IIndexerSettings
{
IndexerTorrentBaseSettings TorrentBaseSettings { get; set; }
}
}

@ -0,0 +1,47 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Indexers
{
public class IndexerTorrentSettingsValidator : AbstractValidator<IndexerTorrentBaseSettings>
{
public IndexerTorrentSettingsValidator(double seedRatioMinimum = 0.0, int seedTimeMinimum = 0, int seasonPackSeedTimeMinimum = 0)
{
RuleFor(c => c.SeedRatio).GreaterThan(0.0)
.When(c => c.SeedRatio.HasValue)
.AsWarning().WithMessage("Should be greater than zero");
RuleFor(c => c.SeedTime).GreaterThan(0)
.When(c => c.SeedTime.HasValue)
.AsWarning().WithMessage("Should be greater than zero");
if (seedRatioMinimum != 0.0)
{
RuleFor(c => c.SeedRatio).GreaterThanOrEqualTo(seedRatioMinimum)
.When(c => c.SeedRatio > 0.0)
.AsWarning()
.WithMessage($"Under {seedRatioMinimum} leads to H&R");
}
if (seedTimeMinimum != 0)
{
RuleFor(c => c.SeedTime).GreaterThanOrEqualTo(seedTimeMinimum)
.When(c => c.SeedTime > 0)
.AsWarning()
.WithMessage($"Under {seedTimeMinimum} leads to H&R");
}
}
}
public class IndexerTorrentBaseSettings
{
private static readonly IndexerTorrentSettingsValidator Validator = new IndexerTorrentSettingsValidator();
[FieldDefinition(1, Type = FieldType.Textbox, Label = "Seed Ratio", HelpText = "The ratio a torrent should reach before stopping, empty is app's default", Advanced = true)]
public double? SeedRatio { get; set; }
[FieldDefinition(2, Type = FieldType.Number, Label = "Seed Time", HelpText = "The time a torrent should be seeded before stopping, empty is app's default", Advanced = true)]
public int? SeedTime { get; set; }
}
}

@ -4,7 +4,7 @@ using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Indexers.Settings
{
public class CookieTorrentBaseSettings : IIndexerSettings
public class CookieTorrentBaseSettings : ITorrentIndexerSettings
{
public class CookieBaseSettingsValidator : AbstractValidator<CookieTorrentBaseSettings>
{
@ -30,6 +30,9 @@ namespace NzbDrone.Core.Indexers.Settings
[FieldDefinition(3)]
public IndexerBaseSettings BaseSettings { get; set; } = new IndexerBaseSettings();
[FieldDefinition(4)]
public IndexerTorrentBaseSettings TorrentBaseSettings { get; set; } = new IndexerTorrentBaseSettings();
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));

@ -8,7 +8,7 @@ namespace NzbDrone.Core.Indexers.Settings
{
}
public class NoAuthTorrentBaseSettings : IIndexerSettings
public class NoAuthTorrentBaseSettings : ITorrentIndexerSettings
{
private static readonly NoAuthSettingsValidator Validator = new NoAuthSettingsValidator();
@ -18,6 +18,9 @@ namespace NzbDrone.Core.Indexers.Settings
[FieldDefinition(2)]
public IndexerBaseSettings BaseSettings { get; set; } = new IndexerBaseSettings();
[FieldDefinition(3)]
public IndexerTorrentBaseSettings TorrentBaseSettings { get; set; } = new IndexerTorrentBaseSettings();
public virtual NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));

@ -4,7 +4,7 @@ using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Indexers.Settings
{
public class UserPassTorrentBaseSettings : IIndexerSettings
public class UserPassTorrentBaseSettings : ITorrentIndexerSettings
{
public class UserPassBaseSettingsValidator : AbstractValidator<UserPassTorrentBaseSettings>
{
@ -35,6 +35,9 @@ namespace NzbDrone.Core.Indexers.Settings
[FieldDefinition(4)]
public IndexerBaseSettings BaseSettings { get; set; } = new IndexerBaseSettings();
[FieldDefinition(5)]
public IndexerTorrentBaseSettings TorrentBaseSettings { get; set; } = new IndexerTorrentBaseSettings();
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));

@ -3,7 +3,6 @@
"AcceptConfirmationModal": "Accept Confirmation Modal",
"Actions": "Actions",
"Add": "Add",
"AddAppProfile": "Add App Sync Profile",
"AddDownloadClient": "Add Download Client",
"AddDownloadClientToProwlarr": "Adding a download client allows Prowlarr to send releases direct from the UI while doing a manual search.",
"Added": "Added",
@ -13,6 +12,7 @@
"AddingTag": "Adding tag",
"AddNewIndexer": "Add New Indexer",
"AddRemoveOnly": "Add and Remove Only",
"AddSyncProfile": "Add Sync Profile",
"AddToDownloadClient": "Add release to download client",
"Age": "Age",
"All": "All",
@ -32,10 +32,8 @@
"ApplyTagsHelpTexts2": "Add: Add the tags the existing list of tags",
"ApplyTagsHelpTexts3": "Remove: Remove the entered tags",
"ApplyTagsHelpTexts4": "Replace: Replace the tags with the entered tags (enter no tags to clear all tags)",
"AppProfile": "App Profile",
"AppProfileDeleteConfirm": "Are you sure you want to delete {0}?",
"AppProfileInUse": "App Profile in Use",
"AppProfiles": "App Profiles",
"AppProfileSelectHelpText": "App profiles are used to control RSS, Automatic Search and Interactive Search settings on application sync",
"Apps": "Apps",
"AppSettingsSummary": "Applications and settings to configure how Prowlarr interacts with your PVR programs",
@ -119,8 +117,8 @@
"DownloadClientStatusCheckAllClientMessage": "All download clients are unavailable due to failures",
"DownloadClientStatusCheckSingleClientMessage": "Download clients unavailable due to failures: {0}",
"Edit": "Edit",
"EditAppProfile": "Edit App Profile",
"EditIndexer": "Edit Indexer",
"EditSyncProfile": "Edit Sync Profile",
"Enable": "Enable",
"EnableAutomaticSearch": "Enable Automatic Search",
"EnableAutomaticSearchHelpText": "Will be used when automatic searches are performed via the UI or by Prowlarr",
@ -222,6 +220,8 @@
"Mechanism": "Mechanism",
"Message": "Message",
"MIA": "MIA",
"MinimumSeeders": "Minimum Seeders",
"MinimumSeedersHelpText": "Minimum seeders required by the Appliction for the indexer to grab",
"Mode": "Mode",
"MoreInfo": "More Info",
"MovieIndexScrollBottom": "Movie Index: Scroll Bottom",
@ -372,6 +372,8 @@
"SyncLevel": "Sync Level",
"SyncLevelAddRemove": "Add and Remove Only: When indexers are added or removed from Prowlarr, it will update this remote app.",
"SyncLevelFull": "Full Sync: Will keep this app's indexers fully in sync. Changes made to indexers in Prowlarr are then synced to this app. Any change made to indexers remotely within this app will be overridden by Prowlarr on the next sync.",
"SyncProfile": "Sync Profile",
"SyncProfiles": "Sync Profiles",
"System": "System",
"SystemTimeCheckMessage": "System time is off by more than 1 day. Scheduled tasks may not run correctly until the time is corrected",
"TableOptions": "Table Options",

@ -8,5 +8,6 @@ namespace NzbDrone.Core.Profiles
public bool EnableRss { get; set; }
public bool EnableAutomaticSearch { get; set; }
public bool EnableInteractiveSearch { get; set; }
public int MinimumSeeders { get; set; }
}
}

@ -88,7 +88,8 @@ namespace NzbDrone.Core.Profiles
Name = name,
EnableAutomaticSearch = true,
EnableInteractiveSearch = true,
EnableRss = true
EnableRss = true,
MinimumSeeders = 1
};
return qualityProfile;

@ -11,6 +11,7 @@ namespace Prowlarr.Api.V1.Profiles.App
public bool EnableRss { get; set; }
public bool EnableInteractiveSearch { get; set; }
public bool EnableAutomaticSearch { get; set; }
public int MinimumSeeders { get; set; }
}
public static class ProfileResourceMapper
@ -28,7 +29,8 @@ namespace Prowlarr.Api.V1.Profiles.App
Name = model.Name,
EnableRss = model.EnableRss,
EnableInteractiveSearch = model.EnableInteractiveSearch,
EnableAutomaticSearch = model.EnableAutomaticSearch
EnableAutomaticSearch = model.EnableAutomaticSearch,
MinimumSeeders = model.MinimumSeeders
};
}
@ -45,7 +47,8 @@ namespace Prowlarr.Api.V1.Profiles.App
Name = resource.Name,
EnableRss = resource.EnableRss,
EnableInteractiveSearch = resource.EnableInteractiveSearch,
EnableAutomaticSearch = resource.EnableAutomaticSearch
EnableAutomaticSearch = resource.EnableAutomaticSearch,
MinimumSeeders = resource.MinimumSeeders
};
}

Loading…
Cancel
Save