New: Show Custom Formats on Manual Import / Manage Episodes
Closes #5241
This commit is contained in:
parent
6216a71f8c
commit
da4f6b7df9
|
@ -77,6 +77,15 @@ const columns = [
|
||||||
isSortable: true,
|
isSortable: true,
|
||||||
isVisible: true
|
isVisible: true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'customFormats',
|
||||||
|
label: React.createElement(Icon, {
|
||||||
|
name: icons.INTERACTIVE,
|
||||||
|
title: 'Custom Format'
|
||||||
|
}),
|
||||||
|
isSortable: true,
|
||||||
|
isVisible: true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'rejections',
|
name: 'rejections',
|
||||||
label: React.createElement(Icon, {
|
label: React.createElement(Icon, {
|
||||||
|
|
|
@ -23,3 +23,7 @@
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
text-align: start;
|
text-align: start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.customFormatTooltip {
|
||||||
|
max-width: 250px;
|
||||||
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import TableRowCellButton from 'Components/Table/Cells/TableRowCellButton';
|
||||||
import TableSelectCell from 'Components/Table/Cells/TableSelectCell';
|
import TableSelectCell from 'Components/Table/Cells/TableSelectCell';
|
||||||
import TableRow from 'Components/Table/TableRow';
|
import TableRow from 'Components/Table/TableRow';
|
||||||
import Popover from 'Components/Tooltip/Popover';
|
import Popover from 'Components/Tooltip/Popover';
|
||||||
|
import EpisodeFormats from 'Episode/EpisodeFormats';
|
||||||
import EpisodeLanguages from 'Episode/EpisodeLanguages';
|
import EpisodeLanguages from 'Episode/EpisodeLanguages';
|
||||||
import EpisodeQuality from 'Episode/EpisodeQuality';
|
import EpisodeQuality from 'Episode/EpisodeQuality';
|
||||||
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
|
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
|
||||||
|
@ -213,6 +214,7 @@ class InteractiveImportRow extends Component {
|
||||||
languages,
|
languages,
|
||||||
releaseGroup,
|
releaseGroup,
|
||||||
size,
|
size,
|
||||||
|
customFormats,
|
||||||
rejections,
|
rejections,
|
||||||
isReprocessing,
|
isReprocessing,
|
||||||
isSelected,
|
isSelected,
|
||||||
|
@ -366,7 +368,26 @@ class InteractiveImportRow extends Component {
|
||||||
|
|
||||||
<TableRowCell>
|
<TableRowCell>
|
||||||
{
|
{
|
||||||
rejections && rejections.length ?
|
customFormats?.length ?
|
||||||
|
<Popover
|
||||||
|
anchor={
|
||||||
|
<Icon name={icons.INTERACTIVE} />
|
||||||
|
}
|
||||||
|
title="Formats"
|
||||||
|
body={
|
||||||
|
<div className={styles.customFormatTooltip}>
|
||||||
|
<EpisodeFormats formats={customFormats} />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
position={tooltipPositions.LEFT}
|
||||||
|
/> :
|
||||||
|
null
|
||||||
|
}
|
||||||
|
</TableRowCell>
|
||||||
|
|
||||||
|
<TableRowCell>
|
||||||
|
{
|
||||||
|
rejections.length ?
|
||||||
<Popover
|
<Popover
|
||||||
anchor={
|
anchor={
|
||||||
<Icon
|
<Icon
|
||||||
|
@ -389,6 +410,7 @@ class InteractiveImportRow extends Component {
|
||||||
</ul>
|
</ul>
|
||||||
}
|
}
|
||||||
position={tooltipPositions.LEFT}
|
position={tooltipPositions.LEFT}
|
||||||
|
canFlip={false}
|
||||||
/> :
|
/> :
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
@ -462,6 +484,7 @@ InteractiveImportRow.propTypes = {
|
||||||
quality: PropTypes.object,
|
quality: PropTypes.object,
|
||||||
languages: PropTypes.arrayOf(PropTypes.object),
|
languages: PropTypes.arrayOf(PropTypes.object),
|
||||||
size: PropTypes.number.isRequired,
|
size: PropTypes.number.isRequired,
|
||||||
|
customFormats: PropTypes.arrayOf(PropTypes.object),
|
||||||
rejections: PropTypes.arrayOf(PropTypes.object).isRequired,
|
rejections: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
|
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
episodeFileId: PropTypes.number,
|
episodeFileId: PropTypes.number,
|
||||||
|
|
|
@ -18,6 +18,7 @@ namespace NzbDrone.Core.CustomFormats
|
||||||
List<CustomFormat> ParseCustomFormat(EpisodeFile episodeFile);
|
List<CustomFormat> ParseCustomFormat(EpisodeFile episodeFile);
|
||||||
List<CustomFormat> ParseCustomFormat(Blocklist blocklist, Series series);
|
List<CustomFormat> ParseCustomFormat(Blocklist blocklist, Series series);
|
||||||
List<CustomFormat> ParseCustomFormat(EpisodeHistory history, Series series);
|
List<CustomFormat> ParseCustomFormat(EpisodeHistory history, Series series);
|
||||||
|
List<CustomFormat> ParseCustomFormat(LocalEpisode localEpisode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CustomFormatCalculationService : ICustomFormatCalculationService
|
public class CustomFormatCalculationService : ICustomFormatCalculationService
|
||||||
|
@ -102,6 +103,28 @@ namespace NzbDrone.Core.CustomFormats
|
||||||
return ParseCustomFormat(input);
|
return ParseCustomFormat(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<CustomFormat> ParseCustomFormat(LocalEpisode localEpisode)
|
||||||
|
{
|
||||||
|
var episodeInfo = new ParsedEpisodeInfo
|
||||||
|
{
|
||||||
|
SeriesTitle = localEpisode.Series.Title,
|
||||||
|
ReleaseTitle = localEpisode.SceneName,
|
||||||
|
Quality = localEpisode.Quality,
|
||||||
|
Languages = localEpisode.Languages,
|
||||||
|
ReleaseGroup = localEpisode.ReleaseGroup
|
||||||
|
};
|
||||||
|
|
||||||
|
var input = new CustomFormatInput
|
||||||
|
{
|
||||||
|
EpisodeInfo = episodeInfo,
|
||||||
|
Series = localEpisode.Series,
|
||||||
|
Size = localEpisode.Size,
|
||||||
|
Languages = localEpisode.Languages
|
||||||
|
};
|
||||||
|
|
||||||
|
return ParseCustomFormat(input);
|
||||||
|
}
|
||||||
|
|
||||||
private List<CustomFormat> ParseCustomFormat(CustomFormatInput input)
|
private List<CustomFormat> ParseCustomFormat(CustomFormatInput input)
|
||||||
{
|
{
|
||||||
return ParseCustomFormat(input, _formatService.All());
|
return ParseCustomFormat(input, _formatService.All());
|
||||||
|
@ -148,7 +171,7 @@ namespace NzbDrone.Core.CustomFormats
|
||||||
|
|
||||||
var episodeInfo = new ParsedEpisodeInfo
|
var episodeInfo = new ParsedEpisodeInfo
|
||||||
{
|
{
|
||||||
SeriesTitle = episodeFile.Series.Value.Title,
|
SeriesTitle = series.Title,
|
||||||
ReleaseTitle = sceneName,
|
ReleaseTitle = sceneName,
|
||||||
Quality = episodeFile.Quality,
|
Quality = episodeFile.Quality,
|
||||||
Languages = episodeFile.Languages,
|
Languages = episodeFile.Languages,
|
||||||
|
|
|
@ -4,6 +4,7 @@ using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
|
using NzbDrone.Core.CustomFormats;
|
||||||
using NzbDrone.Core.DecisionEngine;
|
using NzbDrone.Core.DecisionEngine;
|
||||||
using NzbDrone.Core.Download;
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation;
|
using NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation;
|
||||||
|
@ -28,6 +29,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
private readonly IAggregationService _aggregationService;
|
private readonly IAggregationService _aggregationService;
|
||||||
private readonly IDiskProvider _diskProvider;
|
private readonly IDiskProvider _diskProvider;
|
||||||
private readonly IDetectSample _detectSample;
|
private readonly IDetectSample _detectSample;
|
||||||
|
private readonly ICustomFormatCalculationService _formatCalculator;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public ImportDecisionMaker(IEnumerable<IImportDecisionEngineSpecification> specifications,
|
public ImportDecisionMaker(IEnumerable<IImportDecisionEngineSpecification> specifications,
|
||||||
|
@ -35,6 +37,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
IAggregationService aggregationService,
|
IAggregationService aggregationService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IDetectSample detectSample,
|
IDetectSample detectSample,
|
||||||
|
ICustomFormatCalculationService formatCalculator,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
{
|
{
|
||||||
_specifications = specifications;
|
_specifications = specifications;
|
||||||
|
@ -42,6 +45,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
_aggregationService = aggregationService;
|
_aggregationService = aggregationService;
|
||||||
_diskProvider = diskProvider;
|
_diskProvider = diskProvider;
|
||||||
_detectSample = detectSample;
|
_detectSample = detectSample;
|
||||||
|
_formatCalculator = formatCalculator;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using NzbDrone.Core.CustomFormats;
|
||||||
using NzbDrone.Core.DecisionEngine;
|
using NzbDrone.Core.DecisionEngine;
|
||||||
using NzbDrone.Core.Languages;
|
using NzbDrone.Core.Languages;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
|
@ -21,6 +22,12 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
||||||
public List<Language> Languages { get; set; }
|
public List<Language> Languages { get; set; }
|
||||||
public string ReleaseGroup { get; set; }
|
public string ReleaseGroup { get; set; }
|
||||||
public string DownloadId { get; set; }
|
public string DownloadId { get; set; }
|
||||||
|
public List<CustomFormat> CustomFormats { get; set; }
|
||||||
public IEnumerable<Rejection> Rejections { get; set; }
|
public IEnumerable<Rejection> Rejections { get; set; }
|
||||||
|
|
||||||
|
public ManualImportItem()
|
||||||
|
{
|
||||||
|
CustomFormats = new List<CustomFormat>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ using NLog;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Instrumentation.Extensions;
|
using NzbDrone.Common.Instrumentation.Extensions;
|
||||||
|
using NzbDrone.Core.CustomFormats;
|
||||||
using NzbDrone.Core.DecisionEngine;
|
using NzbDrone.Core.DecisionEngine;
|
||||||
using NzbDrone.Core.Download;
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.Download.TrackedDownloads;
|
using NzbDrone.Core.Download.TrackedDownloads;
|
||||||
|
@ -40,6 +41,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
||||||
private readonly ITrackedDownloadService _trackedDownloadService;
|
private readonly ITrackedDownloadService _trackedDownloadService;
|
||||||
private readonly IDownloadedEpisodesImportService _downloadedEpisodesImportService;
|
private readonly IDownloadedEpisodesImportService _downloadedEpisodesImportService;
|
||||||
private readonly IMediaFileService _mediaFileService;
|
private readonly IMediaFileService _mediaFileService;
|
||||||
|
private readonly ICustomFormatCalculationService _formatCalculator;
|
||||||
private readonly IEventAggregator _eventAggregator;
|
private readonly IEventAggregator _eventAggregator;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
@ -54,6 +56,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
||||||
ITrackedDownloadService trackedDownloadService,
|
ITrackedDownloadService trackedDownloadService,
|
||||||
IDownloadedEpisodesImportService downloadedEpisodesImportService,
|
IDownloadedEpisodesImportService downloadedEpisodesImportService,
|
||||||
IMediaFileService mediaFileService,
|
IMediaFileService mediaFileService,
|
||||||
|
ICustomFormatCalculationService formatCalculator,
|
||||||
IEventAggregator eventAggregator,
|
IEventAggregator eventAggregator,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
{
|
{
|
||||||
|
@ -68,6 +71,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
||||||
_trackedDownloadService = trackedDownloadService;
|
_trackedDownloadService = trackedDownloadService;
|
||||||
_downloadedEpisodesImportService = downloadedEpisodesImportService;
|
_downloadedEpisodesImportService = downloadedEpisodesImportService;
|
||||||
_mediaFileService = mediaFileService;
|
_mediaFileService = mediaFileService;
|
||||||
|
_formatCalculator = formatCalculator;
|
||||||
_eventAggregator = eventAggregator;
|
_eventAggregator = eventAggregator;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
@ -382,6 +386,8 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
||||||
if (decision.LocalEpisode.Series != null)
|
if (decision.LocalEpisode.Series != null)
|
||||||
{
|
{
|
||||||
item.Series = decision.LocalEpisode.Series;
|
item.Series = decision.LocalEpisode.Series;
|
||||||
|
|
||||||
|
item.CustomFormats = _formatCalculator.ParseCustomFormat(decision.LocalEpisode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decision.LocalEpisode.Episodes.Any() && decision.LocalEpisode.Episodes.Select(c => c.SeasonNumber).Distinct().Count() == 1)
|
if (decision.LocalEpisode.Episodes.Any() && decision.LocalEpisode.Episodes.Select(c => c.SeasonNumber).Distinct().Count() == 1)
|
||||||
|
@ -429,6 +435,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
||||||
item.Size = _diskProvider.GetFileSize(item.Path);
|
item.Size = _diskProvider.GetFileSize(item.Path);
|
||||||
item.Rejections = Enumerable.Empty<Rejection>();
|
item.Rejections = Enumerable.Empty<Rejection>();
|
||||||
item.EpisodeFileId = episodeFile.Id;
|
item.EpisodeFileId = episodeFile.Id;
|
||||||
|
item.CustomFormats = _formatCalculator.ParseCustomFormat(episodeFile, series);
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ using NzbDrone.Core.DecisionEngine;
|
||||||
using NzbDrone.Core.Languages;
|
using NzbDrone.Core.Languages;
|
||||||
using NzbDrone.Core.MediaFiles.EpisodeImport.Manual;
|
using NzbDrone.Core.MediaFiles.EpisodeImport.Manual;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
|
using Sonarr.Api.V3.CustomFormats;
|
||||||
using Sonarr.Api.V3.Episodes;
|
using Sonarr.Api.V3.Episodes;
|
||||||
using Sonarr.Api.V3.Series;
|
using Sonarr.Api.V3.Series;
|
||||||
using Sonarr.Http.REST;
|
using Sonarr.Http.REST;
|
||||||
|
@ -27,6 +28,7 @@ namespace Sonarr.Api.V3.ManualImport
|
||||||
public List<Language> Languages { get; set; }
|
public List<Language> Languages { get; set; }
|
||||||
public int QualityWeight { get; set; }
|
public int QualityWeight { get; set; }
|
||||||
public string DownloadId { get; set; }
|
public string DownloadId { get; set; }
|
||||||
|
public List<CustomFormatResource> CustomFormats { get; set; }
|
||||||
public IEnumerable<Rejection> Rejections { get; set; }
|
public IEnumerable<Rejection> Rejections { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,6 +56,7 @@ namespace Sonarr.Api.V3.ManualImport
|
||||||
ReleaseGroup = model.ReleaseGroup,
|
ReleaseGroup = model.ReleaseGroup,
|
||||||
Quality = model.Quality,
|
Quality = model.Quality,
|
||||||
Languages = model.Languages,
|
Languages = model.Languages,
|
||||||
|
CustomFormats = model.CustomFormats.ToResource(),
|
||||||
|
|
||||||
// QualityWeight
|
// QualityWeight
|
||||||
DownloadId = model.DownloadId,
|
DownloadId = model.DownloadId,
|
||||||
|
|
Loading…
Reference in New Issue