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
pull/2/head
Devin Buhl 8 years ago committed by GitHub
parent 3f05ef810e
commit 0f2234bcdc

@ -16,13 +16,13 @@ namespace NzbDrone.Api.Calendar
{ {
public class CalendarFeedModule : NzbDroneFeedModule public class CalendarFeedModule : NzbDroneFeedModule
{ {
private readonly IEpisodeService _episodeService; private readonly IMovieService _movieService;
private readonly ITagService _tagService; private readonly ITagService _tagService;
public CalendarFeedModule(IEpisodeService episodeService, ITagService tagService) public CalendarFeedModule(IMovieService movieService, ITagService tagService)
: base("calendar") : base("calendar")
{ {
_episodeService = episodeService; _movieService = movieService;
_tagService = tagService; _tagService = tagService;
Get["/NzbDrone.ics"] = options => GetCalendarFeed(); Get["/NzbDrone.ics"] = options => GetCalendarFeed();
@ -37,7 +37,7 @@ namespace NzbDrone.Api.Calendar
var start = DateTime.Today.AddDays(-pastDays); var start = DateTime.Today.AddDays(-pastDays);
var end = DateTime.Today.AddDays(futureDays); var end = DateTime.Today.AddDays(futureDays);
var unmonitored = false; var unmonitored = false;
var premiersOnly = false; //var premiersOnly = false;
var tags = new List<int>(); var tags = new List<int>();
// TODO: Remove start/end parameters in v3, they don't work well for iCal // 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 queryPastDays = Request.Query.PastDays;
var queryFutureDays = Request.Query.FutureDays; var queryFutureDays = Request.Query.FutureDays;
var queryUnmonitored = Request.Query.Unmonitored; var queryUnmonitored = Request.Query.Unmonitored;
var queryPremiersOnly = Request.Query.PremiersOnly; // var queryPremiersOnly = Request.Query.PremiersOnly;
var queryTags = Request.Query.Tags; var queryTags = Request.Query.Tags;
if (queryStart.HasValue) start = DateTime.Parse(queryStart.Value); if (queryStart.HasValue) start = DateTime.Parse(queryStart.Value);
@ -69,10 +69,10 @@ namespace NzbDrone.Api.Calendar
unmonitored = bool.Parse(queryUnmonitored.Value); unmonitored = bool.Parse(queryUnmonitored.Value);
} }
if (queryPremiersOnly.HasValue) //if (queryPremiersOnly.HasValue)
{ //{
premiersOnly = bool.Parse(queryPremiersOnly.Value); // premiersOnly = bool.Parse(queryPremiersOnly.Value);
} //}
if (queryTags.HasValue) if (queryTags.HasValue)
{ {
@ -80,43 +80,56 @@ namespace NzbDrone.Api.Calendar
tags.AddRange(tagInput.Split(',').Select(_tagService.GetTag).Select(t => t.Id)); 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 var calendar = new Ical.Net.Calendar
{ {
ProductId = "-//sonarr.tv//Sonarr//EN" ProductId = "-//radarr.video//Radarr//EN"
}; };
foreach (var movie in movies.OrderBy(v => v.Added))
foreach (var episode in episodes.OrderBy(v => v.AirDateUtc.Value))
{ {
if (premiersOnly && (episode.SeasonNumber == 0 || episode.EpisodeNumber != 1)) if (tags.Any() && tags.None(movie.Tags.Contains))
{ {
continue; continue;
} }
if (tags.Any() && tags.None(episode.Series.Tags.Contains)) var occurrence = calendar.Create<Event>();
occurrence.Uid = "NzbDrone_movie_" + movie.Id;
occurrence.Status = movie.HasFile ? EventStatus.Confirmed : EventStatus.Tentative;
switch (movie.Status)
{ {
continue; 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;
var occurrence = calendar.Create<Event>(); case MovieStatusType.InCinemas:
occurrence.Uid = "NzbDrone_episode_" + episode.Id; if (movie.InCinemas != null)
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<string>() { episode.Series.Network };
switch (episode.Series.SeriesType)
{ {
case SeriesTypes.Daily: occurrence.Start = new CalDateTime(movie.InCinemas.Value) { HasTime = true };
occurrence.Summary = $"{episode.Series.Title} - {episode.Title}"; occurrence.End = new CalDateTime(movie.InCinemas.Value.AddMinutes(movie.Runtime)) { HasTime = true };
}
break; break;
case MovieStatusType.Announced:
continue; // no date
default: 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; break;
} }
occurrence.Description = movie.Overview;
occurrence.Categories = new List<string>() { movie.Studio };
occurrence.Summary = $"{movie.Title}";
} }
var serializer = (IStringSerializer) new SerializerFactory().Build(calendar.GetType(), new SerializationContext()); var serializer = (IStringSerializer) new SerializerFactory().Build(calendar.GetType(), new SerializationContext());

@ -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.KORSUB.WEBRip.x264.AAC2.0-RADARR", "korsub")]
[TestCase("Movie.Title.2016.1080p.KORSUBS.WEBRip.x264.AAC2.0-RADARR", "korsubs")] [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) public void should_parse_hardcoded_subs(string postTitle, string sub)
{ {
QualityParser.ParseQuality(postTitle).HardcodedSubs.Should().Be(sub); QualityParser.ParseQuality(postTitle).HardcodedSubs.Should().Be(sub);

@ -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; }
}
}

@ -12,21 +12,24 @@ using NzbDrone.Core.DecisionEngine;
namespace NzbDrone.Core.IndexerSearch namespace NzbDrone.Core.IndexerSearch
{ {
public class MovieSearchService : IExecute<MoviesSearchCommand>, IExecute<MissingMoviesSearchCommand> public class MovieSearchService : IExecute<MoviesSearchCommand>, IExecute<MissingMoviesSearchCommand>, IExecute<CutoffUnmetMoviesSearchCommand>
{ {
private readonly IMovieService _movieService; private readonly IMovieService _movieService;
private readonly IMovieCutoffService _movieCutoffService;
private readonly ISearchForNzb _nzbSearchService; private readonly ISearchForNzb _nzbSearchService;
private readonly IProcessDownloadDecisions _processDownloadDecisions; private readonly IProcessDownloadDecisions _processDownloadDecisions;
private readonly IQueueService _queueService; private readonly IQueueService _queueService;
private readonly Logger _logger; private readonly Logger _logger;
public MovieSearchService(IMovieService movieService, public MovieSearchService(IMovieService movieService,
IMovieCutoffService movieCutoffService,
ISearchForNzb nzbSearchService, ISearchForNzb nzbSearchService,
IProcessDownloadDecisions processDownloadDecisions, IProcessDownloadDecisions processDownloadDecisions,
IQueueService queueService, IQueueService queueService,
Logger logger) Logger logger)
{ {
_movieService = movieService; _movieService = movieService;
_movieCutoffService = movieCutoffService;
_nzbSearchService = nzbSearchService; _nzbSearchService = nzbSearchService;
_processDownloadDecisions = processDownloadDecisions; _processDownloadDecisions = processDownloadDecisions;
_queueService = queueService; _queueService = queueService;
@ -71,6 +74,25 @@ namespace NzbDrone.Core.IndexerSearch
} }
public void Execute(CutoffUnmetMoviesSearchCommand message)
{
List<Movie> movies = _movieCutoffService.MoviesWhereCutoffUnmet(new PagingSpec<Movie>
{
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<Movie> movies, bool userInvokedSearch) private void SearchForMissingMovies(List<Movie> movies, bool userInvokedSearch)
{ {
_logger.ProgressInfo("Performing missing search for {0} movies", movies.Count); _logger.ProgressInfo("Performing missing search for {0} movies", movies.Count);

@ -130,6 +130,7 @@
<Compile Include="Datastore\Migration\130_remove_wombles_kickass.cs" /> <Compile Include="Datastore\Migration\130_remove_wombles_kickass.cs" />
<Compile Include="Datastore\Migration\132_rename_torrent_downloadstation.cs" /> <Compile Include="Datastore\Migration\132_rename_torrent_downloadstation.cs" />
<Compile Include="Datastore\Migration\133_add_minimumavailability.cs" /> <Compile Include="Datastore\Migration\133_add_minimumavailability.cs" />
<Compile Include="IndexerSearch\CutoffUnmetMoviesSearchCommand.cs" />
<Compile Include="Indexers\HDBits\HDBitsInfo.cs" /> <Compile Include="Indexers\HDBits\HDBitsInfo.cs" />
<Compile Include="NetImport\TMDb\TMDbLanguageCodes.cs" /> <Compile Include="NetImport\TMDb\TMDbLanguageCodes.cs" />
<Compile Include="NetImport\TMDb\TMDbSettings.cs" /> <Compile Include="NetImport\TMDb\TMDbSettings.cs" />

@ -48,7 +48,7 @@ namespace NzbDrone.Core.Parser
)\b", )\b",
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
private static readonly Regex HardcodedSubsRegex = new Regex(@"\b(?<hcsub>(\w+SUBS?)\b)|(?<hc>(HC))\b", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); private static readonly Regex HardcodedSubsRegex = new Regex(@"\b(?<hcsub>(\w+SUB)\b)|(?<hc>(HC))\b", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
private static readonly Regex RemuxRegex = new Regex(@"\b(?<remux>Remux)\b", private static readonly Regex RemuxRegex = new Regex(@"\b(?<remux>Remux)\b",
RegexOptions.Compiled | RegexOptions.IgnoreCase); RegexOptions.Compiled | RegexOptions.IgnoreCase);

@ -2,9 +2,7 @@ var Marionette = require('marionette');
var Backgrid = require('backgrid'); var Backgrid = require('backgrid');
var HistoryCollection = require('./HistoryCollection'); var HistoryCollection = require('./HistoryCollection');
var EventTypeCell = require('../../Cells/EventTypeCell'); var EventTypeCell = require('../../Cells/EventTypeCell');
var MovieTitleCell = require('../../Cells/MovieTitleHistoryCell'); var MovieTitleCell = require('../../Cells/MovieTitleCell');
var EpisodeNumberCell = require('../../Cells/EpisodeNumberCell');
var EpisodeTitleCell = require('../../Cells/EpisodeTitleCell');
var HistoryQualityCell = require('./HistoryQualityCell'); var HistoryQualityCell = require('./HistoryQualityCell');
var RelativeDateCell = require('../../Cells/RelativeDateCell'); var RelativeDateCell = require('../../Cells/RelativeDateCell');
var HistoryDetailsCell = require('./HistoryDetailsCell'); var HistoryDetailsCell = require('./HistoryDetailsCell');
@ -29,22 +27,10 @@ module.exports = Marionette.Layout.extend({
cellValue : 'this' cellValue : 'this'
}, },
{ {
name : 'movies', name : 'movie',
label : 'Movie Title', label : 'Movie Title',
cell : MovieTitleCell, cell : MovieTitleCell,
}, },
/*{
name : 'episode',
label : 'Episode',
cell : EpisodeNumberCell,
sortable : false
},
{
name : 'episode',
label : 'Episode Title',
cell : EpisodeTitleCell,
sortable : false
},*/
{ {
name : 'this', name : 'this',
label : 'Quality', label : 'Quality',

@ -12,7 +12,6 @@
<ul class='legend-labels'> <ul class='legend-labels'>
<li class="legend-label"><span class="premiere" title="This Movie is still in cinemas and hasn't been released yet. Only poor qualities will be available"></span>In Cinemas</li> <li class="legend-label"><span class="premiere" title="This Movie is still in cinemas and hasn't been released yet. Only poor qualities will be available"></span>In Cinemas</li>
<li class="legend-label"><span class="primary" title="This movie has only been announced yet."></span>Announced</li> <li class="legend-label"><span class="primary" title="This movie has only been announced yet."></span>Announced</li>
<!--<li class="legend-label"><span class="warning" title="Episode is currently airing"></span>On Air</li>-->
<li class="legend-label"><span class="purple" title="Movie is currently downloading"></span>Downloading</li> <li class="legend-label"><span class="purple" title="Movie is currently downloading"></span>Downloading</li>
<li class="legend-label"><span class="danger" title="Movie file has not been found"></span>Missing</li> <li class="legend-label"><span class="danger" title="Movie file has not been found"></span>Missing</li>
<li class="legend-label"><span class="success" title="Movie was downloaded and sorted"></span>Downloaded</li> <li class="legend-label"><span class="success" title="Movie was downloaded and sorted"></span>Downloaded</li>

@ -1,12 +0,0 @@
var TemplatedCell = require('./TemplatedCell');
module.exports = TemplatedCell.extend({
className : 'series-title-cell',
template : 'Cells/SeriesTitleTemplate',
render : function() {
this.$el.html('<a href="/movies/' + this.model.get("movie").get("titleSlug") +'">' + this.model.get("movie").get("title") + '</a>'); //Hack, but somehow handlebar helper does not work.
return this;
}
});

@ -185,7 +185,7 @@ module.exports = Marionette.Layout.extend({
CommandController.bindToCommand({ CommandController.bindToCommand({
element : this.$('.x-search-cutoff'), element : this.$('.x-search-cutoff'),
command : { name : 'missingMoviesSearch' } command : { name : 'cutOffUnmetMoviesSearch' }
}); });
}, },
@ -223,7 +223,7 @@ module.exports = Marionette.Layout.extend({
_searchMissing : function() { _searchMissing : function() {
if (window.confirm('Are you sure you want to search for {0} filtered missing movies?'.format(this.collection.state.totalRecords) + 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.')) { '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, filterKey : this.collection.state.filterKey,
filterValue : this.collection.state.filterValue }); filterValue : this.collection.state.filterValue });
} }

Loading…
Cancel
Save