New: Rework List sync interval logic

(cherry picked from commit c522cd120d08757e7e43c2348be4d7f05a254fac)
pull/2459/head
Qstick 1 year ago committed by Bogdan
parent 145422e00a
commit 86d1250831

@ -13,3 +13,9 @@
.labelIcon {
margin-left: 8px;
}
.message {
composes: alert from '~Components/Alert.css';
margin-bottom: 30px;
}

@ -20,6 +20,7 @@ import ModalFooter from 'Components/Modal/ModalFooter';
import ModalHeader from 'Components/Modal/ModalHeader';
import Popover from 'Components/Tooltip/Popover';
import { icons, inputTypes, kinds, tooltipPositions } from 'Helpers/Props';
import formatShortTimeSpan from 'Utilities/Date/formatShortTimeSpan';
import translate from 'Utilities/String/translate';
import styles from './EditImportListModalContent.css';
@ -74,6 +75,7 @@ function EditImportListModalContent(props) {
id,
name,
enableAutomaticAdd,
minRefreshInterval,
shouldMonitor,
shouldMonitorExisting,
shouldSearch,
@ -118,6 +120,13 @@ function EditImportListModalContent(props) {
</Alert>
}
<Alert
kind={kinds.INFO}
className={styles.message}
>
{translate('ListWillRefreshEveryInterp', [formatShortTimeSpan(minRefreshInterval.value)])}
</Alert>
<FieldSet legend={translate('ImportListSettings')} >
<FormGroup>
<FormLabel>

@ -4,6 +4,7 @@ import Card from 'Components/Card';
import Label from 'Components/Label';
import ConfirmModal from 'Components/Modal/ConfirmModal';
import { kinds } from 'Helpers/Props';
import formatShortTimeSpan from 'Utilities/Date/formatShortTimeSpan';
import translate from 'Utilities/String/translate';
import EditImportListModalConnector from './EditImportListModalConnector';
import styles from './ImportList.css';
@ -56,6 +57,7 @@ class ImportList extends Component {
id,
name,
enableAutomaticAdd,
minRefreshInterval,
shouldSearch
} = this.props;
@ -85,6 +87,15 @@ class ImportList extends Component {
}
</div>
<div className={styles.enabled}>
<Label
kind={kinds.INFO}
title={translate('ListRefreshInterval')}
>
{`${translate('Refresh')}: ${formatShortTimeSpan(minRefreshInterval)}`}
</Label>
</div>
<EditImportListModalConnector
id={id}
isOpen={this.state.isEditImportListModalOpen}
@ -110,6 +121,7 @@ ImportList.propTypes = {
id: PropTypes.number.isRequired,
name: PropTypes.string.isRequired,
enableAutomaticAdd: PropTypes.bool.isRequired,
minRefreshInterval: PropTypes.string.isRequired,
shouldSearch: PropTypes.bool.isRequired,
onConfirmDeleteImportList: PropTypes.func.isRequired
};

@ -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;

@ -0,0 +1,16 @@
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(029)]
public class list_sync_time : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Delete.Column("LastSyncListInfo").FromTable("ImportListStatus");
Alter.Table("ImportListStatus").AddColumn("LastInfoSync").AsDateTime().Nullable();
}
}
}

@ -75,8 +75,9 @@ namespace NzbDrone.Core.Datastore
Mapper.Entity<ImportListDefinition>("ImportLists").RegisterModel()
.Ignore(x => x.ImplementationName)
.Ignore(i => i.Enable)
.Ignore(i => i.ListType);
.Ignore(i => i.ListType)
.Ignore(i => i.MinRefreshInterval)
.Ignore(i => i.Enable);
Mapper.Entity<NotificationDefinition>("Notifications").RegisterModel()
.Ignore(x => x.ImplementationName)

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NLog;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.TPL;
using NzbDrone.Core.Parser.Model;
@ -18,11 +17,13 @@ namespace NzbDrone.Core.ImportLists
public class FetchAndParseImportListService : IFetchAndParseImportList
{
private readonly IImportListFactory _importListFactory;
private readonly IImportListStatusService _importListStatusService;
private readonly Logger _logger;
public FetchAndParseImportListService(IImportListFactory importListFactory, Logger logger)
public FetchAndParseImportListService(IImportListFactory importListFactory, IImportListStatusService importListStatusService, Logger logger)
{
_importListFactory = importListFactory;
_importListStatusService = importListStatusService;
_logger = logger;
}
@ -46,6 +47,13 @@ namespace NzbDrone.Core.ImportLists
foreach (var importList in importLists)
{
var importListLocal = importList;
var importListStatus = _importListStatusService.GetLastSyncListInfo(importListLocal.Definition.Id);
if (DateTime.UtcNow < (importListStatus + importListLocal.MinRefreshInterval))
{
_logger.Trace("Skipping refresh of Import List {0} due to minimum refresh inverval", importListLocal.Definition.Name);
continue;
}
var task = taskFactory.StartNew(() =>
{
@ -59,6 +67,8 @@ namespace NzbDrone.Core.ImportLists
result.AddRange(importListReports);
}
_importListStatusService.UpdateListSyncStatus(importList.Definition.Id);
}
catch (Exception e)
{
@ -90,6 +100,14 @@ namespace NzbDrone.Core.ImportLists
return result;
}
var importListStatus = _importListStatusService.GetLastSyncListInfo(importList.Definition.Id);
if (DateTime.UtcNow < (importListStatus + importList.MinRefreshInterval))
{
_logger.Trace("Skipping refresh of Import List {0} due to minimum refresh inverval", importList.Definition.Name);
return result;
}
var taskList = new List<Task>();
var taskFactory = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.None);

@ -24,6 +24,7 @@ namespace NzbDrone.Core.ImportLists.Goodreads
}
public override string Name => "Goodreads Bookshelves";
public override TimeSpan MinRefreshInterval => TimeSpan.FromHours(12);
public override IList<ImportListItemInfo> Fetch()
{

@ -19,6 +19,7 @@ namespace NzbDrone.Core.ImportLists.Goodreads
public override string Name => "Goodreads List";
public override ImportListType ListType => ImportListType.Goodreads;
public override TimeSpan MinRefreshInterval => TimeSpan.FromHours(12);
public GoodreadsListImportList(IProvideListInfo listInfo,
IImportListStatusService importListStatusService,

@ -27,6 +27,7 @@ namespace NzbDrone.Core.ImportLists.Goodreads
}
public override string Name => "Goodreads Owned Books";
public override TimeSpan MinRefreshInterval => TimeSpan.FromHours(12);
public override IList<ImportListItemInfo> Fetch()
{

@ -18,6 +18,7 @@ namespace NzbDrone.Core.ImportLists.Goodreads
public override string Name => "Goodreads Series";
public override ImportListType ListType => ImportListType.Goodreads;
public override TimeSpan MinRefreshInterval => TimeSpan.FromHours(12);
public GoodreadsSeriesImportList(IProvideSeriesInfo seriesInfo,
IImportListStatusService importListStatusService,

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.ThingiProvider;
@ -7,6 +8,7 @@ namespace NzbDrone.Core.ImportLists
public interface IImportList : IProvider
{
ImportListType ListType { get; }
TimeSpan MinRefreshInterval { get; }
IList<ImportListItemInfo> Fetch();
}
}

@ -5,6 +5,7 @@ using FluentValidation.Results;
using NLog;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.ThingiProvider;
@ -23,6 +24,8 @@ namespace NzbDrone.Core.ImportLists
public abstract ImportListType ListType { get; }
public abstract TimeSpan MinRefreshInterval { get; }
public ImportListBase(IImportListStatusService importListStatusService, IConfigService configService, IParsingService parsingService, Logger logger)
{
_importListStatusService = importListStatusService;

@ -1,3 +1,4 @@
using System;
using NzbDrone.Core.Books;
using NzbDrone.Core.ThingiProvider;
@ -18,6 +19,7 @@ namespace NzbDrone.Core.ImportLists
public ImportListStatus Status { get; set; }
public ImportListType ListType { get; set; }
public TimeSpan MinRefreshInterval { get; set; }
}
public enum ImportListMonitorType

@ -41,6 +41,7 @@ namespace NzbDrone.Core.ImportLists
base.SetProviderCharacteristics(provider, definition);
definition.ListType = provider.ListType;
definition.MinRefreshInterval = provider.MinRefreshInterval;
}
public List<IImportList> AutomaticAddEnabled(bool filterBlockedImportLists = true)

@ -1,3 +1,4 @@
using System;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.ThingiProvider.Status;
@ -5,6 +6,6 @@ namespace NzbDrone.Core.ImportLists
{
public class ImportListStatus : ProviderStatusBase
{
public ImportListItemInfo LastSyncListInfo { get; set; }
public DateTime LastInfoSync { get; set; }
}
}

@ -1,16 +1,16 @@
using System;
using NLog;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.ThingiProvider.Status;
namespace NzbDrone.Core.ImportLists
{
public interface IImportListStatusService : IProviderStatusServiceBase<ImportListStatus>
{
ImportListItemInfo GetLastSyncListInfo(int importListId);
DateTime GetLastSyncListInfo(int importListId);
void UpdateListSyncStatus(int importListId, ImportListItemInfo listItemInfo);
void UpdateListSyncStatus(int importListId);
}
public class ImportListStatusService : ProviderStatusServiceBase<IImportList, ImportListStatus>, IImportListStatusService
@ -20,18 +20,18 @@ namespace NzbDrone.Core.ImportLists
{
}
public ImportListItemInfo GetLastSyncListInfo(int importListId)
public DateTime GetLastSyncListInfo(int importListId)
{
return GetProviderStatus(importListId).LastSyncListInfo;
return GetProviderStatus(importListId).LastInfoSync;
}
public void UpdateListSyncStatus(int importListId, ImportListItemInfo listItemInfo)
public void UpdateListSyncStatus(int importListId)
{
lock (_syncRoot)
{
var status = GetProviderStatus(importListId);
status.LastSyncListInfo = listItemInfo;
status.LastInfoSync = DateTime.UtcNow;
_providerStatusRepository.Upsert(status);
}

@ -1,3 +1,4 @@
using System;
using NLog;
using NzbDrone.Common.Http;
using NzbDrone.Core.Configuration;
@ -10,7 +11,7 @@ namespace NzbDrone.Core.ImportLists.LazyLibrarianImport
public override string Name => "LazyLibrarian";
public override ImportListType ListType => ImportListType.Other;
public override TimeSpan MinRefreshInterval => TimeSpan.FromMinutes(15);
public override int PageSize => 1000;
public LazyLibrarianImport(IHttpClient httpClient, IImportListStatusService importListStatusService, IConfigService configService, IParsingService parsingService, Logger logger)

@ -17,6 +17,7 @@ namespace NzbDrone.Core.ImportLists.Readarr
public override string Name => "Readarr";
public override ImportListType ListType => ImportListType.Program;
public override TimeSpan MinRefreshInterval => TimeSpan.FromMinutes(15);
public ReadarrImport(IReadarrV1Proxy readarrV1Proxy,
IImportListStatusService importListStatusService,

@ -116,7 +116,7 @@ namespace NzbDrone.Core.Jobs
new ScheduledTask
{
Interval = 24 * 60, // TODO: Add a setting?
Interval = 5,
TypeName = typeof(ImportListSyncCommand).FullName
},

@ -401,6 +401,8 @@
"LaunchBrowserHelpText": " Open a web browser and navigate to Readarr homepage on app start.",
"Level": "Level",
"LibraryHelpText": "Calibre content server library name. Leave blank for default.",
"ListRefreshInterval": "List Refresh Interval",
"ListWillRefreshEveryInterp": "List will refresh every {0}",
"Lists": "Lists",
"ListsSettingsSummary": "Import Lists",
"Loading": "loading",

@ -1,3 +1,4 @@
using System;
using NzbDrone.Core.Books;
using NzbDrone.Core.ImportLists;
@ -15,6 +16,7 @@ namespace Readarr.Api.V1.ImportLists
public int MetadataProfileId { get; set; }
public ImportListType ListType { get; set; }
public int ListOrder { get; set; }
public TimeSpan MinRefreshInterval { get; set; }
}
public class ImportListResourceMapper : ProviderResourceMapper<ImportListResource, ImportListDefinition>
@ -38,6 +40,7 @@ namespace Readarr.Api.V1.ImportLists
resource.MetadataProfileId = definition.MetadataProfileId;
resource.ListType = definition.ListType;
resource.ListOrder = (int)definition.ListType;
resource.MinRefreshInterval = definition.MinRefreshInterval;
return resource;
}
@ -60,6 +63,7 @@ namespace Readarr.Api.V1.ImportLists
definition.ProfileId = resource.QualityProfileId;
definition.MetadataProfileId = resource.MetadataProfileId;
definition.ListType = resource.ListType;
definition.MinRefreshInterval = resource.MinRefreshInterval;
return definition;
}

Loading…
Cancel
Save