Added most functionality on the client and serverside
This commit is contained in:
parent
703d650676
commit
f77c1860de
80 changed files with 4081 additions and 72 deletions
6
client/angular-proxy.json
Normal file
6
client/angular-proxy.json
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"/Api": {
|
||||||
|
"target": "http://localhost:4201/",
|
||||||
|
"secure": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -23,13 +23,8 @@
|
||||||
"polyfills": "src/polyfills.ts",
|
"polyfills": "src/polyfills.ts",
|
||||||
"tsConfig": "tsconfig.app.json",
|
"tsConfig": "tsconfig.app.json",
|
||||||
"aot": true,
|
"aot": true,
|
||||||
"assets": [
|
"assets": ["src/favicon.ico", "src/assets"],
|
||||||
"src/favicon.ico",
|
"styles": ["src/styles.scss"],
|
||||||
"src/assets"
|
|
||||||
],
|
|
||||||
"styles": [
|
|
||||||
"src/styles.scss"
|
|
||||||
],
|
|
||||||
"scripts": []
|
"scripts": []
|
||||||
},
|
},
|
||||||
"configurations": {
|
"configurations": {
|
||||||
|
|
@ -66,7 +61,8 @@
|
||||||
"serve": {
|
"serve": {
|
||||||
"builder": "@angular-devkit/build-angular:dev-server",
|
"builder": "@angular-devkit/build-angular:dev-server",
|
||||||
"options": {
|
"options": {
|
||||||
"browserTarget": "rdt-client:build"
|
"browserTarget": "rdt-client:build",
|
||||||
|
"proxyConfig": "angular-proxy.json"
|
||||||
},
|
},
|
||||||
"configurations": {
|
"configurations": {
|
||||||
"production": {
|
"production": {
|
||||||
|
|
@ -87,13 +83,8 @@
|
||||||
"polyfills": "src/polyfills.ts",
|
"polyfills": "src/polyfills.ts",
|
||||||
"tsConfig": "tsconfig.spec.json",
|
"tsConfig": "tsconfig.spec.json",
|
||||||
"karmaConfig": "karma.conf.js",
|
"karmaConfig": "karma.conf.js",
|
||||||
"assets": [
|
"assets": ["src/favicon.ico", "src/assets"],
|
||||||
"src/favicon.ico",
|
"styles": ["src/styles.scss"],
|
||||||
"src/assets"
|
|
||||||
],
|
|
||||||
"styles": [
|
|
||||||
"src/styles.scss"
|
|
||||||
],
|
|
||||||
"scripts": []
|
"scripts": []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -105,9 +96,7 @@
|
||||||
"tsconfig.spec.json",
|
"tsconfig.spec.json",
|
||||||
"e2e/tsconfig.json"
|
"e2e/tsconfig.json"
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": ["**/node_modules/**"]
|
||||||
"**/node_modules/**"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"e2e": {
|
"e2e": {
|
||||||
|
|
@ -123,6 +112,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}},
|
}
|
||||||
|
},
|
||||||
"defaultProject": "rdt-client"
|
"defaultProject": "rdt-client"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
23
client/package-lock.json
generated
23
client/package-lock.json
generated
|
|
@ -1371,6 +1371,11 @@
|
||||||
"to-fast-properties": "^2.0.0"
|
"to-fast-properties": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@fortawesome/fontawesome-free": {
|
||||||
|
"version": "5.13.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.13.0.tgz",
|
||||||
|
"integrity": "sha512-xKOeQEl5O47GPZYIMToj6uuA2syyFlq9EMSl2ui0uytjY9xbe8XS0pexNWmxrdcCyNGyDmLyYw5FtKsalBUeOg=="
|
||||||
|
},
|
||||||
"@istanbuljs/schema": {
|
"@istanbuljs/schema": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz",
|
||||||
|
|
@ -2659,6 +2664,11 @@
|
||||||
"integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=",
|
"integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"bulma": {
|
||||||
|
"version": "0.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/bulma/-/bulma-0.8.1.tgz",
|
||||||
|
"integrity": "sha512-Afi2zv4DKmNSYfmx55V+Mtnt8+WfR8Rs65kWArmzEuWP7vNr7dSAEDI+ORZlgOR1gueNZwpKaPdUi4ZiTNwgPA=="
|
||||||
|
},
|
||||||
"bytes": {
|
"bytes": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
|
||||||
|
|
@ -4807,6 +4817,11 @@
|
||||||
"minimatch": "^3.0.3"
|
"minimatch": "^3.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"filesize": {
|
||||||
|
"version": "6.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/filesize/-/filesize-6.1.0.tgz",
|
||||||
|
"integrity": "sha512-LpCHtPQ3sFx67z+uh2HnSyWSLLu5Jxo21795uRDuar/EOuYWXib5EmPaGIBuSnRqH2IODiKA2k5re/K9OnN/Yg=="
|
||||||
|
},
|
||||||
"fill-range": {
|
"fill-range": {
|
||||||
"version": "7.0.1",
|
"version": "7.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||||
|
|
@ -7377,6 +7392,14 @@
|
||||||
"integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==",
|
"integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"ngx-filesize": {
|
||||||
|
"version": "2.0.13",
|
||||||
|
"resolved": "https://registry.npmjs.org/ngx-filesize/-/ngx-filesize-2.0.13.tgz",
|
||||||
|
"integrity": "sha512-rdOJMmJTou8tjiMLqxybDD1SWrQETbioXE9InlxABuxGJO0eEWzLfXXxMvNj2o92Wo6YqbkkQwi2KEOk7XvFZw==",
|
||||||
|
"requires": {
|
||||||
|
"filesize": ">= 4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nice-try": {
|
"nice-try": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,9 @@
|
||||||
"@angular/platform-browser": "~9.1.0",
|
"@angular/platform-browser": "~9.1.0",
|
||||||
"@angular/platform-browser-dynamic": "~9.1.0",
|
"@angular/platform-browser-dynamic": "~9.1.0",
|
||||||
"@angular/router": "~9.1.0",
|
"@angular/router": "~9.1.0",
|
||||||
|
"@fortawesome/fontawesome-free": "^5.13.0",
|
||||||
|
"bulma": "^0.8.1",
|
||||||
|
"ngx-filesize": "^2.0.13",
|
||||||
"rxjs": "~6.5.4",
|
"rxjs": "~6.5.4",
|
||||||
"tslib": "^1.10.0",
|
"tslib": "^1.10.0",
|
||||||
"zone.js": "~0.10.2"
|
"zone.js": "~0.10.2"
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,23 @@
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { Routes, RouterModule } from '@angular/router';
|
import { Routes, RouterModule } from '@angular/router';
|
||||||
|
import { MainLayoutComponent } from './main-layout/main-layout.component';
|
||||||
|
import { LoginComponent } from './login/login.component';
|
||||||
|
import { AuthGuard } from './auth.guard';
|
||||||
|
|
||||||
const routes: Routes = [];
|
const routes: Routes = [
|
||||||
|
{
|
||||||
|
path: 'login',
|
||||||
|
component: LoginComponent,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
component: MainLayoutComponent,
|
||||||
|
canActivate: [AuthGuard],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [RouterModule.forRoot(routes)],
|
imports: [RouterModule.forRoot(routes)],
|
||||||
exports: [RouterModule]
|
exports: [RouterModule],
|
||||||
})
|
})
|
||||||
export class AppRoutingModule {}
|
export class AppRoutingModule {}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import { Component } from '@angular/core';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
templateUrl: './app.component.html',
|
template: '<router-outlet></router-outlet>',
|
||||||
styleUrls: ['./app.component.scss']
|
styles: []
|
||||||
})
|
})
|
||||||
export class AppComponent {}
|
export class AppComponent {}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,44 @@
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
|
import { FormsModule } from '@angular/forms';
|
||||||
|
import { HttpClientModule } from '@angular/common/http';
|
||||||
|
import { NgxFilesizeModule, FileSizePipe } from 'ngx-filesize';
|
||||||
|
|
||||||
import { AppRoutingModule } from './app-routing.module';
|
import { AppRoutingModule } from './app-routing.module';
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
|
import { MainLayoutComponent } from './main-layout/main-layout.component';
|
||||||
|
import { NavbarComponent } from './navbar/navbar.component';
|
||||||
|
import { AddNewTorrentComponent } from './navbar/add-new-torrent/add-new-torrent.component';
|
||||||
|
import { TorrentTableComponent } from './torrent-table/torrent-table.component';
|
||||||
|
import { TorrentRowComponent } from './torrent-row/torrent-row.component';
|
||||||
|
import { TorrentFileComponent } from './torrent-file/torrent-file.component';
|
||||||
|
import { SettingsComponent } from './navbar/settings/settings.component';
|
||||||
|
import { TorrentStatusPipe } from './torrent-status.pipe';
|
||||||
|
import { FileStatusPipe } from './file-status.pipe';
|
||||||
|
import { LoginComponent } from './login/login.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [AppComponent],
|
declarations: [
|
||||||
imports: [BrowserModule, AppRoutingModule],
|
AppComponent,
|
||||||
providers: [],
|
MainLayoutComponent,
|
||||||
bootstrap: [AppComponent]
|
NavbarComponent,
|
||||||
|
AddNewTorrentComponent,
|
||||||
|
TorrentTableComponent,
|
||||||
|
TorrentRowComponent,
|
||||||
|
TorrentFileComponent,
|
||||||
|
SettingsComponent,
|
||||||
|
TorrentStatusPipe,
|
||||||
|
FileStatusPipe,
|
||||||
|
LoginComponent,
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
BrowserModule,
|
||||||
|
AppRoutingModule,
|
||||||
|
FormsModule,
|
||||||
|
HttpClientModule,
|
||||||
|
NgxFilesizeModule,
|
||||||
|
],
|
||||||
|
providers: [FileSizePipe],
|
||||||
|
bootstrap: [AppComponent],
|
||||||
})
|
})
|
||||||
export class AppModule {}
|
export class AppModule {}
|
||||||
|
|
|
||||||
27
client/src/app/auth.guard.ts
Normal file
27
client/src/app/auth.guard.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import {
|
||||||
|
CanActivate,
|
||||||
|
ActivatedRouteSnapshot,
|
||||||
|
RouterStateSnapshot,
|
||||||
|
Router,
|
||||||
|
} from '@angular/router';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { map } from 'rxjs/operators';
|
||||||
|
import { UsersService } from './users.service';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root',
|
||||||
|
})
|
||||||
|
export class AuthGuard implements CanActivate {
|
||||||
|
constructor(private router: Router, private usersService: UsersService) {}
|
||||||
|
|
||||||
|
canActivate(
|
||||||
|
route: ActivatedRouteSnapshot,
|
||||||
|
state: RouterStateSnapshot
|
||||||
|
): Observable<boolean> | Promise<boolean> | boolean {
|
||||||
|
return true;
|
||||||
|
|
||||||
|
//this.router.navigate(['/login'], { queryParams: { returnUrl: state.url } });
|
||||||
|
//return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
25
client/src/app/file-status.pipe.ts
Normal file
25
client/src/app/file-status.pipe.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { Pipe, PipeTransform } from '@angular/core';
|
||||||
|
import { TorrentFile } from './models/torrent.model';
|
||||||
|
import { DownloadStatus } from './models/download.model';
|
||||||
|
|
||||||
|
@Pipe({
|
||||||
|
name: 'fileStatus',
|
||||||
|
})
|
||||||
|
export class FileStatusPipe implements PipeTransform {
|
||||||
|
transform(value: TorrentFile): string {
|
||||||
|
if (
|
||||||
|
!value.download ||
|
||||||
|
value.download.status === DownloadStatus.PendingDownload
|
||||||
|
) {
|
||||||
|
return 'Pending';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.download.status === DownloadStatus.Downloading) {
|
||||||
|
return `${value.download.progress}%`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.download.status === DownloadStatus.Finished) {
|
||||||
|
return `Finished`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
36
client/src/app/login/login.component.html
Normal file
36
client/src/app/login/login.component.html
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
<section class="hero is-dark is-fullheight">
|
||||||
|
<div class="hero-body">
|
||||||
|
<div class="container">
|
||||||
|
<div class="columns is-centered">
|
||||||
|
<div class="column is-5-tablet is-4-desktop is-3-widescreen">
|
||||||
|
<img src="../../assets/logo.png" />
|
||||||
|
<form class="box">
|
||||||
|
<div class="field">
|
||||||
|
<label for="" class="label">Username</label>
|
||||||
|
<div class="control has-icons-left">
|
||||||
|
<input type="text" placeholder="" class="input" required />
|
||||||
|
<span class="icon is-small is-left">
|
||||||
|
<i class="fa fa-envelope"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label for="" class="label">Password</label>
|
||||||
|
<div class="control has-icons-left">
|
||||||
|
<input type="password" class="input" required />
|
||||||
|
<span class="icon is-small is-left">
|
||||||
|
<i class="fa fa-lock"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<button class="button is-success">
|
||||||
|
Login
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
15
client/src/app/login/login.component.ts
Normal file
15
client/src/app/login/login.component.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-login',
|
||||||
|
templateUrl: './login.component.html',
|
||||||
|
styleUrls: ['./login.component.scss']
|
||||||
|
})
|
||||||
|
export class LoginComponent implements OnInit {
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
6
client/src/app/main-layout/main-layout.component.html
Normal file
6
client/src/app/main-layout/main-layout.component.html
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
<app-navbar></app-navbar>
|
||||||
|
<section class="section main-list">
|
||||||
|
<div class="container">
|
||||||
|
<app-torrent-table></app-torrent-table>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
3
client/src/app/main-layout/main-layout.component.scss
Normal file
3
client/src/app/main-layout/main-layout.component.scss
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
.main-list {
|
||||||
|
padding-top: 6em;
|
||||||
|
}
|
||||||
12
client/src/app/main-layout/main-layout.component.ts
Normal file
12
client/src/app/main-layout/main-layout.component.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-main-layout',
|
||||||
|
templateUrl: './main-layout.component.html',
|
||||||
|
styleUrls: ['./main-layout.component.scss']
|
||||||
|
})
|
||||||
|
export class MainLayoutComponent implements OnInit {
|
||||||
|
constructor() {}
|
||||||
|
|
||||||
|
ngOnInit(): void {}
|
||||||
|
}
|
||||||
19
client/src/app/models/download.model.ts
Normal file
19
client/src/app/models/download.model.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
export class Download {
|
||||||
|
public downloadId: string;
|
||||||
|
|
||||||
|
public torrentId: string;
|
||||||
|
|
||||||
|
public link: string;
|
||||||
|
|
||||||
|
public added: Date;
|
||||||
|
|
||||||
|
public status: DownloadStatus;
|
||||||
|
|
||||||
|
public progress: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum DownloadStatus {
|
||||||
|
PendingDownload = 0,
|
||||||
|
Downloading,
|
||||||
|
Finished,
|
||||||
|
}
|
||||||
4
client/src/app/models/profile.model.ts
Normal file
4
client/src/app/models/profile.model.ts
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
export class Profile {
|
||||||
|
userName: string;
|
||||||
|
expiration: Date;
|
||||||
|
}
|
||||||
4
client/src/app/models/setting.model.ts
Normal file
4
client/src/app/models/setting.model.ts
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
export class Setting {
|
||||||
|
public settingId: string;
|
||||||
|
public value: string;
|
||||||
|
}
|
||||||
41
client/src/app/models/torrent.model.ts
Normal file
41
client/src/app/models/torrent.model.ts
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
import { Download } from './download.model';
|
||||||
|
|
||||||
|
export class Torrent {
|
||||||
|
torrentId: string;
|
||||||
|
hash: string;
|
||||||
|
status: TorrentStatus;
|
||||||
|
rdId: string;
|
||||||
|
rdName: string;
|
||||||
|
rdSize: number;
|
||||||
|
rdHost: string;
|
||||||
|
rdSplit: number;
|
||||||
|
rdProgress: number;
|
||||||
|
rdStatus: string;
|
||||||
|
rdAdded: Date;
|
||||||
|
rdEnded: Date;
|
||||||
|
rdSpeed: number;
|
||||||
|
rdSeeders: number;
|
||||||
|
rdFiles: string;
|
||||||
|
|
||||||
|
files: TorrentFile[];
|
||||||
|
downloads: Download[];
|
||||||
|
downloadProgress: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TorrentFile {
|
||||||
|
id: string;
|
||||||
|
path: string;
|
||||||
|
bytes: string;
|
||||||
|
selected: boolean;
|
||||||
|
|
||||||
|
download: Download;
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum TorrentStatus {
|
||||||
|
RealDebrid = 0,
|
||||||
|
WaitingForDownload,
|
||||||
|
Downloading,
|
||||||
|
Finished,
|
||||||
|
|
||||||
|
Error = 99,
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
<div class="modal" [class.is-active]="isActive">
|
||||||
|
<div class="modal-background"></div>
|
||||||
|
<div class="modal-card">
|
||||||
|
<header class="modal-card-head">
|
||||||
|
<p class="modal-card-title">Add New Torrent</p>
|
||||||
|
<button class="delete" aria-label="close" (click)="cancel()"></button>
|
||||||
|
</header>
|
||||||
|
<section class="modal-card-body">
|
||||||
|
<div class="field">
|
||||||
|
<label class="label">Magnet Link</label>
|
||||||
|
<div class="control">
|
||||||
|
<textarea
|
||||||
|
class="textarea"
|
||||||
|
placeholder="Paste your magnet link here"
|
||||||
|
[(ngModel)]="magnetLink"
|
||||||
|
[disabled]="saving"
|
||||||
|
></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<div class="field">
|
||||||
|
<label class="label">Torrent file</label>
|
||||||
|
<div class="file has-name">
|
||||||
|
<label class="file-label">
|
||||||
|
<input
|
||||||
|
class="file-input"
|
||||||
|
type="file"
|
||||||
|
name="resume"
|
||||||
|
(change)="pickFile($event)"
|
||||||
|
[disabled]="saving"
|
||||||
|
/>
|
||||||
|
<span class="file-cta">
|
||||||
|
<span class="file-icon">
|
||||||
|
<i class="fas fa-upload"></i>
|
||||||
|
</span>
|
||||||
|
<span class="file-label">
|
||||||
|
Pick a torrent file...
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<span class="file-name">
|
||||||
|
{{ fileName }}
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="notification is-danger is-light" *ngIf="error?.length > 0">
|
||||||
|
Cannot add torrent: {{ error }}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<footer class="modal-card-foot">
|
||||||
|
<button class="button is-success" *ngIf="saving">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fas fa-spinner fa-pulse"></i>
|
||||||
|
</span>
|
||||||
|
<span>Add Torrent</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button class="button is-success" (click)="ok()" *ngIf="!saving">
|
||||||
|
Add Torrent
|
||||||
|
</button>
|
||||||
|
<button class="button" (click)="cancel()" [disabled]="saving">
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
.file-name {
|
||||||
|
max-width: 24em;
|
||||||
|
width: 24em;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,91 @@
|
||||||
|
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
||||||
|
import { TorrentService } from 'src/app/torrent.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-add-new-torrent',
|
||||||
|
templateUrl: './add-new-torrent.component.html',
|
||||||
|
styleUrls: ['./add-new-torrent.component.scss']
|
||||||
|
})
|
||||||
|
export class AddNewTorrentComponent implements OnInit {
|
||||||
|
@Input()
|
||||||
|
public get open(): boolean {
|
||||||
|
return this.isActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set open(val: boolean) {
|
||||||
|
this.reset();
|
||||||
|
this.isActive = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
public openChange = new EventEmitter<boolean>();
|
||||||
|
|
||||||
|
public isActive = false;
|
||||||
|
|
||||||
|
public fileName: string;
|
||||||
|
public magnetLink: string;
|
||||||
|
public saving = false;
|
||||||
|
public error: string;
|
||||||
|
|
||||||
|
private selectedFile: File;
|
||||||
|
|
||||||
|
constructor(private torrentService: TorrentService) {}
|
||||||
|
|
||||||
|
ngOnInit(): void {}
|
||||||
|
|
||||||
|
public reset(): void {
|
||||||
|
this.fileName = '';
|
||||||
|
this.magnetLink = '';
|
||||||
|
this.saving = false;
|
||||||
|
this.selectedFile = null;
|
||||||
|
this.error = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public pickFile(evt: Event): void {
|
||||||
|
const files = (evt.target as HTMLInputElement).files;
|
||||||
|
|
||||||
|
if (files.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const file = files[0];
|
||||||
|
|
||||||
|
this.fileName = file.name;
|
||||||
|
|
||||||
|
this.selectedFile = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ok(): void {
|
||||||
|
this.saving = true;
|
||||||
|
this.error = null;
|
||||||
|
|
||||||
|
if (this.magnetLink) {
|
||||||
|
this.torrentService.uploadMagnet(this.magnetLink).subscribe(
|
||||||
|
() => {
|
||||||
|
this.cancel();
|
||||||
|
},
|
||||||
|
err => {
|
||||||
|
this.error = err.error;
|
||||||
|
this.saving = false;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else if (this.selectedFile) {
|
||||||
|
this.torrentService.uploadFile(this.selectedFile).subscribe(
|
||||||
|
() => {
|
||||||
|
this.cancel();
|
||||||
|
},
|
||||||
|
err => {
|
||||||
|
this.error = err.error;
|
||||||
|
this.saving = false;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
this.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public cancel(): void {
|
||||||
|
this.isActive = false;
|
||||||
|
this.openChange.emit(this.open);
|
||||||
|
}
|
||||||
|
}
|
||||||
77
client/src/app/navbar/navbar.component.html
Normal file
77
client/src/app/navbar/navbar.component.html
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
<nav
|
||||||
|
class="navbar is-dark is-fixed-top"
|
||||||
|
role="navigation"
|
||||||
|
aria-label="main navigation"
|
||||||
|
>
|
||||||
|
<div class="navbar-brand">
|
||||||
|
<a class="navbar-item">
|
||||||
|
<img src="../../assets/logo.png" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a
|
||||||
|
role="button"
|
||||||
|
class="navbar-burger burger"
|
||||||
|
aria-label="menu"
|
||||||
|
aria-expanded="false"
|
||||||
|
[class.is-active]="showMobileMenu"
|
||||||
|
(click)="showMobileMenu = !showMobileMenu"
|
||||||
|
>
|
||||||
|
<span aria-hidden="true"></span>
|
||||||
|
<span aria-hidden="true"></span>
|
||||||
|
<span aria-hidden="true"></span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="navbar-menu" [class.is-active]="showMobileMenu">
|
||||||
|
<div class="navbar-start">
|
||||||
|
<a class="navbar-item" (click)="this.showNewTorrent = true">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fas fa-plus" aria-hidden="true"></i>
|
||||||
|
</span>
|
||||||
|
<span>Add New Torrent</span>
|
||||||
|
</a>
|
||||||
|
<a class="navbar-item" (click)="this.showSettings = true">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fas fa-cog" aria-hidden="true"></i>
|
||||||
|
</span>
|
||||||
|
<span>Settings</span>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class="navbar-item"
|
||||||
|
*ngIf="profile"
|
||||||
|
href="https://real-debrid.com/?id=1348683"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
>
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fas fa-euro-sign" aria-hidden="true"></i>
|
||||||
|
</span>
|
||||||
|
<span>Premium Status: {{ profile.expiration | date }}</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="navbar-end">
|
||||||
|
<div class="navbar-item has-dropdown is-hoverable">
|
||||||
|
<span class="navbar-link">
|
||||||
|
Account
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div class="navbar-dropdown is-right">
|
||||||
|
<a class="navbar-item">
|
||||||
|
Profile
|
||||||
|
</a>
|
||||||
|
<a class="navbar-item">
|
||||||
|
Logout
|
||||||
|
</a>
|
||||||
|
<hr class="navbar-divider" />
|
||||||
|
<div class="navbar-item">
|
||||||
|
Version 0.8.0
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<app-add-new-torrent [(open)]="showNewTorrent"></app-add-new-torrent>
|
||||||
|
<app-settings [(open)]="showSettings"></app-settings>
|
||||||
26
client/src/app/navbar/navbar.component.ts
Normal file
26
client/src/app/navbar/navbar.component.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { TorrentService } from '../torrent.service';
|
||||||
|
import { SettingsService } from '../settings.service';
|
||||||
|
import { Profile } from '../models/profile.model';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-navbar',
|
||||||
|
templateUrl: './navbar.component.html',
|
||||||
|
styleUrls: ['./navbar.component.scss'],
|
||||||
|
})
|
||||||
|
export class NavbarComponent implements OnInit {
|
||||||
|
public showMobileMenu = false;
|
||||||
|
|
||||||
|
public showNewTorrent = false;
|
||||||
|
public showSettings = false;
|
||||||
|
|
||||||
|
public profile: Profile;
|
||||||
|
|
||||||
|
constructor(private settingsService: SettingsService) {}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.settingsService.getProfile().subscribe((result) => {
|
||||||
|
this.profile = result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
79
client/src/app/navbar/settings/settings.component.html
Normal file
79
client/src/app/navbar/settings/settings.component.html
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
<div class="modal" [class.is-active]="isActive">
|
||||||
|
<div class="modal-background"></div>
|
||||||
|
<div class="modal-card">
|
||||||
|
<header class="modal-card-head">
|
||||||
|
<p class="modal-card-title">Settings</p>
|
||||||
|
<button class="delete" aria-label="close" (click)="cancel()"></button>
|
||||||
|
</header>
|
||||||
|
<section class="modal-card-body">
|
||||||
|
<div class="field">
|
||||||
|
<label class="label">Real-Debrid API Key</label>
|
||||||
|
<div class="control">
|
||||||
|
<input
|
||||||
|
class="input"
|
||||||
|
type="text"
|
||||||
|
maxlength="100"
|
||||||
|
[(ngModel)]="settingRealDebridApiKey"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<p class="help">
|
||||||
|
You can find your API key here:
|
||||||
|
<a
|
||||||
|
href="https://real-debrid.com/apitoken"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
>https://real-debrid.com/apitoken</a
|
||||||
|
>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label class="label">Download folder</label>
|
||||||
|
<div class="control">
|
||||||
|
<input
|
||||||
|
class="input"
|
||||||
|
type="text"
|
||||||
|
maxlength="1000"
|
||||||
|
[(ngModel)]="settingDownloadFolder"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<p class="help">
|
||||||
|
Path on the host where Real Debrid Client is hosted.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label class="label">Maximum parallel downloads</label>
|
||||||
|
<div class="control">
|
||||||
|
<input
|
||||||
|
class="input"
|
||||||
|
type="number"
|
||||||
|
max="100"
|
||||||
|
min="1"
|
||||||
|
[(ngModel)]="settingDownloadLimit"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<p class="help">
|
||||||
|
Maximum amount of torrents that get downloaded to your host at the
|
||||||
|
same time.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="notification is-danger is-light" *ngIf="error?.length > 0">
|
||||||
|
Error saving settings: {{ error }}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<footer class="modal-card-foot">
|
||||||
|
<button class="button is-success" *ngIf="saving">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fas fa-spinner fa-pulse"></i>
|
||||||
|
</span>
|
||||||
|
<span>Save Settings</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button class="button is-success" (click)="ok()" *ngIf="!saving">
|
||||||
|
Save Settings
|
||||||
|
</button>
|
||||||
|
<button class="button" (click)="cancel()" [disabled]="saving">
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
103
client/src/app/navbar/settings/settings.component.ts
Normal file
103
client/src/app/navbar/settings/settings.component.ts
Normal file
|
|
@ -0,0 +1,103 @@
|
||||||
|
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
||||||
|
import { SettingsService } from 'src/app/settings.service';
|
||||||
|
import { Setting } from 'src/app/models/setting.model';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-settings',
|
||||||
|
templateUrl: './settings.component.html',
|
||||||
|
styleUrls: ['./settings.component.scss'],
|
||||||
|
})
|
||||||
|
export class SettingsComponent implements OnInit {
|
||||||
|
@Input()
|
||||||
|
public get open(): boolean {
|
||||||
|
return this.isActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set open(val: boolean) {
|
||||||
|
this.reset();
|
||||||
|
this.isActive = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
public openChange = new EventEmitter<boolean>();
|
||||||
|
|
||||||
|
public isActive = false;
|
||||||
|
|
||||||
|
public saving = false;
|
||||||
|
public error: string;
|
||||||
|
|
||||||
|
public settingRealDebridApiKey: string;
|
||||||
|
public settingDownloadFolder: string;
|
||||||
|
public settingDownloadLimit: number;
|
||||||
|
|
||||||
|
constructor(private settingsService: SettingsService) {}
|
||||||
|
|
||||||
|
ngOnInit(): void {}
|
||||||
|
|
||||||
|
public reset(): void {
|
||||||
|
this.saving = false;
|
||||||
|
this.error = null;
|
||||||
|
|
||||||
|
this.settingsService.get().subscribe(
|
||||||
|
(results) => {
|
||||||
|
this.settingRealDebridApiKey = this.getSetting(
|
||||||
|
results,
|
||||||
|
'RealDebridApiKey'
|
||||||
|
);
|
||||||
|
this.settingDownloadFolder = this.getSetting(results, 'DownloadFolder');
|
||||||
|
this.settingDownloadLimit = parseInt(
|
||||||
|
this.getSetting(results, 'DownloadLimit'),
|
||||||
|
10
|
||||||
|
);
|
||||||
|
},
|
||||||
|
(err) => {
|
||||||
|
this.error = err.error;
|
||||||
|
this.saving = true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ok(): void {
|
||||||
|
this.saving = true;
|
||||||
|
|
||||||
|
const settings: Setting[] = [
|
||||||
|
{
|
||||||
|
settingId: 'RealDebridApiKey',
|
||||||
|
value: this.settingRealDebridApiKey,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
settingId: 'DownloadFolder',
|
||||||
|
value: this.settingDownloadFolder,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
settingId: 'DownloadLimit',
|
||||||
|
value: (this.settingDownloadLimit ?? 10).toString(),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
this.settingsService.update(settings).subscribe(
|
||||||
|
() => {
|
||||||
|
this.isActive = false;
|
||||||
|
this.openChange.emit(this.open);
|
||||||
|
},
|
||||||
|
(err) => {
|
||||||
|
this.error = err;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public cancel(): void {
|
||||||
|
this.isActive = false;
|
||||||
|
this.openChange.emit(this.open);
|
||||||
|
}
|
||||||
|
|
||||||
|
private getSetting(settings: Setting[], key: string): string {
|
||||||
|
const setting = settings.filter((m) => m.settingId === key);
|
||||||
|
|
||||||
|
if (setting.length !== 1) {
|
||||||
|
throw new Error(`Unable to find setting with key ${key}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return setting[0].value;
|
||||||
|
}
|
||||||
|
}
|
||||||
24
client/src/app/settings.service.ts
Normal file
24
client/src/app/settings.service.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { HttpClient } from '@angular/common/http';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { Setting } from './models/setting.model';
|
||||||
|
import { Profile } from './models/profile.model';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root',
|
||||||
|
})
|
||||||
|
export class SettingsService {
|
||||||
|
constructor(private http: HttpClient) {}
|
||||||
|
|
||||||
|
public get(): Observable<Setting[]> {
|
||||||
|
return this.http.get<Setting[]>(`/Api/Settings`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public update(settings: Setting[]): Observable<void> {
|
||||||
|
return this.http.put<void>(`/Api/Settings`, { settings });
|
||||||
|
}
|
||||||
|
|
||||||
|
public getProfile(): Observable<Profile> {
|
||||||
|
return this.http.get<Profile>(`/Api/Settings/Profile`);
|
||||||
|
}
|
||||||
|
}
|
||||||
10
client/src/app/torrent-file/torrent-file.component.html
Normal file
10
client/src/app/torrent-file/torrent-file.component.html
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
<td>
|
||||||
|
<i class="fas fa-file" aria-hidden="true"></i>
|
||||||
|
{{ file.path }}
|
||||||
|
</td>
|
||||||
|
<td>{{ file.bytes | filesize }}</td>
|
||||||
|
<td>
|
||||||
|
{{ file | fileStatus }}
|
||||||
|
</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
3
client/src/app/torrent-file/torrent-file.component.scss
Normal file
3
client/src/app/torrent-file/torrent-file.component.scss
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
td {
|
||||||
|
font-size: smaller;
|
||||||
|
}
|
||||||
17
client/src/app/torrent-file/torrent-file.component.ts
Normal file
17
client/src/app/torrent-file/torrent-file.component.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
import { Component, OnInit, Input } from '@angular/core';
|
||||||
|
import { Torrent, TorrentFile } from '../models/torrent.model';
|
||||||
|
import { TorrentService } from '../torrent.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: '[app-torrent-file]',
|
||||||
|
templateUrl: './torrent-file.component.html',
|
||||||
|
styleUrls: ['./torrent-file.component.scss'],
|
||||||
|
})
|
||||||
|
export class TorrentFileComponent implements OnInit {
|
||||||
|
@Input()
|
||||||
|
public file: TorrentFile;
|
||||||
|
|
||||||
|
constructor(private torrentService: TorrentService) {}
|
||||||
|
|
||||||
|
ngOnInit(): void {}
|
||||||
|
}
|
||||||
27
client/src/app/torrent-row/torrent-row.component.html
Normal file
27
client/src/app/torrent-row/torrent-row.component.html
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
<td>{{ torrent.rdName }}</td>
|
||||||
|
<td>
|
||||||
|
{{ torrent.rdSize | filesize }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ torrent | status }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span
|
||||||
|
class="icon download-icon"
|
||||||
|
(click)="download($event)"
|
||||||
|
title="Download to disk"
|
||||||
|
*ngIf="!loading && torrent.status === 1"
|
||||||
|
>
|
||||||
|
<i class="fas fa-download"></i>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span
|
||||||
|
class="icon delete-icon"
|
||||||
|
(click)="delete($event)"
|
||||||
|
title="Delete torrent"
|
||||||
|
*ngIf="!loading"
|
||||||
|
>
|
||||||
|
<i class="fas fa-times"></i>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
4
client/src/app/torrent-row/torrent-row.component.scss
Normal file
4
client/src/app/torrent-row/torrent-row.component.scss
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
.delete-icon {
|
||||||
|
color: red;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
36
client/src/app/torrent-row/torrent-row.component.ts
Normal file
36
client/src/app/torrent-row/torrent-row.component.ts
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
import { Component, OnInit, Input } from '@angular/core';
|
||||||
|
import { Torrent, TorrentStatus } from 'src/app/models/torrent.model';
|
||||||
|
import { TorrentService } from 'src/app/torrent.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: '[app-torrent-row]',
|
||||||
|
templateUrl: './torrent-row.component.html',
|
||||||
|
styleUrls: ['./torrent-row.component.scss'],
|
||||||
|
})
|
||||||
|
export class TorrentRowComponent implements OnInit {
|
||||||
|
@Input()
|
||||||
|
public torrent: Torrent;
|
||||||
|
|
||||||
|
public loading = false;
|
||||||
|
|
||||||
|
constructor(private torrentService: TorrentService) {}
|
||||||
|
|
||||||
|
ngOnInit(): void {}
|
||||||
|
|
||||||
|
public download(event: Event): void {
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
|
this.loading = true;
|
||||||
|
this.torrentService.download(this.torrent.torrentId).subscribe(() => {
|
||||||
|
this.loading = false;
|
||||||
|
this.torrent.status = TorrentStatus.Downloading;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public delete(event: Event): void {
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
|
this.loading = true;
|
||||||
|
this.torrentService.delete(this.torrent.torrentId).subscribe(() => {});
|
||||||
|
}
|
||||||
|
}
|
||||||
28
client/src/app/torrent-status.pipe.ts
Normal file
28
client/src/app/torrent-status.pipe.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
import { Pipe, PipeTransform } from '@angular/core';
|
||||||
|
import { Torrent, TorrentStatus } from './models/torrent.model';
|
||||||
|
import { FileSizePipe } from 'ngx-filesize';
|
||||||
|
|
||||||
|
@Pipe({
|
||||||
|
name: 'status',
|
||||||
|
})
|
||||||
|
export class TorrentStatusPipe implements PipeTransform {
|
||||||
|
constructor(private pipe: FileSizePipe) {}
|
||||||
|
|
||||||
|
transform(torrent: Torrent): string {
|
||||||
|
switch (torrent.status) {
|
||||||
|
case TorrentStatus.RealDebrid:
|
||||||
|
const speed = this.pipe.transform(torrent.rdSpeed, 'filesize');
|
||||||
|
return `Downloading from RD (${torrent.rdProgress}% - ${speed}/s)`;
|
||||||
|
case TorrentStatus.WaitingForDownload:
|
||||||
|
return `Waiting to download`;
|
||||||
|
case TorrentStatus.Downloading:
|
||||||
|
return `Downloading (${torrent.downloadProgress}%)`;
|
||||||
|
case TorrentStatus.Finished:
|
||||||
|
return `Finished`;
|
||||||
|
case TorrentStatus.Error:
|
||||||
|
return `Error`;
|
||||||
|
default:
|
||||||
|
return 'Unknown status';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
48
client/src/app/torrent-table/torrent-table.component.html
Normal file
48
client/src/app/torrent-table/torrent-table.component.html
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
<div class="table-container">
|
||||||
|
<table class="table is-fullwidth is-hoverable">
|
||||||
|
<colgroup>
|
||||||
|
<col />
|
||||||
|
<col />
|
||||||
|
<col />
|
||||||
|
<col style="width: 50px;" />
|
||||||
|
<col style="width: 50px;" />
|
||||||
|
</colgroup>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Size</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th></th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<ng-container *ngFor="let torrent of torrents; trackBy: trackByMethod">
|
||||||
|
<tr
|
||||||
|
app-torrent-row
|
||||||
|
[torrent]="torrent"
|
||||||
|
(click)="selectTorrent(torrent)"
|
||||||
|
></tr>
|
||||||
|
|
||||||
|
<ng-container
|
||||||
|
*ngIf="showFiles[torrent.torrentId] && torrent?.files.length === 0"
|
||||||
|
>
|
||||||
|
<tr>
|
||||||
|
<td colspan="20">
|
||||||
|
<i class="fas fa-spinner fa-pulse"></i>
|
||||||
|
</td>
|
||||||
|
</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>
|
||||||
|
</ng-container>
|
||||||
|
</ng-container>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
table {
|
||||||
|
tr {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
61
client/src/app/torrent-table/torrent-table.component.ts
Normal file
61
client/src/app/torrent-table/torrent-table.component.ts
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
import {
|
||||||
|
Component,
|
||||||
|
OnInit,
|
||||||
|
OnDestroy,
|
||||||
|
HostListener,
|
||||||
|
ElementRef,
|
||||||
|
} from '@angular/core';
|
||||||
|
import { Torrent } from '../models/torrent.model';
|
||||||
|
import { TorrentService } from '../torrent.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-torrent-table',
|
||||||
|
templateUrl: './torrent-table.component.html',
|
||||||
|
styleUrls: ['./torrent-table.component.scss'],
|
||||||
|
})
|
||||||
|
export class TorrentTableComponent implements OnInit, OnDestroy {
|
||||||
|
public torrents: Torrent[] = [];
|
||||||
|
|
||||||
|
public showFiles: { [key: string]: boolean } = {};
|
||||||
|
|
||||||
|
private timer: any;
|
||||||
|
|
||||||
|
constructor(private torrentService: TorrentService) {}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.timer = setInterval(() => {
|
||||||
|
this.torrentService.getList().subscribe((result) => {
|
||||||
|
this.torrents = result;
|
||||||
|
});
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
clearInterval(this.timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public selectTorrent(torrent: Torrent): void {
|
||||||
|
this.showFiles[torrent.torrentId] = !this.showFiles[torrent.torrentId];
|
||||||
|
|
||||||
|
if (this.showFiles[torrent.torrentId]) {
|
||||||
|
this.torrentService.getDetails(torrent.torrentId).subscribe((result) => {
|
||||||
|
torrent.files = result.files;
|
||||||
|
torrent.downloads = result.downloads;
|
||||||
|
|
||||||
|
torrent.files.forEach((file) => {
|
||||||
|
const downloads = torrent.downloads.filter(
|
||||||
|
(m) => m.link === file.path
|
||||||
|
);
|
||||||
|
|
||||||
|
if (downloads.length > 0) {
|
||||||
|
file.download = downloads[0];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public trackByMethod(index: number, el: Torrent): string {
|
||||||
|
return el.torrentId;
|
||||||
|
}
|
||||||
|
}
|
||||||
37
client/src/app/torrent.service.ts
Normal file
37
client/src/app/torrent.service.ts
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { HttpClient } from '@angular/common/http';
|
||||||
|
import { Observable, Subject } from 'rxjs';
|
||||||
|
import { Torrent } from './models/torrent.model';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root',
|
||||||
|
})
|
||||||
|
export class TorrentService {
|
||||||
|
constructor(private http: HttpClient) {}
|
||||||
|
|
||||||
|
public getList(): Observable<Torrent[]> {
|
||||||
|
return this.http.get<Torrent[]>(`/Api/Torrents`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getDetails(torrentId: string): Observable<Torrent> {
|
||||||
|
return this.http.get<Torrent>(`/Api/Torrents/${torrentId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public uploadMagnet(magnetLink: string): Observable<void> {
|
||||||
|
return this.http.post<void>(`/Api/Torrents/UploadMagnet`, { magnetLink });
|
||||||
|
}
|
||||||
|
|
||||||
|
public uploadFile(file: File): Observable<void> {
|
||||||
|
const formData: FormData = new FormData();
|
||||||
|
formData.append('file', file);
|
||||||
|
return this.http.post<void>(`/Api/Torrents/UploadFile`, formData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public download(torrentId: string): Observable<void> {
|
||||||
|
return this.http.get<void>(`/Api/Torrents/Download/${torrentId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public delete(torrentId: string): Observable<void> {
|
||||||
|
return this.http.delete<void>(`/Api/Torrents/${torrentId}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
10
client/src/app/users.service.ts
Normal file
10
client/src/app/users.service.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root',
|
||||||
|
})
|
||||||
|
export class UsersService {
|
||||||
|
constructor() {}
|
||||||
|
|
||||||
|
public getLoggedInUser() {}
|
||||||
|
}
|
||||||
BIN
client/src/assets/logo.png
Normal file
BIN
client/src/assets/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
|
|
@ -1 +1,2 @@
|
||||||
/* You can add global styles to this file, and also import other style files */
|
@import "../node_modules/bulma/bulma.sass";
|
||||||
|
@import "../node_modules/@fortawesome/fontawesome-free/css/all.css";
|
||||||
|
|
|
||||||
60
server/RdtClient.Data/Data/DataContext.cs
Normal file
60
server/RdtClient.Data/Data/DataContext.cs
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
using System;
|
||||||
|
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using RdtClient.Data.Models.Data;
|
||||||
|
|
||||||
|
namespace RdtClient.Data.Data
|
||||||
|
{
|
||||||
|
public class DataContext : IdentityDbContext
|
||||||
|
{
|
||||||
|
public DataContext(DbContextOptions options) : base(options)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataContext()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String ConnectionString => $"Data Source={AppContext.BaseDirectory}database.db";
|
||||||
|
|
||||||
|
public DbSet<Download> Downloads { get; set; }
|
||||||
|
public DbSet<Setting> Settings { get; set; }
|
||||||
|
public DbSet<Torrent> Torrents { get; set; }
|
||||||
|
|
||||||
|
protected override void OnConfiguring(DbContextOptionsBuilder options) => options.UseSqlite(ConnectionString);
|
||||||
|
|
||||||
|
protected override void OnModelCreating(ModelBuilder builder)
|
||||||
|
{
|
||||||
|
base.OnModelCreating(builder);
|
||||||
|
|
||||||
|
builder.Entity<Setting>()
|
||||||
|
.HasData(new Setting
|
||||||
|
{
|
||||||
|
SettingId = "RealDebridApiKey",
|
||||||
|
Type = "String",
|
||||||
|
Value = ""
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<Setting>()
|
||||||
|
.HasData(new Setting
|
||||||
|
{
|
||||||
|
SettingId = "DownloadFolder",
|
||||||
|
Type = "String",
|
||||||
|
Value = @"C:\Downloads"
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<Setting>()
|
||||||
|
.HasData(new Setting
|
||||||
|
{
|
||||||
|
SettingId = "DownloadLimit",
|
||||||
|
Type = "Int32",
|
||||||
|
Value = "10"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Migrate()
|
||||||
|
{
|
||||||
|
Database.Migrate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
71
server/RdtClient.Data/Data/DownloadData.cs
Normal file
71
server/RdtClient.Data/Data/DownloadData.cs
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using RdtClient.Data.Enums;
|
||||||
|
using RdtClient.Data.Models.Data;
|
||||||
|
|
||||||
|
namespace RdtClient.Data.Data
|
||||||
|
{
|
||||||
|
public interface IDownloadData
|
||||||
|
{
|
||||||
|
Task<IList<Download>> Get();
|
||||||
|
Task<Download> Add(Guid torrentId, String link);
|
||||||
|
Task UpdateStatus(Guid downloadId, DownloadStatus status);
|
||||||
|
Task DeleteForTorrent(Guid torrentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DownloadData : IDownloadData
|
||||||
|
{
|
||||||
|
private readonly DataContext _dataContext;
|
||||||
|
|
||||||
|
public DownloadData(DataContext dataContext)
|
||||||
|
{
|
||||||
|
_dataContext = dataContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IList<Download>> Get()
|
||||||
|
{
|
||||||
|
return await _dataContext.Downloads.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Download> Add(Guid torrentId, String link)
|
||||||
|
{
|
||||||
|
var download = new Download
|
||||||
|
{
|
||||||
|
DownloadId = Guid.NewGuid(),
|
||||||
|
TorrentId = torrentId,
|
||||||
|
Link = link,
|
||||||
|
Added = DateTimeOffset.UtcNow,
|
||||||
|
Status = DownloadStatus.PendingDownload
|
||||||
|
};
|
||||||
|
|
||||||
|
_dataContext.Downloads.Add(download);
|
||||||
|
|
||||||
|
await _dataContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
return download;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task UpdateStatus(Guid downloadId, DownloadStatus status)
|
||||||
|
{
|
||||||
|
var download = await _dataContext.Downloads.FirstOrDefaultAsync(m => m.DownloadId == downloadId);
|
||||||
|
|
||||||
|
download.Status = status;
|
||||||
|
|
||||||
|
await _dataContext.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task DeleteForTorrent(Guid torrentId)
|
||||||
|
{
|
||||||
|
var downloads = await _dataContext.Downloads
|
||||||
|
.Where(m => m.TorrentId == torrentId)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
_dataContext.Downloads.RemoveRange(downloads);
|
||||||
|
|
||||||
|
await _dataContext.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
53
server/RdtClient.Data/Data/SettingData.cs
Normal file
53
server/RdtClient.Data/Data/SettingData.cs
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using RdtClient.Data.Models.Data;
|
||||||
|
|
||||||
|
namespace RdtClient.Data.Data
|
||||||
|
{
|
||||||
|
public interface ISettingData
|
||||||
|
{
|
||||||
|
Task<IList<Setting>> GetAll();
|
||||||
|
Task Update(IList<Setting> settings);
|
||||||
|
Task<Setting> Get(String key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SettingData : ISettingData
|
||||||
|
{
|
||||||
|
private readonly DataContext _dataContext;
|
||||||
|
|
||||||
|
public SettingData(DataContext dataContext)
|
||||||
|
{
|
||||||
|
_dataContext = dataContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IList<Setting>> GetAll()
|
||||||
|
{
|
||||||
|
return await _dataContext.Settings.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Update(IList<Setting> settings)
|
||||||
|
{
|
||||||
|
var dbSettings = await _dataContext.Settings.ToListAsync();
|
||||||
|
|
||||||
|
foreach (var dbSetting in dbSettings)
|
||||||
|
{
|
||||||
|
var setting = settings.FirstOrDefault(m => m.SettingId == dbSetting.SettingId);
|
||||||
|
|
||||||
|
if (setting != null)
|
||||||
|
{
|
||||||
|
dbSetting.Value = setting.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await _dataContext.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Setting> Get(String key)
|
||||||
|
{
|
||||||
|
return await _dataContext.Settings.FirstOrDefaultAsync(m => m.SettingId == key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
101
server/RdtClient.Data/Data/TorrentData.cs
Normal file
101
server/RdtClient.Data/Data/TorrentData.cs
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using RdtClient.Data.Enums;
|
||||||
|
using RdtClient.Data.Models.Data;
|
||||||
|
|
||||||
|
namespace RdtClient.Data.Data
|
||||||
|
{
|
||||||
|
public interface ITorrentData
|
||||||
|
{
|
||||||
|
Task<IList<Torrent>> Get();
|
||||||
|
Task<Torrent> Get(Guid id);
|
||||||
|
Task<Torrent> Add(String realDebridId, String hash);
|
||||||
|
Task UpdateRdData(Torrent torrent);
|
||||||
|
Task UpdateStatus(Guid torrentId, TorrentStatus status);
|
||||||
|
Task Delete(Guid id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TorrentData : ITorrentData
|
||||||
|
{
|
||||||
|
private readonly DataContext _dataContext;
|
||||||
|
|
||||||
|
public TorrentData(DataContext dataContext)
|
||||||
|
{
|
||||||
|
_dataContext = dataContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IList<Torrent>> Get()
|
||||||
|
{
|
||||||
|
return await _dataContext.Torrents.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Torrent> Get(Guid id)
|
||||||
|
{
|
||||||
|
var results = await _dataContext.Torrents
|
||||||
|
.Include(m => m.Downloads)
|
||||||
|
.FirstOrDefaultAsync(m => m.TorrentId == id);
|
||||||
|
|
||||||
|
foreach (var file in results.Downloads)
|
||||||
|
{
|
||||||
|
file.Torrent = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Torrent> Add(String realDebridId, String hash)
|
||||||
|
{
|
||||||
|
var torrent = new Torrent
|
||||||
|
{
|
||||||
|
TorrentId = Guid.NewGuid(),
|
||||||
|
RdId = realDebridId,
|
||||||
|
Hash = hash,
|
||||||
|
Status = TorrentStatus.RealDebrid
|
||||||
|
};
|
||||||
|
|
||||||
|
_dataContext.Torrents.Add(torrent);
|
||||||
|
|
||||||
|
await _dataContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
return torrent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task UpdateRdData(Torrent torrent)
|
||||||
|
{
|
||||||
|
var dbTorrent = await _dataContext.Torrents.FirstOrDefaultAsync(m => m.TorrentId == torrent.TorrentId);
|
||||||
|
|
||||||
|
dbTorrent.RdName = torrent.RdName;
|
||||||
|
dbTorrent.RdSize = torrent.RdSize;
|
||||||
|
dbTorrent.RdHost = torrent.RdHost;
|
||||||
|
dbTorrent.RdSplit = torrent.RdSplit;
|
||||||
|
dbTorrent.RdProgress = torrent.RdProgress;
|
||||||
|
dbTorrent.RdStatus = torrent.RdStatus;
|
||||||
|
dbTorrent.RdAdded = torrent.RdAdded;
|
||||||
|
dbTorrent.RdEnded = torrent.RdEnded;
|
||||||
|
dbTorrent.RdSpeed = torrent.RdSpeed;
|
||||||
|
dbTorrent.RdSeeders = torrent.RdSeeders;
|
||||||
|
|
||||||
|
await _dataContext.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task UpdateStatus(Guid torrentId, TorrentStatus status)
|
||||||
|
{
|
||||||
|
var dbTorrent = await _dataContext.Torrents.FirstOrDefaultAsync(m => m.TorrentId == torrentId);
|
||||||
|
|
||||||
|
dbTorrent.Status = status;
|
||||||
|
|
||||||
|
await _dataContext.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Delete(Guid id)
|
||||||
|
{
|
||||||
|
var dbTorrent = await _dataContext.Torrents.FirstOrDefaultAsync(m => m.TorrentId == id);
|
||||||
|
|
||||||
|
_dataContext.Torrents.Remove(dbTorrent);
|
||||||
|
|
||||||
|
await _dataContext.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace RdtClient.Data.DataContext
|
|
||||||
{
|
|
||||||
public class DataContext : IdentityDbContext
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using RdtClient.Data.Data;
|
||||||
|
|
||||||
namespace RdtClient.Data
|
namespace RdtClient.Data
|
||||||
{
|
{
|
||||||
|
|
@ -6,7 +7,9 @@ namespace RdtClient.Data
|
||||||
{
|
{
|
||||||
public static void Config(IServiceCollection services)
|
public static void Config(IServiceCollection services)
|
||||||
{
|
{
|
||||||
//services.AddScoped<IFql, Fql>();
|
services.AddScoped<IDownloadData, DownloadData>();
|
||||||
|
services.AddScoped<ISettingData, SettingData>();
|
||||||
|
services.AddScoped<ITorrentData, TorrentData>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
9
server/RdtClient.Data/Enums/DownloadStatus.cs
Normal file
9
server/RdtClient.Data/Enums/DownloadStatus.cs
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
namespace RdtClient.Data.Enums
|
||||||
|
{
|
||||||
|
public enum DownloadStatus
|
||||||
|
{
|
||||||
|
PendingDownload = 0,
|
||||||
|
Downloading,
|
||||||
|
Finished
|
||||||
|
}
|
||||||
|
}
|
||||||
12
server/RdtClient.Data/Enums/TorrentStatus.cs
Normal file
12
server/RdtClient.Data/Enums/TorrentStatus.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
namespace RdtClient.Data.Enums
|
||||||
|
{
|
||||||
|
public enum TorrentStatus
|
||||||
|
{
|
||||||
|
RealDebrid = 0,
|
||||||
|
WaitingForDownload,
|
||||||
|
Downloading,
|
||||||
|
Finished,
|
||||||
|
|
||||||
|
Error = 99
|
||||||
|
}
|
||||||
|
}
|
||||||
395
server/RdtClient.Data/Migrations/20200403195110_Initial.Designer.cs
generated
Normal file
395
server/RdtClient.Data/Migrations/20200403195110_Initial.Designer.cs
generated
Normal file
|
|
@ -0,0 +1,395 @@
|
||||||
|
// <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("20200403195110_Initial")]
|
||||||
|
partial class Initial
|
||||||
|
{
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "3.1.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")
|
||||||
|
.HasColumnType("TEXT")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedName")
|
||||||
|
.HasColumnType("TEXT")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasName("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")
|
||||||
|
.HasColumnType("TEXT")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<bool>("EmailConfirmed")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("LockoutEnabled")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedEmail")
|
||||||
|
.HasColumnType("TEXT")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedUserName")
|
||||||
|
.HasColumnType("TEXT")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
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")
|
||||||
|
.HasColumnType("TEXT")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedEmail")
|
||||||
|
.HasName("EmailIndex");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedUserName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasName("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<string>("Link")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("Status")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<Guid>("TorrentId")
|
||||||
|
.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");
|
||||||
|
|
||||||
|
b.HasData(
|
||||||
|
new
|
||||||
|
{
|
||||||
|
SettingId = "RealDebridApiKey",
|
||||||
|
Type = "String",
|
||||||
|
Value = ""
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
SettingId = "DownloadFolder",
|
||||||
|
Type = "String",
|
||||||
|
Value = "C:\\Downloads"
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
SettingId = "SpeedLimit",
|
||||||
|
Type = "Int32",
|
||||||
|
Value = "0"
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
SettingId = "SegmentsLimit",
|
||||||
|
Type = "Int32",
|
||||||
|
Value = "10"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("RdtClient.Data.Models.Data.Torrent", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("TorrentId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.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<string>("RdStatus")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("Status")
|
||||||
|
.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.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("RdtClient.Data.Models.Data.Download", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("RdtClient.Data.Models.Data.Torrent", "Torrent")
|
||||||
|
.WithMany("Downloads")
|
||||||
|
.HasForeignKey("TorrentId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
305
server/RdtClient.Data/Migrations/20200403195110_Initial.cs
Normal file
305
server/RdtClient.Data/Migrations/20200403195110_Initial.cs
Normal file
|
|
@ -0,0 +1,305 @@
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace RdtClient.Data.Migrations
|
||||||
|
{
|
||||||
|
public partial class Initial : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "AspNetRoles",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<string>(nullable: false),
|
||||||
|
Name = table.Column<string>(maxLength: 256, nullable: true),
|
||||||
|
NormalizedName = table.Column<string>(maxLength: 256, nullable: true),
|
||||||
|
ConcurrencyStamp = table.Column<string>(nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_AspNetRoles", x => x.Id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "AspNetUsers",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<string>(nullable: false),
|
||||||
|
UserName = table.Column<string>(maxLength: 256, nullable: true),
|
||||||
|
NormalizedUserName = table.Column<string>(maxLength: 256, nullable: true),
|
||||||
|
Email = table.Column<string>(maxLength: 256, nullable: true),
|
||||||
|
NormalizedEmail = table.Column<string>(maxLength: 256, nullable: true),
|
||||||
|
EmailConfirmed = table.Column<bool>(nullable: false),
|
||||||
|
PasswordHash = table.Column<string>(nullable: true),
|
||||||
|
SecurityStamp = table.Column<string>(nullable: true),
|
||||||
|
ConcurrencyStamp = table.Column<string>(nullable: true),
|
||||||
|
PhoneNumber = table.Column<string>(nullable: true),
|
||||||
|
PhoneNumberConfirmed = table.Column<bool>(nullable: false),
|
||||||
|
TwoFactorEnabled = table.Column<bool>(nullable: false),
|
||||||
|
LockoutEnd = table.Column<DateTimeOffset>(nullable: true),
|
||||||
|
LockoutEnabled = table.Column<bool>(nullable: false),
|
||||||
|
AccessFailedCount = table.Column<int>(nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_AspNetUsers", x => x.Id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Settings",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
SettingId = table.Column<string>(nullable: false),
|
||||||
|
Value = table.Column<string>(nullable: true),
|
||||||
|
Type = table.Column<string>(nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Settings", x => x.SettingId);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Torrents",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
TorrentId = table.Column<Guid>(nullable: false),
|
||||||
|
Hash = table.Column<string>(nullable: true),
|
||||||
|
Status = table.Column<int>(nullable: false),
|
||||||
|
RdId = table.Column<string>(nullable: true),
|
||||||
|
RdName = table.Column<string>(nullable: true),
|
||||||
|
RdSize = table.Column<long>(nullable: false),
|
||||||
|
RdHost = table.Column<string>(nullable: true),
|
||||||
|
RdSplit = table.Column<long>(nullable: false),
|
||||||
|
RdProgress = table.Column<long>(nullable: false),
|
||||||
|
RdStatus = table.Column<string>(nullable: true),
|
||||||
|
RdAdded = table.Column<DateTimeOffset>(nullable: false),
|
||||||
|
RdEnded = table.Column<DateTimeOffset>(nullable: true),
|
||||||
|
RdSpeed = table.Column<long>(nullable: true),
|
||||||
|
RdSeeders = table.Column<long>(nullable: true),
|
||||||
|
RdFiles = table.Column<string>(nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Torrents", x => x.TorrentId);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "AspNetRoleClaims",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(nullable: false)
|
||||||
|
.Annotation("Sqlite:Autoincrement", true),
|
||||||
|
RoleId = table.Column<string>(nullable: false),
|
||||||
|
ClaimType = table.Column<string>(nullable: true),
|
||||||
|
ClaimValue = table.Column<string>(nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
|
||||||
|
column: x => x.RoleId,
|
||||||
|
principalTable: "AspNetRoles",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "AspNetUserClaims",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(nullable: false)
|
||||||
|
.Annotation("Sqlite:Autoincrement", true),
|
||||||
|
UserId = table.Column<string>(nullable: false),
|
||||||
|
ClaimType = table.Column<string>(nullable: true),
|
||||||
|
ClaimValue = table.Column<string>(nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_AspNetUserClaims", x => x.Id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_AspNetUserClaims_AspNetUsers_UserId",
|
||||||
|
column: x => x.UserId,
|
||||||
|
principalTable: "AspNetUsers",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "AspNetUserLogins",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
LoginProvider = table.Column<string>(nullable: false),
|
||||||
|
ProviderKey = table.Column<string>(nullable: false),
|
||||||
|
ProviderDisplayName = table.Column<string>(nullable: true),
|
||||||
|
UserId = table.Column<string>(nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey });
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_AspNetUserLogins_AspNetUsers_UserId",
|
||||||
|
column: x => x.UserId,
|
||||||
|
principalTable: "AspNetUsers",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "AspNetUserRoles",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
UserId = table.Column<string>(nullable: false),
|
||||||
|
RoleId = table.Column<string>(nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId });
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
|
||||||
|
column: x => x.RoleId,
|
||||||
|
principalTable: "AspNetRoles",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_AspNetUserRoles_AspNetUsers_UserId",
|
||||||
|
column: x => x.UserId,
|
||||||
|
principalTable: "AspNetUsers",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "AspNetUserTokens",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
UserId = table.Column<string>(nullable: false),
|
||||||
|
LoginProvider = table.Column<string>(nullable: false),
|
||||||
|
Name = table.Column<string>(nullable: false),
|
||||||
|
Value = table.Column<string>(nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name });
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_AspNetUserTokens_AspNetUsers_UserId",
|
||||||
|
column: x => x.UserId,
|
||||||
|
principalTable: "AspNetUsers",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Downloads",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
DownloadId = table.Column<Guid>(nullable: false),
|
||||||
|
TorrentId = table.Column<Guid>(nullable: false),
|
||||||
|
Link = table.Column<string>(nullable: true),
|
||||||
|
Added = table.Column<DateTimeOffset>(nullable: false),
|
||||||
|
Status = table.Column<int>(nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Downloads", x => x.DownloadId);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_Downloads_Torrents_TorrentId",
|
||||||
|
column: x => x.TorrentId,
|
||||||
|
principalTable: "Torrents",
|
||||||
|
principalColumn: "TorrentId",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.InsertData(
|
||||||
|
table: "Settings",
|
||||||
|
columns: new[] { "SettingId", "Type", "Value" },
|
||||||
|
values: new object[] { "RealDebridApiKey", "String", "" });
|
||||||
|
|
||||||
|
migrationBuilder.InsertData(
|
||||||
|
table: "Settings",
|
||||||
|
columns: new[] { "SettingId", "Type", "Value" },
|
||||||
|
values: new object[] { "DownloadFolder", "String", "C:\\Downloads" });
|
||||||
|
|
||||||
|
migrationBuilder.InsertData(
|
||||||
|
table: "Settings",
|
||||||
|
columns: new[] { "SettingId", "Type", "Value" },
|
||||||
|
values: new object[] { "DownloadLimit", "Int32", "1" });
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_AspNetRoleClaims_RoleId",
|
||||||
|
table: "AspNetRoleClaims",
|
||||||
|
column: "RoleId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "RoleNameIndex",
|
||||||
|
table: "AspNetRoles",
|
||||||
|
column: "NormalizedName",
|
||||||
|
unique: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_AspNetUserClaims_UserId",
|
||||||
|
table: "AspNetUserClaims",
|
||||||
|
column: "UserId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_AspNetUserLogins_UserId",
|
||||||
|
table: "AspNetUserLogins",
|
||||||
|
column: "UserId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_AspNetUserRoles_RoleId",
|
||||||
|
table: "AspNetUserRoles",
|
||||||
|
column: "RoleId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "EmailIndex",
|
||||||
|
table: "AspNetUsers",
|
||||||
|
column: "NormalizedEmail");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "UserNameIndex",
|
||||||
|
table: "AspNetUsers",
|
||||||
|
column: "NormalizedUserName",
|
||||||
|
unique: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_Downloads_TorrentId",
|
||||||
|
table: "Downloads",
|
||||||
|
column: "TorrentId");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "AspNetRoleClaims");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "AspNetUserClaims");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "AspNetUserLogins");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "AspNetUserRoles");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "AspNetUserTokens");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Downloads");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Settings");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "AspNetRoles");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "AspNetUsers");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Torrents");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
387
server/RdtClient.Data/Migrations/DataContextModelSnapshot.cs
Normal file
387
server/RdtClient.Data/Migrations/DataContextModelSnapshot.cs
Normal file
|
|
@ -0,0 +1,387 @@
|
||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using RdtClient.Data.Data;
|
||||||
|
|
||||||
|
namespace RdtClient.Data.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(DataContext))]
|
||||||
|
partial class DataContextModelSnapshot : ModelSnapshot
|
||||||
|
{
|
||||||
|
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "3.1.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")
|
||||||
|
.HasColumnType("TEXT")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedName")
|
||||||
|
.HasColumnType("TEXT")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasName("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")
|
||||||
|
.HasColumnType("TEXT")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<bool>("EmailConfirmed")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("LockoutEnabled")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedEmail")
|
||||||
|
.HasColumnType("TEXT")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedUserName")
|
||||||
|
.HasColumnType("TEXT")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
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")
|
||||||
|
.HasColumnType("TEXT")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedEmail")
|
||||||
|
.HasName("EmailIndex");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedUserName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasName("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<string>("Link")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("Status")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<Guid>("TorrentId")
|
||||||
|
.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");
|
||||||
|
|
||||||
|
b.HasData(
|
||||||
|
new
|
||||||
|
{
|
||||||
|
SettingId = "RealDebridApiKey",
|
||||||
|
Type = "String",
|
||||||
|
Value = ""
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
SettingId = "DownloadFolder",
|
||||||
|
Type = "String",
|
||||||
|
Value = "C:\\Downloads"
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
SettingId = "DownloadLimit",
|
||||||
|
Type = "Int32",
|
||||||
|
Value = "10"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("RdtClient.Data.Models.Data.Torrent", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("TorrentId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.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<string>("RdStatus")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("Status")
|
||||||
|
.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.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("RdtClient.Data.Models.Data.Download", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("RdtClient.Data.Models.Data.Torrent", "Torrent")
|
||||||
|
.WithMany("Downloads")
|
||||||
|
.HasForeignKey("TorrentId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
27
server/RdtClient.Data/Models/Data/Download.cs
Normal file
27
server/RdtClient.Data/Models/Data/Download.cs
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using RdtClient.Data.Enums;
|
||||||
|
|
||||||
|
namespace RdtClient.Data.Models.Data
|
||||||
|
{
|
||||||
|
public class Download
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
public Guid DownloadId { get; set; }
|
||||||
|
|
||||||
|
public Guid TorrentId { get; set; }
|
||||||
|
|
||||||
|
public String Link { get; set; }
|
||||||
|
|
||||||
|
public DateTimeOffset Added { get; set; }
|
||||||
|
|
||||||
|
public DownloadStatus Status { get; set; }
|
||||||
|
|
||||||
|
[ForeignKey("TorrentId")]
|
||||||
|
public Torrent Torrent { get; set; }
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public Int32 Progress { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
15
server/RdtClient.Data/Models/Data/Setting.cs
Normal file
15
server/RdtClient.Data/Models/Data/Setting.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace RdtClient.Data.Models.Data
|
||||||
|
{
|
||||||
|
public class Setting
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
public String SettingId { get; set; }
|
||||||
|
|
||||||
|
public String Value { get; set; }
|
||||||
|
|
||||||
|
public String Type { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
60
server/RdtClient.Data/Models/Data/Torrent.cs
Normal file
60
server/RdtClient.Data/Models/Data/Torrent.cs
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using RDNET.Models;
|
||||||
|
using RdtClient.Data.Enums;
|
||||||
|
|
||||||
|
namespace RdtClient.Data.Models.Data
|
||||||
|
{
|
||||||
|
public class Torrent
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
public Guid TorrentId { get; set; }
|
||||||
|
|
||||||
|
public String Hash { get; set; }
|
||||||
|
|
||||||
|
public TorrentStatus Status { get; set; }
|
||||||
|
|
||||||
|
[InverseProperty("Torrent")]
|
||||||
|
public IList<Download> Downloads { get; set; }
|
||||||
|
|
||||||
|
public String RdId { get; set; }
|
||||||
|
public String RdName { get; set; }
|
||||||
|
public Int64 RdSize { get; set; }
|
||||||
|
public String RdHost { get; set; }
|
||||||
|
public Int64 RdSplit { get; set; }
|
||||||
|
public Int64 RdProgress { get; set; }
|
||||||
|
public String RdStatus { get; set; }
|
||||||
|
public DateTimeOffset RdAdded { get; set; }
|
||||||
|
public DateTimeOffset? RdEnded { get; set; }
|
||||||
|
public Int64? RdSpeed { get; set; }
|
||||||
|
public Int64? RdSeeders { get; set; }
|
||||||
|
public String RdFiles { get; set; }
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public Int32 DownloadProgress { get; set; }
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public IList<TorrentFile> Files
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (String.IsNullOrWhiteSpace(RdFiles))
|
||||||
|
{
|
||||||
|
return new List<TorrentFile>();
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return JsonConvert.DeserializeObject<List<TorrentFile>>(RdFiles);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return new List<TorrentFile>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,14 +1,6 @@
|
||||||
using System;
|
namespace RdtClient.Data.Models.Internal
|
||||||
|
|
||||||
namespace RdtClient.Data.Models.Internal
|
|
||||||
{
|
{
|
||||||
public class AppSettings
|
public class AppSettings
|
||||||
{
|
{
|
||||||
public AppSettingsConnectionStrings ConnectionStrings { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class AppSettingsConnectionStrings
|
|
||||||
{
|
|
||||||
public String Client { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,47 @@
|
||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Remove="Migrations\20200402172935_AspNetIdentity.cs" />
|
||||||
|
<Compile Remove="Migrations\20200402172935_AspNetIdentity.Designer.cs" />
|
||||||
|
<Compile Remove="Migrations\20200402173119_Torrents.cs" />
|
||||||
|
<Compile Remove="Migrations\20200402173119_Torrents.Designer.cs" />
|
||||||
|
<Compile Remove="Migrations\20200402190746_Torrents.cs" />
|
||||||
|
<Compile Remove="Migrations\20200402190746_Torrents.Designer.cs" />
|
||||||
|
<Compile Remove="Migrations\20200402194059_Torrents.cs" />
|
||||||
|
<Compile Remove="Migrations\20200402194059_Torrents.Designer.cs" />
|
||||||
|
<Compile Remove="Migrations\20200402212417_Torrents.cs" />
|
||||||
|
<Compile Remove="Migrations\20200402212417_Torrents.Designer.cs" />
|
||||||
|
<Compile Remove="Migrations\20200403143200_Torrent.cs" />
|
||||||
|
<Compile Remove="Migrations\20200403143200_Torrent.Designer.cs" />
|
||||||
|
<Compile Remove="Migrations\20200403143240_Settings.cs" />
|
||||||
|
<Compile Remove="Migrations\20200403143240_Settings.Designer.cs" />
|
||||||
|
<Compile Remove="Migrations\20200403145651_Settings.cs" />
|
||||||
|
<Compile Remove="Migrations\20200403145651_Settings.Designer.cs" />
|
||||||
|
<Compile Remove="Migrations\20200403164143_Downloads.cs" />
|
||||||
|
<Compile Remove="Migrations\20200403164143_Downloads.Designer.cs" />
|
||||||
|
<Compile Remove="Migrations\20200403174830_Initia.cs" />
|
||||||
|
<Compile Remove="Migrations\20200403174830_Initia.Designer.cs" />
|
||||||
|
<Compile Remove="Migrations\20200403174846_Initial.cs" />
|
||||||
|
<Compile Remove="Migrations\20200403174846_Initial.Designer.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.1.3" />
|
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.1.3" />
|
||||||
|
<PackageReference Include="Microsoft.Data.Sqlite" Version="3.1.3" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.3" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.3" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="3.1.3" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="3.1.3" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.3">
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.3">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="RDNET">
|
||||||
|
<HintPath>..\libs\RDNET.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using RdtClient.Service.Services;
|
||||||
|
|
||||||
namespace RdtClient.Service
|
namespace RdtClient.Service
|
||||||
{
|
{
|
||||||
|
|
@ -6,7 +7,10 @@ namespace RdtClient.Service
|
||||||
{
|
{
|
||||||
public static void Config(IServiceCollection services)
|
public static void Config(IServiceCollection services)
|
||||||
{
|
{
|
||||||
//services.AddScoped<IFql, Fql>();
|
services.AddScoped<IDownloads, Downloads>();
|
||||||
|
services.AddScoped<IScheduler, Scheduler>();
|
||||||
|
services.AddScoped<ISettings, Settings>();
|
||||||
|
services.AddScoped<ITorrents, Torrents>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
10
server/RdtClient.Service/Models/Profile.cs
Normal file
10
server/RdtClient.Service/Models/Profile.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace RdtClient.Service.Models
|
||||||
|
{
|
||||||
|
public class Profile
|
||||||
|
{
|
||||||
|
public String UserName { get; set; }
|
||||||
|
public DateTimeOffset Expiration { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
27
server/RdtClient.Service/Properties/launchSettings.json
Normal file
27
server/RdtClient.Service/Properties/launchSettings.json
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:53591/",
|
||||||
|
"sslPort": 44310
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"IIS Express": {
|
||||||
|
"commandName": "IISExpress",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"RdtClient.Service": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
},
|
||||||
|
"applicationUrl": "https://localhost:5001;http://localhost:5000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,11 +1,25 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
|
<OutputType>library</OutputType>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Hangfire.Core" Version="1.7.10" />
|
||||||
|
<PackageReference Include="MonoTorrent" Version="1.0.19" />
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||||
|
<PackageReference Include="SharpCompress" Version="0.25.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\RdtClient.Data\RdtClient.Data.csproj" />
|
<ProjectReference Include="..\RdtClient.Data\RdtClient.Data.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="RDNET">
|
||||||
|
<HintPath>..\libs\RDNET.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
6
server/RdtClient.Service/RdtClient.Service.csproj.user
Normal file
6
server/RdtClient.Service/RdtClient.Service.csproj.user
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<ActiveDebugProfile>IIS Express</ActiveDebugProfile>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
147
server/RdtClient.Service/Services/DownloadManager.cs
Normal file
147
server/RdtClient.Service/Services/DownloadManager.cs
Normal file
|
|
@ -0,0 +1,147 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using RdtClient.Data.Data;
|
||||||
|
using RdtClient.Data.Enums;
|
||||||
|
using RdtClient.Data.Models.Data;
|
||||||
|
using SharpCompress.Common;
|
||||||
|
using SharpCompress.Readers;
|
||||||
|
|
||||||
|
namespace RdtClient.Service.Services
|
||||||
|
{
|
||||||
|
public class DownloadManager
|
||||||
|
{
|
||||||
|
public static readonly ConcurrentDictionary<Guid, Download> ActiveDownloads = new ConcurrentDictionary<Guid, Download>();
|
||||||
|
|
||||||
|
private static readonly Object Lock = new Object();
|
||||||
|
|
||||||
|
static DownloadManager()
|
||||||
|
{
|
||||||
|
ServicePointManager.Expect100Continue = false;
|
||||||
|
ServicePointManager.DefaultConnectionLimit = 100;
|
||||||
|
ServicePointManager.MaxServicePointIdleTime = 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task Download(Download download, String destinationFolderPath)
|
||||||
|
{
|
||||||
|
await UpdateStatus(download.DownloadId, DownloadStatus.Downloading, TorrentStatus.Downloading);
|
||||||
|
|
||||||
|
if (!ActiveDownloads.TryAdd(download.DownloadId, download))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var fileUrl = download.Link;
|
||||||
|
|
||||||
|
var uri = new Uri(fileUrl);
|
||||||
|
var filePath = Path.Combine(destinationFolderPath, uri.Segments.Last());
|
||||||
|
|
||||||
|
var webRequest = WebRequest.Create(fileUrl);
|
||||||
|
webRequest.Method = "HEAD";
|
||||||
|
Int64 responseLength;
|
||||||
|
using (var webResponse = await webRequest.GetResponseAsync())
|
||||||
|
{
|
||||||
|
responseLength = Int64.Parse(webResponse.Headers.Get("Content-Length"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (File.Exists(filePath))
|
||||||
|
{
|
||||||
|
File.Delete(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
var request = WebRequest.Create(fileUrl);
|
||||||
|
using (var response = await request.GetResponseAsync())
|
||||||
|
{
|
||||||
|
await using var stream = response.GetResponseStream();
|
||||||
|
await using var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Write);
|
||||||
|
|
||||||
|
var buffer = new Byte[4096];
|
||||||
|
|
||||||
|
while (fileStream.Length < response.ContentLength)
|
||||||
|
{
|
||||||
|
var read = stream.Read(buffer, 0, buffer.Length);
|
||||||
|
|
||||||
|
if (read > 0)
|
||||||
|
{
|
||||||
|
fileStream.Write(buffer, 0, read);
|
||||||
|
|
||||||
|
download.Progress = (Int32) (fileStream.Length * 100 / responseLength);
|
||||||
|
ActiveDownloads.TryAdd(download.DownloadId, download);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await using Stream stream = File.OpenRead(filePath);
|
||||||
|
|
||||||
|
var reader = ReaderFactory.Open(stream);
|
||||||
|
while (reader.MoveToNextEntry())
|
||||||
|
{
|
||||||
|
if (!reader.Entry.IsDirectory)
|
||||||
|
{
|
||||||
|
Console.WriteLine(reader.Entry.Key);
|
||||||
|
reader.WriteEntryToDirectory(destinationFolderPath,
|
||||||
|
new ExtractionOptions
|
||||||
|
{
|
||||||
|
ExtractFullPath = true,
|
||||||
|
Overwrite = true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
File.Delete(filePath);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
|
||||||
|
await UpdateStatus(download.DownloadId, DownloadStatus.Finished, TorrentStatus.Finished);
|
||||||
|
|
||||||
|
ActiveDownloads.TryRemove(download.DownloadId, out _);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task UpdateStatus(Guid downloadId, DownloadStatus downloadStatus, TorrentStatus torrentStatus)
|
||||||
|
{
|
||||||
|
await using var context = new DataContext();
|
||||||
|
|
||||||
|
var download = await context.Downloads.FirstOrDefaultAsync(m => m.DownloadId == downloadId);
|
||||||
|
|
||||||
|
download.Status = downloadStatus;
|
||||||
|
|
||||||
|
await context.SaveChangesAsync();
|
||||||
|
|
||||||
|
var torrent = await context.Torrents.FirstOrDefaultAsync(m => m.TorrentId == download.TorrentId);
|
||||||
|
|
||||||
|
if (torrentStatus == TorrentStatus.Finished)
|
||||||
|
{
|
||||||
|
var allDownloads = await context.Downloads.Where(m => m.TorrentId == download.TorrentId)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
if (allDownloads.All(m => m.Status == DownloadStatus.Finished))
|
||||||
|
{
|
||||||
|
torrent.Status = TorrentStatus.Finished;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
torrent.Status = TorrentStatus.Downloading;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
torrent.Status = torrentStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
await context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
49
server/RdtClient.Service/Services/Downloads.cs
Normal file
49
server/RdtClient.Service/Services/Downloads.cs
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using RdtClient.Data.Data;
|
||||||
|
using RdtClient.Data.Enums;
|
||||||
|
using RdtClient.Data.Models.Data;
|
||||||
|
|
||||||
|
namespace RdtClient.Service.Services
|
||||||
|
{
|
||||||
|
public interface IDownloads
|
||||||
|
{
|
||||||
|
Task<IList<Download>> Get();
|
||||||
|
Task<Download> Add(Guid torrentId, String link);
|
||||||
|
Task UpdateStatus(Guid downloadId, DownloadStatus status);
|
||||||
|
Task DeleteForTorrent(Guid torrentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Downloads : IDownloads
|
||||||
|
{
|
||||||
|
private readonly IDownloadData _downloadData;
|
||||||
|
private readonly ISettings _settings;
|
||||||
|
|
||||||
|
public Downloads(IDownloadData downloadData, ISettings settings)
|
||||||
|
{
|
||||||
|
_downloadData = downloadData;
|
||||||
|
_settings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IList<Download>> Get()
|
||||||
|
{
|
||||||
|
return await _downloadData.Get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Download> Add(Guid torrentId, String link)
|
||||||
|
{
|
||||||
|
return await _downloadData.Add(torrentId, link);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task UpdateStatus(Guid downloadId, DownloadStatus status)
|
||||||
|
{
|
||||||
|
await _downloadData.UpdateStatus(downloadId, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task DeleteForTorrent(Guid torrentId)
|
||||||
|
{
|
||||||
|
await _downloadData.DeleteForTorrent(torrentId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
62
server/RdtClient.Service/Services/Scheduler.cs
Normal file
62
server/RdtClient.Service/Services/Scheduler.cs
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Hangfire;
|
||||||
|
using RdtClient.Data.Enums;
|
||||||
|
|
||||||
|
namespace RdtClient.Service.Services
|
||||||
|
{
|
||||||
|
public interface IScheduler
|
||||||
|
{
|
||||||
|
void Start();
|
||||||
|
Task Process();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Scheduler : IScheduler
|
||||||
|
{
|
||||||
|
private readonly IDownloads _downloads;
|
||||||
|
private readonly ISettings _settings;
|
||||||
|
private readonly ITorrents _torrents;
|
||||||
|
|
||||||
|
public Scheduler(ITorrents torrents, IDownloads downloads, ISettings settings)
|
||||||
|
{
|
||||||
|
_torrents = torrents;
|
||||||
|
_downloads = downloads;
|
||||||
|
_settings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
RecurringJob.AddOrUpdate(() => Process(), "* * * * *");
|
||||||
|
BackgroundJob.Enqueue(() => Process());
|
||||||
|
}
|
||||||
|
|
||||||
|
[DisableConcurrentExecution(5)]
|
||||||
|
public async Task Process()
|
||||||
|
{
|
||||||
|
await _torrents.Update();
|
||||||
|
|
||||||
|
var downloads = await _downloads.Get();
|
||||||
|
|
||||||
|
downloads = downloads.Where(m => m.Status != DownloadStatus.Finished)
|
||||||
|
.OrderByDescending(m => m.Status)
|
||||||
|
.ThenByDescending(m => m.Added)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
var maxDownloads = await _settings.GetNumber("DownloadLimit");
|
||||||
|
var destinationFolderPath = await _settings.GetString("DownloadFolder");
|
||||||
|
|
||||||
|
foreach (var download in downloads)
|
||||||
|
{
|
||||||
|
if (DownloadManager.ActiveDownloads.Count >= maxDownloads)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
download.Torrent = null;
|
||||||
|
BackgroundJob.Enqueue(() => DownloadManager.Download(download, destinationFolderPath));
|
||||||
|
|
||||||
|
await Task.Delay(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
60
server/RdtClient.Service/Services/Settings.cs
Normal file
60
server/RdtClient.Service/Services/Settings.cs
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using RdtClient.Data.Data;
|
||||||
|
using RdtClient.Data.Models.Data;
|
||||||
|
|
||||||
|
namespace RdtClient.Service.Services
|
||||||
|
{
|
||||||
|
public interface ISettings
|
||||||
|
{
|
||||||
|
Task<IList<Setting>> GetAll();
|
||||||
|
Task Update(IList<Setting> settings);
|
||||||
|
Task<String> GetString(String key);
|
||||||
|
Task<Int32> GetNumber(String key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Settings : ISettings
|
||||||
|
{
|
||||||
|
private readonly ISettingData _settingData;
|
||||||
|
|
||||||
|
public Settings(ISettingData settingData)
|
||||||
|
{
|
||||||
|
_settingData = settingData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IList<Setting>> GetAll()
|
||||||
|
{
|
||||||
|
return await _settingData.GetAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Update(IList<Setting> settings)
|
||||||
|
{
|
||||||
|
await _settingData.Update(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<String> GetString(String key)
|
||||||
|
{
|
||||||
|
var setting = await _settingData.Get(key);
|
||||||
|
|
||||||
|
if (setting == null)
|
||||||
|
{
|
||||||
|
throw new Exception($"Setting with key {key} not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
return setting.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Int32> GetNumber(String key)
|
||||||
|
{
|
||||||
|
var setting = await _settingData.Get(key);
|
||||||
|
|
||||||
|
if (setting == null)
|
||||||
|
{
|
||||||
|
throw new Exception($"Setting with key {key} not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Int32.Parse(setting.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
277
server/RdtClient.Service/Services/Torrents.cs
Normal file
277
server/RdtClient.Service/Services/Torrents.cs
Normal file
|
|
@ -0,0 +1,277 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using RDNET;
|
||||||
|
using RdtClient.Data.Data;
|
||||||
|
using RdtClient.Data.Enums;
|
||||||
|
using RdtClient.Data.Models.Data;
|
||||||
|
using RdtClient.Service.Models;
|
||||||
|
|
||||||
|
namespace RdtClient.Service.Services
|
||||||
|
{
|
||||||
|
public interface ITorrents
|
||||||
|
{
|
||||||
|
Task<IList<Torrent>> Get();
|
||||||
|
Task<Torrent> Get(Guid id);
|
||||||
|
Task<IList<Torrent>> Update();
|
||||||
|
Task UploadMagnet(String magnetLink);
|
||||||
|
Task UploadFile(Byte[] bytes);
|
||||||
|
Task Delete(Guid id);
|
||||||
|
Task Download(Guid id);
|
||||||
|
void Reset();
|
||||||
|
Task<Profile> GetProfile();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Torrents : ITorrents
|
||||||
|
{
|
||||||
|
private readonly ITorrentData _torrentData;
|
||||||
|
private readonly ISettings _settings;
|
||||||
|
private readonly IDownloads _downloads;
|
||||||
|
|
||||||
|
private static RdNetClient _rdtClient;
|
||||||
|
|
||||||
|
private static DateTime _rdtLastUpdate = DateTime.UtcNow;
|
||||||
|
|
||||||
|
private static readonly SemaphoreSlim SemaphoreSlim = new SemaphoreSlim(1,1);
|
||||||
|
|
||||||
|
private RdNetClient RdNetClient
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_rdtClient == null)
|
||||||
|
{
|
||||||
|
var apiKey = _settings.GetString("RealDebridApiKey").Result;
|
||||||
|
|
||||||
|
if (String.IsNullOrWhiteSpace(apiKey))
|
||||||
|
{
|
||||||
|
throw new Exception("RealDebrid API Key not set in the settings");
|
||||||
|
}
|
||||||
|
|
||||||
|
_rdtClient = new RdNetClient("X245A4XAIBGVM", null, null, null, null, apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _rdtClient;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Torrents(ITorrentData torrentData, ISettings settings, IDownloads downloads)
|
||||||
|
{
|
||||||
|
_torrentData = torrentData;
|
||||||
|
_settings = settings;
|
||||||
|
_downloads = downloads;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IList<Torrent>> Get()
|
||||||
|
{
|
||||||
|
var torrents = await _torrentData.Get();
|
||||||
|
|
||||||
|
if (DateTime.UtcNow > _rdtLastUpdate)
|
||||||
|
{
|
||||||
|
_rdtLastUpdate = DateTime.UtcNow.AddSeconds(10);
|
||||||
|
|
||||||
|
torrents = await Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var torrent in torrents)
|
||||||
|
{
|
||||||
|
var downloads = DownloadManager.ActiveDownloads.Where(m => m.Value.TorrentId == torrent.TorrentId).ToList();
|
||||||
|
|
||||||
|
if (torrent.Files.Count > 0)
|
||||||
|
{
|
||||||
|
torrent.DownloadProgress = downloads.Sum(m => m.Value.Progress) / torrent.Files.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return torrents;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Torrent> Get(Guid id)
|
||||||
|
{
|
||||||
|
var torrent = await _torrentData.Get(id);
|
||||||
|
|
||||||
|
if (torrent != null)
|
||||||
|
{
|
||||||
|
var rdTorrent = await RdNetClient.TorrentInfoAsync(torrent.RdId);
|
||||||
|
|
||||||
|
await Update(torrent, rdTorrent);
|
||||||
|
}
|
||||||
|
|
||||||
|
return torrent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IList<Torrent>> Update()
|
||||||
|
{
|
||||||
|
var torrents = await _torrentData.Get();
|
||||||
|
|
||||||
|
var w = await SemaphoreSlim.WaitAsync(10);
|
||||||
|
if (!w)
|
||||||
|
{
|
||||||
|
return torrents;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var rdTorrents = await RdNetClient.TorrentsAsync(0, 100);
|
||||||
|
|
||||||
|
foreach (var rdTorrent in rdTorrents)
|
||||||
|
{
|
||||||
|
var torrent = torrents.FirstOrDefault(m => m.RdId == rdTorrent.Id);
|
||||||
|
|
||||||
|
if (torrent == null)
|
||||||
|
{
|
||||||
|
var newTorrent = await _torrentData.Add(rdTorrent.Id, rdTorrent.Hash);
|
||||||
|
await Get(newTorrent.TorrentId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await Update(torrent, rdTorrent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var torrent in torrents)
|
||||||
|
{
|
||||||
|
var rdTorrent = rdTorrents.FirstOrDefault(m => m.Id == torrent.RdId);
|
||||||
|
|
||||||
|
if (rdTorrent == null)
|
||||||
|
{
|
||||||
|
await _torrentData.Delete(torrent.TorrentId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return torrents;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
SemaphoreSlim.Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task UploadMagnet(String magnetLink)
|
||||||
|
{
|
||||||
|
var magnet = MonoTorrent.MagnetLink.Parse(magnetLink);
|
||||||
|
|
||||||
|
var rdTorrent = await RdNetClient.TorrentAddMagnet(magnetLink);
|
||||||
|
|
||||||
|
await Add(rdTorrent.Id, magnet.InfoHash.ToHex());
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task UploadFile(Byte[] bytes)
|
||||||
|
{
|
||||||
|
var torrent = MonoTorrent.Torrent.Load(bytes);
|
||||||
|
|
||||||
|
var rdTorrent = await RdNetClient.TorrentAddFile(bytes);
|
||||||
|
|
||||||
|
await Add(rdTorrent.Id, torrent.InfoHash.ToHex());
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Delete(Guid id)
|
||||||
|
{
|
||||||
|
var torrent = await Get(id);
|
||||||
|
|
||||||
|
if (torrent != null)
|
||||||
|
{
|
||||||
|
await _torrentData.Delete(id);
|
||||||
|
await RdNetClient.TorrentDelete(torrent.RdId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Download(Guid id)
|
||||||
|
{
|
||||||
|
var torrent = await _torrentData.Get(id);
|
||||||
|
|
||||||
|
await _downloads.DeleteForTorrent(id);
|
||||||
|
|
||||||
|
var rdTorrent = await RdNetClient.TorrentInfoAsync(torrent.RdId);
|
||||||
|
|
||||||
|
foreach (var file in rdTorrent.Files)
|
||||||
|
{
|
||||||
|
var unrestrictedLink = await RdNetClient.UnrestrictLinkAsync(file.Path);
|
||||||
|
|
||||||
|
await _downloads.Add(torrent.TorrentId, unrestrictedLink.Download);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
_rdtClient = null;
|
||||||
|
_rdtLastUpdate = DateTime.UtcNow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Profile> GetProfile()
|
||||||
|
{
|
||||||
|
var user = await _rdtClient.UserAsync();
|
||||||
|
|
||||||
|
var profile = new Profile
|
||||||
|
{
|
||||||
|
UserName = user.Username,
|
||||||
|
Expiration = user.Expiration
|
||||||
|
};
|
||||||
|
|
||||||
|
return profile;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Add(String rdTorrentId, String infoHash)
|
||||||
|
{
|
||||||
|
var newTorrent = await _torrentData.Add(rdTorrentId, infoHash);
|
||||||
|
|
||||||
|
var rdTorrent = await RdNetClient.TorrentInfoAsync(rdTorrentId);
|
||||||
|
|
||||||
|
if (rdTorrent.Files != null && rdTorrent.Files.Count > 0)
|
||||||
|
{
|
||||||
|
if (!rdTorrent.Files.Any(m => m.Selected))
|
||||||
|
{
|
||||||
|
var fileIds = rdTorrent.Files.Select(m => m.Id.ToString()).ToArray();
|
||||||
|
|
||||||
|
await RdNetClient.TorrentSelectFiles(rdTorrentId, fileIds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await Update(newTorrent, rdTorrent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Update(Torrent torrent, RDNET.Models.Torrent rdTorrent)
|
||||||
|
{
|
||||||
|
if (!String.IsNullOrWhiteSpace(rdTorrent.Filename))
|
||||||
|
{
|
||||||
|
torrent.RdName = rdTorrent.Filename;
|
||||||
|
}
|
||||||
|
else if (!String.IsNullOrWhiteSpace(rdTorrent.OriginalFilename))
|
||||||
|
{
|
||||||
|
torrent.RdName = rdTorrent.OriginalFilename;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rdTorrent.Bytes > 0)
|
||||||
|
{
|
||||||
|
torrent.RdSize = rdTorrent.Bytes;
|
||||||
|
}
|
||||||
|
else if (rdTorrent.OriginalBytes > 0)
|
||||||
|
{
|
||||||
|
torrent.RdSize = rdTorrent.OriginalBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rdTorrent.Files != null)
|
||||||
|
{
|
||||||
|
torrent.RdFiles = JsonConvert.SerializeObject(rdTorrent.Files);
|
||||||
|
}
|
||||||
|
|
||||||
|
torrent.RdHost = rdTorrent.Host;
|
||||||
|
torrent.RdSplit = rdTorrent.Split;
|
||||||
|
torrent.RdProgress = rdTorrent.Progress;
|
||||||
|
torrent.RdStatus = rdTorrent.Status;
|
||||||
|
torrent.RdAdded = rdTorrent.Added;
|
||||||
|
torrent.RdEnded = rdTorrent.Ended;
|
||||||
|
torrent.RdSpeed = rdTorrent.Speed;
|
||||||
|
torrent.RdSeeders = rdTorrent.Seeders;
|
||||||
|
|
||||||
|
await _torrentData.UpdateRdData(torrent);
|
||||||
|
|
||||||
|
if (torrent.Status == TorrentStatus.RealDebrid && torrent.RdProgress == 100)
|
||||||
|
{
|
||||||
|
await _torrentData.UpdateStatus(torrent.TorrentId, TorrentStatus.WaitingForDownload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
75
server/RdtClient.Web/Controllers/SettingsController.cs
Normal file
75
server/RdtClient.Web/Controllers/SettingsController.cs
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using RdtClient.Data.Models.Data;
|
||||||
|
using RdtClient.Service.Models;
|
||||||
|
using RdtClient.Service.Services;
|
||||||
|
|
||||||
|
namespace RdtClient.Web.Controllers
|
||||||
|
{
|
||||||
|
[Route("Api/Settings")]
|
||||||
|
public class SettingsController : Controller
|
||||||
|
{
|
||||||
|
private readonly ISettings _settings;
|
||||||
|
private readonly ITorrents _torrents;
|
||||||
|
|
||||||
|
public SettingsController(ISettings settings, ITorrents torrents)
|
||||||
|
{
|
||||||
|
_settings = settings;
|
||||||
|
_torrents = torrents;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[Route("")]
|
||||||
|
public async Task<ActionResult<IList<Setting>>> Get()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = await _settings.GetAll();
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return BadRequest(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPut]
|
||||||
|
[Route("")]
|
||||||
|
public async Task<ActionResult> Update([FromBody] SettingsControllerUpdateRequest request)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _settings.Update(request.Settings);
|
||||||
|
_torrents.Reset();
|
||||||
|
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return BadRequest(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[Route("Profile")]
|
||||||
|
public async Task<ActionResult<Profile>> Profile()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var profile = await _torrents.GetProfile();
|
||||||
|
return Ok(profile);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return BadRequest(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SettingsControllerUpdateRequest
|
||||||
|
{
|
||||||
|
public IList<Setting> Settings { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
143
server/RdtClient.Web/Controllers/TorrentsController.cs
Normal file
143
server/RdtClient.Web/Controllers/TorrentsController.cs
Normal file
|
|
@ -0,0 +1,143 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using RdtClient.Data.Models.Data;
|
||||||
|
using RdtClient.Service.Services;
|
||||||
|
|
||||||
|
namespace RdtClient.Web.Controllers
|
||||||
|
{
|
||||||
|
[Route("Api/Torrents")]
|
||||||
|
public class TorrentsController : Controller
|
||||||
|
{
|
||||||
|
private readonly ITorrents _torrents;
|
||||||
|
private readonly IScheduler _scheduler;
|
||||||
|
|
||||||
|
public TorrentsController(ITorrents torrents, IScheduler scheduler)
|
||||||
|
{
|
||||||
|
_torrents = torrents;
|
||||||
|
_scheduler = scheduler;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[Route("")]
|
||||||
|
public async Task<ActionResult<IList<Torrent>>> Get()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = await _torrents.Get();
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return BadRequest(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[Route("{id}")]
|
||||||
|
public async Task<ActionResult<Torrent>> Get(Guid id)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = await _torrents.Get(id);
|
||||||
|
|
||||||
|
if (result == null)
|
||||||
|
{
|
||||||
|
throw new Exception("Torrent not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return BadRequest(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("UploadFile")]
|
||||||
|
public async Task<ActionResult> UploadFile([FromForm] IFormFile file)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (file == null || file.Length <= 0)
|
||||||
|
{
|
||||||
|
throw new Exception("Invalid torrent file");
|
||||||
|
}
|
||||||
|
|
||||||
|
var fileStream = file.OpenReadStream();
|
||||||
|
|
||||||
|
await using var memoryStream = new MemoryStream();
|
||||||
|
|
||||||
|
fileStream.CopyTo(memoryStream);
|
||||||
|
|
||||||
|
var bytes = memoryStream.ToArray();
|
||||||
|
|
||||||
|
await _torrents.UploadFile(bytes);
|
||||||
|
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return BadRequest(ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("UploadMagnet")]
|
||||||
|
public async Task<ActionResult> UploadMagnet([FromBody] TorrentControllerUploadMagnetRequest request)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _torrents.UploadMagnet(request.MagnetLink);
|
||||||
|
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return BadRequest(ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpDelete]
|
||||||
|
[Route("{id}")]
|
||||||
|
public async Task<ActionResult> Delete(Guid id)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _torrents.Delete(id);
|
||||||
|
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
return BadRequest(ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[Route("Download/{id}")]
|
||||||
|
public async Task<ActionResult> Download(Guid id)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _torrents.Download(id);
|
||||||
|
await _scheduler.Process();
|
||||||
|
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
return BadRequest(ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TorrentControllerUploadMagnetRequest
|
||||||
|
{
|
||||||
|
public String MagnetLink { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace RdtClient.Web
|
namespace RdtClient.Web
|
||||||
{
|
{
|
||||||
|
|
@ -13,8 +14,15 @@ namespace RdtClient.Web
|
||||||
.Run();
|
.Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IHostBuilder CreateHostBuilder(String[] args) =>
|
private static IHostBuilder CreateHostBuilder(String[] args)
|
||||||
Host.CreateDefaultBuilder(args)
|
{
|
||||||
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
|
return Host
|
||||||
|
.CreateDefaultBuilder(args)
|
||||||
|
.ConfigureLogging(logging =>
|
||||||
|
{
|
||||||
|
logging.AddFile("app.log");
|
||||||
|
})
|
||||||
|
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,18 +1,16 @@
|
||||||
{
|
{
|
||||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
|
||||||
"iisSettings": {
|
"iisSettings": {
|
||||||
"windowsAuthentication": false,
|
"windowsAuthentication": false,
|
||||||
"anonymousAuthentication": true,
|
"anonymousAuthentication": true,
|
||||||
"iisExpress": {
|
"iisExpress": {
|
||||||
"applicationUrl": "http://localhost:52923",
|
"applicationUrl": "http://localhost:4201",
|
||||||
"sslPort": 44356
|
"sslPort": 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||||
"profiles": {
|
"profiles": {
|
||||||
"IIS Express": {
|
"IIS Express": {
|
||||||
"commandName": "IISExpress",
|
"commandName": "IISExpress",
|
||||||
"launchBrowser": true,
|
|
||||||
"launchUrl": "weatherforecast",
|
|
||||||
"environmentVariables": {
|
"environmentVariables": {
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
}
|
}
|
||||||
|
|
@ -21,10 +19,10 @@
|
||||||
"commandName": "Project",
|
"commandName": "Project",
|
||||||
"launchBrowser": true,
|
"launchBrowser": true,
|
||||||
"launchUrl": "weatherforecast",
|
"launchUrl": "weatherforecast",
|
||||||
"applicationUrl": "https://localhost:5001;http://localhost:5000",
|
|
||||||
"environmentVariables": {
|
"environmentVariables": {
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
}
|
},
|
||||||
|
"applicationUrl": "https://localhost:5001;http://localhost:5000"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -5,11 +5,13 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Controllers\" />
|
|
||||||
<Folder Include="wwwroot\" />
|
<Folder Include="wwwroot\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Hangfire.AspNetCore" Version="1.7.10" />
|
||||||
|
<PackageReference Include="Hangfire.Core" Version="1.7.10" />
|
||||||
|
<PackageReference Include="Hangfire.MemoryStorage" Version="1.7.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="3.1.3" />
|
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="3.1.3" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="3.1.3" />
|
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="3.1.3" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.3" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.3" />
|
||||||
|
|
@ -19,6 +21,7 @@
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="3.1.3" />
|
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="3.1.3" />
|
||||||
|
<PackageReference Include="NReco.Logging.File" Version="1.0.5" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
using Hangfire;
|
||||||
|
using Hangfire.MemoryStorage;
|
||||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
|
@ -6,8 +8,9 @@ using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using RdtClient.Data.DataContext;
|
using RdtClient.Data.Data;
|
||||||
using RdtClient.Data.Models.Internal;
|
using RdtClient.Data.Models.Internal;
|
||||||
|
using RdtClient.Service.Services;
|
||||||
|
|
||||||
namespace RdtClient.Web
|
namespace RdtClient.Web
|
||||||
{
|
{
|
||||||
|
|
@ -27,7 +30,7 @@ namespace RdtClient.Web
|
||||||
|
|
||||||
services.AddSingleton(appSettings);
|
services.AddSingleton(appSettings);
|
||||||
|
|
||||||
services.AddDbContext<DataContext>(options => options.UseSqlite(appSettings.ConnectionStrings.Client));
|
services.AddDbContext<DataContext>(options => options.UseSqlite(DataContext.ConnectionString));
|
||||||
|
|
||||||
services.AddControllers();
|
services.AddControllers();
|
||||||
|
|
||||||
|
|
@ -51,6 +54,8 @@ namespace RdtClient.Web
|
||||||
|
|
||||||
services.AddHttpsRedirection(options => { options.HttpsPort = 443; });
|
services.AddHttpsRedirection(options => { options.HttpsPort = 443; });
|
||||||
|
|
||||||
|
services.AddHttpClient();
|
||||||
|
|
||||||
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
|
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
|
||||||
.AddCookie(options => { options.SlidingExpiration = true; });
|
.AddCookie(options => { options.SlidingExpiration = true; });
|
||||||
|
|
||||||
|
|
@ -68,15 +73,22 @@ namespace RdtClient.Web
|
||||||
.AddEntityFrameworkStores<DataContext>()
|
.AddEntityFrameworkStores<DataContext>()
|
||||||
.AddDefaultTokenProviders();
|
.AddDefaultTokenProviders();
|
||||||
|
|
||||||
|
services.AddHangfire(configuration => configuration
|
||||||
|
.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
|
||||||
|
.UseSimpleAssemblyNameTypeSerializer()
|
||||||
|
.UseRecommendedSerializerSettings()
|
||||||
|
.UseMemoryStorage());
|
||||||
|
|
||||||
|
services.AddHangfireServer();
|
||||||
|
|
||||||
Data.DiConfig.Config(services);
|
Data.DiConfig.Config(services);
|
||||||
Service.DiConfig.Config(services);
|
Service.DiConfig.Config(services);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, DataContext dataContext, IScheduler scheduler)
|
||||||
{
|
{
|
||||||
if (env.IsDevelopment())
|
if (env.IsDevelopment())
|
||||||
{
|
{
|
||||||
app.UseDeveloperExceptionPage();
|
|
||||||
app.UseCors("Dev");
|
app.UseCors("Dev");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -92,6 +104,8 @@ namespace RdtClient.Web
|
||||||
|
|
||||||
app.UseAuthorization();
|
app.UseAuthorization();
|
||||||
|
|
||||||
|
app.UseHangfireServer();
|
||||||
|
|
||||||
app.UseEndpoints(endpoints =>
|
app.UseEndpoints(endpoints =>
|
||||||
{
|
{
|
||||||
endpoints.MapControllers();
|
endpoints.MapControllers();
|
||||||
|
|
@ -101,6 +115,10 @@ namespace RdtClient.Web
|
||||||
{
|
{
|
||||||
spa.Options.SourcePath = "wwwroot";
|
spa.Options.SourcePath = "wwwroot";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
dataContext.Migrate();
|
||||||
|
|
||||||
|
scheduler.Start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
512
server/RdtClient.Web/app.log
Normal file
512
server/RdtClient.Web/app.log
Normal file
|
|
@ -0,0 +1,512 @@
|
||||||
|
2020-04-03T15:59:20.1355273-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-03T15:59:20.1385649-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-03T15:59:20.2294123-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-03T15:59:20.2294368-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-03T15:59:20.2510079-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:17836:3146ca38 successfully announced in 101.8542 ms
|
||||||
|
2020-04-03T15:59:20.2510111-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:17836:f605d0e0 successfully announced in 20.7292 ms
|
||||||
|
2020-04-03T15:59:20.2541883-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:17836:3146ca38 is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-03T15:59:20.2541883-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:17836:f605d0e0 is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-03T15:59:20.2588662-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:17836:f605d0e0 all the dispatchers started
|
||||||
|
2020-04-03T15:59:20.2589265-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:17836:3146ca38 all the dispatchers started
|
||||||
|
2020-04-03T15:59:20.9901692-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Application started. Press Ctrl+C to shut down.
|
||||||
|
2020-04-03T15:59:20.9902829-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Hosting environment: Development
|
||||||
|
2020-04-03T15:59:20.9903021-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Content root path: C:\Projects\rdt-client\server\RdtClient.Web
|
||||||
|
2020-04-03T15:59:22.6292638-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-03T15:59:22.6322230-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-03T15:59:22.7242705-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-03T15:59:22.7243034-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-03T15:59:22.7452766-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:25392:c48269cc successfully announced in 19.9586 ms
|
||||||
|
2020-04-03T15:59:22.7452765-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:25392:15034db2 successfully announced in 101.7602 ms
|
||||||
|
2020-04-03T15:59:22.7481327-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:25392:15034db2 is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-03T15:59:22.7481351-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:25392:c48269cc is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-03T15:59:22.7533167-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:25392:15034db2 all the dispatchers started
|
||||||
|
2020-04-03T15:59:22.7535232-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:25392:c48269cc all the dispatchers started
|
||||||
|
2020-04-03T15:59:23.4204963-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Application started. Press Ctrl+C to shut down.
|
||||||
|
2020-04-03T15:59:23.4206249-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Hosting environment: Development
|
||||||
|
2020-04-03T15:59:23.4206510-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Content root path: C:\Projects\rdt-client\server\RdtClient.Web
|
||||||
|
2020-04-03T15:59:30.7772267-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:25392:c48269cc caught stopping signal...
|
||||||
|
2020-04-03T15:59:30.7779767-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Application is shutting down...
|
||||||
|
2020-04-03T15:59:30.7783343-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:25392:c48269cc caught stopped signal...
|
||||||
|
2020-04-03T15:59:30.7794920-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:25392:15034db2 caught stopping signal...
|
||||||
|
2020-04-03T15:59:30.7796436-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:25392:15034db2 caught stopped signal...
|
||||||
|
2020-04-03T15:59:30.7812297-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:25392:15034db2 All dispatchers stopped
|
||||||
|
2020-04-03T15:59:30.7812297-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:25392:c48269cc All dispatchers stopped
|
||||||
|
2020-04-03T15:59:30.7828238-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:25392:15034db2 successfully reported itself as stopped in 0.2783 ms
|
||||||
|
2020-04-03T15:59:30.7828222-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:25392:c48269cc successfully reported itself as stopped in 0.2778 ms
|
||||||
|
2020-04-03T15:59:30.7828386-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:25392:15034db2 has been stopped in total 3.303 ms
|
||||||
|
2020-04-03T15:59:30.7828431-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:25392:c48269cc has been stopped in total 5.4344 ms
|
||||||
|
2020-04-03T15:59:49.2420348-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-03T15:59:49.2449966-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-03T15:59:49.7330627-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-03T15:59:49.7342224-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-03T15:59:49.7767552-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:7656:238a3170 successfully announced in 518.619 ms
|
||||||
|
2020-04-03T15:59:49.7778417-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:7656:b384ecba successfully announced in 37.4892 ms
|
||||||
|
2020-04-03T15:59:49.7897107-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:7656:238a3170 is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-03T15:59:49.7907947-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:7656:b384ecba is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-03T15:59:49.9335939-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:7656:238a3170 all the dispatchers started
|
||||||
|
2020-04-03T15:59:49.9493934-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:7656:b384ecba all the dispatchers started
|
||||||
|
2020-04-03T15:59:50.8034032-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Application started. Press Ctrl+C to shut down.
|
||||||
|
2020-04-03T15:59:50.8108739-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Hosting environment: Development
|
||||||
|
2020-04-03T15:59:50.8127580-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Content root path: C:\Projects\rdt-client\server\RdtClient.Web
|
||||||
|
2020-04-03T16:06:29.6254854-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-03T16:06:29.6288727-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-03T16:06:29.7314839-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-03T16:06:29.7315143-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-03T16:06:29.7529384-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:18896:dd12c44a successfully announced in 111.5091 ms
|
||||||
|
2020-04-03T16:06:29.7529396-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:18896:15c956d5 successfully announced in 20.4625 ms
|
||||||
|
2020-04-03T16:06:29.7557415-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:18896:dd12c44a is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-03T16:06:29.7557411-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:18896:15c956d5 is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-03T16:06:29.7606532-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:18896:15c956d5 all the dispatchers started
|
||||||
|
2020-04-03T16:06:29.7608761-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:18896:dd12c44a all the dispatchers started
|
||||||
|
2020-04-03T16:06:30.9858222-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Application started. Press Ctrl+C to shut down.
|
||||||
|
2020-04-03T16:06:30.9940710-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Hosting environment: Development
|
||||||
|
2020-04-03T16:06:30.9966766-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Content root path: C:\Projects\rdt-client\server\RdtClient.Web
|
||||||
|
2020-04-03T17:20:18.4268508-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-03T17:20:18.4340796-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-03T17:20:18.6487165-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-03T17:20:18.6500981-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-03T17:20:18.6947841-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:21168:a6490904 successfully announced in 34.9489 ms
|
||||||
|
2020-04-03T17:20:18.6960854-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:21168:b2e9a60c successfully announced in 230.7784 ms
|
||||||
|
2020-04-03T17:20:18.7105510-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:21168:a6490904 is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-03T17:20:18.7121052-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:21168:b2e9a60c is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-03T17:20:18.8720117-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:21168:a6490904 all the dispatchers started
|
||||||
|
2020-04-03T17:20:18.8774595-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:21168:b2e9a60c all the dispatchers started
|
||||||
|
2020-04-03T17:20:19.7386911-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Application started. Press Ctrl+C to shut down.
|
||||||
|
2020-04-03T17:20:19.7416238-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Hosting environment: Development
|
||||||
|
2020-04-03T17:20:19.7486505-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Content root path: C:\Projects\rdt-client\server\RdtClient.Web
|
||||||
|
2020-04-03T17:59:08.0700362-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-03T17:59:08.0750113-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-03T17:59:08.2398601-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-03T17:59:08.2411315-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-03T17:59:08.2913718-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:10716:5ebe162c successfully announced in 42.0268 ms
|
||||||
|
2020-04-03T17:59:08.2925085-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:10716:fb956c19 successfully announced in 197.5027 ms
|
||||||
|
2020-04-03T17:59:08.3038936-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:10716:5ebe162c is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-03T17:59:08.3049895-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:10716:fb956c19 is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-03T17:59:08.4396784-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:10716:5ebe162c all the dispatchers started
|
||||||
|
2020-04-03T17:59:08.4538634-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:10716:fb956c19 all the dispatchers started
|
||||||
|
2020-04-03T17:59:09.4423137-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Application started. Press Ctrl+C to shut down.
|
||||||
|
2020-04-03T17:59:09.4523143-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Hosting environment: Development
|
||||||
|
2020-04-03T17:59:09.4550262-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Content root path: C:\Projects\rdt-client\server\RdtClient.Web
|
||||||
|
2020-04-04T13:36:51.3899679-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T13:36:51.3954070-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T13:36:52.2046648-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T13:36:52.2058469-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T13:36:52.2165588-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:18576:7232176f successfully announced in 5.629 ms
|
||||||
|
2020-04-04T13:36:52.2175955-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:18576:0c930dc4 successfully announced in 783.68 ms
|
||||||
|
2020-04-04T13:36:52.2258088-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:18576:0c930dc4 is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T13:36:52.2270592-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:18576:7232176f is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T13:36:52.3608248-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:18576:0c930dc4 all the dispatchers started
|
||||||
|
2020-04-04T13:36:52.3651180-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:18576:7232176f all the dispatchers started
|
||||||
|
2020-04-04T13:36:53.3815332-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Application started. Press Ctrl+C to shut down.
|
||||||
|
2020-04-04T13:36:53.3835819-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Hosting environment: Development
|
||||||
|
2020-04-04T13:36:53.3855069-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Content root path: C:\Projects\rdt-client\server\RdtClient.Web
|
||||||
|
2020-04-04T13:39:17.4290475-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T13:39:17.4351614-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T13:39:17.6188800-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T13:39:17.6200228-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T13:39:17.6633116-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:12312:46ba0401 successfully announced in 205.437 ms
|
||||||
|
2020-04-04T13:39:17.6653058-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:12312:626ef5ce successfully announced in 36.9854 ms
|
||||||
|
2020-04-04T13:39:17.6810736-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:12312:46ba0401 is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T13:39:17.6821454-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:12312:626ef5ce is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T13:39:17.8313892-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:12312:626ef5ce all the dispatchers started
|
||||||
|
2020-04-04T13:39:17.8518228-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:12312:46ba0401 all the dispatchers started
|
||||||
|
2020-04-04T13:39:18.6777049-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Application started. Press Ctrl+C to shut down.
|
||||||
|
2020-04-04T13:39:18.6853112-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Hosting environment: Development
|
||||||
|
2020-04-04T13:39:18.6872717-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Content root path: C:\Projects\rdt-client\server\RdtClient.Web
|
||||||
|
2020-04-04T13:45:52.2178972-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T13:45:52.2209059-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T13:45:52.7257245-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T13:45:52.7268420-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T13:45:52.7605590-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:25428:371ab538 successfully announced in 29.31 ms
|
||||||
|
2020-04-04T13:45:52.7616163-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:25428:beb90aed successfully announced in 527.3207 ms
|
||||||
|
2020-04-04T13:45:52.7947890-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:25428:371ab538 is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T13:45:52.7958992-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:25428:beb90aed is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T13:45:52.9335865-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:25428:beb90aed all the dispatchers started
|
||||||
|
2020-04-04T13:45:52.9433737-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:25428:371ab538 all the dispatchers started
|
||||||
|
2020-04-04T13:45:53.7610065-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Application started. Press Ctrl+C to shut down.
|
||||||
|
2020-04-04T13:45:53.7667118-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Hosting environment: Development
|
||||||
|
2020-04-04T13:45:53.7686187-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Content root path: C:\Projects\rdt-client\server\RdtClient.Web
|
||||||
|
2020-04-04T14:06:51.9875312-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T14:06:51.9910970-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T14:06:52.4849160-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T14:06:52.4860716-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T14:06:52.5226185-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:4496:e9cb1104 successfully announced in 517.9776 ms
|
||||||
|
2020-04-04T14:06:52.5276877-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:4496:2aa9fc9e successfully announced in 32.1255 ms
|
||||||
|
2020-04-04T14:06:52.5356524-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:4496:2aa9fc9e is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T14:06:52.5368007-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:4496:e9cb1104 is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T14:06:52.6798034-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:4496:e9cb1104 all the dispatchers started
|
||||||
|
2020-04-04T14:06:52.6843382-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:4496:2aa9fc9e all the dispatchers started
|
||||||
|
2020-04-04T14:06:53.5337779-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Application started. Press Ctrl+C to shut down.
|
||||||
|
2020-04-04T14:06:53.5419397-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Hosting environment: Development
|
||||||
|
2020-04-04T14:06:53.5438903-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Content root path: C:\Projects\rdt-client\server\RdtClient.Web
|
||||||
|
2020-04-04T14:09:28.6901247-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T14:09:28.6934944-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T14:09:28.8003885-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T14:09:28.8004416-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T14:09:28.8235716-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:11712:2f63d054 successfully announced in 22.2108 ms
|
||||||
|
2020-04-04T14:09:28.8235763-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:11712:6de68e38 successfully announced in 117.3382 ms
|
||||||
|
2020-04-04T14:09:28.8266785-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:11712:6de68e38 is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T14:09:28.8266804-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:11712:2f63d054 is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T14:09:28.8331305-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:11712:6de68e38 all the dispatchers started
|
||||||
|
2020-04-04T14:09:28.8332117-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:11712:2f63d054 all the dispatchers started
|
||||||
|
2020-04-04T14:09:30.0597550-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Application started. Press Ctrl+C to shut down.
|
||||||
|
2020-04-04T14:09:30.0661109-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Hosting environment: Development
|
||||||
|
2020-04-04T14:09:30.0679982-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Content root path: C:\Projects\rdt-client\server\RdtClient.Web
|
||||||
|
2020-04-04T14:10:30.2700465-06:00 FAIL [Microsoft.AspNetCore.Server.IIS.Core.IISHttpServer] [ApplicationError] Connection ID "18158513750708060161", Request ID "80000002-000c-fc00-b63f-84710c7967bb": An unhandled exception was thrown by the application.System.Text.Json.JsonException: A possible object cycle was detected which is not supported. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32.
|
||||||
|
at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_SerializerCycleDetected(Int32 maxDepth)
|
||||||
|
at System.Text.Json.JsonSerializer.Write(Utf8JsonWriter writer, Int32 originalWriterDepth, Int32 flushThreshold, JsonSerializerOptions options, WriteStack& state)
|
||||||
|
at System.Text.Json.JsonSerializer.WriteAsyncCore(Stream utf8Json, Object value, Type inputType, JsonSerializerOptions options, CancellationToken cancellationToken)
|
||||||
|
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
|
||||||
|
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
|
||||||
|
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeResultFilters>g__Awaited|27_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
|
||||||
|
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
|
||||||
|
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
|
||||||
|
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
|
||||||
|
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
|
||||||
|
at Microsoft.AspNetCore.Server.IIS.Core.IISHttpContextOfT`1.ProcessRequestAsync()
|
||||||
|
|
||||||
|
2020-04-04T14:11:12.4711056-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T14:11:12.4740177-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T14:11:12.5685353-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T14:11:12.5685678-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T14:11:12.5896902-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:11556:f733969e successfully announced in 104.0185 ms
|
||||||
|
2020-04-04T14:11:12.5896902-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:11556:85c7f28f successfully announced in 20.4301 ms
|
||||||
|
2020-04-04T14:11:12.5927719-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:11556:85c7f28f is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T14:11:12.5927773-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:11556:f733969e is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T14:11:12.5982186-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:11556:85c7f28f all the dispatchers started
|
||||||
|
2020-04-04T14:11:12.5982679-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:11556:f733969e all the dispatchers started
|
||||||
|
2020-04-04T14:11:13.8266479-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Application started. Press Ctrl+C to shut down.
|
||||||
|
2020-04-04T14:11:13.8300908-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Hosting environment: Development
|
||||||
|
2020-04-04T14:11:13.8397525-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Content root path: C:\Projects\rdt-client\server\RdtClient.Web
|
||||||
|
2020-04-04T14:23:21.7687075-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T14:23:21.7715620-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T14:23:21.8650133-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T14:23:21.8650397-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T14:23:21.8862045-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:13516:63077182 successfully announced in 103.9192 ms
|
||||||
|
2020-04-04T14:23:21.8862045-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:13516:8f1cdbd3 successfully announced in 19.9902 ms
|
||||||
|
2020-04-04T14:23:21.8889891-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:13516:63077182 is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T14:23:21.8889884-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:13516:8f1cdbd3 is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T14:23:21.8939088-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:13516:63077182 all the dispatchers started
|
||||||
|
2020-04-04T14:23:21.8939936-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:13516:8f1cdbd3 all the dispatchers started
|
||||||
|
2020-04-04T14:23:23.0689646-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Application started. Press Ctrl+C to shut down.
|
||||||
|
2020-04-04T14:23:23.0709673-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Hosting environment: Development
|
||||||
|
2020-04-04T14:23:23.0779228-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Content root path: C:\Projects\rdt-client\server\RdtClient.Web
|
||||||
|
2020-04-04T14:24:37.9847342-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T14:24:37.9882985-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T14:24:38.0825819-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T14:24:38.0826064-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T14:24:38.1036306-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:22580:c1366df7 successfully announced in 103.9479 ms
|
||||||
|
2020-04-04T14:24:38.1036305-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:22580:e3e831b7 successfully announced in 20.0026 ms
|
||||||
|
2020-04-04T14:24:38.1065641-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:22580:c1366df7 is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T14:24:38.1065662-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:22580:e3e831b7 is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T14:24:38.1114065-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:22580:e3e831b7 all the dispatchers started
|
||||||
|
2020-04-04T14:24:38.1114793-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:22580:c1366df7 all the dispatchers started
|
||||||
|
2020-04-04T14:24:39.2282210-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Application started. Press Ctrl+C to shut down.
|
||||||
|
2020-04-04T14:24:39.2423550-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Hosting environment: Development
|
||||||
|
2020-04-04T14:24:39.2447909-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Content root path: C:\Projects\rdt-client\server\RdtClient.Web
|
||||||
|
2020-04-04T14:28:26.3492596-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T14:28:26.3544781-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T14:28:26.5174135-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T14:28:26.5187379-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T14:28:26.5578223-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:20488:c6bc92b2 successfully announced in 182.3826 ms
|
||||||
|
2020-04-04T14:28:26.5588998-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:20488:20d17df5 successfully announced in 34.3576 ms
|
||||||
|
2020-04-04T14:28:26.5704666-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:20488:c6bc92b2 is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T14:28:26.5716322-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:20488:20d17df5 is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T14:28:26.7149113-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:20488:20d17df5 all the dispatchers started
|
||||||
|
2020-04-04T14:28:26.7226988-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:20488:c6bc92b2 all the dispatchers started
|
||||||
|
2020-04-04T14:28:27.5476942-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Application started. Press Ctrl+C to shut down.
|
||||||
|
2020-04-04T14:28:27.5548312-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Hosting environment: Development
|
||||||
|
2020-04-04T14:28:27.5565374-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Content root path: C:\Projects\rdt-client\server\RdtClient.Web
|
||||||
|
2020-04-04T14:29:22.4970867-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T14:29:22.5000868-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T14:29:22.5972226-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T14:29:22.5972498-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T14:29:22.6185406-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:8704:7f562bd0 successfully announced in 20.3044 ms
|
||||||
|
2020-04-04T14:29:22.6185503-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:8704:25c03ed6 successfully announced in 107.2263 ms
|
||||||
|
2020-04-04T14:29:22.6212883-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:8704:25c03ed6 is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T14:29:22.6212868-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:8704:7f562bd0 is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T14:29:22.6272480-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:8704:25c03ed6 all the dispatchers started
|
||||||
|
2020-04-04T14:29:22.6275399-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:8704:7f562bd0 all the dispatchers started
|
||||||
|
2020-04-04T14:29:23.8020576-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Application started. Press Ctrl+C to shut down.
|
||||||
|
2020-04-04T14:29:23.8092332-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Hosting environment: Development
|
||||||
|
2020-04-04T14:29:23.8114626-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Content root path: C:\Projects\rdt-client\server\RdtClient.Web
|
||||||
|
2020-04-04T14:33:29.3029557-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T14:33:29.3060421-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T14:33:29.3995563-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T14:33:29.3996017-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T14:33:29.4210320-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:11468:78e298c5 successfully announced in 103.7016 ms
|
||||||
|
2020-04-04T14:33:29.4210325-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:11468:79ee0690 successfully announced in 20.3431 ms
|
||||||
|
2020-04-04T14:33:29.4238373-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:11468:78e298c5 is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T14:33:29.4238390-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:11468:79ee0690 is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T14:33:29.4293346-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:11468:78e298c5 all the dispatchers started
|
||||||
|
2020-04-04T14:33:29.4294031-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:11468:79ee0690 all the dispatchers started
|
||||||
|
2020-04-04T14:33:30.5171651-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Application started. Press Ctrl+C to shut down.
|
||||||
|
2020-04-04T14:33:30.5207118-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Hosting environment: Development
|
||||||
|
2020-04-04T14:33:30.5262510-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Content root path: C:\Projects\rdt-client\server\RdtClient.Web
|
||||||
|
2020-04-04T14:35:26.4931298-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T14:35:26.4960740-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T14:35:26.5902385-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T14:35:26.5902725-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T14:35:26.6112554-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:9364:548bcc22 successfully announced in 20.0425 ms
|
||||||
|
2020-04-04T14:35:26.6112554-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:9364:a39fa135 successfully announced in 104.5842 ms
|
||||||
|
2020-04-04T14:35:26.6138703-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:9364:548bcc22 is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T14:35:26.6138680-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:9364:a39fa135 is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T14:35:26.6186498-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:9364:a39fa135 all the dispatchers started
|
||||||
|
2020-04-04T14:35:26.6187979-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:9364:548bcc22 all the dispatchers started
|
||||||
|
2020-04-04T14:35:27.7550471-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Application started. Press Ctrl+C to shut down.
|
||||||
|
2020-04-04T14:35:27.7577200-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Hosting environment: Development
|
||||||
|
2020-04-04T14:35:27.7656669-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Content root path: C:\Projects\rdt-client\server\RdtClient.Web
|
||||||
|
2020-04-04T14:36:13.4963403-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T14:36:13.4995347-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T14:36:13.5937296-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T14:36:13.5937661-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T14:36:13.6136017-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:24484:d3f096b7 successfully announced in 102.8649 ms
|
||||||
|
2020-04-04T14:36:13.6136017-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:24484:0486235c successfully announced in 18.8774 ms
|
||||||
|
2020-04-04T14:36:13.6161824-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:24484:0486235c is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T14:36:13.6161810-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:24484:d3f096b7 is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T14:36:13.6211768-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:24484:0486235c all the dispatchers started
|
||||||
|
2020-04-04T14:36:13.6212520-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:24484:d3f096b7 all the dispatchers started
|
||||||
|
2020-04-04T14:36:14.7116432-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Application started. Press Ctrl+C to shut down.
|
||||||
|
2020-04-04T14:36:14.7193962-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Hosting environment: Development
|
||||||
|
2020-04-04T14:36:14.7217224-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Content root path: C:\Projects\rdt-client\server\RdtClient.Web
|
||||||
|
2020-04-04T14:44:06.0389258-06:00 FAIL [Microsoft.AspNetCore.Server.IIS.Core.IISHttpServer] [ApplicationError] Connection ID "18302628887244309062", Request ID "80000247-0000-fe00-b63f-84710c7967bb": An unhandled exception was thrown by the application.System.InvalidOperationException: The SPA default page middleware could not return the default page '/index.html' because it was not found, and no other middleware handled the request.
|
||||||
|
|
||||||
|
at Microsoft.AspNetCore.SpaServices.SpaDefaultPageMiddleware.<>c__DisplayClass0_0.<Attach>b__1(HttpContext context, Func`1 next)
|
||||||
|
at Microsoft.AspNetCore.Builder.UseExtensions.<>c__DisplayClass0_1.<Use>b__1(HttpContext context)
|
||||||
|
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.TryServeStaticFile(HttpContext context, String contentType, PathString subPath)
|
||||||
|
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
|
||||||
|
at Microsoft.AspNetCore.Builder.UseExtensions.<>c__DisplayClass0_2.<Use>b__2()
|
||||||
|
at Microsoft.AspNetCore.SpaServices.SpaDefaultPageMiddleware.<>c__DisplayClass0_0.<Attach>b__0(HttpContext context, Func`1 next)
|
||||||
|
at Microsoft.AspNetCore.Builder.UseExtensions.<>c__DisplayClass0_1.<Use>b__1(HttpContext context)
|
||||||
|
at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
|
||||||
|
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
|
||||||
|
at Microsoft.AspNetCore.Server.IIS.Core.IISHttpContextOfT`1.ProcessRequestAsync()
|
||||||
|
|
||||||
|
2020-04-04T14:44:07.1916383-06:00 FAIL [Microsoft.AspNetCore.Server.IIS.Core.IISHttpServer] [ApplicationError] Connection ID "18302628930193982207", Request ID "80000300-000a-fe00-b63f-84710c7967bb": An unhandled exception was thrown by the application.System.InvalidOperationException: The SPA default page middleware could not return the default page '/index.html' because it was not found, and no other middleware handled the request.
|
||||||
|
|
||||||
|
at Microsoft.AspNetCore.SpaServices.SpaDefaultPageMiddleware.<>c__DisplayClass0_0.<Attach>b__1(HttpContext context, Func`1 next)
|
||||||
|
at Microsoft.AspNetCore.Builder.UseExtensions.<>c__DisplayClass0_1.<Use>b__1(HttpContext context)
|
||||||
|
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.TryServeStaticFile(HttpContext context, String contentType, PathString subPath)
|
||||||
|
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
|
||||||
|
at Microsoft.AspNetCore.Builder.UseExtensions.<>c__DisplayClass0_2.<Use>b__2()
|
||||||
|
at Microsoft.AspNetCore.SpaServices.SpaDefaultPageMiddleware.<>c__DisplayClass0_0.<Attach>b__0(HttpContext context, Func`1 next)
|
||||||
|
at Microsoft.AspNetCore.Builder.UseExtensions.<>c__DisplayClass0_1.<Use>b__1(HttpContext context)
|
||||||
|
at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
|
||||||
|
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
|
||||||
|
at Microsoft.AspNetCore.Server.IIS.Core.IISHttpContextOfT`1.ProcessRequestAsync()
|
||||||
|
|
||||||
|
2020-04-04T14:47:54.0323392-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T14:47:54.0367216-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T14:47:54.1985129-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T14:47:54.1996782-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T14:47:54.2766426-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:9924:7a1f1a6b successfully announced in 70.8826 ms
|
||||||
|
2020-04-04T14:47:54.2806642-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:9924:d0351e6f successfully announced in 214.1212 ms
|
||||||
|
2020-04-04T14:47:54.2889140-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:9924:7a1f1a6b is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T14:47:54.2900438-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:9924:d0351e6f is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T14:47:54.4139151-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:9924:d0351e6f all the dispatchers started
|
||||||
|
2020-04-04T14:47:54.4368669-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:9924:7a1f1a6b all the dispatchers started
|
||||||
|
2020-04-04T14:47:55.2715624-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Application started. Press Ctrl+C to shut down.
|
||||||
|
2020-04-04T14:47:55.2771286-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Hosting environment: Development
|
||||||
|
2020-04-04T14:47:55.2789075-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Content root path: C:\Projects\rdt-client\server\RdtClient.Web
|
||||||
|
2020-04-04T14:48:49.5565338-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T14:48:49.5594208-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T14:48:49.6547594-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T14:48:49.6547886-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T14:48:49.6754648-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:22936:b12db8cb successfully announced in 105.0262 ms
|
||||||
|
2020-04-04T14:48:49.6754648-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:22936:fd149353 successfully announced in 19.6826 ms
|
||||||
|
2020-04-04T14:48:49.6783402-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:22936:b12db8cb is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T14:48:49.6783431-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:22936:fd149353 is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T14:48:50.1962026-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:22936:fd149353 all the dispatchers started
|
||||||
|
2020-04-04T14:48:50.1981452-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:22936:b12db8cb all the dispatchers started
|
||||||
|
2020-04-04T14:48:51.0147387-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Application started. Press Ctrl+C to shut down.
|
||||||
|
2020-04-04T14:48:51.0220660-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Hosting environment: Development
|
||||||
|
2020-04-04T14:48:51.0239132-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Content root path: C:\Projects\rdt-client\server\RdtClient.Web
|
||||||
|
2020-04-04T14:50:09.5762316-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T14:50:09.5792141-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T14:50:09.6739724-06:00 INFO [Hangfire.BackgroundJobServer] [0] Starting Hangfire Server using job storage: 'Hangfire.MemoryStorage.MemoryStorage'
|
||||||
|
2020-04-04T14:50:09.6740028-06:00 INFO [Hangfire.BackgroundJobServer] [0] Using the following options for Hangfire Server:
|
||||||
|
Worker count: 20
|
||||||
|
Listening queues: 'default'
|
||||||
|
Shutdown timeout: 00:00:15
|
||||||
|
Schedule polling interval: 00:00:15
|
||||||
|
2020-04-04T14:50:09.6944222-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:18196:9c827089 successfully announced in 19.5569 ms
|
||||||
|
2020-04-04T14:50:09.6944222-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:18196:a1cafa69 successfully announced in 104.5052 ms
|
||||||
|
2020-04-04T14:50:09.6970626-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:18196:9c827089 is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T14:50:09.6970626-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:18196:a1cafa69 is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
|
||||||
|
2020-04-04T14:50:09.7022113-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:18196:9c827089 all the dispatchers started
|
||||||
|
2020-04-04T14:50:09.7024526-06:00 INFO [Hangfire.Server.BackgroundServerProcess] [0] Server roger-pc:18196:a1cafa69 all the dispatchers started
|
||||||
|
2020-04-04T14:50:10.8721989-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Application started. Press Ctrl+C to shut down.
|
||||||
|
2020-04-04T14:50:10.8807198-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Hosting environment: Development
|
||||||
|
2020-04-04T14:50:10.8830457-06:00 INFO [Microsoft.Hosting.Lifetime] [0] Content root path: C:\Projects\rdt-client\server\RdtClient.Web
|
||||||
|
|
@ -3,11 +3,15 @@
|
||||||
"LogLevel": {
|
"LogLevel": {
|
||||||
"Default": "Information",
|
"Default": "Information",
|
||||||
"Microsoft": "Warning",
|
"Microsoft": "Warning",
|
||||||
"Microsoft.Hosting.Lifetime": "Information"
|
"Microsoft.Hosting.Lifetime": "Information",
|
||||||
|
"Hangfire": "Information"
|
||||||
|
},
|
||||||
|
"File": {
|
||||||
|
"Path": "app.log",
|
||||||
|
"Append": "True",
|
||||||
|
"FileSizeLimitBytes": 2048,
|
||||||
|
"MaxRollingFiles": 5
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"AllowedHosts": "*",
|
"AllowedHosts": "*"
|
||||||
"ConnectionStrings": {
|
|
||||||
"Client": "Host=localhost;Database=fieldcap;Username=fieldcap;Password=fieldcap;Maximum Pool Size=30"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
63
server/libs/RDNET.deps.json
Normal file
63
server/libs/RDNET.deps.json
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
{
|
||||||
|
"runtimeTarget": {
|
||||||
|
"name": ".NETStandard,Version=v2.0/",
|
||||||
|
"signature": ""
|
||||||
|
},
|
||||||
|
"compilationOptions": {},
|
||||||
|
"targets": {
|
||||||
|
".NETStandard,Version=v2.0": {},
|
||||||
|
".NETStandard,Version=v2.0/": {
|
||||||
|
"RDNET/1.0.0": {
|
||||||
|
"dependencies": {
|
||||||
|
"NETStandard.Library": "2.0.3",
|
||||||
|
"Newtonsoft.Json": "12.0.3"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"RDNET.dll": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.NETCore.Platforms/1.1.0": {},
|
||||||
|
"NETStandard.Library/2.0.3": {
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.Platforms": "1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Newtonsoft.Json/12.0.3": {
|
||||||
|
"runtime": {
|
||||||
|
"lib/netstandard2.0/Newtonsoft.Json.dll": {
|
||||||
|
"assemblyVersion": "12.0.0.0",
|
||||||
|
"fileVersion": "12.0.3.23909"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"libraries": {
|
||||||
|
"RDNET/1.0.0": {
|
||||||
|
"type": "project",
|
||||||
|
"serviceable": false,
|
||||||
|
"sha512": ""
|
||||||
|
},
|
||||||
|
"Microsoft.NETCore.Platforms/1.1.0": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==",
|
||||||
|
"path": "microsoft.netcore.platforms/1.1.0",
|
||||||
|
"hashPath": "microsoft.netcore.platforms.1.1.0.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"NETStandard.Library/2.0.3": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==",
|
||||||
|
"path": "netstandard.library/2.0.3",
|
||||||
|
"hashPath": "netstandard.library.2.0.3.nupkg.sha512"
|
||||||
|
},
|
||||||
|
"Newtonsoft.Json/12.0.3": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-6mgjfnRB4jKMlzHSl+VD+oUc1IebOZabkbyWj2RiTgWwYPPuaK1H97G1sHqGwPlS5npiF5Q0OrxN1wni2n5QWg==",
|
||||||
|
"path": "newtonsoft.json/12.0.3",
|
||||||
|
"hashPath": "newtonsoft.json.12.0.3.nupkg.sha512"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
server/libs/RDNET.dll
Normal file
BIN
server/libs/RDNET.dll
Normal file
Binary file not shown.
BIN
server/libs/RDNET.pdb
Normal file
BIN
server/libs/RDNET.pdb
Normal file
Binary file not shown.
Loading…
Reference in a new issue