예제 #1
0
        public void DeleteFolder(string path)
        {
            _logger.Info("Attempting to send '{0}' to recycling bin", path);
            var recyclingBin = _configService.RecycleBin;

            if (string.IsNullOrWhiteSpace(recyclingBin))
            {
                _logger.Info("Recycling Bin has not been configured, deleting permanently. {0}", path);
                _diskProvider.DeleteFolder(path, true);
                _logger.Debug("Folder has been permanently deleted: {0}", path);
            }

            else
            {
                var destination = Path.Combine(recyclingBin, new DirectoryInfo(path).Name);

                _logger.Debug("Moving '{0}' to '{1}'", path, destination);
                _diskTransferService.TransferFolder(path, destination, TransferMode.Move);

                _logger.Debug("Setting last accessed: {0}", path);
                _diskProvider.FolderSetLastWriteTime(destination, DateTime.UtcNow);
                foreach (var file in _diskProvider.GetFiles(destination, SearchOption.AllDirectories))
                {
                    if (OsInfo.IsWindows)
                    {
                        //TODO: Better fix than this for non-Windows?
                        _diskProvider.FileSetLastWriteTime(file, DateTime.UtcNow);
                    }
                }

                _logger.Debug("Folder has been moved to the recycling bin: {0}", destination);
            }
        }
예제 #2
0
        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, series.Path);

                _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);
            }
        }
예제 #3
0
        private void MoveSingleArtist(Artist artist, 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, artist.Name);
                return;
            }

            if (index != null && total != null)
            {
                _logger.ProgressInfo("Moving {0} from '{1}' to '{2}' ({3}/{4})", artist.Name, sourcePath, destinationPath, index + 1, total);
            }
            else
            {
                _logger.ProgressInfo("Moving {0} from '{1}' to '{2}'", artist.Name, sourcePath, destinationPath);
            }

            try
            {
                _diskTransferService.TransferFolder(sourcePath, destinationPath, TransferMode.Move);

                _logger.ProgressInfo("{0} moved successfully to {1}", artist.Name, artist.Path);

                _eventAggregator.PublishEvent(new ArtistMovedEvent(artist, sourcePath, destinationPath));
            }
            catch (IOException ex)
            {
                _logger.Error(ex, "Unable to move artist from '{0}' to '{1}'. Try moving files manually", sourcePath, destinationPath);

                RevertPath(artist.Id, sourcePath);
            }
        }
        public void Execute(MoveSeriesCommand message)
        {
            var series      = _seriesService.GetSeries(message.SeriesId);
            var source      = message.SourcePath;
            var destination = message.DestinationPath;

            if (!message.DestinationRootFolder.IsNullOrWhiteSpace())
            {
                _logger.Debug("Buiding destination path using root folder: {0} and the series title", message.DestinationRootFolder);
                destination = Path.Combine(message.DestinationRootFolder, _filenameBuilder.GetSeriesFolder(series));
            }

            _logger.ProgressInfo("Moving {0} from '{1}' to '{2}'", series.Title, source, destination);

            //TODO: Move to transactional disk operations
            try
            {
                _diskTransferService.TransferFolder(source, destination, TransferMode.Move);
            }
            catch (IOException ex)
            {
                var errorMessage = string.Format("Unable to move series from '{0}' to '{1}'", source, destination);

                _logger.Error(ex, errorMessage);
                throw;
            }

            _logger.ProgressInfo("{0} moved successfully to {1}", series.Title, series.Path);

            //Update the series path to the new path
            series.Path = destination;
            series      = _seriesService.UpdateSeries(series);

            _eventAggregator.PublishEvent(new SeriesMovedEvent(series, source, destination));
        }
예제 #5
0
        private void InstallUpdate(UpdatePackage updatePackage)
        {
            EnsureAppDataSafety();

            if (OsInfo.IsWindows || _configFileProvider.UpdateMechanism != UpdateMechanism.Script)
            {
                if (!_diskProvider.FolderWritable(_appFolderInfo.StartUpFolder))
                {
                    throw new UpdateFolderNotWritableException("Cannot install update because startup folder '{0}' is not writable by the user '{1}'.", _appFolderInfo.StartUpFolder, Environment.UserName);
                }
            }

            var updateSandboxFolder = _appFolderInfo.GetUpdateSandboxFolder();

            var packageDestination = Path.Combine(updateSandboxFolder, updatePackage.FileName);

            if (_diskProvider.FolderExists(updateSandboxFolder))
            {
                _logger.Info("Deleting old update files");
                _diskProvider.DeleteFolder(updateSandboxFolder, true);
            }

            _logger.ProgressInfo("Downloading update {0}", updatePackage.Version);
            _logger.Debug("Downloading update package from [{0}] to [{1}]", updatePackage.Url, packageDestination);
            _httpClient.DownloadFile(updatePackage.Url, packageDestination);

            _logger.ProgressInfo("Verifying update package");

            if (!_updateVerifier.Verify(updatePackage, packageDestination))
            {
                _logger.Error("Update package is invalid");
                throw new UpdateVerificationFailedException("Update file '{0}' is invalid", packageDestination);
            }

            _logger.Info("Update package verified successfully");

            _logger.ProgressInfo("Extracting Update package");
            _archiveService.Extract(packageDestination, updateSandboxFolder);
            _logger.Info("Update package extracted successfully");

            EnsureValidBranch(updatePackage);

            _backupService.Backup(BackupType.Update);

            if (OsInfo.IsNotWindows && _configFileProvider.UpdateMechanism == UpdateMechanism.Script)
            {
                InstallUpdateWithScript(updateSandboxFolder);
                return;
            }

            _logger.Info("Preparing client");
            _diskTransferService.TransferFolder(_appFolderInfo.GetUpdateClientFolder(), updateSandboxFolder, TransferMode.Move, false);

            _logger.Info("Starting update client {0}", _appFolderInfo.GetUpdateClientExePath());
            _logger.ProgressInfo("Sonarr will restart shortly.");

            _processProvider.Start(_appFolderInfo.GetUpdateClientExePath(), GetUpdaterArgs(updateSandboxFolder));
        }
예제 #6
0
        public void Start(string installationFolder, int processId)
        {
            Verify(installationFolder, processId);

            var appType = _detectApplicationType.GetAppType();

            try
            {
                _processProvider.FindProcessByName(ProcessProvider.NZB_DRONE_CONSOLE_PROCESS_NAME);
                _processProvider.FindProcessByName(ProcessProvider.NZB_DRONE_PROCESS_NAME);

                if (OsInfo.IsWindows)
                {
                    _terminateNzbDrone.Terminate(processId);
                }

                _backupAndRestore.Backup(installationFolder);
                _backupAppData.Backup();

                try
                {
                    _logger.Info("Emptying installation folder");
                    _diskProvider.EmptyFolder(installationFolder);

                    _logger.Info("Copying new files to target folder");
                    _diskTransferService.TransferFolder(_appFolderInfo.GetUpdatePackageFolder(), installationFolder, TransferMode.Copy, false);

                    // Set executable flag on Sonarr app
                    if (OsInfo.IsOsx)
                    {
                        _diskProvider.SetPermissions(Path.Combine(installationFolder, "Sonarr"), "0755", null, null);
                    }
                }
                catch (Exception e)
                {
                    _logger.FatalException("Failed to copy upgrade package to target folder.", e);
                    _backupAndRestore.Restore(installationFolder);
                }
            }
            finally
            {
                if (OsInfo.IsWindows)
                {
                    _startNzbDrone.Start(appType, installationFolder);
                }
                else
                {
                    _terminateNzbDrone.Terminate(processId);

                    _logger.Info("Waiting for external auto-restart.");
                    for (int i = 0; i < 5; i++)
                    {
                        System.Threading.Thread.Sleep(1000);

                        if (_processProvider.Exists(ProcessProvider.NZB_DRONE_PROCESS_NAME))
                        {
                            _logger.Info("Sonarr was restarted by external process.");
                            break;
                        }
                    }

                    if (!_processProvider.Exists(ProcessProvider.NZB_DRONE_PROCESS_NAME))
                    {
                        _startNzbDrone.Start(appType, installationFolder);
                    }
                }
            }
        }
예제 #7
0
 public void Backup(string source)
 {
     _logger.Info("Creating backup of existing installation");
     _diskTransferService.TransferFolder(source, _appFolderInfo.GetUpdateBackUpFolder(), TransferMode.Copy, false);
 }
예제 #8
0
        private bool InstallUpdate(UpdatePackage updatePackage)
        {
            EnsureAppDataSafety();

            if (OsInfo.IsWindows || _configFileProvider.UpdateMechanism != UpdateMechanism.Script)
            {
                var startupFolder = _appFolderInfo.StartUpFolder;
                var uiFolder      = Path.Combine(startupFolder, "UI");

                if (!_diskProvider.FolderWritable(startupFolder))
                {
                    throw new UpdateFolderNotWritableException("Cannot install update because startup folder '{0}' is not writable by the user '{1}'.", startupFolder, Environment.UserName);
                }

                if (!_diskProvider.FolderWritable(uiFolder))
                {
                    throw new UpdateFolderNotWritableException("Cannot install update because UI folder '{0}' is not writable by the user '{1}'.", uiFolder, Environment.UserName);
                }
            }

            if (_appFolderInfo.StartUpFolder.EndsWith("_output"))
            {
                _logger.ProgressDebug("Running in developer environment, not updating.");
                return(false);
            }

            var updateSandboxFolder = _appFolderInfo.GetUpdateSandboxFolder();

            var packageDestination = Path.Combine(updateSandboxFolder, updatePackage.FileName);

            if (_diskProvider.FolderExists(updateSandboxFolder))
            {
                _logger.Info("Deleting old update files");
                _diskProvider.DeleteFolder(updateSandboxFolder, true);
            }

            _logger.ProgressInfo("Downloading update {0}", updatePackage.Version);
            _logger.Debug("Downloading update package from [{0}] to [{1}]", updatePackage.Url, packageDestination);
            _httpClient.DownloadFile(updatePackage.Url, packageDestination);

            _logger.ProgressInfo("Verifying update package");

            if (!_updateVerifier.Verify(updatePackage, packageDestination))
            {
                _logger.Error("Update package is invalid");
                throw new UpdateVerificationFailedException("Update file '{0}' is invalid", packageDestination);
            }

            _logger.Info("Update package verified successfully");

            _logger.ProgressInfo("Extracting Update package");
            _archiveService.Extract(packageDestination, updateSandboxFolder);
            _logger.Info("Update package extracted successfully");

            EnsureValidBranch(updatePackage);

            _backupService.Backup(BackupType.Update);

            if (OsInfo.IsNotWindows && _configFileProvider.UpdateMechanism == UpdateMechanism.Script)
            {
                InstallUpdateWithScript(updateSandboxFolder);
                return(true);
            }

            _logger.Info("Preparing client");
            _diskTransferService.TransferFolder(_appFolderInfo.GetUpdateClientFolder(), updateSandboxFolder, TransferMode.Move);

            // Set executable flag on update app
            if (OsInfo.IsOsx || (OsInfo.IsLinux && PlatformInfo.IsNetCore))
            {
                _diskProvider.SetFilePermissions(_appFolderInfo.GetUpdateClientExePath(updatePackage.Runtime), "755", null);
            }

            _logger.Info("Starting update client {0}", _appFolderInfo.GetUpdateClientExePath(updatePackage.Runtime));
            _logger.ProgressInfo("Radarr will restart shortly.");

            _processProvider.Start(_appFolderInfo.GetUpdateClientExePath(updatePackage.Runtime), GetUpdaterArgs(updateSandboxFolder));

            return(true);
        }
예제 #9
0
        private void MigrateAppDataFolder()
        {
            try
            {
                var oldDbFile = Path.Combine(_appFolderInfo.AppDataFolder, "nzbdrone.db");

                if (_startupContext.Args.ContainsKey(StartupContext.APPDATA))
                {
                    if (_diskProvider.FileExists(_appFolderInfo.GetDatabase()))
                    {
                        return;
                    }
                    if (!_diskProvider.FileExists(oldDbFile))
                    {
                        return;
                    }

                    _diskProvider.MoveFile(oldDbFile, _appFolderInfo.GetDatabase());
                    CleanupSqLiteRollbackFiles();
                    RemovePidFile();
                }

                if (_appFolderInfo.LegacyAppDataFolder.IsNullOrWhiteSpace())
                {
                    return;
                }
                if (_diskProvider.FileExists(_appFolderInfo.GetDatabase()) || _diskProvider.FileExists(_appFolderInfo.GetConfigPath()))
                {
                    return;
                }
                if (!_diskProvider.FolderExists(_appFolderInfo.LegacyAppDataFolder))
                {
                    return;
                }

                // Delete the bin folder on Windows
                var binFolder = Path.Combine(_appFolderInfo.LegacyAppDataFolder, "bin");

                if (OsInfo.IsWindows && _diskProvider.FolderExists(binFolder))
                {
                    _diskProvider.DeleteFolder(binFolder, true);
                }

                // Transfer other files and folders (with copy so a backup is maintained)
                _diskTransferService.TransferFolder(_appFolderInfo.LegacyAppDataFolder, _appFolderInfo.AppDataFolder, TransferMode.Copy);

                // Rename the DB file
                if (_diskProvider.FileExists(oldDbFile))
                {
                    _diskProvider.MoveFile(oldDbFile, _appFolderInfo.GetDatabase());
                }

                // Remove SQLite rollback files
                CleanupSqLiteRollbackFiles();

                // Remove Old PID file
                RemovePidFile();

                // Delete the old files after everything has been copied
                _diskProvider.DeleteFolder(_appFolderInfo.LegacyAppDataFolder, true);
            }
            catch (Exception ex)
            {
                _logger.Debug(ex, ex.Message);
                throw new SonarrStartupException("Unable to migrate AppData folder from {0} to {1}. Migrate manually", _appFolderInfo.LegacyAppDataFolder, _appFolderInfo.AppDataFolder);
            }
        }