feat: resolve Manual Import mode to Copy when copyUsingHardlinks is enabled

When ImportMode is Auto and copyUsingHardlinks is true in Media Management
settings, resolve Manual Import mode to Copy instead of letting it fall
through to Move. This prevents breaking active torrents when using a
hardlink-based workflow.

Fixes #11418
This commit is contained in:
Sergey Gladkovskiy 2026-04-05 17:47:05 +03:00
parent 4b85fab05b
commit f450edf033

View file

@ -6,6 +6,7 @@
using NzbDrone.Common.Disk;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Instrumentation.Extensions;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.CustomFormats;
using NzbDrone.Core.Download;
using NzbDrone.Core.Download.TrackedDownloads;
@ -40,6 +41,7 @@ public class ManualImportService : IExecute<ManualImportCommand>, IManualImportS
private readonly IDownloadedMovieImportService _downloadedMovieImportService;
private readonly IMediaFileService _mediaFileService;
private readonly ICustomFormatCalculationService _formatCalculator;
private readonly IConfigService _configService;
private readonly IEventAggregator _eventAggregator;
private readonly Logger _logger;
@ -54,6 +56,7 @@ public ManualImportService(IDiskProvider diskProvider,
IDownloadedMovieImportService downloadedMovieImportService,
IMediaFileService mediaFileService,
ICustomFormatCalculationService formatCalculator,
IConfigService configService,
IEventAggregator eventAggregator,
Logger logger)
{
@ -68,6 +71,7 @@ public ManualImportService(IDiskProvider diskProvider,
_downloadedMovieImportService = downloadedMovieImportService;
_mediaFileService = mediaFileService;
_formatCalculator = formatCalculator;
_configService = configService;
_eventAggregator = eventAggregator;
_logger = logger;
}
@ -406,6 +410,16 @@ public void Execute(ManualImportCommand message)
{
_logger.ProgressTrace("Manually importing {0} files using mode {1}", message.Files.Count, message.ImportMode);
var importMode = message.ImportMode;
// When ImportMode is Auto and CopyUsingHardlinks is enabled, default to Copy
// to preserve original files for seeding and use hardlinks instead of moving.
if (importMode == ImportMode.Auto && _configService.CopyUsingHardlinks)
{
importMode = ImportMode.Copy;
_logger.Debug("ImportMode Auto resolved to Copy because CopyUsingHardlinks is enabled");
}
var imported = new List<ImportResult>();
var importedTrackedDownload = new List<ManuallyImportedFile>();
@ -463,11 +477,11 @@ public void Execute(ManualImportCommand message)
if (trackedDownload == null)
{
imported.AddRange(_importApprovedMovie.Import(new List<ImportDecision> { importDecision }, !existingFile, null, message.ImportMode));
imported.AddRange(_importApprovedMovie.Import(new List<ImportDecision> { importDecision }, !existingFile, null, importMode));
}
else
{
var importResult = _importApprovedMovie.Import(new List<ImportDecision> { importDecision }, true, trackedDownload.DownloadItem, message.ImportMode).First();
var importResult = _importApprovedMovie.Import(new List<ImportDecision> { importDecision }, true, trackedDownload.DownloadItem, importMode).First();
imported.Add(importResult);