Using string for airdate instead of DateTime in models to prevent timezone issues

Fixed: Manual search air by date shows can now be sent to download client
This commit is contained in:
Mark McDowall 2013-10-22 22:17:02 -07:00
parent 46bd5d1767
commit 52da5b643d
14 changed files with 79 additions and 40 deletions

View File

@ -18,7 +18,7 @@ namespace NzbDrone.Api.Indexers
public Boolean SceneSource { get; set; }
public Int32 SeasonNumber { get; set; }
public Language Language { get; set; }
public DateTime? AirDate { get; set; }
public String AirDate { get; set; }
public String SeriesTitle { get; set; }
public int[] EpisodeNumbers { get; set; }
public Boolean Approved { get; set; }

View File

@ -6,6 +6,7 @@ using NUnit.Framework;
using NzbDrone.Common.Expansive;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Tv;
using NzbDrone.Test.Common;
namespace NzbDrone.Core.Test.ParserTests
@ -169,7 +170,7 @@ namespace NzbDrone.Core.Test.ParserTests
var airDate = new DateTime(year, month, day);
result.Should().NotBeNull();
result.SeriesTitle.Should().Be(title.CleanSeriesTitle());
result.AirDate.Should().Be(airDate);
result.AirDate.Should().Be(airDate.ToString(Episode.AIR_DATE_FORMAT));
result.EpisodeNumbers.Should().BeNull();
}

View File

@ -61,7 +61,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
private void GivenDailyParseResult()
{
_parsedEpisodeInfo.AirDate = DateTime.Today;
_parsedEpisodeInfo.AirDate = DateTime.Today.ToString(Episode.AIR_DATE_FORMAT);
}
private void GivenSceneNumberingSeries()
@ -78,7 +78,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
Subject.Map(_parsedEpisodeInfo, _series.TvRageId);
Mocker.GetMock<IEpisodeService>()
.Verify(v => v.FindEpisode(It.IsAny<Int32>(), It.IsAny<DateTime>()), Times.Once());
.Verify(v => v.FindEpisode(It.IsAny<Int32>(), It.IsAny<String>()), Times.Once());
}
[Test]
@ -90,19 +90,19 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
Subject.Map(_parsedEpisodeInfo, _series.TvRageId, _singleEpisodeSearchCriteria);
Mocker.GetMock<IEpisodeService>()
.Verify(v => v.FindEpisode(It.IsAny<Int32>(), It.IsAny<DateTime>()), Times.Never());
.Verify(v => v.FindEpisode(It.IsAny<Int32>(), It.IsAny<String>()), Times.Never());
}
[Test]
public void should_fallback_to_daily_episode_lookup_when_search_criteria_episode_doesnt_match()
{
GivenDailySeries();
_parsedEpisodeInfo.AirDate = DateTime.Today.AddDays(-5);
_parsedEpisodeInfo.AirDate = DateTime.Today.AddDays(-5).ToString(Episode.AIR_DATE_FORMAT); ;
Subject.Map(_parsedEpisodeInfo, _series.TvRageId, _singleEpisodeSearchCriteria);
Mocker.GetMock<IEpisodeService>()
.Verify(v => v.FindEpisode(It.IsAny<Int32>(), It.IsAny<DateTime>()), Times.Once());
.Verify(v => v.FindEpisode(It.IsAny<Int32>(), It.IsAny<String>()), Times.Once());
}
[Test]

View File

@ -34,9 +34,9 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.Search
if (dailySearchSpec == null) return true;
var episode = _episodeService.GetEpisode(dailySearchSpec.Series.Id, dailySearchSpec.Airtime);
var episode = _episodeService.GetEpisode(dailySearchSpec.Series.Id, dailySearchSpec.AirDate.ToString(Episode.AIR_DATE_FORMAT));
if (!remoteEpisode.ParsedEpisodeInfo.AirDate.HasValue || remoteEpisode.ParsedEpisodeInfo.AirDate.Value.ToString(Episode.AIR_DATE_FORMAT) != episode.AirDate)
if (!remoteEpisode.ParsedEpisodeInfo.IsDaily() || remoteEpisode.ParsedEpisodeInfo.AirDate != episode.AirDate)
{
_logger.Trace("Episode AirDate does not match searched episode number, skipping.");
return false;

View File

@ -4,11 +4,11 @@ namespace NzbDrone.Core.IndexerSearch.Definitions
{
public class DailyEpisodeSearchCriteria : SearchCriteriaBase
{
public DateTime Airtime { get; set; }
public DateTime AirDate { get; set; }
public override string ToString()
{
return string.Format("[{0} : {1}", SceneTitle, Airtime);
return string.Format("[{0} : {1}", SceneTitle, AirDate);
}
}
}

View File

@ -98,7 +98,7 @@ namespace NzbDrone.Core.IndexerSearch
{
var airDate = DateTime.ParseExact(episode.AirDate, Episode.AIR_DATE_FORMAT, CultureInfo.InvariantCulture);
var searchSpec = Get<DailyEpisodeSearchCriteria>(series, new List<Episode>{ episode });
searchSpec.Airtime = airDate;
searchSpec.AirDate = airDate;
return Dispatch(indexer => _feedFetcher.Fetch(indexer, searchSpec), searchSpec);
}

View File

@ -87,7 +87,7 @@ namespace NzbDrone.Core.Indexers
{
_logger.Debug("Searching for {0}", searchCriteria);
var searchUrls = indexer.GetDailyEpisodeSearchUrls(searchCriteria.QueryTitle, searchCriteria.Series.TvRageId, searchCriteria.Airtime);
var searchUrls = indexer.GetDailyEpisodeSearchUrls(searchCriteria.QueryTitle, searchCriteria.Series.TvRageId, searchCriteria.AirDate);
var result = Fetch(indexer, searchUrls);
_logger.Info("Finished searching {0} for {1}. Found {2}", indexer, searchCriteria, result.Count);

View File

@ -307,6 +307,7 @@
<Compile Include="Notifications\Xbmc\Model\VersionResult.cs" />
<Compile Include="Notifications\Xbmc\Model\XbmcJsonResult.cs" />
<Compile Include="Notifications\Xbmc\Model\XbmcVersion.cs" />
<Compile Include="Parser\InvalidDateException.cs" />
<Compile Include="ProgressMessaging\CommandUpdatedEvent.cs" />
<Compile Include="ProgressMessaging\ProgressMessageTarget.cs" />
<Compile Include="Instrumentation\SetLoggingLevel.cs" />

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NzbDrone.Common.Exceptions;
namespace NzbDrone.Core.Parser
{
public class InvalidDateException : NzbDroneException
{
public InvalidDateException(string message, params object[] args) : base(message, args)
{
}
public InvalidDateException(string message) : base(message)
{
}
}
}

View File

@ -10,7 +10,7 @@ namespace NzbDrone.Core.Parser.Model
public QualityModel Quality { get; set; }
public int SeasonNumber { get; set; }
public int[] EpisodeNumbers { get; set; }
public DateTime? AirDate { get; set; }
public String AirDate { get; set; }
public Language Language { get; set; }
public bool FullSeason { get; set; }
@ -19,9 +19,9 @@ namespace NzbDrone.Core.Parser.Model
{
string episodeString = "[Unknown Episode]";
if (AirDate != null && EpisodeNumbers == null)
if (IsDaily() && EpisodeNumbers == null)
{
episodeString = string.Format("{0}", AirDate.Value.ToString("yyyy-MM-dd"));
episodeString = string.Format("{0}", AirDate);
}
else if (FullSeason)
{
@ -34,5 +34,10 @@ namespace NzbDrone.Core.Parser.Model
return string.Format("{0} - {1} {2}", SeriesTitle, episodeString, Quality);
}
public bool IsDaily()
{
return !String.IsNullOrWhiteSpace(AirDate);
}
}
}

View File

@ -6,6 +6,7 @@ using System.Text.RegularExpressions;
using NLog;
using NzbDrone.Common.Instrumentation;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Parser
{
@ -110,16 +111,20 @@ namespace NzbDrone.Core.Parser
if (match.Count != 0)
{
var result = ParseMatchCollection(match);
if (result != null)
try
{
//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;
result.Language = ParseLanguage(title);
result.Quality = QualityParser.ParseQuality(title);
return result;
var result = ParseMatchCollection(match);
if (result != null)
{
result.Language = ParseLanguage(title);
result.Quality = QualityParser.ParseQuality(title);
return result;
}
}
catch (InvalidDateException ex)
{
Logger.TraceException(ex.Message, ex);
break;
}
}
}
@ -212,9 +217,17 @@ namespace NzbDrone.Core.Parser
airmonth = tempDay;
}
var airDate = new DateTime(airYear, airmonth, airday);
//Check if episode is in the future (most likely a parse error)
if (airDate > DateTime.Now.AddDays(1).Date || airDate < new DateTime(1970, 1, 1))
{
throw new InvalidDateException("Invalid date found: {0}", airDate);
}
result = new ParsedEpisodeInfo
{
AirDate = new DateTime(airYear, airmonth, airday).Date,
AirDate = airDate.ToString(Episode.AIR_DATE_FORMAT),
};
}

View File

@ -104,7 +104,7 @@ namespace NzbDrone.Core.Parser
{
var result = new List<Episode>();
if (parsedEpisodeInfo.AirDate.HasValue)
if (parsedEpisodeInfo.IsDaily())
{
if (series.SeriesType == SeriesTypes.Standard)
{
@ -112,7 +112,7 @@ namespace NzbDrone.Core.Parser
return null;
}
var episodeInfo = GetDailyEpisode(series, parsedEpisodeInfo.AirDate.Value, searchCriteria);
var episodeInfo = GetDailyEpisode(series, parsedEpisodeInfo.AirDate, searchCriteria);
if (episodeInfo != null)
{
@ -223,14 +223,14 @@ namespace NzbDrone.Core.Parser
return series;
}
private Episode GetDailyEpisode(Series series, DateTime airDate, SearchCriteriaBase searchCriteria)
private Episode GetDailyEpisode(Series series, String airDate, SearchCriteriaBase searchCriteria)
{
Episode episodeInfo = null;
if (searchCriteria != null)
{
episodeInfo = searchCriteria.Episodes.SingleOrDefault(
e => e.AirDate == airDate.ToString(Episode.AIR_DATE_FORMAT));
e => e.AirDate == airDate);
}
if (episodeInfo == null)

View File

@ -11,8 +11,8 @@ namespace NzbDrone.Core.Tv
public interface IEpisodeRepository : IBasicRepository<Episode>
{
Episode Find(int seriesId, int season, int episodeNumber);
Episode Get(int seriesId, DateTime date);
Episode Find(int seriesId, DateTime date);
Episode Get(int seriesId, String date);
Episode Find(int seriesId, String date);
List<Episode> GetEpisodes(int seriesId);
List<Episode> GetEpisodes(int seriesId, int seasonNumber);
List<Episode> GetEpisodeByFileId(int fileId);
@ -39,14 +39,14 @@ namespace NzbDrone.Core.Tv
return Query.SingleOrDefault(s => s.SeriesId == seriesId && s.SeasonNumber == season && s.EpisodeNumber == episodeNumber);
}
public Episode Get(int seriesId, DateTime date)
public Episode Get(int seriesId, String date)
{
return Query.Single(s => s.SeriesId == seriesId && s.AirDate == date.ToString(Episode.AIR_DATE_FORMAT));
return Query.Single(s => s.SeriesId == seriesId && s.AirDate == date);
}
public Episode Find(int seriesId, DateTime date)
public Episode Find(int seriesId, String date)
{
return Query.SingleOrDefault(s => s.SeriesId == seriesId && s.AirDate == date.ToString(Episode.AIR_DATE_FORMAT));
return Query.SingleOrDefault(s => s.SeriesId == seriesId && s.AirDate == date);
}
public List<Episode> GetEpisodes(int seriesId)

View File

@ -14,8 +14,8 @@ namespace NzbDrone.Core.Tv
{
Episode GetEpisode(int id);
Episode FindEpisode(int seriesId, int seasonNumber, int episodeNumber, bool useScene = false);
Episode GetEpisode(int seriesId, DateTime date);
Episode FindEpisode(int seriesId, DateTime date);
Episode GetEpisode(int seriesId, String date);
Episode FindEpisode(int seriesId, String date);
List<Episode> GetEpisodeBySeries(int seriesId);
List<Episode> GetEpisodesBySeason(int seriesId, int seasonNumber);
PagingSpec<Episode> EpisodesWithoutFiles(PagingSpec<Episode> pagingSpec);
@ -62,12 +62,12 @@ namespace NzbDrone.Core.Tv
return _episodeRepository.Find(seriesId, seasonNumber, episodeNumber);
}
public Episode GetEpisode(int seriesId, DateTime date)
public Episode GetEpisode(int seriesId, String date)
{
return _episodeRepository.Get(seriesId, date);
}
public Episode FindEpisode(int seriesId, DateTime date)
public Episode FindEpisode(int seriesId, String date)
{
return _episodeRepository.Find(seriesId, date);
}