From 59899286ee0f25d81022d12a3d60bc6c7c145868 Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Tue, 19 Apr 2011 18:20:20 -0700 Subject: [PATCH] Added TimerProvider --- NzbDrone.Core.Test/NzbDrone.Core.Test.csproj | 1 + NzbDrone.Core.Test/ParserTest.cs | 11 +- NzbDrone.Core.Test/TimerProviderTest.cs | 110 ++++++++++++++ NzbDrone.Core/CentralDispatch.cs | 39 +---- NzbDrone.Core/Helpers/ServerHelper.cs | 14 -- NzbDrone.Core/NzbDrone.Core.csproj | 7 +- NzbDrone.Core/Parser.cs | 16 +-- NzbDrone.Core/Providers/IndexerProvider.cs | 2 +- NzbDrone.Core/Providers/RssSyncProvider.cs | 9 -- NzbDrone.Core/Providers/SabProvider.cs | 2 +- NzbDrone.Core/Providers/TimerProvider.cs | 130 ----------------- NzbDrone.Core/Providers/Timers/ITimer.cs | 11 ++ .../Providers/Timers/RssSyncTimer.cs | 39 +++++ .../Providers/Timers/TimerProvider.cs | 123 ++++++++++++++++ NzbDrone.Core/Providers/XbmcProvider.cs | 4 +- NzbDrone.Core/Repository/Season.cs | 4 +- NzbDrone.Core/Repository/Series.cs | 8 +- NzbDrone.Core/Repository/TimerSetting.cs | 23 +++ ...ler (x201's conflicted copy 2011-04-09).cs | 134 ------------------ NzbDrone.Web/Controllers/SeriesController.cs | 19 +-- NzbDrone.Web/Controllers/SharedController.cs | 6 +- 21 files changed, 353 insertions(+), 359 deletions(-) create mode 100644 NzbDrone.Core.Test/TimerProviderTest.cs delete mode 100644 NzbDrone.Core/Helpers/ServerHelper.cs delete mode 100644 NzbDrone.Core/Providers/RssSyncProvider.cs delete mode 100644 NzbDrone.Core/Providers/TimerProvider.cs create mode 100644 NzbDrone.Core/Providers/Timers/ITimer.cs create mode 100644 NzbDrone.Core/Providers/Timers/RssSyncTimer.cs create mode 100644 NzbDrone.Core/Providers/Timers/TimerProvider.cs create mode 100644 NzbDrone.Core/Repository/TimerSetting.cs delete mode 100644 NzbDrone.Web/Controllers/AddSeriesController (x201's conflicted copy 2011-04-09).cs diff --git a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index cd8c3e5e0..607d586ec 100644 --- a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -93,6 +93,7 @@ Code + diff --git a/NzbDrone.Core.Test/ParserTest.cs b/NzbDrone.Core.Test/ParserTest.cs index 25dce37aa..793acab90 100644 --- a/NzbDrone.Core.Test/ParserTest.cs +++ b/NzbDrone.Core.Test/ParserTest.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 @@ namespace NzbDrone.Core.Test * */ - [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 @@ namespace NzbDrone.Core.Test } [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 @@ namespace NzbDrone.Core.Test } [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 })] diff --git a/NzbDrone.Core.Test/TimerProviderTest.cs b/NzbDrone.Core.Test/TimerProviderTest.cs new file mode 100644 index 000000000..2c399a9cd --- /dev/null +++ b/NzbDrone.Core.Test/TimerProviderTest.cs @@ -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 fakeTimers = new List { new FakeTimer() }; + var mocker = new AutoMoqer(); + + mocker.SetConstant(MockLib.GetEmptyRepository()); + mocker.SetConstant(fakeTimers); + + var timerProvider = mocker.Resolve(); + timerProvider.Initialize(); + timerProvider.Run(); + + } + + [Test] + public void Init_Timers() + { + var fakeTimer = new FakeTimer(); + IEnumerable fakeTimers = new List { fakeTimer }; + var mocker = new AutoMoqer(); + + mocker.SetConstant(MockLib.GetEmptyRepository()); + mocker.SetConstant(fakeTimers); + + var timerProvider = mocker.Resolve(); + 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 fakeTimers = new List { fakeTimer }; + var mocker = new AutoMoqer(); + + mocker.SetConstant(repo); + mocker.SetConstant(fakeTimers); + + var timerProvider = mocker.Resolve(); + timerProvider.Initialize(); + } + + var mocker2 = new AutoMoqer(); + + mocker2.SetConstant(repo); + var assertTimerProvider = mocker2.Resolve(); + + 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() + { + } + } +} \ No newline at end of file diff --git a/NzbDrone.Core/CentralDispatch.cs b/NzbDrone.Core/CentralDispatch.cs index a8e78471f..addfffa09 100644 --- a/NzbDrone.Core/CentralDispatch.cs +++ b/NzbDrone.Core/CentralDispatch.cs @@ -10,6 +10,7 @@ using NzbDrone.Core.Instrumentation; 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 @@ namespace NzbDrone.Core 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 @@ namespace NzbDrone.Core } } - 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 @@ namespace NzbDrone.Core 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 @@ namespace NzbDrone.Core _kernel.Bind().ToSelf().InSingletonScope(); _kernel.Bind().ToSelf().InSingletonScope(); _kernel.Bind().ToSelf().InSingletonScope(); - _kernel.Bind().ToSelf().InSingletonScope(); _kernel.Bind().ToSelf().InSingletonScope(); _kernel.Bind().ToSelf().InSingletonScope(); _kernel.Bind().ToSelf().InSingletonScope(); @@ -127,12 +108,6 @@ namespace NzbDrone.Core ForceMigration(_kernel.Get()); SetupDefaultQualityProfiles(_kernel.Get()); //Setup the default QualityProfiles on start-up - //Get the Timers going - var config = _kernel.Get(); - var timer = _kernel.Get(); - timer.SetRssSyncTimer(Convert.ToInt32(config.GetValue("SyncFrequency", "15", true))); - timer.StartRssSyncTimer(); - BindIndexers(); } } @@ -140,6 +115,7 @@ namespace NzbDrone.Core private static void BindIndexers() { _kernel.Bind().To().InSingletonScope(); + var indexers = _kernel.GetAll(); _kernel.Get().InitializeIndexers(indexers.ToList()); } @@ -154,7 +130,7 @@ namespace NzbDrone.Core } /// - /// This method forces IISExpress process to exit with the host application + /// Forces IISExpress process to exit with the host application /// public static void DedicateToHost() { @@ -187,7 +163,6 @@ namespace NzbDrone.Core Process.GetCurrentProcess().Kill(); } - private static void SetupDefaultQualityProfiles(IRepository repository) { var sd = new QualityProfile diff --git a/NzbDrone.Core/Helpers/ServerHelper.cs b/NzbDrone.Core/Helpers/ServerHelper.cs deleted file mode 100644 index 88b23ffde..000000000 --- a/NzbDrone.Core/Helpers/ServerHelper.cs +++ /dev/null @@ -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(); - } - } -} \ No newline at end of file diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index 7290c3408..56b174966 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -163,14 +163,17 @@ - + + + + @@ -187,12 +190,10 @@ - - diff --git a/NzbDrone.Core/Parser.cs b/NzbDrone.Core/Parser.cs index 0f5338bc0..dca6fc199 100644 --- a/NzbDrone.Core/Parser.cs +++ b/NzbDrone.Core/Parser.cs @@ -116,7 +116,7 @@ namespace NzbDrone.Core 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 @@ namespace NzbDrone.Core { 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 @@ namespace NzbDrone.Core 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; } diff --git a/NzbDrone.Core/Providers/IndexerProvider.cs b/NzbDrone.Core/Providers/IndexerProvider.cs index 6359e7dcc..dde868228 100644 --- a/NzbDrone.Core/Providers/IndexerProvider.cs +++ b/NzbDrone.Core/Providers/IndexerProvider.cs @@ -48,7 +48,7 @@ namespace NzbDrone.Core.Providers return _repository.Single(s => s.IndexProviderType == type.ToString()); } - public IndexerSetting GetSettings(int id) + public virtual IndexerSetting GetSettings(int id) { return _repository.Single(s => s.Id == id); } diff --git a/NzbDrone.Core/Providers/RssSyncProvider.cs b/NzbDrone.Core/Providers/RssSyncProvider.cs deleted file mode 100644 index 3da8aa058..000000000 --- a/NzbDrone.Core/Providers/RssSyncProvider.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace NzbDrone.Core.Providers -{ - public class RssSyncProvider - { - public virtual void Begin() - { - } - } -} \ No newline at end of file diff --git a/NzbDrone.Core/Providers/SabProvider.cs b/NzbDrone.Core/Providers/SabProvider.cs index ca667a280..e5b926893 100644 --- a/NzbDrone.Core/Providers/SabProvider.cs +++ b/NzbDrone.Core/Providers/SabProvider.cs @@ -51,7 +51,7 @@ namespace NzbDrone.Core.Providers XDocument xDoc = XDocument.Parse(response); - //If an Error Occurred, retuyrn) + //If an Error Occurred, return) if (xDoc.Descendants("error").Count() != 0) return false; diff --git a/NzbDrone.Core/Providers/TimerProvider.cs b/NzbDrone.Core/Providers/TimerProvider.cs deleted file mode 100644 index a976ec663..000000000 --- a/NzbDrone.Core/Providers/TimerProvider.cs +++ /dev/null @@ -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(); - } - } -} \ No newline at end of file diff --git a/NzbDrone.Core/Providers/Timers/ITimer.cs b/NzbDrone.Core/Providers/Timers/ITimer.cs new file mode 100644 index 000000000..ec4fdd599 --- /dev/null +++ b/NzbDrone.Core/Providers/Timers/ITimer.cs @@ -0,0 +1,11 @@ +namespace NzbDrone.Core.Providers.Timers +{ + public interface ITimer + { + string Name { get; } + + int DefaultInterval { get; } + + void Start(); + } +} \ No newline at end of file diff --git a/NzbDrone.Core/Providers/Timers/RssSyncTimer.cs b/NzbDrone.Core/Providers/Timers/RssSyncTimer.cs new file mode 100644 index 000000000..46305ed15 --- /dev/null +++ b/NzbDrone.Core/Providers/Timers/RssSyncTimer.cs @@ -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) + { + + } + } + } +} \ No newline at end of file diff --git a/NzbDrone.Core/Providers/Timers/TimerProvider.cs b/NzbDrone.Core/Providers/Timers/TimerProvider.cs new file mode 100644 index 000000000..334f0b67f --- /dev/null +++ b/NzbDrone.Core/Providers/Timers/TimerProvider.cs @@ -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 _timerJobs; + + private static readonly object ExecutionLock = new object(); + private static bool _isRunning; + + public TimerProvider(IRepository repository, IEnumerable timerJobs) + { + _repository = repository; + _timerJobs = timerJobs; + } + + public TimerProvider() { } + + public virtual List All() + { + return _repository.All().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); + } + } + } + + + } +} \ No newline at end of file diff --git a/NzbDrone.Core/Providers/XbmcProvider.cs b/NzbDrone.Core/Providers/XbmcProvider.cs index 4d61f03a1..b7cccefbe 100644 --- a/NzbDrone.Core/Providers/XbmcProvider.cs +++ b/NzbDrone.Core/Providers/XbmcProvider.cs @@ -23,13 +23,13 @@ namespace NzbDrone.Core.Providers 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); diff --git a/NzbDrone.Core/Repository/Season.cs b/NzbDrone.Core/Repository/Season.cs index ee1d3def0..f75dff0dd 100644 --- a/NzbDrone.Core/Repository/Season.cs +++ b/NzbDrone.Core/Repository/Season.cs @@ -18,9 +18,9 @@ namespace NzbDrone.Core.Repository public DayOfWeek? LastDiskSync { get; set; } [SubSonicToManyRelation] - public virtual List Episodes { get; private set; } + public virtual List Episodes { get; protected set; } [SubSonicToOneRelation(ThisClassContainsJoinKey = true)] - public virtual Series Series { get; private set; } + public virtual Series Series { get; protected set; } } } \ No newline at end of file diff --git a/NzbDrone.Core/Repository/Series.cs b/NzbDrone.Core/Repository/Series.cs index 011de2d11..f34f6cdd6 100644 --- a/NzbDrone.Core/Repository/Series.cs +++ b/NzbDrone.Core/Repository/Series.cs @@ -45,15 +45,15 @@ namespace NzbDrone.Core.Repository 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 Seasons { get; private set; } + public virtual List Seasons { get; protected set; } [SubSonicToManyRelation] - public virtual List Episodes { get; private set; } + public virtual List Episodes { get; protected set; } [SubSonicToManyRelation] - public virtual List EpisodeFiles { get; private set; } + public virtual List EpisodeFiles { get; protected set; } } } \ No newline at end of file diff --git a/NzbDrone.Core/Repository/TimerSetting.cs b/NzbDrone.Core/Repository/TimerSetting.cs new file mode 100644 index 000000000..e4a58bf9d --- /dev/null +++ b/NzbDrone.Core/Repository/TimerSetting.cs @@ -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; } + } +} \ No newline at end of file diff --git a/NzbDrone.Web/Controllers/AddSeriesController (x201's conflicted copy 2011-04-09).cs b/NzbDrone.Web/Controllers/AddSeriesController (x201's conflicted copy 2011-04-09).cs deleted file mode 100644 index dbfa65355..000000000 --- a/NzbDrone.Web/Controllers/AddSeriesController (x201's conflicted copy 2011-04-09).cs +++ /dev/null @@ -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(); - - 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); - } - - } -} diff --git a/NzbDrone.Web/Controllers/SeriesController.cs b/NzbDrone.Web/Controllers/SeriesController.cs index b37badb47..468af8972 100644 --- a/NzbDrone.Web/Controllers/SeriesController.cs +++ b/NzbDrone.Web/Controllers/SeriesController.cs @@ -4,6 +4,7 @@ using System.IO; 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 @@ namespace NzbDrone.Web.Controllers 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 @@ namespace NzbDrone.Web.Controllers 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 @@ namespace NzbDrone.Web.Controllers //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 @@ namespace NzbDrone.Web.Controllers 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 @@ namespace NzbDrone.Web.Controllers public ActionResult RenameSeries(int seriesId) { _renameProvider.RenameSeries(seriesId); - return RedirectToAction("Details", new {seriesId}); + return RedirectToAction("Details", new { seriesId }); } public ActionResult RenameSeason(int seasonId) diff --git a/NzbDrone.Web/Controllers/SharedController.cs b/NzbDrone.Web/Controllers/SharedController.cs index 5cc16ce1e..246e6c5a5 100644 --- a/NzbDrone.Web/Controllers/SharedController.cs +++ b/NzbDrone.Web/Controllers/SharedController.cs @@ -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 @@ namespace NzbDrone.Web.Controllers [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(); }