1
0
mirror of https://github.com/Radarr/Radarr.git synced 2024-11-04 10:02:40 +01:00

Added TimerProvider

This commit is contained in:
kay.one 2011-04-19 18:20:20 -07:00
parent 848553da73
commit 59899286ee
21 changed files with 353 additions and 359 deletions

View File

@ -93,6 +93,7 @@
<Compile Include="AutoMoq\Unity\AutoMockingContainerExtension.cs"> <Compile Include="AutoMoq\Unity\AutoMockingContainerExtension.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="TimerProviderTest.cs" />
<Compile Include="SyncProviderTest.cs" /> <Compile Include="SyncProviderTest.cs" />
<Compile Include="RootDirProviderTest.cs" /> <Compile Include="RootDirProviderTest.cs" />
<Compile Include="IndexerProviderTest.cs" /> <Compile Include="IndexerProviderTest.cs" />

View File

@ -1,4 +1,5 @@
using MbUnit.Framework; using System.Threading;
using MbUnit.Framework;
using NzbDrone.Core.Repository.Quality; using NzbDrone.Core.Repository.Quality;
namespace NzbDrone.Core.Test namespace NzbDrone.Core.Test
@ -13,8 +14,8 @@ public class ParserTest
* *
*/ */
[Test] [Test]
[Timeout(1)]
[Row("Sonny.With.a.Chance.S02E15", 2, 15)] [Row("Sonny.With.a.Chance.S02E15", 2, 15)]
[Row("WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD", 3, 1)] [Row("WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD", 3, 1)]
[Row("Two.and.a.Half.Me.103.720p.HDTV.X264-DIMENSION", 1, 3)] [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] [Test]
[Timeout(1)]
[Row("WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD", QualityTypes.BDRip)] [Row("WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD", QualityTypes.BDRip)]
[Row("WEEDS.S03E01-06.DUAL.BDRip.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)] [Row("Two.and.a.Half.Men.S08E05.720p.HDTV.X264-DIMENSION", QualityTypes.HDTV)]
@ -66,6 +68,7 @@ public void quality_parse(string path, object quality)
} }
[Test] [Test]
[Timeout(1)]
[Row("WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD", 3, new[] { 1, 2, 3, 4, 5, 6 })] [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("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("Weeds.S03E01.S03E02.720p.HDTV.X264-DIMENSION", 3, new[] { 1, 2 })]

View 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()
{
}
}
}

View File

@ -10,6 +10,7 @@
using NzbDrone.Core.Providers; using NzbDrone.Core.Providers;
using NzbDrone.Core.Providers.Core; using NzbDrone.Core.Providers.Core;
using NzbDrone.Core.Providers.Indexer; using NzbDrone.Core.Providers.Indexer;
using NzbDrone.Core.Providers.Timers;
using NzbDrone.Core.Repository; using NzbDrone.Core.Repository;
using NzbDrone.Core.Repository.Quality; using NzbDrone.Core.Repository.Quality;
using SubSonic.DataProviders; using SubSonic.DataProviders;
@ -22,7 +23,6 @@ public static class CentralDispatch
private static StandardKernel _kernel; private static StandardKernel _kernel;
private static readonly Object KernelLock = new object(); private static readonly Object KernelLock = new object();
private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private static string _startupPath;
public static String AppPath 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 public static StandardKernel NinjectKernel
{ {
get get
@ -70,19 +55,16 @@ public static void BindKernel()
Logger.Debug("Binding Ninject's Kernel"); Logger.Debug("Binding Ninject's Kernel");
_kernel = new StandardKernel(); _kernel = new StandardKernel();
//Store the startup path
_startupPath = AppPath;
//Sqlite //Sqlite
var AppDataPath = new DirectoryInfo(Path.Combine(AppPath, "App_Data")); var appDataPath = new DirectoryInfo(Path.Combine(AppPath, "App_Data"));
if (!AppDataPath.Exists) AppDataPath.Create(); if (!appDataPath.Exists) appDataPath.Create();
string connectionString = String.Format("Data Source={0};Version=3;", 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"); var dbProvider = ProviderFactory.GetProvider(connectionString, "System.Data.SQLite");
string logConnectionString = String.Format("Data Source={0};Version=3;", 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"); var logDbProvider = ProviderFactory.GetProvider(logConnectionString, "System.Data.SQLite");
@ -99,7 +81,6 @@ public static void BindKernel()
_kernel.Bind<HttpProvider>().ToSelf().InSingletonScope(); _kernel.Bind<HttpProvider>().ToSelf().InSingletonScope();
_kernel.Bind<SeriesProvider>().ToSelf().InSingletonScope(); _kernel.Bind<SeriesProvider>().ToSelf().InSingletonScope();
_kernel.Bind<SeasonProvider>().ToSelf().InSingletonScope(); _kernel.Bind<SeasonProvider>().ToSelf().InSingletonScope();
_kernel.Bind<RssSyncProvider>().ToSelf().InSingletonScope();
_kernel.Bind<EpisodeProvider>().ToSelf().InSingletonScope(); _kernel.Bind<EpisodeProvider>().ToSelf().InSingletonScope();
_kernel.Bind<UpcomingEpisodesProvider>().ToSelf().InSingletonScope(); _kernel.Bind<UpcomingEpisodesProvider>().ToSelf().InSingletonScope();
_kernel.Bind<DiskProvider>().ToSelf().InSingletonScope(); _kernel.Bind<DiskProvider>().ToSelf().InSingletonScope();
@ -127,12 +108,6 @@ public static void BindKernel()
ForceMigration(_kernel.Get<IRepository>()); ForceMigration(_kernel.Get<IRepository>());
SetupDefaultQualityProfiles(_kernel.Get<IRepository>()); //Setup the default QualityProfiles on start-up 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(); BindIndexers();
} }
} }
@ -140,6 +115,7 @@ public static void BindKernel()
private static void BindIndexers() private static void BindIndexers()
{ {
_kernel.Bind<IndexerProviderBase>().To<NzbsOrgProvider>().InSingletonScope(); _kernel.Bind<IndexerProviderBase>().To<NzbsOrgProvider>().InSingletonScope();
var indexers = _kernel.GetAll<IndexerProviderBase>(); var indexers = _kernel.GetAll<IndexerProviderBase>();
_kernel.Get<IndexerProvider>().InitializeIndexers(indexers.ToList()); _kernel.Get<IndexerProvider>().InitializeIndexers(indexers.ToList());
} }
@ -154,7 +130,7 @@ private static void ForceMigration(IRepository repository)
} }
/// <summary> /// <summary>
/// This method forces IISExpress process to exit with the host application /// Forces IISExpress process to exit with the host application
/// </summary> /// </summary>
public static void DedicateToHost() public static void DedicateToHost()
{ {
@ -187,7 +163,6 @@ private static void ShutDown()
Process.GetCurrentProcess().Kill(); Process.GetCurrentProcess().Kill();
} }
private static void SetupDefaultQualityProfiles(IRepository repository) private static void SetupDefaultQualityProfiles(IRepository repository)
{ {
var sd = new QualityProfile var sd = new QualityProfile

View File

@ -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();
}
}
}

View File

@ -163,14 +163,17 @@
<Compile Include="Helpers\EpisodeRenameHelper.cs" /> <Compile Include="Helpers\EpisodeRenameHelper.cs" />
<Compile Include="Helpers\EpisodeSortingHelper.cs" /> <Compile Include="Helpers\EpisodeSortingHelper.cs" />
<Compile Include="Helpers\SceneNameHelper.cs" /> <Compile Include="Helpers\SceneNameHelper.cs" />
<Compile Include="Helpers\ServerHelper.cs" />
<Compile Include="Instrumentation\LogLevel.cs" /> <Compile Include="Instrumentation\LogLevel.cs" />
<Compile Include="Instrumentation\LogProvider.cs" /> <Compile Include="Instrumentation\LogProvider.cs" />
<Compile Include="Instrumentation\SubsonicTarget.cs" /> <Compile Include="Instrumentation\SubsonicTarget.cs" />
<Compile Include="Instrumentation\ExceptioneerTarget.cs" /> <Compile Include="Instrumentation\ExceptioneerTarget.cs" />
<Compile Include="Instrumentation\NlogWriter.cs" /> <Compile Include="Instrumentation\NlogWriter.cs" />
<Compile Include="Providers\Timers\TimerProvider.cs" />
<Compile Include="Providers\Indexer\NzbMatrixFeedProvider.cs" /> <Compile Include="Providers\Indexer\NzbMatrixFeedProvider.cs" />
<Compile Include="Providers\Indexer\NzbsRUsFeedProvider.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="Repository\IndexerSetting.cs" />
<Compile Include="Model\EpisodeParseResult.cs" /> <Compile Include="Model\EpisodeParseResult.cs" />
<Compile Include="Model\EpisodeRenameModel.cs" /> <Compile Include="Model\EpisodeRenameModel.cs" />
@ -187,12 +190,10 @@
<Compile Include="Providers\HistoryProvider.cs" /> <Compile Include="Providers\HistoryProvider.cs" />
<Compile Include="Providers\BacklogProvider.cs" /> <Compile Include="Providers\BacklogProvider.cs" />
<Compile Include="Providers\IndexerProvider.cs" /> <Compile Include="Providers\IndexerProvider.cs" />
<Compile Include="Providers\RssSyncProvider.cs" />
<Compile Include="Providers\PostProcessingProvider.cs" /> <Compile Include="Providers\PostProcessingProvider.cs" />
<Compile Include="Providers\QualityProvider.cs" /> <Compile Include="Providers\QualityProvider.cs" />
<Compile Include="Providers\RenameProvider.cs" /> <Compile Include="Providers\RenameProvider.cs" />
<Compile Include="Providers\RootDirProvider.cs" /> <Compile Include="Providers\RootDirProvider.cs" />
<Compile Include="Providers\TimerProvider.cs" />
<Compile Include="Providers\UpcomingEpisodesProvider.cs" /> <Compile Include="Providers\UpcomingEpisodesProvider.cs" />
<Compile Include="Providers\XbmcProvider.cs" /> <Compile Include="Providers\XbmcProvider.cs" />
<Compile Include="Repository\EpisodeFile.cs" /> <Compile Include="Repository\EpisodeFile.cs" />

View File

@ -116,7 +116,7 @@ internal static SeasonParseResult ParseSeasonInfo(string title)
if (match.Count != 0) if (match.Count != 0)
{ {
var seriesName = NormalizeTitle(match[0].Groups["title"].Value); var seriesName = NormalizeTitle(match[0].Groups["title"].Value);
var year = 0; int year;
Int32.TryParse(match[0].Groups["year"].Value, out year); Int32.TryParse(match[0].Groups["year"].Value, out year);
if (year < 1900 || year > DateTime.Now.Year + 1) if (year < 1900 || year > DateTime.Now.Year + 1)
@ -130,12 +130,11 @@ internal static SeasonParseResult ParseSeasonInfo(string title)
{ {
SeriesTitle = seriesName, SeriesTitle = seriesName,
SeasonNumber = seasonNumber, SeasonNumber = seasonNumber,
Year = year Year = year,
Quality = ParseQuality(title)
}; };
result.Quality = ParseQuality(title);
Logger.Trace("Season Parsed. {0}", result); Logger.Trace("Season Parsed. {0}", result);
return result; return result;
} }
@ -160,13 +159,6 @@ internal static string ParseSeriesName(string title)
if (match.Count != 0) if (match.Count != 0)
{ {
var seriesName = NormalizeTitle(match[0].Groups["title"].Value); 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); Logger.Trace("Series Parsed. {0}", seriesName);
return seriesName; return seriesName;

View File

@ -48,7 +48,7 @@ public virtual IndexerSetting GetSettings(Type type)
return _repository.Single<IndexerSetting>(s => s.IndexProviderType == type.ToString()); 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); return _repository.Single<IndexerSetting>(s => s.Id == id);
} }

View File

@ -1,9 +0,0 @@
namespace NzbDrone.Core.Providers
{
public class RssSyncProvider
{
public virtual void Begin()
{
}
}
}

View File

@ -51,7 +51,7 @@ public virtual bool IsInQueue(string title)
XDocument xDoc = XDocument.Parse(response); XDocument xDoc = XDocument.Parse(response);
//If an Error Occurred, retuyrn) //If an Error Occurred, return)
if (xDoc.Descendants("error").Count() != 0) if (xDoc.Descendants("error").Count() != 0)
return false; return false;

View File

@ -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();
}
}
}

View File

@ -0,0 +1,11 @@
namespace NzbDrone.Core.Providers.Timers
{
public interface ITimer
{
string Name { get; }
int DefaultInterval { get; }
void Start();
}
}

View 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)
{
}
}
}
}

View 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);
}
}
}
}
}

View File

@ -29,7 +29,7 @@ public virtual void Notify(string header, string message)
if (Convert.ToBoolean(_configProvider.GetValue("XbmcNotificationImage", false, true))) if (Convert.ToBoolean(_configProvider.GetValue("XbmcNotificationImage", false, true)))
{ {
//Todo: Get the actual port that NzbDrone is running on... //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); var imageUrl = String.Format("{0}/Content/XbmcNotification.png", serverInfo);
command = String.Format("ExecBuiltIn(Notification({0},{1},{2}, {3}))", header, message, time, imageUrl); command = String.Format("ExecBuiltIn(Notification({0},{1},{2}, {3}))", header, message, time, imageUrl);

View File

@ -18,9 +18,9 @@ public class Season
public DayOfWeek? LastDiskSync { get; set; } public DayOfWeek? LastDiskSync { get; set; }
[SubSonicToManyRelation] [SubSonicToManyRelation]
public virtual List<Episode> Episodes { get; private set; } public virtual List<Episode> Episodes { get; protected set; }
[SubSonicToOneRelation(ThisClassContainsJoinKey = true)] [SubSonicToOneRelation(ThisClassContainsJoinKey = true)]
public virtual Series Series { get; private set; } public virtual Series Series { get; protected set; }
} }
} }

View File

@ -45,15 +45,15 @@ public class Series
public DateTime? LastDiskSync { get; set; } public DateTime? LastDiskSync { get; set; }
[SubSonicToOneRelation(ThisClassContainsJoinKey = true, JoinKeyName = "QualityProfileId")] [SubSonicToOneRelation(ThisClassContainsJoinKey = true, JoinKeyName = "QualityProfileId")]
public virtual QualityProfile QualityProfile { get; private set; } public virtual QualityProfile QualityProfile { get; protected set; }
[SubSonicToManyRelation] [SubSonicToManyRelation]
public virtual List<Season> Seasons { get; private set; } public virtual List<Season> Seasons { get; protected set; }
[SubSonicToManyRelation] [SubSonicToManyRelation]
public virtual List<Episode> Episodes { get; private set; } public virtual List<Episode> Episodes { get; protected set; }
[SubSonicToManyRelation] [SubSonicToManyRelation]
public virtual List<EpisodeFile> EpisodeFiles { get; private set; } public virtual List<EpisodeFile> EpisodeFiles { get; protected set; }
} }
} }

View 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; }
}
}

View File

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

View File

@ -4,6 +4,7 @@
using System.Linq; using System.Linq;
using System.Web.Mvc; using System.Web.Mvc;
using NzbDrone.Core.Providers; using NzbDrone.Core.Providers;
using NzbDrone.Core.Providers.Timers;
using NzbDrone.Core.Repository; using NzbDrone.Core.Repository;
using NzbDrone.Web.Models; using NzbDrone.Web.Models;
using Telerik.Web.Mvc; using Telerik.Web.Mvc;
@ -19,28 +20,28 @@ public class SeriesController : Controller
private readonly QualityProvider _qualityProvider; private readonly QualityProvider _qualityProvider;
private readonly RenameProvider _renameProvider; private readonly RenameProvider _renameProvider;
private readonly RootDirProvider _rootDirProvider; private readonly RootDirProvider _rootDirProvider;
private readonly RssSyncProvider _rssSyncProvider;
private readonly SeriesProvider _seriesProvider; private readonly SeriesProvider _seriesProvider;
private readonly SyncProvider _syncProvider; private readonly SyncProvider _syncProvider;
private readonly TvDbProvider _tvDbProvider; private readonly TvDbProvider _tvDbProvider;
private readonly TimerProvider _timerProvider;
// //
// GET: /Series/ // GET: /Series/
public SeriesController(SyncProvider syncProvider, SeriesProvider seriesProvider, public SeriesController(SyncProvider syncProvider, SeriesProvider seriesProvider,
EpisodeProvider episodeProvider, RssSyncProvider rssSyncProvider, EpisodeProvider episodeProvider,
QualityProvider qualityProvider, MediaFileProvider mediaFileProvider, QualityProvider qualityProvider, MediaFileProvider mediaFileProvider,
RenameProvider renameProvider, RootDirProvider rootDirProvider, RenameProvider renameProvider, RootDirProvider rootDirProvider,
TvDbProvider tvDbProvider) TvDbProvider tvDbProvider, TimerProvider timerProvider)
{ {
_seriesProvider = seriesProvider; _seriesProvider = seriesProvider;
_episodeProvider = episodeProvider; _episodeProvider = episodeProvider;
_syncProvider = syncProvider; _syncProvider = syncProvider;
_rssSyncProvider = rssSyncProvider;
_qualityProvider = qualityProvider; _qualityProvider = qualityProvider;
_mediaFileProvider = mediaFileProvider; _mediaFileProvider = mediaFileProvider;
_renameProvider = renameProvider; _renameProvider = renameProvider;
_rootDirProvider = rootDirProvider; _rootDirProvider = rootDirProvider;
_tvDbProvider = tvDbProvider; _tvDbProvider = tvDbProvider;
_timerProvider = timerProvider;
} }
public ActionResult Index() public ActionResult Index()
@ -52,7 +53,7 @@ public ActionResult Index()
public ActionResult RssSync() public ActionResult RssSync()
{ {
_rssSyncProvider.Begin(); _timerProvider.ForceExecute(typeof(RssSyncTimer));
return RedirectToAction("Index"); return RedirectToAction("Index");
} }

View File

@ -1,5 +1,7 @@
using System.Web.Mvc; using System;
using System.Web.Mvc;
using NzbDrone.Core.Providers; using NzbDrone.Core.Providers;
using NzbDrone.Core.Providers.Timers;
namespace NzbDrone.Web.Controllers namespace NzbDrone.Web.Controllers
{ {
@ -20,7 +22,7 @@ public ActionResult Index()
[ChildActionOnly] [ChildActionOnly]
public ActionResult Footer() 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"); //ViewData["RssTimer"] = DateTime.Now.AddMinutes(61).AddSeconds(10).ToString("yyyyMMddHHmmss");
return PartialView(); return PartialView();
} }