mirror of https://github.com/Radarr/Radarr
fixed a bunch of things. added basic support for file scanning. logs are now avilable in the UI
This commit is contained in:
parent
c8a8fb4d62
commit
fa0af257ff
|
@ -30,4 +30,4 @@ _ReSharper*/
|
|||
[Ll]ogs/
|
||||
/[Pp]ackage/
|
||||
#NZBDrone specific
|
||||
nzbdrone.db
|
||||
*.db
|
|
@ -0,0 +1,15 @@
|
|||
<configuration>
|
||||
|
||||
<configSections>
|
||||
<section name="configurationRedirection" />
|
||||
</configSections>
|
||||
|
||||
<configProtectedData>
|
||||
<providers>
|
||||
<add name="IISRsaProvider" type="" description="Uses RsaCryptoServiceProvider to encrypt and decrypt" keyContainerName="iisConfigurationKey" cspProviderName="" useMachineContainer="true" useOAEP="false" />
|
||||
</providers>
|
||||
</configProtectedData>
|
||||
|
||||
<configurationRedirection />
|
||||
|
||||
</configuration>
|
|
@ -1,6 +1,9 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using MbUnit.Framework;
|
||||
using NLog;
|
||||
using NLog.Config;
|
||||
using System.Linq;
|
||||
|
||||
namespace NzbDrone.Core.Test
|
||||
{
|
||||
|
@ -10,24 +13,43 @@ namespace NzbDrone.Core.Test
|
|||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
var dbFiles = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.testdb");
|
||||
|
||||
foreach (var dbFile in dbFiles)
|
||||
foreach (var file in Directory.GetFiles(Directory.GetCurrentDirectory(), "*.db", SearchOption.AllDirectories))
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(dbFile);
|
||||
File.Delete(file);
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
||||
[FixtureTearDown]
|
||||
public void FixtureTearDown()
|
||||
{
|
||||
foreach (var file in Directory.GetFiles(Directory.GetCurrentDirectory(), "*.*", SearchOption.AllDirectories))
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(file);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
public void SetUp()
|
||||
{
|
||||
Instrumentation.Setup();
|
||||
try
|
||||
{
|
||||
LogManager.Configuration = new XmlLoggingConfiguration(Path.Combine(CentralDispatch.AppPath, "log.config"), false);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine("Unable to configure logging. " + e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text;
|
||||
using FizzWare.NBuilder;
|
||||
using Gallio.Framework;
|
||||
using MbUnit.Framework;
|
||||
using MbUnit.Framework.ContractVerifiers;
|
||||
|
@ -18,68 +20,144 @@ namespace NzbDrone.Core.Test
|
|||
// ReSharper disable InconsistentNaming
|
||||
public class MediaFileProviderTests
|
||||
{
|
||||
|
||||
[Test]
|
||||
public void scan_test()
|
||||
[Description("Verifies that a new file imported properly")]
|
||||
public void import_new_file()
|
||||
{
|
||||
//Arrange
|
||||
var repository = new Mock<IRepository>();
|
||||
repository.Setup(c => c.Update(It.IsAny<Episode>())).Verifiable();
|
||||
/////////////////////////////////////////
|
||||
|
||||
var diskProvider = MockLib.GetStandardDisk(1, 2);
|
||||
//Constants
|
||||
const string fileName = "WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD.avi";
|
||||
const int seasonNumber = 3;
|
||||
const int episodeNumner = 01;
|
||||
const int size = 12345;
|
||||
|
||||
//Fakes
|
||||
var fakeSeries = Builder<Series>.CreateNew().Build();
|
||||
var fakeEpisode = Builder<Episode>.CreateNew().With(c => c.SeriesId = fakeSeries.SeriesId).Build();
|
||||
|
||||
//Mocks
|
||||
var repository = new Mock<IRepository>();
|
||||
repository.Setup(r => r.Exists<EpisodeFile>(It.IsAny<Expression<Func<EpisodeFile, Boolean>>>())).Returns(false).Verifiable();
|
||||
|
||||
var episodeProvider = new Mock<IEpisodeProvider>();
|
||||
episodeProvider.Setup(e => e.GetEpisode(fakeSeries.SeriesId, seasonNumber, episodeNumner)).Returns(fakeEpisode).Verifiable();
|
||||
|
||||
var diskProvider = new Mock<IDiskProvider>();
|
||||
diskProvider.Setup(e => e.GetSize(fileName)).Returns(12345).Verifiable();
|
||||
|
||||
var kernel = new MockingKernel();
|
||||
kernel.Bind<IDiskProvider>().ToConstant(diskProvider);
|
||||
kernel.Bind<IRepository>().ToConstant(repository.Object);
|
||||
|
||||
kernel.Bind<IEpisodeProvider>().ToConstant(episodeProvider.Object);
|
||||
kernel.Bind<IDiskProvider>().ToConstant(diskProvider.Object);
|
||||
kernel.Bind<IMediaFileProvider>().To<MediaFileProvider>();
|
||||
|
||||
var fakeSeries = new Series()
|
||||
{
|
||||
Path = MockLib.StandardSeries[0]
|
||||
};
|
||||
|
||||
//Act
|
||||
kernel.Get<IMediaFileProvider>().Scan(fakeSeries);
|
||||
var result = kernel.Get<IMediaFileProvider>().ImportFile(fakeSeries, fileName);
|
||||
|
||||
//Assert
|
||||
repository.Verify(c => c.Update(It.IsAny<Episode>()), Times.Exactly(1 * 2));
|
||||
repository.VerifyAll();
|
||||
episodeProvider.VerifyAll();
|
||||
diskProvider.VerifyAll();
|
||||
Assert.IsNotNull(result);
|
||||
repository.Verify(r => r.Add<EpisodeFile>(result), Times.Once());
|
||||
|
||||
Assert.AreEqual(fakeEpisode.EpisodeId, result.EpisodeId);
|
||||
Assert.AreEqual(fakeEpisode.SeriesId, result.SeriesId);
|
||||
Assert.AreEqual(QualityTypes.DVD, result.Quality);
|
||||
Assert.AreEqual(Parser.NormalizePath(fileName), result.Path);
|
||||
Assert.AreEqual(size, result.Size);
|
||||
Assert.AreEqual(false, result.Proper);
|
||||
Assert.AreNotEqual(new DateTime(), result.DateAdded);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
[Description("Verifies that an existing file will skip import")]
|
||||
public void import_existing_file()
|
||||
{
|
||||
//Arrange
|
||||
/////////////////////////////////////////
|
||||
|
||||
//Constants
|
||||
const string fileName = "WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD.avi";
|
||||
|
||||
//Fakes
|
||||
var fakeSeries = Builder<Series>.CreateNew().Build();
|
||||
var fakeEpisode = Builder<Episode>.CreateNew().With(c => c.SeriesId = fakeSeries.SeriesId).Build();
|
||||
|
||||
//Mocks
|
||||
var repository = new Mock<IRepository>(MockBehavior.Strict);
|
||||
repository.Setup(r => r.Exists<EpisodeFile>(It.IsAny<Expression<Func<EpisodeFile, Boolean>>>())).Returns(true).Verifiable();
|
||||
|
||||
var episodeProvider = new Mock<IEpisodeProvider>(MockBehavior.Strict);
|
||||
var diskProvider = new Mock<IDiskProvider>(MockBehavior.Strict);
|
||||
|
||||
var kernel = new MockingKernel();
|
||||
kernel.Bind<IRepository>().ToConstant(repository.Object);
|
||||
|
||||
kernel.Bind<IEpisodeProvider>().ToConstant(episodeProvider.Object);
|
||||
kernel.Bind<IDiskProvider>().ToConstant(diskProvider.Object);
|
||||
kernel.Bind<IMediaFileProvider>().To<MediaFileProvider>();
|
||||
|
||||
//Act
|
||||
var result = kernel.Get<IMediaFileProvider>().ImportFile(fakeSeries, fileName);
|
||||
|
||||
//Assert
|
||||
repository.VerifyAll();
|
||||
episodeProvider.VerifyAll();
|
||||
diskProvider.VerifyAll();
|
||||
Assert.IsNull(result);
|
||||
repository.Verify(r => r.Add<EpisodeFile>(result), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
[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("Chuck.4x05.HDTV.XviD-LOL", 4, 5)]
|
||||
[Row("The.Girls.Next.Door.S03E06.DVDRip.XviD-WiDE", 3, 6)]
|
||||
[Row("Degrassi.S10E27.WS.DSR.XviD-2HD", 10, 27)]
|
||||
public void episode_parse(string path, int season, int episode)
|
||||
[Description("Verifies that a file with no episode is skipped")]
|
||||
public void import_file_with_no_episode()
|
||||
{
|
||||
var result = Parser.ParseEpisodeInfo(path);
|
||||
Assert.Count(1, result);
|
||||
Assert.AreEqual(season, result[0].SeasonNumber);
|
||||
Assert.AreEqual(episode, result[0].EpisodeNumber);
|
||||
//Arrange
|
||||
/////////////////////////////////////////
|
||||
|
||||
//Constants
|
||||
const string fileName = "WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD.avi";
|
||||
const int seasonNumber = 3;
|
||||
const int episodeNumner = 01;
|
||||
|
||||
//Fakes
|
||||
var fakeSeries = Builder<Series>.CreateNew().Build();
|
||||
|
||||
//Mocks
|
||||
var repository = new Mock<IRepository>(MockBehavior.Strict);
|
||||
repository.Setup(r => r.Exists<EpisodeFile>(It.IsAny<Expression<Func<EpisodeFile, Boolean>>>())).Returns(false).Verifiable();
|
||||
|
||||
var episodeProvider = new Mock<IEpisodeProvider>(MockBehavior.Strict);
|
||||
episodeProvider.Setup(e => e.GetEpisode(fakeSeries.SeriesId, seasonNumber, episodeNumner)).Returns<Episode>(null).Verifiable();
|
||||
|
||||
var diskProvider = new Mock<IDiskProvider>(MockBehavior.Strict);
|
||||
|
||||
|
||||
var kernel = new MockingKernel();
|
||||
kernel.Bind<IRepository>().ToConstant(repository.Object);
|
||||
kernel.Bind<IEpisodeProvider>().ToConstant(episodeProvider.Object);
|
||||
kernel.Bind<IDiskProvider>().ToConstant(diskProvider.Object);
|
||||
kernel.Bind<IMediaFileProvider>().To<MediaFileProvider>();
|
||||
|
||||
//Act
|
||||
var result = kernel.Get<IMediaFileProvider>().ImportFile(fakeSeries, fileName);
|
||||
|
||||
//Assert
|
||||
repository.VerifyAll();
|
||||
episodeProvider.VerifyAll();
|
||||
diskProvider.VerifyAll();
|
||||
Assert.IsNull(result);
|
||||
repository.Verify(r => r.Add<EpisodeFile>(result), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Row("WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD", QualityTypes.DVD)]
|
||||
[Row("WEEDS.S03E01-06.DUAL.BDRip.AC3.-HELLYWOOD", QualityTypes.Bluray)]
|
||||
[Row("Two.and.a.Half.Men.S08E05.720p.HDTV.X264-DIMENSION", QualityTypes.HDTV)]
|
||||
[Row("Chuck.S04E05.HDTV.XviD-LOL", QualityTypes.TV)]
|
||||
[Row("The.Girls.Next.Door.S03E06.DVDRip.XviD-WiDE", QualityTypes.DVD)]
|
||||
[Row("Degrassi.S10E27.WS.DSR.XviD-2HD", QualityTypes.TV)]
|
||||
[Row("Sonny.With.a.Chance.S02E15.720p.WEB-DL.DD5.1.H.264-SURFER", QualityTypes.WEBDL)]
|
||||
[Row("Sonny.With.a.Chance.S02E15.720p", QualityTypes.HDTV)]
|
||||
[Row("Sonny.With.a.Chance.S02E15.mkv", QualityTypes.HDTV)]
|
||||
[Row("Sonny.With.a.Chance.S02E15.avi", QualityTypes.TV)]
|
||||
[Row("Sonny.With.a.Chance.S02E15.xvid", QualityTypes.TV)]
|
||||
[Row("Sonny.With.a.Chance.S02E15.divx", QualityTypes.TV)]
|
||||
[Row("Sonny.With.a.Chance.S02E15", QualityTypes.Unknown)]
|
||||
|
||||
public void quality_parse(string path, object quality)
|
||||
{
|
||||
var result = Parser.ParseQuality(path);
|
||||
Assert.AreEqual(quality, result);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ using System.Text;
|
|||
using FizzWare.NBuilder;
|
||||
using Moq;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Instrumentation;
|
||||
using NzbDrone.Core.Providers;
|
||||
using SubSonic.DataProviders;
|
||||
using SubSonic.Repository;
|
||||
|
@ -32,10 +33,10 @@ namespace NzbDrone.Core.Test
|
|||
public static IRepository GetEmptyRepository(bool enableLogging)
|
||||
{
|
||||
Console.WriteLine("Creating an empty SQLite database");
|
||||
var provider = ProviderFactory.GetProvider("Data Source=" + Guid.NewGuid() + ".testdb;Version=3;New=True", "System.Data.SQLite");
|
||||
var provider = ProviderFactory.GetProvider("Data Source=" + Guid.NewGuid() + ".db;Version=3;New=True", "System.Data.SQLite");
|
||||
if (enableLogging)
|
||||
{
|
||||
provider.Log = new Instrumentation.NlogWriter();
|
||||
provider.Log = new NlogWriter();
|
||||
provider.LogParams = true;
|
||||
}
|
||||
return new SimpleRepository(provider, SimpleRepositoryOptions.RunMigrations);
|
||||
|
@ -55,7 +56,7 @@ namespace NzbDrone.Core.Test
|
|||
{
|
||||
var mock = new Mock<IDiskProvider>();
|
||||
mock.Setup(c => c.GetDirectories(It.IsAny<String>())).Returns(StandardSeries);
|
||||
mock.Setup(c => c.Exists(It.Is<String>(d => StandardSeries.Contains(d)))).Returns(true);
|
||||
mock.Setup(c => c.FolderExists(It.Is<String>(d => StandardSeries.Contains(d)))).Returns(true);
|
||||
|
||||
|
||||
foreach (var series in StandardSeries)
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
<Compile Include="Ninject.Moq\ExtensionsForBindingSyntax.cs" />
|
||||
<Compile Include="Ninject.Moq\MockingKernel.cs" />
|
||||
<Compile Include="Ninject.Moq\MockProvider.cs" />
|
||||
<Compile Include="ParserTest.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="QualityProfileTest.cs" />
|
||||
<Compile Include="RepoTest.cs" />
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Gallio.Framework;
|
||||
using MbUnit.Framework;
|
||||
using MbUnit.Framework.ContractVerifiers;
|
||||
using NzbDrone.Core.Repository.Quality;
|
||||
|
||||
namespace NzbDrone.Core.Test
|
||||
{
|
||||
[TestFixture]
|
||||
// ReSharper disable InconsistentNaming
|
||||
public class ParserTest
|
||||
{
|
||||
[Test]
|
||||
[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("Chuck.4x05.HDTV.XviD-LOL", 4, 5)]
|
||||
[Row("The.Girls.Next.Door.S03E06.DVDRip.XviD-WiDE", 3, 6)]
|
||||
[Row("Degrassi.S10E27.WS.DSR.XviD-2HD", 10, 27)]
|
||||
public void episode_parse(string path, int season, int episode)
|
||||
{
|
||||
var result = Parser.ParseEpisodeInfo(path);
|
||||
Assert.Count(1, result);
|
||||
Assert.AreEqual(season, result[0].SeasonNumber);
|
||||
Assert.AreEqual(episode, result[0].EpisodeNumber);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Row("WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD", QualityTypes.DVD)]
|
||||
[Row("WEEDS.S03E01-06.DUAL.BDRip.AC3.-HELLYWOOD", QualityTypes.Bluray)]
|
||||
[Row("Two.and.a.Half.Men.S08E05.720p.HDTV.X264-DIMENSION", QualityTypes.HDTV)]
|
||||
[Row("Chuck.S04E05.HDTV.XviD-LOL", QualityTypes.TV)]
|
||||
[Row("The.Girls.Next.Door.S03E06.DVDRip.XviD-WiDE", QualityTypes.DVD)]
|
||||
[Row("Degrassi.S10E27.WS.DSR.XviD-2HD", QualityTypes.TV)]
|
||||
[Row("Sonny.With.a.Chance.S02E15.720p.WEB-DL.DD5.1.H.264-SURFER", QualityTypes.WEBDL)]
|
||||
[Row("Sonny.With.a.Chance.S02E15.720p", QualityTypes.HDTV)]
|
||||
[Row("Sonny.With.a.Chance.S02E15.mkv", QualityTypes.HDTV)]
|
||||
[Row("Sonny.With.a.Chance.S02E15.avi", QualityTypes.TV)]
|
||||
[Row("Sonny.With.a.Chance.S02E15.xvid", QualityTypes.TV)]
|
||||
[Row("Sonny.With.a.Chance.S02E15.divx", QualityTypes.TV)]
|
||||
[Row("Sonny.With.a.Chance.S02E15", QualityTypes.Unknown)]
|
||||
public void quality_parse(string path, object quality)
|
||||
{
|
||||
var result = Parser.ParseQuality(path);
|
||||
Assert.AreEqual(quality, result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Row(@"c:\test\", @"c:\test")]
|
||||
[Row(@"c:\\test\\", @"c:\test")]
|
||||
[Row(@"C:\\Test\\", @"c:\test")]
|
||||
[Row(@"C:\\Test\\Test\", @"c:\test\test")]
|
||||
public void Normalize_Path(string dirty, string clean)
|
||||
{
|
||||
var result = Parser.NormalizePath(dirty);
|
||||
Assert.AreEqual(clean, result);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,8 +6,13 @@ using FizzWare.NBuilder;
|
|||
using Gallio.Framework;
|
||||
using MbUnit.Framework;
|
||||
using MbUnit.Framework.ContractVerifiers;
|
||||
using Ninject;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Instrumentation;
|
||||
using NzbDrone.Core.Model;
|
||||
using NzbDrone.Core.Repository;
|
||||
using LogLevel = NzbDrone.Core.Instrumentation.LogLevel;
|
||||
using NLog.Config;
|
||||
|
||||
namespace NzbDrone.Core.Test
|
||||
{
|
||||
|
@ -62,5 +67,69 @@ namespace NzbDrone.Core.Test
|
|||
Console.WriteLine(new Episode().ToString());
|
||||
Console.WriteLine(new EpisodeModel().ToString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void write_log()
|
||||
{
|
||||
//setup
|
||||
var message = Guid.NewGuid().ToString();
|
||||
|
||||
var sonicRepo = MockLib.GetEmptyRepository();
|
||||
|
||||
var sonicTarget = new SubsonicTarget(sonicRepo);
|
||||
LogManager.Configuration.AddTarget("DbLogger", sonicTarget);
|
||||
LogManager.Configuration.LoggingRules.Add(new LoggingRule("*", NLog.LogLevel.Info, sonicTarget));
|
||||
LogManager.Configuration.Reload();
|
||||
|
||||
Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
//Act
|
||||
|
||||
Logger.Info(message);
|
||||
|
||||
//Assert
|
||||
Assert.IsNotEmpty(sonicRepo.All<Log>());
|
||||
Assert.Count(1, sonicRepo.All<Log>());
|
||||
|
||||
var logItem = sonicRepo.All<Log>().First();
|
||||
Assert.AreNotEqual(new DateTime(), logItem.Time);
|
||||
Assert.AreEqual(message, logItem.Message);
|
||||
Assert.AreEqual(Logger.Name, logItem.Logger);
|
||||
Assert.AreEqual(Logger.Name, logItem.Logger);
|
||||
Assert.AreEqual(LogLevel.Info, logItem.Level);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void write_log_exception()
|
||||
{
|
||||
//setup
|
||||
var message = Guid.NewGuid().ToString();
|
||||
|
||||
var sonicRepo = MockLib.GetEmptyRepository();
|
||||
|
||||
var sonicTarget = new SubsonicTarget(sonicRepo);
|
||||
LogManager.Configuration.AddTarget("DbLogger", sonicTarget);
|
||||
LogManager.Configuration.LoggingRules.Add(new LoggingRule("*", NLog.LogLevel.Info, sonicTarget));
|
||||
LogManager.Configuration.Reload();
|
||||
|
||||
Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
var ex = new InvalidOperationException("Fake Exception");
|
||||
//Act
|
||||
|
||||
Logger.ErrorException(message, ex);
|
||||
|
||||
//Assert
|
||||
Assert.IsNotEmpty(sonicRepo.All<Log>());
|
||||
Assert.Count(1, sonicRepo.All<Log>());
|
||||
|
||||
var logItem = sonicRepo.All<Log>().First();
|
||||
Assert.AreNotEqual(new DateTime(), logItem.Time);
|
||||
Assert.AreEqual(message, logItem.Message);
|
||||
Assert.AreEqual(Logger.Name, logItem.Logger);
|
||||
Assert.AreEqual(LogLevel.Error, logItem.Level);
|
||||
Assert.AreEqual(ex.GetType().ToString(), logItem.ExceptionType);
|
||||
Assert.AreEqual(ex.ToString(), logItem.ExceptionString);
|
||||
Assert.AreEqual(ex.Message, logItem.ExceptionMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ using System.Web;
|
|||
using Ninject;
|
||||
using NLog.Config;
|
||||
using NLog.Targets;
|
||||
using NzbDrone.Core.Instrumentation;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.Providers.Fakes;
|
||||
using NzbDrone.Core.Repository;
|
||||
|
@ -29,10 +30,15 @@ namespace NzbDrone.Core
|
|||
_kernel = new StandardKernel();
|
||||
|
||||
string connectionString = String.Format("Data Source={0};Version=3;", Path.Combine(AppPath, "nzbdrone.db"));
|
||||
var provider = ProviderFactory.GetProvider(connectionString, "System.Data.SQLite");
|
||||
provider.Log = new Instrumentation.NlogWriter();
|
||||
provider.LogParams = true;
|
||||
var dbProvider = ProviderFactory.GetProvider(connectionString, "System.Data.SQLite");
|
||||
|
||||
string logConnectionString = String.Format("Data Source={0};Version=3;", Path.Combine(AppPath, "log.db"));
|
||||
var logDbProvider = ProviderFactory.GetProvider(logConnectionString, "System.Data.SQLite");
|
||||
var logRepository = new SimpleRepository(logDbProvider, SimpleRepositoryOptions.RunMigrations);
|
||||
|
||||
dbProvider.Log = new NlogWriter();
|
||||
dbProvider.LogParams = true;
|
||||
|
||||
_kernel.Bind<ISeriesProvider>().To<SeriesProvider>().InSingletonScope();
|
||||
_kernel.Bind<ISeasonProvider>().To<SeasonProvider>();
|
||||
_kernel.Bind<IEpisodeProvider>().To<EpisodeProvider>();
|
||||
|
@ -41,7 +47,12 @@ namespace NzbDrone.Core
|
|||
_kernel.Bind<IConfigProvider>().To<ConfigProvider>().InSingletonScope();
|
||||
_kernel.Bind<ISyncProvider>().To<SyncProvider>().InSingletonScope();
|
||||
_kernel.Bind<INotificationProvider>().To<NotificationProvider>().InSingletonScope();
|
||||
_kernel.Bind<IRepository>().ToMethod(c => new SimpleRepository(provider, SimpleRepositoryOptions.RunMigrations)).InSingletonScope();
|
||||
_kernel.Bind<ILogProvider>().To<LogProvider>().InSingletonScope();
|
||||
_kernel.Bind<IRepository>().ToMethod(c => new SimpleRepository(dbProvider, SimpleRepositoryOptions.RunMigrations)).InSingletonScope();
|
||||
|
||||
_kernel.Bind<IRepository>().ToConstant(logRepository).WhenInjectedInto<SubsonicTarget>().InSingletonScope();
|
||||
_kernel.Bind<IRepository>().ToConstant(logRepository).WhenInjectedInto<LogProvider>().InSingletonScope();
|
||||
|
||||
|
||||
ForceMigration(_kernel.Get<IRepository>());
|
||||
}
|
||||
|
@ -57,7 +68,6 @@ namespace NzbDrone.Core
|
|||
}
|
||||
return Directory.GetCurrentDirectory();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static IKernel NinjectKernel
|
||||
|
@ -75,6 +85,7 @@ namespace NzbDrone.Core
|
|||
private static void ForceMigration(IRepository repository)
|
||||
{
|
||||
repository.GetPaged<Series>(0, 1);
|
||||
repository.GetPaged<EpisodeFile>(0, 1);
|
||||
repository.GetPaged<Episode>(0, 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,86 +0,0 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Exceptioneer.WindowsFormsClient;
|
||||
using NLog;
|
||||
using NLog.Config;
|
||||
using NLog.Targets;
|
||||
|
||||
namespace NzbDrone.Core
|
||||
{
|
||||
public static class Instrumentation
|
||||
{
|
||||
public static void Setup()
|
||||
{
|
||||
if (Debugger.IsAttached)
|
||||
{
|
||||
LogManager.ThrowExceptions = true;
|
||||
}
|
||||
|
||||
LogManager.Configuration = new XmlLoggingConfiguration(Path.Combine(CentralDispatch.AppPath, "log.config"), false);
|
||||
LogManager.ConfigurationReloaded += ((s, e) => BindExceptioneer());
|
||||
BindExceptioneer();
|
||||
}
|
||||
|
||||
private static void BindExceptioneer()
|
||||
{
|
||||
var exTarget = new ExceptioneerTarget();
|
||||
LogManager.Configuration.AddTarget("Exceptioneer", exTarget);
|
||||
LogManager.Configuration.LoggingRules.Add(new LoggingRule("*", LogLevel.Error, exTarget));
|
||||
LogManager.Configuration.Reload();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class NlogWriter : TextWriter
|
||||
{
|
||||
private static readonly Logger Logger = LogManager.GetLogger("DB");
|
||||
|
||||
|
||||
public override void Write(char[] buffer, int index, int count)
|
||||
{
|
||||
Write(new string(buffer, index, count));
|
||||
}
|
||||
|
||||
public override void Write(string value)
|
||||
{
|
||||
DbAction(value);
|
||||
}
|
||||
|
||||
private static void DbAction(string value)
|
||||
{
|
||||
Logger.Trace(value);
|
||||
}
|
||||
|
||||
public override Encoding Encoding
|
||||
{
|
||||
get { return Encoding.Default; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class ExceptioneerTarget : Target
|
||||
{
|
||||
protected override void Write(LogEventInfo logEvent)
|
||||
{
|
||||
if (logEvent.Exception == null)
|
||||
throw new InvalidOperationException(@"Missing Exception Object.. Please Use Logger.FatalException() or Logger.ErrorException() rather
|
||||
than Logger.Fatal() and Logger.Error()");
|
||||
|
||||
if (!Debugger.IsAttached)
|
||||
{
|
||||
new Client
|
||||
{
|
||||
ApiKey = "43BBF60A-EB2A-4C1C-B09E-422ADF637265",
|
||||
ApplicationName = "NZBDrone",
|
||||
CurrentException = logEvent.Exception
|
||||
}.Submit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using Exceptioneer.WindowsFormsClient;
|
||||
using NLog;
|
||||
using NLog.Targets;
|
||||
|
||||
namespace NzbDrone.Core.Instrumentation
|
||||
{
|
||||
public class ExceptioneerTarget : Target
|
||||
{
|
||||
protected override void Write(LogEventInfo logEvent)
|
||||
{
|
||||
if (logEvent.Exception == null)
|
||||
throw new InvalidOperationException(@"Missing Exception Object.. Please Use Logger.FatalException() or Logger.ErrorException() rather
|
||||
than Logger.Fatal() and Logger.Error()");
|
||||
|
||||
if (!Debugger.IsAttached)
|
||||
{
|
||||
new Client
|
||||
{
|
||||
ApiKey = "43BBF60A-EB2A-4C1C-B09E-422ADF637265",
|
||||
ApplicationName = "NZBDrone",
|
||||
CurrentException = logEvent.Exception
|
||||
}.Submit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace NzbDrone.Core.Instrumentation
|
||||
{
|
||||
public interface ILogProvider
|
||||
{
|
||||
IQueryable<Log> GetAllLogs();
|
||||
void DeleteAll();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
using SubSonic.SqlGeneration.Schema;
|
||||
|
||||
namespace NzbDrone.Core.Instrumentation
|
||||
{
|
||||
public class Log
|
||||
{
|
||||
public int LogId { get; set; }
|
||||
public string Message { get; set; }
|
||||
public DateTime Time { get; set; }
|
||||
public string Logger { get; set; }
|
||||
|
||||
[SubSonicNullString]
|
||||
public string Stack { get; set; }
|
||||
[SubSonicNullString]
|
||||
public string ExceptionMessage { get; set; }
|
||||
[SubSonicNullString]
|
||||
public string ExceptionString { get; set; }
|
||||
[SubSonicNullString]
|
||||
public string ExceptionType { get; set; }
|
||||
|
||||
public LogLevel Level { get; set; }
|
||||
|
||||
//This is needed for telerik grid binding
|
||||
[SubSonicIgnore]
|
||||
public string DisplayLevel{
|
||||
get { return Level.ToString(); }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using NLog;
|
||||
using NLog.Config;
|
||||
using Ninject;
|
||||
|
||||
namespace NzbDrone.Core.Instrumentation
|
||||
{
|
||||
public static class LogConfiguration
|
||||
{
|
||||
public static void Setup()
|
||||
{
|
||||
if (Debugger.IsAttached)
|
||||
{
|
||||
LogManager.ThrowExceptions = true;
|
||||
}
|
||||
|
||||
LogManager.Configuration = new XmlLoggingConfiguration(Path.Combine(CentralDispatch.AppPath, "log.config"), false);
|
||||
LogManager.ConfigurationReloaded += ((s, e) => BindCustomLoggers());
|
||||
BindCustomLoggers();
|
||||
}
|
||||
|
||||
private static void BindCustomLoggers()
|
||||
{
|
||||
var exTarget = new ExceptioneerTarget();
|
||||
LogManager.Configuration.AddTarget("Exceptioneer", exTarget);
|
||||
LogManager.Configuration.LoggingRules.Add(new LoggingRule("*", NLog.LogLevel.Error, exTarget));
|
||||
|
||||
var sonicTarget = CentralDispatch.NinjectKernel.Get<SubsonicTarget>();
|
||||
LogManager.Configuration.AddTarget("DbLogger", sonicTarget);
|
||||
LogManager.Configuration.LoggingRules.Add(new LoggingRule("*", NLog.LogLevel.Info, sonicTarget));
|
||||
|
||||
LogManager.Configuration.Reload();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
namespace NzbDrone.Core.Instrumentation
|
||||
{
|
||||
public enum LogLevel
|
||||
{
|
||||
Trace,
|
||||
Debug,
|
||||
Info,
|
||||
Warn,
|
||||
Error,
|
||||
Fatal
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using NLog;
|
||||
using SubSonic.Repository;
|
||||
|
||||
namespace NzbDrone.Core.Instrumentation
|
||||
{
|
||||
|
||||
public class LogProvider : ILogProvider
|
||||
{
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
private readonly IRepository _repository;
|
||||
|
||||
public LogProvider(IRepository repository)
|
||||
{
|
||||
_repository = repository;
|
||||
}
|
||||
|
||||
public IQueryable<Log> GetAllLogs()
|
||||
{
|
||||
return _repository.All<Log>();
|
||||
}
|
||||
|
||||
public void DeleteAll()
|
||||
{
|
||||
_repository.DeleteMany(GetAllLogs());
|
||||
Logger.Info("Cleared Log History");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
using System.IO;
|
||||
using System.Text;
|
||||
using NLog;
|
||||
|
||||
namespace NzbDrone.Core.Instrumentation
|
||||
{
|
||||
public class NlogWriter : TextWriter
|
||||
{
|
||||
private static readonly Logger Logger = LogManager.GetLogger("DB");
|
||||
|
||||
|
||||
public override void Write(char[] buffer, int index, int count)
|
||||
{
|
||||
Write(new string(buffer, index, count));
|
||||
}
|
||||
|
||||
public override void Write(string value)
|
||||
{
|
||||
DbAction(value);
|
||||
}
|
||||
|
||||
private static void DbAction(string value)
|
||||
{
|
||||
Logger.Trace(value);
|
||||
}
|
||||
|
||||
public override Encoding Encoding
|
||||
{
|
||||
get { return Encoding.Default; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using Exceptioneer.WindowsFormsClient;
|
||||
using NLog;
|
||||
using NLog.Targets;
|
||||
using SubSonic.Repository;
|
||||
using Ninject;
|
||||
using NzbDrone.Core.Repository;
|
||||
|
||||
namespace NzbDrone.Core.Instrumentation
|
||||
{
|
||||
public class SubsonicTarget : Target
|
||||
{
|
||||
private readonly IRepository _repo;
|
||||
|
||||
public SubsonicTarget(IRepository repo)
|
||||
{
|
||||
_repo = repo;
|
||||
}
|
||||
|
||||
protected override void Write(LogEventInfo logEvent)
|
||||
{
|
||||
var log = new Log();
|
||||
log.Time = logEvent.TimeStamp;
|
||||
log.Message = logEvent.FormattedMessage;
|
||||
|
||||
if (log.Stack != null)
|
||||
{
|
||||
log.Stack = logEvent.StackTrace.ToString();
|
||||
}
|
||||
|
||||
log.Logger = logEvent.LoggerName;
|
||||
|
||||
if (logEvent.Exception != null)
|
||||
{
|
||||
log.ExceptionMessage = logEvent.Exception.Message;
|
||||
log.ExceptionString = logEvent.Exception.ToString();
|
||||
log.ExceptionType = logEvent.Exception.GetType().ToString();
|
||||
}
|
||||
|
||||
switch (logEvent.Level.Name.ToLower())
|
||||
{
|
||||
case "trace":
|
||||
{
|
||||
log.Level = LogLevel.Trace;
|
||||
break;
|
||||
}
|
||||
case "debug":
|
||||
{
|
||||
log.Level = LogLevel.Debug;
|
||||
break;
|
||||
}
|
||||
case "info":
|
||||
{
|
||||
log.Level = LogLevel.Info;
|
||||
break;
|
||||
}
|
||||
case "warn":
|
||||
{
|
||||
log.Level = LogLevel.Warn;
|
||||
break;
|
||||
}
|
||||
case "error":
|
||||
{
|
||||
log.Level = LogLevel.Error;
|
||||
break;
|
||||
}
|
||||
case "fatal":
|
||||
{
|
||||
log.Level = LogLevel.Fatal;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_repo.Add(log);
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -150,13 +150,19 @@
|
|||
<Reference Include="UPnP, Version=1.0.3932.37442, Culture=neutral, processorArchitecture=MSIL" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Instrumentation\ILogProvider.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="Model\EpisodeParseResult.cs" />
|
||||
<Compile Include="Model\EpisodeModel.cs" />
|
||||
<Compile Include="Repository\EpisodeFile.cs" />
|
||||
<Compile Include="Model\Notification\BasicNotification.cs" />
|
||||
<Compile Include="Model\Notification\ProgressNotificationStatus.cs" />
|
||||
<Compile Include="Model\Notification\BasicNotificationType.cs" />
|
||||
<Compile Include="Instrumentation.cs" />
|
||||
<Compile Include="Instrumentation\LogConfiguration.cs" />
|
||||
<Compile Include="Parser.cs" />
|
||||
<Compile Include="Providers\Fakes\FakeNotificationProvider.cs" />
|
||||
<Compile Include="Providers\IMediaFileProvider.cs" />
|
||||
|
@ -182,6 +188,7 @@
|
|||
<Compile Include="Providers\SabProvider.cs" />
|
||||
<Compile Include="Providers\SeasonProvider.cs" />
|
||||
<Compile Include="Repository\Episode.cs" />
|
||||
<Compile Include="Instrumentation\Log.cs" />
|
||||
<Compile Include="Repository\Quality\AllowedQuality.cs" />
|
||||
<Compile Include="Repository\Config.cs" />
|
||||
<Compile Include="Repository\Quality\QualityProfile.cs" />
|
||||
|
|
|
@ -131,5 +131,12 @@ namespace NzbDrone.Core
|
|||
{
|
||||
return NormalizeRegex.Replace(title, String.Empty).ToLower();
|
||||
}
|
||||
|
||||
public static string NormalizePath(string path)
|
||||
{
|
||||
if (String.IsNullOrEmpty(path))
|
||||
throw new ArgumentException("Path can not be null or empty");
|
||||
return new FileInfo(path).FullName.ToLower().Trim('/', '\\', ' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,11 +7,16 @@ namespace NzbDrone.Core.Providers
|
|||
{
|
||||
#region IDiskProvider Members
|
||||
|
||||
public bool Exists(string path)
|
||||
public bool FolderExists(string path)
|
||||
{
|
||||
return Directory.Exists(path);
|
||||
}
|
||||
|
||||
public bool FileExists(string path)
|
||||
{
|
||||
return File.Exists(path);
|
||||
}
|
||||
|
||||
public string[] GetDirectories(string path)
|
||||
{
|
||||
return Directory.GetDirectories(path);
|
||||
|
@ -22,18 +27,16 @@ namespace NzbDrone.Core.Providers
|
|||
return Directory.GetFiles(path, pattern, searchOption);
|
||||
}
|
||||
|
||||
public long GetSize(string path)
|
||||
{
|
||||
return new FileInfo(path).Length;
|
||||
}
|
||||
|
||||
public String CreateDirectory(string path)
|
||||
{
|
||||
return Directory.CreateDirectory(path).FullName;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public static string CleanPath(string path)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path))
|
||||
throw new ArgumentException("Path can not be null or empty");
|
||||
return path.ToLower().Trim('/', '\\', ' ');
|
||||
}
|
||||
}
|
||||
}
|
|
@ -30,7 +30,12 @@ namespace NzbDrone.Core.Providers
|
|||
|
||||
public Episode GetEpisode(long id)
|
||||
{
|
||||
return _sonicRepo.Single<Episode>(e => e.EpisodeId == id);
|
||||
return _sonicRepo.Single<Episode>(id);
|
||||
}
|
||||
|
||||
public Episode GetEpisode(int seriesId, int seasonNumber, int episodeNumber)
|
||||
{
|
||||
return _sonicRepo.Single<Episode>(c => c.SeriesId == seriesId && c.SeasonNumber == seasonNumber && c.EpisodeNumber == episodeNumber);
|
||||
}
|
||||
|
||||
public IList<Episode> GetEpisodeBySeries(long seriesId)
|
||||
|
|
|
@ -5,9 +5,11 @@ namespace NzbDrone.Core.Providers
|
|||
{
|
||||
public interface IDiskProvider
|
||||
{
|
||||
bool Exists(string path);
|
||||
bool FolderExists(string path);
|
||||
string[] GetDirectories(string path);
|
||||
String CreateDirectory(string path);
|
||||
string[] GetFiles(string path, string pattern, SearchOption searchOption);
|
||||
bool FileExists(string path);
|
||||
long GetSize(string path);
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ namespace NzbDrone.Core.Providers
|
|||
public interface IEpisodeProvider
|
||||
{
|
||||
Episode GetEpisode(long id);
|
||||
Episode GetEpisode(int seriesId, int seasonNumber, int episodeNumber);
|
||||
IList<Episode> GetEpisodeBySeries(long seriesId);
|
||||
String GetSabTitle(Episode episode);
|
||||
|
||||
|
|
|
@ -9,5 +9,7 @@ namespace NzbDrone.Core.Providers
|
|||
/// </summary>
|
||||
/// <param name="series">The series to be scanned</param>
|
||||
void Scan(Series series);
|
||||
|
||||
EpisodeFile ImportFile(Series series, string filePath);
|
||||
}
|
||||
}
|
|
@ -5,22 +5,24 @@ using System.Linq;
|
|||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Model;
|
||||
using NzbDrone.Core.Repository;
|
||||
using SubSonic.Repository;
|
||||
|
||||
namespace NzbDrone.Core.Providers
|
||||
{
|
||||
public class MediaFileProvider : IMediaFileProvider
|
||||
{
|
||||
|
||||
|
||||
private readonly IRepository _repository;
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly IEpisodeProvider _episodeProvider;
|
||||
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
private static readonly string[] MediaExtentions = new[] { "*.mkv", "*.avi", "*.wmv" };
|
||||
|
||||
public MediaFileProvider(IDiskProvider diskProvider, IEpisodeProvider episodeProvider)
|
||||
public MediaFileProvider(IRepository repository, IDiskProvider diskProvider, IEpisodeProvider episodeProvider)
|
||||
{
|
||||
_repository = repository;
|
||||
_diskProvider = diskProvider;
|
||||
_episodeProvider = episodeProvider;
|
||||
}
|
||||
|
@ -31,19 +33,82 @@ namespace NzbDrone.Core.Providers
|
|||
/// <param name="series">The series to be scanned</param>
|
||||
public void Scan(Series series)
|
||||
{
|
||||
var mediaFileList = GetMediaFileList(series.Path);
|
||||
|
||||
foreach (var filePath in mediaFileList)
|
||||
{
|
||||
ImportFile(series, filePath);
|
||||
}
|
||||
}
|
||||
|
||||
public EpisodeFile ImportFile(Series series, string filePath)
|
||||
{
|
||||
Logger.Trace("Importing file to database [{0}]", filePath);
|
||||
|
||||
if (!_repository.Exists<EpisodeFile>(e => e.Path == Parser.NormalizePath(filePath)))
|
||||
{
|
||||
var episodesInFile = Parser.ParseEpisodeInfo(filePath);
|
||||
|
||||
foreach (var parsedEpisode in episodesInFile)
|
||||
{
|
||||
EpisodeParseResult closureEpisode = parsedEpisode;
|
||||
var episode = _episodeProvider.GetEpisode(series.SeriesId, closureEpisode.SeasonNumber, closureEpisode.EpisodeNumber);
|
||||
if (episode != null)
|
||||
{
|
||||
var epFile = new EpisodeFile();
|
||||
epFile.DateAdded = DateTime.Now;
|
||||
epFile.SeriesId = series.SeriesId;
|
||||
epFile.EpisodeId = episode.EpisodeId;
|
||||
epFile.Path = Parser.NormalizePath(filePath);
|
||||
epFile.Size = _diskProvider.GetSize(filePath);
|
||||
epFile.Quality = Parser.ParseQuality(filePath);
|
||||
epFile.Proper = Parser.ParseProper(filePath);
|
||||
_repository.Add(epFile);
|
||||
Logger.Info("File '{0}' successfully attached to {1}", episode.EpisodeId);
|
||||
|
||||
return epFile;
|
||||
}
|
||||
|
||||
Logger.Warn("Unable to find Series:{0} Season:{1} Episode:{2} in the database.", series.Title, closureEpisode.SeasonNumber, closureEpisode.EpisodeNumber);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Trace("[{0}] already exists in the database. skipping.", filePath);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes files that no longer exist from the database
|
||||
/// </summary>
|
||||
/// <param name="files">list of files to verify</param>
|
||||
public void CleanUp(List<EpisodeFile> files)
|
||||
{
|
||||
foreach (var episodeFile in files)
|
||||
{
|
||||
if (!_diskProvider.FileExists(episodeFile.Path))
|
||||
{
|
||||
Logger.Trace("File {0} no longer exists on disk. removing from database.", episodeFile.Path);
|
||||
_repository.Delete<EpisodeFile>(episodeFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<string> GetMediaFileList(string path)
|
||||
{
|
||||
Logger.Info("Scanning '{0}' for episodes", path);
|
||||
|
||||
var mediaFileList = new List<string>();
|
||||
Logger.Info("Scanning '{0}'", series.Path);
|
||||
|
||||
foreach (var ext in MediaExtentions)
|
||||
{
|
||||
mediaFileList.AddRange(_diskProvider.GetFiles(series.Path, ext, SearchOption.AllDirectories));
|
||||
mediaFileList.AddRange(_diskProvider.GetFiles(path, ext, SearchOption.AllDirectories));
|
||||
}
|
||||
|
||||
Logger.Info("{0} media files were found", mediaFileList.Count);
|
||||
|
||||
foreach (var file in mediaFileList)
|
||||
{
|
||||
var episode = Parser.ParseEpisodeInfo(file);
|
||||
}
|
||||
Logger.Info("{0} media files were found in {1}", mediaFileList.Count, path);
|
||||
return mediaFileList;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ namespace NzbDrone.Core.Providers
|
|||
var results = new List<String>();
|
||||
foreach (string seriesFolder in _diskProvider.GetDirectories(_config.SeriesRoot))
|
||||
{
|
||||
var cleanPath = DiskProvider.CleanPath(new DirectoryInfo(seriesFolder).FullName);
|
||||
var cleanPath = Parser.NormalizePath(new DirectoryInfo(seriesFolder).FullName);
|
||||
if (!_sonioRepo.Exists<Series>(s => s.Path == cleanPath))
|
||||
{
|
||||
results.Add(cleanPath);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using SubSonic.SqlGeneration.Schema;
|
||||
|
||||
namespace NzbDrone.Core.Repository
|
||||
|
@ -16,14 +17,13 @@ namespace NzbDrone.Core.Repository
|
|||
public string Overview { get; set; }
|
||||
public string Language { get; set; }
|
||||
|
||||
[SubSonicNullString]
|
||||
public string Path { get; set; }
|
||||
public long? Size { get; set; }
|
||||
|
||||
[SubSonicToOneRelation(ThisClassContainsJoinKey = true)]
|
||||
public virtual Season Season { get; set; }
|
||||
|
||||
[SubSonicToOneRelation(ThisClassContainsJoinKey = true)]
|
||||
public virtual Series Series { get; private set; }
|
||||
|
||||
[SubSonicToManyRelation]
|
||||
public virtual List<EpisodeFile> Files { get; private set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,18 +4,19 @@ using SubSonic.SqlGeneration.Schema;
|
|||
|
||||
namespace NzbDrone.Core.Repository
|
||||
{
|
||||
class EpisodeFile
|
||||
public class EpisodeFile
|
||||
{
|
||||
[SubSonicPrimaryKey]
|
||||
public virtual int FileId { get; set; }
|
||||
public int EpisodeId { get; set; }
|
||||
public int SeriesId { get; set; }
|
||||
public string Path { get; set; }
|
||||
public QualityTypes Quality { get; set; }
|
||||
public bool Proper { get; set; }
|
||||
public long Size { get; set; }
|
||||
public DateTime DateAdded { get; set; }
|
||||
|
||||
[SubSonicToOneRelation]
|
||||
[SubSonicToOneRelation(ThisClassContainsJoinKey = true)]
|
||||
public virtual Episode Episode { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ namespace NzbDrone.Core.Repository
|
|||
[SubSonicToManyRelation]
|
||||
public virtual List<Episode> Episodes { get; private set; }
|
||||
|
||||
|
||||
[SubSonicToManyRelation]
|
||||
public virtual List<EpisodeFile> Files { get; private set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using NzbDrone.Core.Instrumentation;
|
||||
using SubSonic.Repository;
|
||||
using Telerik.Web.Mvc;
|
||||
|
||||
namespace NzbDrone.Web.Controllers
|
||||
{
|
||||
public class LogController : Controller
|
||||
{
|
||||
private readonly ILogProvider _logProvider;
|
||||
|
||||
public LogController(ILogProvider logProvider)
|
||||
{
|
||||
_logProvider = logProvider;
|
||||
}
|
||||
|
||||
public ActionResult Index()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
|
||||
public ActionResult Clear()
|
||||
{
|
||||
_logProvider.DeleteAll();
|
||||
return RedirectToAction("Index");
|
||||
|
||||
}
|
||||
|
||||
[GridAction]
|
||||
public ActionResult _AjaxBinding()
|
||||
{
|
||||
return View(new GridModel(_logProvider.GetAllLogs()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -34,7 +34,7 @@ namespace NzbDrone.Web.Controllers
|
|||
_configProvider.SeriesRoot = model.TvFolder;
|
||||
//return RedirectToAction("index");
|
||||
}
|
||||
return View(model);
|
||||
return RedirectToAction("index", "series");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@ using Ninject;
|
|||
using Ninject.Web.Mvc;
|
||||
using NLog;
|
||||
using NzbDrone.Core;
|
||||
using NzbDrone.Core.Instrumentation;
|
||||
using SubSonic.Repository;
|
||||
|
||||
namespace NzbDrone.Web
|
||||
{
|
||||
|
@ -30,7 +32,8 @@ namespace NzbDrone.Web
|
|||
|
||||
protected override void OnApplicationStarted()
|
||||
{
|
||||
Instrumentation.Setup();
|
||||
LogConfiguration.Setup();
|
||||
Logger.Info("NZBDrone Starting up.");
|
||||
CentralDispatch.DedicateToHost();
|
||||
AreaRegistration.RegisterAllAreas();
|
||||
RegisterRoutes(RouteTable.Routes);
|
||||
|
@ -39,7 +42,10 @@ namespace NzbDrone.Web
|
|||
|
||||
protected override IKernel CreateKernel()
|
||||
{
|
||||
return CentralDispatch.NinjectKernel;
|
||||
var kernel = CentralDispatch.NinjectKernel;
|
||||
// kernel.Bind<IRepository>().ToConstant(kernel.Get<IRepository>("LogDb"));
|
||||
|
||||
return kernel;
|
||||
}
|
||||
|
||||
// ReSharper disable InconsistentNaming
|
||||
|
|
|
@ -38,6 +38,9 @@
|
|||
<ItemGroup>
|
||||
<Reference Include="Ninject, Version=2.1.0.76, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL" />
|
||||
<Reference Include="NLog, Version=2.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL" />
|
||||
<Reference Include="SubSonic.Core, Version=3.0.0.3, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>D:\My Dropbox\Git\NzbDrone\NzbDrone.Core\Libraries\SubSonic.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
|
@ -74,6 +77,7 @@
|
|||
<ItemGroup>
|
||||
<Compile Include="Controllers\AccountController.cs" />
|
||||
<Compile Include="Controllers\HomeController.cs" />
|
||||
<Compile Include="Controllers\LogController.cs" />
|
||||
<Compile Include="Controllers\NotificationController.cs" />
|
||||
<Compile Include="Controllers\SeriesController.cs" />
|
||||
<Compile Include="Controllers\SettingsController.cs" />
|
||||
|
@ -209,7 +213,10 @@
|
|||
<Content Include="Scripts\jquery-ui-1.8.5.custom.min.js" />
|
||||
<Content Include="Scripts\jquery.jgrowl.js" />
|
||||
<Content Include="Scripts\Notification.js" />
|
||||
<Content Include="Views\Log\LogDetail.ascx" />
|
||||
<Content Include="Views\Log\Index.aspx" />
|
||||
<Content Include="Views\Series\Details.aspx" />
|
||||
<Content Include="Views\Series\EpisodeDetail.ascx" />
|
||||
<Content Include="Views\Series\index.aspx" />
|
||||
<Content Include="Views\Series\Unmapped.aspx" />
|
||||
<Content Include="Views\Settings\Index.aspx" />
|
||||
|
@ -244,6 +251,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="App_Data\" />
|
||||
<Folder Include="Views\Series\DisplayTemplates\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\NzbDrone.Core\NzbDrone.Core.csproj">
|
||||
|
@ -269,7 +277,15 @@
|
|||
<VisualStudio>
|
||||
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
|
||||
<WebProjectProperties>
|
||||
<SaveServerSettingsInUserFile>True</SaveServerSettingsInUserFile>
|
||||
<UseIIS>False</UseIIS>
|
||||
<AutoAssignPort>True</AutoAssignPort>
|
||||
<DevelopmentServerPort>21704</DevelopmentServerPort>
|
||||
<DevelopmentServerVPath>/</DevelopmentServerVPath>
|
||||
<IISUrl>http://localhost/NzbDrone</IISUrl>
|
||||
<NTLMAuthentication>False</NTLMAuthentication>
|
||||
<UseCustomServer>True</UseCustomServer>
|
||||
<CustomServerUrl>http://localhost:8989</CustomServerUrl>
|
||||
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
|
||||
</WebProjectProperties>
|
||||
</FlavorProperties>
|
||||
</VisualStudio>
|
||||
|
|
|
@ -5,7 +5,7 @@ $(function () {
|
|||
refreshNotifications();
|
||||
|
||||
var timer = window.setInterval(function () {
|
||||
speed = 1800;
|
||||
speed = 1000;
|
||||
refreshNotifications();
|
||||
}, 2000);
|
||||
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
|
||||
|
||||
<%@ Import Namespace="Telerik.Web.Mvc.UI" %>
|
||||
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
|
||||
Home Page
|
||||
Logs
|
||||
</asp:Content>
|
||||
<asp:Content ID="Menu" ContentPlaceHolderID="ActionMenu" runat="server">
|
||||
<%
|
||||
Html.Telerik().Menu().Name("logMenu").Items(items => items.Add().Text("Clear Logs").Action("Clear", "Log")).Render();
|
||||
%>
|
||||
</asp:Content>
|
||||
|
||||
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
|
||||
<h2><%: ViewData["Message"] %></h2>
|
||||
<h2>
|
||||
<%: ViewData["Message"] %></h2>
|
||||
<p>
|
||||
To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.
|
||||
To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">
|
||||
http://asp.net/mvc</a>.
|
||||
</p>
|
||||
</asp:Content>
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<NzbDrone.Core.Instrumentation.Log>>" %>
|
||||
|
||||
<%@ Import Namespace="Telerik.Web.Mvc.UI" %>
|
||||
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
|
||||
Logs
|
||||
</asp:Content>
|
||||
<asp:Content ID="Menu" ContentPlaceHolderID="ActionMenu" runat="server">
|
||||
<%
|
||||
Html.Telerik().Menu().Name("logMenu").Items(items => items.Add().Text("Clear Logs").Action("Clear", "Log")).Render();
|
||||
%>
|
||||
</asp:Content>
|
||||
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
|
||||
<%Html.Telerik().Grid(Model).Name("logs")
|
||||
.Columns(columns =>
|
||||
{
|
||||
columns.Bound(c => c.Time).Title("Time").Width(190);
|
||||
//columns.Bound(c => c.Time).Title("Time").Template(c => c.Time.ToShortTimeString()).Groupable(false);
|
||||
columns.Bound(c => c.DisplayLevel).Title("Level").Width(0);
|
||||
columns.Bound(c => c.Message);
|
||||
})
|
||||
.DataBinding(dataBinding => dataBinding.Ajax().Select("_AjaxBinding", "Log"))
|
||||
//.DetailView(detailView => detailView.Template(e => Html.RenderPartial("LogDetail", e)))
|
||||
.Sortable(rows => rows.OrderBy(epSort => epSort.Add(c => c.Time).Descending()).Enabled(true))
|
||||
.Pageable(c => c.PageSize(50).Position(GridPagerPosition.Both).Style(GridPagerStyles.PageInput | GridPagerStyles.NextPreviousAndNumeric))
|
||||
//.Groupable()
|
||||
.Filterable()
|
||||
//.Groupable(grouping => grouping.Groups(groups => groups.Add(c => c.Time.Date)).Enabled(true))
|
||||
.Render();
|
||||
%>
|
||||
</asp:Content>
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<NzbDrone.Core.Instrumentation.Log>" %>
|
||||
<ul>
|
||||
<li>
|
||||
<%: Model.Logger %>
|
||||
</li>
|
||||
<li>
|
||||
<%: Model.ExceptionType%>
|
||||
</li>
|
||||
<li>
|
||||
<%: Model.ExceptionMessage%>
|
||||
</li>
|
||||
<li>
|
||||
<%: Model.ExceptionString%>
|
||||
</li>
|
||||
</ul>
|
|
@ -1,6 +1,7 @@
|
|||
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<NzbDrone.Core.Repository.Series>" %>
|
||||
|
||||
<%@ Import Namespace="Telerik.Web.Mvc.UI" %>
|
||||
<%@ Import Namespace="NzbDrone.Core.Repository" %>
|
||||
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
|
||||
<%: Model.Title %>
|
||||
</asp:Content>
|
||||
|
@ -31,22 +32,56 @@
|
|||
<div class="display-field">
|
||||
<%: Model.Path %></div>
|
||||
</fieldset>
|
||||
<%= Html.Telerik().Grid(Model.Episodes)
|
||||
.Name("Episodes")
|
||||
.Columns(columns =>
|
||||
<%
|
||||
//Normal Seasons
|
||||
foreach (var season in Model.Seasons.Where(s => s.SeasonNumber > 0))
|
||||
{
|
||||
columns.Bound(c => c.EpisodeNumber).Width(10);
|
||||
columns.Bound(c => c.Title);
|
||||
columns.Bound(c => c.AirDate).Format("{0:d}").Width(150);
|
||||
})
|
||||
.Groupable(grouping => grouping.Groups(groups => groups.Add(c => c.SeasonNumber)))
|
||||
.Sortable(rows=>rows
|
||||
.OrderBy(epSort => epSort.Add(c => c.EpisodeNumber)))
|
||||
%>
|
||||
<br />
|
||||
<h3>
|
||||
Season
|
||||
<%: season.SeasonNumber %></h3>
|
||||
<%
|
||||
Html.Telerik().Grid(season.Episodes).Name("seasons_" + season.SeasonNumber)
|
||||
.Columns(columns =>
|
||||
{
|
||||
columns.Bound(c => c.SeasonNumber).Width(0).Title("Seasons");
|
||||
columns.Bound(c => c.EpisodeNumber).Width(0).Title("Episode");
|
||||
columns.Bound(c => c.Title);
|
||||
columns.Bound(c => c.AirDate).Format("{0:d}").Width(0);
|
||||
})
|
||||
.DetailView(detailView => detailView.Template(e => Html.RenderPartial("EpisodeDetail", e)))
|
||||
.Sortable(rows => rows.OrderBy(epSort => epSort.Add(c => c.EpisodeNumber)).Enabled(false))
|
||||
.Footer(false)
|
||||
.Render();
|
||||
}
|
||||
|
||||
//Specials
|
||||
var specialSeasons = Model.Seasons.Where(s => s.SeasonNumber == 0).FirstOrDefault();
|
||||
|
||||
if (specialSeasons != null)
|
||||
{
|
||||
%>
|
||||
<br />
|
||||
<h3>
|
||||
Specials</h3>
|
||||
<%
|
||||
|
||||
Html.Telerik().Grid(specialSeasons.Episodes).Name("seasons_specials")
|
||||
.Columns(columns =>
|
||||
{
|
||||
columns.Bound(c => c.EpisodeNumber).Width(0).Title("Episode");
|
||||
columns.Bound(c => c.Title);
|
||||
columns.Bound(c => c.AirDate).Format("{0:d}").Width(0);
|
||||
})
|
||||
.DetailView(detailView => detailView.Template(e => Html.RenderPartial("EpisodeDetail", e)))
|
||||
.Sortable(rows => rows.OrderBy(epSort => epSort.Add(c => c.EpisodeNumber)).Enabled(false))
|
||||
.Footer(false)
|
||||
.Render();
|
||||
}
|
||||
%>
|
||||
<p>
|
||||
<%-- <%: Html.ActionLink("Edit", "Edit", new { /* id=Model.PrimaryKey */ }) %> |--%>
|
||||
<%: Html.ActionLink("Back to List", "Index") %>
|
||||
<%: Html.ActionLink("Load Episodes", "LoadEpisodes", new{seriesId= Model.SeriesId}) %>
|
||||
<%: Html.ActionLink("Back to Series", "Index") %>
|
||||
</p>
|
||||
</asp:Content>
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<NzbDrone.Core.Repository.Episode>" %>
|
||||
<%@ Import Namespace="Telerik.Web.Mvc.UI" %>
|
||||
<%: Model.Overview %>
|
||||
<%:
|
||||
Html.Telerik().Grid(Model.Files)
|
||||
.Name("files_" + Model.EpisodeId)
|
||||
.Columns(columns =>
|
||||
{
|
||||
columns.Bound(c => c.Path);
|
||||
columns.Bound(c => c.Quality);
|
||||
columns.Bound(c => c.DateAdded);
|
||||
})
|
||||
.Footer(false)
|
||||
%>
|
|
@ -5,9 +5,7 @@
|
|||
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
|
||||
Series
|
||||
</asp:Content>
|
||||
<asp:Content ID="Menue" ContentPlaceHolderID="ActionMenue" runat="server">
|
||||
<div id="Mediabox">
|
||||
</div>
|
||||
<asp:Content ID="Menu" ContentPlaceHolderID="ActionMenu" runat="server">
|
||||
<%
|
||||
Html.Telerik().Menu().Name("telerikGrid").Items(items => { items.Add().Text("View Unmapped Folders").Action("Unmapped", "Series"); })
|
||||
.Items(items => items.Add().Text("Sync With Disk").Action("Sync", "Series"))
|
||||
|
|
|
@ -32,6 +32,10 @@ Released : 20100727
|
|||
%>
|
||||
</head>
|
||||
<body>
|
||||
<a href="http://github.com/kayone/NzbDrone">
|
||||
<img style="position: absolute; top: 0; left: 0; border: 0;" src="http://s3.amazonaws.com/github/ribbons/forkme_left_darkblue_121621.png"
|
||||
alt="Fork me on GitHub" />
|
||||
</a>
|
||||
<div id="header">
|
||||
<div id="msgBox">
|
||||
<span id="msgText">Scanning Series Folder...</span>
|
||||
|
@ -40,6 +44,7 @@ Released : 20100727
|
|||
<ul>
|
||||
<%=Html.CurrentActionLink("Series", "Index", "Series") %>
|
||||
<%=Html.CurrentActionLink("Settings", "Index", "Settings") %>
|
||||
<%=Html.CurrentActionLink("Logs", "Index", "Log") %>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- end #menu -->
|
||||
|
@ -53,7 +58,7 @@ Released : 20100727
|
|||
<hr />
|
||||
<!-- end #logo -->
|
||||
<div id="page">
|
||||
<asp:ContentPlaceHolder ID="ActionMenue" runat="server" />
|
||||
<asp:ContentPlaceHolder ID="ActionMenu" runat="server" />
|
||||
<div id="content">
|
||||
<div class="post">
|
||||
<div class="entry">
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NzbDrone.Web.Tests", "NzbDrone.Web.Test\NzbDrone.Web.Tests.csproj", "{99CDD5DC-698F-4624-B431-2D6381CE3A15}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NzbDrone", "NzbDrone\NzbDrone.csproj", "{D12F7F2F-8A3C-415F-88FA-6DD061A84869}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NzbDrone.Core", "NzbDrone.Core\NzbDrone.Core.csproj", "{FF5EE3B6-913B-47CE-9CEB-11C51B4E1205}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NzbDrone.Web", "NzbDrone.Web\NzbDrone.Web.csproj", "{43BD3BBD-1531-4D8F-9C08-E1CD544AB2CD}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NzbDrone.Core.Test", "NzbDrone.Core.Test\NzbDrone.Core.Test.csproj", "{193ADD3B-792B-4173-8E4C-5A3F8F0237F0}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NzbDrone.Core", "NzbDrone.Core\NzbDrone.Core.csproj", "{FF5EE3B6-913B-47CE-9CEB-11C51B4E1205}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NzbDrone", "NzbDrone\NzbDrone.csproj", "{D12F7F2F-8A3C-415F-88FA-6DD061A84869}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NzbDrone.Web.Tests", "NzbDrone.Web.Test\NzbDrone.Web.Tests.csproj", "{99CDD5DC-698F-4624-B431-2D6381CE3A15}"
|
||||
EndProject
|
||||
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{57A04B72-8088-4F75-A582-1158CF8291F7}"
|
||||
EndProject
|
||||
Global
|
||||
|
|
|
@ -35,8 +35,8 @@ namespace NzbDrone
|
|||
dte2 = (DTE2)System.Runtime.InteropServices.Marshal.
|
||||
GetActiveObject("VisualStudio.DTE.10.0");
|
||||
|
||||
var pa = new ProcessAttacher(dte2, "iisexpress", 20);
|
||||
pa.OptimisticAttachManaged();
|
||||
var pa = new ProcessAttacher(dte2, "iisexpress", 10);
|
||||
pa.PessimisticAttachManaged();
|
||||
}
|
||||
|
||||
|
||||
|
@ -87,10 +87,9 @@ namespace NzbDrone
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (ex.Message.Contains("Invalid index."))
|
||||
{
|
||||
return AttachResult.NotRunning;
|
||||
}
|
||||
|
||||
return AttachResult.NotRunning;
|
||||
|
||||
}
|
||||
|
||||
proc.Attach2(eng);
|
||||
|
|
|
@ -41,7 +41,15 @@ namespace NzbDrone
|
|||
//Manually Attach debugger to IISExpress
|
||||
if (Debugger.IsAttached)
|
||||
{
|
||||
ProcessAttacher.Attach();
|
||||
try
|
||||
{
|
||||
ProcessAttacher.Attach();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Warn("Unable to attach to debugger", e);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue