Improved statuses, add more actions.

This commit is contained in:
Roger Far 2021-01-10 15:59:44 -07:00
parent a27bd37991
commit 8f35952f90
11 changed files with 115 additions and 52 deletions

View file

@ -2,15 +2,32 @@
<td> <td>
{{ torrent.rdSize | filesize }} {{ torrent.rdSize | filesize }}
</td> </td>
<td>
{{ torrent.files.length | number }}
</td>
<td>
{{ torrent.downloads.length | number }}
</td>
<td class="auto">
<i class="fas fa-download" *ngIf="!torrent.autoDownload" title="Auto download"></i>
<i class="fas fa-box-open" *ngIf="!torrent.autoUnpack" title="Auto unpack"></i>
<i class="fas fa-trash" *ngIf="!torrent.autoDelete" title="Auto delete"></i>
</td>
<td> <td>
{{ torrent | status }} {{ torrent | status }}
</td> </td>
<td> <td>
<span class="icon download-icon" (click)="download($event)" title="Download to disk" *ngIf="!loading"> <span
class="icon download-icon"
(click)="download($event)"
title="Download to disk"
*ngIf="!loading && canDownload()"
>
<i class="fas fa-download"></i> <i class="fas fa-download"></i>
</span> </span>
</td> <span class="icon download-icon" (click)="unpack($event)" title="Unpack" *ngIf="!loading && canUnpack()">
<td> <i class="fas fa-box-open"></i>
</span>
<span class="icon delete-icon" (click)="delete1($event)" title="Delete torrent" *ngIf="!loading"> <span class="icon delete-icon" (click)="delete1($event)" title="Delete torrent" *ngIf="!loading">
<i class="fas fa-times"></i> <i class="fas fa-times"></i>
</span> </span>

View file

@ -2,3 +2,7 @@
color: red; color: red;
cursor: pointer; cursor: pointer;
} }
.auto .fas {
margin-right: 4px;
}

View file

@ -1,5 +1,5 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { Torrent } from 'src/app/models/torrent.model'; import { RealDebridStatus, Torrent } from 'src/app/models/torrent.model';
import { TorrentService } from 'src/app/torrent.service'; import { TorrentService } from 'src/app/torrent.service';
@Component({ @Component({
@ -24,13 +24,42 @@ export class TorrentRowComponent implements OnInit {
event.stopPropagation(); event.stopPropagation();
this.loading = true; this.loading = true;
this.torrentService.download(this.torrent.torrentId).subscribe(() => { this.torrentService.download(this.torrent.torrentId).subscribe(
this.loading = false; () => {
}); this.loading = false;
},
(err) => {
this.loading = false;
}
);
}
public unpack(event: Event): void {
event.stopPropagation();
this.loading = true;
this.torrentService.unpack(this.torrent.torrentId).subscribe(
() => {
this.loading = false;
},
(err) => {
this.loading = false;
}
);
} }
public delete1(event: Event): void { public delete1(event: Event): void {
event.stopPropagation(); event.stopPropagation();
this.delete.emit(this.torrent.torrentId); this.delete.emit(this.torrent.torrentId);
} }
public canDownload(): boolean {
return this.torrent.rdStatus === RealDebridStatus.Finished && this.torrent.downloads.length === 0;
}
public canUnpack(): boolean {
const downloadsDone = this.torrent.downloads.any((m) => m.downloadFinished != null);
const downloadsUnpacked = this.torrent.downloads.any((m) => m.unpackingQueued != null);
return downloadsDone && !downloadsUnpacked;
}
} }

View file

@ -19,11 +19,16 @@ export class TorrentStatusPipe implements PipeTransform {
return 'Finished'; return 'Finished';
} }
const errors = torrent.downloads.where((m) => m.error != null);
const downloading = torrent.downloads.where((m) => m.downloadStarted && !m.downloadFinished); const downloading = torrent.downloads.where((m) => m.downloadStarted && !m.downloadFinished);
const downloaded = torrent.downloads.where((m) => m.downloadFinished != null);
const unpacking = torrent.downloads.where((m) => m.unpackingStarted && !m.unpackingFinished); const unpacking = torrent.downloads.where((m) => m.unpackingStarted && !m.unpackingFinished);
const queuedForDownload = torrent.downloads.where((m) => m.downloadQueued && !m.downloadStarted);
const queuedForUnpacking = torrent.downloads.where((m) => m.unpackingQueued && !m.unpackingStarted);
let downloadText = ''; if (errors.length > 0) {
let unpackText = ''; return 'Error';
}
if (downloading.length > 0) { if (downloading.length > 0) {
const bytesDone = downloading.sum((m) => m.bytesDone); const bytesDone = downloading.sum((m) => m.bytesDone);
@ -35,7 +40,7 @@ export class TorrentStatusPipe implements PipeTransform {
if (allSpeeds > 0) { if (allSpeeds > 0) {
speed = this.pipe.transform(allSpeeds, 'filesize'); speed = this.pipe.transform(allSpeeds, 'filesize');
downloadText = `Downloading (${progress.toFixed(2)}% - ${speed}/s)`; return `Downloading (${progress.toFixed(2)}% - ${speed}/s)`;
} }
} }
@ -46,20 +51,20 @@ export class TorrentStatusPipe implements PipeTransform {
let allSpeeds = unpacking.sum((m) => m.speed) / unpacking.length; let allSpeeds = unpacking.sum((m) => m.speed) / unpacking.length;
if (allSpeeds > 0) { if (allSpeeds > 0) {
downloadText = `Extracting (${progress.toFixed(2)}%)`; return `Extracting (${progress.toFixed(2)}%)`;
} }
} }
let result: string[] = []; if (queuedForUnpacking.length > 0) {
if (downloadText) { return `Queued for unpacking`;
result.push(downloadText);
}
if (unpackText) {
result.push(unpackText);
} }
if (result.length > 0) { if (queuedForDownload.length > 0) {
return result.join('\r\n'); return `Queued for downloading`;
}
if (downloaded.length > 0) {
return `Files downloaded to host`;
} }
} }

View file

@ -5,19 +5,23 @@
<div class="table-container"> <div class="table-container">
<table class="table is-fullwidth is-hoverable"> <table class="table is-fullwidth is-hoverable">
<colgroup> <colgroup>
<col style="width: 50%" /> <col style="width: calc(65% - 550px)" />
<col style="width: 15%" /> <col style="width: 15%" />
<col style="width: 35%" /> <col style="width: 150px" />
<col style="width: 50px" /> <col style="width: 150px" />
<col style="width: 50px" /> <col style="width: 150px" />
<col style="width: 20%" />
<col style="width: 100px" />
</colgroup> </colgroup>
<thead> <thead>
<tr> <tr>
<th>Name</th> <th>Name</th>
<th>Size</th> <th>Size</th>
<th>Files</th>
<th>Downloads</th>
<th>Auto</th>
<th>Status</th> <th>Status</th>
<th></th> <th>Action</th>
<th></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -28,15 +32,12 @@
(click)="selectTorrent(torrent)" (click)="selectTorrent(torrent)"
(delete)="showDeleteModal($event)" (delete)="showDeleteModal($event)"
></tr> ></tr>
<ng-container *ngIf="showFiles[torrent.torrentId] && torrent?.files.length === 0"> <ng-container *ngIf="showFiles[torrent.torrentId] && torrent?.files.length === 0">
<tr> <tr>
<td colspan="20"> <td colspan="20">
<i class="fas fa-spinner fa-pulse"></i> <i class="fas fa-spinner fa-pulse"></i>
</td> </td>
</tr> </tr>
</ng-container>
<ng-container *ngIf="showFiles[torrent.torrentId] && torrent?.files.length > 0">
<tr app-torrent-file [file]="file" *ngFor="let file of torrent.files"></tr> <tr app-torrent-file [file]="file" *ngFor="let file of torrent.files"></tr>
</ng-container> </ng-container>
</ng-container> </ng-container>

View file

@ -42,6 +42,10 @@ export class TorrentService {
return this.http.get<void>(`/Api/Torrents/Download/${torrentId}`); return this.http.get<void>(`/Api/Torrents/Download/${torrentId}`);
} }
public unpack(torrentId: string): Observable<void> {
return this.http.get<void>(`/Api/Torrents/Unpack/${torrentId}`);
}
public delete( public delete(
torrentId: string, torrentId: string,
deleteData: boolean, deleteData: boolean,

View file

@ -13,7 +13,6 @@ namespace RdtClient.Service
services.AddScoped<ISettings, Settings>(); services.AddScoped<ISettings, Settings>();
services.AddScoped<ITorrents, Torrents>(); services.AddScoped<ITorrents, Torrents>();
services.AddScoped<ITorrentRunner, TorrentRunner>(); services.AddScoped<ITorrentRunner, TorrentRunner>();
services.AddScoped<ITorrentDownloadManager, TorrentDownloadManager>();
} }
} }
} }

View file

@ -1,17 +0,0 @@
using System.Threading.Tasks;
namespace RdtClient.Service.Services
{
public interface ITorrentDownloadManager
{
Task Tick();
}
public class TorrentDownloadManager : ITorrentDownloadManager
{
public async Task Tick()
{
throw new System.NotImplementedException();
}
}
}

View file

@ -163,6 +163,15 @@ namespace RdtClient.Service.Services
if (torrent != null) if (torrent != null)
{ {
if (deleteLocalFiles)
{
var settingDownloadFolder = await _settings.GetString("DownloadFolder");
var torrentPath = Path.Combine(settingDownloadFolder, torrent.RdName);
Directory.Delete(torrentPath, true);
}
if (deleteData) if (deleteData)
{ {
await _downloads.DeleteForTorrent(torrent.TorrentId); await _downloads.DeleteForTorrent(torrent.TorrentId);
@ -173,11 +182,6 @@ namespace RdtClient.Service.Services
{ {
await GetRdNetClient().DeleteTorrentAsync(torrent.RdId); await GetRdNetClient().DeleteTorrentAsync(torrent.RdId);
} }
if (deleteLocalFiles)
{
// TODO
}
} }
} }

View file

@ -17,10 +17,12 @@ namespace RdtClient.Web.Controllers
public class TorrentsController : Controller public class TorrentsController : Controller
{ {
private readonly ITorrents _torrents; private readonly ITorrents _torrents;
private readonly IDownloads _downloads;
public TorrentsController(ITorrents torrents) public TorrentsController(ITorrents torrents, IDownloads downloads)
{ {
_torrents = torrents; _torrents = torrents;
_downloads = downloads;
} }
[HttpGet] [HttpGet]
@ -102,6 +104,20 @@ namespace RdtClient.Web.Controllers
return Ok(); return Ok();
} }
[HttpGet]
[Route("Unpack/{id}")]
public async Task<ActionResult> Unpack(Guid id)
{
var downloads = await _downloads.GetForTorrent(id);
foreach (var download in downloads)
{
await _torrents.Unpack(download.DownloadId);
}
return Ok();
}
} }
public class TorrentControllerUploadFileRequest public class TorrentControllerUploadFileRequest

View file

@ -71,6 +71,7 @@ namespace RdtClient.Web
.Enrich.FromLogContext() .Enrich.FromLogContext()
.Enrich.WithExceptionDetails() .Enrich.WithExceptionDetails()
.WriteTo.File(appSettings.Logging.File.Path, logLevel, rollOnFileSizeLimit: true, fileSizeLimitBytes: appSettings.Logging.File.FileSizeLimitBytes, retainedFileCountLimit: appSettings.Logging.File.MaxRollingFiles) .WriteTo.File(appSettings.Logging.File.Path, logLevel, rollOnFileSizeLimit: true, fileSizeLimitBytes: appSettings.Logging.File.FileSizeLimitBytes, retainedFileCountLimit: appSettings.Logging.File.MaxRollingFiles)
.WriteTo.Console()
.MinimumLevel.Information() .MinimumLevel.Information()
.CreateLogger(); .CreateLogger();