using System.IO; using NLog; using NzbDrone.Common.Disk; using NzbDrone.Common.Instrumentation.Extensions; using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Organizer; using NzbDrone.Core.Tv.Commands; using NzbDrone.Core.Tv.Events; namespace NzbDrone.Core.Tv { public class MoveSeriesService : IExecute, IExecute { private readonly ISeriesService _seriesService; private readonly IBuildFileNames _filenameBuilder; private readonly IDiskProvider _diskProvider; private readonly IDiskTransferService _diskTransferService; private readonly IEventAggregator _eventAggregator; private readonly Logger _logger; public MoveSeriesService(ISeriesService seriesService, IBuildFileNames filenameBuilder, IDiskProvider diskProvider, IDiskTransferService diskTransferService, IEventAggregator eventAggregator, Logger logger) { _seriesService = seriesService; _filenameBuilder = filenameBuilder; _diskProvider = diskProvider; _diskTransferService = diskTransferService; _eventAggregator = eventAggregator; _logger = logger; } private void MoveSingleSeries(Series series, string sourcePath, string destinationPath, int? index = null, int? total = null) { if (!_diskProvider.FolderExists(sourcePath)) { _logger.Debug("Folder '{0}' for '{1}' does not exist, not moving.", sourcePath, series.Title); return; } if (index != null && total != null) { _logger.ProgressInfo("Moving {0} from '{1}' to '{2}' ({3}/{4})", series.Title, sourcePath, destinationPath, index + 1, total); } else { _logger.ProgressInfo("Moving {0} from '{1}' to '{2}'", series.Title, sourcePath, destinationPath); } try { // Ensure the parent of the series folder exists, this will often just be the root folder, but // in cases where people are using subfolders for first letter (etc) it may not yet exist. _diskProvider.CreateFolder(new DirectoryInfo(destinationPath).Parent.FullName); _diskTransferService.TransferFolder(sourcePath, destinationPath, TransferMode.Move); _logger.ProgressInfo("{0} moved successfully to {1}", series.Title, destinationPath); _eventAggregator.PublishEvent(new SeriesMovedEvent(series, sourcePath, destinationPath)); } catch (IOException ex) { _logger.Error(ex, "Unable to move series from '{0}' to '{1}'. Try moving files manually", sourcePath, destinationPath); RevertPath(series.Id, sourcePath); } } private void RevertPath(int seriesId, string path) { var series = _seriesService.GetSeries(seriesId); series.Path = path; _seriesService.UpdateSeries(series); } public void Execute(MoveSeriesCommand message) { var series = _seriesService.GetSeries(message.SeriesId); MoveSingleSeries(series, message.SourcePath, message.DestinationPath); } public void Execute(BulkMoveSeriesCommand message) { var seriesToMove = message.Series; var destinationRootFolder = message.DestinationRootFolder; _logger.ProgressInfo("Moving {0} series to '{1}'", seriesToMove.Count, destinationRootFolder); for (var index = 0; index < seriesToMove.Count; index++) { var s = seriesToMove[index]; var series = _seriesService.GetSeries(s.SeriesId); var destinationPath = Path.Combine(destinationRootFolder, _filenameBuilder.GetSeriesFolder(series)); MoveSingleSeries(series, s.SourcePath, destinationPath, index, seriesToMove.Count); } _logger.ProgressInfo("Finished moving {0} series to '{1}'", seriesToMove.Count, destinationRootFolder); } } }