using System; using System.Collections.Generic; using System.IO; using System.Text; using NLog; using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; using NzbDrone.Core.Configuration; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.Music; namespace NzbDrone.Core.Extras.Files { public interface IManageExtraFiles { int Order { get; } IEnumerable CreateAfterMediaCoverUpdate(Artist artist); IEnumerable CreateAfterArtistScan(Artist artist, List trackFiles); IEnumerable CreateAfterTrackImport(Artist artist, TrackFile trackFile); IEnumerable CreateAfterTrackFolder(Artist artist, Album album, string artistFolder, string albumFolder); IEnumerable MoveFilesAfterRename(Artist artist, List trackFiles); ExtraFile Import(Artist artist, TrackFile trackFile, string path, string extension, bool readOnly); } public abstract class ExtraFileManager : IManageExtraFiles where TExtraFile : ExtraFile, new() { private readonly IConfigService _configService; private readonly IDiskProvider _diskProvider; private readonly IDiskTransferService _diskTransferService; private readonly Logger _logger; public ExtraFileManager(IConfigService configService, IDiskProvider diskProvider, IDiskTransferService diskTransferService, Logger logger) { _configService = configService; _diskProvider = diskProvider; _diskTransferService = diskTransferService; _logger = logger; } public abstract int Order { get; } public abstract IEnumerable CreateAfterMediaCoverUpdate(Artist artist); public abstract IEnumerable CreateAfterArtistScan(Artist artist, List trackFiles); public abstract IEnumerable CreateAfterTrackImport(Artist artist, TrackFile trackFile); public abstract IEnumerable CreateAfterTrackFolder(Artist artist, Album album, string artistFolder, string albumFolder); public abstract IEnumerable MoveFilesAfterRename(Artist artist, List trackFiles); public abstract ExtraFile Import(Artist artist, TrackFile trackFile, string path, string extension, bool readOnly); protected TExtraFile ImportFile(Artist artist, TrackFile trackFile, string path, bool readOnly, string extension, string fileNameSuffix = null) { var newFolder = Path.GetDirectoryName(trackFile.Path); var filenameBuilder = new StringBuilder(Path.GetFileNameWithoutExtension(trackFile.Path)); if (fileNameSuffix.IsNotNullOrWhiteSpace()) { filenameBuilder.Append(fileNameSuffix); } filenameBuilder.Append(extension); var newFileName = Path.Combine(newFolder, filenameBuilder.ToString()); var transferMode = TransferMode.Move; if (readOnly) { transferMode = _configService.CopyUsingHardlinks ? TransferMode.HardLinkOrCopy : TransferMode.Copy; } _diskTransferService.TransferFile(path, newFileName, transferMode, true); return new TExtraFile { ArtistId = artist.Id, AlbumId = trackFile.AlbumId, TrackFileId = trackFile.Id, RelativePath = artist.Path.GetRelativePath(newFileName), Extension = extension }; } protected TExtraFile MoveFile(Artist artist, TrackFile trackFile, TExtraFile extraFile, string fileNameSuffix = null) { var newFolder = Path.GetDirectoryName(trackFile.Path); var filenameBuilder = new StringBuilder(Path.GetFileNameWithoutExtension(trackFile.Path)); if (fileNameSuffix.IsNotNullOrWhiteSpace()) { filenameBuilder.Append(fileNameSuffix); } filenameBuilder.Append(extraFile.Extension); var existingFileName = Path.Combine(artist.Path, extraFile.RelativePath); var newFileName = Path.Combine(newFolder, filenameBuilder.ToString()); if (newFileName.PathNotEquals(existingFileName)) { try { _diskProvider.MoveFile(existingFileName, newFileName); extraFile.RelativePath = artist.Path.GetRelativePath(newFileName); return extraFile; } catch (Exception ex) { _logger.Warn(ex, "Unable to move file after rename: {0}", existingFileName); } } return null; } } }