commit
7573492bcf
12 changed files with 416 additions and 20 deletions
|
|
@ -74,7 +74,10 @@
|
|||
<div class="field">
|
||||
<label class="label">Post Torrent Download Action</label>
|
||||
<div class="control select is-fullwidth">
|
||||
<select [(ngModel)]="downloadAction" [disabled]="provider === 'AllDebrid' || provider === 'Premiumize'">
|
||||
<select
|
||||
[(ngModel)]="downloadAction"
|
||||
[disabled]="provider === 'AllDebrid' || provider === 'Premiumize' || provider === 'TorBox'"
|
||||
>
|
||||
<option [ngValue]="0">Download all files</option>
|
||||
<option [ngValue]="1">Download all available files</option>
|
||||
<option [ngValue]="2">Manually pick files</option>
|
||||
|
|
@ -82,7 +85,7 @@
|
|||
</div>
|
||||
<p class="help">When a torrent is fully downloaded on the provider, perform this action.</p>
|
||||
<p class="help" *ngIf="provider === 'AllDebrid'">
|
||||
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.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -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) => {},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
<div class="notification is-primary">
|
||||
To be able to use the Real-Debrid Client you need a premium subscription to download torrents.
|
||||
<br /><br />
|
||||
Not premium yet? You have the choice of 2 providers:
|
||||
Not premium yet? You have the choice of 4 providers:
|
||||
<br />
|
||||
<a href="https://real-debrid.com/?id=1348683" target="_blank" rel="noopener"
|
||||
>Use this link to sign up to Real-Debrid.</a
|
||||
|
|
@ -55,6 +55,8 @@
|
|||
<a href="https://www.premiumize.me/" target="_blank" rel="noopener"
|
||||
>Use this link to sign up to Premiumize.</a
|
||||
>
|
||||
<a href="https://torbox.app/" target="_blank" rel="noopener"
|
||||
>Use this link to sign up to TorBox.</a>
|
||||
<br />
|
||||
<small>(Referal links)</small>
|
||||
</div>
|
||||
|
|
@ -65,6 +67,7 @@
|
|||
<option [ngValue]="0">Real-Debrid</option>
|
||||
<option [ngValue]="1">AllDebrid</option>
|
||||
<option [ngValue]="2">Premiumize</option>
|
||||
<option [ngValue]="3">TorBox</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -91,6 +94,10 @@
|
|||
>https://www.premiumize.me/account</a
|
||||
>.
|
||||
</p>
|
||||
<p class="help" *ngIf="provider === 3">
|
||||
You can find your API key here:
|
||||
<a href="https://torbox.app/settings" target="_blank" rel="noopener">https://torbox.app/settings</a>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
|
|
|
|||
|
|
@ -11,5 +11,8 @@ public enum Provider
|
|||
AllDebrid,
|
||||
|
||||
[Description("Premiumize")]
|
||||
Premiumize
|
||||
Premiumize,
|
||||
|
||||
[Description("TorBox")]
|
||||
TorBox
|
||||
}
|
||||
|
|
@ -123,7 +123,7 @@ http://127.0.0.1:6800/jsonrpc.")]
|
|||
[DisplayName("Aria2c Secret (only used for the Aria2c Downloader)")]
|
||||
[Description("The secret of your Aria2c instance. Optional.")]
|
||||
public String Aria2cSecret { get; set; } = "mysecret123";
|
||||
|
||||
|
||||
[DisplayName("Aria2c Download Path")]
|
||||
[Description("The root path to download the file to on the Aria2c host, if empty use the Download path setting.")]
|
||||
public String? Aria2cDownloadPath { get; set; } = null;
|
||||
|
|
@ -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:
|
||||
<a href=""https://real-debrid.com/?id=1348683"" target=""_blank"" rel=""noopener"">https://real-debrid.com</a>
|
||||
<a href=""https://alldebrid.com/?uid=2v91l&lang=en"" target=""_blank"" rel=""noopener"">https://alldebrid.com</a>
|
||||
<a href=""https://www.premiumize.me/"" target=""_blank"" rel=""noopener"">https://www.premiumize.me/</a>
|
||||
<a href=""https://torbox.app/"" target=""_blank"" rel=""noopener"">https://torbox.app/</a>
|
||||
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
|
||||
<a href=""""https://alldebrid.com/apikeys/"""" target=""""_blank"""" rel=""""noopener"""">https://alldebrid.com/apikeys/</a>
|
||||
or
|
||||
<a href=""https://www.premiumize.me/account/"" target=""_blank"" rel=""noopener"">https://www.premiumize.me/account/</a>")]
|
||||
<a href=""https://www.premiumize.me/account/"" target=""_blank"" rel=""noopener"">https://www.premiumize.me/account/</a>
|
||||
or
|
||||
<a href=""""https://torbox.app/settings/"""" target=""""_blank"""" rel=""""noopener"""">https://torbox.app/settings/</a>")]
|
||||
public String ApiKey { get; set; } = "";
|
||||
|
||||
[DisplayName("Automatically import and process torrents added to provider")]
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ public static class DiConfig
|
|||
services.AddScoped<RemoteService>();
|
||||
services.AddScoped<RealDebridTorrentClient>();
|
||||
services.AddScoped<Settings>();
|
||||
services.AddScoped<TorBoxTorrentClient>();
|
||||
services.AddScoped<Torrents>();
|
||||
services.AddScoped<TorrentRunner>();
|
||||
|
||||
|
|
|
|||
|
|
@ -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<String?> 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);
|
||||
|
|
@ -51,7 +68,7 @@ public static class DownloadHelper
|
|||
return filePath;
|
||||
}
|
||||
|
||||
public static String? GetDownloadPath(Torrent torrent, Download download)
|
||||
public static async Task<String?> GetDownloadPath(Torrent torrent, Download download)
|
||||
{
|
||||
var fileUrl = download.Link;
|
||||
|
||||
|
|
@ -65,6 +82,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);
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
<PackageReference Include="Serilog" Version="4.0.1" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
|
||||
<PackageReference Include="SharpCompress" Version="0.38.0" />
|
||||
<PackageReference Include="TorBox.NET" Version="1.2.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -43,15 +43,15 @@ public class DownloadClient(Download download, Torrent torrent, String destinati
|
|||
|
||||
if (Type != Data.Enums.DownloadClient.Symlink)
|
||||
{
|
||||
await FileHelper.Delete(filePath);
|
||||
await FileHelper.Delete(filePath.Result!);
|
||||
}
|
||||
|
||||
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}")
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,338 @@
|
|||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using TorBoxNET;
|
||||
using RdtClient.Data.Enums;
|
||||
using RdtClient.Data.Models.TorrentClient;
|
||||
using RdtClient.Service.Helpers;
|
||||
|
||||
namespace RdtClient.Service.Services.TorrentClients;
|
||||
|
||||
public class TorBoxTorrentClient(ILogger<TorBoxTorrentClient> logger, IHttpClientFactory httpClientFactory) : ITorrentClient
|
||||
{
|
||||
private TimeSpan? _offset;
|
||||
private TorBoxNetClient GetClient()
|
||||
{
|
||||
try
|
||||
{
|
||||
var apiKey = Settings.Get.Provider.ApiKey;
|
||||
|
||||
if (String.IsNullOrWhiteSpace(apiKey))
|
||||
{
|
||||
throw new("TorBox API Key not set in the settings");
|
||||
}
|
||||
|
||||
var httpClient = httpClientFactory.CreateClient();
|
||||
httpClient.Timeout = TimeSpan.FromSeconds(Settings.Get.Provider.Timeout);
|
||||
|
||||
var torBoxNetClient = new TorBoxNetClient(null, httpClient, 5);
|
||||
torBoxNetClient.UseApiAuthentication(apiKey);
|
||||
|
||||
// Get the server time to fix up the timezones on results
|
||||
if (_offset == null)
|
||||
{
|
||||
var serverTime = DateTimeOffset.UtcNow;
|
||||
_offset = serverTime.Offset;
|
||||
}
|
||||
|
||||
return torBoxNetClient;
|
||||
}
|
||||
catch (AggregateException ae)
|
||||
{
|
||||
foreach (var inner in ae.InnerExceptions)
|
||||
{
|
||||
logger.LogError(inner, $"The connection to RealDebrid has failed: {inner.Message}");
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
catch (TaskCanceledException ex) when (ex.InnerException is TimeoutException)
|
||||
{
|
||||
logger.LogError(ex, $"The connection to RealDebrid has timed out: {ex.Message}");
|
||||
|
||||
throw;
|
||||
}
|
||||
catch (TaskCanceledException ex)
|
||||
{
|
||||
logger.LogError(ex, $"The connection to RealDebrid has timed out: {ex.Message}");
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private TorrentClientTorrent Map(TorrentInfoResult torrent)
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Id = torrent.Hash,
|
||||
Filename = torrent.Name,
|
||||
OriginalFilename = torrent.Name,
|
||||
Hash = torrent.Hash,
|
||||
Bytes = torrent.Size,
|
||||
OriginalBytes = torrent.Size,
|
||||
Host = torrent.DownloadPresent.ToString(),
|
||||
Split = 0,
|
||||
Progress = (Int64)((torrent.Progress) * 100.0),
|
||||
Status = torrent.DownloadState,
|
||||
Added = ChangeTimeZone(torrent.CreatedAt)!.Value,
|
||||
Files = (torrent.Files ?? []).Select(m => new TorrentClientFile
|
||||
{
|
||||
Path = string.Join("/", m.Name.Split('/').Skip(1)),
|
||||
Bytes = m.Size,
|
||||
Id = m.Id,
|
||||
Selected = true
|
||||
}).ToList(),
|
||||
Links = [],
|
||||
Ended = ChangeTimeZone(torrent.UpdatedAt),
|
||||
Speed = torrent.DownloadSpeed,
|
||||
Seeders = torrent.Seeds,
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<IList<TorrentClientTorrent>> GetTorrents()
|
||||
{
|
||||
var torrents = new List<TorrentInfoResult>();
|
||||
|
||||
var currentTorrents = await GetClient().Torrents.GetCurrentAsync(true);
|
||||
if (currentTorrents != null)
|
||||
{
|
||||
torrents.AddRange(currentTorrents);
|
||||
}
|
||||
|
||||
var queuedTorrents = await GetClient().Torrents.GetQueuedAsync(true);
|
||||
if (queuedTorrents != null)
|
||||
{
|
||||
torrents.AddRange(queuedTorrents);
|
||||
}
|
||||
|
||||
return torrents!.Select(Map).ToList();
|
||||
}
|
||||
|
||||
public async Task<TorrentClientUser> GetUser()
|
||||
{
|
||||
var user = await GetClient().User.GetAsync(false);
|
||||
|
||||
return new()
|
||||
{
|
||||
Username = user.Data!.Email,
|
||||
Expiration = user.Data!.Plan != 0 ? user.Data!.PremiumExpiresAt!.Value : null
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<String> AddMagnet(String magnetLink)
|
||||
{
|
||||
// var seeding = Settings.Get.Integrations.Default.FinishedAction;
|
||||
|
||||
// Line is not working right now, will disable seeding and fix in december when I have time again.
|
||||
// var seed = (seeding == TorrentFinishedAction.RemoveAllTorrents || seeding == TorrentFinishedAction.RemoveRealDebrid) ? 3 : 2;
|
||||
|
||||
var seed = 3;
|
||||
var result = await GetClient().Torrents.AddMagnetAsync(magnetLink, seed, false);
|
||||
|
||||
if (result.Error == "ACTIVE_LIMIT")
|
||||
{
|
||||
var magnetLinkInfo = MonoTorrent.MagnetLink.Parse(magnetLink);
|
||||
return magnetLinkInfo.InfoHashes.V1!.ToHex().ToLowerInvariant();
|
||||
}
|
||||
else
|
||||
{
|
||||
return result.Data!.Hash!;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<String> AddFile(Byte[] bytes)
|
||||
{
|
||||
var seeding = Settings.Get.Integrations.Default.FinishedAction;
|
||||
|
||||
// Line is not working right now, will disable seeding and fix in december when I have time again.
|
||||
// var seed = (seeding == TorrentFinishedAction.RemoveAllTorrents || seeding == TorrentFinishedAction.RemoveRealDebrid) ? 3 : 2;
|
||||
|
||||
var seed = 3;
|
||||
|
||||
var result = await GetClient().Torrents.AddFileAsync(bytes, seed, false);
|
||||
if (result.Error == "ACTIVE_LIMIT")
|
||||
{
|
||||
using (var stream = new MemoryStream(bytes))
|
||||
{
|
||||
var torrent = MonoTorrent.Torrent.Load(stream);
|
||||
return torrent!.InfoHashes.V1!.ToHex().ToLowerInvariant();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return result.Data!.Hash!;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IList<TorrentClientAvailableFile>> GetAvailableFiles(String hash)
|
||||
{
|
||||
var availability = await GetClient().Torrents.GetAvailabilityAsync(hash, listFiles: true);
|
||||
|
||||
if (availability.Data != null)
|
||||
{
|
||||
var availableFiles = new List<TorrentClientAvailableFile>();
|
||||
foreach (var file in availability.Data[0]?.Files!)
|
||||
{
|
||||
availableFiles.Add(
|
||||
new TorrentClientAvailableFile
|
||||
{
|
||||
Filename = file!.Name,
|
||||
Filesize = file.Size
|
||||
});
|
||||
}
|
||||
return availableFiles;
|
||||
}
|
||||
else
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public Task SelectFiles(Data.Models.Data.Torrent torrent)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public async Task Delete(String torrentId)
|
||||
{
|
||||
await GetClient().Torrents.ControlAsync(torrentId, "delete");
|
||||
}
|
||||
|
||||
public async Task<string> Unrestrict(string link)
|
||||
{
|
||||
var segments = link.Split('/');
|
||||
|
||||
bool zipped = segments[5] == "zip";
|
||||
string fileId = zipped ? "0" : segments[5];
|
||||
|
||||
var result = await GetClient().Torrents.RequestDownloadAsync(Convert.ToInt32(segments[4]), Convert.ToInt32(fileId), zipped);
|
||||
|
||||
if (result?.Error != null)
|
||||
{
|
||||
throw new("Unrestrict returned an invalid download");
|
||||
}
|
||||
|
||||
return result!.Data!;
|
||||
}
|
||||
|
||||
public async Task<Data.Models.Data.Torrent> UpdateData(Data.Models.Data.Torrent torrent, TorrentClientTorrent? torrentClientTorrent)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (torrent.RdId == null)
|
||||
{
|
||||
return torrent;
|
||||
}
|
||||
|
||||
var rdTorrent = await GetInfo(torrent.Hash) ?? throw new($"Resource not found");
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(rdTorrent.Filename))
|
||||
{
|
||||
torrent.RdName = rdTorrent.Filename;
|
||||
}
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(rdTorrent.OriginalFilename))
|
||||
{
|
||||
torrent.RdName = rdTorrent.OriginalFilename;
|
||||
}
|
||||
|
||||
if (rdTorrent.Bytes > 0)
|
||||
{
|
||||
torrent.RdSize = rdTorrent.Bytes;
|
||||
}
|
||||
else if (rdTorrent.OriginalBytes > 0)
|
||||
{
|
||||
torrent.RdSize = rdTorrent.OriginalBytes;
|
||||
}
|
||||
|
||||
if (rdTorrent.Files != null)
|
||||
{
|
||||
torrent.RdFiles = JsonConvert.SerializeObject(rdTorrent.Files);
|
||||
}
|
||||
|
||||
torrent.RdHost = rdTorrent.Host;
|
||||
torrent.RdSplit = rdTorrent.Split;
|
||||
torrent.RdProgress = rdTorrent.Progress;
|
||||
torrent.RdAdded = rdTorrent.Added;
|
||||
torrent.RdEnded = rdTorrent.Ended;
|
||||
torrent.RdSpeed = rdTorrent.Speed;
|
||||
torrent.RdSeeders = rdTorrent.Seeders;
|
||||
torrent.RdStatusRaw = rdTorrent.Status;
|
||||
|
||||
if (rdTorrent.Host == "True")
|
||||
{
|
||||
torrent.RdStatus = TorrentStatus.Finished;
|
||||
}
|
||||
else
|
||||
{
|
||||
torrent.RdStatus = rdTorrent.Status switch
|
||||
{
|
||||
"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,
|
||||
"stalled" => TorrentStatus.Downloading,
|
||||
"stalled (no seeds)" => TorrentStatus.Downloading,
|
||||
"processing" => TorrentStatus.Downloading,
|
||||
"cached" => TorrentStatus.Finished,
|
||||
_ => TorrentStatus.Error
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (ex.Message == "Resource not found")
|
||||
{
|
||||
torrent.RdStatusRaw = "deleted";
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
return torrent;
|
||||
}
|
||||
|
||||
public async Task<IList<String>?> GetDownloadLinks(Data.Models.Data.Torrent torrent)
|
||||
{
|
||||
if (torrent.Hash == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var rdTorrent = await GetInfo(torrent.Hash);
|
||||
var files = new List<String>();
|
||||
|
||||
var torrentId = await GetClient().Torrents.GetHashInfoAsync(torrent.Hash, skipCache: true);
|
||||
|
||||
var newFile = $"https://torbox.app/fakedl/{torrentId?.Id}/zip";
|
||||
files.Add(newFile);
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
private DateTimeOffset? ChangeTimeZone(DateTimeOffset? dateTimeOffset)
|
||||
{
|
||||
if (_offset == null)
|
||||
{
|
||||
return dateTimeOffset;
|
||||
}
|
||||
|
||||
return dateTimeOffset?.Subtract(_offset.Value).ToOffset(_offset.Value);
|
||||
}
|
||||
|
||||
private async Task<TorrentClientTorrent> GetInfo(String torrentHash)
|
||||
{
|
||||
var result = await GetClient().Torrents.GetHashInfoAsync(torrentHash, skipCache: true);
|
||||
|
||||
return Map(result!);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue