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"
|
[(ngModel)]="magnetLink"
|
||||||
[disabled]="saving"
|
[disabled]="saving"
|
||||||
(blur)="checkFiles()"
|
(blur)="checkFiles()"
|
||||||
|
(paste)="onPaste()"
|
||||||
></textarea>
|
></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -79,6 +80,16 @@
|
||||||
</div>
|
</div>
|
||||||
<p class="help">The category becomes a sub-folder in your main download path.</p>
|
<p class="help">The category becomes a sub-folder in your main download path.</p>
|
||||||
</div>
|
</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>
|
||||||
<div fxFlex>
|
<div fxFlex>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ export class AddNewTorrentComponent implements OnInit {
|
||||||
private currentTorrentFile: string;
|
private currentTorrentFile: string;
|
||||||
|
|
||||||
public category: string;
|
public category: string;
|
||||||
|
public priority: number;
|
||||||
|
|
||||||
public downloadAction: number = 0;
|
public downloadAction: number = 0;
|
||||||
public finishedAction: number = 0;
|
public finishedAction: number = 0;
|
||||||
|
|
@ -98,7 +99,8 @@ export class AddNewTorrentComponent implements OnInit {
|
||||||
this.downloadAction,
|
this.downloadAction,
|
||||||
this.finishedAction,
|
this.finishedAction,
|
||||||
this.downloadMinSize,
|
this.downloadMinSize,
|
||||||
downloadManualFiles
|
downloadManualFiles,
|
||||||
|
this.priority
|
||||||
)
|
)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
() => {
|
() => {
|
||||||
|
|
@ -117,7 +119,8 @@ export class AddNewTorrentComponent implements OnInit {
|
||||||
this.downloadAction,
|
this.downloadAction,
|
||||||
this.finishedAction,
|
this.finishedAction,
|
||||||
this.downloadMinSize,
|
this.downloadMinSize,
|
||||||
downloadManualFiles
|
downloadManualFiles,
|
||||||
|
this.priority
|
||||||
)
|
)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
() => {
|
() => {
|
||||||
|
|
@ -134,6 +137,12 @@ export class AddNewTorrentComponent implements OnInit {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public onPaste(): void {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.checkFiles();
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
|
||||||
public checkFiles(): void {
|
public checkFiles(): void {
|
||||||
if (this.magnetLink && this.magnetLink === this.currentTorrentFile) {
|
if (this.magnetLink && this.magnetLink === this.currentTorrentFile) {
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ export class Torrent {
|
||||||
public isFile: boolean;
|
public isFile: boolean;
|
||||||
|
|
||||||
public retryCount: number;
|
public retryCount: number;
|
||||||
|
public priority: number;
|
||||||
|
|
||||||
public rdId: string;
|
public rdId: string;
|
||||||
public rdName: string;
|
public rdName: string;
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
<tr>
|
<tr>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th>Category</th>
|
<th>Category</th>
|
||||||
|
<th>Priority</th>
|
||||||
<th>Files</th>
|
<th>Files</th>
|
||||||
<th>Downloads</th>
|
<th>Downloads</th>
|
||||||
<th>Size</th>
|
<th>Size</th>
|
||||||
|
|
@ -22,6 +23,9 @@
|
||||||
<td>
|
<td>
|
||||||
{{ torrent.category }}
|
{{ torrent.category }}
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ torrent.priority }}
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{ torrent.files.length | number }}
|
{{ torrent.files.length | number }}
|
||||||
</td>
|
</td>
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,8 @@ export class TorrentService {
|
||||||
downloadAction: number,
|
downloadAction: number,
|
||||||
finishedAction: number,
|
finishedAction: number,
|
||||||
downloadMinSize: number,
|
downloadMinSize: number,
|
||||||
downloadManualFiles: string
|
downloadManualFiles: string,
|
||||||
|
priority: number
|
||||||
): Observable<void> {
|
): Observable<void> {
|
||||||
return this.http.post<void>(`/Api/Torrents/UploadMagnet`, {
|
return this.http.post<void>(`/Api/Torrents/UploadMagnet`, {
|
||||||
magnetLink,
|
magnetLink,
|
||||||
|
|
@ -52,6 +53,7 @@ export class TorrentService {
|
||||||
finishedAction,
|
finishedAction,
|
||||||
downloadMinSize,
|
downloadMinSize,
|
||||||
downloadManualFiles,
|
downloadManualFiles,
|
||||||
|
priority,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,13 +63,14 @@ export class TorrentService {
|
||||||
downloadAction: number,
|
downloadAction: number,
|
||||||
finishedAction: number,
|
finishedAction: number,
|
||||||
downloadMinSize: number,
|
downloadMinSize: number,
|
||||||
downloadManualFiles: string
|
downloadManualFiles: string,
|
||||||
|
priority: number
|
||||||
): Observable<void> {
|
): Observable<void> {
|
||||||
const formData: FormData = new FormData();
|
const formData: FormData = new FormData();
|
||||||
formData.append('file', file);
|
formData.append('file', file);
|
||||||
formData.append(
|
formData.append(
|
||||||
'formData',
|
'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);
|
return this.http.post<void>(`/Api/Torrents/UploadFile`, formData);
|
||||||
}
|
}
|
||||||
|
|
@ -104,4 +107,8 @@ export class TorrentService {
|
||||||
public retryDownload(downloadId: string): Observable<void> {
|
public retryDownload(downloadId: string): Observable<void> {
|
||||||
return this.http.post<void>(`/Api/Torrents/RetryDownload/${downloadId}`, {});
|
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">
|
<div class="control">
|
||||||
<button class="button is-primary" (click)="showRetryModal()">Retry Torrent</button>
|
<button class="button is-primary" (click)="showRetryModal()">Retry Torrent</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="control">
|
||||||
|
<button class="button is-light" (click)="showUpdateSettingsModal()">Change priority</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label">Status</label>
|
<label class="label">Status</label>
|
||||||
|
|
@ -40,6 +43,10 @@
|
||||||
<label class="label">Hash</label>
|
<label class="label">Hash</label>
|
||||||
{{ torrent.hash }}
|
{{ torrent.hash }}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label class="label">Priority</label>
|
||||||
|
{{ torrent.priority || "" }}
|
||||||
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label">Category</label>
|
<label class="label">Category</label>
|
||||||
{{ torrent.category || "(no category set)" }}
|
{{ torrent.category || "(no category set)" }}
|
||||||
|
|
@ -445,3 +452,42 @@
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
</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 downloadRetrying: boolean;
|
||||||
public downloadRetryId: string;
|
public downloadRetryId: string;
|
||||||
|
|
||||||
|
public isUpdateSettingsModalActive: boolean;
|
||||||
|
public updateSettingsPriority: number;
|
||||||
|
public updating: boolean;
|
||||||
|
|
||||||
constructor(private activatedRoute: ActivatedRoute, private router: Router, private torrentService: TorrentService) {}
|
constructor(private activatedRoute: ActivatedRoute, private router: Router, private torrentService: TorrentService) {}
|
||||||
|
|
||||||
ngOnInit(): void {
|
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;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
@ -15,6 +16,14 @@ namespace RdtClient.Data.Data
|
||||||
_dataContext = dataContext;
|
_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)
|
public async Task<Download> GetById(Guid downloadId)
|
||||||
{
|
{
|
||||||
return await _dataContext.Downloads
|
return await _dataContext.Downloads
|
||||||
|
|
|
||||||
|
|
@ -27,15 +27,12 @@ namespace RdtClient.Data.Data
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (_torrentCache == null)
|
_torrentCache ??= await _dataContext.Torrents
|
||||||
{
|
.AsNoTracking()
|
||||||
_torrentCache = await _dataContext.Torrents
|
.Include(m => m.Downloads)
|
||||||
.AsNoTracking()
|
.ToListAsync();
|
||||||
.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
|
finally
|
||||||
{
|
{
|
||||||
|
|
@ -91,7 +88,8 @@ namespace RdtClient.Data.Data
|
||||||
Int32 downloadMinSize,
|
Int32 downloadMinSize,
|
||||||
String downloadManualFiles,
|
String downloadManualFiles,
|
||||||
String fileOrMagnetContents,
|
String fileOrMagnetContents,
|
||||||
Boolean isFile)
|
Boolean isFile,
|
||||||
|
Int32? priority)
|
||||||
{
|
{
|
||||||
var torrent = new Torrent
|
var torrent = new Torrent
|
||||||
{
|
{
|
||||||
|
|
@ -105,7 +103,8 @@ namespace RdtClient.Data.Data
|
||||||
DownloadMinSize = downloadMinSize,
|
DownloadMinSize = downloadMinSize,
|
||||||
DownloadManualFiles = downloadManualFiles,
|
DownloadManualFiles = downloadManualFiles,
|
||||||
FileOrMagnet = fileOrMagnetContents,
|
FileOrMagnet = fileOrMagnetContents,
|
||||||
IsFile = isFile
|
IsFile = isFile,
|
||||||
|
Priority = priority
|
||||||
};
|
};
|
||||||
|
|
||||||
await _dataContext.Torrents.AddAsync(torrent);
|
await _dataContext.Torrents.AddAsync(torrent);
|
||||||
|
|
@ -148,6 +147,22 @@ namespace RdtClient.Data.Data
|
||||||
await VoidCache();
|
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)
|
public async Task UpdateCategory(Guid torrentId, String category)
|
||||||
{
|
{
|
||||||
var dbTorrent = await _dataContext.Torrents.FirstOrDefaultAsync(m => m.TorrentId == torrentId);
|
var dbTorrent = await _dataContext.Torrents.FirstOrDefaultAsync(m => m.TorrentId == torrentId);
|
||||||
|
|
@ -212,6 +227,22 @@ namespace RdtClient.Data.Data
|
||||||
await VoidCache();
|
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)
|
public async Task Delete(Guid torrentId)
|
||||||
{
|
{
|
||||||
var dbTorrent = await _dataContext.Torrents.FirstOrDefaultAsync(m => m.TorrentId == 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")
|
b.Property<bool>("IsFile")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int?>("Priority")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("RdAdded")
|
b.Property<DateTimeOffset>("RdAdded")
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ namespace RdtClient.Data.Models.Data
|
||||||
public String FileOrMagnet { get; set; }
|
public String FileOrMagnet { get; set; }
|
||||||
public Boolean IsFile { get; set; }
|
public Boolean IsFile { get; set; }
|
||||||
|
|
||||||
|
public Int32? Priority { get; set; }
|
||||||
public Int32 RetryCount { get; set; }
|
public Int32 RetryCount { get; set; }
|
||||||
|
|
||||||
[InverseProperty("Torrent")]
|
[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;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Timers;
|
using System.Timers;
|
||||||
using Aria2NET;
|
using Aria2NET;
|
||||||
|
|
@ -29,7 +30,12 @@ namespace RdtClient.Service.Services.Downloaders
|
||||||
_uri = uri;
|
_uri = uri;
|
||||||
_filePath = filePath;
|
_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();
|
_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)
|
private async void OnTimedEvent(Object source, ElapsedEventArgs e)
|
||||||
{
|
{
|
||||||
if (_gid == null)
|
if (_gid == null)
|
||||||
|
|
|
||||||
|
|
@ -21,5 +21,7 @@ namespace RdtClient.Service.Services.Downloaders
|
||||||
event EventHandler<DownloadProgressEventArgs> DownloadProgress;
|
event EventHandler<DownloadProgressEventArgs> DownloadProgress;
|
||||||
Task<String> Download();
|
Task<String> Download();
|
||||||
Task Cancel();
|
Task Cancel();
|
||||||
|
Task Pause();
|
||||||
|
Task Resume();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -124,5 +124,15 @@ namespace RdtClient.Service.Services.Downloaders
|
||||||
|
|
||||||
return Task.CompletedTask;
|
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;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using RdtClient.Data.Data;
|
using RdtClient.Data.Data;
|
||||||
using Download = RdtClient.Data.Models.Data.Download;
|
using Download = RdtClient.Data.Models.Data.Download;
|
||||||
|
|
@ -14,6 +15,11 @@ namespace RdtClient.Service.Services
|
||||||
_downloadData = downloadData;
|
_downloadData = downloadData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<List<Download>> GetForTorrent(Guid torrentId)
|
||||||
|
{
|
||||||
|
return await _downloadData.GetForTorrent(torrentId);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<Download> GetById(Guid downloadId)
|
public async Task<Download> GetById(Guid downloadId)
|
||||||
{
|
{
|
||||||
return await _downloadData.GetById(downloadId);
|
return await _downloadData.GetById(downloadId);
|
||||||
|
|
|
||||||
|
|
@ -14,12 +14,14 @@ namespace RdtClient.Service.Services
|
||||||
private readonly Authentication _authentication;
|
private readonly Authentication _authentication;
|
||||||
private readonly Settings _settings;
|
private readonly Settings _settings;
|
||||||
private readonly Torrents _torrents;
|
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;
|
_settings = settings;
|
||||||
_authentication = authentication;
|
_authentication = authentication;
|
||||||
_torrents = torrents;
|
_torrents = torrents;
|
||||||
|
_downloads = downloads;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Boolean> AuthLogin(String userName, String password)
|
public async Task<Boolean> AuthLogin(String userName, String password)
|
||||||
|
|
@ -291,7 +293,7 @@ namespace RdtClient.Service.Services
|
||||||
Upspeed = speed
|
Upspeed = speed
|
||||||
};
|
};
|
||||||
|
|
||||||
if (torrent.Completed.HasValue)
|
if (torrent.Completed.HasValue && torrent.Downloads.All(m => m.Completed.HasValue))
|
||||||
{
|
{
|
||||||
// Indicates completed torrent and not seeding anymore.
|
// Indicates completed torrent and not seeding anymore.
|
||||||
result.State = "pausedUP";
|
result.State = "pausedUP";
|
||||||
|
|
@ -329,7 +331,7 @@ namespace RdtClient.Service.Services
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var file in torrent.Files)
|
foreach (var file in torrent.Files.Where(m => m.Selected))
|
||||||
{
|
{
|
||||||
var result = new TorrentFileItem
|
var result = new TorrentFileItem
|
||||||
{
|
{
|
||||||
|
|
@ -421,18 +423,18 @@ namespace RdtClient.Service.Services
|
||||||
await _torrents.Delete(torrent.TorrentId, true, true, deleteFiles);
|
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;
|
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;
|
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)
|
public async Task TorrentsSetCategory(String hash, String category)
|
||||||
|
|
@ -515,5 +517,50 @@ namespace RdtClient.Service.Services
|
||||||
|
|
||||||
await _settings.UpdateString("Categories", categoriesSetting);
|
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);
|
_nextUpdate = DateTime.UtcNow.AddSeconds(updateTime);
|
||||||
|
|
||||||
await _torrents.Update();
|
await _torrents.UpdateRdData();
|
||||||
|
|
||||||
// Re-get torrents to account for updated info
|
// Re-get torrents to account for updated info
|
||||||
torrents = await _torrents.Get();
|
torrents = await _torrents.Get();
|
||||||
|
|
@ -297,6 +297,7 @@ namespace RdtClient.Service.Services
|
||||||
if (download.Link == null)
|
if (download.Link == null)
|
||||||
{
|
{
|
||||||
await _downloads.UpdateError(download.DownloadId, "Download Link cannot be null");
|
await _downloads.UpdateError(download.DownloadId, "Download Link cannot be null");
|
||||||
|
await _downloads.UpdateCompleted(download.DownloadId, DateTimeOffset.UtcNow);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ namespace RdtClient.Service.Services
|
||||||
|
|
||||||
if (torrent != null)
|
if (torrent != null)
|
||||||
{
|
{
|
||||||
await Update(torrent);
|
await UpdateRdData(torrent);
|
||||||
}
|
}
|
||||||
|
|
||||||
return torrent;
|
return torrent;
|
||||||
|
|
@ -106,7 +106,8 @@ namespace RdtClient.Service.Services
|
||||||
TorrentDownloadAction downloadAction,
|
TorrentDownloadAction downloadAction,
|
||||||
TorrentFinishedAction finishedAction,
|
TorrentFinishedAction finishedAction,
|
||||||
Int32 downloadMinSize,
|
Int32 downloadMinSize,
|
||||||
String downloadManualFiles)
|
String downloadManualFiles,
|
||||||
|
Int32? priority)
|
||||||
{
|
{
|
||||||
MagnetLink magnet;
|
MagnetLink magnet;
|
||||||
|
|
||||||
|
|
@ -121,7 +122,7 @@ namespace RdtClient.Service.Services
|
||||||
|
|
||||||
var rdTorrent = await GetRdNetClient().Torrents.AddMagnetAsync(magnetLink);
|
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,
|
public async Task<Torrent> UploadFile(Byte[] bytes,
|
||||||
|
|
@ -129,7 +130,8 @@ namespace RdtClient.Service.Services
|
||||||
TorrentDownloadAction downloadAction,
|
TorrentDownloadAction downloadAction,
|
||||||
TorrentFinishedAction finishedAction,
|
TorrentFinishedAction finishedAction,
|
||||||
Int32 downloadMinSize,
|
Int32 downloadMinSize,
|
||||||
String downloadManualFiles)
|
String downloadManualFiles,
|
||||||
|
Int32? priority)
|
||||||
{
|
{
|
||||||
MonoTorrent.Torrent torrent;
|
MonoTorrent.Torrent torrent;
|
||||||
|
|
||||||
|
|
@ -146,7 +148,7 @@ namespace RdtClient.Service.Services
|
||||||
|
|
||||||
var rdTorrent = await GetRdNetClient().Torrents.AddFileAsync(bytes);
|
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)
|
public async Task<List<TorrentInstantAvailabilityFile>> GetAvailableFiles(String hash)
|
||||||
|
|
@ -373,7 +375,7 @@ namespace RdtClient.Service.Services
|
||||||
return profile;
|
return profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Update()
|
public async Task UpdateRdData()
|
||||||
{
|
{
|
||||||
await RealDebridUpdateLock.WaitAsync();
|
await RealDebridUpdateLock.WaitAsync();
|
||||||
|
|
||||||
|
|
@ -392,7 +394,7 @@ namespace RdtClient.Service.Services
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
await Update(torrent);
|
await UpdateRdData(torrent);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var torrent in torrents)
|
foreach (var torrent in torrents)
|
||||||
|
|
@ -457,7 +459,7 @@ namespace RdtClient.Service.Services
|
||||||
{
|
{
|
||||||
var bytes = Convert.FromBase64String(torrent.FileOrMagnet);
|
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
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -466,7 +468,8 @@ namespace RdtClient.Service.Services
|
||||||
torrent.DownloadAction,
|
torrent.DownloadAction,
|
||||||
torrent.FinishedAction,
|
torrent.FinishedAction,
|
||||||
torrent.DownloadMinSize,
|
torrent.DownloadMinSize,
|
||||||
torrent.DownloadManualFiles);
|
torrent.DownloadManualFiles,
|
||||||
|
torrent.Priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
await _torrentData.UpdateRetryCount(newTorrent.TorrentId, newRetryCount);
|
await _torrentData.UpdateRetryCount(newTorrent.TorrentId, newRetryCount);
|
||||||
|
|
@ -527,6 +530,18 @@ namespace RdtClient.Service.Services
|
||||||
await _torrentData.UpdateFilesSelected(torrentId, datetime);
|
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)
|
public async Task<Torrent> GetById(Guid torrentId)
|
||||||
{
|
{
|
||||||
var torrent = await _torrentData.GetById(torrentId);
|
var torrent = await _torrentData.GetById(torrentId);
|
||||||
|
|
@ -536,7 +551,7 @@ namespace RdtClient.Service.Services
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
await Update(torrent);
|
await UpdateRdData(torrent);
|
||||||
|
|
||||||
foreach (var download in torrent.Downloads)
|
foreach (var download in torrent.Downloads)
|
||||||
{
|
{
|
||||||
|
|
@ -577,7 +592,8 @@ namespace RdtClient.Service.Services
|
||||||
Int32 downloadMinSize,
|
Int32 downloadMinSize,
|
||||||
String downloadManualFiles,
|
String downloadManualFiles,
|
||||||
String fileOrMagnetContents,
|
String fileOrMagnetContents,
|
||||||
Boolean isFile)
|
Boolean isFile,
|
||||||
|
Int32? priority)
|
||||||
{
|
{
|
||||||
await RealDebridUpdateLock.WaitAsync();
|
await RealDebridUpdateLock.WaitAsync();
|
||||||
|
|
||||||
|
|
@ -598,9 +614,10 @@ namespace RdtClient.Service.Services
|
||||||
downloadMinSize,
|
downloadMinSize,
|
||||||
downloadManualFiles,
|
downloadManualFiles,
|
||||||
fileOrMagnetContents,
|
fileOrMagnetContents,
|
||||||
isFile);
|
isFile,
|
||||||
|
priority);
|
||||||
|
|
||||||
await Update(newTorrent);
|
await UpdateRdData(newTorrent);
|
||||||
|
|
||||||
return newTorrent;
|
return newTorrent;
|
||||||
}
|
}
|
||||||
|
|
@ -610,7 +627,12 @@ namespace RdtClient.Service.Services
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Update(Torrent torrent)
|
public async Task Update(Torrent torrent)
|
||||||
|
{
|
||||||
|
await _torrentData.Update(torrent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task UpdateRdData(Torrent torrent)
|
||||||
{
|
{
|
||||||
var originalTorrent = JsonConvert.SerializeObject(torrent,
|
var originalTorrent = JsonConvert.SerializeObject(torrent,
|
||||||
new JsonSerializerSettings
|
new JsonSerializerSettings
|
||||||
|
|
|
||||||
|
|
@ -190,21 +190,49 @@ namespace RdtClient.Web.Controllers
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[Route("torrents/pause")]
|
[Route("torrents/pause")]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[HttpPost]
|
public async Task<ActionResult> TorrentsPause([FromQuery] QBTorrentsHashesRequest request)
|
||||||
public ActionResult TorrentsPause()
|
|
||||||
{
|
{
|
||||||
|
var hashes = request.Hashes.Split("|");
|
||||||
|
|
||||||
|
foreach (var hash in hashes)
|
||||||
|
{
|
||||||
|
await _qBittorrent.TorrentPause(hash);
|
||||||
|
}
|
||||||
|
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Authorize]
|
||||||
|
[Route("torrents/topPrio")]
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<ActionResult> TorrentsPausePost([FromForm] QBTorrentsHashesRequest request)
|
||||||
|
{
|
||||||
|
return await TorrentsPause(request);
|
||||||
|
}
|
||||||
|
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[Route("torrents/resume")]
|
[Route("torrents/resume")]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[HttpPost]
|
public async Task<ActionResult> TorrentsResume([FromQuery] QBTorrentsHashesRequest request)
|
||||||
public ActionResult TorrentsResume()
|
|
||||||
{
|
{
|
||||||
|
var hashes = request.Hashes.Split("|");
|
||||||
|
|
||||||
|
foreach (var hash in hashes)
|
||||||
|
{
|
||||||
|
await _qBittorrent.TorrentResume(hash);
|
||||||
|
}
|
||||||
|
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Authorize]
|
||||||
|
[Route("torrents/topPrio")]
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<ActionResult> TorrentsResumePost([FromForm] QBTorrentsHashesRequest request)
|
||||||
|
{
|
||||||
|
return await TorrentsResume(request);
|
||||||
|
}
|
||||||
|
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[Route("torrents/setShareLimits")]
|
[Route("torrents/setShareLimits")]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
|
|
@ -248,13 +276,13 @@ namespace RdtClient.Web.Controllers
|
||||||
{
|
{
|
||||||
if (url.StartsWith("magnet"))
|
if (url.StartsWith("magnet"))
|
||||||
{
|
{
|
||||||
await _qBittorrent.TorrentsAddMagnet(url.Trim(), request.Category);
|
await _qBittorrent.TorrentsAddMagnet(url.Trim(), request.Category, null);
|
||||||
}
|
}
|
||||||
else if (url.StartsWith("http"))
|
else if (url.StartsWith("http"))
|
||||||
{
|
{
|
||||||
var httpClient = new HttpClient();
|
var httpClient = new HttpClient();
|
||||||
var result = await httpClient.GetByteArrayAsync(url);
|
var result = await httpClient.GetByteArrayAsync(url);
|
||||||
await _qBittorrent.TorrentsAddFile(result, request.Category);
|
await _qBittorrent.TorrentsAddFile(result, request.Category, null);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -279,7 +307,7 @@ namespace RdtClient.Web.Controllers
|
||||||
await file.CopyToAsync(target);
|
await file.CopyToAsync(target);
|
||||||
var fileBytes = target.ToArray();
|
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();
|
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
|
public class QBAuthLoginRequest
|
||||||
|
|
@ -393,6 +444,7 @@ namespace RdtClient.Web.Controllers
|
||||||
{
|
{
|
||||||
public String Urls { get; set; }
|
public String Urls { get; set; }
|
||||||
public String Category { get; set; }
|
public String Category { get; set; }
|
||||||
|
public Int32? Priority { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class QBTorrentsSetCategoryRequest
|
public class QBTorrentsSetCategoryRequest
|
||||||
|
|
@ -410,4 +462,9 @@ namespace RdtClient.Web.Controllers
|
||||||
{
|
{
|
||||||
public String Categories { get; set; }
|
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();
|
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();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
@ -105,7 +105,8 @@ namespace RdtClient.Web.Controllers
|
||||||
request.DownloadAction,
|
request.DownloadAction,
|
||||||
request.FinishedAction,
|
request.FinishedAction,
|
||||||
request.DownloadMinSize,
|
request.DownloadMinSize,
|
||||||
request.DownloadManualFiles);
|
request.DownloadManualFiles,
|
||||||
|
request.Priority);
|
||||||
|
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
@ -171,6 +172,15 @@ namespace RdtClient.Web.Controllers
|
||||||
|
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPut]
|
||||||
|
[Route("Update")]
|
||||||
|
public async Task<ActionResult> Update([FromBody] Torrent torrent)
|
||||||
|
{
|
||||||
|
await _torrents.Update(torrent);
|
||||||
|
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TorrentControllerUploadFileRequest
|
public class TorrentControllerUploadFileRequest
|
||||||
|
|
@ -180,6 +190,7 @@ namespace RdtClient.Web.Controllers
|
||||||
public TorrentFinishedAction FinishedAction { get; set; }
|
public TorrentFinishedAction FinishedAction { get; set; }
|
||||||
public Int32 DownloadMinSize { get; set; }
|
public Int32 DownloadMinSize { get; set; }
|
||||||
public String DownloadManualFiles { get; set; }
|
public String DownloadManualFiles { get; set; }
|
||||||
|
public Int32? Priority { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TorrentControllerUploadMagnetRequest
|
public class TorrentControllerUploadMagnetRequest
|
||||||
|
|
@ -190,6 +201,7 @@ namespace RdtClient.Web.Controllers
|
||||||
public TorrentFinishedAction FinishedAction { get; set; }
|
public TorrentFinishedAction FinishedAction { get; set; }
|
||||||
public Int32 DownloadMinSize { get; set; }
|
public Int32 DownloadMinSize { get; set; }
|
||||||
public String DownloadManualFiles { get; set; }
|
public String DownloadManualFiles { get; set; }
|
||||||
|
public Int32? Priority { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TorrentControllerDeleteRequest
|
public class TorrentControllerDeleteRequest
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue