From 0f2234bcdc653e6a0df5739d2d34e6a0d0c5fcf9 Mon Sep 17 00:00:00 2001 From: Devin Buhl Date: Sat, 4 Mar 2017 11:40:38 -0500 Subject: [PATCH] Patch/onedr0p 3 4 2017 (#1006) * Fix link in History tab (#734) * Fix iCal feed (#746) * Removed DKSubs from hardcoded subs * Fix searching all cut off unmet --- .../Calendar/CalendarFeedModule.cs | 75 +++++++++++-------- .../ParserTests/QualityParserFixture.cs | 2 - .../CutoffUnmetMoviesSearchCommand.cs | 11 +++ .../IndexerSearch/MoviesSearchService.cs | 24 +++++- src/NzbDrone.Core/NzbDrone.Core.csproj | 1 + src/NzbDrone.Core/Parser/QualityParser.cs | 2 +- src/NzbDrone.Core/Tv/MovieRepository.cs | 2 +- src/UI/Activity/History/HistoryLayout.js | 18 +---- src/UI/Calendar/CalendarLayoutTemplate.hbs | 1 - src/UI/Cells/MovieTitleHistoryCell.js | 12 --- src/UI/Wanted/Cutoff/CutoffUnmetLayout.js | 4 +- 11 files changed, 85 insertions(+), 67 deletions(-) create mode 100644 src/NzbDrone.Core/IndexerSearch/CutoffUnmetMoviesSearchCommand.cs delete mode 100644 src/UI/Cells/MovieTitleHistoryCell.js diff --git a/src/NzbDrone.Api/Calendar/CalendarFeedModule.cs b/src/NzbDrone.Api/Calendar/CalendarFeedModule.cs index 685c5cf16..65ba3710b 100644 --- a/src/NzbDrone.Api/Calendar/CalendarFeedModule.cs +++ b/src/NzbDrone.Api/Calendar/CalendarFeedModule.cs @@ -16,13 +16,13 @@ namespace NzbDrone.Api.Calendar { public class CalendarFeedModule : NzbDroneFeedModule { - private readonly IEpisodeService _episodeService; + private readonly IMovieService _movieService; private readonly ITagService _tagService; - public CalendarFeedModule(IEpisodeService episodeService, ITagService tagService) + public CalendarFeedModule(IMovieService movieService, ITagService tagService) : base("calendar") { - _episodeService = episodeService; + _movieService = movieService; _tagService = tagService; Get["/NzbDrone.ics"] = options => GetCalendarFeed(); @@ -37,7 +37,7 @@ namespace NzbDrone.Api.Calendar var start = DateTime.Today.AddDays(-pastDays); var end = DateTime.Today.AddDays(futureDays); var unmonitored = false; - var premiersOnly = false; + //var premiersOnly = false; var tags = new List(); // TODO: Remove start/end parameters in v3, they don't work well for iCal @@ -46,7 +46,7 @@ namespace NzbDrone.Api.Calendar var queryPastDays = Request.Query.PastDays; var queryFutureDays = Request.Query.FutureDays; var queryUnmonitored = Request.Query.Unmonitored; - var queryPremiersOnly = Request.Query.PremiersOnly; + // var queryPremiersOnly = Request.Query.PremiersOnly; var queryTags = Request.Query.Tags; if (queryStart.HasValue) start = DateTime.Parse(queryStart.Value); @@ -69,10 +69,10 @@ namespace NzbDrone.Api.Calendar unmonitored = bool.Parse(queryUnmonitored.Value); } - if (queryPremiersOnly.HasValue) - { - premiersOnly = bool.Parse(queryPremiersOnly.Value); - } + //if (queryPremiersOnly.HasValue) + //{ + // premiersOnly = bool.Parse(queryPremiersOnly.Value); + //} if (queryTags.HasValue) { @@ -80,43 +80,56 @@ namespace NzbDrone.Api.Calendar tags.AddRange(tagInput.Split(',').Select(_tagService.GetTag).Select(t => t.Id)); } - var episodes = _episodeService.EpisodesBetweenDates(start, end, unmonitored); + var movies = _movieService.GetMoviesBetweenDates(start, end, unmonitored); var calendar = new Ical.Net.Calendar { - ProductId = "-//sonarr.tv//Sonarr//EN" + ProductId = "-//radarr.video//Radarr//EN" }; - - - foreach (var episode in episodes.OrderBy(v => v.AirDateUtc.Value)) + foreach (var movie in movies.OrderBy(v => v.Added)) { - if (premiersOnly && (episode.SeasonNumber == 0 || episode.EpisodeNumber != 1)) - { - continue; - } - - if (tags.Any() && tags.None(episode.Series.Tags.Contains)) + if (tags.Any() && tags.None(movie.Tags.Contains)) { continue; } var occurrence = calendar.Create(); - occurrence.Uid = "NzbDrone_episode_" + episode.Id; - occurrence.Status = episode.HasFile ? EventStatus.Confirmed : EventStatus.Tentative; - occurrence.Start = new CalDateTime(episode.AirDateUtc.Value) { HasTime = true }; - occurrence.End = new CalDateTime(episode.AirDateUtc.Value.AddMinutes(episode.Series.Runtime)) { HasTime = true }; - occurrence.Description = episode.Overview; - occurrence.Categories = new List() { episode.Series.Network }; - - switch (episode.Series.SeriesType) + occurrence.Uid = "NzbDrone_movie_" + movie.Id; + occurrence.Status = movie.HasFile ? EventStatus.Confirmed : EventStatus.Tentative; + + switch (movie.Status) { - case SeriesTypes.Daily: - occurrence.Summary = $"{episode.Series.Title} - {episode.Title}"; + case MovieStatusType.PreDB: + if (movie.PhysicalRelease != null) + { + occurrence.Start = new CalDateTime(movie.PhysicalRelease.Value) { HasTime = true }; + occurrence.End = new CalDateTime(movie.PhysicalRelease.Value.AddMinutes(movie.Runtime)) { HasTime = true }; + } + break; + + case MovieStatusType.InCinemas: + if (movie.InCinemas != null) + { + occurrence.Start = new CalDateTime(movie.InCinemas.Value) { HasTime = true }; + occurrence.End = new CalDateTime(movie.InCinemas.Value.AddMinutes(movie.Runtime)) { HasTime = true }; + } break; + case MovieStatusType.Announced: + continue; // no date default: - occurrence.Summary =$"{episode.Series.Title} - {episode.SeasonNumber}x{episode.EpisodeNumber:00} - {episode.Title}"; + if (movie.PhysicalRelease != null) + { + occurrence.Start = new CalDateTime(movie.PhysicalRelease.Value) { HasTime = true }; + occurrence.End = new CalDateTime(movie.PhysicalRelease.Value.AddMinutes(movie.Runtime)) { HasTime = true }; + } break; } + + occurrence.Description = movie.Overview; + occurrence.Categories = new List() { movie.Studio }; + + occurrence.Summary = $"{movie.Title}"; + } var serializer = (IStringSerializer) new SerializerFactory().Build(calendar.GetType(), new SerializationContext()); diff --git a/src/NzbDrone.Core.Test/ParserTests/QualityParserFixture.cs b/src/NzbDrone.Core.Test/ParserTests/QualityParserFixture.cs index fcf25f4b7..cafe517f5 100644 --- a/src/NzbDrone.Core.Test/ParserTests/QualityParserFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/QualityParserFixture.cs @@ -301,8 +301,6 @@ namespace NzbDrone.Core.Test.ParserTests [TestCase("Movie.Title.2016.1080p.KORSUB.WEBRip.x264.AAC2.0-RADARR", "korsub")] [TestCase("Movie.Title.2016.1080p.KORSUBS.WEBRip.x264.AAC2.0-RADARR", "korsubs")] - [TestCase("Movie.Title.2016.1080p.DKSUB.WEBRip.x264.AAC2.0-RADARR", "dksub")] - [TestCase("Movie.Title.2016.1080p.DKSUBS.WEBRip.x264.AAC2.0-RADARR", "dksubs")] public void should_parse_hardcoded_subs(string postTitle, string sub) { QualityParser.ParseQuality(postTitle).HardcodedSubs.Should().Be(sub); diff --git a/src/NzbDrone.Core/IndexerSearch/CutoffUnmetMoviesSearchCommand.cs b/src/NzbDrone.Core/IndexerSearch/CutoffUnmetMoviesSearchCommand.cs new file mode 100644 index 000000000..b7a00ebab --- /dev/null +++ b/src/NzbDrone.Core/IndexerSearch/CutoffUnmetMoviesSearchCommand.cs @@ -0,0 +1,11 @@ +using NzbDrone.Core.Messaging.Commands; + +namespace NzbDrone.Core.IndexerSearch +{ + public class CutoffUnmetMoviesSearchCommand : Command + { + public override bool SendUpdatesToClient => true; + public string FilterKey { get; set; } + public string FilterValue { get; set; } + } +} diff --git a/src/NzbDrone.Core/IndexerSearch/MoviesSearchService.cs b/src/NzbDrone.Core/IndexerSearch/MoviesSearchService.cs index e771f5ff6..27f4940f3 100644 --- a/src/NzbDrone.Core/IndexerSearch/MoviesSearchService.cs +++ b/src/NzbDrone.Core/IndexerSearch/MoviesSearchService.cs @@ -12,21 +12,24 @@ using NzbDrone.Core.DecisionEngine; namespace NzbDrone.Core.IndexerSearch { - public class MovieSearchService : IExecute, IExecute + public class MovieSearchService : IExecute, IExecute, IExecute { private readonly IMovieService _movieService; + private readonly IMovieCutoffService _movieCutoffService; private readonly ISearchForNzb _nzbSearchService; private readonly IProcessDownloadDecisions _processDownloadDecisions; private readonly IQueueService _queueService; private readonly Logger _logger; public MovieSearchService(IMovieService movieService, + IMovieCutoffService movieCutoffService, ISearchForNzb nzbSearchService, IProcessDownloadDecisions processDownloadDecisions, IQueueService queueService, Logger logger) { _movieService = movieService; + _movieCutoffService = movieCutoffService; _nzbSearchService = nzbSearchService; _processDownloadDecisions = processDownloadDecisions; _queueService = queueService; @@ -71,6 +74,25 @@ namespace NzbDrone.Core.IndexerSearch } + public void Execute(CutoffUnmetMoviesSearchCommand message) + { + List movies = _movieCutoffService.MoviesWhereCutoffUnmet(new PagingSpec + { + Page = 1, + PageSize = 100000, + SortDirection = SortDirection.Ascending, + SortKey = "Id", + FilterExpression = _movieService.ConstructFilterExpression(message.FilterKey, message.FilterValue) + }).Records.ToList(); + + + var queue = _queueService.GetQueue().Select(q => q.Movie.Id); + var missing = movies.Where(e => !queue.Contains(e.Id)).ToList(); + + SearchForMissingMovies(missing, message.Trigger == CommandTrigger.Manual); + + } + private void SearchForMissingMovies(List movies, bool userInvokedSearch) { _logger.ProgressInfo("Performing missing search for {0} movies", movies.Count); diff --git a/src/NzbDrone.Core/NzbDrone.Core.csproj b/src/NzbDrone.Core/NzbDrone.Core.csproj index 67ed3aab1..c52a385e2 100644 --- a/src/NzbDrone.Core/NzbDrone.Core.csproj +++ b/src/NzbDrone.Core/NzbDrone.Core.csproj @@ -130,6 +130,7 @@ + diff --git a/src/NzbDrone.Core/Parser/QualityParser.cs b/src/NzbDrone.Core/Parser/QualityParser.cs index 93f706b3d..70dcd9ec2 100644 --- a/src/NzbDrone.Core/Parser/QualityParser.cs +++ b/src/NzbDrone.Core/Parser/QualityParser.cs @@ -48,7 +48,7 @@ namespace NzbDrone.Core.Parser )\b", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); - private static readonly Regex HardcodedSubsRegex = new Regex(@"\b(?(\w+SUBS?)\b)|(?(HC))\b", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); + private static readonly Regex HardcodedSubsRegex = new Regex(@"\b(?(\w+SUB)\b)|(?(HC))\b", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); private static readonly Regex RemuxRegex = new Regex(@"\b(?Remux)\b", RegexOptions.Compiled | RegexOptions.IgnoreCase); diff --git a/src/NzbDrone.Core/Tv/MovieRepository.cs b/src/NzbDrone.Core/Tv/MovieRepository.cs index 7bcd1fc96..816b6f35d 100644 --- a/src/NzbDrone.Core/Tv/MovieRepository.cs +++ b/src/NzbDrone.Core/Tv/MovieRepository.cs @@ -195,7 +195,7 @@ namespace NzbDrone.Core.Tv return pagingSpec; } - public override PagingSpec GetPaged(PagingSpec pagingSpec) + public override PagingSpec GetPaged(PagingSpec pagingSpec) { if (pagingSpec.SortKey == "downloadedQuality") { diff --git a/src/UI/Activity/History/HistoryLayout.js b/src/UI/Activity/History/HistoryLayout.js index 9f9c88f2a..3231d1cbf 100644 --- a/src/UI/Activity/History/HistoryLayout.js +++ b/src/UI/Activity/History/HistoryLayout.js @@ -2,9 +2,7 @@ var Marionette = require('marionette'); var Backgrid = require('backgrid'); var HistoryCollection = require('./HistoryCollection'); var EventTypeCell = require('../../Cells/EventTypeCell'); -var MovieTitleCell = require('../../Cells/MovieTitleHistoryCell'); -var EpisodeNumberCell = require('../../Cells/EpisodeNumberCell'); -var EpisodeTitleCell = require('../../Cells/EpisodeTitleCell'); +var MovieTitleCell = require('../../Cells/MovieTitleCell'); var HistoryQualityCell = require('./HistoryQualityCell'); var RelativeDateCell = require('../../Cells/RelativeDateCell'); var HistoryDetailsCell = require('./HistoryDetailsCell'); @@ -29,22 +27,10 @@ module.exports = Marionette.Layout.extend({ cellValue : 'this' }, { - name : 'movies', + name : 'movie', label : 'Movie Title', cell : MovieTitleCell, }, - /*{ - name : 'episode', - label : 'Episode', - cell : EpisodeNumberCell, - sortable : false - }, - { - name : 'episode', - label : 'Episode Title', - cell : EpisodeTitleCell, - sortable : false - },*/ { name : 'this', label : 'Quality', diff --git a/src/UI/Calendar/CalendarLayoutTemplate.hbs b/src/UI/Calendar/CalendarLayoutTemplate.hbs index bb21fcffb..ac5d6540e 100644 --- a/src/UI/Calendar/CalendarLayoutTemplate.hbs +++ b/src/UI/Calendar/CalendarLayoutTemplate.hbs @@ -12,7 +12,6 @@
  • In Cinemas
  • Announced
  • -
  • Downloading
  • Missing
  • Downloaded
  • diff --git a/src/UI/Cells/MovieTitleHistoryCell.js b/src/UI/Cells/MovieTitleHistoryCell.js deleted file mode 100644 index cf2855f13..000000000 --- a/src/UI/Cells/MovieTitleHistoryCell.js +++ /dev/null @@ -1,12 +0,0 @@ -var TemplatedCell = require('./TemplatedCell'); - -module.exports = TemplatedCell.extend({ - className : 'series-title-cell', - template : 'Cells/SeriesTitleTemplate', - - - render : function() { - this.$el.html('' + this.model.get("movie").get("title") + ''); //Hack, but somehow handlebar helper does not work. - return this; - } -}); diff --git a/src/UI/Wanted/Cutoff/CutoffUnmetLayout.js b/src/UI/Wanted/Cutoff/CutoffUnmetLayout.js index e326c514d..9cf1bf1cc 100644 --- a/src/UI/Wanted/Cutoff/CutoffUnmetLayout.js +++ b/src/UI/Wanted/Cutoff/CutoffUnmetLayout.js @@ -185,7 +185,7 @@ module.exports = Marionette.Layout.extend({ CommandController.bindToCommand({ element : this.$('.x-search-cutoff'), - command : { name : 'missingMoviesSearch' } + command : { name : 'cutOffUnmetMoviesSearch' } }); }, @@ -223,7 +223,7 @@ module.exports = Marionette.Layout.extend({ _searchMissing : function() { if (window.confirm('Are you sure you want to search for {0} filtered missing movies?'.format(this.collection.state.totalRecords) + 'One API request to each indexer will be used for each movie. ' + 'This cannot be stopped once started.')) { - CommandController.Execute('missingMoviesSearch', { name : 'missingMoviesSearch', + CommandController.Execute('cutOffUnmetMoviesSearch', { name : 'cutOffUnmetMoviesSearch', filterKey : this.collection.state.filterKey, filterValue : this.collection.state.filterValue }); }