mirror of
https://github.com/Radarr/Radarr.git
synced 2024-09-17 15:02:34 +02:00
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 @@ public class ReleaseResource : RestResource
|
||||
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; }
|
||||
|
@ -6,6 +6,7 @@
|
||||
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 @@ public void parse_daily_episodes(string postTitle, string title, int year, int m
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ private void GivenDailySeries()
|
||||
|
||||
private void GivenDailyParseResult()
|
||||
{
|
||||
_parsedEpisodeInfo.AirDate = DateTime.Today;
|
||||
_parsedEpisodeInfo.AirDate = DateTime.Today.ToString(Episode.AIR_DATE_FORMAT);
|
||||
}
|
||||
|
||||
private void GivenSceneNumberingSeries()
|
||||
@ -78,7 +78,7 @@ public void should_get_daily_episode_episode_when_search_criteria_is_null()
|
||||
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 @@ public void should_use_search_criteria_episode_when_it_matches_daily()
|
||||
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]
|
||||
|
@ -34,9 +34,9 @@ public bool IsSatisfiedBy(RemoteEpisode remoteEpisode, SearchCriteriaBase 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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -98,7 +98,7 @@ private List<DownloadDecision> SearchDaily(Series series, Episode episode)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ public IList<ReleaseInfo> Fetch(IIndexer indexer, DailyEpisodeSearchCriteria sea
|
||||
{
|
||||
_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);
|
||||
|
@ -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" />
|
||||
|
19
src/NzbDrone.Core/Parser/InvalidDateException.cs
Normal file
19
src/NzbDrone.Core/Parser/InvalidDateException.cs
Normal 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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -10,7 +10,7 @@ public class ParsedEpisodeInfo
|
||||
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 @@ public override string ToString()
|
||||
{
|
||||
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 @@ public override string ToString()
|
||||
|
||||
return string.Format("{0} - {1} {2}", SeriesTitle, episodeString, Quality);
|
||||
}
|
||||
|
||||
public bool IsDaily()
|
||||
{
|
||||
return !String.IsNullOrWhiteSpace(AirDate);
|
||||
}
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@
|
||||
using NLog;
|
||||
using NzbDrone.Common.Instrumentation;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Parser
|
||||
{
|
||||
@ -110,16 +111,20 @@ public static ParsedEpisodeInfo ParseTitle(string title)
|
||||
|
||||
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 @@ private static ParsedEpisodeInfo ParseMatchCollection(MatchCollection matchColle
|
||||
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),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@ public List<Episode> GetEpisodes(ParsedEpisodeInfo parsedEpisodeInfo, Series ser
|
||||
{
|
||||
var result = new List<Episode>();
|
||||
|
||||
if (parsedEpisodeInfo.AirDate.HasValue)
|
||||
if (parsedEpisodeInfo.IsDaily())
|
||||
{
|
||||
if (series.SeriesType == SeriesTypes.Standard)
|
||||
{
|
||||
@ -112,7 +112,7 @@ public List<Episode> GetEpisodes(ParsedEpisodeInfo parsedEpisodeInfo, Series ser
|
||||
return null;
|
||||
}
|
||||
|
||||
var episodeInfo = GetDailyEpisode(series, parsedEpisodeInfo.AirDate.Value, searchCriteria);
|
||||
var episodeInfo = GetDailyEpisode(series, parsedEpisodeInfo.AirDate, searchCriteria);
|
||||
|
||||
if (episodeInfo != null)
|
||||
{
|
||||
@ -223,14 +223,14 @@ private Series GetSeries(ParsedEpisodeInfo parsedEpisodeInfo, int tvRageId)
|
||||
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)
|
||||
|
@ -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 @@ public Episode Find(int seriesId, int season, int 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)
|
||||
|
@ -14,8 +14,8 @@ public interface IEpisodeService
|
||||
{
|
||||
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 @@ public Episode FindEpisode(int seriesId, int seasonNumber, int episodeNumber, bo
|
||||
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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user