User configurable RSS Sync Time

New: RSS Sync Interval is now user configurable (Default 25 minutes)
This commit is contained in:
Mark McDowall 2012-10-07 12:16:43 -07:00
parent 23f8f534fc
commit 8280561e11
9 changed files with 84 additions and 7 deletions

View File

@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Core.Jobs;
using NzbDrone.Core.Model.Notification;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Providers.Core;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Test.Common.AutoMoq;
namespace NzbDrone.Core.Test.JobTests
{
[TestFixture]
// ReSharper disable InconsistentNaming
public class RssSyncJobTest : CoreTest
{
public void WithMinutes(int minutes)
{
Mocker.GetMock<ConfigProvider>().SetupGet(s => s.RssSyncInterval).Returns(minutes);
}
[TestCase(10)]
[TestCase(15)]
[TestCase(25)]
[TestCase(60)]
[TestCase(120)]
public void should_use_value_from_config_provider(int minutes)
{
WithMinutes(minutes);
Mocker.Resolve<RssSyncJob>().DefaultInterval.Should().Be(TimeSpan.FromMinutes(minutes));
}
}
}

View File

@ -142,6 +142,7 @@
<Compile Include="Integeration\ServiceIntegerationFixture.cs" /> <Compile Include="Integeration\ServiceIntegerationFixture.cs" />
<Compile Include="JobTests\BacklogSearchJobTest.cs" /> <Compile Include="JobTests\BacklogSearchJobTest.cs" />
<Compile Include="JobTests\BannerDownloadJobTest.cs" /> <Compile Include="JobTests\BannerDownloadJobTest.cs" />
<Compile Include="JobTests\RssSyncJobTest.cs" />
<Compile Include="JobTests\RecentBacklogSearchJobTest.cs" /> <Compile Include="JobTests\RecentBacklogSearchJobTest.cs" />
<Compile Include="ProviderTests\ConfigProviderTests\ConfigCachingFixture.cs" /> <Compile Include="ProviderTests\ConfigProviderTests\ConfigCachingFixture.cs" />
<Compile Include="ProviderTests\BannerProviderTest.cs" /> <Compile Include="ProviderTests\BannerProviderTest.cs" />

View File

@ -96,7 +96,9 @@ namespace NzbDrone.Core.Jobs
jobDefinition.Enable = job.DefaultInterval.TotalSeconds > 0; jobDefinition.Enable = job.DefaultInterval.TotalSeconds > 0;
jobDefinition.Name = job.Name; jobDefinition.Name = job.Name;
jobDefinition.Interval = Convert.ToInt32(job.DefaultInterval.TotalMinutes); jobDefinition.Interval = Convert.ToInt32(job.DefaultInterval.TotalMinutes);
//Todo: Need to have a way for users to change this and not have it overwritten on start-up.
SaveDefinition(jobDefinition); SaveDefinition(jobDefinition);
} }
@ -196,6 +198,11 @@ namespace NzbDrone.Core.Jobs
return true; return true;
} }
public virtual JobDefinition GetDefinition(Type type)
{
return _database.Single<JobDefinition>("WHERE TypeName = @0", type.ToString());
}
private void ProcessQueue() private void ProcessQueue()
{ {
try try
@ -321,7 +328,5 @@ namespace NzbDrone.Core.Jobs
logger.Trace("resetting queue processor thread"); logger.Trace("resetting queue processor thread");
_jobThread = new Thread(ProcessQueue) { Name = "JobQueueThread" }; _jobThread = new Thread(ProcessQueue) { Name = "JobQueueThread" };
} }
} }
} }

View File

@ -7,6 +7,7 @@ using NLog;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Model.Notification; using NzbDrone.Core.Model.Notification;
using NzbDrone.Core.Providers; using NzbDrone.Core.Providers;
using NzbDrone.Core.Providers.Core;
using NzbDrone.Core.Providers.DecisionEngine; using NzbDrone.Core.Providers.DecisionEngine;
using NzbDrone.Core.Providers.Indexer; using NzbDrone.Core.Providers.Indexer;
using StackExchange.Profiling; using StackExchange.Profiling;
@ -20,19 +21,22 @@ namespace NzbDrone.Core.Jobs
private readonly MonitoredEpisodeSpecification _isMonitoredEpisodeSpecification; private readonly MonitoredEpisodeSpecification _isMonitoredEpisodeSpecification;
private readonly AllowedDownloadSpecification _allowedDownloadSpecification; private readonly AllowedDownloadSpecification _allowedDownloadSpecification;
private readonly UpgradeHistorySpecification _upgradeHistorySpecification; private readonly UpgradeHistorySpecification _upgradeHistorySpecification;
private readonly ConfigProvider _configProvider;
private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[Inject] [Inject]
public RssSyncJob(DownloadProvider downloadProvider, IndexerProvider indexerProvider, public RssSyncJob(DownloadProvider downloadProvider, IndexerProvider indexerProvider,
MonitoredEpisodeSpecification isMonitoredEpisodeSpecification, AllowedDownloadSpecification allowedDownloadSpecification, UpgradeHistorySpecification upgradeHistorySpecification) MonitoredEpisodeSpecification isMonitoredEpisodeSpecification, AllowedDownloadSpecification allowedDownloadSpecification,
UpgradeHistorySpecification upgradeHistorySpecification, ConfigProvider configProvider)
{ {
_downloadProvider = downloadProvider; _downloadProvider = downloadProvider;
_indexerProvider = indexerProvider; _indexerProvider = indexerProvider;
_isMonitoredEpisodeSpecification = isMonitoredEpisodeSpecification; _isMonitoredEpisodeSpecification = isMonitoredEpisodeSpecification;
_allowedDownloadSpecification = allowedDownloadSpecification; _allowedDownloadSpecification = allowedDownloadSpecification;
_upgradeHistorySpecification = upgradeHistorySpecification; _upgradeHistorySpecification = upgradeHistorySpecification;
_configProvider = configProvider;
} }
public string Name public string Name
@ -42,7 +46,7 @@ namespace NzbDrone.Core.Jobs
public TimeSpan DefaultInterval public TimeSpan DefaultInterval
{ {
get { return TimeSpan.FromMinutes(25); } get { return TimeSpan.FromMinutes(_configProvider.RssSyncInterval); }
} }
public void Start(ProgressNotification notification, int targetId, int secondaryTargetId) public void Start(ProgressNotification notification, int targetId, int secondaryTargetId)

View File

@ -532,6 +532,12 @@ namespace NzbDrone.Core.Providers.Core
set { SetValue("RecycleBin", value); } set { SetValue("RecycleBin", value); }
} }
public virtual int RssSyncInterval
{
get { return GetValueInt("RssSyncInterval", 25); }
set { SetValue("RssSyncInterval", value); }
}
private string GetValue(string key) private string GetValue(string key)
{ {
return GetValue(key, String.Empty); return GetValue(key, String.Empty);

View File

@ -91,7 +91,7 @@
overflow: auto; overflow: auto;
} }
.retentionContainer .indexer-global-settings
{ {
padding-top: 20px; padding-top: 20px;
overflow: hidden; overflow: hidden;

View File

@ -6,6 +6,7 @@ using NLog;
using NzbDrone.Common; using NzbDrone.Common;
using NzbDrone.Common.Model; using NzbDrone.Common.Model;
using NzbDrone.Core.Helpers; using NzbDrone.Core.Helpers;
using NzbDrone.Core.Jobs;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Providers; using NzbDrone.Core.Providers;
using NzbDrone.Core.Providers.Core; using NzbDrone.Core.Providers.Core;
@ -32,18 +33,21 @@ namespace NzbDrone.Web.Controllers
private readonly ConfigFileProvider _configFileProvider; private readonly ConfigFileProvider _configFileProvider;
private readonly NewznabProvider _newznabProvider; private readonly NewznabProvider _newznabProvider;
private readonly MetadataProvider _metadataProvider; private readonly MetadataProvider _metadataProvider;
private readonly JobProvider _jobProvider;
public SettingsController(ConfigProvider configProvider, IndexerProvider indexerProvider, public SettingsController(ConfigProvider configProvider, IndexerProvider indexerProvider,
QualityProvider qualityProvider, AutoConfigureProvider autoConfigureProvider, QualityProvider qualityProvider, AutoConfigureProvider autoConfigureProvider,
SeriesProvider seriesProvider, ExternalNotificationProvider externalNotificationProvider, SeriesProvider seriesProvider, ExternalNotificationProvider externalNotificationProvider,
QualityTypeProvider qualityTypeProvider, ConfigFileProvider configFileProvider, QualityTypeProvider qualityTypeProvider, ConfigFileProvider configFileProvider,
NewznabProvider newznabProvider, MetadataProvider metadataProvider) NewznabProvider newznabProvider, MetadataProvider metadataProvider,
JobProvider jobProvider)
{ {
_externalNotificationProvider = externalNotificationProvider; _externalNotificationProvider = externalNotificationProvider;
_qualityTypeProvider = qualityTypeProvider; _qualityTypeProvider = qualityTypeProvider;
_configFileProvider = configFileProvider; _configFileProvider = configFileProvider;
_newznabProvider = newznabProvider; _newznabProvider = newznabProvider;
_metadataProvider = metadataProvider; _metadataProvider = metadataProvider;
_jobProvider = jobProvider;
_configProvider = configProvider; _configProvider = configProvider;
_indexerProvider = indexerProvider; _indexerProvider = indexerProvider;
_qualityProvider = qualityProvider; _qualityProvider = qualityProvider;
@ -84,6 +88,8 @@ namespace NzbDrone.Web.Controllers
NzbIndexEnabled = _indexerProvider.GetSettings(typeof(NzbIndex)).Enable, NzbIndexEnabled = _indexerProvider.GetSettings(typeof(NzbIndex)).Enable,
NzbClubEnabled = _indexerProvider.GetSettings(typeof(NzbClub)).Enable, NzbClubEnabled = _indexerProvider.GetSettings(typeof(NzbClub)).Enable,
RssSyncInterval = _configProvider.RssSyncInterval,
NewznabDefinitions = _newznabProvider.All(), NewznabDefinitions = _newznabProvider.All(),
}); });
} }
@ -401,6 +407,13 @@ namespace NzbDrone.Web.Controllers
_configProvider.FileSharingTalkUid = data.FileSharingTalkUid; _configProvider.FileSharingTalkUid = data.FileSharingTalkUid;
_configProvider.FileSharingTalkSecret = data.FileSharingTalkSecret; _configProvider.FileSharingTalkSecret = data.FileSharingTalkSecret;
//Save the interval to config and immediately apply it the the job (to avoid a restart)
_configProvider.RssSyncInterval = data.RssSyncInterval;
var rssSyncJob = _jobProvider.GetDefinition(typeof(RssSyncJob));
rssSyncJob.Interval = data.RssSyncInterval;
_jobProvider.SaveDefinition(rssSyncJob);
try try
{ {
if (data.NewznabDefinitions != null) if (data.NewznabDefinitions != null)

View File

@ -103,6 +103,13 @@ namespace NzbDrone.Web.Models
[Description("Usenet provider retention in days (0 = unlimited)")] [Description("Usenet provider retention in days (0 = unlimited)")]
public int Retention { get; set; } public int Retention { get; set; }
[DisplayName("RSS Sync Interval")]
[Description("Check for new episodes every X minutes")]
[DisplayFormat(ConvertEmptyStringToNull = false)]
[Required(AllowEmptyStrings = false, ErrorMessage = "You must enter a valid time in minutes")]
[Range(15, 240, ErrorMessage = "Interval must be between 15 and 240 minutes")]
public int RssSyncInterval { get; set; }
public List<NewznabDefinition> NewznabDefinitions { get; set; } public List<NewznabDefinition> NewznabDefinitions { get; set; }
} }
} }

View File

@ -160,13 +160,19 @@
</div> </div>
</div> </div>
<div class="retentionContainer"> <div class="indexer-global-settings">
@Html.ValidationSummary(true, "Unable to save your settings. Please correct the errors and try again.") @Html.ValidationSummary(true, "Unable to save your settings. Please correct the errors and try again.")
<label class="labelClass">@Html.LabelFor(m => m.Retention) <label class="labelClass">@Html.LabelFor(m => m.Retention)
<span class="small">@Html.DescriptionFor(m => m.Retention)</span> <span class="small">@Html.DescriptionFor(m => m.Retention)</span>
<span class="small">@Html.ValidationMessageFor(m => m.Retention)</span> <span class="small">@Html.ValidationMessageFor(m => m.Retention)</span>
</label> </label>
@Html.TextBoxFor(m => m.Retention, new { @class = "inputClass" }) @Html.TextBoxFor(m => m.Retention, new { @class = "inputClass" })
<label class="labelClass">@Html.LabelFor(m => m.RssSyncInterval)
<span class="small">@Html.DescriptionFor(m => m.RssSyncInterval)</span>
<span class="small">@Html.ValidationMessageFor(m => m.RssSyncInterval)</span>
</label>
@Html.TextBoxFor(m => m.RssSyncInterval, new { @class = "inputClass" })
</div> </div>
<button type="submit" class="save_button" disabled="disabled">Save</button> <button type="submit" class="save_button" disabled="disabled">Save</button>