From ff0e0597b44ba8efdfe2b0de16f354ef6bdc12df Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Tue, 26 Apr 2011 19:47:29 -0700 Subject: [PATCH] Upcoming view column width fixed for Air Date (added time). --- NzbDrone.Core/Parser.cs | 568 +++++++++--------- NzbDrone.Core/Providers/SeriesProvider.cs | 27 +- .../Controllers/UpcomingController.cs | 9 +- NzbDrone.Web/Views/Upcoming/Index.cshtml | 6 +- 4 files changed, 318 insertions(+), 292 deletions(-) diff --git a/NzbDrone.Core/Parser.cs b/NzbDrone.Core/Parser.cs index e67d7738e..bc0c2c4ad 100644 --- a/NzbDrone.Core/Parser.cs +++ b/NzbDrone.Core/Parser.cs @@ -1,81 +1,81 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Text.RegularExpressions; -using NLog; -using NzbDrone.Core.Model; -using NzbDrone.Core.Repository.Quality; - -namespace NzbDrone.Core -{ - public static class Parser - { - private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); - - private static readonly Regex[] ReportTitleRegex = new[] - { - new Regex(@"^(?.+?)?\W*(?<airyear>\d{4})\W+(?<airmonth>\d{2})\W+(?<airday>\d{2})\W?(?!\\)", - RegexOptions.IgnoreCase | RegexOptions.Compiled), - new Regex(@"^(?<title>.*?)?(?:\W?S?(?<season>\d{1,2}(?!\d+))(?:(?:\-|\.|[ex]|\s|\sto\s){1,2}(?<episode>\d{1,2}(?!\d+)))+)+\W?(?!\\)", - RegexOptions.IgnoreCase | RegexOptions.Compiled), - new Regex(@"^(?<title>.+?)?\W?(?:\W(?<season>\d+)(?<episode>\d{2}))+\W?(?!\\)", - RegexOptions.IgnoreCase | RegexOptions.Compiled), //Supports 103/113 naming - new Regex(@"^(?<title>.*?)?(?:\W?S?(?<season>\d{1,2}(?!\d+))(?:(?:\-|\.|[ex]|\s|to)+(?<episode>\d+))+)+\W?(?!\\)", - RegexOptions.IgnoreCase | RegexOptions.Compiled), - new Regex(@"^(?<title>.*?)\W(?:S|Season\W?)?(?<season>\d{1,2}(?!\d+))+\W?(?!\\)", - RegexOptions.IgnoreCase | RegexOptions.Compiled) //Supports Season only releases - }; - - private static readonly Regex[] SeasonReportTitleRegex = new[] - { - new Regex( - @"(?<title>.+?)?\W?(?<year>\d{4}?)?\W(?:S|Season)?\W?(?<season>\d+)(?!\\)", - RegexOptions.IgnoreCase | - RegexOptions.Compiled), - }; - - private static readonly Regex NormalizeRegex = new Regex(@"((^|\W)(a|an|the|and|or|of)($|\W))|\W|\b(?!(?:19\d{2}|20\d{2}))\d+\b", - RegexOptions.IgnoreCase | RegexOptions.Compiled); - - /// <summary> - /// Parses a post title into list of episodes it contains - /// </summary> - /// <param name = "title">Title of the report</param> - /// <returns>List of episodes contained to the post</returns> - internal static EpisodeParseResult ParseEpisodeInfo(string title) - { - Logger.Trace("Parsing string '{0}'", title); - - foreach (var regex in ReportTitleRegex) - { - var simpleTitle = Regex.Replace(title, @"480[i|p]|720[i|p]|1080[i|p]|[x|h]264", String.Empty, RegexOptions.IgnoreCase | RegexOptions.Compiled); - - var match = regex.Matches(simpleTitle); - - if (match.Count != 0) - { - var seriesName = NormalizeTitle(match[0].Groups["title"].Value); - - var airyear = 0; - Int32.TryParse(match[0].Groups["airyear"].Value, out airyear); - - EpisodeParseResult parsedEpisode; - - if (airyear < 1) - { - var season = 0; - Int32.TryParse(match[0].Groups["season"].Value, out season); - - parsedEpisode = new EpisodeParseResult - { - Proper = title.ToLower().Contains("proper"), - CleanTitle = seriesName, - SeasonNumber = season, - Episodes = new List<int>() - }; - - foreach (Match matchGroup in match) - { +using System; +using System.Collections.Generic; +using System.IO; +using System.Text.RegularExpressions; +using NLog; +using NzbDrone.Core.Model; +using NzbDrone.Core.Repository.Quality; + +namespace NzbDrone.Core +{ + public static class Parser + { + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + + private static readonly Regex[] ReportTitleRegex = new[] + { + new Regex(@"^(?<title>.+?)?\W*(?<airyear>\d{4})\W+(?<airmonth>\d{2})\W+(?<airday>\d{2})\W?(?!\\)", + RegexOptions.IgnoreCase | RegexOptions.Compiled), + new Regex(@"^(?<title>.*?)?(?:\W?S?(?<season>\d{1,2}(?!\d+))(?:(?:\-|\.|[ex]|\s|\sto\s){1,2}(?<episode>\d{1,2}(?!\d+)))+)+\W?(?!\\)", + RegexOptions.IgnoreCase | RegexOptions.Compiled), + new Regex(@"^(?<title>.+?)?\W?(?:\W(?<season>\d+)(?<episode>\d{2}))+\W?(?!\\)", + RegexOptions.IgnoreCase | RegexOptions.Compiled), //Supports 103/113 naming + new Regex(@"^(?<title>.*?)?(?:\W?S?(?<season>\d{1,2}(?!\d+))(?:(?:\-|\.|[ex]|\s|to)+(?<episode>\d+))+)+\W?(?!\\)", + RegexOptions.IgnoreCase | RegexOptions.Compiled), + new Regex(@"^(?<title>.*?)\W(?:S|Season\W?)?(?<season>\d{1,2}(?!\d+))+\W?(?!\\)", + RegexOptions.IgnoreCase | RegexOptions.Compiled) //Supports Season only releases + }; + + private static readonly Regex[] SeasonReportTitleRegex = new[] + { + new Regex( + @"(?<title>.+?)?\W?(?<year>\d{4}?)?\W(?:S|Season)?\W?(?<season>\d+)(?!\\)", + RegexOptions.IgnoreCase | + RegexOptions.Compiled), + }; + + private static readonly Regex NormalizeRegex = new Regex(@"((^|\W)(a|an|the|and|or|of)($|\W))|\W|\b(?!(?:19\d{2}|20\d{2}))\d+\b", + RegexOptions.IgnoreCase | RegexOptions.Compiled); + + /// <summary> + /// Parses a post title into list of episodes it contains + /// </summary> + /// <param name = "title">Title of the report</param> + /// <returns>List of episodes contained to the post</returns> + internal static EpisodeParseResult ParseEpisodeInfo(string title) + { + Logger.Trace("Parsing string '{0}'", title); + + foreach (var regex in ReportTitleRegex) + { + var simpleTitle = Regex.Replace(title, @"480[i|p]|720[i|p]|1080[i|p]|[x|h]264", String.Empty, RegexOptions.IgnoreCase | RegexOptions.Compiled); + + var match = regex.Matches(simpleTitle); + + if (match.Count != 0) + { + var seriesName = NormalizeTitle(match[0].Groups["title"].Value); + + var airyear = 0; + Int32.TryParse(match[0].Groups["airyear"].Value, out airyear); + + EpisodeParseResult parsedEpisode; + + if (airyear < 1) + { + var season = 0; + Int32.TryParse(match[0].Groups["season"].Value, out season); + + parsedEpisode = new EpisodeParseResult + { + Proper = title.ToLower().Contains("proper"), + CleanTitle = seriesName, + SeasonNumber = season, + Episodes = new List<int>() + }; + + foreach (Match matchGroup in match) + { var count = matchGroup.Groups["episode"].Captures.Count; //Allows use to return a list of 0 episodes (We can handle that as a full season release) @@ -88,209 +88,209 @@ namespace NzbDrone.Core { parsedEpisode.Episodes.Add(i); } - } - } - } - - else - { - //Try to Parse as a daily show - if (airyear > 0) - { - var airmonth = Convert.ToInt32(match[0].Groups["airmonth"].Value); - var airday = Convert.ToInt32(match[0].Groups["airday"].Value); - - parsedEpisode = new EpisodeParseResult - { - Proper = title.ToLower().Contains("proper"), - CleanTitle = seriesName, - AirDate = new DateTime(airyear, airmonth, airday) - }; - } - - //Something went wrong with this one... return null - else - return null; - } - - parsedEpisode.Quality = ParseQuality(title); - - Logger.Trace("Episode Parsed. {0}", parsedEpisode); - - return parsedEpisode; - } - } - Logger.Debug("Unable to parse text into episode info. {0}", title); - return null; - } - - /// <summary> - /// Parses a post title into season it contains - /// </summary> - /// <param name = "title">Title of the report</param> - /// <returns>Season information contained in the post</returns> - internal static SeasonParseResult ParseSeasonInfo(string title) - { - Logger.Trace("Parsing string '{0}'", title); - - foreach (var regex in ReportTitleRegex) - { - var match = regex.Matches(title); - - if (match.Count != 0) - { - var seriesName = NormalizeTitle(match[0].Groups["title"].Value); - int year; - Int32.TryParse(match[0].Groups["year"].Value, out year); - - if (year < 1900 || year > DateTime.Now.Year + 1) - { - year = 0; - } - - var seasonNumber = Convert.ToInt32(match[0].Groups["season"].Value); - - var result = new SeasonParseResult - { - SeriesTitle = seriesName, - SeasonNumber = seasonNumber, - Year = year, - Quality = ParseQuality(title) - }; - - - Logger.Trace("Season Parsed. {0}", result); - return result; - } - } - - return null; //Return null - } - - /// <summary> - /// Parses a post title to find the series that relates to it - /// </summary> - /// <param name = "title">Title of the report</param> - /// <returns>Normalized Series Name</returns> - internal static string ParseSeriesName(string title) - { - Logger.Trace("Parsing string '{0}'", title); - - foreach (var regex in ReportTitleRegex) - { - var match = regex.Matches(title); - - if (match.Count != 0) - { - var seriesName = NormalizeTitle(match[0].Groups["title"].Value); - - Logger.Trace("Series Parsed. {0}", seriesName); - return seriesName; - } - } - - return String.Empty; - } - - /// <summary> - /// Parses proper status out of a report title - /// </summary> - /// <param name = "title">Title of the report</param> - /// <returns></returns> - internal static bool ParseProper(string title) - { - return title.ToLower().Contains("proper"); - } - - internal static QualityTypes ParseQuality(string name) - { - Logger.Trace("Trying to parse quality for {0}", name); - - var result = QualityTypes.Unknown; - name = name.ToLowerInvariant(); - - if (name.Contains("dvd")) - return QualityTypes.DVD; - - if (name.Contains("bdrip") || name.Contains("brrip")) - { - return QualityTypes.BDRip; - } - - if (name.Contains("xvid") || name.Contains("divx")) - { - if (name.Contains("bluray")) - { - return QualityTypes.BDRip; - } - - return QualityTypes.TV; - } - - if (name.Contains("bluray")) - { - if (name.Contains("720p")) - return QualityTypes.Bluray720; - - if (name.Contains("1080p")) - return QualityTypes.Bluray1080; - - return QualityTypes.Bluray720; - } - if (name.Contains("web-dl")) - return QualityTypes.WEBDL; - if (name.Contains("x264") || name.Contains("h264") || name.Contains("720p")) - return QualityTypes.HDTV; - - //Based on extension - if (result == QualityTypes.Unknown && Path.HasExtension(name)) - { - switch (Path.GetExtension(name).ToLower()) - { - case ".avi": - case ".xvid": - case ".wmv": - { - result = QualityTypes.TV; - break; - } - case ".mkv": - { - result = QualityTypes.HDTV; - break; - } - } - } - - Logger.Trace("Quality Parsed:{0} Title:", result, name); - return result; - } - - /// <summary> - /// Normalizes the title. removing all non-word characters as well as common tokens - /// such as 'the' and 'and' - /// </summary> - /// <param name = "title">title</param> - /// <returns></returns> - public static string NormalizeTitle(string title) - { - return NormalizeRegex.Replace(title, String.Empty).ToLower(); - } - - - public static string NormalizePath(string path) - { - if (String.IsNullOrWhiteSpace(path)) - throw new ArgumentException("Path can not be null or empty"); - - var info = new FileInfo(path); - - if (info.FullName.StartsWith(@"\\")) //UNC - { - return info.FullName.TrimEnd('/', '\\', ' '); - } - - return info.FullName.Trim('/', '\\', ' '); - } - } -}��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� + } + } + } + + else + { + //Try to Parse as a daily show + if (airyear > 0) + { + var airmonth = Convert.ToInt32(match[0].Groups["airmonth"].Value); + var airday = Convert.ToInt32(match[0].Groups["airday"].Value); + + parsedEpisode = new EpisodeParseResult + { + Proper = title.ToLower().Contains("proper"), + CleanTitle = seriesName, + AirDate = new DateTime(airyear, airmonth, airday) + }; + } + + //Something went wrong with this one... return null + else + return null; + } + + parsedEpisode.Quality = ParseQuality(title); + + Logger.Trace("Episode Parsed. {0}", parsedEpisode); + + return parsedEpisode; + } + } + Logger.Debug("Unable to parse text into episode info. {0}", title); + return null; + } + + /// <summary> + /// Parses a post title into season it contains + /// </summary> + /// <param name = "title">Title of the report</param> + /// <returns>Season information contained in the post</returns> + internal static SeasonParseResult ParseSeasonInfo(string title) + { + Logger.Trace("Parsing string '{0}'", title); + + foreach (var regex in ReportTitleRegex) + { + var match = regex.Matches(title); + + if (match.Count != 0) + { + var seriesName = NormalizeTitle(match[0].Groups["title"].Value); + int year; + Int32.TryParse(match[0].Groups["year"].Value, out year); + + if (year < 1900 || year > DateTime.Now.Year + 1) + { + year = 0; + } + + var seasonNumber = Convert.ToInt32(match[0].Groups["season"].Value); + + var result = new SeasonParseResult + { + SeriesTitle = seriesName, + SeasonNumber = seasonNumber, + Year = year, + Quality = ParseQuality(title) + }; + + + Logger.Trace("Season Parsed. {0}", result); + return result; + } + } + + return null; //Return null + } + + /// <summary> + /// Parses a post title to find the series that relates to it + /// </summary> + /// <param name = "title">Title of the report</param> + /// <returns>Normalized Series Name</returns> + internal static string ParseSeriesName(string title) + { + Logger.Trace("Parsing string '{0}'", title); + + foreach (var regex in ReportTitleRegex) + { + var match = regex.Matches(title); + + if (match.Count != 0) + { + var seriesName = NormalizeTitle(match[0].Groups["title"].Value); + + Logger.Trace("Series Parsed. {0}", seriesName); + return seriesName; + } + } + + return String.Empty; + } + + /// <summary> + /// Parses proper status out of a report title + /// </summary> + /// <param name = "title">Title of the report</param> + /// <returns></returns> + internal static bool ParseProper(string title) + { + return title.ToLower().Contains("proper"); + } + + internal static QualityTypes ParseQuality(string name) + { + Logger.Trace("Trying to parse quality for {0}", name); + + var result = QualityTypes.Unknown; + name = name.ToLowerInvariant(); + + if (name.Contains("dvd")) + return QualityTypes.DVD; + + if (name.Contains("bdrip") || name.Contains("brrip")) + { + return QualityTypes.BDRip; + } + + if (name.Contains("xvid") || name.Contains("divx")) + { + if (name.Contains("bluray")) + { + return QualityTypes.BDRip; + } + + return QualityTypes.TV; + } + + if (name.Contains("bluray")) + { + if (name.Contains("720p")) + return QualityTypes.Bluray720; + + if (name.Contains("1080p")) + return QualityTypes.Bluray1080; + + return QualityTypes.Bluray720; + } + if (name.Contains("web-dl")) + return QualityTypes.WEBDL; + if (name.Contains("x264") || name.Contains("h264") || name.Contains("720p")) + return QualityTypes.HDTV; + + //Based on extension + if (result == QualityTypes.Unknown && Path.HasExtension(name)) + { + switch (Path.GetExtension(name).ToLower()) + { + case ".avi": + case ".xvid": + case ".wmv": + { + result = QualityTypes.TV; + break; + } + case ".mkv": + { + result = QualityTypes.HDTV; + break; + } + } + } + + Logger.Trace("Quality Parsed:{0} Title:", result, name); + return result; + } + + /// <summary> + /// Normalizes the title. removing all non-word characters as well as common tokens + /// such as 'the' and 'and' + /// </summary> + /// <param name = "title">title</param> + /// <returns></returns> + public static string NormalizeTitle(string title) + { + return NormalizeRegex.Replace(title, String.Empty).ToLower(); + } + + + public static string NormalizePath(string path) + { + if (String.IsNullOrWhiteSpace(path)) + throw new ArgumentException("Path can not be null or empty"); + + var info = new FileInfo(path); + + if (info.FullName.StartsWith(@"\\")) //UNC + { + return info.FullName.TrimEnd('/', '\\', ' '); + } + + return info.FullName.Trim('/', '\\', ' '); + } + } +}��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� diff --git a/NzbDrone.Core/Providers/SeriesProvider.cs b/NzbDrone.Core/Providers/SeriesProvider.cs index 6bdee1408..62d22fe87 100644 --- a/NzbDrone.Core/Providers/SeriesProvider.cs +++ b/NzbDrone.Core/Providers/SeriesProvider.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Linq; +using System.Text.RegularExpressions; using NLog; using NzbDrone.Core.Providers.Core; using NzbDrone.Core.Repository; @@ -76,7 +77,7 @@ namespace NzbDrone.Core.Providers series.SeriesId = tvDbSeries.Id; series.Title = tvDbSeries.SeriesName; - series.AirTimes = tvDbSeries.AirsTime; + series.AirTimes = CleanAirsTime(tvDbSeries.AirsTime); series.AirsDayOfWeek = tvDbSeries.AirsDayOfWeek; series.Overview = tvDbSeries.Overview; series.Status = tvDbSeries.Status; @@ -155,5 +156,29 @@ namespace NzbDrone.Core.Providers return false; } + + /// <summary> + /// Cleans up the AirsTime Component from TheTVDB since it can be garbage that comes in. + /// </summary> + /// <param name = "input">The TVDB AirsTime</param> + /// <returns>String that contains the AirTimes</returns> + private string CleanAirsTime(string inputTime) + { + Regex timeRegex = new Regex(@"^(?<time>\d+:?\d*)\W*(?<meridiem>am|pm)?", RegexOptions.IgnoreCase | RegexOptions.Compiled); + + var match = timeRegex.Match(inputTime); + var time = match.Groups["time"].Value; + var meridiem = match.Groups["meridiem"].Value; + + //Lets assume that a string that doesn't contain a Merideim is aired at night... So we'll add it + if (String.IsNullOrEmpty(meridiem)) + meridiem = "PM"; + + if (String.IsNullOrEmpty(time)) + return String.Empty; + + var dateTime = DateTime.Parse(time + " " + meridiem); + return dateTime.ToString("hh:mm tt"); + } } } \ No newline at end of file diff --git a/NzbDrone.Web/Controllers/UpcomingController.cs b/NzbDrone.Web/Controllers/UpcomingController.cs index f0b5af4fe..af264a4a4 100644 --- a/NzbDrone.Web/Controllers/UpcomingController.cs +++ b/NzbDrone.Web/Controllers/UpcomingController.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System; +using System.Linq; using System.Web.Mvc; using NzbDrone.Core.Providers; using NzbDrone.Web.Models; @@ -34,7 +35,7 @@ namespace NzbDrone.Web.Controllers EpisodeNumber = e.EpisodeNumber, Title = e.Title, Overview = e.Overview, - AirDate = e.AirDate + AirDate = e.AirDate.Add(Convert.ToDateTime(e.Series.AirTimes).TimeOfDay) }); return View(new GridModel(upcoming)); @@ -51,7 +52,7 @@ namespace NzbDrone.Web.Controllers EpisodeNumber = e.EpisodeNumber, Title = e.Title, Overview = e.Overview, - AirDate = e.AirDate + AirDate = e.AirDate.Add(Convert.ToDateTime(e.Series.AirTimes).TimeOfDay) }); return View(new GridModel(upcoming)); @@ -68,7 +69,7 @@ namespace NzbDrone.Web.Controllers EpisodeNumber = e.EpisodeNumber, Title = e.Title, Overview = e.Overview, - AirDate = e.AirDate + AirDate = e.AirDate.Add(Convert.ToDateTime(e.Series.AirTimes).TimeOfDay) }); return View(new GridModel(upcoming)); diff --git a/NzbDrone.Web/Views/Upcoming/Index.cshtml b/NzbDrone.Web/Views/Upcoming/Index.cshtml index 0476e15d4..b835206e1 100644 --- a/NzbDrone.Web/Views/Upcoming/Index.cshtml +++ b/NzbDrone.Web/Views/Upcoming/Index.cshtml @@ -24,7 +24,7 @@ Upcoming columns.Bound(c => c.SeasonNumber).Title("Season #").Width(40); columns.Bound(c => c.EpisodeNumber).Title("Episode #").Width(40); columns.Bound(c => c.Title).Title("Episode Title"); - columns.Bound(c => c.AirDate).Title("Air Date").Width(0); + columns.Bound(c => c.AirDate).Title("Air Date").Width(160); }) .DetailView(detailView => detailView.ClientTemplate( "<fieldset>" + @@ -54,7 +54,7 @@ Upcoming columns.Bound(c => c.SeasonNumber).Title("Season #").Width(40); columns.Bound(c => c.EpisodeNumber).Title("Episode #").Width(40); columns.Bound(c => c.Title).Title("Episode Title"); - columns.Bound(c => c.AirDate).Title("Air Date").Width(0); + columns.Bound(c => c.AirDate).Title("Air Date").Width(160); }) .DetailView(detailView => detailView.ClientTemplate( "<fieldset>" + @@ -82,7 +82,7 @@ Upcoming columns.Bound(c => c.SeasonNumber).Title("Season #").Width(40); columns.Bound(c => c.EpisodeNumber).Title("Episode #").Width(40); columns.Bound(c => c.Title).Title("Episode Title"); - columns.Bound(c => c.AirDate).Title("Air Date").Width(0); + columns.Bound(c => c.AirDate).Title("Air Date").Width(160); }) .DetailView(detailView => detailView.ClientTemplate( "<fieldset>" +