Add recursive searching for the symlink downloader.

This commit is contained in:
Roger Far 2024-04-20 09:47:51 -06:00
parent 0bfb4974d8
commit dbb502a164
6 changed files with 49 additions and 31 deletions

View file

@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [2.0.74] - 2024-04-20
### Added
- Added support for symlink recursive searching.
## [2.0.73] - 2024-04-11
### Changed
- Fixed another issue with the symlinker and file resolver.

View file

@ -1,6 +1,6 @@
{
"name": "rdt-client",
"version": "2.0.73",
"version": "2.0.74",
"description": "This is a web interface to manage your torrents on Real-Debrid.",
"main": "index.js",
"dependencies": {

View file

@ -129,7 +129,7 @@ http://127.0.0.1:6800/jsonrpc.")]
public String? Aria2cDownloadPath { get; set; } = null;
[DisplayName("Rclone mount path (only used for the Symlink Downloader)")]
[Description("Path where Rclone is mounted. Required for Symlink Downloader.")]
[Description("Path where Rclone is mounted. Required for Symlink Downloader. Suffix this path with a * to search subdirectories too.")]
public String RcloneMountPath { get; set; } = "/mnt/rd/";
[DisplayName("Log level")]

View file

@ -66,8 +66,6 @@ public class DownloadClient(Download download, Torrent torrent, String destinati
};
var result = await Downloader.Download();
await Task.Delay(1000);
return result;
}

View file

@ -23,6 +23,14 @@ public class SymlinkDownloader(String uri, String destinationPath, String path)
var filePath = new FileInfo(path);
var rcloneMountPath = Settings.Get.DownloadClient.RcloneMountPath.TrimEnd(['\\', '/']);
var searchSubDirectories = rcloneMountPath.EndsWith("*");
rcloneMountPath = rcloneMountPath.TrimEnd('*').TrimEnd(['\\', '/']);
if (!Directory.Exists(rcloneMountPath))
{
throw new($"Mount path {rcloneMountPath} does not exist!");
}
var fileName = filePath.Name;
var fileExtension = filePath.Extension;
var fileNameWithoutExtension = fileName.Replace(fileExtension, "");
@ -31,9 +39,9 @@ public class SymlinkDownloader(String uri, String destinationPath, String path)
List<String> unWantedExtensions =
[
"zip",
"rar",
"tar"
".zip",
".rar",
".tar"
];
if (unWantedExtensions.Any(m => fileExtension == m))
@ -54,7 +62,7 @@ public class SymlinkDownloader(String uri, String destinationPath, String path)
var directoryInfo = new DirectoryInfo(searchPath);
while (directoryInfo.Parent != null)
{
potentialFilePaths.Add(directoryInfo.FullName);
potentialFilePaths.Add(directoryInfo.Name);
directoryInfo = directoryInfo.Parent;
if (directoryInfo.FullName.TrimEnd(['\\', '/']) == rcloneMountPath)
@ -63,10 +71,12 @@ public class SymlinkDownloader(String uri, String destinationPath, String path)
}
}
potentialFilePaths.Add(Path.Combine(rcloneMountPath, fileName));
potentialFilePaths.Add(Path.Combine(rcloneMountPath, fileNameWithoutExtension));
potentialFilePaths.Add(fileName);
potentialFilePaths.Add(fileNameWithoutExtension);
FileInfo? file = null;
potentialFilePaths = potentialFilePaths.Distinct().ToList();
String? file = null;
for (var retryCount = 0; retryCount < MaxRetries; retryCount++)
{
@ -80,16 +90,15 @@ public class SymlinkDownloader(String uri, String destinationPath, String path)
_logger.Debug($"Searching {rcloneMountPath} for {fileName} (attempt #{retryCount})...");
foreach (var potentialFilePath in potentialFilePaths)
file = FindFile(rcloneMountPath, potentialFilePaths, fileName);
if (file == null && searchSubDirectories)
{
var potentialFilePathWithFileName = Path.Combine(potentialFilePath, fileName);
var subDirectories = Directory.GetDirectories(rcloneMountPath, "*.*", SearchOption.TopDirectoryOnly);
_logger.Debug($"Searching {potentialFilePathWithFileName}...");
if (File.Exists(potentialFilePathWithFileName))
foreach (var subDirectory in subDirectories)
{
file = new(potentialFilePathWithFileName);
break;
FindFile(Path.Combine(rcloneMountPath, subDirectory), potentialFilePaths, fileName);
}
}
@ -120,9 +129,9 @@ public class SymlinkDownloader(String uri, String destinationPath, String path)
throw new("Could not find file from rclone mount!");
}
_logger.Debug($"Found {file.FullName} at {file.FullName}");
_logger.Debug($"Creating symbolic link from {file} to {destinationPath}");
var result = TryCreateSymbolicLink(file.FullName, destinationPath);
var result = TryCreateSymbolicLink(file, destinationPath);
if (!result)
{
@ -131,7 +140,7 @@ public class SymlinkDownloader(String uri, String destinationPath, String path)
DownloadComplete?.Invoke(this, new());
return file.FullName;
return file;
}
catch (Exception ex)
{
@ -161,6 +170,23 @@ public class SymlinkDownloader(String uri, String destinationPath, String path)
return Task.CompletedTask;
}
private String? FindFile(String rootPath, List<String> filePaths, String fileName)
{
foreach (var potentialFilePath in filePaths)
{
var potentialFilePathWithFileName = Path.Combine(rootPath, potentialFilePath, fileName);
_logger.Debug($"Searching {potentialFilePathWithFileName}...");
if (File.Exists(potentialFilePathWithFileName))
{
return potentialFilePathWithFileName;
}
}
return null;
}
private Boolean TryCreateSymbolicLink(String sourcePath, String symlinkPath)
{
try

View file

@ -93,16 +93,6 @@ public class TorrentRunner(ILogger<TorrentRunner> logger, Torrents torrents, Dow
return;
}
if (Settings.Get.DownloadClient.Client == Data.Enums.DownloadClient.Symlink)
{
var rcloneMountPath = Settings.Get.DownloadClient.RcloneMountPath;
if (!Directory.Exists(rcloneMountPath))
{
throw new($"Rclone mount path ({rcloneMountPath}) was not found!");
}
}
var sw = new Stopwatch();
sw.Start();