public void Backup() { _logger.Info("Backing up appdata (database/config)"); var backupFolderAppData = _appFolderInfo.GetUpdateBackUpAppDataFolder(); _diskProvider.CreateFolder(backupFolderAppData); _diskProvider.CopyFile(_appFolderInfo.GetConfigPath(), _appFolderInfo.GetUpdateBackupConfigFile(), true); _diskProvider.CopyFile(_appFolderInfo.GetNzbDroneDatabase(), _appFolderInfo.GetUpdateBackupDatabase(), true); }
private void DownloadImage(Series series, ImageFileResult image) { var fullPath = Path.Combine(series.Path, image.RelativePath); try { if (image.Url.StartsWith("http")) { _httpClient.DownloadFile(image.Url, fullPath); } else { _diskProvider.CopyFile(image.Url, fullPath); } _mediaFileAttributeService.SetFilePermissions(fullPath); } catch (WebException ex) { _logger.Warn(ex, "Couldn't download image {0} for {1}. {2}", image.Url, series, ex.Message); } catch (Exception ex) { _logger.Error(ex, "Couldn't download image {0} for {1}. {2}", image.Url, series, ex.Message); } }
private void BackupDatabase() { _logger.ProgressDebug("Backing up database"); using (var unitOfWork = new UnitOfWork(() => _maindDb.GetDataMapper())) { unitOfWork.BeginTransaction(IsolationLevel.Serializable); var databaseFile = _appFolderInfo.GetNzbDroneDatabase(); var tempDatabaseFile = Path.Combine(_backupTempFolder, Path.GetFileName(databaseFile)); _diskProvider.CopyFile(databaseFile, tempDatabaseFile, true); unitOfWork.Commit(); } }
private List <MetadataFile> ProcessSeriesImages(IMetadata consumer, Series series, List <MetadataFile> existingMetadataFiles) { var result = new List <MetadataFile>(); foreach (var image in consumer.SeriesImages(series)) { if (_diskProvider.FileExists(image.RelativePath)) { _logger.Debug("Series image already exists: {0}", image.RelativePath); continue; } var metadata = existingMetadataFiles.SingleOrDefault(c => c.Type == MetadataType.SeriesImage && c.RelativePath == image.RelativePath) ?? new MetadataFile { SeriesId = series.Id, Consumer = consumer.GetType().Name, Type = MetadataType.SeriesImage, RelativePath = image.RelativePath }; _diskProvider.CopyFile(image.Url, image.RelativePath); result.Add(metadata); } return(result); }
private void MoveSqliteDatabase(string source, string destination) { _logger.Info("Moving {0}* to {1}*", source, destination); var dbSuffixes = new[] { "", "-shm", "-wal", "-journal" }; foreach (var suffix in dbSuffixes) { var sourceFile = source + suffix; var destFile = destination + suffix; if (_diskProvider.FileExists(destFile)) { _diskProvider.DeleteFile(destFile); } if (_diskProvider.FileExists(sourceFile)) { _diskProvider.CopyFile(sourceFile, destFile); } } foreach (var suffix in dbSuffixes) { var sourceFile = source + suffix; if (_diskProvider.FileExists(sourceFile)) { _diskProvider.DeleteFile(sourceFile); } } }
private IEnumerable <MetadataFile> WriteSeriesImages(Series series, List <MetadataFile> existingMetadataFiles) { foreach (var image in series.Images) { var source = _mediaCoverService.GetCoverPath(series.Id, image.CoverType); var destination = Path.Combine(series.Path, image.CoverType.ToString().ToLowerInvariant() + Path.GetExtension(source)); //TODO: Do we want to overwrite the file if it exists? if (_diskProvider.FileExists(destination)) { _logger.Debug("Series image: {0} already exists.", image.CoverType); continue; } _diskProvider.CopyFile(source, destination, false); var relativePath = DiskProviderBase.GetRelativePath(series.Path, destination); var metadata = existingMetadataFiles.SingleOrDefault(c => c.Type == MetadataType.SeriesImage && c.RelativePath == relativePath) ?? new MetadataFile { SeriesId = series.Id, Consumer = GetType().Name, Type = MetadataType.SeriesImage, RelativePath = relativePath }; yield return(metadata); } }
private void DownloadImage(Movie movie, ImageFileResult image) { _logger.Debug("Download Movie Image for: {0}", Path.Combine(movie.Path, movie.MovieFile?.RelativePath ?? string.Empty)); var fullPath = Path.Combine(movie.Path, image.RelativePath); try { if (image.Url.StartsWith("http")) { _httpClient.DownloadFile(image.Url, fullPath); } else { _diskProvider.CopyFile(image.Url, fullPath); } _mediaFileAttributeService.SetFilePermissions(fullPath); } catch (HttpException ex) { _logger.Warn(ex, "Couldn't download image {0} for {1}. {2}", image.Url, movie, ex.Message); } catch (WebException ex) { _logger.Warn(ex, "Couldn't download image {0} for {1}. {2}", image.Url, movie, ex.Message); } catch (Exception ex) { _logger.Error(ex, "Couldn't download image {0} for {1}. {2}", image.Url, movie, ex.Message); } }
public void Backup() { _logger.Info("Backing up appdata (database/config)"); var backupFolderAppData = _appFolderInfo.GetUpdateBackUpAppDataFolder(); _diskProvider.CreateFolder(backupFolderAppData); try { _diskProvider.CopyFile(_appFolderInfo.GetConfigPath(), _appFolderInfo.GetUpdateBackupConfigFile(), true); _diskProvider.CopyFile(_appFolderInfo.GetNzbDroneDatabase(), _appFolderInfo.GetUpdateBackupDatabase(), true); } catch (Exception e) { _logger.ErrorException("Couldn't create a data backup", e); } }
private void TryCopyFileVerified(string sourcePath, string targetPath, long originalSize) { try { _diskProvider.CopyFile(sourcePath, targetPath); var targetSize = _diskProvider.GetFileSize(targetPath); if (targetSize != originalSize) { throw new IOException(string.Format("File copy incomplete. [{0}] was {1} bytes long instead of {2} bytes.", targetPath, targetSize, originalSize)); } } catch { RollbackCopy(sourcePath, targetPath); throw; } }
private MetadataFile WriteSeriesImages(Series series, List <MetadataFile> existingMetadataFiles) { //Because we only support one image, attempt to get the Poster type, then if that fails grab the first var image = series.Images.SingleOrDefault(c => c.CoverType == MediaCoverTypes.Poster) ?? series.Images.FirstOrDefault(); if (image == null) { _logger.Trace("Failed to find suitable Series image for series {0}.", series.Title); return(null); } var source = _mediaCoverService.GetCoverPath(series.Id, image.CoverType); var destination = Path.Combine(series.Path, "folder" + Path.GetExtension(source)); //TODO: Do we want to overwrite the file if it exists? if (_diskProvider.FileExists(destination)) { _logger.Debug("Series image: {0} already exists.", image.CoverType); return(null); } else { _diskProvider.CopyFile(source, destination, false); var metadata = existingMetadataFiles.SingleOrDefault(c => c.Type == MetadataType.SeriesImage) ?? new MetadataFile { SeriesId = series.Id, Consumer = GetType().Name, Type = MetadataType.SeriesImage, RelativePath = DiskProviderBase.GetRelativePath(series.Path, destination) }; return(metadata); } }
private EpisodeFile TransferFile(EpisodeFile episodeFile, Series series, List <Episode> episodes, String destinationFilename, Boolean copyOnly) { Ensure.That(episodeFile, () => episodeFile).IsNotNull(); Ensure.That(series, () => series).IsNotNull(); Ensure.That(destinationFilename, () => destinationFilename).IsValidPath(); var episodeFilePath = episodeFile.Path ?? Path.Combine(series.Path, episodeFile.RelativePath); if (!_diskProvider.FileExists(episodeFilePath)) { throw new FileNotFoundException("Episode file path does not exist", episodeFilePath); } if (episodeFilePath.PathEquals(destinationFilename)) { throw new SameFilenameException("File not moved, source and destination are the same", episodeFilePath); } var directoryName = new FileInfo(destinationFilename).DirectoryName; if (!_diskProvider.FolderExists(directoryName)) { try { _diskProvider.CreateFolder(directoryName); } catch (IOException ex) { _logger.ErrorException("Unable to create directory: " + directoryName, ex); } SetFolderPermissions(directoryName); if (!directoryName.PathEquals(series.Path)) { SetFolderPermissions(series.Path); } } if (copyOnly) { _logger.Debug("Copying [{0}] > [{1}]", episodeFilePath, destinationFilename); _diskProvider.CopyFile(episodeFilePath, destinationFilename); } else { _logger.Debug("Moving [{0}] > [{1}]", episodeFilePath, destinationFilename); _diskProvider.MoveFile(episodeFilePath, destinationFilename); } episodeFile.RelativePath = series.Path.GetRelativePath(destinationFilename); _updateEpisodeFileService.ChangeFileDateForFile(episodeFile, series, episodes); try { SetFolderLastWriteTime(series.Path, episodeFile.DateAdded); if (series.SeasonFolder) { var seasonFolder = Path.GetDirectoryName(destinationFilename); SetFolderLastWriteTime(seasonFolder, episodeFile.DateAdded); } } catch (Exception ex) { _logger.WarnException("Unable to set last write time", ex); } //We should only run this on Windows if (OsInfo.IsWindows) { //Wrapped in Try/Catch to prevent this from causing issues with remote NAS boxes, the move worked, which is more important. try { _diskProvider.InheritFolderPermissions(destinationFilename); } catch (Exception ex) { if (ex is UnauthorizedAccessException || ex is InvalidOperationException) { _logger.Debug("Unable to apply folder permissions to: ", destinationFilename); _logger.DebugException(ex.Message, ex); } else { throw; } } } else { SetPermissions(destinationFilename, _configService.FileChmod); } return(episodeFile); }
public TransferMode TransferFile(string sourcePath, string targetPath, TransferMode mode, bool overwrite, DiskTransferVerificationMode verificationMode) { Ensure.That(sourcePath, () => sourcePath).IsValidPath(); Ensure.That(targetPath, () => targetPath).IsValidPath(); _logger.Debug("{0} [{1}] > [{2}]", mode, sourcePath, targetPath); var originalSize = _diskProvider.GetFileSize(sourcePath); if (sourcePath == targetPath) { throw new IOException(string.Format("Source and destination can't be the same {0}", sourcePath)); } if (sourcePath.PathEquals(targetPath, StringComparison.InvariantCultureIgnoreCase)) { if (mode.HasFlag(TransferMode.HardLink) || mode.HasFlag(TransferMode.Copy)) { throw new IOException(string.Format("Source and destination can't be the same {0}", sourcePath)); } if (mode.HasFlag(TransferMode.Move)) { var tempPath = sourcePath + ".backup~"; _diskProvider.MoveFile(sourcePath, tempPath, true); try { ClearTargetPath(targetPath, overwrite); _diskProvider.MoveFile(tempPath, targetPath); return(TransferMode.Move); } catch { RollbackMove(sourcePath, tempPath); throw; } } return(TransferMode.None); } if (sourcePath.GetParentPath() == targetPath.GetParentPath()) { if (mode.HasFlag(TransferMode.Move)) { TryMoveFileVerified(sourcePath, targetPath, originalSize); return(TransferMode.Move); } } if (sourcePath.IsParentPath(targetPath)) { throw new IOException(string.Format("Destination cannot be a child of the source [{0}] => [{1}]", sourcePath, targetPath)); } ClearTargetPath(targetPath, overwrite); if (mode.HasFlag(TransferMode.HardLink)) { var createdHardlink = _diskProvider.TryCreateHardLink(sourcePath, targetPath); if (createdHardlink) { return(TransferMode.HardLink); } if (!mode.HasFlag(TransferMode.Copy)) { throw new IOException("Hardlinking from '" + sourcePath + "' to '" + targetPath + "' failed."); } } // We force a transactional transfer if the transfer occurs between mounts and one of the mounts is cifs, it would be a copy anyway. if (verificationMode == DiskTransferVerificationMode.TryTransactional && OsInfo.IsNotWindows) { var sourceMount = _diskProvider.GetMount(sourcePath); var targetMount = _diskProvider.GetMount(targetPath); if (sourceMount != null && targetMount != null && sourceMount.RootDirectory != targetMount.RootDirectory && (sourceMount.DriveFormat == "cifs" || targetMount.DriveFormat == "cifs")) { verificationMode = DiskTransferVerificationMode.Transactional; } } if (mode.HasFlag(TransferMode.Copy)) { if (verificationMode == DiskTransferVerificationMode.Transactional || verificationMode == DiskTransferVerificationMode.TryTransactional) { if (TryCopyFileTransactional(sourcePath, targetPath, originalSize)) { return(TransferMode.Copy); } throw new IOException(string.Format("Failed to completely transfer [{0}] to [{1}], aborting.", sourcePath, targetPath)); } else if (verificationMode == DiskTransferVerificationMode.VerifyOnly) { TryCopyFileVerified(sourcePath, targetPath, originalSize); return(TransferMode.Copy); } else { _diskProvider.CopyFile(sourcePath, targetPath); return(TransferMode.Copy); } } if (mode.HasFlag(TransferMode.Move)) { if (verificationMode == DiskTransferVerificationMode.Transactional || verificationMode == DiskTransferVerificationMode.TryTransactional) { if (TryMoveFileTransactional(sourcePath, targetPath, originalSize, verificationMode)) { return(TransferMode.Move); } throw new IOException(string.Format("Failed to completely transfer [{0}] to [{1}], aborting.", sourcePath, targetPath)); } else if (verificationMode == DiskTransferVerificationMode.VerifyOnly) { TryMoveFileVerified(sourcePath, targetPath, originalSize); return(TransferMode.Move); } else { _diskProvider.MoveFile(sourcePath, targetPath); return(TransferMode.Move); } } return(TransferMode.None); }
public TransferMode TransferFile(string sourcePath, string targetPath, TransferMode mode, bool overwrite = false, bool verified = true) { Ensure.That(sourcePath, () => sourcePath).IsValidPath(); Ensure.That(targetPath, () => targetPath).IsValidPath(); if (VerificationMode != DiskTransferVerificationMode.Transactional) { verified = false; } _logger.Debug("{0} [{1}] > [{2}]", mode, sourcePath, targetPath); if (sourcePath == targetPath) { throw new IOException(string.Format("Source and destination can't be the same {0}", sourcePath)); } if (sourcePath.PathEquals(targetPath, StringComparison.InvariantCultureIgnoreCase)) { if (mode.HasFlag(TransferMode.HardLink) || mode.HasFlag(TransferMode.Copy)) { throw new IOException(string.Format("Source and destination can't be the same {0}", sourcePath)); } if (mode.HasFlag(TransferMode.Move)) { var tempPath = sourcePath + ".backup~"; _diskProvider.MoveFile(sourcePath, tempPath, true); try { ClearTargetPath(targetPath, overwrite); _diskProvider.MoveFile(tempPath, targetPath); return(TransferMode.Move); } catch { RollbackMove(sourcePath, tempPath); throw; } } return(TransferMode.None); } if (sourcePath.IsParentPath(targetPath)) { throw new IOException(string.Format("Destination cannot be a child of the source [{0}] => [{1}]", sourcePath, targetPath)); } ClearTargetPath(targetPath, overwrite); if (mode.HasFlag(TransferMode.HardLink)) { var createdHardlink = _diskProvider.TryCreateHardLink(sourcePath, targetPath); if (createdHardlink) { return(TransferMode.HardLink); } if (!mode.HasFlag(TransferMode.Copy)) { throw new IOException("Hardlinking from '" + sourcePath + "' to '" + targetPath + "' failed."); } } if (verified) { if (mode.HasFlag(TransferMode.Copy)) { if (TryCopyFile(sourcePath, targetPath)) { return(TransferMode.Copy); } } if (mode.HasFlag(TransferMode.Move)) { if (TryMoveFile(sourcePath, targetPath)) { return(TransferMode.Move); } } throw new IOException(string.Format("Failed to completely transfer [{0}] to [{1}], aborting.", sourcePath, targetPath)); } else if (VerificationMode == DiskTransferVerificationMode.VerifyOnly) { var originalSize = _diskProvider.GetFileSize(sourcePath); if (mode.HasFlag(TransferMode.Copy)) { try { _diskProvider.CopyFile(sourcePath, targetPath); var targetSize = _diskProvider.GetFileSize(targetPath); if (targetSize != originalSize) { throw new IOException(string.Format("File copy incomplete. [{0}] was {1} bytes long instead of {2} bytes.", targetPath, targetSize, originalSize)); } return(TransferMode.Copy); } catch { RollbackCopy(sourcePath, targetPath); throw; } } if (mode.HasFlag(TransferMode.Move)) { try { _diskProvider.MoveFile(sourcePath, targetPath); var targetSize = _diskProvider.GetFileSize(targetPath); if (targetSize != originalSize) { throw new IOException(string.Format("File copy incomplete, data loss may have occured. [{0}] was {1} bytes long instead of the expected {2}.", targetPath, targetSize, originalSize)); } return(TransferMode.Move); } catch { RollbackPartialMove(sourcePath, targetPath); throw; } } } else { if (mode.HasFlag(TransferMode.Copy)) { _diskProvider.CopyFile(sourcePath, targetPath); return(TransferMode.Copy); } if (mode.HasFlag(TransferMode.Move)) { _diskProvider.MoveFile(sourcePath, targetPath); return(TransferMode.Move); } } return(TransferMode.None); }
public TransferMode TransferFile(string sourcePath, string targetPath, TransferMode mode, bool overwrite, DiskTransferVerificationMode verificationMode) { Ensure.That(sourcePath, () => sourcePath).IsValidPath(); Ensure.That(targetPath, () => targetPath).IsValidPath(); _logger.Debug("{0} [{1}] > [{2}]", mode, sourcePath, targetPath); var originalSize = _diskProvider.GetFileSize(sourcePath); if (sourcePath == targetPath) { throw new IOException(string.Format("Source and destination can't be the same {0}", sourcePath)); } if (sourcePath.PathEquals(targetPath, StringComparison.InvariantCultureIgnoreCase)) { if (mode.HasFlag(TransferMode.HardLink) || mode.HasFlag(TransferMode.Copy)) { throw new IOException(string.Format("Source and destination can't be the same {0}", sourcePath)); } if (mode.HasFlag(TransferMode.Move)) { var tempPath = sourcePath + ".backup~"; _diskProvider.MoveFile(sourcePath, tempPath, true); try { ClearTargetPath(sourcePath, targetPath, overwrite); _diskProvider.MoveFile(tempPath, targetPath); return(TransferMode.Move); } catch { RollbackMove(sourcePath, tempPath); throw; } } return(TransferMode.None); } if (sourcePath.GetParentPath() == targetPath.GetParentPath()) { if (mode.HasFlag(TransferMode.Move)) { TryMoveFileVerified(sourcePath, targetPath, originalSize); return(TransferMode.Move); } } if (sourcePath.IsParentPath(targetPath)) { throw new IOException(string.Format("Destination cannot be a child of the source [{0}] => [{1}]", sourcePath, targetPath)); } ClearTargetPath(sourcePath, targetPath, overwrite); if (mode.HasFlag(TransferMode.HardLink)) { var createdHardlink = _diskProvider.TryCreateHardLink(sourcePath, targetPath); if (createdHardlink) { return(TransferMode.HardLink); } if (!mode.HasFlag(TransferMode.Copy)) { throw new IOException("Hardlinking from '" + sourcePath + "' to '" + targetPath + "' failed."); } } // Adjust the transfer mode depending on the filesystems if (verificationMode == DiskTransferVerificationMode.TryTransactional) { var sourceMount = _diskProvider.GetMount(sourcePath); var targetMount = _diskProvider.GetMount(targetPath); var isSameMount = (sourceMount != null && targetMount != null && sourceMount.RootDirectory == targetMount.RootDirectory); var sourceDriveFormat = sourceMount?.DriveFormat ?? string.Empty; var targetDriveFormat = targetMount?.DriveFormat ?? string.Empty; if (isSameMount) { // No transaction needed for operations on same mount, force VerifyOnly verificationMode = DiskTransferVerificationMode.VerifyOnly; } else if (sourceDriveFormat.Contains("mergerfs") || sourceDriveFormat.Contains("rclone") || targetDriveFormat.Contains("mergerfs") || targetDriveFormat.Contains("rclone")) { // Cloud storage filesystems don't need any Transactional stuff and it hurts performance, force VerifyOnly verificationMode = DiskTransferVerificationMode.VerifyOnly; } else if ((sourceDriveFormat == "cifs" || targetDriveFormat == "cifs") && OsInfo.IsNotWindows) { // Force Transactional on a cifs mount due to the likeliness of move failures on certain scenario's on mono verificationMode = DiskTransferVerificationMode.Transactional; } } if (mode.HasFlag(TransferMode.Copy)) { if (verificationMode == DiskTransferVerificationMode.Transactional || verificationMode == DiskTransferVerificationMode.TryTransactional) { if (TryCopyFileTransactional(sourcePath, targetPath, originalSize)) { return(TransferMode.Copy); } throw new IOException(string.Format("Failed to completely transfer [{0}] to [{1}], aborting.", sourcePath, targetPath)); } else if (verificationMode == DiskTransferVerificationMode.VerifyOnly) { TryCopyFileVerified(sourcePath, targetPath, originalSize); return(TransferMode.Copy); } else { _diskProvider.CopyFile(sourcePath, targetPath); return(TransferMode.Copy); } } if (mode.HasFlag(TransferMode.Move)) { if (verificationMode == DiskTransferVerificationMode.Transactional || verificationMode == DiskTransferVerificationMode.TryTransactional) { if (TryMoveFileTransactional(sourcePath, targetPath, originalSize, verificationMode)) { return(TransferMode.Move); } throw new IOException(string.Format("Failed to completely transfer [{0}] to [{1}], aborting.", sourcePath, targetPath)); } else if (verificationMode == DiskTransferVerificationMode.VerifyOnly) { TryMoveFileVerified(sourcePath, targetPath, originalSize); return(TransferMode.Move); } else { _diskProvider.MoveFile(sourcePath, targetPath); return(TransferMode.Move); } } return(TransferMode.None); }