mirror of
https://github.com/lidarr/lidarr.git
synced 2025-08-19 13:10:13 -07:00
New: Rework List sync interval logic
(cherry picked from commit c522cd120d08757e7e43c2348be4d7f05a254fac)
This commit is contained in:
parent
69c7d526bc
commit
0b029b6d42
24 changed files with 128 additions and 13 deletions
|
@ -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
|
||||
};
|
||||
|
|
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;
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using NzbDrone.Core.ImportLists;
|
||||
using NzbDrone.Core.Music;
|
||||
|
||||
|
@ -15,6 +16,7 @@ namespace Lidarr.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 Lidarr.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 Lidarr.Api.V1.ImportLists
|
|||
definition.ProfileId = resource.QualityProfileId;
|
||||
definition.MetadataProfileId = resource.MetadataProfileId;
|
||||
definition.ListType = resource.ListType;
|
||||
definition.MinRefreshInterval = resource.MinRefreshInterval;
|
||||
|
||||
return definition;
|
||||
}
|
||||
|
|
16
src/NzbDrone.Core/Datastore/Migration/069_list_sync_time.cs
Normal file
16
src/NzbDrone.Core/Datastore/Migration/069_list_sync_time.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
using FluentMigrator;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Migration
|
||||
{
|
||||
[Migration(069)]
|
||||
public class list_sync_time : NzbDroneMigrationBase
|
||||
{
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Delete.Column("LastSyncListInfo").FromTable("ImportListStatus");
|
||||
|
||||
Alter.Table("ImportListStatus").AddColumn("LastInfoSync").AsDateTimeOffset().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)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using FluentValidation.Results;
|
||||
using NLog;
|
||||
|
@ -14,6 +15,7 @@ namespace NzbDrone.Core.ImportLists.Custom
|
|||
public override string Name => "Custom List";
|
||||
|
||||
public override ImportListType ListType => ImportListType.Advanced;
|
||||
public override TimeSpan MinRefreshInterval => TimeSpan.FromHours(6);
|
||||
|
||||
public CustomImport(ICustomImportProxy customProxy,
|
||||
IImportListStatusService importListStatusService,
|
||||
|
|
|
@ -17,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;
|
||||
}
|
||||
|
||||
|
@ -45,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(() =>
|
||||
{
|
||||
|
@ -58,6 +67,8 @@ namespace NzbDrone.Core.ImportLists
|
|||
|
||||
result.AddRange(importListReports);
|
||||
}
|
||||
|
||||
_importListStatusService.UpdateListSyncStatus(importList.Definition.Id);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -89,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);
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Configuration;
|
||||
|
@ -10,6 +11,7 @@ namespace NzbDrone.Core.ImportLists.HeadphonesImport
|
|||
public override string Name => "Headphones";
|
||||
|
||||
public override ImportListType ListType => ImportListType.Other;
|
||||
public override TimeSpan MinRefreshInterval => TimeSpan.FromHours(1);
|
||||
|
||||
public override int PageSize => 1000;
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,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.Music;
|
||||
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
|
||||
|
|
|
@ -40,6 +40,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,10 +1,10 @@
|
|||
using NzbDrone.Core.Parser.Model;
|
||||
using System;
|
||||
using NzbDrone.Core.ThingiProvider.Status;
|
||||
|
||||
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,6 +11,7 @@ namespace NzbDrone.Core.ImportLists.LastFm
|
|||
public override string Name => "Last.fm Tag";
|
||||
|
||||
public override ImportListType ListType => ImportListType.LastFm;
|
||||
public override TimeSpan MinRefreshInterval => TimeSpan.FromHours(12);
|
||||
|
||||
public override int PageSize => 1000;
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Configuration;
|
||||
|
@ -10,6 +11,7 @@ namespace NzbDrone.Core.ImportLists.LastFm
|
|||
public override string Name => "Last.fm User";
|
||||
|
||||
public override ImportListType ListType => ImportListType.LastFm;
|
||||
public override TimeSpan MinRefreshInterval => TimeSpan.FromHours(12);
|
||||
|
||||
public override int PageSize => 1000;
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ namespace NzbDrone.Core.ImportLists.Lidarr
|
|||
public override string Name => "Lidarr";
|
||||
|
||||
public override ImportListType ListType => ImportListType.Program;
|
||||
public override TimeSpan MinRefreshInterval => TimeSpan.FromMinutes(15);
|
||||
|
||||
public LidarrImport(ILidarrV1Proxy lidarrV1Proxy,
|
||||
IImportListStatusService importListStatusService,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Http;
|
||||
|
@ -13,6 +14,7 @@ namespace NzbDrone.Core.ImportLists.LidarrLists
|
|||
public override string Name => "Lidarr Lists";
|
||||
|
||||
public override ImportListType ListType => ImportListType.Other;
|
||||
public override TimeSpan MinRefreshInterval => TimeSpan.FromMinutes(15);
|
||||
|
||||
public override int PageSize => 10;
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Configuration;
|
||||
|
@ -14,6 +15,7 @@ namespace NzbDrone.Core.ImportLists.MusicBrainzSeries
|
|||
public override ProviderMessage Message => new ProviderMessage("MusicBrainz Series only supports release groups within series, other types of member will not be picked up by Lidarr", ProviderMessageType.Warning);
|
||||
|
||||
public override ImportListType ListType => ImportListType.Other;
|
||||
public override TimeSpan MinRefreshInterval => TimeSpan.FromHours(12);
|
||||
|
||||
private readonly IMetadataRequestBuilder _requestBuilder;
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ namespace NzbDrone.Core.ImportLists.Spotify
|
|||
}
|
||||
|
||||
public override ImportListType ListType => ImportListType.Spotify;
|
||||
public override TimeSpan MinRefreshInterval => TimeSpan.FromHours(12);
|
||||
|
||||
public string AccessToken => Settings.AccessToken;
|
||||
|
||||
|
|
|
@ -116,7 +116,7 @@ namespace NzbDrone.Core.Jobs
|
|||
|
||||
new ScheduledTask
|
||||
{
|
||||
Interval = 24 * 60, // TODO: Add a setting?
|
||||
Interval = 5,
|
||||
TypeName = typeof(ImportListSyncCommand).FullName
|
||||
},
|
||||
|
||||
|
|
|
@ -453,6 +453,8 @@
|
|||
"LidarrSupportsAnyIndexerThatUsesTheNewznabStandardAsWellAsOtherIndexersListedBelow": "Lidarr supports any indexer that uses the Newznab standard, as well as other indexers listed below.",
|
||||
"LidarrSupportsMultipleListsForImportingAlbumsAndArtistsIntoTheDatabase": "Lidarr supports multiple lists for importing Albums and Artists into the database.",
|
||||
"LidarrTags": "Lidarr Tags",
|
||||
"ListRefreshInterval": "List Refresh Interval",
|
||||
"ListWillRefreshEveryInterp": "List will refresh every {0}",
|
||||
"Loading": "loading",
|
||||
"LoadingAlbumsFailed": "Loading albums failed",
|
||||
"LoadingTrackFilesFailed": "Loading track files failed",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue