diff --git a/client/src/app/add-new-torrent/add-new-torrent.component.html b/client/src/app/add-new-torrent/add-new-torrent.component.html index ed6a853..a083d1d 100644 --- a/client/src/app/add-new-torrent/add-new-torrent.component.html +++ b/client/src/app/add-new-torrent/add-new-torrent.component.html @@ -74,7 +74,10 @@
- @@ -82,7 +85,7 @@

When a torrent is fully downloaded on the provider, perform this action.

- This option is only available for RealDebrid. AllDebrid and Premiumize will always download the full torrent. + This option is only available for RealDebrid. AllDebrid, Premiumize, and Torbox will always download the full torrent.

diff --git a/client/src/app/navbar/navbar.component.ts b/client/src/app/navbar/navbar.component.ts index c47e2b9..95c8067 100644 --- a/client/src/app/navbar/navbar.component.ts +++ b/client/src/app/navbar/navbar.component.ts @@ -15,7 +15,11 @@ export class NavbarComponent implements OnInit { public profile: Profile; public providerLink: string; - constructor(private settingsService: SettingsService, private authService: AuthService, private router: Router) {} + constructor( + private settingsService: SettingsService, + private authService: AuthService, + private router: Router, + ) {} ngOnInit(): void { this.settingsService.getProfile().subscribe((result) => { @@ -31,6 +35,9 @@ export class NavbarComponent implements OnInit { case 'Premiumize': this.providerLink = 'https://www.premiumize.me/'; break; + case 'TorBox': + this.providerLink = 'https://torbox.app/'; + break; } }); } @@ -40,7 +47,7 @@ export class NavbarComponent implements OnInit { () => { this.router.navigate(['/login']); }, - (err) => {} + (err) => {}, ); } } diff --git a/client/src/app/setup/setup.component.html b/client/src/app/setup/setup.component.html index 3de49e5..c794ba9 100644 --- a/client/src/app/setup/setup.component.html +++ b/client/src/app/setup/setup.component.html @@ -42,7 +42,7 @@
To be able to use the Real-Debrid Client you need a premium subscription to download torrents.

- Not premium yet? You have the choice of 2 providers: + Not premium yet? You have the choice of 4 providers:
Use this link to sign up to Real-Debrid.Use this link to sign up to Premiumize. + Use this link to sign up to Premiumize.
(Referal links)
@@ -65,6 +66,7 @@ + @@ -91,6 +93,10 @@ >https://www.premiumize.me/account.

+

+ You can find your API key here: + https://torbox.app/settings. +

diff --git a/server/RdtClient.Data/Enums/Provider.cs b/server/RdtClient.Data/Enums/Provider.cs index 7422663..ff372dc 100644 --- a/server/RdtClient.Data/Enums/Provider.cs +++ b/server/RdtClient.Data/Enums/Provider.cs @@ -11,5 +11,8 @@ public enum Provider AllDebrid, [Description("Premiumize")] - Premiumize + Premiumize, + + [Description("TorBox")] + TorBox } \ No newline at end of file diff --git a/server/RdtClient.Data/Models/Internal/DbSettings.cs b/server/RdtClient.Data/Models/Internal/DbSettings.cs index 10381fd..ee58bb5 100644 --- a/server/RdtClient.Data/Models/Internal/DbSettings.cs +++ b/server/RdtClient.Data/Models/Internal/DbSettings.cs @@ -140,10 +140,11 @@ http://127.0.0.1:6800/jsonrpc.")] public class DbSettingsProvider { [DisplayName("Provider")] - [Description(@"The following 3 providers are supported: + [Description(@"The following 4 providers are supported: https://real-debrid.com https://alldebrid.com https://www.premiumize.me/ +https://torbox.app/ At this point only 1 provider can be used at the time.")] public Provider Provider { get; set; } = Provider.RealDebrid; @@ -153,7 +154,9 @@ At this point only 1 provider can be used at the time.")] or https://alldebrid.com/apikeys/ or -https://www.premiumize.me/account/")] +https://www.premiumize.me/account/ +or +https://torbox.app/settings/")] public String ApiKey { get; set; } = ""; [DisplayName("Automatically import and process torrents added to provider")] diff --git a/server/RdtClient.Service/DiConfig.cs b/server/RdtClient.Service/DiConfig.cs index e5f7aa2..695443f 100644 --- a/server/RdtClient.Service/DiConfig.cs +++ b/server/RdtClient.Service/DiConfig.cs @@ -24,6 +24,7 @@ public static class DiConfig services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); services.AddScoped(); services.AddScoped(); diff --git a/server/RdtClient.Service/Helpers/DownloadHelper.cs b/server/RdtClient.Service/Helpers/DownloadHelper.cs index 0c9a1c4..aaa04c0 100644 --- a/server/RdtClient.Service/Helpers/DownloadHelper.cs +++ b/server/RdtClient.Service/Helpers/DownloadHelper.cs @@ -1,11 +1,14 @@ -using System.Web; +using System; +using System.Web; +using RdtClient.Data.Enums; using RdtClient.Data.Models.Data; +using RdtClient.Service.Services; namespace RdtClient.Service.Helpers; public static class DownloadHelper { - public static String? GetDownloadPath(String downloadPath, Torrent torrent, Download download) + public static async Task GetDownloadPath(String downloadPath, Torrent torrent, Download download) { var fileUrl = download.Link; @@ -21,6 +24,20 @@ public static class DownloadHelper var fileName = uri.Segments.Last(); + if (Settings.Get.Provider.Provider == Provider.TorBox) + { + using (HttpClient client = new HttpClient()) + { + HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Head, uri); + HttpResponseMessage response = await client.SendAsync(request); + + if (response.Content.Headers.ContentDisposition != null) + { + fileName = response.Content.Headers.ContentDisposition.FileName!.Trim('"'); + } + } + } + fileName = HttpUtility.UrlDecode(fileName); fileName = FileHelper.RemoveInvalidFileNameChars(fileName); @@ -48,10 +65,12 @@ public static class DownloadHelper var filePath = Path.Combine(torrentPath, fileName); + Console.WriteLine($"FILEPATH HERE {filePath}"); + return filePath; } - public static String? GetDownloadPath(Torrent torrent, Download download) + public static async Task GetDownloadPath(Torrent torrent, Download download) { var fileUrl = download.Link; @@ -65,6 +84,20 @@ public static class DownloadHelper var fileName = uri.Segments.Last(); + if (Settings.Get.Provider.Provider == Provider.TorBox) + { + using (HttpClient client = new HttpClient()) + { + HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Head, uri); + HttpResponseMessage response = await client.SendAsync(request); + + if (response.Content.Headers.ContentDisposition != null) + { + fileName = response.Content.Headers.ContentDisposition.FileName!.Trim('"'); + } + } + } + fileName = HttpUtility.UrlDecode(fileName); fileName = FileHelper.RemoveInvalidFileNameChars(fileName); diff --git a/server/RdtClient.Service/RdtClient.Service.csproj b/server/RdtClient.Service/RdtClient.Service.csproj index 2c5daa6..6d43ec2 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/DownloadClient.cs b/server/RdtClient.Service/Services/DownloadClient.cs index b8a268d..51220cf 100644 --- a/server/RdtClient.Service/Services/DownloadClient.cs +++ b/server/RdtClient.Service/Services/DownloadClient.cs @@ -39,16 +39,16 @@ public class DownloadClient(Download download, Torrent torrent, String destinati throw new("Invalid download path"); } - await FileHelper.Delete(filePath); + await FileHelper.Delete(filePath.Result!); Type = torrent.DownloadClient; Downloader = Type switch { - Data.Enums.DownloadClient.Internal => new InternalDownloader(download.Link, filePath), - Data.Enums.DownloadClient.Bezzad => new BezzadDownloader(download.Link, filePath), - Data.Enums.DownloadClient.Aria2c => new Aria2cDownloader(download.RemoteId, download.Link, filePath, downloadPath, category), - Data.Enums.DownloadClient.Symlink => new SymlinkDownloader(download.Link, filePath, downloadPath), + Data.Enums.DownloadClient.Internal => new InternalDownloader(download.Link, filePath.Result!), + Data.Enums.DownloadClient.Bezzad => new BezzadDownloader(download.Link, filePath.Result!), + Data.Enums.DownloadClient.Aria2c => new Aria2cDownloader(download.RemoteId, download.Link, filePath.Result!, downloadPath.Result!, category), + Data.Enums.DownloadClient.Symlink => new SymlinkDownloader(download.Link, filePath.Result!, downloadPath.Result!), _ => throw new($"Unknown download client {Type}") }; diff --git a/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs b/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs index fb65098..1d031f0 100644 --- a/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs +++ b/server/RdtClient.Service/Services/TorrentClients/TorBoxTorrentClient.cs @@ -1,12 +1,10 @@ -using System.Text.RegularExpressions; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using TorBoxNET; using RdtClient.Data.Enums; using RdtClient.Data.Models.TorrentClient; using RdtClient.Service.Helpers; -using Microsoft.AspNetCore.Mvc.RazorPages; -using System.Diagnostics.Eventing.Reader; +using Microsoft.AspNetCore.Routing.Constraints; namespace RdtClient.Service.Services.TorrentClients; @@ -80,7 +78,7 @@ public class TorBoxTorrentClient(ILogger logger, IHttpClien Added = ChangeTimeZone(torrent.CreatedAt)!.Value, Files = (torrent.Files ?? []).Select(m => new TorrentClientFile { - Path = m.S3Path.Replace(m.Hash + "/", string.Empty), + Path = string.Join("/", m.Name.Split('/').Skip(1)), Bytes = m.Size, Id = m.Id, Selected = true @@ -125,14 +123,14 @@ public class TorBoxTorrentClient(ILogger logger, IHttpClien public async Task AddMagnet(String magnetLink) { - var result = await GetClient().Torrents.AddMagnetAsync(magnetLink); + var result = await GetClient().Torrents.AddMagnetAsync(magnetLink, seeding: 3); return result.Data?.Hash?.ToString()!; } public async Task AddFile(Byte[] bytes) { - var result = await GetClient().Torrents.AddFileAsync(bytes); + var result = await GetClient().Torrents.AddFileAsync(bytes, seeding: 3); return result.Data?.Hash?.ToString()!; } @@ -155,7 +153,10 @@ public class TorBoxTorrentClient(ILogger logger, IHttpClien public async Task Unrestrict(String link) { - var result = await GetClient().Unrestrict.LinkAsync(link); + var torrentFile = new List(link.Split('/')); + var torrentID = torrentFile[4]; + var fileID = torrentFile[5]; + var result = await GetClient().Unrestrict.LinkAsync(torrentID, fileID); if (result.Error != null) { @@ -219,12 +220,13 @@ public class TorBoxTorrentClient(ILogger logger, IHttpClien { "queued" => TorrentStatus.Processing, "metaDL" => TorrentStatus.Processing, + "checking" => TorrentStatus.Processing, "checkingResumeData" => TorrentStatus.Processing, "paused" => TorrentStatus.Downloading, "downloading" => TorrentStatus.Downloading, "completed" => TorrentStatus.Downloading, - "uploading" => TorrentStatus.Downloading, - "uploading (no peers)" => TorrentStatus.Downloading, + "uploading" => TorrentStatus.Finished, + "uploading (no peers)" => TorrentStatus.Finished, "stalled" => TorrentStatus.Downloading, "stalled (no seeds)" => TorrentStatus.Downloading, "cached" => TorrentStatus.Finished, @@ -263,8 +265,8 @@ public class TorBoxTorrentClient(ILogger logger, IHttpClien { foreach (var file in rdTorrent.Files!) { - var newFile = new List { rdTorrent.Id, file.Id.ToString() }; - files.Add(newFile.ToString()!); + var newFile = $"https://torbox.app/fakedl/{rdTorrent.Id}/{file.Id}"; + files.Add(newFile); } } @@ -283,7 +285,7 @@ public class TorBoxTorrentClient(ILogger logger, IHttpClien private async Task GetInfo(String torrentHash) { - var result = await GetClient().Torrents.GetInfoAsync(torrentHash); + var result = await GetClient().Torrents.GetInfoAsync(torrentHash, skipCache: true); return Map(result!); } diff --git a/server/RdtClient.Service/Services/Torrents.cs b/server/RdtClient.Service/Services/Torrents.cs index cc39252..3053891 100644 --- a/server/RdtClient.Service/Services/Torrents.cs +++ b/server/RdtClient.Service/Services/Torrents.cs @@ -22,7 +22,8 @@ public class Torrents( Downloads downloads, AllDebridTorrentClient allDebridTorrentClient, PremiumizeTorrentClient premiumizeTorrentClient, - RealDebridTorrentClient realDebridTorrentClient) + RealDebridTorrentClient realDebridTorrentClient, + TorBoxTorrentClient torBoxTorrentClient) { private static readonly SemaphoreSlim RealDebridUpdateLock = new(1, 1); @@ -40,6 +41,7 @@ public class Torrents( Provider.Premiumize => premiumizeTorrentClient, Provider.RealDebrid => realDebridTorrentClient, Provider.AllDebrid => allDebridTorrentClient, + Provider.TorBox => torBoxTorrentClient, _ => throw new("Invalid Provider") }; } @@ -551,7 +553,7 @@ public class Torrents( { Log($"Deleting {filePath}", download, download.Torrent); - await FileHelper.Delete(filePath); + await FileHelper.Delete(filePath.Result!); } Log($"Resetting", download, download.Torrent); diff --git a/server/RdtClient.Service/Services/UnpackClient.cs b/server/RdtClient.Service/Services/UnpackClient.cs index 2724f43..c702d71 100644 --- a/server/RdtClient.Service/Services/UnpackClient.cs +++ b/server/RdtClient.Service/Services/UnpackClient.cs @@ -31,7 +31,7 @@ public class UnpackClient(Download download, String destinationPath) { if (!_cancellationTokenSource.IsCancellationRequested) { - await Unpack(filePath, _cancellationTokenSource.Token); + await Unpack(filePath.Result!, _cancellationTokenSource.Token); } }); }