diff --git a/server/RdtClient.Service/Services/DownloadClient.cs b/server/RdtClient.Service/Services/DownloadClient.cs index ddfd144..54d8f16 100644 --- a/server/RdtClient.Service/Services/DownloadClient.cs +++ b/server/RdtClient.Service/Services/DownloadClient.cs @@ -28,6 +28,8 @@ public class DownloadClient _download = download; _torrent = torrent; _destinationPath = destinationPath; + + Type = Settings.Get.DownloadClient.Client; } public async Task Start() @@ -52,8 +54,6 @@ public class DownloadClient await FileHelper.Delete(filePath); - Type = Settings.Get.DownloadClient.Client; - Downloader = Settings.Get.DownloadClient.Client switch { Data.Enums.DownloadClient.Internal => new InternalDownloader(_download.Link, filePath), diff --git a/server/RdtClient.Service/Services/Downloaders/SymlinkDownloader.cs b/server/RdtClient.Service/Services/Downloaders/SymlinkDownloader.cs index 5bf3830..5f08525 100644 --- a/server/RdtClient.Service/Services/Downloaders/SymlinkDownloader.cs +++ b/server/RdtClient.Service/Services/Downloaders/SymlinkDownloader.cs @@ -9,6 +9,7 @@ public class SymlinkDownloader : IDownloader public event EventHandler? DownloadProgress; private const Int32 RetryCount = 5; + private const Int32 RetryDelaySeconds = 30; private readonly String _filePath; private readonly String _uri; @@ -45,13 +46,13 @@ public class SymlinkDownloader : IDownloader _logger.Debug($"Searching {Settings.Get.DownloadClient.RcloneMountPath} for {fileName} ({retryCount}/{RetryCount}) "); // Recursively search for the fileName in the rclone mount location. - var foundFiles = Directory.GetFiles(Settings.Get.DownloadClient.RcloneMountPath, fileName, SearchOption.AllDirectories).ToList(); + var foundFiles = Directory.GetFiles(Settings.Get.DownloadClient.RcloneMountPath, fileName, SearchOption.AllDirectories); if (foundFiles.Any()) { - if (foundFiles.Count > 1) + if (foundFiles.Length > 1) { - _logger.Warning($"Found {foundFiles.Count} files named {fileName}"); + _logger.Warning($"Found {foundFiles.Length} files named {fileName}"); } // Assume first matching filename is the one we want. @@ -105,33 +106,21 @@ public class SymlinkDownloader : IDownloader { try { - var process = new Process(); - process.StartInfo.FileName = "ln"; - process.StartInfo.Arguments = @$"-s ""{sourcePath}"" ""{symlinkPath}"""; - process.StartInfo.UseShellExecute = false; - process.StartInfo.RedirectStandardError = true; - - process.Start(); - - var errors = process.StandardError.ReadToEnd(); - - process.WaitForExit(); - - if (process.ExitCode == 0) + File.CreateSymbolicLink(symlinkPath, sourcePath); + if (File.Exists(symlinkPath)) // Double-check that the link was created { _logger.Information($"Created symbolic link from {sourcePath} to {symlinkPath}"); - return true; } - - _logger.Error($"Failed to create symbolic link: {process.ExitCode} - {errors}"); - - return false; + else + { + _logger.Error($"Failed to create symbolic link from {sourcePath} to {symlinkPath}"); + return false; + } } catch (Exception ex) { _logger.Error($"Error creating symbolic link from {sourcePath} to {symlinkPath}: {ex.Message}"); - return false; } } diff --git a/server/RdtClient.Service/Services/TorrentRunner.cs b/server/RdtClient.Service/Services/TorrentRunner.cs index ae4f2c4..8b0d0cf 100644 --- a/server/RdtClient.Service/Services/TorrentRunner.cs +++ b/server/RdtClient.Service/Services/TorrentRunner.cs @@ -312,75 +312,7 @@ public class TorrentRunner foreach (var download in queuedDownloads) { - Log($"Processing to download", download, torrent); - - if (ActiveDownloadClients.Count >= settingDownloadLimit) - { - Log($"Not starting download because there are already the max number of downloads active", download, torrent); - - continue; - } - - if (ActiveDownloadClients.ContainsKey(download.DownloadId)) - { - Log($"Not starting download because this download is already active", download, torrent); - - continue; - } - - try - { - Log($"Unrestricting links", download, torrent); - - var downloadLink = await _torrents.UnrestrictLink(download.DownloadId); - download.Link = downloadLink; - } - catch (Exception ex) - { - _logger.LogError(ex, "Cannot unrestrict link: {ex.Message}", ex.Message); - - await _downloads.UpdateError(download.DownloadId, ex.Message); - await _downloads.UpdateCompleted(download.DownloadId, DateTimeOffset.UtcNow); - download.Error = ex.Message; - download.Completed = DateTimeOffset.UtcNow; - - continue; - } - - Log($"Marking download as started", download, torrent); - - download.DownloadStarted = DateTime.UtcNow; - await _downloads.UpdateDownloadStarted(download.DownloadId, download.DownloadStarted); - - var downloadPath = settingDownloadPath; - - if (!String.IsNullOrWhiteSpace(torrent.Category)) - { - downloadPath = Path.Combine(downloadPath, torrent.Category); - } - - Log($"Setting download path to {downloadPath}", download, torrent); - - // Start the download process - var downloadClient = new DownloadClient(download, torrent, downloadPath); - - if (ActiveDownloadClients.TryAdd(download.DownloadId, downloadClient)) - { - Log($"Starting download", download, torrent); - - var remoteId = await downloadClient.Start(); - - if (!String.IsNullOrWhiteSpace(remoteId) && download.RemoteId != remoteId) - { - Log($"Received ID {remoteId}", download, torrent); - - await _downloads.UpdateRemoteId(download.DownloadId, remoteId); - } - else - { - Log($"No ID received", download, torrent); - } - } + await ProcessDownload(download, torrent, settingDownloadPath, settingDownloadLimit); } // Check if there are any unpacks that are queued and can be started. @@ -628,4 +560,88 @@ public class TorrentRunner _logger.LogError(message); } + + private async Task ProcessDownload(Download download, Torrent torrent, string settingDownloadPath, int settingDownloadLimit) + { + Log($"Processing to download", download, torrent); + + if (ActiveDownloadClients.Count >= settingDownloadLimit) + { + Log($"Not starting download because there are already the max number of downloads active", download, torrent); + + return; + } + + if (ActiveDownloadClients.ContainsKey(download.DownloadId)) + { + Log($"Not starting download because this download is already active", download, torrent); + + return; + } + + try + { + Log($"Unrestricting links", download, torrent); + + var downloadLink = await _torrents.UnrestrictLink(download.DownloadId); + download.Link = downloadLink; + } + catch (Exception ex) + { + _logger.LogError(ex, "Cannot unrestrict link: {ex.Message}", ex.Message); + + await _downloads.UpdateError(download.DownloadId, ex.Message); + await _downloads.UpdateCompleted(download.DownloadId, DateTimeOffset.UtcNow); + download.Error = ex.Message; + download.Completed = DateTimeOffset.UtcNow; + + return; + } + + Log($"Marking download as started", download, torrent); + + download.DownloadStarted = DateTime.UtcNow; + await _downloads.UpdateDownloadStarted(download.DownloadId, download.DownloadStarted); + + var downloadPath = settingDownloadPath; + + if (!String.IsNullOrWhiteSpace(torrent.Category)) + { + downloadPath = Path.Combine(downloadPath, torrent.Category); + } + + Log($"Setting download path to {downloadPath}", download, torrent); + + var downloadClient = new DownloadClient(download, torrent, downloadPath); + + if (downloadClient.Type == Data.Enums.DownloadClient.Symlink) // Check if the type is "Symlink" + { + // If it's Symlink type, start the download concurrently + _ = Task.Run(async () => await StartDownload(download, torrent, downloadClient)); + } + else + { + await StartDownload(download, torrent, downloadClient); + } + } + + private async Task StartDownload(Download download, Torrent torrent, DownloadClient downloadClient) + { + if (ActiveDownloadClients.TryAdd(download.DownloadId, downloadClient)) + { + Log($"Starting download", download, torrent); + + var remoteId = await downloadClient.Start(); + + if (!String.IsNullOrWhiteSpace(remoteId) && download.RemoteId != remoteId) + { + Log($"Received ID {remoteId}", download, torrent); + await _downloads.UpdateRemoteId(download.DownloadId, remoteId); + } + else + { + Log($"No ID received", download, torrent); + } + } + } } \ No newline at end of file