Fixed: Cutoff Status and Filter on MovieIndex

pull/4017/head
ta264 5 years ago committed by Qstick
parent f83ccb6ca4
commit 89fec7841c

@ -4,7 +4,7 @@ import formatBytes from 'Utilities/Number/formatBytes';
import { kinds } from 'Helpers/Props'; import { kinds } from 'Helpers/Props';
import Label from 'Components/Label'; import Label from 'Components/Label';
function getTooltip(title, quality, size) { function getTooltip(title, quality, size, isMonitored, isCutoffNotMet) {
const revision = quality.revision; const revision = quality.revision;
if (revision.real && revision.real > 0) { if (revision.real && revision.real > 0) {
@ -19,6 +19,12 @@ function getTooltip(title, quality, size) {
title += ` - ${formatBytes(size)}`; title += ` - ${formatBytes(size)}`;
} }
if (!isMonitored) {
title += ' [Not Monitored]';
} else if (isCutoffNotMet) {
title += ' [Cutoff Not Met]';
}
return title; return title;
} }
@ -28,14 +34,22 @@ function MovieQuality(props) {
title, title,
quality, quality,
size, size,
isMonitored,
isCutoffNotMet isCutoffNotMet
} = props; } = props;
let kind = kinds.DEFAULT;
if (!isMonitored) {
kind = kinds.DISABLED;
} else if (isCutoffNotMet) {
kind = kinds.INVERSE;
}
return ( return (
<Label <Label
className={className} className={className}
kind={isCutoffNotMet ? kinds.INVERSE : kinds.DEFAULT} kind={kind}
title={getTooltip(title, quality, size)} title={getTooltip(title, quality, size, isMonitored, isCutoffNotMet)}
> >
{quality.quality.name} {quality.quality.name}
</Label> </Label>
@ -47,11 +61,13 @@ MovieQuality.propTypes = {
title: PropTypes.string, title: PropTypes.string,
quality: PropTypes.object.isRequired, quality: PropTypes.object.isRequired,
size: PropTypes.number, size: PropTypes.number,
isMonitored: PropTypes.bool,
isCutoffNotMet: PropTypes.bool isCutoffNotMet: PropTypes.bool
}; };
MovieQuality.defaultProps = { MovieQuality.defaultProps = {
title: '' title: '',
isMonitored: true
}; };
export default MovieQuality; export default MovieQuality;

@ -4,28 +4,10 @@ import { icons, kinds, sizes } from 'Helpers/Props';
import Icon from 'Components/Icon'; import Icon from 'Components/Icon';
import ProgressBar from 'Components/ProgressBar'; import ProgressBar from 'Components/ProgressBar';
import QueueDetails from 'Activity/Queue/QueueDetails'; import QueueDetails from 'Activity/Queue/QueueDetails';
import formatBytes from 'Utilities/Number/formatBytes'; import MovieQuality from 'Movie/MovieQuality';
import Label from 'Components/Label'; import Label from 'Components/Label';
import styles from './MovieStatus.css'; import styles from './MovieStatus.css';
function getTooltip(title, quality, size) {
const revision = quality.revision;
if (revision.real && revision.real > 0) {
title += ' [REAL]';
}
if (revision.version && revision.version > 1) {
title += ' [PROPER]';
}
if (size) {
title += ` - ${formatBytes(size)}`;
}
return title;
}
function MovieStatus(props) { function MovieStatus(props) {
const { const {
inCinemas, inCinemas,
@ -76,32 +58,18 @@ function MovieStatus(props) {
); );
} }
if (hasMovieFile && monitored) { if (hasMovieFile) {
const quality = movieFile.quality;
// TODO: Fix on Backend
// const isCutoffNotMet = movieFile.qualityCutoffNotMet;
return (
<div className={styles.center}>
<Label
kind={kinds.SUCCESS}
title={getTooltip('Movie Downloaded', quality, movieFile.size)}
>
{quality.quality.name}
</Label>
</div>
);
} else if (hasMovieFile && !monitored) {
const quality = movieFile.quality; const quality = movieFile.quality;
return ( return (
<div className={styles.center}> <div className={styles.center}>
<Label <MovieQuality
kind={kinds.DISABLED} title={quality.quality.name}
title={getTooltip('Movie Downloaded', quality, movieFile.size)} size={movieFile.size}
> quality={quality}
{quality.quality.name} isMonitored={monitored}
</Label> isCutoffNotMet={movieFile.qualityCutoffNotMet}
/>
</div> </div>
); );
} }

@ -97,7 +97,7 @@ export const filters = [
type: filterTypes.EQUAL type: filterTypes.EQUAL
}, },
{ {
key: 'movieFile.qualityCutoffNotMet', key: 'qualityCutoffNotMet',
value: true, value: true,
type: filterTypes.EQUAL type: filterTypes.EQUAL
} }
@ -106,12 +106,6 @@ export const filters = [
]; ];
export const filterPredicates = { export const filterPredicates = {
missing: function(item) {
const { statistics = {} } = item;
return statistics.episodeCount - statistics.episodeFileCount > 0;
},
added: function(item, filterValue, type) { added: function(item, filterValue, type) {
return dateFilterPredicate(item.added, filterValue, type); return dateFilterPredicate(item.added, filterValue, type);
}, },
@ -128,6 +122,12 @@ export const filterPredicates = {
const predicate = filterTypePredicates[type]; const predicate = filterTypePredicates[type];
return predicate(item.ratings.value * 10, filterValue); return predicate(item.ratings.value * 10, filterValue);
},
qualityCutoffNotMet: function(item) {
const { movieFile = {} } = item;
return movieFile.qualityCutoffNotMet;
} }
}; };

@ -3,6 +3,7 @@ using FluentValidation;
using Nancy; using Nancy;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Datastore.Events; using NzbDrone.Core.Datastore.Events;
using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.MediaCover; using NzbDrone.Core.MediaCover;
using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.MediaFiles.Events; using NzbDrone.Core.MediaFiles.Events;
@ -28,20 +29,22 @@ namespace Radarr.Api.V3.Movies
{ {
protected readonly IMovieService _moviesService; protected readonly IMovieService _moviesService;
private readonly IMapCoversToLocal _coverMapper; private readonly IMapCoversToLocal _coverMapper;
private readonly IUpgradableSpecification _qualityUpgradableSpecification;
public MovieModule(IBroadcastSignalRMessage signalRBroadcaster, public MovieModule(IBroadcastSignalRMessage signalRBroadcaster,
IMovieService moviesService, IMovieService moviesService,
IMapCoversToLocal coverMapper, IMapCoversToLocal coverMapper,
RootFolderValidator rootFolderValidator, IUpgradableSpecification qualityUpgradableSpecification,
MoviePathValidator moviesPathValidator, RootFolderValidator rootFolderValidator,
MovieExistsValidator moviesExistsValidator, MoviePathValidator moviesPathValidator,
MovieAncestorValidator moviesAncestorValidator, MovieExistsValidator moviesExistsValidator,
ProfileExistsValidator profileExistsValidator, MovieAncestorValidator moviesAncestorValidator,
MovieFolderAsRootFolderValidator movieFolderAsRootFolderValidator) ProfileExistsValidator profileExistsValidator,
MovieFolderAsRootFolderValidator movieFolderAsRootFolderValidator)
: base(signalRBroadcaster) : base(signalRBroadcaster)
{ {
_moviesService = moviesService; _moviesService = moviesService;
_qualityUpgradableSpecification = qualityUpgradableSpecification;
_coverMapper = coverMapper; _coverMapper = coverMapper;
GetResourceAll = AllMovie; GetResourceAll = AllMovie;
@ -75,7 +78,7 @@ namespace Radarr.Api.V3.Movies
private List<MovieResource> AllMovie() private List<MovieResource> AllMovie()
{ {
var moviesResources = _moviesService.GetAllMovies().ToResource(); var moviesResources = _moviesService.GetAllMovies().ToResource(_qualityUpgradableSpecification);
MapCoversToLocal(moviesResources.ToArray()); MapCoversToLocal(moviesResources.ToArray());
PopulateAlternateTitles(moviesResources); PopulateAlternateTitles(moviesResources);

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.MediaCover; using NzbDrone.Core.MediaCover;
using NzbDrone.Core.Movies; using NzbDrone.Core.Movies;
using Radarr.Api.V3.MovieFiles; using Radarr.Api.V3.MovieFiles;
@ -132,6 +133,67 @@ namespace Radarr.Api.V3.Movies
}; };
} }
public static MovieResource ToResource(this Movie model, IUpgradableSpecification upgradableSpecification)
{
if (model == null)
{
return null;
}
long size = model.MovieFile?.Size ?? 0;
MovieFileResource movieFile = model.MovieFile?.ToResource(model, upgradableSpecification);
return new MovieResource
{
Id = model.Id,
TmdbId = model.TmdbId,
Title = model.Title,
SortTitle = model.SortTitle,
InCinemas = model.InCinemas,
PhysicalRelease = model.PhysicalRelease,
PhysicalReleaseNote = model.PhysicalReleaseNote,
HasFile = model.HasFile,
SizeOnDisk = size,
Status = model.Status,
Overview = model.Overview,
Images = model.Images,
Year = model.Year,
SecondaryYear = model.SecondaryYear,
SecondaryYearSourceId = model.SecondaryYearSourceId,
Path = model.Path,
QualityProfileId = model.ProfileId,
PathState = model.PathState,
Monitored = model.Monitored,
MinimumAvailability = model.MinimumAvailability,
IsAvailable = model.IsAvailable(),
FolderName = model.FolderName(),
Runtime = model.Runtime,
LastInfoSync = model.LastInfoSync,
CleanTitle = model.CleanTitle,
ImdbId = model.ImdbId,
TitleSlug = model.TitleSlug,
RootFolderPath = model.RootFolderPath,
Certification = model.Certification,
Website = model.Website,
Genres = model.Genres,
Tags = model.Tags,
Added = model.Added,
AddOptions = model.AddOptions,
AlternateTitles = model.AlternativeTitles.ToResource(),
Ratings = model.Ratings,
MovieFile = movieFile,
YouTubeTrailerId = model.YouTubeTrailerId,
Studio = model.Studio
};
}
public static Movie ToModel(this MovieResource resource) public static Movie ToModel(this MovieResource resource)
{ {
if (resource == null) if (resource == null)
@ -197,6 +259,11 @@ namespace Radarr.Api.V3.Movies
return movies.Select(ToResource).ToList(); return movies.Select(ToResource).ToList();
} }
public static List<MovieResource> ToResource(this IEnumerable<Movie> movies, IUpgradableSpecification upgradableSpecification)
{
return movies.ToList().ConvertAll(f => f.ToResource(upgradableSpecification));
}
public static List<Movie> ToModel(this IEnumerable<MovieResource> resources) public static List<Movie> ToModel(this IEnumerable<MovieResource> resources)
{ {
return resources.Select(ToModel).ToList(); return resources.Select(ToModel).ToList();

Loading…
Cancel
Save