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:
parent
46bd5d1767
commit
52da5b643d
|
@ -18,7 +18,7 @@ namespace NzbDrone.Api.Indexers
|
||||||
public Boolean SceneSource { get; set; }
|
public Boolean SceneSource { get; set; }
|
||||||
public Int32 SeasonNumber { get; set; }
|
public Int32 SeasonNumber { get; set; }
|
||||||
public Language Language { get; set; }
|
public Language Language { get; set; }
|
||||||
public DateTime? AirDate { get; set; }
|
public String AirDate { get; set; }
|
||||||
public String SeriesTitle { get; set; }
|
public String SeriesTitle { get; set; }
|
||||||
public int[] EpisodeNumbers { get; set; }
|
public int[] EpisodeNumbers { get; set; }
|
||||||
public Boolean Approved { get; set; }
|
public Boolean Approved { get; set; }
|
||||||
|
|
|
@ -6,6 +6,7 @@ using NUnit.Framework;
|
||||||
using NzbDrone.Common.Expansive;
|
using NzbDrone.Common.Expansive;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
using NzbDrone.Test.Common;
|
using NzbDrone.Test.Common;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.ParserTests
|
namespace NzbDrone.Core.Test.ParserTests
|
||||||
|
@ -169,7 +170,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||||
var airDate = new DateTime(year, month, day);
|
var airDate = new DateTime(year, month, day);
|
||||||
result.Should().NotBeNull();
|
result.Should().NotBeNull();
|
||||||
result.SeriesTitle.Should().Be(title.CleanSeriesTitle());
|
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();
|
result.EpisodeNumbers.Should().BeNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
||||||
|
|
||||||
private void GivenDailyParseResult()
|
private void GivenDailyParseResult()
|
||||||
{
|
{
|
||||||
_parsedEpisodeInfo.AirDate = DateTime.Today;
|
_parsedEpisodeInfo.AirDate = DateTime.Today.ToString(Episode.AIR_DATE_FORMAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenSceneNumberingSeries()
|
private void GivenSceneNumberingSeries()
|
||||||
|
@ -78,7 +78,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
||||||
Subject.Map(_parsedEpisodeInfo, _series.TvRageId);
|
Subject.Map(_parsedEpisodeInfo, _series.TvRageId);
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>()
|
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]
|
[Test]
|
||||||
|
@ -90,19 +90,19 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
||||||
Subject.Map(_parsedEpisodeInfo, _series.TvRageId, _singleEpisodeSearchCriteria);
|
Subject.Map(_parsedEpisodeInfo, _series.TvRageId, _singleEpisodeSearchCriteria);
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>()
|
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]
|
[Test]
|
||||||
public void should_fallback_to_daily_episode_lookup_when_search_criteria_episode_doesnt_match()
|
public void should_fallback_to_daily_episode_lookup_when_search_criteria_episode_doesnt_match()
|
||||||
{
|
{
|
||||||
GivenDailySeries();
|
GivenDailySeries();
|
||||||
_parsedEpisodeInfo.AirDate = DateTime.Today.AddDays(-5);
|
_parsedEpisodeInfo.AirDate = DateTime.Today.AddDays(-5).ToString(Episode.AIR_DATE_FORMAT); ;
|
||||||
|
|
||||||
Subject.Map(_parsedEpisodeInfo, _series.TvRageId, _singleEpisodeSearchCriteria);
|
Subject.Map(_parsedEpisodeInfo, _series.TvRageId, _singleEpisodeSearchCriteria);
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>()
|
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]
|
[Test]
|
||||||
|
|
|
@ -34,9 +34,9 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.Search
|
||||||
|
|
||||||
if (dailySearchSpec == null) return true;
|
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.");
|
_logger.Trace("Episode AirDate does not match searched episode number, skipping.");
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -4,11 +4,11 @@ namespace NzbDrone.Core.IndexerSearch.Definitions
|
||||||
{
|
{
|
||||||
public class DailyEpisodeSearchCriteria : SearchCriteriaBase
|
public class DailyEpisodeSearchCriteria : SearchCriteriaBase
|
||||||
{
|
{
|
||||||
public DateTime Airtime { get; set; }
|
public DateTime AirDate { get; set; }
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return string.Format("[{0} : {1}", SceneTitle, Airtime);
|
return string.Format("[{0} : {1}", SceneTitle, AirDate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -98,7 +98,7 @@ namespace NzbDrone.Core.IndexerSearch
|
||||||
{
|
{
|
||||||
var airDate = DateTime.ParseExact(episode.AirDate, Episode.AIR_DATE_FORMAT, CultureInfo.InvariantCulture);
|
var airDate = DateTime.ParseExact(episode.AirDate, Episode.AIR_DATE_FORMAT, CultureInfo.InvariantCulture);
|
||||||
var searchSpec = Get<DailyEpisodeSearchCriteria>(series, new List<Episode>{ episode });
|
var searchSpec = Get<DailyEpisodeSearchCriteria>(series, new List<Episode>{ episode });
|
||||||
searchSpec.Airtime = airDate;
|
searchSpec.AirDate = airDate;
|
||||||
|
|
||||||
return Dispatch(indexer => _feedFetcher.Fetch(indexer, searchSpec), searchSpec);
|
return Dispatch(indexer => _feedFetcher.Fetch(indexer, searchSpec), searchSpec);
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ namespace NzbDrone.Core.Indexers
|
||||||
{
|
{
|
||||||
_logger.Debug("Searching for {0}", searchCriteria);
|
_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);
|
var result = Fetch(indexer, searchUrls);
|
||||||
|
|
||||||
_logger.Info("Finished searching {0} for {1}. Found {2}", indexer, searchCriteria, result.Count);
|
_logger.Info("Finished searching {0} for {1}. Found {2}", indexer, searchCriteria, result.Count);
|
||||||
|
|
|
@ -307,6 +307,7 @@
|
||||||
<Compile Include="Notifications\Xbmc\Model\VersionResult.cs" />
|
<Compile Include="Notifications\Xbmc\Model\VersionResult.cs" />
|
||||||
<Compile Include="Notifications\Xbmc\Model\XbmcJsonResult.cs" />
|
<Compile Include="Notifications\Xbmc\Model\XbmcJsonResult.cs" />
|
||||||
<Compile Include="Notifications\Xbmc\Model\XbmcVersion.cs" />
|
<Compile Include="Notifications\Xbmc\Model\XbmcVersion.cs" />
|
||||||
|
<Compile Include="Parser\InvalidDateException.cs" />
|
||||||
<Compile Include="ProgressMessaging\CommandUpdatedEvent.cs" />
|
<Compile Include="ProgressMessaging\CommandUpdatedEvent.cs" />
|
||||||
<Compile Include="ProgressMessaging\ProgressMessageTarget.cs" />
|
<Compile Include="ProgressMessaging\ProgressMessageTarget.cs" />
|
||||||
<Compile Include="Instrumentation\SetLoggingLevel.cs" />
|
<Compile Include="Instrumentation\SetLoggingLevel.cs" />
|
||||||
|
|
|
@ -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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,7 +10,7 @@ namespace NzbDrone.Core.Parser.Model
|
||||||
public QualityModel Quality { get; set; }
|
public QualityModel Quality { get; set; }
|
||||||
public int SeasonNumber { get; set; }
|
public int SeasonNumber { get; set; }
|
||||||
public int[] EpisodeNumbers { get; set; }
|
public int[] EpisodeNumbers { get; set; }
|
||||||
public DateTime? AirDate { get; set; }
|
public String AirDate { get; set; }
|
||||||
public Language Language { get; set; }
|
public Language Language { get; set; }
|
||||||
|
|
||||||
public bool FullSeason { get; set; }
|
public bool FullSeason { get; set; }
|
||||||
|
@ -19,9 +19,9 @@ namespace NzbDrone.Core.Parser.Model
|
||||||
{
|
{
|
||||||
string episodeString = "[Unknown Episode]";
|
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)
|
else if (FullSeason)
|
||||||
{
|
{
|
||||||
|
@ -34,5 +34,10 @@ namespace NzbDrone.Core.Parser.Model
|
||||||
|
|
||||||
return string.Format("{0} - {1} {2}", SeriesTitle, episodeString, Quality);
|
return string.Format("{0} - {1} {2}", SeriesTitle, episodeString, Quality);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsDaily()
|
||||||
|
{
|
||||||
|
return !String.IsNullOrWhiteSpace(AirDate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,6 +6,7 @@ using System.Text.RegularExpressions;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Instrumentation;
|
using NzbDrone.Common.Instrumentation;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Parser
|
namespace NzbDrone.Core.Parser
|
||||||
{
|
{
|
||||||
|
@ -110,16 +111,20 @@ namespace NzbDrone.Core.Parser
|
||||||
|
|
||||||
if (match.Count != 0)
|
if (match.Count != 0)
|
||||||
{
|
{
|
||||||
var result = ParseMatchCollection(match);
|
try
|
||||||
if (result != null)
|
|
||||||
{
|
{
|
||||||
//Check if episode is in the future (most likely a parse error)
|
var result = ParseMatchCollection(match);
|
||||||
if (result.AirDate > DateTime.Now.AddDays(1).Date || result.AirDate < new DateTime(1970, 1, 1))
|
if (result != null)
|
||||||
break;
|
{
|
||||||
|
result.Language = ParseLanguage(title);
|
||||||
result.Language = ParseLanguage(title);
|
result.Quality = QualityParser.ParseQuality(title);
|
||||||
result.Quality = QualityParser.ParseQuality(title);
|
return result;
|
||||||
return result;
|
}
|
||||||
|
}
|
||||||
|
catch (InvalidDateException ex)
|
||||||
|
{
|
||||||
|
Logger.TraceException(ex.Message, ex);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -212,9 +217,17 @@ namespace NzbDrone.Core.Parser
|
||||||
airmonth = tempDay;
|
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
|
result = new ParsedEpisodeInfo
|
||||||
{
|
{
|
||||||
AirDate = new DateTime(airYear, airmonth, airday).Date,
|
AirDate = airDate.ToString(Episode.AIR_DATE_FORMAT),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,7 @@ namespace NzbDrone.Core.Parser
|
||||||
{
|
{
|
||||||
var result = new List<Episode>();
|
var result = new List<Episode>();
|
||||||
|
|
||||||
if (parsedEpisodeInfo.AirDate.HasValue)
|
if (parsedEpisodeInfo.IsDaily())
|
||||||
{
|
{
|
||||||
if (series.SeriesType == SeriesTypes.Standard)
|
if (series.SeriesType == SeriesTypes.Standard)
|
||||||
{
|
{
|
||||||
|
@ -112,7 +112,7 @@ namespace NzbDrone.Core.Parser
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var episodeInfo = GetDailyEpisode(series, parsedEpisodeInfo.AirDate.Value, searchCriteria);
|
var episodeInfo = GetDailyEpisode(series, parsedEpisodeInfo.AirDate, searchCriteria);
|
||||||
|
|
||||||
if (episodeInfo != null)
|
if (episodeInfo != null)
|
||||||
{
|
{
|
||||||
|
@ -223,14 +223,14 @@ namespace NzbDrone.Core.Parser
|
||||||
return series;
|
return series;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Episode GetDailyEpisode(Series series, DateTime airDate, SearchCriteriaBase searchCriteria)
|
private Episode GetDailyEpisode(Series series, String airDate, SearchCriteriaBase searchCriteria)
|
||||||
{
|
{
|
||||||
Episode episodeInfo = null;
|
Episode episodeInfo = null;
|
||||||
|
|
||||||
if (searchCriteria != null)
|
if (searchCriteria != null)
|
||||||
{
|
{
|
||||||
episodeInfo = searchCriteria.Episodes.SingleOrDefault(
|
episodeInfo = searchCriteria.Episodes.SingleOrDefault(
|
||||||
e => e.AirDate == airDate.ToString(Episode.AIR_DATE_FORMAT));
|
e => e.AirDate == airDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (episodeInfo == null)
|
if (episodeInfo == null)
|
||||||
|
|
|
@ -11,8 +11,8 @@ namespace NzbDrone.Core.Tv
|
||||||
public interface IEpisodeRepository : IBasicRepository<Episode>
|
public interface IEpisodeRepository : IBasicRepository<Episode>
|
||||||
{
|
{
|
||||||
Episode Find(int seriesId, int season, int episodeNumber);
|
Episode Find(int seriesId, int season, int episodeNumber);
|
||||||
Episode Get(int seriesId, DateTime date);
|
Episode Get(int seriesId, String date);
|
||||||
Episode Find(int seriesId, DateTime date);
|
Episode Find(int seriesId, String date);
|
||||||
List<Episode> GetEpisodes(int seriesId);
|
List<Episode> GetEpisodes(int seriesId);
|
||||||
List<Episode> GetEpisodes(int seriesId, int seasonNumber);
|
List<Episode> GetEpisodes(int seriesId, int seasonNumber);
|
||||||
List<Episode> GetEpisodeByFileId(int fileId);
|
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);
|
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)
|
public List<Episode> GetEpisodes(int seriesId)
|
||||||
|
|
|
@ -14,8 +14,8 @@ namespace NzbDrone.Core.Tv
|
||||||
{
|
{
|
||||||
Episode GetEpisode(int id);
|
Episode GetEpisode(int id);
|
||||||
Episode FindEpisode(int seriesId, int seasonNumber, int episodeNumber, bool useScene = false);
|
Episode FindEpisode(int seriesId, int seasonNumber, int episodeNumber, bool useScene = false);
|
||||||
Episode GetEpisode(int seriesId, DateTime date);
|
Episode GetEpisode(int seriesId, String date);
|
||||||
Episode FindEpisode(int seriesId, DateTime date);
|
Episode FindEpisode(int seriesId, String date);
|
||||||
List<Episode> GetEpisodeBySeries(int seriesId);
|
List<Episode> GetEpisodeBySeries(int seriesId);
|
||||||
List<Episode> GetEpisodesBySeason(int seriesId, int seasonNumber);
|
List<Episode> GetEpisodesBySeason(int seriesId, int seasonNumber);
|
||||||
PagingSpec<Episode> EpisodesWithoutFiles(PagingSpec<Episode> pagingSpec);
|
PagingSpec<Episode> EpisodesWithoutFiles(PagingSpec<Episode> pagingSpec);
|
||||||
|
@ -62,12 +62,12 @@ namespace NzbDrone.Core.Tv
|
||||||
return _episodeRepository.Find(seriesId, seasonNumber, episodeNumber);
|
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);
|
return _episodeRepository.Get(seriesId, date);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Episode FindEpisode(int seriesId, DateTime date)
|
public Episode FindEpisode(int seriesId, String date)
|
||||||
{
|
{
|
||||||
return _episodeRepository.Find(seriesId, date);
|
return _episodeRepository.Find(seriesId, date);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue