Add priority mechanishm and support for sonarr priority.
Changed to have /torrents/files return only files that are selected. Add pause/unpause from Sonarr/Radar. Works only for Aria2.
This commit is contained in:
parent
e9e16bedf0
commit
6ac0265d2d
24 changed files with 898 additions and 51 deletions
|
|
@ -29,6 +29,7 @@
|
|||
[(ngModel)]="magnetLink"
|
||||
[disabled]="saving"
|
||||
(blur)="checkFiles()"
|
||||
(paste)="onPaste()"
|
||||
></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -79,6 +80,16 @@
|
|||
</div>
|
||||
<p class="help">The category becomes a sub-folder in your main download path.</p>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="label">Priority</label>
|
||||
<div class="control">
|
||||
<input class="input" type="number" [(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.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div fxFlex>
|
||||
<div class="field">
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ export class AddNewTorrentComponent implements OnInit {
|
|||
private currentTorrentFile: string;
|
||||
|
||||
public category: string;
|
||||
public priority: number;
|
||||
|
||||
public downloadAction: number = 0;
|
||||
public finishedAction: number = 0;
|
||||
|
|
@ -98,7 +99,8 @@ export class AddNewTorrentComponent implements OnInit {
|
|||
this.downloadAction,
|
||||
this.finishedAction,
|
||||
this.downloadMinSize,
|
||||
downloadManualFiles
|
||||
downloadManualFiles,
|
||||
this.priority
|
||||
)
|
||||
.subscribe(
|
||||
() => {
|
||||
|
|
@ -117,7 +119,8 @@ export class AddNewTorrentComponent implements OnInit {
|
|||
this.downloadAction,
|
||||
this.finishedAction,
|
||||
this.downloadMinSize,
|
||||
downloadManualFiles
|
||||
downloadManualFiles,
|
||||
this.priority
|
||||
)
|
||||
.subscribe(
|
||||
() => {
|
||||
|
|
@ -134,6 +137,12 @@ export class AddNewTorrentComponent implements OnInit {
|
|||
}
|
||||
}
|
||||
|
||||
public onPaste(): void {
|
||||
setTimeout(() => {
|
||||
this.checkFiles();
|
||||
}, 100);
|
||||
}
|
||||
|
||||
public checkFiles(): void {
|
||||
if (this.magnetLink && this.magnetLink === this.currentTorrentFile) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ export class Torrent {
|
|||
public isFile: boolean;
|
||||
|
||||
public retryCount: number;
|
||||
public priority: number;
|
||||
|
||||
public rdId: string;
|
||||
public rdName: string;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Category</th>
|
||||
<th>Priority</th>
|
||||
<th>Files</th>
|
||||
<th>Downloads</th>
|
||||
<th>Size</th>
|
||||
|
|
@ -22,6 +23,9 @@
|
|||
<td>
|
||||
{{ torrent.category }}
|
||||
</td>
|
||||
<td>
|
||||
{{ torrent.priority }}
|
||||
</td>
|
||||
<td>
|
||||
{{ torrent.files.length | number }}
|
||||
</td>
|
||||
|
|
|
|||
|
|
@ -43,7 +43,8 @@ export class TorrentService {
|
|||
downloadAction: number,
|
||||
finishedAction: number,
|
||||
downloadMinSize: number,
|
||||
downloadManualFiles: string
|
||||
downloadManualFiles: string,
|
||||
priority: number
|
||||
): Observable<void> {
|
||||
return this.http.post<void>(`/Api/Torrents/UploadMagnet`, {
|
||||
magnetLink,
|
||||
|
|
@ -52,6 +53,7 @@ export class TorrentService {
|
|||
finishedAction,
|
||||
downloadMinSize,
|
||||
downloadManualFiles,
|
||||
priority,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -61,13 +63,14 @@ export class TorrentService {
|
|||
downloadAction: number,
|
||||
finishedAction: number,
|
||||
downloadMinSize: number,
|
||||
downloadManualFiles: string
|
||||
downloadManualFiles: string,
|
||||
priority: number
|
||||
): Observable<void> {
|
||||
const formData: FormData = new FormData();
|
||||
formData.append('file', file);
|
||||
formData.append(
|
||||
'formData',
|
||||
JSON.stringify({ category, downloadAction, finishedAction, downloadMinSize, downloadManualFiles })
|
||||
JSON.stringify({ category, downloadAction, finishedAction, downloadMinSize, downloadManualFiles, priority })
|
||||
);
|
||||
return this.http.post<void>(`/Api/Torrents/UploadFile`, formData);
|
||||
}
|
||||
|
|
@ -104,4 +107,8 @@ export class TorrentService {
|
|||
public retryDownload(downloadId: string): Observable<void> {
|
||||
return this.http.post<void>(`/Api/Torrents/RetryDownload/${downloadId}`, {});
|
||||
}
|
||||
|
||||
public update(torrent: Torrent): Observable<void> {
|
||||
return this.http.put<void>(`/Api/Torrents/Update`, torrent);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,9 @@
|
|||
<div class="control">
|
||||
<button class="button is-primary" (click)="showRetryModal()">Retry Torrent</button>
|
||||
</div>
|
||||
<div class="control">
|
||||
<button class="button is-light" (click)="showUpdateSettingsModal()">Change priority</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">Status</label>
|
||||
|
|
@ -40,6 +43,10 @@
|
|||
<label class="label">Hash</label>
|
||||
{{ torrent.hash }}
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">Priority</label>
|
||||
{{ torrent.priority || "" }}
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">Category</label>
|
||||
{{ torrent.category || "(no category set)" }}
|
||||
|
|
@ -445,3 +452,42 @@
|
|||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal" [class.is-active]="isUpdateSettingsModalActive">
|
||||
<div class="modal-background"></div>
|
||||
<div class="modal-card">
|
||||
<header class="modal-card-head">
|
||||
<p class="modal-card-title">Update torrent settings</p>
|
||||
<button class="delete" aria-label="close" (click)="updateSettingsCancel()"></button>
|
||||
</header>
|
||||
<section class="modal-card-body">
|
||||
<div class="field">
|
||||
<label class="label">Priority</label>
|
||||
<div class="control">
|
||||
<input class="input" type="number" [(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.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
<footer class="modal-card-foot">
|
||||
<button
|
||||
class="button is-success"
|
||||
(click)="updateSettingsOk()"
|
||||
[disabled]="updating"
|
||||
[ngClass]="{ 'is-loading': updating }"
|
||||
>
|
||||
Retry
|
||||
</button>
|
||||
<button
|
||||
class="button"
|
||||
(click)="updateSettingsCancel()"
|
||||
[disabled]="updating"
|
||||
[ngClass]="{ 'is-loading': updating }"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -34,6 +34,10 @@ export class TorrentComponent implements OnInit {
|
|||
public downloadRetrying: boolean;
|
||||
public downloadRetryId: string;
|
||||
|
||||
public isUpdateSettingsModalActive: boolean;
|
||||
public updateSettingsPriority: number;
|
||||
public updating: boolean;
|
||||
|
||||
constructor(private activatedRoute: ActivatedRoute, private router: Router, private torrentService: TorrentService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
|
@ -163,4 +167,31 @@ export class TorrentComponent implements OnInit {
|
|||
}
|
||||
);
|
||||
}
|
||||
|
||||
public showUpdateSettingsModal(): void {
|
||||
this.updateSettingsPriority = this.torrent.priority;
|
||||
|
||||
this.isUpdateSettingsModalActive = true;
|
||||
}
|
||||
|
||||
public updateSettingsCancel(): void {
|
||||
this.isUpdateSettingsModalActive = false;
|
||||
}
|
||||
|
||||
public updateSettingsOk(): void {
|
||||
this.updating = true;
|
||||
|
||||
this.torrent.priority = this.updateSettingsPriority;
|
||||
|
||||
this.torrentService.update(this.torrent).subscribe(
|
||||
() => {
|
||||
this.isUpdateSettingsModalActive = false;
|
||||
this.updating = false;
|
||||
},
|
||||
() => {
|
||||
this.isUpdateSettingsModalActive = false;
|
||||
this.updating = false;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
|
@ -15,6 +16,14 @@ namespace RdtClient.Data.Data
|
|||
_dataContext = dataContext;
|
||||
}
|
||||
|
||||
public async Task<List<Download>> GetForTorrent(Guid torrentId)
|
||||
{
|
||||
return await _dataContext.Downloads
|
||||
.AsNoTracking()
|
||||
.Where(m => m.TorrentId == torrentId)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<Download> GetById(Guid downloadId)
|
||||
{
|
||||
return await _dataContext.Downloads
|
||||
|
|
|
|||
|
|
@ -27,15 +27,12 @@ namespace RdtClient.Data.Data
|
|||
|
||||
try
|
||||
{
|
||||
if (_torrentCache == null)
|
||||
{
|
||||
_torrentCache = await _dataContext.Torrents
|
||||
.AsNoTracking()
|
||||
.Include(m => m.Downloads)
|
||||
.ToListAsync();
|
||||
}
|
||||
_torrentCache ??= await _dataContext.Torrents
|
||||
.AsNoTracking()
|
||||
.Include(m => m.Downloads)
|
||||
.ToListAsync();
|
||||
|
||||
return _torrentCache.OrderByDescending(m => m.Added).ToList();
|
||||
return _torrentCache.OrderBy(m => m.Priority ?? 9999).ThenBy(m => m.Added).ToList();
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
@ -91,7 +88,8 @@ namespace RdtClient.Data.Data
|
|||
Int32 downloadMinSize,
|
||||
String downloadManualFiles,
|
||||
String fileOrMagnetContents,
|
||||
Boolean isFile)
|
||||
Boolean isFile,
|
||||
Int32? priority)
|
||||
{
|
||||
var torrent = new Torrent
|
||||
{
|
||||
|
|
@ -105,7 +103,8 @@ namespace RdtClient.Data.Data
|
|||
DownloadMinSize = downloadMinSize,
|
||||
DownloadManualFiles = downloadManualFiles,
|
||||
FileOrMagnet = fileOrMagnetContents,
|
||||
IsFile = isFile
|
||||
IsFile = isFile,
|
||||
Priority = priority
|
||||
};
|
||||
|
||||
await _dataContext.Torrents.AddAsync(torrent);
|
||||
|
|
@ -148,6 +147,22 @@ namespace RdtClient.Data.Data
|
|||
await VoidCache();
|
||||
}
|
||||
|
||||
public async Task Update(Torrent torrent)
|
||||
{
|
||||
var dbTorrent = await _dataContext.Torrents.FirstOrDefaultAsync(m => m.TorrentId == torrent.TorrentId);
|
||||
|
||||
if (dbTorrent == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dbTorrent.Priority = torrent.Priority;
|
||||
|
||||
await _dataContext.SaveChangesAsync();
|
||||
|
||||
await VoidCache();
|
||||
}
|
||||
|
||||
public async Task UpdateCategory(Guid torrentId, String category)
|
||||
{
|
||||
var dbTorrent = await _dataContext.Torrents.FirstOrDefaultAsync(m => m.TorrentId == torrentId);
|
||||
|
|
@ -212,6 +227,22 @@ namespace RdtClient.Data.Data
|
|||
await VoidCache();
|
||||
}
|
||||
|
||||
public async Task UpdatePriority(Guid torrentId, Int32? priority)
|
||||
{
|
||||
var dbTorrent = await _dataContext.Torrents.FirstOrDefaultAsync(m => m.TorrentId == torrentId);
|
||||
|
||||
if (dbTorrent == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dbTorrent.Priority = priority;
|
||||
|
||||
await _dataContext.SaveChangesAsync();
|
||||
|
||||
await VoidCache();
|
||||
}
|
||||
|
||||
public async Task Delete(Guid torrentId)
|
||||
{
|
||||
var dbTorrent = await _dataContext.Torrents.FirstOrDefaultAsync(m => m.TorrentId == torrentId);
|
||||
|
|
|
|||
442
server/RdtClient.Data/Migrations/20211024161405_Torrents_Add_Priority.Designer.cs
generated
Normal file
442
server/RdtClient.Data/Migrations/20211024161405_Torrents_Add_Priority.Designer.cs
generated
Normal file
|
|
@ -0,0 +1,442 @@
|
|||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using RdtClient.Data.Data;
|
||||
|
||||
namespace RdtClient.Data.Migrations
|
||||
{
|
||||
[DbContext(typeof(DataContext))]
|
||||
[Migration("20211024161405_Torrents_Add_Priority")]
|
||||
partial class Torrents_Add_Priority
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "5.0.10");
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("NormalizedName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedName")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("RoleNameIndex");
|
||||
|
||||
b.ToTable("AspNetRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetRoleClaims");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("AccessFailedCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("EmailConfirmed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("LockoutEnabled")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("NormalizedEmail")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("NormalizedUserName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("PhoneNumber")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("PhoneNumberConfirmed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("SecurityStamp")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("TwoFactorEnabled")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedEmail")
|
||||
.HasDatabaseName("EmailIndex");
|
||||
|
||||
b.HasIndex("NormalizedUserName")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("UserNameIndex");
|
||||
|
||||
b.ToTable("AspNetUsers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserClaims");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ProviderKey")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ProviderDisplayName")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("LoginProvider", "ProviderKey");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserLogins");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("UserId", "RoleId");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetUserRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("UserId", "LoginProvider", "Name");
|
||||
|
||||
b.ToTable("AspNetUserTokens");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RdtClient.Data.Models.Data.Download", b =>
|
||||
{
|
||||
b.Property<Guid>("DownloadId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTimeOffset>("Added")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTimeOffset?>("Completed")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTimeOffset?>("DownloadFinished")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTimeOffset?>("DownloadQueued")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTimeOffset?>("DownloadStarted")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Error")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Link")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Path")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("RemoteId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("RetryCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<Guid>("TorrentId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTimeOffset?>("UnpackingFinished")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTimeOffset?>("UnpackingQueued")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTimeOffset?>("UnpackingStarted")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("DownloadId");
|
||||
|
||||
b.HasIndex("TorrentId");
|
||||
|
||||
b.ToTable("Downloads");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RdtClient.Data.Models.Data.Setting", b =>
|
||||
{
|
||||
b.Property<string>("SettingId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Type")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("SettingId");
|
||||
|
||||
b.ToTable("Settings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RdtClient.Data.Models.Data.Torrent", b =>
|
||||
{
|
||||
b.Property<Guid>("TorrentId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTimeOffset>("Added")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Category")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTimeOffset?>("Completed")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("DownloadAction")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("DownloadManualFiles")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("DownloadMinSize")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("FileOrMagnet")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTimeOffset?>("FilesSelected")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("FinishedAction")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Hash")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsFile")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("Priority")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTimeOffset>("RdAdded")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTimeOffset?>("RdEnded")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("RdFiles")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("RdHost")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("RdId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("RdName")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<long>("RdProgress")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<long?>("RdSeeders")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<long>("RdSize")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<long?>("RdSpeed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<long>("RdSplit")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("RdStatus")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("RdStatusRaw")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("RetryCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("TorrentId");
|
||||
|
||||
b.ToTable("Torrents");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RdtClient.Data.Models.Data.Download", b =>
|
||||
{
|
||||
b.HasOne("RdtClient.Data.Models.Data.Torrent", "Torrent")
|
||||
.WithMany("Downloads")
|
||||
.HasForeignKey("TorrentId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Torrent");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RdtClient.Data.Models.Data.Torrent", b =>
|
||||
{
|
||||
b.Navigation("Downloads");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace RdtClient.Data.Migrations
|
||||
{
|
||||
public partial class Torrents_Add_Priority : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "Priority",
|
||||
table: "Torrents",
|
||||
type: "INTEGER",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Priority",
|
||||
table: "Torrents");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -318,6 +318,9 @@ namespace RdtClient.Data.Migrations
|
|||
b.Property<bool>("IsFile")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("Priority")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTimeOffset>("RdAdded")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,8 @@ namespace RdtClient.Data.Models.Data
|
|||
|
||||
public String FileOrMagnet { get; set; }
|
||||
public Boolean IsFile { get; set; }
|
||||
|
||||
|
||||
public Int32? Priority { get; set; }
|
||||
public Int32 RetryCount { get; set; }
|
||||
|
||||
[InverseProperty("Torrent")]
|
||||
|
|
|
|||
|
|
@ -84,9 +84,31 @@ namespace RdtClient.Service.Services
|
|||
}
|
||||
}
|
||||
|
||||
public void Cancel()
|
||||
public async Task Cancel()
|
||||
{
|
||||
_downloader?.Cancel();
|
||||
if (_downloader == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
await _downloader.Cancel();
|
||||
}
|
||||
|
||||
public async Task Pause()
|
||||
{
|
||||
if (_downloader == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
await _downloader.Pause();
|
||||
}
|
||||
|
||||
public async Task Resume()
|
||||
{
|
||||
if (_downloader == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
await _downloader.Resume();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using System.Timers;
|
||||
using Aria2NET;
|
||||
|
|
@ -29,7 +30,12 @@ namespace RdtClient.Service.Services.Downloaders
|
|||
_uri = uri;
|
||||
_filePath = filePath;
|
||||
|
||||
_aria2NetClient = new Aria2NetClient(settings.Aria2cUrl, settings.Aria2cSecret);
|
||||
var httpClient = new HttpClient
|
||||
{
|
||||
Timeout = TimeSpan.FromSeconds(1)
|
||||
};
|
||||
|
||||
_aria2NetClient = new Aria2NetClient(settings.Aria2cUrl, settings.Aria2cSecret, httpClient);
|
||||
|
||||
_timer = new Timer();
|
||||
|
||||
|
|
@ -126,6 +132,40 @@ namespace RdtClient.Service.Services.Downloaders
|
|||
}
|
||||
}
|
||||
|
||||
public async Task Pause()
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(_gid))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await _aria2NetClient.Pause(_gid);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
public async Task Resume()
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(_gid))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await _aria2NetClient.Unpause(_gid);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
private async void OnTimedEvent(Object source, ElapsedEventArgs e)
|
||||
{
|
||||
if (_gid == null)
|
||||
|
|
|
|||
|
|
@ -21,5 +21,7 @@ namespace RdtClient.Service.Services.Downloaders
|
|||
event EventHandler<DownloadProgressEventArgs> DownloadProgress;
|
||||
Task<String> Download();
|
||||
Task Cancel();
|
||||
Task Pause();
|
||||
Task Resume();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,5 +124,15 @@ namespace RdtClient.Service.Services.Downloaders
|
|||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task Pause()
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task Resume()
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,5 +143,15 @@ namespace RdtClient.Service.Services.Downloaders
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
public Task Pause()
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task Resume()
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using RdtClient.Data.Data;
|
||||
using Download = RdtClient.Data.Models.Data.Download;
|
||||
|
|
@ -13,7 +14,12 @@ namespace RdtClient.Service.Services
|
|||
{
|
||||
_downloadData = downloadData;
|
||||
}
|
||||
|
||||
|
||||
public async Task<List<Download>> GetForTorrent(Guid torrentId)
|
||||
{
|
||||
return await _downloadData.GetForTorrent(torrentId);
|
||||
}
|
||||
|
||||
public async Task<Download> GetById(Guid downloadId)
|
||||
{
|
||||
return await _downloadData.GetById(downloadId);
|
||||
|
|
|
|||
|
|
@ -14,12 +14,14 @@ namespace RdtClient.Service.Services
|
|||
private readonly Authentication _authentication;
|
||||
private readonly Settings _settings;
|
||||
private readonly Torrents _torrents;
|
||||
private readonly Downloads _downloads;
|
||||
|
||||
public QBittorrent(Settings settings, Authentication authentication, Torrents torrents)
|
||||
public QBittorrent(Settings settings, Authentication authentication, Torrents torrents, Downloads downloads)
|
||||
{
|
||||
_settings = settings;
|
||||
_authentication = authentication;
|
||||
_torrents = torrents;
|
||||
_downloads = downloads;
|
||||
}
|
||||
|
||||
public async Task<Boolean> AuthLogin(String userName, String password)
|
||||
|
|
@ -291,7 +293,7 @@ namespace RdtClient.Service.Services
|
|||
Upspeed = speed
|
||||
};
|
||||
|
||||
if (torrent.Completed.HasValue)
|
||||
if (torrent.Completed.HasValue && torrent.Downloads.All(m => m.Completed.HasValue))
|
||||
{
|
||||
// Indicates completed torrent and not seeding anymore.
|
||||
result.State = "pausedUP";
|
||||
|
|
@ -329,7 +331,7 @@ namespace RdtClient.Service.Services
|
|||
return null;
|
||||
}
|
||||
|
||||
foreach (var file in torrent.Files)
|
||||
foreach (var file in torrent.Files.Where(m => m.Selected))
|
||||
{
|
||||
var result = new TorrentFileItem
|
||||
{
|
||||
|
|
@ -421,18 +423,18 @@ namespace RdtClient.Service.Services
|
|||
await _torrents.Delete(torrent.TorrentId, true, true, deleteFiles);
|
||||
}
|
||||
|
||||
public async Task TorrentsAddMagnet(String magnetLink, String category)
|
||||
public async Task TorrentsAddMagnet(String magnetLink, String category, Int32? priority)
|
||||
{
|
||||
var downloadAction = Settings.Get.OnlyDownloadAvailableFiles == 1 ? TorrentDownloadAction.DownloadAvailableFiles : TorrentDownloadAction.DownloadAll;
|
||||
|
||||
await _torrents.UploadMagnet(magnetLink, category, downloadAction, TorrentFinishedAction.None, Settings.Get.MinFileSize, null);
|
||||
await _torrents.UploadMagnet(magnetLink, category, downloadAction, TorrentFinishedAction.None, Settings.Get.MinFileSize, null, priority);
|
||||
}
|
||||
|
||||
public async Task TorrentsAddFile(Byte[] fileBytes, String category)
|
||||
public async Task TorrentsAddFile(Byte[] fileBytes, String category, Int32? priority)
|
||||
{
|
||||
var downloadAction = Settings.Get.OnlyDownloadAvailableFiles == 1 ? TorrentDownloadAction.DownloadAvailableFiles : TorrentDownloadAction.DownloadAll;
|
||||
|
||||
await _torrents.UploadFile(fileBytes, category, downloadAction, TorrentFinishedAction.None, Settings.Get.MinFileSize, null);
|
||||
await _torrents.UploadFile(fileBytes, category, downloadAction, TorrentFinishedAction.None, Settings.Get.MinFileSize, null, priority);
|
||||
}
|
||||
|
||||
public async Task TorrentsSetCategory(String hash, String category)
|
||||
|
|
@ -515,5 +517,50 @@ namespace RdtClient.Service.Services
|
|||
|
||||
await _settings.UpdateString("Categories", categoriesSetting);
|
||||
}
|
||||
|
||||
public async Task TorrentsTopPrio(String hash)
|
||||
{
|
||||
await _torrents.UpdatePriority(hash, 1);
|
||||
}
|
||||
|
||||
public async Task TorrentPause(String hash)
|
||||
{
|
||||
var torrent = await _torrents.GetByHash(hash);
|
||||
|
||||
if (torrent == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var downloads = await _downloads.GetForTorrent(torrent.TorrentId);
|
||||
|
||||
foreach (var download in downloads)
|
||||
{
|
||||
if (TorrentRunner.ActiveDownloadClients.TryGetValue(download.DownloadId, out var downloadClient))
|
||||
{
|
||||
downloadClient.Pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task TorrentResume(String hash)
|
||||
{
|
||||
var torrent = await _torrents.GetByHash(hash);
|
||||
|
||||
if (torrent == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var downloads = await _downloads.GetForTorrent(torrent.TorrentId);
|
||||
|
||||
foreach (var download in downloads)
|
||||
{
|
||||
if (TorrentRunner.ActiveDownloadClients.TryGetValue(download.DownloadId, out var downloadClient))
|
||||
{
|
||||
downloadClient.Resume();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ namespace RdtClient.Service.Services
|
|||
|
||||
_nextUpdate = DateTime.UtcNow.AddSeconds(updateTime);
|
||||
|
||||
await _torrents.Update();
|
||||
await _torrents.UpdateRdData();
|
||||
|
||||
// Re-get torrents to account for updated info
|
||||
torrents = await _torrents.Get();
|
||||
|
|
@ -297,6 +297,7 @@ namespace RdtClient.Service.Services
|
|||
if (download.Link == null)
|
||||
{
|
||||
await _downloads.UpdateError(download.DownloadId, "Download Link cannot be null");
|
||||
await _downloads.UpdateCompleted(download.DownloadId, DateTimeOffset.UtcNow);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ namespace RdtClient.Service.Services
|
|||
|
||||
if (torrent != null)
|
||||
{
|
||||
await Update(torrent);
|
||||
await UpdateRdData(torrent);
|
||||
}
|
||||
|
||||
return torrent;
|
||||
|
|
@ -106,7 +106,8 @@ namespace RdtClient.Service.Services
|
|||
TorrentDownloadAction downloadAction,
|
||||
TorrentFinishedAction finishedAction,
|
||||
Int32 downloadMinSize,
|
||||
String downloadManualFiles)
|
||||
String downloadManualFiles,
|
||||
Int32? priority)
|
||||
{
|
||||
MagnetLink magnet;
|
||||
|
||||
|
|
@ -121,7 +122,7 @@ namespace RdtClient.Service.Services
|
|||
|
||||
var rdTorrent = await GetRdNetClient().Torrents.AddMagnetAsync(magnetLink);
|
||||
|
||||
return await Add(rdTorrent.Id, magnet.InfoHash.ToHex(), category, downloadAction, finishedAction, downloadMinSize, downloadManualFiles, magnetLink, false);
|
||||
return await Add(rdTorrent.Id, magnet.InfoHash.ToHex(), category, downloadAction, finishedAction, downloadMinSize, downloadManualFiles, magnetLink, false, priority);
|
||||
}
|
||||
|
||||
public async Task<Torrent> UploadFile(Byte[] bytes,
|
||||
|
|
@ -129,7 +130,8 @@ namespace RdtClient.Service.Services
|
|||
TorrentDownloadAction downloadAction,
|
||||
TorrentFinishedAction finishedAction,
|
||||
Int32 downloadMinSize,
|
||||
String downloadManualFiles)
|
||||
String downloadManualFiles,
|
||||
Int32? priority)
|
||||
{
|
||||
MonoTorrent.Torrent torrent;
|
||||
|
||||
|
|
@ -146,7 +148,7 @@ namespace RdtClient.Service.Services
|
|||
|
||||
var rdTorrent = await GetRdNetClient().Torrents.AddFileAsync(bytes);
|
||||
|
||||
return await Add(rdTorrent.Id, torrent.InfoHash.ToHex(), category, downloadAction, finishedAction, downloadMinSize, downloadManualFiles, fileAsBase64, true);
|
||||
return await Add(rdTorrent.Id, torrent.InfoHash.ToHex(), category, downloadAction, finishedAction, downloadMinSize, downloadManualFiles, fileAsBase64, true, priority);
|
||||
}
|
||||
|
||||
public async Task<List<TorrentInstantAvailabilityFile>> GetAvailableFiles(String hash)
|
||||
|
|
@ -373,7 +375,7 @@ namespace RdtClient.Service.Services
|
|||
return profile;
|
||||
}
|
||||
|
||||
public async Task Update()
|
||||
public async Task UpdateRdData()
|
||||
{
|
||||
await RealDebridUpdateLock.WaitAsync();
|
||||
|
||||
|
|
@ -392,7 +394,7 @@ namespace RdtClient.Service.Services
|
|||
continue;
|
||||
}
|
||||
|
||||
await Update(torrent);
|
||||
await UpdateRdData(torrent);
|
||||
}
|
||||
|
||||
foreach (var torrent in torrents)
|
||||
|
|
@ -457,7 +459,7 @@ namespace RdtClient.Service.Services
|
|||
{
|
||||
var bytes = Convert.FromBase64String(torrent.FileOrMagnet);
|
||||
|
||||
newTorrent = await UploadFile(bytes, torrent.Category, torrent.DownloadAction, torrent.FinishedAction, torrent.DownloadMinSize, torrent.DownloadManualFiles);
|
||||
newTorrent = await UploadFile(bytes, torrent.Category, torrent.DownloadAction, torrent.FinishedAction, torrent.DownloadMinSize, torrent.DownloadManualFiles, torrent.Priority);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -466,7 +468,8 @@ namespace RdtClient.Service.Services
|
|||
torrent.DownloadAction,
|
||||
torrent.FinishedAction,
|
||||
torrent.DownloadMinSize,
|
||||
torrent.DownloadManualFiles);
|
||||
torrent.DownloadManualFiles,
|
||||
torrent.Priority);
|
||||
}
|
||||
|
||||
await _torrentData.UpdateRetryCount(newTorrent.TorrentId, newRetryCount);
|
||||
|
|
@ -527,6 +530,18 @@ namespace RdtClient.Service.Services
|
|||
await _torrentData.UpdateFilesSelected(torrentId, datetime);
|
||||
}
|
||||
|
||||
public async Task UpdatePriority(String hash, Int32 priority)
|
||||
{
|
||||
var torrent = await _torrentData.GetByHash(hash);
|
||||
|
||||
if (torrent == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await _torrentData.UpdatePriority(torrent.TorrentId, priority);
|
||||
}
|
||||
|
||||
public async Task<Torrent> GetById(Guid torrentId)
|
||||
{
|
||||
var torrent = await _torrentData.GetById(torrentId);
|
||||
|
|
@ -536,7 +551,7 @@ namespace RdtClient.Service.Services
|
|||
return null;
|
||||
}
|
||||
|
||||
await Update(torrent);
|
||||
await UpdateRdData(torrent);
|
||||
|
||||
foreach (var download in torrent.Downloads)
|
||||
{
|
||||
|
|
@ -577,7 +592,8 @@ namespace RdtClient.Service.Services
|
|||
Int32 downloadMinSize,
|
||||
String downloadManualFiles,
|
||||
String fileOrMagnetContents,
|
||||
Boolean isFile)
|
||||
Boolean isFile,
|
||||
Int32? priority)
|
||||
{
|
||||
await RealDebridUpdateLock.WaitAsync();
|
||||
|
||||
|
|
@ -598,9 +614,10 @@ namespace RdtClient.Service.Services
|
|||
downloadMinSize,
|
||||
downloadManualFiles,
|
||||
fileOrMagnetContents,
|
||||
isFile);
|
||||
isFile,
|
||||
priority);
|
||||
|
||||
await Update(newTorrent);
|
||||
await UpdateRdData(newTorrent);
|
||||
|
||||
return newTorrent;
|
||||
}
|
||||
|
|
@ -609,8 +626,13 @@ namespace RdtClient.Service.Services
|
|||
RealDebridUpdateLock.Release();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task Update(Torrent torrent)
|
||||
{
|
||||
await _torrentData.Update(torrent);
|
||||
}
|
||||
|
||||
private async Task Update(Torrent torrent)
|
||||
private async Task UpdateRdData(Torrent torrent)
|
||||
{
|
||||
var originalTorrent = JsonConvert.SerializeObject(torrent,
|
||||
new JsonSerializerSettings
|
||||
|
|
|
|||
|
|
@ -190,21 +190,49 @@ namespace RdtClient.Web.Controllers
|
|||
[Authorize]
|
||||
[Route("torrents/pause")]
|
||||
[HttpGet]
|
||||
[HttpPost]
|
||||
public ActionResult TorrentsPause()
|
||||
public async Task<ActionResult> TorrentsPause([FromQuery] QBTorrentsHashesRequest request)
|
||||
{
|
||||
var hashes = request.Hashes.Split("|");
|
||||
|
||||
foreach (var hash in hashes)
|
||||
{
|
||||
await _qBittorrent.TorrentPause(hash);
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
[Route("torrents/topPrio")]
|
||||
[HttpPost]
|
||||
public async Task<ActionResult> TorrentsPausePost([FromForm] QBTorrentsHashesRequest request)
|
||||
{
|
||||
return await TorrentsPause(request);
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
[Route("torrents/resume")]
|
||||
[HttpGet]
|
||||
[HttpPost]
|
||||
public ActionResult TorrentsResume()
|
||||
public async Task<ActionResult> TorrentsResume([FromQuery] QBTorrentsHashesRequest request)
|
||||
{
|
||||
var hashes = request.Hashes.Split("|");
|
||||
|
||||
foreach (var hash in hashes)
|
||||
{
|
||||
await _qBittorrent.TorrentResume(hash);
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
[Route("torrents/topPrio")]
|
||||
[HttpPost]
|
||||
public async Task<ActionResult> TorrentsResumePost([FromForm] QBTorrentsHashesRequest request)
|
||||
{
|
||||
return await TorrentsResume(request);
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
[Route("torrents/setShareLimits")]
|
||||
[HttpGet]
|
||||
|
|
@ -248,13 +276,13 @@ namespace RdtClient.Web.Controllers
|
|||
{
|
||||
if (url.StartsWith("magnet"))
|
||||
{
|
||||
await _qBittorrent.TorrentsAddMagnet(url.Trim(), request.Category);
|
||||
await _qBittorrent.TorrentsAddMagnet(url.Trim(), request.Category, null);
|
||||
}
|
||||
else if (url.StartsWith("http"))
|
||||
{
|
||||
var httpClient = new HttpClient();
|
||||
var result = await httpClient.GetByteArrayAsync(url);
|
||||
await _qBittorrent.TorrentsAddFile(result, request.Category);
|
||||
await _qBittorrent.TorrentsAddFile(result, request.Category, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -279,7 +307,7 @@ namespace RdtClient.Web.Controllers
|
|||
await file.CopyToAsync(target);
|
||||
var fileBytes = target.ToArray();
|
||||
|
||||
await _qBittorrent.TorrentsAddFile(fileBytes, request.Category);
|
||||
await _qBittorrent.TorrentsAddFile(fileBytes, request.Category, request.Priority);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -370,6 +398,29 @@ namespace RdtClient.Web.Controllers
|
|||
{
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
[Route("torrents/topPrio")]
|
||||
[HttpGet]
|
||||
public async Task<ActionResult> TorrentsTopPrio([FromQuery] QBTorrentsHashesRequest request)
|
||||
{
|
||||
var hashes = request.Hashes.Split("|");
|
||||
|
||||
foreach (var hash in hashes)
|
||||
{
|
||||
await _qBittorrent.TorrentsTopPrio(hash);
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
[Route("torrents/topPrio")]
|
||||
[HttpPost]
|
||||
public async Task<ActionResult> TorrentsTopPrioPost([FromForm] QBTorrentsHashesRequest request)
|
||||
{
|
||||
return await TorrentsTopPrio(request);
|
||||
}
|
||||
}
|
||||
|
||||
public class QBAuthLoginRequest
|
||||
|
|
@ -393,6 +444,7 @@ namespace RdtClient.Web.Controllers
|
|||
{
|
||||
public String Urls { get; set; }
|
||||
public String Category { get; set; }
|
||||
public Int32? Priority { get; set; }
|
||||
}
|
||||
|
||||
public class QBTorrentsSetCategoryRequest
|
||||
|
|
@ -410,4 +462,9 @@ namespace RdtClient.Web.Controllers
|
|||
{
|
||||
public String Categories { get; set; }
|
||||
}
|
||||
|
||||
public class QBTorrentsHashesRequest
|
||||
{
|
||||
public String Hashes { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -91,7 +91,7 @@ namespace RdtClient.Web.Controllers
|
|||
|
||||
var bytes = memoryStream.ToArray();
|
||||
|
||||
await _torrents.UploadFile(bytes, formData.Category, formData.DownloadAction, formData.FinishedAction, formData.DownloadMinSize, formData.DownloadManualFiles);
|
||||
await _torrents.UploadFile(bytes, formData.Category, formData.DownloadAction, formData.FinishedAction, formData.DownloadMinSize, formData.DownloadManualFiles, formData.Priority);
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
|
@ -105,7 +105,8 @@ namespace RdtClient.Web.Controllers
|
|||
request.DownloadAction,
|
||||
request.FinishedAction,
|
||||
request.DownloadMinSize,
|
||||
request.DownloadManualFiles);
|
||||
request.DownloadManualFiles,
|
||||
request.Priority);
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
|
@ -171,6 +172,15 @@ namespace RdtClient.Web.Controllers
|
|||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[Route("Update")]
|
||||
public async Task<ActionResult> Update([FromBody] Torrent torrent)
|
||||
{
|
||||
await _torrents.Update(torrent);
|
||||
|
||||
return Ok();
|
||||
}
|
||||
}
|
||||
|
||||
public class TorrentControllerUploadFileRequest
|
||||
|
|
@ -180,6 +190,7 @@ namespace RdtClient.Web.Controllers
|
|||
public TorrentFinishedAction FinishedAction { get; set; }
|
||||
public Int32 DownloadMinSize { get; set; }
|
||||
public String DownloadManualFiles { get; set; }
|
||||
public Int32? Priority { get; set; }
|
||||
}
|
||||
|
||||
public class TorrentControllerUploadMagnetRequest
|
||||
|
|
@ -190,6 +201,7 @@ namespace RdtClient.Web.Controllers
|
|||
public TorrentFinishedAction FinishedAction { get; set; }
|
||||
public Int32 DownloadMinSize { get; set; }
|
||||
public String DownloadManualFiles { get; set; }
|
||||
public Int32? Priority { get; set; }
|
||||
}
|
||||
|
||||
public class TorrentControllerDeleteRequest
|
||||
|
|
|
|||
Loading…
Reference in a new issue