diff --git a/src/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs b/src/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs index 5de2ae56d..c87a3bc16 100644 --- a/src/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs +++ b/src/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs @@ -80,8 +80,9 @@ private IEnumerable GetDecisions(List reports, Se if (remoteEpisode.Series == null) { - remoteEpisode.DownloadAllowed = true; //Fuck you :) - decision = GetDecisionForReport(remoteEpisode, searchCriteria); + //remoteEpisode.DownloadAllowed = true; //Fuck you :) + //decision = GetDecisionForReport(remoteEpisode, searchCriteria); + decision = new DownloadDecision(remoteEpisode, new Rejection("Unknown release. Movie not Found.")); } else if (remoteEpisode.Episodes.Empty()) { diff --git a/src/NzbDrone.Core/MediaFiles/EpisodeImport/Specifications/FullSeasonSpecification.cs b/src/NzbDrone.Core/MediaFiles/EpisodeImport/Specifications/FullSeasonSpecification.cs index 7397c13e7..853f6b1b7 100644 --- a/src/NzbDrone.Core/MediaFiles/EpisodeImport/Specifications/FullSeasonSpecification.cs +++ b/src/NzbDrone.Core/MediaFiles/EpisodeImport/Specifications/FullSeasonSpecification.cs @@ -17,8 +17,8 @@ public Decision IsSatisfiedBy(LocalEpisode localEpisode) { if (localEpisode.ParsedEpisodeInfo.FullSeason) { - _logger.Debug("Single episode file detected as containing all episodes in the season"); - return Decision.Reject("Single episode file contains all episodes in seasons"); + //_logger.Debug("Single episode file detected as containing all episodes in the season"); //Not needed for Movies mwhahahahah + //return Decision.Reject("Single episode file contains all episodes in seasons"); } return Decision.Accept(); diff --git a/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs b/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs index 3aaaf41aa..785257c94 100644 --- a/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs +++ b/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs @@ -65,7 +65,7 @@ public Tuple> GetSeriesInfo(int tvdbSeriesId) series.Title = json.Title; series.TitleSlug = series.Title.ToLower().Replace(" ", "-"); series.Overview = json.Plot; - series.CleanTitle = series.Title; + series.CleanTitle = Parser.Parser.CleanSeriesTitle(series.Title); series.TvdbId = tvdbSeriesId; string airDateStr = json.Released; DateTime airDate = DateTime.Parse(airDateStr); @@ -76,6 +76,10 @@ public Tuple> GetSeriesInfo(int tvdbSeriesId) string url = json.Poster; var imdbPoster = new MediaCover.MediaCover(MediaCoverTypes.Poster, url); series.Images.Add(imdbPoster); + string runtime = json.Runtime; + int runtimeNum = 0; + int.TryParse(runtime.Replace("min", "").Trim(), out runtimeNum); + series.Runtime = runtimeNum; var season = new Season(); season.SeasonNumber = 1; @@ -85,7 +89,7 @@ public Tuple> GetSeriesInfo(int tvdbSeriesId) var episode = new Episode(); - episode.AirDate = airDate.ToShortTimeString(); + episode.AirDate = airDate.ToBestDateString(); episode.Title = json.Title; episode.SeasonNumber = 1; episode.EpisodeNumber = 1; diff --git a/src/NzbDrone.Core/Parser/Parser.cs b/src/NzbDrone.Core/Parser/Parser.cs index 9b8759bd1..f482c2c9a 100644 --- a/src/NzbDrone.Core/Parser/Parser.cs +++ b/src/NzbDrone.Core/Parser/Parser.cs @@ -26,6 +26,10 @@ public static class Parser new Regex(@"^(?:\W*S?(?(?\d{1,3}(?!\d+)))+){2,}", RegexOptions.IgnoreCase | RegexOptions.Compiled), + //Matches Movie name with AirYear + new Regex(@"^(?.+?)?(?:(?:[-_\W](?<![()\[!]))*(?<year>(?<!e|x)\d{4}(?!p|i|\d+|\)|\]|\W\d+)))+(\W+|_|$)(?!\\)", + RegexOptions.IgnoreCase | RegexOptions.Compiled), + //Episodes without a title, Single (S01E05, 1x05) AND Multi (S01E04E05, 1x04x05, etc) new Regex(@"^(?:S?(?<season>(?<!\d+)(?:\d{1,2}|\d{4})(?!\d+))(?:(?:\-|[ex]|\W[ex]|_){1,2}(?<episode>\d{2,3}(?!\d+)))+)", RegexOptions.IgnoreCase | RegexOptions.Compiled), @@ -296,6 +300,8 @@ public static ParsedEpisodeInfo ParsePath(string path) public static ParsedEpisodeInfo ParseTitle(string title) { + + ParsedEpisodeInfo realResult = null; try { if (!ValidateBeforeParsing(title)) return null; @@ -342,6 +348,8 @@ public static ParsedEpisodeInfo ParseTitle(string title) } } + + foreach (var regex in ReportTitleRegex) { var match = regex.Matches(simpleTitle); @@ -383,6 +391,8 @@ public static ParsedEpisodeInfo ParseTitle(string title) Logger.Debug("Release Hash parsed: {0}", result.ReleaseHash); } + realResult = result; + return result; } } @@ -401,7 +411,7 @@ public static ParsedEpisodeInfo ParseTitle(string title) } Logger.Debug("Unable to parse {0}", title); - return null; + return realResult; } public static string ParseSeriesName(string title) @@ -525,6 +535,7 @@ private static ParsedEpisodeInfo ParseMatchCollection(MatchCollection matchColle int airYear; int.TryParse(matchCollection[0].Groups["airyear"].Value, out airYear); + //int.TryParse(matchCollection[0].Groups["year"].Value, out airYear); ParsedEpisodeInfo result; diff --git a/src/NzbDrone.Core/Parser/ParsingService.cs b/src/NzbDrone.Core/Parser/ParsingService.cs index 4ab4fd4c7..777c5d0ed 100644 --- a/src/NzbDrone.Core/Parser/ParsingService.cs +++ b/src/NzbDrone.Core/Parser/ParsingService.cs @@ -100,7 +100,7 @@ public Series GetSeries(string title) if (parsedEpisodeInfo == null) { - return _seriesService.FindByTitle(title); + return _seriesService.FindByTitle(title); //Here we have a problem since it is not possible for movies to find a scene mapping, so these releases are always rejected :( } var series = _seriesService.FindByTitle(parsedEpisodeInfo.SeriesTitle); @@ -252,10 +252,12 @@ private Series GetSeries(ParsedEpisodeInfo parsedEpisodeInfo, int tvdbId, int tv { Series series = null; + /*var localEpisode = _seriesService.FindByTitle(parsedEpisodeInfo.SeriesTitle); + var sceneMappingTvdbId = _sceneMappingService.FindTvdbId(parsedEpisodeInfo.SeriesTitle); - if (sceneMappingTvdbId.HasValue) + if (localEpisode != null) { - if (searchCriteria != null && searchCriteria.Series.TvdbId == sceneMappingTvdbId.Value) + if (searchCriteria != null && searchCriteria.Series.TvdbId == localEpisode.TvdbId) { return searchCriteria.Series; } @@ -269,7 +271,7 @@ private Series GetSeries(ParsedEpisodeInfo parsedEpisodeInfo, int tvdbId, int tv } return series; - } + }*/ //This is only to find scene mapping should not be necessary for movies. if (searchCriteria != null) { diff --git a/src/NzbDrone.Core/Qualities/Quality.cs b/src/NzbDrone.Core/Qualities/Quality.cs index 6476e5766..2230b7320 100644 --- a/src/NzbDrone.Core/Qualities/Quality.cs +++ b/src/NzbDrone.Core/Qualities/Quality.cs @@ -114,7 +114,7 @@ static Quality() new QualityDefinition(Quality.WEBDL720p) { Weight = 8, MinSize = 0, MaxSize = 100 }, new QualityDefinition(Quality.Bluray720p) { Weight = 9, MinSize = 0, MaxSize = 100 }, new QualityDefinition(Quality.WEBDL1080p) { Weight = 10, MinSize = 0, MaxSize = 100 }, - new QualityDefinition(Quality.Bluray1080p) { Weight = 11, MinSize = 0, MaxSize = 100 }, + new QualityDefinition(Quality.Bluray1080p) { Weight = 11, MinSize = 0, MaxSize = null }, new QualityDefinition(Quality.HDTV2160p) { Weight = 12, MinSize = 0, MaxSize = null }, new QualityDefinition(Quality.WEBDL2160p) { Weight = 13, MinSize = 0, MaxSize = null }, new QualityDefinition(Quality.Bluray2160p) { Weight = 14, MinSize = 0, MaxSize = null }, diff --git a/src/UI/Cells/EpisodeActionsCell.js b/src/UI/Cells/EpisodeActionsCell.js index 383942d34..0a8d20211 100644 --- a/src/UI/Cells/EpisodeActionsCell.js +++ b/src/UI/Cells/EpisodeActionsCell.js @@ -35,10 +35,11 @@ module.exports = NzbDroneCell.extend({ }, _manualSearch : function() { + console.warn(this.cellValue); vent.trigger(vent.Commands.ShowEpisodeDetails, { episode : this.cellValue, hideSeriesLink : true, openingTab : 'search' }); } -}); \ No newline at end of file +}); diff --git a/src/UI/Controller.js b/src/UI/Controller.js index f1e4032ab..ef901c60a 100644 --- a/src/UI/Controller.js +++ b/src/UI/Controller.js @@ -13,7 +13,7 @@ var SeriesEditorLayout = require('./Series/Editor/SeriesEditorLayout'); module.exports = NzbDroneController.extend({ addSeries : function(action) { - this.setTitle('Add Series'); + this.setTitle('Add Movie'); this.showMainRegion(new AddSeriesLayout({ action : action })); }, @@ -56,4 +56,4 @@ module.exports = NzbDroneController.extend({ this.setTitle('Series Editor'); this.showMainRegion(new SeriesEditorLayout()); } -}); \ No newline at end of file +}); diff --git a/src/UI/Handlebars/Helpers/Series.js b/src/UI/Handlebars/Helpers/Series.js index 2c8a96bed..4bac9e659 100644 --- a/src/UI/Handlebars/Helpers/Series.js +++ b/src/UI/Handlebars/Helpers/Series.js @@ -11,7 +11,7 @@ Handlebars.registerHelper('poster', function() { if (!poster[0].url.match(/^https?:\/\//)) { return new Handlebars.SafeString('<img class="series-poster x-series-poster" {0}>'.format(Handlebars.helpers.defaultImg.call(null, poster[0].url, 250))); } else { - var url = poster[0].url.replace(/^https?\:/, ''); + var url = poster[0].url.replace(/^https?\:/, 'https://'); //IMDb posters need https to work, k? return new Handlebars.SafeString('<img class="series-poster x-series-poster" {0}>'.format(Handlebars.helpers.defaultImg.call(null, url))); } } @@ -28,7 +28,7 @@ Handlebars.registerHelper('imdbUrl', function() { }); Handlebars.registerHelper('tvdbUrl', function() { - return 'http://www.thetvdb.com/?tab=series&id=' + this.tvdbId; + return 'http://imdb.com/title/tt' + this.tvdbId; }); Handlebars.registerHelper('tvRageUrl', function() { diff --git a/src/UI/Series/Details/InfoViewTemplate.hbs b/src/UI/Series/Details/InfoViewTemplate.hbs index b52130246..666003f77 100644 --- a/src/UI/Series/Details/InfoViewTemplate.hbs +++ b/src/UI/Series/Details/InfoViewTemplate.hbs @@ -29,9 +29,9 @@ </div> <div class="col-md-3"> <span class="series-info-links"> - <a href="{{traktUrl}}" class="label label-info">Trakt</a> + <!--<a href="{{traktUrl}}" class="label label-info">Trakt</a> - <a href="{{tvdbUrl}}" class="label label-info">The TVDB</a> + <a href="{{tvdbUrl}}" class="label label-info">The TVDB</a>--> {{#if imdbId}} <a href="{{imdbUrl}}" class="label label-info">IMDB</a> diff --git a/src/UI/Series/Details/SeriesDetailsLayout.js b/src/UI/Series/Details/SeriesDetailsLayout.js index f33cb0414..d869b47c9 100644 --- a/src/UI/Series/Details/SeriesDetailsLayout.js +++ b/src/UI/Series/Details/SeriesDetailsLayout.js @@ -32,7 +32,8 @@ module.exports = Marionette.Layout.extend({ refresh : '.x-refresh', rename : '.x-rename', search : '.x-search', - poster : '.x-series-poster' + poster : '.x-series-poster', + manualSearch : '.x-manual-search' }, events : { @@ -41,7 +42,8 @@ module.exports = Marionette.Layout.extend({ 'click .x-edit' : '_editSeries', 'click .x-refresh' : '_refreshSeries', 'click .x-rename' : '_renameSeries', - 'click .x-search' : '_seriesSearch' + 'click .x-search' : '_seriesSearch', + 'click .x-manual-search' : '_manualSearchM' }, initialize : function() { @@ -178,11 +180,11 @@ module.exports = Marionette.Layout.extend({ if (self.model.get('id') !== seriesId) { return []; } - + if (sceneSeasonNumber === undefined) { sceneSeasonNumber = seasonNumber; } - + return _.where(self.model.get('alternateTitles'), function(alt) { return alt.sceneSeasonNumber === sceneSeasonNumber || alt.seasonNumber === seasonNumber; @@ -254,5 +256,17 @@ module.exports = Marionette.Layout.extend({ } else { $('body').removeClass('backdrop'); } + }, + + _manualSearchM : function() { + console.warn("Manual Search started"); + console.warn(this.model.get("seriesId")); + console.warn(this.model) + console.warn(this.episodeCollection); + vent.trigger(vent.Commands.ShowEpisodeDetails, { + episode : this.episodeCollection.models[0], + hideSeriesLink : true, + openingTab : 'search' + }); } -}); \ No newline at end of file +}); diff --git a/src/UI/Series/Details/SeriesDetailsTemplate.hbs b/src/UI/Series/Details/SeriesDetailsTemplate.hbs index 818cee455..04978e3d4 100644 --- a/src/UI/Series/Details/SeriesDetailsTemplate.hbs +++ b/src/UI/Series/Details/SeriesDetailsTemplate.hbs @@ -5,23 +5,26 @@ <div class="col-md-12 col-lg-10"> <div> <h1 class="header-text"> - <i class="x-monitored" title="Toggle monitored state for entire series"/> + <i class="x-monitored" title="Toggle monitored state for movie"/> {{title}} <div class="series-actions pull-right"> <div class="x-episode-file-editor"> - <i class="icon-sonarr-episode-file" title="Modify episode files for series"/> + <i class="icon-sonarr-episode-file" title="Modify episode files for movie"/> </div> <div class="x-refresh"> - <i class="icon-sonarr-refresh icon-can-spin" title="Update series info and scan disk"/> + <i class="icon-sonarr-refresh icon-can-spin" title="Update movie info and scan disk"/> </div> <div class="x-rename"> <i class="icon-sonarr-rename" title="Preview rename for all episodes"/> </div> <div class="x-search"> - <i class="icon-sonarr-search" title="Search for monitored episodes in this series"/> + <i class="icon-sonarr-search" title="Search for movie"/> + </div> + <div class="x-manual-search"> + <i class="icon-sonarr-search-manual" title="Manual Search"/> </div> <div class="x-edit"> - <i class="icon-sonarr-edit" title="Edit series"/> + <i class="icon-sonarr-edit" title="Edit movie"/> </div> </div> </h1> diff --git a/src/UI/Series/Index/SeriesIndexLayout.js b/src/UI/Series/Index/SeriesIndexLayout.js index f5f47b983..f79d17a76 100644 --- a/src/UI/Series/Index/SeriesIndexLayout.js +++ b/src/UI/Series/Index/SeriesIndexLayout.js @@ -80,7 +80,7 @@ module.exports = Marionette.Layout.extend({ collapse : true, items : [ { - title : 'Add Series', + title : 'Add Movie', icon : 'icon-sonarr-add', route : 'addseries' },