Fixed: Scene Info displaying mappings for wrong season

Fixed: Extraneous searches based on scene mappings
This commit is contained in:
Taloth Saldono 2021-05-08 01:03:47 +02:00
parent 87897d56ea
commit 8fc68420c9
4 changed files with 101 additions and 30 deletions

View File

@ -1,3 +1,4 @@
import _ from 'lodash';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import DescriptionList from 'Components/DescriptionList/DescriptionList'; import DescriptionList from 'Components/DescriptionList/DescriptionList';
@ -16,6 +17,38 @@ function SceneInfo(props) {
seriesType seriesType
} = props; } = props;
const reducedAlternateTitles = alternateTitles.map((alternateTitle) => {
let suffix = '';
const altSceneSeasonNumber = sceneSeasonNumber === undefined ? seasonNumber : sceneSeasonNumber;
const altSceneEpisodeNumber = sceneEpisodeNumber === undefined ? episodeNumber : sceneEpisodeNumber;
const mappingSeasonNumber = alternateTitle.sceneOrigin === 'tvdb' ? seasonNumber : altSceneSeasonNumber;
const altSeasonNumber = (alternateTitle.sceneSeasonNumber !== -1 && alternateTitle.sceneSeasonNumber !== undefined) ? alternateTitle.sceneSeasonNumber : mappingSeasonNumber;
const altEpisodeNumber = alternateTitle.sceneOrigin === 'tvdb' ? episodeNumber : altSceneEpisodeNumber;
if (altEpisodeNumber !== altSceneEpisodeNumber) {
suffix = `S${padNumber(altSeasonNumber, 2)}E${padNumber(altEpisodeNumber, 2)}`;
} else if (altSeasonNumber !== altSceneSeasonNumber) {
suffix = `S${padNumber(altSeasonNumber, 2)}`;
}
return {
alternateTitle,
title: alternateTitle.title,
suffix,
comment: alternateTitle.comment
};
});
const groupedAlternateTitles = _.map(_.groupBy(reducedAlternateTitles, (item) => `${item.title} ${item.suffix}`), (group) => {
return {
title: group[0].title,
suffix: group[0].suffix,
comment: _.uniq(group.map((item) => item.comment)).join('/')
};
});
return ( return (
<DescriptionList className={styles.descriptionList}> <DescriptionList className={styles.descriptionList}>
{ {
@ -53,38 +86,23 @@ function SceneInfo(props) {
<DescriptionListItem <DescriptionListItem
titleClassName={styles.title} titleClassName={styles.title}
descriptionClassName={styles.description} descriptionClassName={styles.description}
title={alternateTitles.length === 1 ? 'Title' : 'Titles'} title={groupedAlternateTitles.length === 1 ? 'Title' : 'Titles'}
data={ data={
<div> <div>
{ {
alternateTitles.map((alternateTitle) => { groupedAlternateTitles.map(({ title, suffix, comment }) => {
let suffix = '';
const altSceneSeasonNumber = sceneSeasonNumber === undefined ? seasonNumber : sceneSeasonNumber;
const altSceneEpisodeNumber = sceneEpisodeNumber === undefined ? episodeNumber : sceneEpisodeNumber;
const mappingSeasonNumber = alternateTitle.sceneOrigin === 'tvdb' ? seasonNumber : altSceneSeasonNumber;
const altSeasonNumber = (alternateTitle.sceneSeasonNumber !== -1 && alternateTitle.sceneSeasonNumber !== undefined) ? alternateTitle.sceneSeasonNumber : mappingSeasonNumber;
const altEpisodeNumber = alternateTitle.sceneOrigin === 'tvdb' ? episodeNumber : altSceneEpisodeNumber;
if (altEpisodeNumber !== altSceneEpisodeNumber) {
suffix = `S${padNumber(altSeasonNumber, 2)}E${padNumber(altEpisodeNumber, 2)}`;
} else if (altSeasonNumber !== altSceneSeasonNumber) {
suffix = `S${padNumber(altSeasonNumber, 2)}`;
}
return ( return (
<div <div
key={alternateTitle.title} key={`${title} ${suffix}`}
> >
{alternateTitle.title} {title}
{ {
suffix && suffix &&
<span> ({suffix})</span> <span> ({suffix})</span>
} }
{ {
alternateTitle.comment && comment &&
<span className={styles.comment}> {alternateTitle.comment}</span> <span className={styles.comment}> {comment}</span>
} }
</div> </div>
); );

View File

@ -17,6 +17,7 @@ function filterAlternateTitles(alternateTitles, seriesTitle, useSceneNumbering,
const hasAltSeasonNumber = (alternateTitle.seasonNumber !== -1 && alternateTitle.seasonNumber !== undefined); const hasAltSeasonNumber = (alternateTitle.seasonNumber !== -1 && alternateTitle.seasonNumber !== undefined);
const hasAltSceneSeasonNumber = (alternateTitle.sceneSeasonNumber !== -1 && alternateTitle.sceneSeasonNumber !== undefined); const hasAltSceneSeasonNumber = (alternateTitle.sceneSeasonNumber !== -1 && alternateTitle.sceneSeasonNumber !== undefined);
// Global alias that should be displayed global
if (!hasAltSeasonNumber && !hasAltSceneSeasonNumber && if (!hasAltSeasonNumber && !hasAltSceneSeasonNumber &&
(alternateTitle.title !== seriesTitle) && (alternateTitle.title !== seriesTitle) &&
(!alternateTitle.sceneOrigin || !useSceneNumbering)) { (!alternateTitle.sceneOrigin || !useSceneNumbering)) {
@ -24,9 +25,18 @@ function filterAlternateTitles(alternateTitles, seriesTitle, useSceneNumbering,
return; return;
} }
if ((sceneSeasonNumber !== undefined && sceneSeasonNumber === alternateTitle.sceneSeasonNumber) || // Global alias that should be displayed per episode
(seasonNumber !== undefined && seasonNumber === alternateTitle.seasonNumber) || if (!hasAltSeasonNumber && !hasAltSceneSeasonNumber && alternateTitle.sceneOrigin && useSceneNumbering) {
(!hasAltSeasonNumber && !hasAltSceneSeasonNumber && alternateTitle.sceneOrigin && useSceneNumbering)) { seasonTitles.push(alternateTitle);
return;
}
// Apply the alternative mapping (release to scene)
const mappedAltSeasonNumber = hasAltSeasonNumber ? alternateTitle.seasonNumber : alternateTitle.sceneSeasonNumber;
// Select scene or tvdb on the episode
const mappedSeasonNumber = alternateTitle.sceneOrigin === 'tvdb' ? seasonNumber : sceneSeasonNumber;
if (mappedSeasonNumber !== undefined && mappedSeasonNumber === mappedAltSeasonNumber) {
seasonTitles.push(alternateTitle); seasonTitles.push(alternateTitle);
return; return;
} }

View File

@ -0,0 +1,15 @@
namespace NzbDrone.Common.Extensions
{
public static class NullableExtensions
{
public static int? NonNegative(this int? source)
{
if (source.HasValue && source.Value != -1)
{
return source;
}
return null;
}
}
}

View File

@ -14,6 +14,7 @@ using System.Linq;
using NzbDrone.Common.TPL; using NzbDrone.Common.TPL;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Exceptions; using NzbDrone.Core.Exceptions;
using NzbDrone.Core.Parser;
namespace NzbDrone.Core.IndexerSearch namespace NzbDrone.Core.IndexerSearch
{ {
@ -233,9 +234,36 @@ namespace NzbDrone.Core.IndexerSearch
foreach (var sceneMapping in sceneMappings) foreach (var sceneMapping in sceneMappings)
{ {
if ((sceneMapping.SeasonNumber ?? -1) != -1 && sceneMapping.SeasonNumber != episode.SeasonNumber) // There are two kinds of mappings:
// - Mapped on Release Season Number with sceneMapping.SceneSeasonNumber specified and optionally sceneMapping.SeasonNumber. This translates via episode.SceneSeasonNumber/SeasonNumber to specific episodes.
// - Mapped on Episode Season Number with optionally sceneMapping.SeasonNumber. This translates from episode.SceneSeasonNumber/SeasonNumber to specific releases. (Filter by episode.SeasonNumber or globally)
var ignoreSceneNumbering = (sceneMapping.SceneOrigin == "tvdb" || sceneMapping.SceneOrigin == "unknown:tvdb");
var mappingSceneSeasonNumber = sceneMapping.SceneSeasonNumber.NonNegative();
var mappingSeasonNumber = sceneMapping.SeasonNumber.NonNegative();
// Select scene or tvdb on the episode
var mappedSeasonNumber = ignoreSceneNumbering ? episode.SeasonNumber : (episode.SceneSeasonNumber ?? episode.SeasonNumber);
var releaseSeasonNumber = sceneMapping.SceneSeasonNumber.NonNegative() ?? mappedSeasonNumber;
if (mappingSceneSeasonNumber.HasValue)
{ {
continue; // Apply the alternative mapping (release to scene/tvdb)
var mappedAltSeasonNumber = sceneMapping.SeasonNumber.NonNegative() ?? sceneMapping.SceneSeasonNumber.NonNegative() ?? mappedSeasonNumber;
// Check if the mapping applies to the current season
if (mappedAltSeasonNumber != mappedSeasonNumber)
{
continue;
}
}
else
{
// Check if the mapping applies to the current season
if (mappingSeasonNumber.HasValue && mappingSeasonNumber.Value != episode.SeasonNumber)
{
continue;
}
} }
if (sceneMapping.ParseTerm == series.CleanTitle && sceneMapping.FilterRegex.IsNotNullOrWhiteSpace()) if (sceneMapping.ParseTerm == series.CleanTitle && sceneMapping.FilterRegex.IsNotNullOrWhiteSpace())
@ -245,16 +273,16 @@ namespace NzbDrone.Core.IndexerSearch
} }
// By default we do a alt title search in case indexers don't have the release properly indexed. Services can override this behavior. // By default we do a alt title search in case indexers don't have the release properly indexed. Services can override this behavior.
var searchMode = sceneMapping.SearchMode ?? ((sceneMapping.SceneSeasonNumber ?? -1) != -1 ? SearchMode.SearchTitle : SearchMode.Default); var searchMode = sceneMapping.SearchMode ?? ((mappingSceneSeasonNumber.HasValue && series.CleanTitle != sceneMapping.SearchTerm.CleanSeriesTitle()) ? SearchMode.SearchTitle : SearchMode.Default);
if (sceneMapping.SceneOrigin == "tvdb" || sceneMapping.SceneOrigin == "unknown:tvdb") if (ignoreSceneNumbering)
{ {
yield return new SceneEpisodeMapping yield return new SceneEpisodeMapping
{ {
Episode = episode, Episode = episode,
SearchMode = searchMode, SearchMode = searchMode,
SceneTitles = new List<string> { sceneMapping.SearchTerm }, SceneTitles = new List<string> { sceneMapping.SearchTerm },
SeasonNumber = (sceneMapping.SceneSeasonNumber ?? -1) == -1 ? episode.SeasonNumber : sceneMapping.SceneSeasonNumber.Value, SeasonNumber = releaseSeasonNumber,
EpisodeNumber = episode.EpisodeNumber, EpisodeNumber = episode.EpisodeNumber,
AbsoluteEpisodeNumber = episode.AbsoluteEpisodeNumber AbsoluteEpisodeNumber = episode.AbsoluteEpisodeNumber
}; };
@ -266,7 +294,7 @@ namespace NzbDrone.Core.IndexerSearch
Episode = episode, Episode = episode,
SearchMode = searchMode, SearchMode = searchMode,
SceneTitles = new List<string> { sceneMapping.SearchTerm }, SceneTitles = new List<string> { sceneMapping.SearchTerm },
SeasonNumber = (sceneMapping.SceneSeasonNumber ?? -1) == -1 ? (episode.SceneSeasonNumber ?? episode.SeasonNumber) : sceneMapping.SceneSeasonNumber.Value, SeasonNumber = releaseSeasonNumber,
EpisodeNumber = episode.SceneEpisodeNumber ?? episode.EpisodeNumber, EpisodeNumber = episode.SceneEpisodeNumber ?? episode.EpisodeNumber,
AbsoluteEpisodeNumber = episode.SceneAbsoluteEpisodeNumber ?? episode.AbsoluteEpisodeNumber AbsoluteEpisodeNumber = episode.SceneAbsoluteEpisodeNumber ?? episode.AbsoluteEpisodeNumber
}; };