From fcbd9d8096450acb84fa5674fe6d25356f7154ea Mon Sep 17 00:00:00 2001 From: YvesPa <166829028+YvesPa@users.noreply.github.com> Date: Wed, 25 Sep 2024 14:50:46 +0200 Subject: [PATCH] Correct Path using qbittorrent --- .../Models/Internal/DbSettings.cs | 2 +- .../RdtClient.Service.csproj | 2 +- .../Downloaders/DownloadStationDownloader.cs | 118 ++++++++++++------ 3 files changed, 80 insertions(+), 42 deletions(-) diff --git a/server/RdtClient.Data/Models/Internal/DbSettings.cs b/server/RdtClient.Data/Models/Internal/DbSettings.cs index 0461d9a..21a0f34 100644 --- a/server/RdtClient.Data/Models/Internal/DbSettings.cs +++ b/server/RdtClient.Data/Models/Internal/DbSettings.cs @@ -144,7 +144,7 @@ http://127.0.0.1:6800/jsonrpc.")] public String? DownloadStationPassword { get; set; } = null; [DisplayName("Synology Download Station Download Path")] - [Description("The root path to doawnload the file on the Synology DownloadStation host, if empty use the default DownloadStation path but won't create catagory folders.")] + [Description("The root path to doawnload the file on the Synology DownloadStation host, if empty use the default DownloadStation path.")] public String? DownloadStationDownloadPath { get; set; } = null; [DisplayName("Log level")] diff --git a/server/RdtClient.Service/RdtClient.Service.csproj b/server/RdtClient.Service/RdtClient.Service.csproj index dd334a4..d1b47e2 100644 --- a/server/RdtClient.Service/RdtClient.Service.csproj +++ b/server/RdtClient.Service/RdtClient.Service.csproj @@ -22,7 +22,7 @@ - + diff --git a/server/RdtClient.Service/Services/Downloaders/DownloadStationDownloader.cs b/server/RdtClient.Service/Services/Downloaders/DownloadStationDownloader.cs index 0bf53c9..3a11918 100644 --- a/server/RdtClient.Service/Services/Downloaders/DownloadStationDownloader.cs +++ b/server/RdtClient.Service/Services/Downloaders/DownloadStationDownloader.cs @@ -1,7 +1,7 @@ - -using Serilog; +using Serilog; using Synology.Api.Client; using Synology.Api.Client.Apis.DownloadStation.Task.Models; +using Synology.Api.Client.Apis.FileStation.List.Models; namespace RdtClient.Service.Services.Downloaders; @@ -15,36 +15,55 @@ public class DownloadStationDownloader : IDownloader private readonly SynologyClient _synologyClient; private readonly ILogger _logger; - private readonly String _uri; private readonly String _filePath; + private readonly String _uri; private readonly String? _remotePath; private String? _gid; - private DownloadStationDownloader(String? gid, String uri, String filePath, String downloadPath, String? category) + private DownloadStationDownloader(String? gid, String uri, String? remotePath, String filePath, String downloadPath, String? category, SynologyClient synologyClient) { _logger = Log.ForContext(); _logger.Debug($"Instantiated new DownloadStation Downloader for URI {uri} to filePath {filePath} and downloadPath {downloadPath} and GID {gid}"); _gid = gid; - _uri = uri; _filePath = filePath; - - _remotePath = !String.IsNullOrWhiteSpace(Settings.Get.DownloadClient.DownloadStationDownloadPath) - ? String.IsNullOrWhiteSpace(category) - ? Path.Combine(ToCurrentPath(Settings.Get.DownloadClient.DownloadStationDownloadPath)) - : Path.Combine(ToCurrentPath(Settings.Get.DownloadClient.DownloadStationDownloadPath), category) - : null; - - _synologyClient = new SynologyClient(Settings.Get.DownloadClient.DownloadStationUrl); + _uri = uri; + _remotePath = remotePath; + _synologyClient = synologyClient; } public static async Task Init(String? gid, String uri, String filePath, String downloadPath, String? category) { - var result = new DownloadStationDownloader(gid, uri, filePath, downloadPath, category); + var synologyClient = new SynologyClient(Settings.Get.DownloadClient.DownloadStationUrl); if (Settings.Get.DownloadClient.DownloadStationUsername != null && Settings.Get.DownloadClient.DownloadStationPassword != null) - await result._synologyClient.LoginAsync(Settings.Get.DownloadClient.DownloadStationUsername, Settings.Get.DownloadClient.DownloadStationPassword); + await synologyClient.LoginAsync(Settings.Get.DownloadClient.DownloadStationUsername, Settings.Get.DownloadClient.DownloadStationPassword); - return result; + String? remotePath = null; + String? rootPath; + if (!String.IsNullOrWhiteSpace(Settings.Get.DownloadClient.DownloadStationDownloadPath)) + { + rootPath = Settings.Get.DownloadClient.DownloadStationDownloadPath; + } + else + { + var config = await synologyClient.DownloadStationApi().InfoEndpoint().GetConfigAsync(); + rootPath = config.DefaultDestination; + } + + if (rootPath != null) + { + + if (String.IsNullOrWhiteSpace(category)) + { + remotePath = Path.Combine(rootPath, downloadPath).Replace('\\', '/'); + } + else + { + remotePath = Path.Combine(downloadPath, category, downloadPath).Replace('\\', '/'); + } + } + + return new DownloadStationDownloader(gid, uri, remotePath, filePath, downloadPath, category, synologyClient); } public async Task Cancel() @@ -63,7 +82,8 @@ public class DownloadStationDownloader : IDownloader public async Task Download() { - var path = _remotePath != null ? ToUnixPath(_remotePath) : null; + var path = Path.GetDirectoryName(_remotePath)?.Replace('\\', '/') ?? throw new($"Invalid file path {_filePath}"); + if (!path.StartsWith('/')) path = '/' + path; _logger.Debug($"Starting download of {_uri}, writing to path: {path}"); if (_gid != null) @@ -84,33 +104,43 @@ public class DownloadStationDownloader : IDownloader _logger.Debug($"Download with ID {_gid} found in DownloadStation"); return _gid; } - - var createResult = await _synologyClient - .DownloadStationApi() - .TaskEndpoint() - .CreateAsync(new DownloadStationTaskCreateRequest(_uri, path)); - - _logger.Debug($"Added download to DownloadStation, received ID {_gid}"); - - if (createResult.Success) + try { - _gid = await GetGidFromUri(); - if (_gid != null) + await CheckFolderOrCreate(path); + + var createResult = await _synologyClient + .DownloadStationApi() + .TaskEndpoint() + .CreateAsync(new DownloadStationTaskCreateRequest(_uri, path.Substring(1))); + + _logger.Debug($"Added download to DownloadStation, received ID {_gid}"); + + if (createResult.Success) { - _logger.Debug($"Download with ID {_gid} found in DownloadStation"); - return _gid; + _gid = await GetGidFromUri(); + if (_gid != null) + { + _logger.Debug($"Download with ID {_gid} found in DownloadStation"); + return _gid; + } + else + { + retryCount++; + _logger.Debug($"Task not found in DownloadStation after creat Sucess. Retrying {retryCount}/{RetryCount}"); + await Task.Delay(retryCount * 1000); + } } else { retryCount++; - _logger.Debug($"Task not found in DownloadStation after creat Sucess. Retrying {retryCount}/{RetryCount}"); + _logger.Debug($"Error starting download: {createResult.Error.Code}. Retrying {retryCount}/{RetryCount}"); await Task.Delay(retryCount * 1000); } } - else + catch (Exception e) { retryCount++; - _logger.Debug($"Error starting download: {createResult.Error.Code}. Retrying {retryCount}/{RetryCount}"); + _logger.Debug($"Error starting download: {e.Message}. Retrying {retryCount}/{RetryCount}"); await Task.Delay(retryCount * 1000); } } @@ -165,14 +195,22 @@ public class DownloadStationDownloader : IDownloader }); } - private static string ToUnixPath(string path) + private async Task CheckFolderOrCreate(string path) { - return path.Replace(Path.DirectorySeparatorChar, '/'); - } - - private static string ToCurrentPath(string path) - { - return path.Replace('/', Path.DirectorySeparatorChar); + if (path != null) + { + try + { + await _synologyClient.FileStationApi().ListEndpoint() + .ListAsync(new FileStationListRequest(path)); + } + catch // if not exists create it + { + await _synologyClient.FileStationApi().CreateFolderEndpoint() + .CreateAsync(new[] { path }, true); + //if error handle by the caller + } + } } private async Task GetTask()