Changed the unrestrict process to only unrestrict when the download is starting.
This commit is contained in:
parent
e291989ace
commit
5265a8b442
23 changed files with 1095 additions and 102 deletions
|
|
@ -1,6 +1,7 @@
|
|||
export class Download {
|
||||
public downloadId: string;
|
||||
public torrentId: string;
|
||||
public path: string;
|
||||
public link: string;
|
||||
public added: Date;
|
||||
public downloadQueued: Date;
|
||||
|
|
|
|||
|
|
@ -6,8 +6,6 @@ export class Torrent {
|
|||
public category: string;
|
||||
public added: Date;
|
||||
public completed: Date;
|
||||
public autoDownload: boolean;
|
||||
public autoUnpack: boolean;
|
||||
public autoDelete: boolean;
|
||||
|
||||
public rdId: string;
|
||||
|
|
|
|||
|
|
@ -37,14 +37,6 @@
|
|||
</div>
|
||||
<hr />
|
||||
<div class="field">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" [(ngModel)]="autoDownload" />
|
||||
Download torrent to host when finished downloading on Real-Debrid
|
||||
</label>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" [(ngModel)]="autoUnpack" />
|
||||
Unpack files after downloading to host
|
||||
</label>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" [(ngModel)]="autoDelete" />
|
||||
Remove torrent when finished downloading on host
|
||||
|
|
@ -56,7 +48,30 @@
|
|||
<button class="button is-success" [disabled]="saving" [ngClass]="{ 'is-loading': saving }" (click)="ok()">
|
||||
<span>Add Torrent</span>
|
||||
</button>
|
||||
<button class="button is-info" [disabled]="saving" [ngClass]="{ 'is-loading': saving }" (click)="checkFiles()">
|
||||
<span>Check available files</span>
|
||||
</button>
|
||||
<button class="button" (click)="cancel()" [disabled]="saving">Cancel</button>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal" [class.is-active]="isFileModalActive">
|
||||
<div class="modal-background"></div>
|
||||
<div class="modal-card file-modal">
|
||||
<header class="modal-card-head">
|
||||
<p class="modal-card-title">Available Files</p>
|
||||
<button class="delete" aria-label="close" (click)="isFileModalActive = false"></button>
|
||||
</header>
|
||||
<section class="modal-card-body">
|
||||
<table class="table" style="width: 100%">
|
||||
<tbody>
|
||||
<tr *ngFor="let file of fileList">
|
||||
<td>{{ file }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
<footer class="modal-card-foot"></footer>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,3 +2,7 @@
|
|||
max-width: 24em;
|
||||
width: 24em;
|
||||
}
|
||||
|
||||
.file-modal {
|
||||
width: calc(75% - 40px);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,13 +21,14 @@ export class AddNewTorrentComponent implements OnInit {
|
|||
public openChange = new EventEmitter<boolean>();
|
||||
|
||||
public isActive = false;
|
||||
public isFileModalActive = false;
|
||||
|
||||
public fileName: string;
|
||||
public magnetLink: string;
|
||||
public autoDownload: boolean;
|
||||
public autoUnpack: boolean;
|
||||
public autoDelete: boolean;
|
||||
|
||||
public fileList: string[];
|
||||
|
||||
public saving = false;
|
||||
public error: string;
|
||||
|
||||
|
|
@ -41,7 +42,6 @@ export class AddNewTorrentComponent implements OnInit {
|
|||
this.fileName = '';
|
||||
this.magnetLink = '';
|
||||
this.autoDelete = false;
|
||||
this.autoDownload = true;
|
||||
|
||||
this.saving = false;
|
||||
this.selectedFile = null;
|
||||
|
|
@ -67,7 +67,7 @@ export class AddNewTorrentComponent implements OnInit {
|
|||
this.error = null;
|
||||
|
||||
if (this.magnetLink) {
|
||||
this.torrentService.uploadMagnet(this.magnetLink, this.autoDownload, this.autoUnpack, this.autoDelete).subscribe(
|
||||
this.torrentService.uploadMagnet(this.magnetLink, this.autoDelete).subscribe(
|
||||
() => {
|
||||
this.cancel();
|
||||
},
|
||||
|
|
@ -77,7 +77,7 @@ export class AddNewTorrentComponent implements OnInit {
|
|||
}
|
||||
);
|
||||
} else if (this.selectedFile) {
|
||||
this.torrentService.uploadFile(this.selectedFile, this.autoDownload, this.autoUnpack, this.autoDelete).subscribe(
|
||||
this.torrentService.uploadFile(this.selectedFile, this.autoDelete).subscribe(
|
||||
() => {
|
||||
this.cancel();
|
||||
},
|
||||
|
|
@ -91,6 +91,39 @@ export class AddNewTorrentComponent implements OnInit {
|
|||
}
|
||||
}
|
||||
|
||||
public checkFiles(): void {
|
||||
this.saving = true;
|
||||
this.error = null;
|
||||
|
||||
if (this.magnetLink) {
|
||||
this.torrentService.checkFilesMagnet(this.magnetLink).subscribe(
|
||||
(result) => {
|
||||
this.saving = false;
|
||||
this.isFileModalActive = true;
|
||||
this.fileList = result;
|
||||
},
|
||||
(err) => {
|
||||
this.error = err.error;
|
||||
this.saving = false;
|
||||
}
|
||||
);
|
||||
} else if (this.selectedFile) {
|
||||
this.torrentService.checkFiles(this.selectedFile).subscribe(
|
||||
(result) => {
|
||||
this.saving = false;
|
||||
this.isFileModalActive = true;
|
||||
this.fileList = result;
|
||||
},
|
||||
(err) => {
|
||||
this.error = err.error;
|
||||
this.saving = false;
|
||||
}
|
||||
);
|
||||
} else {
|
||||
this.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
public cancel(): void {
|
||||
this.isActive = false;
|
||||
this.openChange.emit(this.open);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<td colspan="4">
|
||||
<i class="fas fa-download" aria-hidden="true"></i>
|
||||
{{ download.link }}
|
||||
<span *ngIf="download.link">{{ download.link }}</span>
|
||||
<span *ngIf="!download.link">{{ download.path }}</span>
|
||||
</td>
|
||||
<td>
|
||||
{{ download.bytesTotal | filesize }}
|
||||
|
|
|
|||
|
|
@ -6,8 +6,6 @@
|
|||
{{ 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>
|
||||
|
|
|
|||
|
|
@ -31,27 +31,32 @@ export class TorrentService {
|
|||
return this.http.get<Torrent[]>(`/Api/Torrents`);
|
||||
}
|
||||
|
||||
public uploadMagnet(
|
||||
magnetLink: string,
|
||||
autoDownload: boolean,
|
||||
autoUnpack: boolean,
|
||||
autoDelete: boolean
|
||||
): Observable<void> {
|
||||
public uploadMagnet(magnetLink: string, autoDelete: boolean): Observable<void> {
|
||||
return this.http.post<void>(`/Api/Torrents/UploadMagnet`, {
|
||||
magnetLink,
|
||||
autoDownload,
|
||||
autoUnpack,
|
||||
autoDelete,
|
||||
});
|
||||
}
|
||||
|
||||
public uploadFile(file: File, autoDownload: boolean, autoUnpack: boolean, autoDelete: boolean): Observable<void> {
|
||||
public uploadFile(file: File, autoDelete: boolean): Observable<void> {
|
||||
const formData: FormData = new FormData();
|
||||
formData.append('file', file);
|
||||
formData.append('formData', JSON.stringify({ autoDownload, autoUnpack, autoDelete }));
|
||||
formData.append('formData', JSON.stringify({ autoDelete }));
|
||||
return this.http.post<void>(`/Api/Torrents/UploadFile`, formData);
|
||||
}
|
||||
|
||||
public checkFilesMagnet(magnetLink: string): Observable<string[]> {
|
||||
return this.http.post<string[]>(`/Api/Torrents/CheckFilesMagnet`, {
|
||||
magnetLink,
|
||||
});
|
||||
}
|
||||
|
||||
public checkFiles(file: File): Observable<string[]> {
|
||||
const formData: FormData = new FormData();
|
||||
formData.append('file', file);
|
||||
return this.http.post<string[]>(`/Api/Torrents/CheckFiles`, formData);
|
||||
}
|
||||
|
||||
public download(torrentId: string): Observable<void> {
|
||||
return this.http.get<void>(`/Api/Torrents/Download/${torrentId}`);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RdtClient.Data.Models.Data;
|
||||
using Download = RdtClient.Data.Models.Data.Download;
|
||||
|
||||
namespace RdtClient.Data.Data
|
||||
{
|
||||
|
|
@ -12,7 +12,8 @@ namespace RdtClient.Data.Data
|
|||
Task<IList<Download>> Get();
|
||||
Task<IList<Download>> GetForTorrent(Guid torrentId);
|
||||
Task<Download> GetById(Guid downloadId);
|
||||
Task<Download> Add(Guid torrentId, String link);
|
||||
Task<Download> Add(Guid torrentId, String path);
|
||||
Task UpdateUnrestrictedLink(Guid downloadId, String unrestrictedLink);
|
||||
Task UpdateDownloadStarted(Guid downloadId, DateTimeOffset? dateTime);
|
||||
Task UpdateDownloadFinished(Guid downloadId, DateTimeOffset? dateTime);
|
||||
Task UpdateUnpackingQueued(Guid downloadId, DateTimeOffset? dateTime);
|
||||
|
|
@ -56,13 +57,13 @@ namespace RdtClient.Data.Data
|
|||
.FirstOrDefaultAsync(m => m.DownloadId == downloadId);
|
||||
}
|
||||
|
||||
public async Task<Download> Add(Guid torrentId, String link)
|
||||
public async Task<Download> Add(Guid torrentId, String path)
|
||||
{
|
||||
var download = new Download
|
||||
{
|
||||
DownloadId = Guid.NewGuid(),
|
||||
TorrentId = torrentId,
|
||||
Link = link,
|
||||
Path = path,
|
||||
Added = DateTimeOffset.UtcNow,
|
||||
DownloadQueued = DateTimeOffset.UtcNow
|
||||
};
|
||||
|
|
@ -73,7 +74,17 @@ namespace RdtClient.Data.Data
|
|||
|
||||
return download;
|
||||
}
|
||||
|
||||
|
||||
public async Task UpdateUnrestrictedLink(Guid downloadId, String unrestrictedLink)
|
||||
{
|
||||
var dbDownload = await _dataContext.Downloads
|
||||
.FirstOrDefaultAsync(m => m.DownloadId == downloadId);
|
||||
|
||||
dbDownload.Link = unrestrictedLink;
|
||||
|
||||
await _dataContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task UpdateDownloadStarted(Guid downloadId, DateTimeOffset? dateTime)
|
||||
{
|
||||
var dbDownload = await _dataContext.Downloads
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ namespace RdtClient.Data.Data
|
|||
Task<IList<Torrent>> Get();
|
||||
Task<Torrent> GetById(Guid torrentId);
|
||||
Task<Torrent> GetByHash(String hash);
|
||||
Task<Torrent> Add(String realDebridId, String hash, String category, Boolean autoDownload, Boolean autoUnpack, Boolean autoDelete);
|
||||
Task<Torrent> Add(String realDebridId, String hash, String category, Boolean autoDelete);
|
||||
Task UpdateRdData(Torrent torrent);
|
||||
Task UpdateCategory(Guid torrentId, String category);
|
||||
Task UpdateComplete(Guid torrentId, DateTimeOffset datetime);
|
||||
|
|
@ -78,7 +78,7 @@ namespace RdtClient.Data.Data
|
|||
return dbTorrent;
|
||||
}
|
||||
|
||||
public async Task<Torrent> Add(String realDebridId, String hash, String category, Boolean autoDownload, Boolean autoUnpack, Boolean autoDelete)
|
||||
public async Task<Torrent> Add(String realDebridId, String hash, String category, Boolean autoDelete)
|
||||
{
|
||||
var torrent = new Torrent
|
||||
{
|
||||
|
|
@ -87,8 +87,6 @@ namespace RdtClient.Data.Data
|
|||
RdId = realDebridId,
|
||||
Hash = hash.ToLower(),
|
||||
Category = category,
|
||||
AutoDownload = autoDownload,
|
||||
AutoUnpack = autoUnpack,
|
||||
AutoDelete = autoDelete
|
||||
};
|
||||
|
||||
|
|
|
|||
418
server/RdtClient.Data/Migrations/20210311002748_Downloads_Add_Path.Designer.cs
generated
Normal file
418
server/RdtClient.Data/Migrations/20210311002748_Downloads_Add_Path.Designer.cs
generated
Normal file
|
|
@ -0,0 +1,418 @@
|
|||
// <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("20210311002748_Downloads_Add_Path")]
|
||||
partial class Downloads_Add_Path
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "5.0.3");
|
||||
|
||||
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<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<bool>("AutoDelete")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("AutoDownload")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("AutoUnpack")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Category")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTimeOffset?>("Completed")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Hash")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
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.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 Downloads_Add_Path : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "Path",
|
||||
table: "Downloads",
|
||||
type: "TEXT",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Path",
|
||||
table: "Downloads");
|
||||
}
|
||||
}
|
||||
}
|
||||
412
server/RdtClient.Data/Migrations/20210311005539_Torrents_Removed_Auto.Designer.cs
generated
Normal file
412
server/RdtClient.Data/Migrations/20210311005539_Torrents_Removed_Auto.Designer.cs
generated
Normal file
|
|
@ -0,0 +1,412 @@
|
|||
// <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("20210311005539_Torrents_Removed_Auto")]
|
||||
partial class Torrents_Removed_Auto
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "5.0.3");
|
||||
|
||||
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<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<bool>("AutoDelete")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Category")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTimeOffset?>("Completed")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Hash")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
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.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,35 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace RdtClient.Data.Migrations
|
||||
{
|
||||
public partial class Torrents_Removed_Auto : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "AutoDownload",
|
||||
table: "Torrents");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "AutoUnpack",
|
||||
table: "Torrents");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "AutoDownload",
|
||||
table: "Torrents",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "AutoUnpack",
|
||||
table: "Torrents",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@ namespace RdtClient.Data.Migrations
|
|||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "5.0.1");
|
||||
.HasAnnotation("ProductVersion", "5.0.3");
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||
{
|
||||
|
|
@ -235,6 +235,9 @@ namespace RdtClient.Data.Migrations
|
|||
b.Property<string>("Link")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Path")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("TorrentId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
|
|
@ -282,12 +285,6 @@ namespace RdtClient.Data.Migrations
|
|||
b.Property<bool>("AutoDelete")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("AutoDownload")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("AutoUnpack")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Category")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ namespace RdtClient.Data.Models.Data
|
|||
|
||||
public Guid TorrentId { get; set; }
|
||||
|
||||
public String Path { get; set; }
|
||||
|
||||
public String Link { get; set; }
|
||||
|
||||
public DateTimeOffset Added { get; set; }
|
||||
|
|
|
|||
|
|
@ -20,8 +20,6 @@ namespace RdtClient.Data.Models.Data
|
|||
public DateTimeOffset Added { get; set; }
|
||||
public DateTimeOffset? Completed { get; set; }
|
||||
|
||||
public Boolean AutoDownload { get; set; }
|
||||
public Boolean AutoUnpack { get; set; }
|
||||
public Boolean AutoDelete { get; set; }
|
||||
|
||||
[InverseProperty("Torrent")]
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using RdtClient.Data.Data;
|
||||
using RdtClient.Data.Models.Data;
|
||||
using Download = RdtClient.Data.Models.Data.Download;
|
||||
|
||||
namespace RdtClient.Service.Services
|
||||
{
|
||||
|
|
@ -12,6 +12,7 @@ namespace RdtClient.Service.Services
|
|||
Task<IList<Download>> GetForTorrent(Guid torrentId);
|
||||
Task<Download> GetById(Guid downloadId);
|
||||
Task<Download> Add(Guid torrentId, String link);
|
||||
Task UpdateUnrestrictedLink(Guid downloadId, String unrestrictedLink);
|
||||
Task UpdateDownloadStarted(Guid downloadId, DateTimeOffset? dateTime);
|
||||
Task UpdateDownloadFinished(Guid downloadId, DateTimeOffset? dateTime);
|
||||
Task UpdateUnpackingQueued(Guid downloadId, DateTimeOffset? dateTime);
|
||||
|
|
@ -51,6 +52,11 @@ namespace RdtClient.Service.Services
|
|||
return await _downloadData.Add(torrentId, link);
|
||||
}
|
||||
|
||||
public async Task UpdateUnrestrictedLink(Guid downloadId, String unrestrictedLink)
|
||||
{
|
||||
await _downloadData.UpdateUnrestrictedLink(downloadId, unrestrictedLink);
|
||||
}
|
||||
|
||||
public async Task UpdateDownloadStarted(Guid downloadId, DateTimeOffset? dateTime)
|
||||
{
|
||||
await _downloadData.UpdateDownloadStarted(downloadId, dateTime);
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ namespace RdtClient.Service.Services
|
|||
Task<IList<TorrentFileItem>> TorrentFileContents(String hash);
|
||||
Task<TorrentProperties> TorrentProperties(String hash);
|
||||
Task TorrentsDelete(String hash, Boolean deleteFiles);
|
||||
Task TorrentsAddMagnet(String magnetLink, String category, Boolean autoDownload, Boolean autoUnpack, Boolean autoDelete);
|
||||
Task TorrentsAddFile(Byte[] fileBytes, String category, Boolean autoDownload, Boolean autoUnpack, Boolean autoDelete);
|
||||
Task TorrentsAddMagnet(String magnetLink, String category, Boolean autoDelete);
|
||||
Task TorrentsAddFile(Byte[] fileBytes, String category, Boolean autoDelete);
|
||||
Task TorrentsSetCategory(String hash, String category);
|
||||
Task<IDictionary<String, TorrentCategory>> TorrentsCategories();
|
||||
}
|
||||
|
|
@ -424,14 +424,14 @@ namespace RdtClient.Service.Services
|
|||
await _torrents.Delete(torrent.TorrentId, true, true, deleteFiles);
|
||||
}
|
||||
|
||||
public async Task TorrentsAddMagnet(String magnetLink, String category, Boolean autoDownload, Boolean autoUnpack, Boolean autoDelete)
|
||||
public async Task TorrentsAddMagnet(String magnetLink, String category, Boolean autoDelete)
|
||||
{
|
||||
await _torrents.UploadMagnet(magnetLink, category, autoDownload, autoUnpack, autoDelete);
|
||||
await _torrents.UploadMagnet(magnetLink, category, autoDelete);
|
||||
}
|
||||
|
||||
public async Task TorrentsAddFile(Byte[] fileBytes, String category,Boolean autoDownload, Boolean autoUnpack, Boolean autoDelete)
|
||||
public async Task TorrentsAddFile(Byte[] fileBytes, String category, Boolean autoDelete)
|
||||
{
|
||||
await _torrents.UploadFile(fileBytes, category, autoDownload, autoUnpack, autoDelete);
|
||||
await _torrents.UploadFile(fileBytes, category, autoDelete);
|
||||
}
|
||||
|
||||
public async Task TorrentsSetCategory(String hash, String category)
|
||||
|
|
|
|||
|
|
@ -219,6 +219,9 @@ namespace RdtClient.Service.Services
|
|||
continue;
|
||||
}
|
||||
|
||||
var downloadLink = await _torrents.UnrestrictLink(download.DownloadId);
|
||||
download.Link = downloadLink;
|
||||
|
||||
download.DownloadStarted = DateTime.UtcNow;
|
||||
await _downloads.UpdateDownloadStarted(download.DownloadId, download.DownloadStarted);
|
||||
|
||||
|
|
@ -332,7 +335,7 @@ namespace RdtClient.Service.Services
|
|||
}
|
||||
|
||||
// RealDebrid is waiting for file selection, select which files to download.
|
||||
if (torrent.AutoDownload && torrent.RdStatus == RealDebridStatus.WaitingForFileSelection)
|
||||
if (torrent.RdStatus == RealDebridStatus.WaitingForFileSelection)
|
||||
{
|
||||
Log.Debug($"Torrent {torrent.RdId} selecting files");
|
||||
|
||||
|
|
@ -374,7 +377,7 @@ namespace RdtClient.Service.Services
|
|||
|
||||
Log.Debug($"Selecting files for torrent {torrent.RdId}: {String.Join(", ", fileIds)}");
|
||||
|
||||
await _torrents.SelectFiles(torrent.RdId, fileIds);
|
||||
await _torrents.SelectFiles(torrent.TorrentId, fileIds);
|
||||
}
|
||||
|
||||
// If the torrent doesn't have any files at this point, don't process it further.
|
||||
|
|
@ -385,25 +388,16 @@ namespace RdtClient.Service.Services
|
|||
}
|
||||
|
||||
// RealDebrid finished downloading the torrent, process the file to host.
|
||||
if (torrent.AutoDownload && torrent.RdStatus == RealDebridStatus.Finished)
|
||||
if (torrent.RdStatus == RealDebridStatus.Finished)
|
||||
{
|
||||
Log.Debug($"Torrent {torrent.RdId} completed, download starting");
|
||||
|
||||
// If the torrent doesn't have any Downloads, unrestrict the links and add them to the database.
|
||||
if (torrent.Downloads.Count == 0)
|
||||
{
|
||||
Log.Debug($"Torrent {torrent.RdId} unrestricting links");
|
||||
|
||||
await _torrents.Unrestrict(torrent.TorrentId);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the torrent has any files that need starting to be downloaded, download them.
|
||||
var downloadsPending = torrent.Downloads
|
||||
.Where(m => m.Completed == null &&
|
||||
m.DownloadStarted == null &&
|
||||
m.DownloadFinished == null)
|
||||
.OrderBy(m => m.Added)
|
||||
.ToList();
|
||||
|
||||
Log.Debug($"Torrent {torrent.RdId} found {downloadsPending.Count} downloads pending");
|
||||
|
|
@ -421,7 +415,7 @@ namespace RdtClient.Service.Services
|
|||
}
|
||||
}
|
||||
|
||||
if (torrent.AutoUnpack && torrent.RdStatus == RealDebridStatus.Finished)
|
||||
if (torrent.RdStatus == RealDebridStatus.Finished)
|
||||
{
|
||||
Log.Debug($"Torrent {torrent.RdId} completed, unpack starting");
|
||||
|
||||
|
|
|
|||
|
|
@ -20,12 +20,12 @@ namespace RdtClient.Service.Services
|
|||
Task<Torrent> GetById(Guid torrentId);
|
||||
Task<Torrent> GetByHash(String hash);
|
||||
Task UpdateCategory(String hash, String category);
|
||||
Task UploadMagnet(String magnetLink, String category, Boolean autoDownload, Boolean autoUnpack, Boolean autoDelete);
|
||||
Task UploadFile(Byte[] bytes, String category, Boolean autoDownload, Boolean autoUnpack, Boolean autoDelete);
|
||||
Task UploadMagnet(String magnetLink, String category, Boolean autoDelete);
|
||||
Task UploadFile(Byte[] bytes, String category, Boolean autoDelete);
|
||||
Task<List<String>> GetAvailableFiles(String hash);
|
||||
Task SelectFiles(String torrentId, IList<String> fileIds);
|
||||
Task SelectFiles(Guid torrentId, IList<String> fileIds);
|
||||
Task Delete(Guid torrentId, Boolean deleteData, Boolean deleteRdTorrent, Boolean deleteLocalFiles);
|
||||
Task Unrestrict(Guid torrentId);
|
||||
Task<String> UnrestrictLink(Guid downloadId);
|
||||
Task Download(Guid downloadId);
|
||||
Task Unpack(Guid downloadId);
|
||||
void Reset();
|
||||
|
|
@ -135,22 +135,22 @@ namespace RdtClient.Service.Services
|
|||
await _torrentData.UpdateCategory(torrent.TorrentId, category);
|
||||
}
|
||||
|
||||
public async Task UploadMagnet(String magnetLink, String category, Boolean autoDownload, Boolean autoUnpack, Boolean autoDelete)
|
||||
public async Task UploadMagnet(String magnetLink, String category, Boolean autoDelete)
|
||||
{
|
||||
var magnet = MagnetLink.Parse(magnetLink);
|
||||
|
||||
var rdTorrent = await GetRdNetClient().AddTorrentMagnetAsync(magnetLink);
|
||||
|
||||
await Add(rdTorrent.Id, magnet.InfoHash.ToHex(), category, autoDownload, autoUnpack, autoDelete);
|
||||
await Add(rdTorrent.Id, magnet.InfoHash.ToHex(), category, autoDelete);
|
||||
}
|
||||
|
||||
public async Task UploadFile(Byte[] bytes, String category, Boolean autoDownload, Boolean autoUnpack, Boolean autoDelete)
|
||||
public async Task UploadFile(Byte[] bytes, String category, Boolean autoDelete)
|
||||
{
|
||||
var torrent = await MonoTorrent.Torrent.LoadAsync(bytes);
|
||||
|
||||
var rdTorrent = await GetRdNetClient().AddTorrentFileAsync(bytes);
|
||||
|
||||
await Add(rdTorrent.Id, torrent.InfoHash.ToHex(), category, autoDownload, autoUnpack, autoDelete);
|
||||
await Add(rdTorrent.Id, torrent.InfoHash.ToHex(), category, autoDelete);
|
||||
}
|
||||
|
||||
public async Task<List<String>> GetAvailableFiles(String hash)
|
||||
|
|
@ -164,9 +164,18 @@ namespace RdtClient.Service.Services
|
|||
return groups.Select(m => m.Key).ToList();
|
||||
}
|
||||
|
||||
public async Task SelectFiles(String torrentId, IList<String> fileIds)
|
||||
public async Task SelectFiles(Guid torrentId, IList<String> fileIds)
|
||||
{
|
||||
await GetRdNetClient().SelectTorrentFilesAsync(torrentId, fileIds.ToArray());
|
||||
var torrent = await GetById(torrentId);
|
||||
|
||||
await GetRdNetClient().SelectTorrentFilesAsync(torrent.RdId, fileIds.ToArray());
|
||||
|
||||
var rdTorrent = await GetRdNetClient().GetTorrentInfoAsync(torrent.RdId);
|
||||
|
||||
foreach (var file in rdTorrent.Links)
|
||||
{
|
||||
await _downloads.Add(torrent.TorrentId, file);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task Delete(Guid torrentId, Boolean deleteData, Boolean deleteRdTorrent, Boolean deleteLocalFiles)
|
||||
|
|
@ -212,23 +221,15 @@ namespace RdtClient.Service.Services
|
|||
}
|
||||
}
|
||||
|
||||
public async Task Unrestrict(Guid torrentId)
|
||||
public async Task<String> UnrestrictLink(Guid downloadId)
|
||||
{
|
||||
var torrent = await _torrentData.GetById(torrentId);
|
||||
var download = await _downloads.GetById(downloadId);
|
||||
|
||||
var rdTorrent = await GetRdNetClient().GetTorrentInfoAsync(torrent.RdId);
|
||||
var unrestrictedLink = await GetRdNetClient().UnrestrictLinkAsync(download.Path);
|
||||
|
||||
foreach (var link in rdTorrent.Links)
|
||||
{
|
||||
var unrestrictedLink = await GetRdNetClient().UnrestrictLinkAsync(link);
|
||||
await _downloads.UpdateUnrestrictedLink(downloadId, unrestrictedLink.Download);
|
||||
|
||||
if (torrent.Downloads.Any(m => m.Link == unrestrictedLink.Download))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
await _downloads.Add(torrent.TorrentId, unrestrictedLink.Download);
|
||||
}
|
||||
return unrestrictedLink.Download;
|
||||
}
|
||||
|
||||
public async Task Download(Guid downloadId)
|
||||
|
|
@ -269,7 +270,7 @@ namespace RdtClient.Service.Services
|
|||
return profile;
|
||||
}
|
||||
|
||||
private async Task Add(String rdTorrentId, String infoHash, String category, Boolean autoDownload, Boolean autoUnpack, Boolean autoDelete)
|
||||
private async Task Add(String rdTorrentId, String infoHash, String category, Boolean autoDelete)
|
||||
{
|
||||
var w = await SemaphoreSlim.WaitAsync(60000);
|
||||
if (!w)
|
||||
|
|
@ -286,7 +287,7 @@ namespace RdtClient.Service.Services
|
|||
return;
|
||||
}
|
||||
|
||||
var newTorrent = await _torrentData.Add(rdTorrentId, infoHash, category, autoDownload, autoUnpack, autoDelete);
|
||||
var newTorrent = await _torrentData.Add(rdTorrentId, infoHash, category, autoDelete);
|
||||
|
||||
var rdTorrent = await GetRdNetClient().GetTorrentInfoAsync(rdTorrentId);
|
||||
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ namespace RdtClient.Web.Controllers
|
|||
|
||||
foreach (var url in urls)
|
||||
{
|
||||
await _qBittorrent.TorrentsAddMagnet(url.Trim(), request.Category, true, true, false);
|
||||
await _qBittorrent.TorrentsAddMagnet(url.Trim(), request.Category, false);
|
||||
}
|
||||
|
||||
return Ok();
|
||||
|
|
@ -265,7 +265,7 @@ namespace RdtClient.Web.Controllers
|
|||
await file.CopyToAsync(target);
|
||||
var fileBytes = target.ToArray();
|
||||
|
||||
await _qBittorrent.TorrentsAddFile(fileBytes, request.Category, true, true, false);
|
||||
await _qBittorrent.TorrentsAddFile(fileBytes, request.Category, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,9 +6,10 @@ using System.Threading.Tasks;
|
|||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using RdtClient.Data.Models.Data;
|
||||
using MonoTorrent;
|
||||
using RdtClient.Service.Helpers;
|
||||
using RdtClient.Service.Services;
|
||||
using Torrent = RdtClient.Data.Models.Data.Torrent;
|
||||
|
||||
namespace RdtClient.Web.Controllers
|
||||
{
|
||||
|
|
@ -74,7 +75,7 @@ namespace RdtClient.Web.Controllers
|
|||
|
||||
var bytes = memoryStream.ToArray();
|
||||
|
||||
await _torrents.UploadFile(bytes, null, formData.AutoDownload, formData.AutoUnpack, formData.AutoDelete);
|
||||
await _torrents.UploadFile(bytes, null, formData.AutoDelete);
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
|
@ -83,10 +84,45 @@ namespace RdtClient.Web.Controllers
|
|||
[Route("UploadMagnet")]
|
||||
public async Task<ActionResult> UploadMagnet([FromBody] TorrentControllerUploadMagnetRequest request)
|
||||
{
|
||||
await _torrents.UploadMagnet(request.MagnetLink, null, request.AutoDownload, request.AutoUnpack, request.AutoDelete);
|
||||
await _torrents.UploadMagnet(request.MagnetLink, null, request.AutoDelete);
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("CheckFiles")]
|
||||
public async Task<ActionResult> CheckFiles([FromForm] IFormFile file)
|
||||
{
|
||||
if (file == null || file.Length <= 0)
|
||||
{
|
||||
throw new Exception("Invalid torrent file");
|
||||
}
|
||||
|
||||
var fileStream = file.OpenReadStream();
|
||||
|
||||
await using var memoryStream = new MemoryStream();
|
||||
|
||||
await fileStream.CopyToAsync(memoryStream);
|
||||
|
||||
var bytes = memoryStream.ToArray();
|
||||
|
||||
var torrent = await MonoTorrent.Torrent.LoadAsync(bytes);
|
||||
|
||||
var result = await _torrents.GetAvailableFiles(torrent.InfoHash.ToHex());
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("CheckFilesMagnet")]
|
||||
public async Task<ActionResult> CheckFilesMagnet([FromBody] TorrentControllerCheckFilesRequest request)
|
||||
{
|
||||
var magnet = MagnetLink.Parse(request.MagnetLink);
|
||||
|
||||
var result = await _torrents.GetAvailableFiles(magnet.InfoHash.ToHex());
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("Delete/{id}")]
|
||||
|
|
@ -101,7 +137,13 @@ namespace RdtClient.Web.Controllers
|
|||
[Route("Download/{id}")]
|
||||
public async Task<ActionResult> Download(Guid id)
|
||||
{
|
||||
await _torrents.Unrestrict(id);
|
||||
var torrent = await _torrents.GetById(id);
|
||||
|
||||
foreach (var link in torrent.Files.Where(m => m.Selected))
|
||||
{
|
||||
await _downloads.Add(id, link.Path);
|
||||
await _torrents.UnrestrictLink(id);
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
|
@ -123,16 +165,12 @@ namespace RdtClient.Web.Controllers
|
|||
|
||||
public class TorrentControllerUploadFileRequest
|
||||
{
|
||||
public Boolean AutoDownload { get; set; }
|
||||
public Boolean AutoUnpack { get; set; }
|
||||
public Boolean AutoDelete { get; set; }
|
||||
}
|
||||
|
||||
public class TorrentControllerUploadMagnetRequest
|
||||
{
|
||||
public String MagnetLink { get; set; }
|
||||
public Boolean AutoDownload { get; set; }
|
||||
public Boolean AutoUnpack { get; set; }
|
||||
public Boolean AutoDelete { get; set; }
|
||||
}
|
||||
|
||||
|
|
@ -142,4 +180,9 @@ namespace RdtClient.Web.Controllers
|
|||
public Boolean DeleteRdTorrent { get; set; }
|
||||
public Boolean DeleteLocalFiles { get; set; }
|
||||
}
|
||||
|
||||
public class TorrentControllerCheckFilesRequest
|
||||
{
|
||||
public String MagnetLink { get; set; }
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue