mirror of
https://github.com/Radarr/Radarr.git
synced 2024-08-16 23:39:44 +02:00
Added TimerProvider
This commit is contained in:
parent
848553da73
commit
59899286ee
@ -93,6 +93,7 @@
|
||||
<Compile Include="AutoMoq\Unity\AutoMockingContainerExtension.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="TimerProviderTest.cs" />
|
||||
<Compile Include="SyncProviderTest.cs" />
|
||||
<Compile Include="RootDirProviderTest.cs" />
|
||||
<Compile Include="IndexerProviderTest.cs" />
|
||||
|
@ -1,4 +1,5 @@
|
||||
using MbUnit.Framework;
|
||||
using System.Threading;
|
||||
using MbUnit.Framework;
|
||||
using NzbDrone.Core.Repository.Quality;
|
||||
|
||||
namespace NzbDrone.Core.Test
|
||||
@ -13,8 +14,8 @@ public class ParserTest
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
[Test]
|
||||
[Timeout(1)]
|
||||
[Row("Sonny.With.a.Chance.S02E15", 2, 15)]
|
||||
[Row("WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD", 3, 1)]
|
||||
[Row("Two.and.a.Half.Me.103.720p.HDTV.X264-DIMENSION", 1, 3)]
|
||||
@ -40,6 +41,7 @@ public void episode_parse(string path, int season, int episode)
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Timeout(1)]
|
||||
[Row("WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD", QualityTypes.BDRip)]
|
||||
[Row("WEEDS.S03E01-06.DUAL.BDRip.AC3.-HELLYWOOD", QualityTypes.BDRip)]
|
||||
[Row("Two.and.a.Half.Men.S08E05.720p.HDTV.X264-DIMENSION", QualityTypes.HDTV)]
|
||||
@ -66,9 +68,10 @@ public void quality_parse(string path, object quality)
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Timeout(1)]
|
||||
[Row("WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD", 3, new[] { 1, 2, 3, 4, 5, 6 })]
|
||||
[Row("Two.and.a.Half.Men.103.104.720p.HDTV.X264-DIMENSION", 1, new[] {3, 4})]
|
||||
[Row("Weeds.S03E01.S03E02.720p.HDTV.X264-DIMENSION", 3, new[] {1, 2})]
|
||||
[Row("Two.and.a.Half.Men.103.104.720p.HDTV.X264-DIMENSION", 1, new[] { 3, 4 })]
|
||||
[Row("Weeds.S03E01.S03E02.720p.HDTV.X264-DIMENSION", 3, new[] { 1, 2 })]
|
||||
[Row("The Borgias S01e01 e02 ShoHD On Demand 1080i DD5 1 ALANiS", 1, new[] { 1, 2 })]
|
||||
[Row("Big Time Rush 1x01 to 10 480i DD2 0 Sianto", 1, new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 })]
|
||||
[Row("White.Collar.2x04.2x05.720p.BluRay-FUTV", 2, new[] { 4, 5 })]
|
||||
|
110
NzbDrone.Core.Test/TimerProviderTest.cs
Normal file
110
NzbDrone.Core.Test/TimerProviderTest.cs
Normal file
@ -0,0 +1,110 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using AutoMoq;
|
||||
using MbUnit.Framework;
|
||||
using Moq;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.Providers.Core;
|
||||
using NzbDrone.Core.Providers.Timers;
|
||||
|
||||
namespace NzbDrone.Core.Test
|
||||
{
|
||||
[TestFixture]
|
||||
// ReSharper disable InconsistentNaming
|
||||
public class TimerProviderTest
|
||||
{
|
||||
[Test]
|
||||
public void Run_Timers()
|
||||
{
|
||||
|
||||
IEnumerable<ITimer> fakeTimers = new List<ITimer> { new FakeTimer() };
|
||||
var mocker = new AutoMoqer();
|
||||
|
||||
mocker.SetConstant(MockLib.GetEmptyRepository());
|
||||
mocker.SetConstant(fakeTimers);
|
||||
|
||||
var timerProvider = mocker.Resolve<TimerProvider>();
|
||||
timerProvider.Initialize();
|
||||
timerProvider.Run();
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Init_Timers()
|
||||
{
|
||||
var fakeTimer = new FakeTimer();
|
||||
IEnumerable<ITimer> fakeTimers = new List<ITimer> { fakeTimer };
|
||||
var mocker = new AutoMoqer();
|
||||
|
||||
mocker.SetConstant(MockLib.GetEmptyRepository());
|
||||
mocker.SetConstant(fakeTimers);
|
||||
|
||||
var timerProvider = mocker.Resolve<TimerProvider>();
|
||||
timerProvider.Initialize();
|
||||
|
||||
var timers = timerProvider.All();
|
||||
|
||||
|
||||
//Assert
|
||||
Assert.Count(1, timers);
|
||||
Assert.AreEqual(fakeTimer.DefaultInterval, timers[0].Interval);
|
||||
Assert.AreEqual(fakeTimer.Name, timers[0].Name);
|
||||
Assert.AreEqual(fakeTimer.GetType().ToString(), timers[0].TypeName);
|
||||
Assert.AreEqual(DateTime.MinValue, timers[0].LastExecution);
|
||||
Assert.IsTrue(timers[0].Enable);
|
||||
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Init_Timers_only_registers_once()
|
||||
{
|
||||
var repo = MockLib.GetEmptyRepository();
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
var fakeTimer = new FakeTimer();
|
||||
IEnumerable<ITimer> fakeTimers = new List<ITimer> { fakeTimer };
|
||||
var mocker = new AutoMoqer();
|
||||
|
||||
mocker.SetConstant(repo);
|
||||
mocker.SetConstant(fakeTimers);
|
||||
|
||||
var timerProvider = mocker.Resolve<TimerProvider>();
|
||||
timerProvider.Initialize();
|
||||
}
|
||||
|
||||
var mocker2 = new AutoMoqer();
|
||||
|
||||
mocker2.SetConstant(repo);
|
||||
var assertTimerProvider = mocker2.Resolve<TimerProvider>();
|
||||
|
||||
var timers = assertTimerProvider.All();
|
||||
|
||||
|
||||
//Assert
|
||||
Assert.Count(1, timers);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class FakeTimer : ITimer
|
||||
{
|
||||
public string Name
|
||||
{
|
||||
get { return "FakeTimer"; }
|
||||
}
|
||||
|
||||
public int DefaultInterval
|
||||
{
|
||||
get { return 15; }
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.Providers.Core;
|
||||
using NzbDrone.Core.Providers.Indexer;
|
||||
using NzbDrone.Core.Providers.Timers;
|
||||
using NzbDrone.Core.Repository;
|
||||
using NzbDrone.Core.Repository.Quality;
|
||||
using SubSonic.DataProviders;
|
||||
@ -22,7 +23,6 @@ public static class CentralDispatch
|
||||
private static StandardKernel _kernel;
|
||||
private static readonly Object KernelLock = new object();
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
private static string _startupPath;
|
||||
|
||||
public static String AppPath
|
||||
{
|
||||
@ -36,21 +36,6 @@ public static String AppPath
|
||||
}
|
||||
}
|
||||
|
||||
public static string ExecutablePath
|
||||
{
|
||||
get
|
||||
{
|
||||
//var uri = new Uri(Assembly.EscapedCodeBase);
|
||||
//return Path.GetDirectoryName(uri.LocalPath);
|
||||
return Directory.GetCurrentDirectory();
|
||||
}
|
||||
}
|
||||
|
||||
public static string StartupPath
|
||||
{
|
||||
get { return _startupPath; }
|
||||
}
|
||||
|
||||
public static StandardKernel NinjectKernel
|
||||
{
|
||||
get
|
||||
@ -70,19 +55,16 @@ public static void BindKernel()
|
||||
Logger.Debug("Binding Ninject's Kernel");
|
||||
_kernel = new StandardKernel();
|
||||
|
||||
//Store the startup path
|
||||
_startupPath = AppPath;
|
||||
|
||||
//Sqlite
|
||||
var AppDataPath = new DirectoryInfo(Path.Combine(AppPath, "App_Data"));
|
||||
if (!AppDataPath.Exists) AppDataPath.Create();
|
||||
var appDataPath = new DirectoryInfo(Path.Combine(AppPath, "App_Data"));
|
||||
if (!appDataPath.Exists) appDataPath.Create();
|
||||
|
||||
string connectionString = String.Format("Data Source={0};Version=3;",
|
||||
Path.Combine(AppDataPath.FullName, "nzbdrone.db"));
|
||||
Path.Combine(appDataPath.FullName, "nzbdrone.db"));
|
||||
var dbProvider = ProviderFactory.GetProvider(connectionString, "System.Data.SQLite");
|
||||
|
||||
string logConnectionString = String.Format("Data Source={0};Version=3;",
|
||||
Path.Combine(AppDataPath.FullName, "log.db"));
|
||||
Path.Combine(appDataPath.FullName, "log.db"));
|
||||
var logDbProvider = ProviderFactory.GetProvider(logConnectionString, "System.Data.SQLite");
|
||||
|
||||
|
||||
@ -99,7 +81,6 @@ public static void BindKernel()
|
||||
_kernel.Bind<HttpProvider>().ToSelf().InSingletonScope();
|
||||
_kernel.Bind<SeriesProvider>().ToSelf().InSingletonScope();
|
||||
_kernel.Bind<SeasonProvider>().ToSelf().InSingletonScope();
|
||||
_kernel.Bind<RssSyncProvider>().ToSelf().InSingletonScope();
|
||||
_kernel.Bind<EpisodeProvider>().ToSelf().InSingletonScope();
|
||||
_kernel.Bind<UpcomingEpisodesProvider>().ToSelf().InSingletonScope();
|
||||
_kernel.Bind<DiskProvider>().ToSelf().InSingletonScope();
|
||||
@ -127,12 +108,6 @@ public static void BindKernel()
|
||||
ForceMigration(_kernel.Get<IRepository>());
|
||||
SetupDefaultQualityProfiles(_kernel.Get<IRepository>()); //Setup the default QualityProfiles on start-up
|
||||
|
||||
//Get the Timers going
|
||||
var config = _kernel.Get<ConfigProvider>();
|
||||
var timer = _kernel.Get<TimerProvider>();
|
||||
timer.SetRssSyncTimer(Convert.ToInt32(config.GetValue("SyncFrequency", "15", true)));
|
||||
timer.StartRssSyncTimer();
|
||||
|
||||
BindIndexers();
|
||||
}
|
||||
}
|
||||
@ -140,6 +115,7 @@ public static void BindKernel()
|
||||
private static void BindIndexers()
|
||||
{
|
||||
_kernel.Bind<IndexerProviderBase>().To<NzbsOrgProvider>().InSingletonScope();
|
||||
|
||||
var indexers = _kernel.GetAll<IndexerProviderBase>();
|
||||
_kernel.Get<IndexerProvider>().InitializeIndexers(indexers.ToList());
|
||||
}
|
||||
@ -154,7 +130,7 @@ private static void ForceMigration(IRepository repository)
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method forces IISExpress process to exit with the host application
|
||||
/// Forces IISExpress process to exit with the host application
|
||||
/// </summary>
|
||||
public static void DedicateToHost()
|
||||
{
|
||||
@ -187,7 +163,6 @@ private static void ShutDown()
|
||||
Process.GetCurrentProcess().Kill();
|
||||
}
|
||||
|
||||
|
||||
private static void SetupDefaultQualityProfiles(IRepository repository)
|
||||
{
|
||||
var sd = new QualityProfile
|
||||
|
@ -1,14 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace NzbDrone.Core.Helpers
|
||||
{
|
||||
public static class ServerHelper
|
||||
{
|
||||
public static string GetServerHostname()
|
||||
{
|
||||
//Both these seem to return the same result... Is on better than the other?
|
||||
return Environment.MachineName;
|
||||
//return Dns.GetHostName();
|
||||
}
|
||||
}
|
||||
}
|
@ -163,14 +163,17 @@
|
||||
<Compile Include="Helpers\EpisodeRenameHelper.cs" />
|
||||
<Compile Include="Helpers\EpisodeSortingHelper.cs" />
|
||||
<Compile Include="Helpers\SceneNameHelper.cs" />
|
||||
<Compile Include="Helpers\ServerHelper.cs" />
|
||||
<Compile Include="Instrumentation\LogLevel.cs" />
|
||||
<Compile Include="Instrumentation\LogProvider.cs" />
|
||||
<Compile Include="Instrumentation\SubsonicTarget.cs" />
|
||||
<Compile Include="Instrumentation\ExceptioneerTarget.cs" />
|
||||
<Compile Include="Instrumentation\NlogWriter.cs" />
|
||||
<Compile Include="Providers\Timers\TimerProvider.cs" />
|
||||
<Compile Include="Providers\Indexer\NzbMatrixFeedProvider.cs" />
|
||||
<Compile Include="Providers\Indexer\NzbsRUsFeedProvider.cs" />
|
||||
<Compile Include="Providers\Timers\ITimer.cs" />
|
||||
<Compile Include="Providers\Timers\RssSyncTimer.cs" />
|
||||
<Compile Include="Repository\TimerSetting.cs" />
|
||||
<Compile Include="Repository\IndexerSetting.cs" />
|
||||
<Compile Include="Model\EpisodeParseResult.cs" />
|
||||
<Compile Include="Model\EpisodeRenameModel.cs" />
|
||||
@ -187,12 +190,10 @@
|
||||
<Compile Include="Providers\HistoryProvider.cs" />
|
||||
<Compile Include="Providers\BacklogProvider.cs" />
|
||||
<Compile Include="Providers\IndexerProvider.cs" />
|
||||
<Compile Include="Providers\RssSyncProvider.cs" />
|
||||
<Compile Include="Providers\PostProcessingProvider.cs" />
|
||||
<Compile Include="Providers\QualityProvider.cs" />
|
||||
<Compile Include="Providers\RenameProvider.cs" />
|
||||
<Compile Include="Providers\RootDirProvider.cs" />
|
||||
<Compile Include="Providers\TimerProvider.cs" />
|
||||
<Compile Include="Providers\UpcomingEpisodesProvider.cs" />
|
||||
<Compile Include="Providers\XbmcProvider.cs" />
|
||||
<Compile Include="Repository\EpisodeFile.cs" />
|
||||
|
@ -116,7 +116,7 @@ internal static SeasonParseResult ParseSeasonInfo(string title)
|
||||
if (match.Count != 0)
|
||||
{
|
||||
var seriesName = NormalizeTitle(match[0].Groups["title"].Value);
|
||||
var year = 0;
|
||||
int year;
|
||||
Int32.TryParse(match[0].Groups["year"].Value, out year);
|
||||
|
||||
if (year < 1900 || year > DateTime.Now.Year + 1)
|
||||
@ -130,12 +130,11 @@ internal static SeasonParseResult ParseSeasonInfo(string title)
|
||||
{
|
||||
SeriesTitle = seriesName,
|
||||
SeasonNumber = seasonNumber,
|
||||
Year = year
|
||||
Year = year,
|
||||
Quality = ParseQuality(title)
|
||||
};
|
||||
|
||||
|
||||
result.Quality = ParseQuality(title);
|
||||
|
||||
Logger.Trace("Season Parsed. {0}", result);
|
||||
return result;
|
||||
}
|
||||
@ -160,14 +159,7 @@ internal static string ParseSeriesName(string title)
|
||||
if (match.Count != 0)
|
||||
{
|
||||
var seriesName = NormalizeTitle(match[0].Groups["title"].Value);
|
||||
var year = 0;
|
||||
Int32.TryParse(match[0].Groups["year"].Value, out year);
|
||||
|
||||
if (year < 1900 || year > DateTime.Now.Year + 1)
|
||||
{
|
||||
year = 0;
|
||||
}
|
||||
|
||||
|
||||
Logger.Trace("Series Parsed. {0}", seriesName);
|
||||
return seriesName;
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ public virtual IndexerSetting GetSettings(Type type)
|
||||
return _repository.Single<IndexerSetting>(s => s.IndexProviderType == type.ToString());
|
||||
}
|
||||
|
||||
public IndexerSetting GetSettings(int id)
|
||||
public virtual IndexerSetting GetSettings(int id)
|
||||
{
|
||||
return _repository.Single<IndexerSetting>(s => s.Id == id);
|
||||
}
|
||||
|
@ -1,9 +0,0 @@
|
||||
namespace NzbDrone.Core.Providers
|
||||
{
|
||||
public class RssSyncProvider
|
||||
{
|
||||
public virtual void Begin()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -51,7 +51,7 @@ public virtual bool IsInQueue(string title)
|
||||
|
||||
XDocument xDoc = XDocument.Parse(response);
|
||||
|
||||
//If an Error Occurred, retuyrn)
|
||||
//If an Error Occurred, return)
|
||||
if (xDoc.Descendants("error").Count() != 0)
|
||||
return false;
|
||||
|
||||
|
@ -1,130 +0,0 @@
|
||||
using System;
|
||||
using System.Timers;
|
||||
using NLog;
|
||||
|
||||
namespace NzbDrone.Core.Providers
|
||||
{
|
||||
public class TimerProvider
|
||||
{
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
private readonly EpisodeProvider _episodeProvider;
|
||||
private readonly MediaFileProvider _mediaFileProvider;
|
||||
|
||||
private readonly Timer _minuteTimer;
|
||||
private readonly RssSyncProvider _rssSyncProvider;
|
||||
private readonly Timer _rssSyncTimer;
|
||||
private readonly SeasonProvider _seasonProvider;
|
||||
private readonly SeriesProvider _seriesProvider;
|
||||
private DateTime _rssSyncNextInterval;
|
||||
|
||||
public TimerProvider(RssSyncProvider rssSyncProvider, SeriesProvider seriesProvider,
|
||||
SeasonProvider seasonProvider, EpisodeProvider episodeProvider,
|
||||
MediaFileProvider mediaFileProvider)
|
||||
{
|
||||
_rssSyncProvider = rssSyncProvider;
|
||||
_seriesProvider = seriesProvider;
|
||||
_seasonProvider = seasonProvider;
|
||||
_episodeProvider = episodeProvider;
|
||||
_mediaFileProvider = mediaFileProvider;
|
||||
|
||||
_rssSyncTimer = new Timer();
|
||||
_minuteTimer = new Timer(60000);
|
||||
}
|
||||
|
||||
public virtual void ResetRssSyncTimer()
|
||||
{
|
||||
double interval = _rssSyncTimer.Interval;
|
||||
_rssSyncTimer.Interval = interval;
|
||||
}
|
||||
|
||||
public virtual void StartRssSyncTimer()
|
||||
{
|
||||
if (_rssSyncTimer.Interval < 900000)
|
||||
//If Timer is less than 15 minutes, throw an error! This should also be handled when saving the config, though a user could by-pass it by editing the DB directly... TNO (Trust No One)
|
||||
{
|
||||
Logger.Error("RSS Sync Frequency is invalid, please set the interval first");
|
||||
throw new InvalidOperationException("RSS Sync Frequency Invalid");
|
||||
}
|
||||
|
||||
_rssSyncTimer.Elapsed += RunRssSync;
|
||||
_rssSyncTimer.Start();
|
||||
_rssSyncNextInterval = DateTime.Now.AddMilliseconds(_rssSyncTimer.Interval);
|
||||
}
|
||||
|
||||
public virtual void StopRssSyncTimer()
|
||||
{
|
||||
_rssSyncTimer.Stop();
|
||||
}
|
||||
|
||||
public virtual void SetRssSyncTimer(int minutes)
|
||||
{
|
||||
long ms = minutes*60*1000;
|
||||
_rssSyncTimer.Interval = ms;
|
||||
}
|
||||
|
||||
public virtual TimeSpan RssSyncTimeLeft()
|
||||
{
|
||||
return _rssSyncNextInterval.Subtract(DateTime.Now);
|
||||
}
|
||||
|
||||
public virtual DateTime NextRssSyncTime()
|
||||
{
|
||||
return _rssSyncNextInterval;
|
||||
}
|
||||
|
||||
public virtual void StartMinuteTimer()
|
||||
{
|
||||
_minuteTimer.Elapsed += MinuteTimer_Elapsed;
|
||||
_minuteTimer.Start();
|
||||
}
|
||||
|
||||
public virtual void StopMinuteTimer()
|
||||
{
|
||||
_minuteTimer.Stop();
|
||||
}
|
||||
|
||||
private void RunRssSync(object obj, ElapsedEventArgs args)
|
||||
{
|
||||
_rssSyncNextInterval = DateTime.Now.AddMilliseconds(_rssSyncTimer.Interval);
|
||||
_rssSyncProvider.Begin();
|
||||
}
|
||||
|
||||
private void MinuteTimer_Elapsed(object obj, ElapsedEventArgs args)
|
||||
{
|
||||
//Check to see if anything should be run at this time, if so run it
|
||||
|
||||
var now = DateTime.Now;
|
||||
|
||||
//Daily (Except Sunday) 03:00 - Update the lastest season for all TV Shows
|
||||
if (now.Hour == 3 && now.Minute == 0 && now.DayOfWeek != DayOfWeek.Sunday)
|
||||
{
|
||||
foreach (var series in _seriesProvider.GetAllSeries())
|
||||
{
|
||||
var season = _seasonProvider.GetLatestSeason(series.SeriesId);
|
||||
_episodeProvider.RefreshEpisodeInfo(season);
|
||||
}
|
||||
}
|
||||
|
||||
//Sunday 03:00 - Update all TV Shows
|
||||
if (now.Hour == 3 && now.Minute == 0 && now.DayOfWeek == DayOfWeek.Sunday)
|
||||
{
|
||||
foreach (var series in _seriesProvider.GetAllSeries())
|
||||
{
|
||||
_episodeProvider.RefreshEpisodeInfo(series.SeriesId);
|
||||
}
|
||||
}
|
||||
|
||||
//Daily 00:00 (Midnight) - Cleanup (removed) EpisodeFiles + Scan for New EpisodeFiles
|
||||
if (now.Hour == 0 && now.Minute == 0)
|
||||
{
|
||||
foreach (var series in _seriesProvider.GetAllSeries())
|
||||
{
|
||||
_mediaFileProvider.CleanUp(series.EpisodeFiles);
|
||||
_mediaFileProvider.Scan(series);
|
||||
}
|
||||
}
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
11
NzbDrone.Core/Providers/Timers/ITimer.cs
Normal file
11
NzbDrone.Core/Providers/Timers/ITimer.cs
Normal file
@ -0,0 +1,11 @@
|
||||
namespace NzbDrone.Core.Providers.Timers
|
||||
{
|
||||
public interface ITimer
|
||||
{
|
||||
string Name { get; }
|
||||
|
||||
int DefaultInterval { get; }
|
||||
|
||||
void Start();
|
||||
}
|
||||
}
|
39
NzbDrone.Core/Providers/Timers/RssSyncTimer.cs
Normal file
39
NzbDrone.Core/Providers/Timers/RssSyncTimer.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
|
||||
namespace NzbDrone.Core.Providers.Timers
|
||||
{
|
||||
public class RssSyncTimer : ITimer
|
||||
{
|
||||
private readonly IndexerProvider _indexerProvider;
|
||||
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
public RssSyncTimer(IndexerProvider indexerProvider)
|
||||
{
|
||||
_indexerProvider = indexerProvider;
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "RSS Sync"; }
|
||||
}
|
||||
|
||||
public int DefaultInterval
|
||||
{
|
||||
get { return 15; }
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
Logger.Info("Doing Things!!!!");
|
||||
|
||||
var indexers = _indexerProvider.AllIndexers().Where(c => c.Enable);
|
||||
|
||||
foreach (var indexerSetting in indexers)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
123
NzbDrone.Core/Providers/Timers/TimerProvider.cs
Normal file
123
NzbDrone.Core/Providers/Timers/TimerProvider.cs
Normal file
@ -0,0 +1,123 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Repository;
|
||||
using SubSonic.Repository;
|
||||
|
||||
namespace NzbDrone.Core.Providers.Timers
|
||||
{
|
||||
public class TimerProvider
|
||||
{
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
private readonly IRepository _repository;
|
||||
private readonly IEnumerable<ITimer> _timerJobs;
|
||||
|
||||
private static readonly object ExecutionLock = new object();
|
||||
private static bool _isRunning;
|
||||
|
||||
public TimerProvider(IRepository repository, IEnumerable<ITimer> timerJobs)
|
||||
{
|
||||
_repository = repository;
|
||||
_timerJobs = timerJobs;
|
||||
}
|
||||
|
||||
public TimerProvider() { }
|
||||
|
||||
public virtual List<TimerSetting> All()
|
||||
{
|
||||
return _repository.All<TimerSetting>().ToList();
|
||||
}
|
||||
|
||||
public virtual void SaveSettings(TimerSetting settings)
|
||||
{
|
||||
if (settings.Id == 0)
|
||||
{
|
||||
Logger.Debug("Adding timer settings for {0}", settings.Name);
|
||||
_repository.Add(settings);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Debug("Updating timer settings for {0}", settings.Name);
|
||||
_repository.Update(settings);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Run()
|
||||
{
|
||||
lock (ExecutionLock)
|
||||
{
|
||||
if (_isRunning)
|
||||
{
|
||||
Logger.Info("Another instance of timer is already running. Ignoring request.");
|
||||
return;
|
||||
}
|
||||
_isRunning = true;
|
||||
}
|
||||
|
||||
Logger.Trace("Getting list of timers needing to be executed");
|
||||
|
||||
var pendingTimers = All().Where(
|
||||
t => t.Enable &&
|
||||
(DateTime.Now - t.LastExecution) > TimeSpan.FromMinutes(t.Interval)
|
||||
);
|
||||
|
||||
foreach (var pendingTimer in pendingTimers)
|
||||
{
|
||||
Logger.Info("Attempting to start timer [{0}]. Last executing {1}", pendingTimer.Name, pendingTimer.LastExecution);
|
||||
var timerClass = _timerJobs.Where(t => t.GetType().ToString() == pendingTimer.TypeName).FirstOrDefault();
|
||||
ForceExecute(timerClass.GetType());
|
||||
}
|
||||
}
|
||||
|
||||
public void ForceExecute(Type timerType)
|
||||
{
|
||||
var timerClass = _timerJobs.Where(t => t.GetType() == timerType).FirstOrDefault();
|
||||
if (timerClass == null)
|
||||
{
|
||||
Logger.Error("Unable to locate implantation for [{0}]. Make sure its properly registered.", timerType.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var sw = Stopwatch.StartNew();
|
||||
timerClass.Start();
|
||||
sw.Stop();
|
||||
Logger.Info("timer [{0}] finished executing successfully. Duration {1}", timerClass.Name, sw.Elapsed.ToString());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error("An error has occurred while executing timer job " + timerClass.Name, e);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Initialize()
|
||||
{
|
||||
Logger.Info("Initializing timer jobs. Count {0}", _timerJobs.Count());
|
||||
var currentTimer = All();
|
||||
|
||||
foreach (var timer in _timerJobs)
|
||||
{
|
||||
var timerProviderLocal = timer;
|
||||
if (!currentTimer.Exists(c => c.TypeName == timerProviderLocal.GetType().ToString()))
|
||||
{
|
||||
var settings = new TimerSetting()
|
||||
{
|
||||
Enable = true,
|
||||
TypeName = timer.GetType().ToString(),
|
||||
Name = timerProviderLocal.Name,
|
||||
Interval = timerProviderLocal.DefaultInterval,
|
||||
LastExecution = DateTime.MinValue
|
||||
|
||||
};
|
||||
|
||||
SaveSettings(settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -23,13 +23,13 @@ public XbmcProvider(ConfigProvider configProvider, HttpProvider httpProvider)
|
||||
public virtual void Notify(string header, string message)
|
||||
{
|
||||
//Get time in seconds and convert to ms
|
||||
var time = Convert.ToInt32(_configProvider.GetValue("XbmcDisplayTime", "3", true))*1000;
|
||||
var time = Convert.ToInt32(_configProvider.GetValue("XbmcDisplayTime", "3", true)) * 1000;
|
||||
var command = String.Format("ExecBuiltIn(Notification({0},{1},{2}))", header, message, time);
|
||||
|
||||
if (Convert.ToBoolean(_configProvider.GetValue("XbmcNotificationImage", false, true)))
|
||||
{
|
||||
//Todo: Get the actual port that NzbDrone is running on...
|
||||
var serverInfo = String.Format("http://{0}:{1}", ServerHelper.GetServerHostname(), "8989");
|
||||
var serverInfo = String.Format("http://{0}:{1}", Environment.MachineName, "8989");
|
||||
|
||||
var imageUrl = String.Format("{0}/Content/XbmcNotification.png", serverInfo);
|
||||
command = String.Format("ExecBuiltIn(Notification({0},{1},{2}, {3}))", header, message, time, imageUrl);
|
||||
|
@ -18,9 +18,9 @@ public class Season
|
||||
public DayOfWeek? LastDiskSync { get; set; }
|
||||
|
||||
[SubSonicToManyRelation]
|
||||
public virtual List<Episode> Episodes { get; private set; }
|
||||
public virtual List<Episode> Episodes { get; protected set; }
|
||||
|
||||
[SubSonicToOneRelation(ThisClassContainsJoinKey = true)]
|
||||
public virtual Series Series { get; private set; }
|
||||
public virtual Series Series { get; protected set; }
|
||||
}
|
||||
}
|
@ -45,15 +45,15 @@ public class Series
|
||||
public DateTime? LastDiskSync { get; set; }
|
||||
|
||||
[SubSonicToOneRelation(ThisClassContainsJoinKey = true, JoinKeyName = "QualityProfileId")]
|
||||
public virtual QualityProfile QualityProfile { get; private set; }
|
||||
public virtual QualityProfile QualityProfile { get; protected set; }
|
||||
|
||||
[SubSonicToManyRelation]
|
||||
public virtual List<Season> Seasons { get; private set; }
|
||||
public virtual List<Season> Seasons { get; protected set; }
|
||||
|
||||
[SubSonicToManyRelation]
|
||||
public virtual List<Episode> Episodes { get; private set; }
|
||||
public virtual List<Episode> Episodes { get; protected set; }
|
||||
|
||||
[SubSonicToManyRelation]
|
||||
public virtual List<EpisodeFile> EpisodeFiles { get; private set; }
|
||||
public virtual List<EpisodeFile> EpisodeFiles { get; protected set; }
|
||||
}
|
||||
}
|
23
NzbDrone.Core/Repository/TimerSetting.cs
Normal file
23
NzbDrone.Core/Repository/TimerSetting.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using SubSonic.SqlGeneration.Schema;
|
||||
|
||||
namespace NzbDrone.Core.Repository
|
||||
{
|
||||
public class TimerSetting
|
||||
{
|
||||
[SubSonicPrimaryKey(true)]
|
||||
public Int32 Id { get; set; }
|
||||
|
||||
public Boolean Enable { get; set; }
|
||||
|
||||
public String TypeName { get; set; }
|
||||
|
||||
public String Name { get; set; }
|
||||
|
||||
public Int32 Interval { get; set; }
|
||||
|
||||
public DateTime LastExecution { get; set; }
|
||||
|
||||
public Boolean Success { get; set; }
|
||||
}
|
||||
}
|
@ -1,134 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.Providers.Core;
|
||||
using NzbDrone.Web.Models;
|
||||
|
||||
namespace NzbDrone.Web.Controllers
|
||||
{
|
||||
public class AddSeriesController : Controller
|
||||
{
|
||||
public IConfigProvider ConfigProvider { get; set; }
|
||||
private readonly SyncProvider _syncProvider;
|
||||
private readonly RootDirProvider _rootFolderProvider;
|
||||
private readonly IConfigProvider _configProvider;
|
||||
private readonly QualityProvider _qualityProvider;
|
||||
private readonly TvDbProvider _tvDbProvider;
|
||||
private readonly SeriesProvider _seriesProvider;
|
||||
|
||||
public AddSeriesController(SyncProvider syncProvider, RootDirProvider rootFolderProvider, IConfigProvider configProvider,
|
||||
QualityProvider qualityProvider, TvDbProvider tvDbProvider, SeriesProvider seriesProvider)
|
||||
{
|
||||
ConfigProvider = configProvider;
|
||||
_syncProvider = syncProvider;
|
||||
_rootFolderProvider = rootFolderProvider;
|
||||
_configProvider = configProvider;
|
||||
_qualityProvider = qualityProvider;
|
||||
_tvDbProvider = tvDbProvider;
|
||||
_seriesProvider = seriesProvider;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public JsonResult ScanNewSeries()
|
||||
{
|
||||
_syncProvider.BeginUpdateNewSeries();
|
||||
return new JsonResult();
|
||||
}
|
||||
|
||||
public ActionResult AddNew()
|
||||
{
|
||||
ViewData["RootDirs"] = _rootFolderProvider.GetAll();
|
||||
ViewData["DirSep"] = Path.DirectorySeparatorChar;
|
||||
|
||||
var profiles = _qualityProvider.GetAllProfiles();
|
||||
var selectList = new SelectList(profiles, "QualityProfileId", "Name");
|
||||
var defaultQuality = Convert.ToInt32(_configProvider.DefaultQualityProfile);
|
||||
|
||||
var model = new AddNewSeriesModel
|
||||
{
|
||||
DirectorySeparatorChar = Path.DirectorySeparatorChar.ToString(),
|
||||
RootDirectories = _rootFolderProvider.GetAll(),
|
||||
QualityProfileId = defaultQuality,
|
||||
QualitySelectList = selectList
|
||||
};
|
||||
|
||||
return View(model);
|
||||
}
|
||||
|
||||
public ActionResult AddExisting()
|
||||
{
|
||||
var unmappedList = new List<String>();
|
||||
|
||||
var profiles = _qualityProvider.GetAllProfiles();
|
||||
var defaultQuality = Convert.ToInt32(_configProvider.DefaultQualityProfile);
|
||||
var selectList = new SelectList(profiles, "QualityProfileId", "Name", defaultQuality);
|
||||
|
||||
ViewData["qualities"] = selectList;
|
||||
|
||||
foreach (var folder in _rootFolderProvider.GetAll())
|
||||
{
|
||||
unmappedList.AddRange(_syncProvider.GetUnmappedFolders(folder.Path));
|
||||
}
|
||||
|
||||
return View(unmappedList);
|
||||
}
|
||||
|
||||
public ActionResult RenderPartial(string path)
|
||||
{
|
||||
|
||||
var suggestions = GetSuggestionList(new DirectoryInfo(path).Name);
|
||||
|
||||
ViewData["guid"] = Guid.NewGuid();
|
||||
ViewData["path"] = path;
|
||||
ViewData["javaPath"] = path.Replace(Path.DirectorySeparatorChar, '|').Replace(Path.VolumeSeparatorChar, '^');
|
||||
|
||||
var defaultQuality = _configProvider.DefaultQualityProfile;
|
||||
var qualityProfiles = _qualityProvider.GetAllProfiles();
|
||||
|
||||
ViewData["quality"] = new SelectList(
|
||||
qualityProfiles,
|
||||
"QualityProfileId",
|
||||
"Name",
|
||||
defaultQuality); ;
|
||||
|
||||
return PartialView("AddSeriesItem", suggestions);
|
||||
|
||||
}
|
||||
|
||||
public JsonResult AddSeries(string path, int seriesId, int qualityProfileId)
|
||||
{
|
||||
//Get TVDB Series Name
|
||||
//Create new folder for series
|
||||
//Add the new series to the Database
|
||||
|
||||
_seriesProvider.AddSeries(path.Replace('|', Path.DirectorySeparatorChar).Replace('^', Path.VolumeSeparatorChar), seriesId, qualityProfileId);
|
||||
ScanNewSeries();
|
||||
return new JsonResult() { Data = "ok" };
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult _textLookUp(string text, int? filterMode)
|
||||
{
|
||||
var suggestions = GetSuggestionList(text);
|
||||
|
||||
return new JsonResult
|
||||
{
|
||||
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
|
||||
Data = suggestions
|
||||
};
|
||||
}
|
||||
|
||||
public SelectList GetSuggestionList(string searchString)
|
||||
{
|
||||
var dataVal = _tvDbProvider.SearchSeries(searchString);
|
||||
//var bestResult = _tvDbProvider.GetBestMatch(dataVal.ToList(), searchString);
|
||||
|
||||
return new SelectList(dataVal, "Id", "SeriesName", dataVal[0].Id);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.Providers.Timers;
|
||||
using NzbDrone.Core.Repository;
|
||||
using NzbDrone.Web.Models;
|
||||
using Telerik.Web.Mvc;
|
||||
@ -19,28 +20,28 @@ public class SeriesController : Controller
|
||||
private readonly QualityProvider _qualityProvider;
|
||||
private readonly RenameProvider _renameProvider;
|
||||
private readonly RootDirProvider _rootDirProvider;
|
||||
private readonly RssSyncProvider _rssSyncProvider;
|
||||
private readonly SeriesProvider _seriesProvider;
|
||||
private readonly SyncProvider _syncProvider;
|
||||
private readonly TvDbProvider _tvDbProvider;
|
||||
private readonly TimerProvider _timerProvider;
|
||||
//
|
||||
// GET: /Series/
|
||||
|
||||
public SeriesController(SyncProvider syncProvider, SeriesProvider seriesProvider,
|
||||
EpisodeProvider episodeProvider, RssSyncProvider rssSyncProvider,
|
||||
EpisodeProvider episodeProvider,
|
||||
QualityProvider qualityProvider, MediaFileProvider mediaFileProvider,
|
||||
RenameProvider renameProvider, RootDirProvider rootDirProvider,
|
||||
TvDbProvider tvDbProvider)
|
||||
TvDbProvider tvDbProvider, TimerProvider timerProvider)
|
||||
{
|
||||
_seriesProvider = seriesProvider;
|
||||
_episodeProvider = episodeProvider;
|
||||
_syncProvider = syncProvider;
|
||||
_rssSyncProvider = rssSyncProvider;
|
||||
_qualityProvider = qualityProvider;
|
||||
_mediaFileProvider = mediaFileProvider;
|
||||
_renameProvider = renameProvider;
|
||||
_rootDirProvider = rootDirProvider;
|
||||
_tvDbProvider = tvDbProvider;
|
||||
_timerProvider = timerProvider;
|
||||
}
|
||||
|
||||
public ActionResult Index()
|
||||
@ -52,13 +53,13 @@ public ActionResult Index()
|
||||
|
||||
public ActionResult RssSync()
|
||||
{
|
||||
_rssSyncProvider.Begin();
|
||||
_timerProvider.ForceExecute(typeof(RssSyncTimer));
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
||||
public ActionResult UnMapped(string path)
|
||||
{
|
||||
return View(_syncProvider.GetUnmappedFolders(path).Select(c => new MappingModel {Id = 1, Path = c}).ToList());
|
||||
return View(_syncProvider.GetUnmappedFolders(path).Select(c => new MappingModel { Id = 1, Path = c }).ToList());
|
||||
}
|
||||
|
||||
public ActionResult LoadEpisodes(int seriesId)
|
||||
@ -121,7 +122,7 @@ public ActionResult _AjaxUnmappedFoldersGrid()
|
||||
//We still want to show this series as unmapped, but we don't know what it will be when mapped
|
||||
//Todo: Provide the user with a way to manually map a folder to a TvDb series (or make them rename the folder...)
|
||||
if (tvDbSeries == null)
|
||||
tvDbSeries = new TvdbSeries {Id = 0, SeriesName = String.Empty};
|
||||
tvDbSeries = new TvdbSeries { Id = 0, SeriesName = String.Empty };
|
||||
|
||||
unmappedList.Add(new AddExistingSeriesModel
|
||||
{
|
||||
@ -263,7 +264,7 @@ public ActionResult SyncEpisodesOnDisk(int seriesId)
|
||||
var series = _seriesProvider.GetSeries(seriesId);
|
||||
_mediaFileProvider.Scan(series);
|
||||
|
||||
return RedirectToAction("Details", new {seriesId});
|
||||
return RedirectToAction("Details", new { seriesId });
|
||||
}
|
||||
|
||||
public ActionResult RenameAll()
|
||||
@ -275,7 +276,7 @@ public ActionResult RenameAll()
|
||||
public ActionResult RenameSeries(int seriesId)
|
||||
{
|
||||
_renameProvider.RenameSeries(seriesId);
|
||||
return RedirectToAction("Details", new {seriesId});
|
||||
return RedirectToAction("Details", new { seriesId });
|
||||
}
|
||||
|
||||
public ActionResult RenameSeason(int seasonId)
|
||||
|
@ -1,5 +1,7 @@
|
||||
using System.Web.Mvc;
|
||||
using System;
|
||||
using System.Web.Mvc;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.Providers.Timers;
|
||||
|
||||
namespace NzbDrone.Web.Controllers
|
||||
{
|
||||
@ -20,7 +22,7 @@ public ActionResult Index()
|
||||
[ChildActionOnly]
|
||||
public ActionResult Footer()
|
||||
{
|
||||
ViewData["RssTimer"] = _timerProvider.NextRssSyncTime().ToString("yyyyMMddHHmmss");
|
||||
ViewData["RssTimer"] = DateTime.Now.ToString("yyyyMMddHHmmss");
|
||||
//ViewData["RssTimer"] = DateTime.Now.AddMinutes(61).AddSeconds(10).ToString("yyyyMMddHHmmss");
|
||||
return PartialView();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user