From bb8a0dda631cd1b084b7cb165457a6224608935e Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 16 Feb 2025 20:58:04 +0200 Subject: [PATCH] Fixed: Processing existing movie files via Manage Files --- frontend/src/Movie/Details/MovieDetails.js | 10 ++-- .../MovieImport/Manual/ManualImportItem.cs | 3 +- .../MovieImport/Manual/ManualImportService.cs | 54 +++++++++++++++++++ .../ManualImport/ManualImportController.cs | 5 ++ .../ManualImport/ManualImportResource.cs | 4 +- 5 files changed, 71 insertions(+), 5 deletions(-) diff --git a/frontend/src/Movie/Details/MovieDetails.js b/frontend/src/Movie/Details/MovieDetails.js index 4ba7dda04..d03f7e9c8 100644 --- a/frontend/src/Movie/Details/MovieDetails.js +++ b/frontend/src/Movie/Details/MovieDetails.js @@ -21,7 +21,7 @@ import TmdbRating from 'Components/TmdbRating'; import Popover from 'Components/Tooltip/Popover'; import Tooltip from 'Components/Tooltip/Tooltip'; import TraktRating from 'Components/TraktRating'; -import { icons, kinds, sizes, tooltipPositions } from 'Helpers/Props'; +import { icons, kinds, sizes, sortDirections, tooltipPositions } from 'Helpers/Props'; import InteractiveImportModal from 'InteractiveImport/InteractiveImportModal'; import DeleteMovieModal from 'Movie/Delete/DeleteMovieModal'; import EditMovieModalConnector from 'Movie/Edit/EditMovieModalConnector'; @@ -753,11 +753,15 @@ class MovieDetails extends Component { diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportItem.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportItem.cs index af6bf94d1..f43ceafc8 100644 --- a/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportItem.cs +++ b/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportItem.cs @@ -13,6 +13,8 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Manual public string FolderName { get; set; } public string Name { get; set; } public long Size { get; set; } + public Movie Movie { get; set; } + public int? MovieFileId { get; set; } public QualityModel Quality { get; set; } public List Languages { get; set; } public string ReleaseGroup { get; set; } @@ -21,7 +23,6 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Manual public int CustomFormatScore { get; set; } public int IndexerFlags { get; set; } public IEnumerable Rejections { get; set; } - public Movie Movie { get; set; } public ManualImportItem() { diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportService.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportService.cs index cfb96548e..f0e5beed9 100644 --- a/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportService.cs +++ b/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportService.cs @@ -22,6 +22,7 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Manual { public interface IManualImportService { + List GetMediaFiles(int movieId); List GetMediaFiles(string path, string downloadId, int? movieId, bool filterExistingFiles); ManualImportItem ReprocessItem(string path, string downloadId, int movieId, string releaseGroup, QualityModel quality, List languages, int indexerFlags); } @@ -37,6 +38,7 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Manual private readonly IAggregationService _aggregationService; private readonly ITrackedDownloadService _trackedDownloadService; private readonly IDownloadedMovieImportService _downloadedMovieImportService; + private readonly IMediaFileService _mediaFileService; private readonly ICustomFormatCalculationService _formatCalculator; private readonly IEventAggregator _eventAggregator; private readonly Logger _logger; @@ -50,6 +52,7 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Manual IImportApprovedMovie importApprovedMovie, ITrackedDownloadService trackedDownloadService, IDownloadedMovieImportService downloadedMovieImportService, + IMediaFileService mediaFileService, ICustomFormatCalculationService formatCalculator, IEventAggregator eventAggregator, Logger logger) @@ -63,11 +66,41 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Manual _importApprovedMovie = importApprovedMovie; _trackedDownloadService = trackedDownloadService; _downloadedMovieImportService = downloadedMovieImportService; + _mediaFileService = mediaFileService; _formatCalculator = formatCalculator; _eventAggregator = eventAggregator; _logger = logger; } + public List GetMediaFiles(int movieId) + { + var movie = _movieService.GetMovie(movieId); + var directoryInfo = new DirectoryInfo(movie.Path); + var movieFiles = _mediaFileService.GetFilesByMovie(movieId); + + var items = movieFiles.Select(movieFile => MapItem(movieFile, movie, directoryInfo.Name)).ToList(); + + var mediaFiles = _diskScanService.FilterPaths(movie.Path, _diskScanService.GetVideoFiles(movie.Path)).ToList(); + var unmappedFiles = MediaFileService.FilterExistingFiles(mediaFiles, movieFiles, movie); + + items.AddRange(unmappedFiles.Select(file => + new ManualImportItem + { + Path = Path.Combine(movie.Path, file), + FolderName = directoryInfo.Name, + RelativePath = movie.Path.GetRelativePath(file), + Name = Path.GetFileNameWithoutExtension(file), + Movie = movie, + ReleaseGroup = string.Empty, + Quality = new QualityModel(Quality.Unknown), + Languages = new List { Language.Unknown }, + Size = _diskProvider.GetFileSize(file), + Rejections = Enumerable.Empty() + })); + + return items; + } + public List GetMediaFiles(string path, string downloadId, int? movieId, bool filterExistingFiles) { if (downloadId.IsNotNullOrWhiteSpace()) @@ -348,6 +381,27 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Manual return item; } + private ManualImportItem MapItem(MovieFile movieFile, Movie movie, string folderName) + { + var item = new ManualImportItem(); + + item.Path = Path.Combine(movie.Path, movieFile.RelativePath); + item.FolderName = folderName; + item.RelativePath = movieFile.RelativePath; + item.Name = Path.GetFileNameWithoutExtension(movieFile.Path); + item.Movie = movie; + item.ReleaseGroup = movieFile.ReleaseGroup; + item.Quality = movieFile.Quality; + item.Languages = movieFile.Languages; + item.IndexerFlags = (int)movieFile.IndexerFlags; + item.Size = _diskProvider.GetFileSize(item.Path); + item.Rejections = Enumerable.Empty(); + item.MovieFileId = movieFile.Id; + item.CustomFormats = _formatCalculator.ParseCustomFormat(movieFile, movie); + + return item; + } + public void Execute(ManualImportCommand message) { _logger.ProgressTrace("Manually importing {0} files using mode {1}", message.Files.Count, message.ImportMode); diff --git a/src/Radarr.Api.V3/ManualImport/ManualImportController.cs b/src/Radarr.Api.V3/ManualImport/ManualImportController.cs index 8c1f3ba38..4df77e9b8 100644 --- a/src/Radarr.Api.V3/ManualImport/ManualImportController.cs +++ b/src/Radarr.Api.V3/ManualImport/ManualImportController.cs @@ -25,6 +25,11 @@ namespace Radarr.Api.V3.ManualImport [Produces("application/json")] public List GetMediaFiles(string folder, string downloadId, int? movieId, bool filterExistingFiles = true) { + if (movieId.HasValue) + { + return _manualImportService.GetMediaFiles(movieId.Value).ToResource().Select(AddQualityWeight).ToList(); + } + return _manualImportService.GetMediaFiles(folder, downloadId, movieId, filterExistingFiles).ToResource().Select(AddQualityWeight).ToList(); } diff --git a/src/Radarr.Api.V3/ManualImport/ManualImportResource.cs b/src/Radarr.Api.V3/ManualImport/ManualImportResource.cs index deae5dad7..d94747714 100644 --- a/src/Radarr.Api.V3/ManualImport/ManualImportResource.cs +++ b/src/Radarr.Api.V3/ManualImport/ManualImportResource.cs @@ -20,9 +20,10 @@ namespace Radarr.Api.V3.ManualImport public string Name { get; set; } public long Size { get; set; } public MovieResource Movie { get; set; } + public int? MovieFileId { get; set; } + public string ReleaseGroup { get; set; } public QualityModel Quality { get; set; } public List Languages { get; set; } - public string ReleaseGroup { get; set; } public int QualityWeight { get; set; } public string DownloadId { get; set; } public List CustomFormats { get; set; } @@ -52,6 +53,7 @@ namespace Radarr.Api.V3.ManualImport Name = model.Name, Size = model.Size, Movie = model.Movie.ToResource(0), + MovieFileId = model.MovieFileId, ReleaseGroup = model.ReleaseGroup, Quality = model.Quality, Languages = model.Languages,