Fixed settings parsing when entering an invalid full Int32.
Add Uploading status to the interface.
This commit is contained in:
parent
075f494ec6
commit
a0d000138c
13 changed files with 210 additions and 14 deletions
|
|
@ -4,6 +4,15 @@ 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).
|
||||
|
||||
## [1.9.5] - 2021-10-28
|
||||
### Changed
|
||||
- Fixed issues with the simple downloader.
|
||||
- Fixed issue with retrying downloads.
|
||||
|
||||
### Added
|
||||
- Added torrent uploading status from Real Debrid.
|
||||
- Restored removing of torrents when deleted from Real Debrid.
|
||||
|
||||
## [1.9.4] - 2021-10-28
|
||||
### Changed
|
||||
- Fixed issues retrying torrents after multiple failed downloads in large torrents.
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@
|
|||
<div class="control">
|
||||
<div class="field has-addons" style="margin-bottom: 0">
|
||||
<div class="control is-expanded">
|
||||
<input class="input" type="number" max="1000" min="0" [(ngModel)]="downloadMinSize" />
|
||||
<input class="input" type="number" max="1000" min="0" step="1" [(ngModel)]="downloadMinSize" />
|
||||
</div>
|
||||
<div class="control">
|
||||
<a class="button is-static">MB</a>
|
||||
|
|
@ -84,7 +84,7 @@
|
|||
<div class="field">
|
||||
<label class="label">Priority</label>
|
||||
<div class="control">
|
||||
<input class="input" type="number" [(ngModel)]="priority" />
|
||||
<input class="input" type="number" step="1" [(ngModel)]="priority" />
|
||||
</div>
|
||||
<p class="help">
|
||||
Set the priority for this torrent where 1 is the highest. When empty it will be assigned the lowest priority.
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ export enum RealDebridStatus {
|
|||
WaitingForFileSelection = 1,
|
||||
Downloading = 2,
|
||||
Finished = 3,
|
||||
Uploading = 4,
|
||||
|
||||
Error = 99,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@
|
|||
<a class="navbar-item"> Profile </a>
|
||||
<a class="navbar-item" (click)="logout()"> Logout </a>
|
||||
<hr class="navbar-divider" />
|
||||
<div class="navbar-item">Version 1.9.4</div>
|
||||
<div class="navbar-item">Version 1.9.5</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@
|
|||
<div class="field">
|
||||
<label class="label">Maximum unpack processes</label>
|
||||
<div class="control">
|
||||
<input class="input" type="number" max="100" min="1" [(ngModel)]="settingUnpackLimit" />
|
||||
<input class="input" type="number" max="100" min="1" step="1" [(ngModel)]="settingUnpackLimit" />
|
||||
</div>
|
||||
<p class="help">Maximum amount of downloads that get unpacked on your host at the same time.</p>
|
||||
</div>
|
||||
|
|
@ -98,7 +98,7 @@
|
|||
<div class="field">
|
||||
<label class="label">Maximum parallel downloads</label>
|
||||
<div class="control">
|
||||
<input class="input" type="number" max="100" min="1" [(ngModel)]="settingDownloadLimit" />
|
||||
<input class="input" type="number" max="100" min="1" step="1" [(ngModel)]="settingDownloadLimit" />
|
||||
</div>
|
||||
<p class="help">Maximum amount of torrents that get downloaded to your host at the same time.</p>
|
||||
</div>
|
||||
|
|
@ -106,7 +106,7 @@
|
|||
<div class="field" *ngIf="settingDownloadClient === 'MultiPart'">
|
||||
<label class="label">Parallel connections per download</label>
|
||||
<div class="control">
|
||||
<input class="input" type="number" max="100" min="0" [(ngModel)]="settingDownloadChunkCount" />
|
||||
<input class="input" type="number" max="100" min="0" step="1" [(ngModel)]="settingDownloadChunkCount" />
|
||||
</div>
|
||||
<p class="help">
|
||||
Maximum amount of parallel threads that are used to download a single torrent to your host. If set to 1 no
|
||||
|
|
@ -117,7 +117,7 @@
|
|||
<div class="field" *ngIf="settingDownloadClient === 'MultiPart'">
|
||||
<label class="label">Download speed (in MB/s)</label>
|
||||
<div class="control">
|
||||
<input class="input" type="number" max="1000" min="0" [(ngModel)]="settingDownloadMaxSpeed" />
|
||||
<input class="input" type="number" max="1000" min="0" step="1" [(ngModel)]="settingDownloadMaxSpeed" />
|
||||
</div>
|
||||
<p class="help">Maximum download speed in Megabytes per second. When set to 0 unlimited speed is used.</p>
|
||||
</div>
|
||||
|
|
@ -178,7 +178,7 @@
|
|||
<div class="control">
|
||||
<div class="field has-addons" style="margin-bottom: 0">
|
||||
<div class="control is-expanded">
|
||||
<input class="input" type="number" max="1000" min="0" [(ngModel)]="settingMinFileSize" />
|
||||
<input class="input" type="number" max="1000" min="0" step="1" [(ngModel)]="settingMinFileSize" />
|
||||
</div>
|
||||
<div class="control">
|
||||
<a class="button is-static">MB</a>
|
||||
|
|
|
|||
|
|
@ -99,6 +99,8 @@ export class TorrentStatusPipe implements PipeTransform {
|
|||
return `Torrent error: ${torrent.rdStatusRaw}`;
|
||||
case RealDebridStatus.Finished:
|
||||
return `Torrent finished, waiting to download`;
|
||||
case RealDebridStatus.Uploading:
|
||||
return `Torrent uploading`;
|
||||
default:
|
||||
return 'Unknown status';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -464,7 +464,7 @@
|
|||
<div class="field">
|
||||
<label class="label">Priority</label>
|
||||
<div class="control">
|
||||
<input class="input" type="number" [(ngModel)]="updateSettingsPriority" />
|
||||
<input class="input" type="number" step="1" [(ngModel)]="updateSettingsPriority" />
|
||||
</div>
|
||||
<p class="help">
|
||||
Set the priority for this torrent where 1 is the highest. When empty it will be assigned the lowest priority.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "rdt-client",
|
||||
"version": "1.9.4",
|
||||
"version": "1.9.5",
|
||||
"description": "This is a web interface to manage your torrents on Real-Debrid.",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using System.Threading.Tasks;
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using RdtClient.Data.Models.Data;
|
||||
using RdtClient.Data.Models.Internal;
|
||||
using Serilog;
|
||||
|
||||
namespace RdtClient.Data.Data
|
||||
{
|
||||
|
|
@ -26,8 +27,24 @@ namespace RdtClient.Data.Data
|
|||
{
|
||||
var allSettings = await _dataContext.Settings.AsNoTracking().ToListAsync();
|
||||
|
||||
String GetString(String name) => allSettings.FirstOrDefault(m => m.SettingId == name)?.Value;
|
||||
Int32 GetInt32(String name) => Int32.Parse(allSettings.FirstOrDefault(m => m.SettingId == name)?.Value ?? "0");
|
||||
String GetString(String name)
|
||||
{
|
||||
return allSettings.FirstOrDefault(m => m.SettingId == name)?.Value;
|
||||
}
|
||||
|
||||
Int32 GetInt32(String name)
|
||||
{
|
||||
var strVal = GetString(name);
|
||||
|
||||
if (!Int32.TryParse(strVal, out var intVal))
|
||||
{
|
||||
Log.Error("Unable to parse setting {name} to Int32", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return intVal;
|
||||
|
||||
}
|
||||
|
||||
Get = new DbSettings
|
||||
{
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
WaitingForFileSelection = 1,
|
||||
Downloading = 2,
|
||||
Finished = 3,
|
||||
Uploading = 4,
|
||||
|
||||
Error = 99
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,155 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using RDNET;
|
||||
using RdtClient.Service.Models.TorrentClient;
|
||||
|
||||
namespace RdtClient.Service.Services.TorrentClients
|
||||
{
|
||||
public class AllDebridTorrentClient : ITorrentClient
|
||||
{
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
|
||||
public AllDebridTorrentClient(IHttpClientFactory httpClientFactory)
|
||||
{
|
||||
_httpClientFactory = httpClientFactory;
|
||||
}
|
||||
|
||||
private RdNetClient GetRdNetClient()
|
||||
{
|
||||
var apiKey = Settings.Get.RealDebridApiKey;
|
||||
|
||||
if (String.IsNullOrWhiteSpace(apiKey))
|
||||
{
|
||||
throw new Exception("Real-Debrid API Key not set in the settings");
|
||||
}
|
||||
|
||||
var httpClient = _httpClientFactory.CreateClient();
|
||||
httpClient.Timeout = TimeSpan.FromSeconds(10);
|
||||
|
||||
var rdtNetClient = new RdNetClient(null, httpClient, 5);
|
||||
rdtNetClient.UseApiAuthentication(apiKey);
|
||||
|
||||
return rdtNetClient;
|
||||
}
|
||||
|
||||
private static TorrentClientTorrent Map(Torrent torrent)
|
||||
{
|
||||
return new TorrentClientTorrent
|
||||
{
|
||||
Id = torrent.Id,
|
||||
Filename = torrent.Filename,
|
||||
OriginalFilename = torrent.OriginalFilename,
|
||||
Hash = torrent.Hash,
|
||||
Bytes = torrent.Bytes,
|
||||
OriginalBytes = torrent.OriginalBytes,
|
||||
Host = torrent.Host,
|
||||
Split = torrent.Split,
|
||||
Progress = torrent.Progress,
|
||||
Status = torrent.Status,
|
||||
Added = torrent.Added,
|
||||
Files = (torrent.Files ?? new List<TorrentFile>()).Select(m => new TorrentClientTorrentFile
|
||||
{
|
||||
Path = m.Path,
|
||||
Bytes = m.Bytes,
|
||||
Id = m.Id,
|
||||
Selected = m.Selected
|
||||
}).ToList(),
|
||||
Links = torrent.Links,
|
||||
Ended = torrent.Ended,
|
||||
Speed = torrent.Speed,
|
||||
Seeders = torrent.Seeders,
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<IList<TorrentClientTorrent>> GetTorrents()
|
||||
{
|
||||
var page = 0;
|
||||
var results = new List<Torrent>();
|
||||
|
||||
while (true)
|
||||
{
|
||||
var pagedResults = await GetRdNetClient().Torrents.GetAsync(page, 100);
|
||||
|
||||
results.AddRange(pagedResults);
|
||||
|
||||
if (pagedResults.Count == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
page += 100;
|
||||
}
|
||||
|
||||
return results.Select(Map).ToList();
|
||||
}
|
||||
|
||||
public async Task<TorrentClientUser> GetUser()
|
||||
{
|
||||
var user = await GetRdNetClient().User.GetAsync();
|
||||
|
||||
return new TorrentClientUser
|
||||
{
|
||||
Username = user.Username,
|
||||
Expiration = user.Expiration
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<String> AddMagnet(String magnetLink)
|
||||
{
|
||||
var result = await GetRdNetClient().Torrents.AddMagnetAsync(magnetLink);
|
||||
|
||||
return result.Id;
|
||||
}
|
||||
|
||||
public async Task<String> AddFile(Byte[] bytes)
|
||||
{
|
||||
var result = await GetRdNetClient().Torrents.AddFileAsync(bytes);
|
||||
|
||||
return result.Id;
|
||||
}
|
||||
|
||||
public async Task<List<TorrentClientAvailableFile>> GetAvailableFiles(String hash)
|
||||
{
|
||||
var result = await GetRdNetClient().Torrents.GetAvailableFiles(hash);
|
||||
|
||||
var files = result.SelectMany(m => m.Value).SelectMany(m => m.Value).SelectMany(m => m.Values);
|
||||
|
||||
var groups = files.GroupBy(m => $"{m.Filename}-{m.Filesize}");
|
||||
|
||||
var torrentClientAvailableFiles = groups.Select(m => new TorrentClientAvailableFile
|
||||
{
|
||||
Filename = m.First().Filename,
|
||||
Filesize = m.First().Filesize
|
||||
} ).ToList();
|
||||
|
||||
return torrentClientAvailableFiles;
|
||||
}
|
||||
|
||||
public async Task SelectFiles(String torrentId, IList<String> fileIds)
|
||||
{
|
||||
await GetRdNetClient().Torrents.SelectFilesAsync(torrentId, fileIds.ToArray());
|
||||
}
|
||||
|
||||
public async Task<TorrentClientTorrent> GetInfo(String torrentId)
|
||||
{
|
||||
var result = await GetRdNetClient().Torrents.GetInfoAsync(torrentId);
|
||||
|
||||
return Map(result);
|
||||
}
|
||||
|
||||
public async Task Delete(String torrentId)
|
||||
{
|
||||
await GetRdNetClient().Torrents.DeleteAsync(torrentId);
|
||||
}
|
||||
|
||||
public async Task<String> Unrestrict(String link)
|
||||
{
|
||||
var result = await GetRdNetClient().Unrestrict.LinkAsync(link);
|
||||
|
||||
return result.Download;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -354,6 +354,17 @@ namespace RdtClient.Service.Services
|
|||
|
||||
await UpdateRdData(torrent);
|
||||
}
|
||||
|
||||
foreach (var torrent in torrents)
|
||||
{
|
||||
var rdTorrent = rdTorrents.FirstOrDefault(m => m.Id == torrent.RdId);
|
||||
|
||||
if (rdTorrent == null)
|
||||
{
|
||||
await _downloads.DeleteForTorrent(torrent.TorrentId);
|
||||
await _torrentData.Delete(torrent.TorrentId);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
@ -649,7 +660,7 @@ namespace RdtClient.Service.Services
|
|||
"error" => RealDebridStatus.Error,
|
||||
"virus" => RealDebridStatus.Error,
|
||||
"compressing" => RealDebridStatus.Downloading,
|
||||
"uploading" => RealDebridStatus.Downloading,
|
||||
"uploading" => RealDebridStatus.Uploading,
|
||||
"dead" => RealDebridStatus.Error,
|
||||
_ => RealDebridStatus.Error
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<TargetFramework>net5.0</TargetFramework>
|
||||
<OutputType>Exe</OutputType>
|
||||
<UserSecretsId>94c24cba-f03f-4453-a671-3640b517c573</UserSecretsId>
|
||||
<Version>1.9.4</Version>
|
||||
<Version>1.9.5</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
Loading…
Reference in a new issue