should be able to queue report using api.

pull/6/head
kay.one 11 years ago
parent 487ad01a0e
commit ac3582d5c4

@ -6,7 +6,6 @@ namespace NzbDrone.Api.Episodes
{ {
public class EpisodeResource : RestResource public class EpisodeResource : RestResource
{ {
public Int32 Id { get; set; }
public Int32 SeriesId { get; set; } public Int32 SeriesId { get; set; }
public Int32 EpisodeFileId { get; set; } public Int32 EpisodeFileId { get; set; }
public Int32 SeasonNumber { get; set; } public Int32 SeasonNumber { get; set; }

@ -1,8 +1,11 @@
using System.Collections.Generic; using System.Collections.Generic;
using NzbDrone.Api.Mapping; using NzbDrone.Api.Mapping;
using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Download;
using NzbDrone.Core.IndexerSearch; using NzbDrone.Core.IndexerSearch;
using NzbDrone.Core.Indexers; using NzbDrone.Core.Indexers;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
using Omu.ValueInjecter; using Omu.ValueInjecter;
using System.Linq; using System.Linq;
@ -13,14 +16,28 @@ namespace NzbDrone.Api.Indexers
private readonly IFetchAndParseRss _rssFetcherAndParser; private readonly IFetchAndParseRss _rssFetcherAndParser;
private readonly ISearchForNzb _nzbSearchService; private readonly ISearchForNzb _nzbSearchService;
private readonly IMakeDownloadDecision _downloadDecisionMaker; private readonly IMakeDownloadDecision _downloadDecisionMaker;
private static List<DownloadDecision> 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; _rssFetcherAndParser = rssFetcherAndParser;
_nzbSearchService = nzbSearchService; _nzbSearchService = nzbSearchService;
_downloadDecisionMaker = downloadDecisionMaker; _downloadDecisionMaker = downloadDecisionMaker;
_downloadService = downloadService;
_parsingService = parsingService;
GetResourceAll = GetReleases; GetResourceAll = GetReleases;
CreateResource = DownloadRelease;
}
private ReleaseResource DownloadRelease(ReleaseResource release)
{
var remoteEpisode = _parsingService.Map(release.InjectTo<ParsedEpisodeInfo>());
remoteEpisode.Report = release.InjectTo<ReportInfo>();
_downloadService.DownloadReport(remoteEpisode);
return release;
} }
@ -42,14 +59,10 @@ namespace NzbDrone.Api.Indexers
private List<ReleaseResource> GetRss() private List<ReleaseResource> GetRss()
{ {
//if (results == null) var reports = _rssFetcherAndParser.Fetch();
{ var decisions = _downloadDecisionMaker.GetRssDecision(reports);
var reports = _rssFetcherAndParser.Fetch();
var decisions = _downloadDecisionMaker.GetRssDecision(reports);
results = decisions;
}
return MapDecisions(results); return MapDecisions(decisions);
} }
private static List<ReleaseResource> MapDecisions(IEnumerable<DownloadDecision> decisions) private static List<ReleaseResource> MapDecisions(IEnumerable<DownloadDecision> decisions)

@ -40,7 +40,6 @@ namespace NzbDrone.Api.Series
public DateTime? CustomStartDate { get; set; } public DateTime? CustomStartDate { get; set; }
public Boolean UseSceneNumbering { get; set; } public Boolean UseSceneNumbering { get; set; }
public Int32 Id { get; set; }
public Int32 Runtime { get; set; } public Int32 Runtime { get; set; }
public Int32 TvdbId { get; set; } public Int32 TvdbId { get; set; }
public Int32 TvRageId { get; set; } public Int32 TvRageId { get; set; }

@ -101,6 +101,19 @@ namespace NzbDrone.Core.Test.Datastore
StoredModel.LastExecution.ToLongTimeString().Should().Be(storedTime.ToLongTimeString()); 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] [Test]
public void should_have_id_when_returned_from_database() public void should_have_id_when_returned_from_database()
{ {

@ -1,21 +1,13 @@
using System; using System.IO;
using System.IO;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Common; using NzbDrone.Common;
using NzbDrone.Core.Model.Notification;
using NzbDrone.Test.Common; using NzbDrone.Test.Common;
namespace NzbDrone.Core.Test.Framework namespace NzbDrone.Core.Test.Framework
{ {
public abstract class CoreTest : TestBase public abstract class CoreTest : TestBase
{ {
protected static ProgressNotification MockNotification
{
get
{
return new ProgressNotification("Mock notification");
}
}
protected FileStream OpenRead(params string[] path) protected FileStream OpenRead(params string[] path)
{ {

@ -174,7 +174,6 @@
<Compile Include="DecisionEngineTests\UpgradeDiskSpecificationFixture.cs" /> <Compile Include="DecisionEngineTests\UpgradeDiskSpecificationFixture.cs" />
<Compile Include="DecisionEngineTests\QualityUpgradeSpecificationFixture.cs" /> <Compile Include="DecisionEngineTests\QualityUpgradeSpecificationFixture.cs" />
<Compile Include="DecisionEngineTests\QualityUpgradableSpecificationFixture.cs" /> <Compile Include="DecisionEngineTests\QualityUpgradableSpecificationFixture.cs" />
<Compile Include="ProviderTests\NotificationProviderTests\NotificationProviderFixture.cs" />
<Compile Include="ProviderTests\DiskProviderTests\FreeDiskSpaceTest.cs" /> <Compile Include="ProviderTests\DiskProviderTests\FreeDiskSpaceTest.cs" />
<Compile Include="ProviderTests\ProwlProviderTest.cs" /> <Compile Include="ProviderTests\ProwlProviderTest.cs" />
<Compile Include="ProviderTests\GrowlProviderTest.cs" /> <Compile Include="ProviderTests\GrowlProviderTest.cs" />

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

@ -1,18 +1,12 @@
using System; using System;
using System.IO;
using System.Linq; using System.Linq;
using System.Net;
using FizzWare.NBuilder;
using FluentAssertions; using FluentAssertions;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Common; using NzbDrone.Common;
using NzbDrone.Core.Model.Notification;
using NzbDrone.Core.Providers; using NzbDrone.Core.Providers;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
using NzbDrone.Test.Common.AutoMoq;
using NzbDrone.Test.Common;
namespace NzbDrone.Core.Test.ProviderTests.XemCommunicationProviderTests namespace NzbDrone.Core.Test.ProviderTests.XemCommunicationProviderTests
{ {

@ -1,18 +1,11 @@
using System; using System;
using System.IO;
using System.Linq;
using System.Net;
using FizzWare.NBuilder;
using FluentAssertions; using FluentAssertions;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Common; using NzbDrone.Common;
using NzbDrone.Core.Model.Notification;
using NzbDrone.Core.Providers; using NzbDrone.Core.Providers;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
using NzbDrone.Test.Common.AutoMoq;
using NzbDrone.Test.Common;
namespace NzbDrone.Core.Test.ProviderTests.XemCommunicationProviderTests namespace NzbDrone.Core.Test.ProviderTests.XemCommunicationProviderTests
{ {

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

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using Marr.Data; using Marr.Data;
using Marr.Data.Mapping; using Marr.Data.Mapping;
@ -30,6 +31,13 @@ namespace NzbDrone.Core.Datastore
.SetAutoIncrement(); .SetAutoIncrement();
} }
public static RelationshipBuilder<T> AutoMapChildModels<T>(this ColumnMapBuilder<T> mapBuilder)
{
return mapBuilder.Relationships.AutoMapPropertiesWhere(m =>
m.MemberType == MemberTypes.Property &&
typeof(ModelBase).IsAssignableFrom(((PropertyInfo) m).PropertyType));
}
public static bool IsMappableProperty(MemberInfo memberInfo) public static bool IsMappableProperty(MemberInfo memberInfo)
{ {
var propertyInfo = memberInfo as PropertyInfo; var propertyInfo = memberInfo as PropertyInfo;

@ -1,6 +1,8 @@
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;
using Marr.Data; using Marr.Data;
using Marr.Data.Mapping; using Marr.Data.Mapping;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
@ -38,11 +40,7 @@ namespace NzbDrone.Core.Datastore
Mapper.Entity<SceneMapping>().RegisterModel("SceneMappings"); Mapper.Entity<SceneMapping>().RegisterModel("SceneMappings");
Mapper.Entity<History.History>().RegisterModel("History") Mapper.Entity<History.History>().RegisterModel("History")
.Relationships .AutoMapChildModels();
.AutoMapICollectionOrComplexProperties();
// .Relationship();
// .HasOne(h => h.Episode, h => h.EpisodeId)
// .HasOne(h => h.Series, h => h.SeriesId);
Mapper.Entity<Series>().RegisterModel("Series") Mapper.Entity<Series>().RegisterModel("Series")
.Ignore(s => s.RootFolderPath) .Ignore(s => s.RootFolderPath)
@ -55,7 +53,6 @@ namespace NzbDrone.Core.Datastore
.Ignore(e => e.SeriesTitle) .Ignore(e => e.SeriesTitle)
.Relationship() .Relationship()
.HasOne(episode => episode.EpisodeFile, episode => episode.EpisodeFileId); .HasOne(episode => episode.EpisodeFile, episode => episode.EpisodeFileId);
//.Relationships.AutoMapICollectionOrComplexProperties();
Mapper.Entity<EpisodeFile>().RegisterModel("EpisodeFiles") Mapper.Entity<EpisodeFile>().RegisterModel("EpisodeFiles")
.Relationships.AutoMapICollectionOrComplexProperties(); .Relationships.AutoMapICollectionOrComplexProperties();
@ -76,6 +73,7 @@ namespace NzbDrone.Core.Datastore
RegisterEmbeddedConverter(); RegisterEmbeddedConverter();
MapRepository.Instance.RegisterTypeConverter(typeof(Int32), new Int32Converter()); 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(Boolean), new BooleanIntConverter());
MapRepository.Instance.RegisterTypeConverter(typeof(Enum), new EnumIntConverter()); MapRepository.Instance.RegisterTypeConverter(typeof(Enum), new EnumIntConverter());
MapRepository.Instance.RegisterTypeConverter(typeof(Quality), new QualityIntConverter()); MapRepository.Instance.RegisterTypeConverter(typeof(Quality), new QualityIntConverter());

@ -1,16 +1,12 @@
using System; using NLog;
using System.Collections.Generic;
using System.Linq;
using NLog;
using NzbDrone.Common.Messaging; using NzbDrone.Common.Messaging;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Download namespace NzbDrone.Core.Download
{ {
public interface IDownloadService public interface IDownloadService
{ {
bool DownloadReport(RemoteEpisode episode); bool DownloadReport(RemoteEpisode remoteEpisode);
} }
public class DownloadService : IDownloadService public class DownloadService : IDownloadService
@ -28,27 +24,23 @@ namespace NzbDrone.Core.Download
_logger = logger; _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 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) if (success)
{ {
_logger.Info("Report sent to download client. {0}", downloadTitle); _logger.Info("Report sent to download client. {0}", downloadTitle);
_messageAggregator.PublishEvent(new EpisodeGrabbedEvent(episode)); _messageAggregator.PublishEvent(new EpisodeGrabbedEvent(remoteEpisode));
} }
return success; return success;
} }
private static bool ContainsRecentEpisode(RemoteEpisode episode)
{
return episode.Episodes.Any(e => e.AirDate >= DateTime.Today.AddDays(-7));
}
} }
} }

@ -24,7 +24,7 @@ namespace NzbDrone.Core.History
public void Trim() public void Trim()
{ {
var cutoff = DateTime.Now.AddDays(-30).Date; var cutoff = DateTime.UtcNow.AddDays(-30).Date;
Delete(c=> c.Date < cutoff); Delete(c=> c.Date < cutoff);
} }

@ -61,7 +61,7 @@ namespace NzbDrone.Core.History
{ {
var history = new History var history = new History
{ {
Date = DateTime.Now, Date = DateTime.UtcNow,
Quality = message.Episode.ParsedEpisodeInfo.Quality, Quality = message.Episode.ParsedEpisodeInfo.Quality,
SourceTitle = message.Episode.Report.Title, SourceTitle = message.Episode.Report.Title,
SeriesId = episode.SeriesId, SeriesId = episode.SeriesId,
@ -83,7 +83,7 @@ namespace NzbDrone.Core.History
{ {
var history = new History var history = new History
{ {
Date = DateTime.Now, Date = DateTime.UtcNow,
Quality = message.EpisodeFile.Quality, Quality = message.EpisodeFile.Quality,
SourceTitle = message.EpisodeFile.Path, SourceTitle = message.EpisodeFile.Path,
SeriesId = message.EpisodeFile.SeriesId, SeriesId = message.EpisodeFile.SeriesId,

@ -20,7 +20,7 @@ namespace NzbDrone.Core.Instrumentation
public void Trim() 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); DeleteMany(oldIds);
} }
} }

@ -105,7 +105,7 @@ namespace NzbDrone.Core.MediaFiles
} }
var episodeFile = new EpisodeFile(); var episodeFile = new EpisodeFile();
episodeFile.DateAdded = DateTime.Now; episodeFile.DateAdded = DateTime.UtcNow;
episodeFile.SeriesId = series.Id; episodeFile.SeriesId = series.Id;
episodeFile.Path = filePath.CleanPath(); episodeFile.Path = filePath.CleanPath();
episodeFile.Size = size; episodeFile.Size = size;

@ -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;
}
/// <summary>
/// Gets or sets the unique id.
/// </summary>
/// <value>The Id.</value>
public Guid Id { get; private set; }
/// <summary>
/// Gets or sets the title for this notification.
/// </summary>
/// <value>The title.</value>
public String Title { get; private set; }
/// <summary>
/// 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.
/// </summary>
/// <value>The current status.</value>
public String CurrentMessage { get; set; }
/// <summary>
/// Gets or sets the completion status in percent.
/// </summary>
/// <value>The percent complete.</value>
public int PercentComplete
{
get { return Convert.ToInt32(Convert.ToDouble(ProgressValue) / Convert.ToDouble(ProgressMax) * 100); }
}
/// <summary>
/// Gets or sets the total number of items that need to be completed
/// </summary>
/// <value>The progress max.</value>
public int ProgressMax { get; set; }
/// <summary>
/// Gets or sets the number of items successfully completed.
/// </summary>
/// <value>The progress value.</value>
public int ProgressValue { get; set; }
private ProgressNotificationStatus _status;
/// <summary>
/// Gets or sets the status.
/// </summary>
/// <value>The status.</value>
public ProgressNotificationStatus Status
{
get { return _status; }
set
{
if (value != ProgressNotificationStatus.InProgress)
{
CompletedTime = DateTime.Now;
}
_status = value;
}
}
/// <summary>
/// Gets the completed time.
/// </summary>
public Nullable<DateTime> 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
}
}

@ -1,9 +0,0 @@
namespace NzbDrone.Core.Model.Notification
{
public enum ProgressNotificationStatus
{
InProgress = 0,
Completed = 1,
Failed = 2
}
}

@ -198,6 +198,7 @@
<Compile Include="Datastore\Converters\QualityIntConverter.cs" /> <Compile Include="Datastore\Converters\QualityIntConverter.cs" />
<Compile Include="Datastore\Converters\Int32Converter.cs" /> <Compile Include="Datastore\Converters\Int32Converter.cs" />
<Compile Include="Datastore\Converters\EmbeddedDocumentConverter.cs" /> <Compile Include="Datastore\Converters\EmbeddedDocumentConverter.cs" />
<Compile Include="Datastore\Converters\UtcConverter.cs" />
<Compile Include="Datastore\Database.cs" /> <Compile Include="Datastore\Database.cs" />
<Compile Include="Datastore\DbFactory.cs" /> <Compile Include="Datastore\DbFactory.cs" />
<Compile Include="Datastore\Converters\EnumIntConverter.cs" /> <Compile Include="Datastore\Converters\EnumIntConverter.cs" />
@ -467,9 +468,6 @@
<Compile Include="MediaFiles\MediaFileService.cs"> <Compile Include="MediaFiles\MediaFileService.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="Providers\NotificationProvider.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Notifications\Plex\PlexProvider.cs" /> <Compile Include="Notifications\Plex\PlexProvider.cs" />
<Compile Include="MediaFiles\DownloadedEpisodesImportService.cs"> <Compile Include="MediaFiles\DownloadedEpisodesImportService.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
@ -505,8 +503,6 @@
<Compile Include="Notifications\NotificationDefinition.cs" /> <Compile Include="Notifications\NotificationDefinition.cs" />
<Compile Include="Download\Clients\Sabnzbd\SabPriorityType.cs" /> <Compile Include="Download\Clients\Sabnzbd\SabPriorityType.cs" />
<Compile Include="MediaFiles\EpisodeFile.cs" /> <Compile Include="MediaFiles\EpisodeFile.cs" />
<Compile Include="Model\Notification\ProgressNotificationStatus.cs" />
<Compile Include="Model\Notification\ProgressNotification.cs" />
<Compile Include="Tv\Episode.cs" /> <Compile Include="Tv\Episode.cs" />
<Compile Include="Instrumentation\Log.cs" /> <Compile Include="Instrumentation\Log.cs" />
<Compile Include="History\History.cs" /> <Compile Include="History\History.cs" />

@ -116,7 +116,7 @@ namespace NzbDrone.Core.Parser
var result = ParseMatchCollection(match); var result = ParseMatchCollection(match);
if (result != null) 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)) if (result.AirDate > DateTime.Now.AddDays(1).Date || result.AirDate < new DateTime(1970, 1, 1))
break; break;

@ -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;
}
}
}
Loading…
Cancel
Save