mirror of
https://github.com/Radarr/Radarr.git
synced 2024-08-16 23:39:44 +02:00
New: Rework List sync interval logic
* New: Rework List sync interval logic (cherry picked from commit c522cd120d08757e7e43c2348be4d7f05a254fac) * Minor alignment with Sonarr * Remove ListUpdateInterval --------- Co-authored-by: Qstick <qstick@gmail.com>
This commit is contained in:
parent
148ee5983d
commit
bd1844030d
@ -3,3 +3,9 @@
|
|||||||
|
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.message {
|
||||||
|
composes: alert from '~Components/Alert.css';
|
||||||
|
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// Please do not change this file!
|
// Please do not change this file!
|
||||||
interface CssExports {
|
interface CssExports {
|
||||||
'deleteButton': string;
|
'deleteButton': string;
|
||||||
|
'message': string;
|
||||||
}
|
}
|
||||||
export const cssExports: CssExports;
|
export const cssExports: CssExports;
|
||||||
export default cssExports;
|
export default cssExports;
|
||||||
|
@ -14,6 +14,7 @@ import ModalContent from 'Components/Modal/ModalContent';
|
|||||||
import ModalFooter from 'Components/Modal/ModalFooter';
|
import ModalFooter from 'Components/Modal/ModalFooter';
|
||||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||||
import { inputTypes, kinds } from 'Helpers/Props';
|
import { inputTypes, kinds } from 'Helpers/Props';
|
||||||
|
import formatShortTimeSpan from 'Utilities/Date/formatShortTimeSpan';
|
||||||
import translate from 'Utilities/String/translate';
|
import translate from 'Utilities/String/translate';
|
||||||
import styles from './EditImportListModalContent.css';
|
import styles from './EditImportListModalContent.css';
|
||||||
|
|
||||||
@ -42,6 +43,7 @@ function EditImportListModalContent(props) {
|
|||||||
name,
|
name,
|
||||||
enabled,
|
enabled,
|
||||||
enableAuto,
|
enableAuto,
|
||||||
|
minRefreshInterval,
|
||||||
monitor,
|
monitor,
|
||||||
minimumAvailability,
|
minimumAvailability,
|
||||||
qualityProfileId,
|
qualityProfileId,
|
||||||
@ -85,6 +87,14 @@ function EditImportListModalContent(props) {
|
|||||||
{message.value.message}
|
{message.value.message}
|
||||||
</Alert>
|
</Alert>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<Alert
|
||||||
|
kind={kinds.INFO}
|
||||||
|
className={styles.message}
|
||||||
|
>
|
||||||
|
{translate('ListWillRefreshEveryInterp', [formatShortTimeSpan(minRefreshInterval.value)])}
|
||||||
|
</Alert>
|
||||||
|
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<FormLabel>{translate('Name')}</FormLabel>
|
<FormLabel>{translate('Name')}</FormLabel>
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import Card from 'Components/Card';
|
|||||||
import Label from 'Components/Label';
|
import Label from 'Components/Label';
|
||||||
import ConfirmModal from 'Components/Modal/ConfirmModal';
|
import ConfirmModal from 'Components/Modal/ConfirmModal';
|
||||||
import { kinds } from 'Helpers/Props';
|
import { kinds } from 'Helpers/Props';
|
||||||
|
import formatShortTimeSpan from 'Utilities/Date/formatShortTimeSpan';
|
||||||
import translate from 'Utilities/String/translate';
|
import translate from 'Utilities/String/translate';
|
||||||
import EditImportListModalConnector from './EditImportListModalConnector';
|
import EditImportListModalConnector from './EditImportListModalConnector';
|
||||||
import styles from './ImportList.css';
|
import styles from './ImportList.css';
|
||||||
@ -56,7 +57,8 @@ class ImportList extends Component {
|
|||||||
id,
|
id,
|
||||||
name,
|
name,
|
||||||
enabled,
|
enabled,
|
||||||
enableAuto
|
enableAuto,
|
||||||
|
minRefreshInterval
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -96,6 +98,12 @@ class ImportList extends Component {
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.enabled}>
|
||||||
|
<Label kind={kinds.INFO} title='List Refresh Interval'>
|
||||||
|
{`${translate('Refresh')}: ${formatShortTimeSpan(minRefreshInterval)}`}
|
||||||
|
</Label>
|
||||||
|
</div>
|
||||||
|
|
||||||
<EditImportListModalConnector
|
<EditImportListModalConnector
|
||||||
id={id}
|
id={id}
|
||||||
isOpen={this.state.isEditImportListModalOpen}
|
isOpen={this.state.isEditImportListModalOpen}
|
||||||
@ -122,6 +130,7 @@ ImportList.propTypes = {
|
|||||||
name: PropTypes.string.isRequired,
|
name: PropTypes.string.isRequired,
|
||||||
enabled: PropTypes.bool.isRequired,
|
enabled: PropTypes.bool.isRequired,
|
||||||
enableAuto: PropTypes.bool.isRequired,
|
enableAuto: PropTypes.bool.isRequired,
|
||||||
|
minRefreshInterval: PropTypes.string.isRequired,
|
||||||
onConfirmDeleteImportList: PropTypes.func.isRequired
|
onConfirmDeleteImportList: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -46,23 +46,6 @@ function ImportListOptions(props) {
|
|||||||
{
|
{
|
||||||
hasSettings && !isFetching && !error &&
|
hasSettings && !isFetching && !error &&
|
||||||
<Form>
|
<Form>
|
||||||
<FormGroup
|
|
||||||
advancedSettings={advancedSettings}
|
|
||||||
isAdvanced={true}
|
|
||||||
>
|
|
||||||
<FormLabel>{translate('ListUpdateInterval')}</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.NUMBER}
|
|
||||||
name="importListSyncInterval"
|
|
||||||
min={6}
|
|
||||||
unit="hours"
|
|
||||||
helpText={translate('ImportListSyncIntervalHelpText')}
|
|
||||||
onChange={onInputChange}
|
|
||||||
{...settings.importListSyncInterval}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
|
|
||||||
<FormGroup
|
<FormGroup
|
||||||
advancedSettings={advancedSettings}
|
advancedSettings={advancedSettings}
|
||||||
isAdvanced={true}
|
isAdvanced={true}
|
||||||
|
25
frontend/src/Utilities/Date/formatShortTimeSpan.js
Normal file
25
frontend/src/Utilities/Date/formatShortTimeSpan.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
|
function formatShortTimeSpan(timeSpan) {
|
||||||
|
if (!timeSpan) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const duration = moment.duration(timeSpan);
|
||||||
|
|
||||||
|
const hours = Math.floor(duration.asHours());
|
||||||
|
const minutes = Math.floor(duration.asMinutes());
|
||||||
|
const seconds = Math.floor(duration.asSeconds());
|
||||||
|
|
||||||
|
if (hours > 0) {
|
||||||
|
return `${hours} hour(s)`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minutes > 0) {
|
||||||
|
return `${minutes} minute(s)`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${seconds} second(s)`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default formatShortTimeSpan;
|
@ -27,7 +27,7 @@ public void Setup()
|
|||||||
_blockedLists = new List<ImportListStatus>();
|
_blockedLists = new List<ImportListStatus>();
|
||||||
|
|
||||||
Mocker.GetMock<IImportListFactory>()
|
Mocker.GetMock<IImportListFactory>()
|
||||||
.Setup(v => v.Enabled())
|
.Setup(v => v.Enabled(It.IsAny<bool>()))
|
||||||
.Returns(_importLists);
|
.Returns(_importLists);
|
||||||
|
|
||||||
Mocker.GetMock<IImportListStatusService>()
|
Mocker.GetMock<IImportListStatusService>()
|
||||||
@ -183,7 +183,7 @@ public void should_return_all_results_for_all_lists()
|
|||||||
|
|
||||||
var listResult = Subject.Fetch();
|
var listResult = Subject.Fetch();
|
||||||
listResult.AnyFailure.Should().BeFalse();
|
listResult.AnyFailure.Should().BeFalse();
|
||||||
listResult.Movies.Count.Should().Be(10);
|
listResult.Movies.Count.Should().Be(5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ public void Setup()
|
|||||||
};
|
};
|
||||||
|
|
||||||
Mocker.GetMock<IImportListFactory>()
|
Mocker.GetMock<IImportListFactory>()
|
||||||
.Setup(v => v.Enabled())
|
.Setup(v => v.Enabled(It.IsAny<bool>()))
|
||||||
.Returns(_importLists);
|
.Returns(_importLists);
|
||||||
|
|
||||||
Mocker.GetMock<IImportExclusionsService>()
|
Mocker.GetMock<IImportExclusionsService>()
|
||||||
@ -347,7 +347,7 @@ public void should_add_new_movies_from_enabled_lists_to_library()
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_not_add_duplicate_movies_from_seperate_lists()
|
public void should_not_add_duplicate_movies_from_separate_lists()
|
||||||
{
|
{
|
||||||
_list2Movies.ForEach(m => m.ListId = 2);
|
_list2Movies.ForEach(m => m.ListId = 2);
|
||||||
_importListFetch.Movies.ForEach(m => m.ListId = 1);
|
_importListFetch.Movies.ForEach(m => m.ListId = 1);
|
||||||
@ -384,7 +384,7 @@ public void should_not_add_movie_from_on_exclusion_list()
|
|||||||
Subject.Execute(_commandAll);
|
Subject.Execute(_commandAll);
|
||||||
|
|
||||||
Mocker.GetMock<IAddMovieService>()
|
Mocker.GetMock<IAddMovieService>()
|
||||||
.Verify(v => v.AddMovies(It.Is<List<Movie>>(s => s.Count == 7 && !s.Any(m => m.TmdbId == _existingMovies[0].TmdbId)), true), Times.Once());
|
.Verify(v => v.AddMovies(It.Is<List<Movie>>(s => s.Count == 7 && s.All(m => m.TmdbId != _existingMovies[0].TmdbId)), true), Times.Once());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -406,7 +406,7 @@ public void should_not_add_movie_that_exists_in_library()
|
|||||||
Subject.Execute(_commandAll);
|
Subject.Execute(_commandAll);
|
||||||
|
|
||||||
Mocker.GetMock<IAddMovieService>()
|
Mocker.GetMock<IAddMovieService>()
|
||||||
.Verify(v => v.AddMovies(It.Is<List<Movie>>(s => s.Count == 7 && !s.Any(m => m.TmdbId == _existingMovies[0].TmdbId)), true), Times.Once());
|
.Verify(v => v.AddMovies(It.Is<List<Movie>>(s => s.Count == 7 && s.All(m => m.TmdbId != _existingMovies[0].TmdbId)), true), Times.Once());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,13 +116,6 @@ public int AvailabilityDelay
|
|||||||
set { SetValue("AvailabilityDelay", value); }
|
set { SetValue("AvailabilityDelay", value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public int ImportListSyncInterval
|
|
||||||
{
|
|
||||||
get { return GetValueInt("ImportListSyncInterval", 24); }
|
|
||||||
|
|
||||||
set { SetValue("ImportListSyncInterval", value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public string ListSyncLevel
|
public string ListSyncLevel
|
||||||
{
|
{
|
||||||
get { return GetValue("ListSyncLevel", "disabled"); }
|
get { return GetValue("ListSyncLevel", "disabled"); }
|
||||||
|
@ -60,7 +60,6 @@ public interface IConfigService
|
|||||||
bool AllowHardcodedSubs { get; set; }
|
bool AllowHardcodedSubs { get; set; }
|
||||||
string WhitelistedHardcodedSubs { get; set; }
|
string WhitelistedHardcodedSubs { get; set; }
|
||||||
|
|
||||||
int ImportListSyncInterval { get; set; }
|
|
||||||
string ListSyncLevel { get; set; }
|
string ListSyncLevel { get; set; }
|
||||||
string ImportExclusions { get; set; }
|
string ImportExclusions { get; set; }
|
||||||
|
|
||||||
|
18
src/NzbDrone.Core/Datastore/Migration/224_list_sync_time.cs
Normal file
18
src/NzbDrone.Core/Datastore/Migration/224_list_sync_time.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(224)]
|
||||||
|
public class list_sync_time : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Delete.Column("LastSyncListInfo").FromTable("ImportListStatus");
|
||||||
|
|
||||||
|
Alter.Table("ImportListStatus").AddColumn("LastInfoSync").AsDateTimeOffset().Nullable();
|
||||||
|
|
||||||
|
Delete.FromTable("Config").Row(new { Key = "importlistsyncinterval" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -80,6 +80,7 @@ public static void Map()
|
|||||||
Mapper.Entity<ImportListDefinition>("ImportLists").RegisterModel()
|
Mapper.Entity<ImportListDefinition>("ImportLists").RegisterModel()
|
||||||
.Ignore(x => x.ImplementationName)
|
.Ignore(x => x.ImplementationName)
|
||||||
.Ignore(i => i.ListType)
|
.Ignore(i => i.ListType)
|
||||||
|
.Ignore(i => i.MinRefreshInterval)
|
||||||
.Ignore(i => i.Enable);
|
.Ignore(i => i.Enable);
|
||||||
|
|
||||||
Mapper.Entity<NotificationDefinition>("Notifications").RegisterModel()
|
Mapper.Entity<NotificationDefinition>("Notifications").RegisterModel()
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
@ -10,6 +11,7 @@ public class CouchPotatoImport : HttpImportListBase<CouchPotatoSettings>
|
|||||||
public override string Name => "CouchPotato";
|
public override string Name => "CouchPotato";
|
||||||
|
|
||||||
public override ImportListType ListType => ImportListType.Program;
|
public override ImportListType ListType => ImportListType.Program;
|
||||||
|
public override TimeSpan MinRefreshInterval => TimeSpan.FromMinutes(30);
|
||||||
public override bool Enabled => true;
|
public override bool Enabled => true;
|
||||||
public override bool EnableAuto => false;
|
public override bool EnableAuto => false;
|
||||||
|
|
||||||
|
@ -66,6 +66,15 @@ public ImportListFetchResult Fetch()
|
|||||||
_logger.ProgressInfo("Syncing Movies for List: {0}", importList.Name);
|
_logger.ProgressInfo("Syncing Movies for List: {0}", importList.Name);
|
||||||
|
|
||||||
var importListLocal = importList;
|
var importListLocal = importList;
|
||||||
|
|
||||||
|
var importListStatus = _importListStatusService.GetLastSyncListInfo(importListLocal.Definition.Id);
|
||||||
|
|
||||||
|
if (importListStatus.HasValue && DateTime.UtcNow < importListStatus + importListLocal.MinRefreshInterval)
|
||||||
|
{
|
||||||
|
_logger.Trace("Skipping refresh of Import List {0} due to minimum refresh inverval", importListLocal.Definition.Name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
var blockedLists = _importListStatusService.GetBlockedProviders().ToDictionary(v => v.ProviderId, v => v);
|
var blockedLists = _importListStatusService.GetBlockedProviders().ToDictionary(v => v.ProviderId, v => v);
|
||||||
|
|
||||||
if (blockedLists.TryGetValue(importList.Definition.Id, out var blockedListStatus))
|
if (blockedLists.TryGetValue(importList.Definition.Id, out var blockedListStatus))
|
||||||
@ -88,7 +97,7 @@ public ImportListFetchResult Fetch()
|
|||||||
if (!importListReports.AnyFailure)
|
if (!importListReports.AnyFailure)
|
||||||
{
|
{
|
||||||
var alreadyMapped = result.Movies.Where(x => importListReports.Movies.Any(r => r.TmdbId == x.TmdbId));
|
var alreadyMapped = result.Movies.Where(x => importListReports.Movies.Any(r => r.TmdbId == x.TmdbId));
|
||||||
var listMovies = MapMovieReports(importListReports.Movies.Where(x => !result.Movies.Any(r => r.TmdbId == x.TmdbId)).ToList()).Where(x => x.TmdbId > 0).ToList();
|
var listMovies = MapMovieReports(importListReports.Movies.Where(x => result.Movies.All(r => r.TmdbId != x.TmdbId)).ToList()).Where(x => x.TmdbId > 0).ToList();
|
||||||
|
|
||||||
listMovies.AddRange(alreadyMapped);
|
listMovies.AddRange(alreadyMapped);
|
||||||
listMovies = listMovies.DistinctBy(x => x.TmdbId).ToList();
|
listMovies = listMovies.DistinctBy(x => x.TmdbId).ToList();
|
||||||
@ -99,6 +108,8 @@ public ImportListFetchResult Fetch()
|
|||||||
}
|
}
|
||||||
|
|
||||||
result.AnyFailure |= importListReports.AnyFailure;
|
result.AnyFailure |= importListReports.AnyFailure;
|
||||||
|
|
||||||
|
_importListStatusService.UpdateListSyncStatus(importList.Definition.Id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@ -112,6 +123,8 @@ public ImportListFetchResult Fetch()
|
|||||||
|
|
||||||
Task.WaitAll(taskList.ToArray());
|
Task.WaitAll(taskList.ToArray());
|
||||||
|
|
||||||
|
result.Movies = result.Movies.DistinctBy(r => new { r.TmdbId, r.ImdbId, r.Title }).ToList();
|
||||||
|
|
||||||
_logger.Debug("Found {0} reports for all lists", result.Movies.Count);
|
_logger.Debug("Found {0} reports for all lists", result.Movies.Count);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -151,6 +164,8 @@ public ImportListFetchResult FetchSingleList(ImportListDefinition definition)
|
|||||||
}
|
}
|
||||||
|
|
||||||
result.AnyFailure |= importListReports.AnyFailure;
|
result.AnyFailure |= importListReports.AnyFailure;
|
||||||
|
|
||||||
|
_importListStatusService.UpdateListSyncStatus(importList.Definition.Id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@ -158,6 +173,8 @@ public ImportListFetchResult FetchSingleList(ImportListDefinition definition)
|
|||||||
_logger.Error(e, "Error during Import List Sync for list {0}", importList.Name);
|
_logger.Error(e, "Error during Import List Sync for list {0}", importList.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result.Movies = result.Movies.DistinctBy(r => new { r.TmdbId, r.ImdbId, r.Title }).ToList();
|
||||||
|
|
||||||
_logger.Debug("Found {0} reports for list {1}", result.Movies.Count, importList.Name);
|
_logger.Debug("Found {0} reports for list {1}", result.Movies.Count, importList.Name);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -166,9 +183,9 @@ public ImportListFetchResult FetchSingleList(ImportListDefinition definition)
|
|||||||
private List<ImportListMovie> MapMovieReports(List<ImportListMovie> reports)
|
private List<ImportListMovie> MapMovieReports(List<ImportListMovie> reports)
|
||||||
{
|
{
|
||||||
var mappedMovies = reports.Select(m => _movieSearch.MapMovieToTmdbMovie(new MovieMetadata { Title = m.Title, TmdbId = m.TmdbId, ImdbId = m.ImdbId, Year = m.Year }))
|
var mappedMovies = reports.Select(m => _movieSearch.MapMovieToTmdbMovie(new MovieMetadata { Title = m.Title, TmdbId = m.TmdbId, ImdbId = m.ImdbId, Year = m.Year }))
|
||||||
.Where(x => x != null)
|
.Where(x => x != null)
|
||||||
.DistinctBy(x => x.TmdbId)
|
.DistinctBy(x => x.TmdbId)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
_movieMetadataService.UpsertMany(mappedMovies);
|
_movieMetadataService.UpsertMany(mappedMovies);
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
namespace NzbDrone.Core.ImportLists
|
namespace NzbDrone.Core.ImportLists
|
||||||
@ -8,6 +9,7 @@ public interface IImportList : IProvider
|
|||||||
bool EnableAuto { get; }
|
bool EnableAuto { get; }
|
||||||
|
|
||||||
ImportListType ListType { get; }
|
ImportListType ListType { get; }
|
||||||
|
TimeSpan MinRefreshInterval { get; }
|
||||||
ImportListFetchResult Fetch();
|
ImportListFetchResult Fetch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ public abstract class ImportListBase<TSettings> : IImportList
|
|||||||
public abstract string Name { get; }
|
public abstract string Name { get; }
|
||||||
|
|
||||||
public abstract ImportListType ListType { get; }
|
public abstract ImportListType ListType { get; }
|
||||||
|
public abstract TimeSpan MinRefreshInterval { get; }
|
||||||
public abstract bool Enabled { get; }
|
public abstract bool Enabled { get; }
|
||||||
public abstract bool EnableAuto { get; }
|
public abstract bool EnableAuto { get; }
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NzbDrone.Core.Movies;
|
using NzbDrone.Core.Movies;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
@ -21,5 +22,6 @@ public ImportListDefinition()
|
|||||||
public override bool Enable => Enabled;
|
public override bool Enable => Enabled;
|
||||||
|
|
||||||
public ImportListType ListType { get; set; }
|
public ImportListType ListType { get; set; }
|
||||||
|
public TimeSpan MinRefreshInterval { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,23 +9,24 @@ namespace NzbDrone.Core.ImportLists
|
|||||||
{
|
{
|
||||||
public interface IImportListFactory : IProviderFactory<IImportList, ImportListDefinition>
|
public interface IImportListFactory : IProviderFactory<IImportList, ImportListDefinition>
|
||||||
{
|
{
|
||||||
List<IImportList> Enabled();
|
List<IImportList> Enabled(bool filterBlockedImportLists = true);
|
||||||
List<IImportList> Discoverable();
|
List<IImportList> Discoverable();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ImportListFactory : ProviderFactory<IImportList, ImportListDefinition>, IImportListFactory
|
public class ImportListFactory : ProviderFactory<IImportList, ImportListDefinition>, IImportListFactory
|
||||||
{
|
{
|
||||||
private readonly IImportListRepository _providerRepository;
|
private readonly IImportListStatusService _importListStatusService;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public ImportListFactory(IImportListRepository providerRepository,
|
public ImportListFactory(IImportListStatusService importListStatusService,
|
||||||
|
IImportListRepository providerRepository,
|
||||||
IEnumerable<IImportList> providers,
|
IEnumerable<IImportList> providers,
|
||||||
IServiceProvider container,
|
IServiceProvider container,
|
||||||
IEventAggregator eventAggregator,
|
IEventAggregator eventAggregator,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
: base(providerRepository, providers, container, eventAggregator, logger)
|
: base(providerRepository, providers, container, eventAggregator, logger)
|
||||||
{
|
{
|
||||||
_providerRepository = providerRepository;
|
_importListStatusService = importListStatusService;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,18 +40,42 @@ public override void SetProviderCharacteristics(IImportList provider, ImportList
|
|||||||
base.SetProviderCharacteristics(provider, definition);
|
base.SetProviderCharacteristics(provider, definition);
|
||||||
|
|
||||||
definition.ListType = provider.ListType;
|
definition.ListType = provider.ListType;
|
||||||
|
definition.MinRefreshInterval = provider.MinRefreshInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<IImportList> Enabled()
|
public List<IImportList> Enabled(bool filterBlockedImportLists = true)
|
||||||
{
|
{
|
||||||
var enabledImporters = GetAvailableProviders().Where(n => ((ImportListDefinition)n.Definition).Enabled);
|
var enabledImportLists = GetAvailableProviders().Where(n => ((ImportListDefinition)n.Definition).Enabled);
|
||||||
return enabledImporters.ToList();
|
|
||||||
|
if (filterBlockedImportLists)
|
||||||
|
{
|
||||||
|
return FilterBlockedImportLists(enabledImportLists).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return enabledImportLists.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<IImportList> Discoverable()
|
public List<IImportList> Discoverable()
|
||||||
{
|
{
|
||||||
var enabledImporters = GetAvailableProviders().Where(n => (n.GetType() == typeof(RadarrList.RadarrListImport) || n.GetType() == typeof(TMDb.Popular.TMDbPopularImport)));
|
var enabledImportLists = GetAvailableProviders().Where(n => n.GetType() == typeof(RadarrList.RadarrListImport) || n.GetType() == typeof(TMDb.Popular.TMDbPopularImport));
|
||||||
return enabledImporters.ToList();
|
|
||||||
|
return enabledImportLists.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerable<IImportList> FilterBlockedImportLists(IEnumerable<IImportList> importLists)
|
||||||
|
{
|
||||||
|
var blockedImportLists = _importListStatusService.GetBlockedProviders().ToDictionary(v => v.ProviderId, v => v);
|
||||||
|
|
||||||
|
foreach (var importList in importLists)
|
||||||
|
{
|
||||||
|
if (blockedImportLists.TryGetValue(importList.Definition.Id, out var blockedImportListStatus))
|
||||||
|
{
|
||||||
|
_logger.Debug("Temporarily ignoring import list {0} till {1} due to recent failures.", importList.Definition.Name, blockedImportListStatus.DisabledTill.Value.ToLocalTime());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
yield return importList;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
using NzbDrone.Core.Movies;
|
using System;
|
||||||
using NzbDrone.Core.ThingiProvider.Status;
|
using NzbDrone.Core.ThingiProvider.Status;
|
||||||
|
|
||||||
namespace NzbDrone.Core.ImportLists
|
namespace NzbDrone.Core.ImportLists
|
||||||
{
|
{
|
||||||
public class ImportListStatus : ProviderStatusBase
|
public class ImportListStatus : ProviderStatusBase
|
||||||
{
|
{
|
||||||
public Movie LastSyncListInfo { get; set; }
|
public DateTime? LastInfoSync { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
|
using System;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
using NzbDrone.Core.Movies;
|
|
||||||
using NzbDrone.Core.ThingiProvider.Status;
|
using NzbDrone.Core.ThingiProvider.Status;
|
||||||
|
|
||||||
namespace NzbDrone.Core.ImportLists
|
namespace NzbDrone.Core.ImportLists
|
||||||
{
|
{
|
||||||
public interface IImportListStatusService : IProviderStatusServiceBase<ImportListStatus>
|
public interface IImportListStatusService : IProviderStatusServiceBase<ImportListStatus>
|
||||||
{
|
{
|
||||||
Movie GetLastSyncListInfo(int importListId);
|
DateTime? GetLastSyncListInfo(int importListId);
|
||||||
|
|
||||||
void UpdateListSyncStatus(int importListId, Movie listItemInfo);
|
void UpdateListSyncStatus(int importListId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ImportListStatusService : ProviderStatusServiceBase<IImportList, ImportListStatus>, IImportListStatusService
|
public class ImportListStatusService : ProviderStatusServiceBase<IImportList, ImportListStatus>, IImportListStatusService
|
||||||
@ -20,18 +20,18 @@ public ImportListStatusService(IImportListStatusRepository providerStatusReposit
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public Movie GetLastSyncListInfo(int importListId)
|
public DateTime? GetLastSyncListInfo(int importListId)
|
||||||
{
|
{
|
||||||
return GetProviderStatus(importListId).LastSyncListInfo;
|
return GetProviderStatus(importListId).LastInfoSync;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateListSyncStatus(int importListId, Movie listItemInfo)
|
public void UpdateListSyncStatus(int importListId)
|
||||||
{
|
{
|
||||||
lock (_syncRoot)
|
lock (_syncRoot)
|
||||||
{
|
{
|
||||||
var status = GetProviderStatus(importListId);
|
var status = GetProviderStatus(importListId);
|
||||||
|
|
||||||
status.LastSyncListInfo = listItemInfo;
|
status.LastInfoSync = DateTime.UtcNow;
|
||||||
|
|
||||||
_providerStatusRepository.Upsert(status);
|
_providerStatusRepository.Upsert(status);
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ public class PlexImport : HttpImportListBase<PlexListSettings>
|
|||||||
{
|
{
|
||||||
public readonly IPlexTvService _plexTvService;
|
public readonly IPlexTvService _plexTvService;
|
||||||
public override ImportListType ListType => ImportListType.Plex;
|
public override ImportListType ListType => ImportListType.Plex;
|
||||||
|
public override TimeSpan MinRefreshInterval => TimeSpan.FromHours(6);
|
||||||
|
|
||||||
public PlexImport(IPlexTvService plexTvService,
|
public PlexImport(IPlexTvService plexTvService,
|
||||||
IHttpClient httpClient,
|
IHttpClient httpClient,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
@ -12,6 +13,7 @@ public class RSSImport : HttpImportListBase<RSSImportSettings>
|
|||||||
public override string Name => "RSS List";
|
public override string Name => "RSS List";
|
||||||
|
|
||||||
public override ImportListType ListType => ImportListType.Advanced;
|
public override ImportListType ListType => ImportListType.Advanced;
|
||||||
|
public override TimeSpan MinRefreshInterval => TimeSpan.FromHours(12);
|
||||||
public override bool Enabled => true;
|
public override bool Enabled => true;
|
||||||
public override bool EnableAuto => false;
|
public override bool EnableAuto => false;
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ public class RadarrImport : ImportListBase<RadarrSettings>
|
|||||||
public override bool EnableAuto => false;
|
public override bool EnableAuto => false;
|
||||||
|
|
||||||
public override ImportListType ListType => ImportListType.Program;
|
public override ImportListType ListType => ImportListType.Program;
|
||||||
|
public override TimeSpan MinRefreshInterval => TimeSpan.FromMinutes(15);
|
||||||
|
|
||||||
public RadarrImport(IRadarrV3Proxy radarrV3Proxy,
|
public RadarrImport(IRadarrV3Proxy radarrV3Proxy,
|
||||||
IImportListStatusService importListStatusService,
|
IImportListStatusService importListStatusService,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
@ -12,6 +13,7 @@ public class RadarrListImport : HttpImportListBase<RadarrListSettings>
|
|||||||
public override string Name => "Custom Lists";
|
public override string Name => "Custom Lists";
|
||||||
|
|
||||||
public override ImportListType ListType => ImportListType.Advanced;
|
public override ImportListType ListType => ImportListType.Advanced;
|
||||||
|
public override TimeSpan MinRefreshInterval => TimeSpan.FromHours(12);
|
||||||
public override bool Enabled => true;
|
public override bool Enabled => true;
|
||||||
public override bool EnableAuto => false;
|
public override bool EnableAuto => false;
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Cloud;
|
using NzbDrone.Common.Cloud;
|
||||||
@ -15,6 +16,7 @@ public class IMDbListImport : HttpImportListBase<IMDbListSettings>
|
|||||||
public override string Name => "IMDb Lists";
|
public override string Name => "IMDb Lists";
|
||||||
|
|
||||||
public override ImportListType ListType => ImportListType.Other;
|
public override ImportListType ListType => ImportListType.Other;
|
||||||
|
public override TimeSpan MinRefreshInterval => TimeSpan.FromHours(12);
|
||||||
public override bool Enabled => true;
|
public override bool Enabled => true;
|
||||||
public override bool EnableAuto => false;
|
public override bool EnableAuto => false;
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Cloud;
|
using NzbDrone.Common.Cloud;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
@ -13,6 +14,8 @@ public class StevenLu2Import : HttpImportListBase<StevenLu2Settings>
|
|||||||
public override string Name => "StevenLu List";
|
public override string Name => "StevenLu List";
|
||||||
|
|
||||||
public override ImportListType ListType => ImportListType.Other;
|
public override ImportListType ListType => ImportListType.Other;
|
||||||
|
public override TimeSpan MinRefreshInterval => TimeSpan.FromHours(12);
|
||||||
|
|
||||||
public override bool Enabled => true;
|
public override bool Enabled => true;
|
||||||
public override bool EnableAuto => false;
|
public override bool EnableAuto => false;
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
@ -9,6 +10,7 @@ public class PlexRssImport : RssImportBase<PlexRssImportSettings>
|
|||||||
{
|
{
|
||||||
public override string Name => "Plex Watchlist RSS";
|
public override string Name => "Plex Watchlist RSS";
|
||||||
public override ImportListType ListType => ImportListType.Plex;
|
public override ImportListType ListType => ImportListType.Plex;
|
||||||
|
public override TimeSpan MinRefreshInterval => TimeSpan.FromHours(6);
|
||||||
|
|
||||||
public PlexRssImport(IHttpClient httpClient,
|
public PlexRssImport(IHttpClient httpClient,
|
||||||
IImportListStatusService importListStatusService,
|
IImportListStatusService importListStatusService,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
@ -10,6 +11,7 @@ public class StevenLuImport : HttpImportListBase<StevenLuSettings>
|
|||||||
public override string Name => "StevenLu Custom";
|
public override string Name => "StevenLu Custom";
|
||||||
|
|
||||||
public override ImportListType ListType => ImportListType.Advanced;
|
public override ImportListType ListType => ImportListType.Advanced;
|
||||||
|
public override TimeSpan MinRefreshInterval => TimeSpan.FromHours(24);
|
||||||
public override bool Enabled => true;
|
public override bool Enabled => true;
|
||||||
public override bool EnableAuto => false;
|
public override bool EnableAuto => false;
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Cloud;
|
using NzbDrone.Common.Cloud;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
@ -11,6 +12,7 @@ public abstract class TMDbImportListBase<TSettings> : HttpImportListBase<TSettin
|
|||||||
where TSettings : TMDbSettingsBase<TSettings>, new()
|
where TSettings : TMDbSettingsBase<TSettings>, new()
|
||||||
{
|
{
|
||||||
public override ImportListType ListType => ImportListType.TMDB;
|
public override ImportListType ListType => ImportListType.TMDB;
|
||||||
|
public override TimeSpan MinRefreshInterval => TimeSpan.FromHours(12);
|
||||||
|
|
||||||
public readonly ISearchForNewMovie _skyhookProxy;
|
public readonly ISearchForNewMovie _skyhookProxy;
|
||||||
public readonly IHttpRequestBuilderFactory _requestBuilder;
|
public readonly IHttpRequestBuilderFactory _requestBuilder;
|
||||||
|
@ -15,6 +15,7 @@ public abstract class TraktImportBase<TSettings> : HttpImportListBase<TSettings>
|
|||||||
public ITraktProxy _traktProxy;
|
public ITraktProxy _traktProxy;
|
||||||
private readonly IImportListRepository _importListRepository;
|
private readonly IImportListRepository _importListRepository;
|
||||||
public override ImportListType ListType => ImportListType.Trakt;
|
public override ImportListType ListType => ImportListType.Trakt;
|
||||||
|
public override TimeSpan MinRefreshInterval => TimeSpan.FromHours(12);
|
||||||
|
|
||||||
protected TraktImportBase(IImportListRepository importListRepository,
|
protected TraktImportBase(IImportListRepository importListRepository,
|
||||||
ITraktProxy traktProxy,
|
ITraktProxy traktProxy,
|
||||||
|
@ -121,7 +121,7 @@ public void Handle(ApplicationStartedEvent message)
|
|||||||
|
|
||||||
new ScheduledTask
|
new ScheduledTask
|
||||||
{
|
{
|
||||||
Interval = GetImportListSyncInterval(),
|
Interval = 5,
|
||||||
TypeName = typeof(ImportListSyncCommand).FullName
|
TypeName = typeof(ImportListSyncCommand).FullName
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -210,14 +210,6 @@ private int GetRefreshMonitoredInterval()
|
|||||||
return interval;
|
return interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int GetImportListSyncInterval()
|
|
||||||
{
|
|
||||||
// Enforce 6 hour min on list sync
|
|
||||||
var interval = Math.Max(_configService.ImportListSyncInterval, 6);
|
|
||||||
|
|
||||||
return interval * 60;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Handle(CommandExecutedEvent message)
|
public void Handle(CommandExecutedEvent message)
|
||||||
{
|
{
|
||||||
var scheduledTask = _scheduledTaskRepository.All().SingleOrDefault(c => c.TypeName == message.Command.Body.GetType().FullName);
|
var scheduledTask = _scheduledTaskRepository.All().SingleOrDefault(c => c.TypeName == message.Command.Body.GetType().FullName);
|
||||||
@ -239,19 +231,15 @@ public void HandleAsync(ConfigSavedEvent message)
|
|||||||
var rss = _scheduledTaskRepository.GetDefinition(typeof(RssSyncCommand));
|
var rss = _scheduledTaskRepository.GetDefinition(typeof(RssSyncCommand));
|
||||||
rss.Interval = GetRssSyncInterval();
|
rss.Interval = GetRssSyncInterval();
|
||||||
|
|
||||||
var importList = _scheduledTaskRepository.GetDefinition(typeof(ImportListSyncCommand));
|
|
||||||
importList.Interval = GetImportListSyncInterval();
|
|
||||||
|
|
||||||
var backup = _scheduledTaskRepository.GetDefinition(typeof(BackupCommand));
|
var backup = _scheduledTaskRepository.GetDefinition(typeof(BackupCommand));
|
||||||
backup.Interval = GetBackupInterval();
|
backup.Interval = GetBackupInterval();
|
||||||
|
|
||||||
var refreshMonitoredDownloads = _scheduledTaskRepository.GetDefinition(typeof(RefreshMonitoredDownloadsCommand));
|
var refreshMonitoredDownloads = _scheduledTaskRepository.GetDefinition(typeof(RefreshMonitoredDownloadsCommand));
|
||||||
refreshMonitoredDownloads.Interval = GetRefreshMonitoredInterval();
|
refreshMonitoredDownloads.Interval = GetRefreshMonitoredInterval();
|
||||||
|
|
||||||
_scheduledTaskRepository.UpdateMany(new List<ScheduledTask> { rss, importList, refreshMonitoredDownloads, backup });
|
_scheduledTaskRepository.UpdateMany(new List<ScheduledTask> { rss, refreshMonitoredDownloads, backup });
|
||||||
|
|
||||||
_cache.Find(rss.TypeName).Interval = rss.Interval;
|
_cache.Find(rss.TypeName).Interval = rss.Interval;
|
||||||
_cache.Find(importList.TypeName).Interval = importList.Interval;
|
|
||||||
_cache.Find(backup.TypeName).Interval = backup.Interval;
|
_cache.Find(backup.TypeName).Interval = backup.Interval;
|
||||||
_cache.Find(refreshMonitoredDownloads.TypeName).Interval = refreshMonitoredDownloads.Interval;
|
_cache.Find(refreshMonitoredDownloads.TypeName).Interval = refreshMonitoredDownloads.Interval;
|
||||||
}
|
}
|
||||||
|
@ -416,7 +416,6 @@
|
|||||||
"ImportListMultipleMissingRoots": "Multiple root folders are missing for import lists: {0}",
|
"ImportListMultipleMissingRoots": "Multiple root folders are missing for import lists: {0}",
|
||||||
"ImportListStatusCheckAllClientMessage": "All lists are unavailable due to failures",
|
"ImportListStatusCheckAllClientMessage": "All lists are unavailable due to failures",
|
||||||
"ImportListStatusCheckSingleClientMessage": "Lists unavailable due to failures: {0}",
|
"ImportListStatusCheckSingleClientMessage": "Lists unavailable due to failures: {0}",
|
||||||
"ImportListSyncIntervalHelpText": "How often Radarr syncs with your lists. Minimum value of 6 hours",
|
|
||||||
"ImportMechanismHealthCheckMessage": "Enable Completed Download Handling",
|
"ImportMechanismHealthCheckMessage": "Enable Completed Download Handling",
|
||||||
"ImportMovies": "Import Movies",
|
"ImportMovies": "Import Movies",
|
||||||
"ImportNotForDownloads": "Do not use for importing downloads from your download client, this is only for existing organized libraries, not unsorted files.",
|
"ImportNotForDownloads": "Do not use for importing downloads from your download client, this is only for existing organized libraries, not unsorted files.",
|
||||||
@ -484,11 +483,12 @@
|
|||||||
"Links": "Links",
|
"Links": "Links",
|
||||||
"List": "List",
|
"List": "List",
|
||||||
"ListExclusions": "List Exclusions",
|
"ListExclusions": "List Exclusions",
|
||||||
|
"ListRefreshInterval": "List Refresh Interval",
|
||||||
"ListSettings": "List Settings",
|
"ListSettings": "List Settings",
|
||||||
"ListSyncLevelHelpText": "Movies in library will be handled based on your selection if they fall off or do not appear on your list(s)",
|
"ListSyncLevelHelpText": "Movies in library will be handled based on your selection if they fall off or do not appear on your list(s)",
|
||||||
"ListSyncLevelHelpTextWarning": "Movie files will be permanently deleted, this can result in wiping your library if your lists are empty",
|
"ListSyncLevelHelpTextWarning": "Movie files will be permanently deleted, this can result in wiping your library if your lists are empty",
|
||||||
"ListTagsHelpText": "Tags list items will be added with",
|
"ListTagsHelpText": "Tags list items will be added with",
|
||||||
"ListUpdateInterval": "List Update Interval",
|
"ListWillRefreshEveryInterp": "List will refresh every {0}",
|
||||||
"Lists": "Lists",
|
"Lists": "Lists",
|
||||||
"ListsSettingsSummary": "Import Lists, list exclusions",
|
"ListsSettingsSummary": "Import Lists, list exclusions",
|
||||||
"Loading": "Loading",
|
"Loading": "Loading",
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using Radarr.Http;
|
using Radarr.Http;
|
||||||
using Radarr.Http.Validation;
|
|
||||||
|
|
||||||
namespace Radarr.Api.V3.Config
|
namespace Radarr.Api.V3.Config
|
||||||
{
|
{
|
||||||
@ -11,8 +10,6 @@ public class ImportListConfigController : ConfigController<ImportListConfigResou
|
|||||||
public ImportListConfigController(IConfigService configService)
|
public ImportListConfigController(IConfigService configService)
|
||||||
: base(configService)
|
: base(configService)
|
||||||
{
|
{
|
||||||
SharedValidator.RuleFor(c => c.ImportListSyncInterval)
|
|
||||||
.IsValidImportListSyncInterval();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override ImportListConfigResource ToResource(IConfigService model)
|
protected override ImportListConfigResource ToResource(IConfigService model)
|
||||||
|
@ -5,7 +5,6 @@ namespace Radarr.Api.V3.Config
|
|||||||
{
|
{
|
||||||
public class ImportListConfigResource : RestResource
|
public class ImportListConfigResource : RestResource
|
||||||
{
|
{
|
||||||
public int ImportListSyncInterval { get; set; }
|
|
||||||
public string ListSyncLevel { get; set; }
|
public string ListSyncLevel { get; set; }
|
||||||
public string ImportExclusions { get; set; }
|
public string ImportExclusions { get; set; }
|
||||||
}
|
}
|
||||||
@ -16,7 +15,6 @@ public static ImportListConfigResource ToResource(IConfigService model)
|
|||||||
{
|
{
|
||||||
return new ImportListConfigResource
|
return new ImportListConfigResource
|
||||||
{
|
{
|
||||||
ImportListSyncInterval = model.ImportListSyncInterval,
|
|
||||||
ListSyncLevel = model.ListSyncLevel,
|
ListSyncLevel = model.ListSyncLevel,
|
||||||
ImportExclusions = model.ImportExclusions
|
ImportExclusions = model.ImportExclusions
|
||||||
};
|
};
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using NzbDrone.Core.ImportLists;
|
using NzbDrone.Core.ImportLists;
|
||||||
using NzbDrone.Core.Movies;
|
using NzbDrone.Core.Movies;
|
||||||
|
|
||||||
@ -14,6 +15,7 @@ public class ImportListResource : ProviderResource<ImportListResource>
|
|||||||
public MovieStatusType MinimumAvailability { get; set; }
|
public MovieStatusType MinimumAvailability { get; set; }
|
||||||
public ImportListType ListType { get; set; }
|
public ImportListType ListType { get; set; }
|
||||||
public int ListOrder { get; set; }
|
public int ListOrder { get; set; }
|
||||||
|
public TimeSpan MinRefreshInterval { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ImportListResourceMapper : ProviderResourceMapper<ImportListResource, ImportListDefinition>
|
public class ImportListResourceMapper : ProviderResourceMapper<ImportListResource, ImportListDefinition>
|
||||||
@ -36,6 +38,7 @@ public override ImportListResource ToResource(ImportListDefinition definition)
|
|||||||
resource.MinimumAvailability = definition.MinimumAvailability;
|
resource.MinimumAvailability = definition.MinimumAvailability;
|
||||||
resource.ListType = definition.ListType;
|
resource.ListType = definition.ListType;
|
||||||
resource.ListOrder = (int)definition.ListType;
|
resource.ListOrder = (int)definition.ListType;
|
||||||
|
resource.MinRefreshInterval = definition.MinRefreshInterval;
|
||||||
|
|
||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
@ -57,6 +60,7 @@ public override ImportListDefinition ToModel(ImportListResource resource)
|
|||||||
definition.ProfileId = resource.QualityProfileId;
|
definition.ProfileId = resource.QualityProfileId;
|
||||||
definition.MinimumAvailability = resource.MinimumAvailability;
|
definition.MinimumAvailability = resource.MinimumAvailability;
|
||||||
definition.ListType = resource.ListType;
|
definition.ListType = resource.ListType;
|
||||||
|
definition.MinRefreshInterval = resource.MinRefreshInterval;
|
||||||
|
|
||||||
return definition;
|
return definition;
|
||||||
}
|
}
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
using FluentValidation.Validators;
|
|
||||||
|
|
||||||
namespace Radarr.Http.Validation
|
|
||||||
{
|
|
||||||
public class ImportListSyncIntervalValidator : PropertyValidator
|
|
||||||
{
|
|
||||||
protected override string GetDefaultMessageTemplate() => "Must be greater than 6 hours";
|
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
|
||||||
{
|
|
||||||
if (context.PropertyValue == null)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
var value = (int)context.PropertyValue;
|
|
||||||
|
|
||||||
return value >= 6;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -36,10 +36,5 @@ public static IRuleBuilderOptions<T, int> IsValidRssSyncInterval<T>(this IRuleBu
|
|||||||
{
|
{
|
||||||
return ruleBuilder.SetValidator(new RssSyncIntervalValidator());
|
return ruleBuilder.SetValidator(new RssSyncIntervalValidator());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IRuleBuilderOptions<T, int> IsValidImportListSyncInterval<T>(this IRuleBuilder<T, int> ruleBuilder)
|
|
||||||
{
|
|
||||||
return ruleBuilder.SetValidator(new ImportListSyncIntervalValidator());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user