diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 308884d..98653b2 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -9,7 +9,7 @@ assignees: '' **What version are you using?** -**Wat OS are you running?** +**What OS are you running?** **Are you using Docker or as a service?** diff --git a/CHANGELOG.md b/CHANGELOG.md index 7950585..2babfed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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). +## [Unreleased] +### Changed +- Download .zip of torrent files from TorBox when possible, thanks @asylumexp! + ## [2.0.102] - 2025-03-07 ### Changed - Fixed Angular build for Docker. diff --git a/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs index 463fb28..22a6994 100644 --- a/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs @@ -4,6 +4,7 @@ using Newtonsoft.Json; using TorBoxNET; using RdtClient.Data.Enums; using RdtClient.Data.Models.TorrentClient; +using System.Web; using RdtClient.Data.Models.Data; using RdtClient.Service.Helpers; @@ -287,10 +288,32 @@ public class TorBoxTorrentClient(ILogger logger, IHttpClien public async Task?> GetDownloadInfos(Torrent torrent) { var torrentId = await GetClient().Torrents.GetHashInfoAsync(torrent.Hash, skipCache: true); + var downloadableFiles = torrent.Files.Where(file => fileFilter.IsDownloadable(torrent, file.Path, file.Bytes)).ToList(); - return torrent.Files.Where(file => fileFilter.IsDownloadable(torrent, file.Path, file.Bytes)) - .Select(file => new DownloadInfo { RestrictedLink = $"https://torbox.app/fakedl/{torrentId?.Id}/{file.Id}", FileName = Path.GetFileName(file.Path)}) - .ToList(); + if (downloadableFiles.Count == torrent.Files.Count && torrent.DownloadClient != Data.Enums.DownloadClient.Symlink) + { + logger.LogDebug("Downloading files from TorBox as a zip."); + + return + [ + new DownloadInfo + { + RestrictedLink = $"https://torbox.app/fakedl/{torrentId?.Id}/zip", + FileName = $"{torrent.RdName}.zip" + } + ]; + } + else + { + logger.LogDebug("Downloading files from TorBox individually."); + + return downloadableFiles.Select(file => new DownloadInfo + { + RestrictedLink = $"https://torbox.app/fakedl/{torrentId?.Id}/{file.Id}", + FileName = Path.GetFileName(file.Path) + }) + .ToList(); + } } /// @@ -318,7 +341,44 @@ public class TorBoxTorrentClient(ILogger logger, IHttpClien return Map(result!); } - + + public static void MoveHashDirContents(String extractPath, Torrent _torrent) + { + var hashDir = Path.Combine(extractPath, _torrent.Hash); + + if (Directory.Exists(hashDir)) + { + var innerFolder = Directory.GetDirectories(hashDir)[0]; + + var moveDir = extractPath; + if (!extractPath.EndsWith(_torrent.RdName!)) + { + moveDir = hashDir; + } + + foreach (var file in Directory.GetFiles(innerFolder)) + { + var destFile = Path.Combine(moveDir, Path.GetFileName(file)); + File.Move(file, destFile); + } + + foreach (var dir in Directory.GetDirectories(innerFolder)) + { + var destDir = Path.Combine(moveDir, Path.GetFileName(dir)); + Directory.Move(dir, destDir); + } + + if (!extractPath.Contains(_torrent.RdName!)) + { + Directory.Delete(innerFolder, true); + } + else + { + Directory.Delete(hashDir, true); + } + } + } + private void Log(String message, Torrent? torrent = null) { if (torrent != null) diff --git a/server/RdtClient.Service/Services/TorrentRunner.cs b/server/RdtClient.Service/Services/TorrentRunner.cs index 102b9b6..2d32031 100644 --- a/server/RdtClient.Service/Services/TorrentRunner.cs +++ b/server/RdtClient.Service/Services/TorrentRunner.cs @@ -8,7 +8,6 @@ using RdtClient.Service.Services.Downloaders; using System.Collections.Concurrent; using System.Diagnostics; using System.Text.Json; -using System.Web; namespace RdtClient.Service.Services; @@ -450,13 +449,8 @@ public class TorrentRunner(ILogger logger, Torrents torrents, Dow // Check if the unpacking process is even needed var uri = new Uri(download.Link); - var fileName = uri.Segments.Last(); - fileName = HttpUtility.UrlDecode(fileName); - - Log($"Found file name {fileName}", download, torrent); - - var extension = Path.GetExtension(fileName); + var extension = Path.GetExtension(download.FileName); if ((extension != ".rar" && extension != ".zip") || torrent.DownloadClient == Data.Enums.DownloadClient.Symlink) diff --git a/server/RdtClient.Service/Services/UnpackClient.cs b/server/RdtClient.Service/Services/UnpackClient.cs index 2724f43..d5e1cd7 100644 --- a/server/RdtClient.Service/Services/UnpackClient.cs +++ b/server/RdtClient.Service/Services/UnpackClient.cs @@ -1,6 +1,7 @@ using System.Diagnostics; using RdtClient.Data.Models.Data; using RdtClient.Service.Helpers; +using RdtClient.Service.Services.TorrentClients; using SharpCompress.Archives; using SharpCompress.Archives.Rar; using SharpCompress.Archives.Zip; @@ -10,13 +11,13 @@ namespace RdtClient.Service.Services; public class UnpackClient(Download download, String destinationPath) { public Boolean Finished { get; private set; } - + public String? Error { get; private set; } - + public Int32 Progess { get; private set; } private readonly Torrent _torrent = download.Torrent ?? throw new($"Torrent is null"); - + private readonly CancellationTokenSource _cancellationTokenSource = new(); public void Start() @@ -69,13 +70,13 @@ public class UnpackClient(Download download, String destinationPath) if (archiveEntries.Any(m => m.Contains(".r00"))) { extractPathTemp = Path.Combine(extractPath, Guid.NewGuid().ToString()); - + if (!Directory.Exists(extractPathTemp)) { Directory.CreateDirectory(extractPathTemp); } } - + if (extractPathTemp != null) { Extract(filePath, extractPathTemp, cancellationToken); @@ -102,6 +103,11 @@ public class UnpackClient(Download download, String destinationPath) await FileHelper.Delete(filePath); } + + if (_torrent.ClientKind == Data.Enums.Provider.TorBox) + { + TorBoxTorrentClient.MoveHashDirContents(extractPath, _torrent); + } } catch (Exception ex) { @@ -113,6 +119,7 @@ public class UnpackClient(Download download, String destinationPath) } } + private static async Task> GetArchiveFiles(String filePath) { await using Stream stream = File.OpenRead(filePath); @@ -161,10 +168,10 @@ public class UnpackClient(Download download, String destinationPath) d => { Debug.WriteLine(d); - Progess = (Int32) Math.Round(d); + Progess = (Int32)Math.Round(d); }, cancellationToken: cancellationToken); - + archive.Dispose(); GC.Collect();