diff --git a/NzbDrone.Api/Episodes/EpisodeResource.cs b/NzbDrone.Api/Episodes/EpisodeResource.cs index e323ea241..4aa9ae80d 100644 --- a/NzbDrone.Api/Episodes/EpisodeResource.cs +++ b/NzbDrone.Api/Episodes/EpisodeResource.cs @@ -6,7 +6,6 @@ namespace NzbDrone.Api.Episodes { public class EpisodeResource : RestResource { - public Int32 Id { get; set; } public Int32 SeriesId { get; set; } public Int32 EpisodeFileId { get; set; } public Int32 SeasonNumber { get; set; } diff --git a/NzbDrone.Api/Indexers/ReleaseModule.cs b/NzbDrone.Api/Indexers/ReleaseModule.cs index a824d0200..a8949c6bb 100644 --- a/NzbDrone.Api/Indexers/ReleaseModule.cs +++ b/NzbDrone.Api/Indexers/ReleaseModule.cs @@ -1,8 +1,11 @@ using System.Collections.Generic; using NzbDrone.Api.Mapping; using NzbDrone.Core.DecisionEngine; +using NzbDrone.Core.Download; using NzbDrone.Core.IndexerSearch; using NzbDrone.Core.Indexers; +using NzbDrone.Core.Parser; +using NzbDrone.Core.Parser.Model; using Omu.ValueInjecter; using System.Linq; @@ -13,14 +16,28 @@ public class ReleaseModule : NzbDroneRestModule private readonly IFetchAndParseRss _rssFetcherAndParser; private readonly ISearchForNzb _nzbSearchService; private readonly IMakeDownloadDecision _downloadDecisionMaker; - private static List results; + private readonly IDownloadService _downloadService; + private readonly IParsingService _parsingService; - public ReleaseModule(IFetchAndParseRss rssFetcherAndParser, ISearchForNzb nzbSearchService, IMakeDownloadDecision downloadDecisionMaker) + public ReleaseModule(IFetchAndParseRss rssFetcherAndParser, ISearchForNzb nzbSearchService, IMakeDownloadDecision downloadDecisionMaker, IDownloadService downloadService, IParsingService parsingService) { _rssFetcherAndParser = rssFetcherAndParser; _nzbSearchService = nzbSearchService; _downloadDecisionMaker = downloadDecisionMaker; + _downloadService = downloadService; + _parsingService = parsingService; GetResourceAll = GetReleases; + CreateResource = DownloadRelease; + } + + private ReleaseResource DownloadRelease(ReleaseResource release) + { + var remoteEpisode = _parsingService.Map(release.InjectTo()); + remoteEpisode.Report = release.InjectTo(); + + _downloadService.DownloadReport(remoteEpisode); + + return release; } @@ -42,14 +59,10 @@ private List GetEpisodeReleases(int episodeId) private List GetRss() { - //if (results == null) - { - var reports = _rssFetcherAndParser.Fetch(); - var decisions = _downloadDecisionMaker.GetRssDecision(reports); - results = decisions; - } + var reports = _rssFetcherAndParser.Fetch(); + var decisions = _downloadDecisionMaker.GetRssDecision(reports); - return MapDecisions(results); + return MapDecisions(decisions); } private static List MapDecisions(IEnumerable decisions) diff --git a/NzbDrone.Api/Series/SeriesResource.cs b/NzbDrone.Api/Series/SeriesResource.cs index 06eda15f8..92b5c39c4 100644 --- a/NzbDrone.Api/Series/SeriesResource.cs +++ b/NzbDrone.Api/Series/SeriesResource.cs @@ -40,7 +40,6 @@ public class SeriesResource : RestResource public DateTime? CustomStartDate { get; set; } public Boolean UseSceneNumbering { get; set; } - public Int32 Id { get; set; } public Int32 Runtime { get; set; } public Int32 TvdbId { get; set; } public Int32 TvRageId { get; set; } diff --git a/NzbDrone.Core.Test/Datastore/ObjectDatabaseFixture.cs b/NzbDrone.Core.Test/Datastore/ObjectDatabaseFixture.cs index 353ed5629..6d805f83d 100644 --- a/NzbDrone.Core.Test/Datastore/ObjectDatabaseFixture.cs +++ b/NzbDrone.Core.Test/Datastore/ObjectDatabaseFixture.cs @@ -101,6 +101,19 @@ public void should_read_and_write_in_utc() StoredModel.LastExecution.ToLongTimeString().Should().Be(storedTime.ToLongTimeString()); } + [Test] + public void should_convert_all_dates_to_utc() + { + var storedTime = DateTime.Now; + + _sampleType.LastExecution = storedTime; + + Subject.Insert(_sampleType); + + StoredModel.LastExecution.Kind.Should().Be(DateTimeKind.Utc); + StoredModel.LastExecution.ToLongTimeString().Should().Be(storedTime.ToUniversalTime().ToLongTimeString()); + } + [Test] public void should_have_id_when_returned_from_database() { diff --git a/NzbDrone.Core.Test/Framework/CoreTest.cs b/NzbDrone.Core.Test/Framework/CoreTest.cs index 3e03b34b6..86e3f024d 100644 --- a/NzbDrone.Core.Test/Framework/CoreTest.cs +++ b/NzbDrone.Core.Test/Framework/CoreTest.cs @@ -1,21 +1,13 @@ -using System; -using System.IO; +using System.IO; using NUnit.Framework; using NzbDrone.Common; -using NzbDrone.Core.Model.Notification; using NzbDrone.Test.Common; namespace NzbDrone.Core.Test.Framework { public abstract class CoreTest : TestBase { - protected static ProgressNotification MockNotification - { - get - { - return new ProgressNotification("Mock notification"); - } - } + protected FileStream OpenRead(params string[] path) { diff --git a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index 01db5f2ce..dc98fb0b9 100644 --- a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -174,7 +174,6 @@ - diff --git a/NzbDrone.Core.Test/ProviderTests/NotificationProviderTests/NotificationProviderFixture.cs b/NzbDrone.Core.Test/ProviderTests/NotificationProviderTests/NotificationProviderFixture.cs deleted file mode 100644 index cd7f40d63..000000000 --- a/NzbDrone.Core.Test/ProviderTests/NotificationProviderTests/NotificationProviderFixture.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System.Linq; -using System.Threading; -using FluentAssertions; -using NUnit.Framework; -using NzbDrone.Core.Model.Notification; -using NzbDrone.Core.Providers; - -namespace NzbDrone.Core.Test.ProviderTests.NotificationProviderTests -{ - [TestFixture] - public class NotificationProviderFixture - { - NotificationProvider _notificationProvider; - - [SetUp] - public void Setup() - { - _notificationProvider = new NotificationProvider(); - } - - [Test] - public void current_notification_should_return_null_at_start() - { - _notificationProvider.GetCurrent().Should().BeNull(); - } - - [Test] - public void should_return_current_on_active_notifications() - { - var fakeNotification = new ProgressNotification("Title"); - _notificationProvider.Register(fakeNotification); - - _notificationProvider.GetCurrent().Should().Be(fakeNotification); - } - - [Test] - public void should_return_last_if_recently_completed() - { - var fakeNotification = new ProgressNotification("Title"); - _notificationProvider.Register(fakeNotification); - fakeNotification.Dispose(); - - _notificationProvider.GetCurrent().Should().Be(fakeNotification); - } - - [Test] - public void should_return_null_if_completed_long_time_ago() - { - var fakeNotification = new ProgressNotification("Title"); - _notificationProvider.Register(fakeNotification); - fakeNotification.Dispose(); - - Thread.Sleep(7000); - - _notificationProvider.GetCurrent().Should().BeNull(); - } - - [Test] - public void new_notification_should_replace_old_one() - { - var oldNotification = new ProgressNotification("Title"); - _notificationProvider.Register(oldNotification); - - var newNotification = new ProgressNotification("Title"); - _notificationProvider.Register(newNotification); - - _notificationProvider.GetCurrent().Should().Be(newNotification); - } - - } -} diff --git a/NzbDrone.Core.Test/ProviderTests/XemCommunicationProviderTests/GetSceneTvdbMappingsFixture.cs b/NzbDrone.Core.Test/ProviderTests/XemCommunicationProviderTests/GetSceneTvdbMappingsFixture.cs index 4d7650960..c8066ace5 100644 --- a/NzbDrone.Core.Test/ProviderTests/XemCommunicationProviderTests/GetSceneTvdbMappingsFixture.cs +++ b/NzbDrone.Core.Test/ProviderTests/XemCommunicationProviderTests/GetSceneTvdbMappingsFixture.cs @@ -1,18 +1,12 @@ using System; -using System.IO; using System.Linq; -using System.Net; -using FizzWare.NBuilder; using FluentAssertions; using Moq; using NUnit.Framework; using NzbDrone.Common; -using NzbDrone.Core.Model.Notification; using NzbDrone.Core.Providers; using NzbDrone.Core.Test.Framework; -using NzbDrone.Test.Common.AutoMoq; -using NzbDrone.Test.Common; namespace NzbDrone.Core.Test.ProviderTests.XemCommunicationProviderTests { diff --git a/NzbDrone.Core.Test/ProviderTests/XemCommunicationProviderTests/GetXemSeriesIdsFixture.cs b/NzbDrone.Core.Test/ProviderTests/XemCommunicationProviderTests/GetXemSeriesIdsFixture.cs index bc82003a9..82035d5c8 100644 --- a/NzbDrone.Core.Test/ProviderTests/XemCommunicationProviderTests/GetXemSeriesIdsFixture.cs +++ b/NzbDrone.Core.Test/ProviderTests/XemCommunicationProviderTests/GetXemSeriesIdsFixture.cs @@ -1,18 +1,11 @@ using System; -using System.IO; -using System.Linq; -using System.Net; -using FizzWare.NBuilder; using FluentAssertions; using Moq; using NUnit.Framework; using NzbDrone.Common; -using NzbDrone.Core.Model.Notification; using NzbDrone.Core.Providers; using NzbDrone.Core.Test.Framework; -using NzbDrone.Test.Common.AutoMoq; -using NzbDrone.Test.Common; namespace NzbDrone.Core.Test.ProviderTests.XemCommunicationProviderTests { diff --git a/NzbDrone.Core/Datastore/Converters/UtcConverter.cs b/NzbDrone.Core/Datastore/Converters/UtcConverter.cs new file mode 100644 index 000000000..9fd2b7aa9 --- /dev/null +++ b/NzbDrone.Core/Datastore/Converters/UtcConverter.cs @@ -0,0 +1,28 @@ +using System; +using Marr.Data.Converters; +using Marr.Data.Mapping; + +namespace NzbDrone.Core.Datastore.Converters +{ + public class UtcConverter : IConverter + { + public object FromDB(ColumnMap map, object dbValue) + { + return dbValue; + } + + public object ToDB(object clrValue) + { + var dateTime = (DateTime)clrValue; + return dateTime.ToUniversalTime(); + } + + public Type DbType + { + get + { + return typeof(DateTime); + } + } + } +} \ No newline at end of file diff --git a/NzbDrone.Core/Datastore/MappingExtensions.cs b/NzbDrone.Core/Datastore/MappingExtensions.cs index 267cb4181..a2c04a890 100644 --- a/NzbDrone.Core/Datastore/MappingExtensions.cs +++ b/NzbDrone.Core/Datastore/MappingExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Reflection; using Marr.Data; using Marr.Data.Mapping; @@ -30,6 +31,13 @@ public static class MappingExtensions .SetAutoIncrement(); } + public static RelationshipBuilder AutoMapChildModels(this ColumnMapBuilder mapBuilder) + { + return mapBuilder.Relationships.AutoMapPropertiesWhere(m => + m.MemberType == MemberTypes.Property && + typeof(ModelBase).IsAssignableFrom(((PropertyInfo) m).PropertyType)); + } + public static bool IsMappableProperty(MemberInfo memberInfo) { var propertyInfo = memberInfo as PropertyInfo; diff --git a/NzbDrone.Core/Datastore/TableMapping.cs b/NzbDrone.Core/Datastore/TableMapping.cs index 520c26e1f..b9cdfa1b5 100644 --- a/NzbDrone.Core/Datastore/TableMapping.cs +++ b/NzbDrone.Core/Datastore/TableMapping.cs @@ -1,6 +1,8 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; +using System.Reflection; using Marr.Data; using Marr.Data.Mapping; using NzbDrone.Core.Configuration; @@ -38,11 +40,7 @@ public static void Map() Mapper.Entity().RegisterModel("SceneMappings"); Mapper.Entity().RegisterModel("History") - .Relationships - .AutoMapICollectionOrComplexProperties(); - // .Relationship(); - // .HasOne(h => h.Episode, h => h.EpisodeId) - // .HasOne(h => h.Series, h => h.SeriesId); + .AutoMapChildModels(); Mapper.Entity().RegisterModel("Series") .Ignore(s => s.RootFolderPath) @@ -55,7 +53,6 @@ public static void Map() .Ignore(e => e.SeriesTitle) .Relationship() .HasOne(episode => episode.EpisodeFile, episode => episode.EpisodeFileId); - //.Relationships.AutoMapICollectionOrComplexProperties(); Mapper.Entity().RegisterModel("EpisodeFiles") .Relationships.AutoMapICollectionOrComplexProperties(); @@ -76,6 +73,7 @@ private static void RegisterMappers() RegisterEmbeddedConverter(); MapRepository.Instance.RegisterTypeConverter(typeof(Int32), new Int32Converter()); + MapRepository.Instance.RegisterTypeConverter(typeof(DateTime), new UtcConverter()); MapRepository.Instance.RegisterTypeConverter(typeof(Boolean), new BooleanIntConverter()); MapRepository.Instance.RegisterTypeConverter(typeof(Enum), new EnumIntConverter()); MapRepository.Instance.RegisterTypeConverter(typeof(Quality), new QualityIntConverter()); diff --git a/NzbDrone.Core/Download/DownloadService.cs b/NzbDrone.Core/Download/DownloadService.cs index 84a3b73e6..14add86d8 100644 --- a/NzbDrone.Core/Download/DownloadService.cs +++ b/NzbDrone.Core/Download/DownloadService.cs @@ -1,16 +1,12 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using NLog; +using NLog; using NzbDrone.Common.Messaging; -using NzbDrone.Core.Configuration; using NzbDrone.Core.Parser.Model; namespace NzbDrone.Core.Download { public interface IDownloadService { - bool DownloadReport(RemoteEpisode episode); + bool DownloadReport(RemoteEpisode remoteEpisode); } public class DownloadService : IDownloadService @@ -28,27 +24,23 @@ public DownloadService(IProvideDownloadClient downloadClientProvider, _logger = logger; } - public bool DownloadReport(RemoteEpisode episode) + public bool DownloadReport(RemoteEpisode remoteEpisode) { - var downloadTitle = episode.Report.Title; + var downloadTitle = remoteEpisode.Report.Title; var provider = _downloadClientProvider.GetDownloadClient(); - var recentEpisode = ContainsRecentEpisode(episode); - bool success = provider.DownloadNzb(episode.Report.NzbUrl, downloadTitle, recentEpisode); + bool success = provider.DownloadNzb(remoteEpisode.Report.NzbUrl, downloadTitle, remoteEpisode.IsRecentEpisode()); if (success) { _logger.Info("Report sent to download client. {0}", downloadTitle); - _messageAggregator.PublishEvent(new EpisodeGrabbedEvent(episode)); + _messageAggregator.PublishEvent(new EpisodeGrabbedEvent(remoteEpisode)); } return success; } - private static bool ContainsRecentEpisode(RemoteEpisode episode) - { - return episode.Episodes.Any(e => e.AirDate >= DateTime.Today.AddDays(-7)); - } + } } \ No newline at end of file diff --git a/NzbDrone.Core/History/HistoryRepository.cs b/NzbDrone.Core/History/HistoryRepository.cs index e391954f9..4a4675384 100644 --- a/NzbDrone.Core/History/HistoryRepository.cs +++ b/NzbDrone.Core/History/HistoryRepository.cs @@ -24,7 +24,7 @@ public HistoryRepository(IDatabase database, IMessageAggregator messageAggregato public void Trim() { - var cutoff = DateTime.Now.AddDays(-30).Date; + var cutoff = DateTime.UtcNow.AddDays(-30).Date; Delete(c=> c.Date < cutoff); } diff --git a/NzbDrone.Core/History/HistoryService.cs b/NzbDrone.Core/History/HistoryService.cs index 45c4596f7..6a334cfe2 100644 --- a/NzbDrone.Core/History/HistoryService.cs +++ b/NzbDrone.Core/History/HistoryService.cs @@ -61,7 +61,7 @@ public void Handle(EpisodeGrabbedEvent message) { var history = new History { - Date = DateTime.Now, + Date = DateTime.UtcNow, Quality = message.Episode.ParsedEpisodeInfo.Quality, SourceTitle = message.Episode.Report.Title, SeriesId = episode.SeriesId, @@ -83,7 +83,7 @@ public void Handle(EpisodeImportedEvent message) { var history = new History { - Date = DateTime.Now, + Date = DateTime.UtcNow, Quality = message.EpisodeFile.Quality, SourceTitle = message.EpisodeFile.Path, SeriesId = message.EpisodeFile.SeriesId, diff --git a/NzbDrone.Core/Instrumentation/LogRepository.cs b/NzbDrone.Core/Instrumentation/LogRepository.cs index abba443e8..29cc4ed7f 100644 --- a/NzbDrone.Core/Instrumentation/LogRepository.cs +++ b/NzbDrone.Core/Instrumentation/LogRepository.cs @@ -20,7 +20,7 @@ public LogRepository(IDatabase database, IMessageAggregator messageAggregator) public void Trim() { - var oldIds = Query.Where(c => c.Time < DateTime.Now.AddDays(-30).Date).Select(c => c.Id); + var oldIds = Query.Where(c => c.Time < DateTime.UtcNow.AddDays(-30).Date).Select(c => c.Id); DeleteMany(oldIds); } } diff --git a/NzbDrone.Core/MediaFiles/DiskScanService.cs b/NzbDrone.Core/MediaFiles/DiskScanService.cs index 815c2cb44..8e9612e73 100644 --- a/NzbDrone.Core/MediaFiles/DiskScanService.cs +++ b/NzbDrone.Core/MediaFiles/DiskScanService.cs @@ -105,7 +105,7 @@ public EpisodeFile ImportFile(Series series, string filePath) } var episodeFile = new EpisodeFile(); - episodeFile.DateAdded = DateTime.Now; + episodeFile.DateAdded = DateTime.UtcNow; episodeFile.SeriesId = series.Id; episodeFile.Path = filePath.CleanPath(); episodeFile.Size = size; diff --git a/NzbDrone.Core/Model/Notification/ProgressNotification.cs b/NzbDrone.Core/Model/Notification/ProgressNotification.cs deleted file mode 100644 index 8e6b84f28..000000000 --- a/NzbDrone.Core/Model/Notification/ProgressNotification.cs +++ /dev/null @@ -1,97 +0,0 @@ -using System; -using NLog; - -namespace NzbDrone.Core.Model.Notification -{ - public class ProgressNotification : IDisposable - { - private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); - - public ProgressNotification(string title) - { - Title = title; - CurrentMessage = String.Empty; - Id = Guid.NewGuid(); - ProgressMax = 100; - ProgressValue = 0; - } - - - /// - /// Gets or sets the unique id. - /// - /// The Id. - public Guid Id { get; private set; } - - /// - /// Gets or sets the title for this notification. - /// - /// The title. - public String Title { get; private set; } - - /// - /// Gets or sets the current status of this task. this field could be use to show the currently processing item in a long running task. - /// - /// The current status. - public String CurrentMessage { get; set; } - - /// - /// Gets or sets the completion status in percent. - /// - /// The percent complete. - public int PercentComplete - { - get { return Convert.ToInt32(Convert.ToDouble(ProgressValue) / Convert.ToDouble(ProgressMax) * 100); } - } - - /// - /// Gets or sets the total number of items that need to be completed - /// - /// The progress max. - public int ProgressMax { get; set; } - - /// - /// Gets or sets the number of items successfully completed. - /// - /// The progress value. - public int ProgressValue { get; set; } - - private ProgressNotificationStatus _status; - - /// - /// Gets or sets the status. - /// - /// The status. - public ProgressNotificationStatus Status - { - get { return _status; } - set - { - if (value != ProgressNotificationStatus.InProgress) - { - CompletedTime = DateTime.Now; - } - _status = value; - } - } - - - /// - /// Gets the completed time. - /// - public Nullable CompletedTime { get; private set; } - - #region IDisposable Members - - public void Dispose() - { - if (Status == ProgressNotificationStatus.InProgress) - { - Logger.Warn("Background task '{0}' was unexpectedly abandoned.", Title); - Status = ProgressNotificationStatus.Failed; - } - } - - #endregion - } -} \ No newline at end of file diff --git a/NzbDrone.Core/Model/Notification/ProgressNotificationStatus.cs b/NzbDrone.Core/Model/Notification/ProgressNotificationStatus.cs deleted file mode 100644 index b79707b34..000000000 --- a/NzbDrone.Core/Model/Notification/ProgressNotificationStatus.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace NzbDrone.Core.Model.Notification -{ - public enum ProgressNotificationStatus - { - InProgress = 0, - Completed = 1, - Failed = 2 - } -} \ No newline at end of file diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index c0cf5a09a..d4a6484f4 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -198,6 +198,7 @@ + @@ -467,9 +468,6 @@ Code - - Code - Code @@ -505,8 +503,6 @@ - - diff --git a/NzbDrone.Core/Parser/Parser.cs b/NzbDrone.Core/Parser/Parser.cs index b8f5b35bb..5f36c38f3 100644 --- a/NzbDrone.Core/Parser/Parser.cs +++ b/NzbDrone.Core/Parser/Parser.cs @@ -116,7 +116,7 @@ public static ParsedEpisodeInfo ParseTitle(string title) var result = ParseMatchCollection(match); if (result != null) { - //Check if episode is in the future (most likley a parse error) + //Check if episode is in the future (most likely a parse error) if (result.AirDate > DateTime.Now.AddDays(1).Date || result.AirDate < new DateTime(1970, 1, 1)) break; diff --git a/NzbDrone.Core/Providers/NotificationProvider.cs b/NzbDrone.Core/Providers/NotificationProvider.cs deleted file mode 100644 index ac3fe4a1d..000000000 --- a/NzbDrone.Core/Providers/NotificationProvider.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.Linq; -using NzbDrone.Core.Model.Notification; - -namespace NzbDrone.Core.Providers -{ - public class NotificationProvider - { - private static ProgressNotification _currentNotification; - - public virtual ProgressNotification GetCurrent() - { - if (_currentNotification == null || _currentNotification.CompletedTime < DateTime.Now.AddSeconds(-6)) - { - return null; - } - - return _currentNotification; - } - - public virtual void Register(ProgressNotification notification) - { - _currentNotification = notification; - } - } -} \ No newline at end of file