the Search All Missing button (#860)

was searching all missing and monitored only
though the dialog that popped up was informing the user it was
going to search for x movies, where x corresponded to the number
of movies filtered on the page.

I changed this button, so now it will search all the items as they are
filtered on the page.

For example, if you want to search all missing (regardless of
monitor/unmonitor) click the all filter and click the button.

If you want to search only monitored/missing, click the monitored button
and then click the search all button...

this included the old functionality, but allows the user alot more
flexibility...

i also added the all filter, and refactored the code,
so that builds the expression for the LINQ.. since this needed to be
used in two places.. just implement it once and use it in both places..

I tested this out... and stepped through with debugger.. i also did a
quick test of everything else. Im confident that the featureset
implemented and bugs fixed by this commit are OK... Im not 100% that
other parts of radarr dont use the same MissingMovieSearch routines..
but i dont think so...
This commit is contained in:
geogolem 2017-02-24 03:22:55 -05:00 committed by Devin Buhl
parent 0678908fd9
commit bab7bd20cd
6 changed files with 61 additions and 36 deletions

View File

@ -30,35 +30,7 @@ namespace NzbDrone.Api.Wanted
{
var pagingSpec = pagingResource.MapToPagingSpec<MovieResource, Core.Tv.Movie>("title", SortDirection.Descending);
if (pagingResource.FilterKey == "monitored" && pagingResource.FilterValue == "false")
{
pagingSpec.FilterExpression = v => v.Monitored == false;
}
else if (pagingResource.FilterKey == "monitored" && pagingResource.FilterValue == "true")
{
pagingSpec.FilterExpression = v => v.Monitored == true;
}
else if (pagingResource.FilterKey == "moviestatus" && pagingResource.FilterValue == "available")
{
//TODO: might need to handle PreDB here
pagingSpec.FilterExpression = v => v.Monitored == true &&
((v.MinimumAvailability == MovieStatusType.Released && v.Status >= MovieStatusType.Released) ||
(v.MinimumAvailability == MovieStatusType.InCinemas && v.Status >= MovieStatusType.InCinemas) ||
(v.MinimumAvailability == MovieStatusType.Announced && v.Status >= MovieStatusType.Announced) ||
(v.MinimumAvailability == MovieStatusType.PreDB && v.Status >= MovieStatusType.Released));
}
else if (pagingResource.FilterKey == "moviestatus" && pagingResource.FilterValue == "announced")
{
pagingSpec.FilterExpression = v => v.Status == MovieStatusType.Announced;
}
else if (pagingResource.FilterKey == "moviestatus" && pagingResource.FilterValue == "incinemas")
{
pagingSpec.FilterExpression = v => v.Status == MovieStatusType.InCinemas;
}
else if (pagingResource.FilterKey == "moviestatus" && pagingResource.FilterValue == "released")
{
pagingSpec.FilterExpression = v => v.Status == MovieStatusType.Released;
}
pagingSpec.FilterExpression = _movieService.ConstructFilterExpression(pagingResource.FilterKey, pagingResource.FilterValue);
var resource = ApplyToPage(_movieService.MoviesWithoutFiles, pagingSpec, v => MapToResource(v, true));

View File

@ -9,5 +9,7 @@ namespace NzbDrone.Core.IndexerSearch
public class MissingMoviesSearchCommand : Command
{
public override bool SendUpdatesToClient => true;
public string FilterKey { get; set; }
public string FilterValue { get; set; }
}
}

View File

@ -90,9 +90,7 @@ namespace NzbDrone.Core.IndexerSearch
PageSize = 100000,
SortDirection = SortDirection.Ascending,
SortKey = "Id",
FilterExpression =
v =>
v.Monitored == true
FilterExpression = _movieService.ConstructFilterExpression(message.FilterKey, message.FilterValue)
}).Records.ToList();

View File

@ -38,6 +38,7 @@ namespace NzbDrone.Core.Tv
bool MoviePathExists(string folder);
void RemoveAddOptions(Movie movie);
List<Movie> MoviesWithFiles(int movieId);
System.Linq.Expressions.Expression<Func<Core.Tv.Movie, bool>> ConstructFilterExpression(string FilterKey, string FilterValue);
}
public class MovieService : IMovieService, IHandle<MovieFileAddedEvent>,
@ -61,6 +62,45 @@ namespace NzbDrone.Core.Tv
_logger = logger;
}
public System.Linq.Expressions.Expression<Func<Core.Tv.Movie, bool>> ConstructFilterExpression(string FilterKey, string FilterValue)
{
if (FilterKey == "all" && FilterValue == "all")
{
return v => v.Monitored == true || v.Monitored == false;
}
else if (FilterKey == "monitored" && FilterValue == "false")
{
return v => v.Monitored == false;
}
else if (FilterKey == "monitored" && FilterValue == "true")
{
return v => v.Monitored == true;
}
else if (FilterKey == "moviestatus" && FilterValue == "available")
{
//TODO: might need to handle PreDB here
return v => v.Monitored == true &&
((v.MinimumAvailability == MovieStatusType.Released && v.Status >= MovieStatusType.Released) ||
(v.MinimumAvailability == MovieStatusType.InCinemas && v.Status >= MovieStatusType.InCinemas) ||
(v.MinimumAvailability == MovieStatusType.Announced && v.Status >= MovieStatusType.Announced) ||
(v.MinimumAvailability == MovieStatusType.PreDB && v.Status >= MovieStatusType.Released));
}
else if (FilterKey == "moviestatus" && FilterValue == "announced")
{
return v => v.Status == MovieStatusType.Announced;
}
else if (FilterKey == "moviestatus" && FilterValue == "incinemas")
{
return v => v.Status == MovieStatusType.InCinemas;
}
else if (FilterKey == "moviestatus" && FilterValue == "released")
{
return v => v.Status == MovieStatusType.Released;
}
return v => v.Monitored == true;
}
public Movie GetMovie(int movieId)
{
return _movieRepository.Get(movieId);

View File

@ -51,7 +51,11 @@ var Collection = PagableCollection.extend({
],
'available' : [
'moviestatus',
'available',
'available'
],
'all' : [
'all',
'all'
]
},

View File

@ -102,7 +102,7 @@ module.exports = Marionette.Layout.extend({
className : 'x-search-selected'
},
{
title : 'Search All Missing',
title : 'Search All',
icon : 'icon-sonarr-search',
callback : this._searchMissing,
ownerContext : this,
@ -136,6 +136,13 @@ module.exports = Marionette.Layout.extend({
menuKey : 'wanted.filterMode',
defaultAction : 'available',
items : [
{
key : 'all',
title : '',
tooltip : 'All',
icon : 'icon-sonarr-all',
callback : this._setFilter
},
{
key : 'available',
title : '',
@ -220,9 +227,11 @@ module.exports = Marionette.Layout.extend({
});
},
_searchMissing : function() {
if (window.confirm('Are you sure you want to search for {0} 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.')) {
CommandController.Execute('missingMoviesSearch', { name : 'missingMoviesSearch' });
CommandController.Execute('missingMoviesSearch', { name : 'missingMoviesSearch',
filterKey : this.collection.state.filterKey,
filterValue : this.collection.state.filterValue });
}
},
_toggleMonitoredOfSelected : function() {