Upgrade to .NET6 and Angular 13.

This commit is contained in:
Roger Far 2021-11-21 13:58:49 -07:00
parent 52b5aa1b09
commit 4dbd2cf8df
39 changed files with 2257 additions and 6619 deletions

38
.gitignore vendored
View file

@ -1,44 +1,6 @@
### Angular ###
# compiled output
client/dist/
client/tmp/
client/app/**/*.js
client/app/**/*.js.map
# dependencies
client/node_modules/
client/bower_components/
# IDEs and editors
client/.idea/
# misc
client/.sass-cache/
client/connect.lock/
client/coverage/
client/libpeerconnection.log/
client/npm-debug.log
client/testem.log
client/typings/
# e2e
client/e2e/*.js
client/e2e/*.map
#System Files
**/.DS_Store/
### DotnetCore ###
# .NET Core build folders
server/**/bin
server/**/obj
server/**/*.user
server/**/.vs
server/RdtClient.Web/wwwroot/
build/
publish/
server/Downloader/
node_modules/
RealDebridClient.zip

View file

@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [2.0.0] - 2021-11-21
### Changed
- Update projects to .NET6 and Angular 13.
## [1.9.8] - 2021-10-30
### Added
- Add speed limit setting on the Simple downloader.

View file

@ -14,12 +14,12 @@ RUN \
cd client && \
echo "**** Building Code ****" && \
npm ci && \
npx ng build --prod --output-path=out
npx ng build --output-path=out
RUN ls -FCla /appclient/root
# Stage 2 - Build the backend
FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim-amd64 AS dotnet-build-env
FROM mcr.microsoft.com/dotnet/sdk:6.0-bullseye-slim-amd64 AS dotnet-build-env
ARG TARGETPLATFORM
ENV TARGETPLATFORM=${TARGETPLATFORM:-linux/amd64}
ARG BUILDPLATFORM

View file

@ -3,10 +3,10 @@
This is a web interface to manage your torrents on Real-Debrid or AllDebrid. It supports the following features:
- Add new torrents through magnets or files
- Download all files from Real Debrid or AllDebrid to your local machine automatically
- Download all files from Real-Debrid or AllDebrid to your local machine automatically
- Unpack all files when finished downloading
- Implements a fake qBittorrent API so you can hook up other applications like Sonarr or Couchpotato.
- Built with Angular 11 and .NET 5
- Built with Angular 13 and .NET 6
**You will need a Premium service at Real-Debrid or AllDebrid!**
@ -70,6 +70,7 @@ Replace the paths in `volumes` as in the above step.
Instead of running in Docker you can install it as a service in Windows or Linux (not tested).
1. Make sure you have the ASP.NET Core Runtime 6 installed: [https://dotnet.microsoft.com/download/dotnet/6.0](https://dotnet.microsoft.com/download/dotnet/6.0)
1. Get the latest zip file from the Releases page and extract it to your host.
1. Open the `appsettings.json` file and replace the `LogLevel` `Path` to a path on your host.
1. In `appsettings.json` replace the `Database` `Path` to a path on your host.
@ -96,7 +97,7 @@ This is a simple 1 connection only download manager. It uses less resources than
It has the following options:
- Maximum parallel downloads: This number indicates how many completed torrents from Real Debrid can be downloaded at the same time. On low powered systems it is recommended to keep this number low.
- Maximum parallel downloads: This number indicates how many completed torrents from Real-Debrid can be downloaded at the same time. On low powered systems it is recommended to keep this number low.
#### Multi Part Downloader
@ -105,7 +106,7 @@ This [downloader](https://github.com/bezzad/Downloader) as more options and such
It has the following options:
- Temp Download path: Set this path to where the downloader temporarily stores chunks. This path can be an internal path in Docker (i.e. `/data/temp`) but make sure you have enough disk space to complete the whole download. When all chunks are completed the completed file is copied to your download folder.
- Maximum parallel downloads: This number indicates how many completed torrents from Real Debrid can be downloaded at the same time.
- Maximum parallel downloads: This number indicates how many completed torrents from Real-Debrid can be downloaded at the same time.
- Parallel connections per download: This number indicates how many threads/connections/parts/chunks it will use per download. This can increase speed, recommended is no more than 8.
- Download speed (in MB/s): This number indicates the speed in MB/s per download. If you set this to 10 and `Maximum parallel downloads` to 2, you can download with a maximum of 20MB/s.
@ -149,8 +150,8 @@ Notice: the progress and ETA reported in Sonarr's Activity tab will not be accur
- NodeJS
- NPM
- Angular CLI
- .NET 5
- Visual Studio 2019
- .NET 6
- Visual Studio 2022
- (optional) Resharper
1. Open the client folder project in VS Code and run `npm install`.

View file

@ -2,11 +2,15 @@
# For additional information regarding the format and rule options, please see:
# https://github.com/browserslist/browserslist#queries
# For the full list of supported browsers by the Angular framework, please see:
# https://angular.io/guide/browser-support
# You can see what browsers were selected by your queries by running:
# npx browserslist
> 0.5%
last 2 versions
last 1 Chrome version
last 1 Firefox version
last 2 Edge major versions
last 2 Safari major versions
last 2 iOS major versions
Firefox ESR
not dead
not IE 9-11 # For IE 9-11 support, remove 'not'.

46
client/.gitignore vendored
View file

@ -0,0 +1,46 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
/dist
/tmp
/out-tsc
# Only exists if Bazel was run
/bazel-out
# dependencies
/node_modules
# profiling files
chrome-profiler-events*.json
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history/*
# misc
/.angular/cache
/.sass-cache
/connect.lock
/coverage
/libpeerconnection.log
npm-debug.log
yarn-error.log
testem.log
/typings
# System Files
.DS_Store
Thumbs.db

View file

@ -3,11 +3,33 @@
"version": 1,
"newProjectRoot": "projects",
"projects": {
"rdt-client": {
"client": {
"projectType": "application",
"schematics": {
"@schematics/angular:component": {
"style": "scss"
"style": "scss",
"skipTests": true
},
"@schematics/angular:class": {
"skipTests": true
},
"@schematics/angular:directive": {
"skipTests": true
},
"@schematics/angular:guard": {
"skipTests": true
},
"@schematics/angular:interceptor": {
"skipTests": true
},
"@schematics/angular:pipe": {
"skipTests": true
},
"@schematics/angular:service": {
"skipTests": true
},
"@schematics/angular:application": {
"strict": true
}
},
"root": "",
@ -22,102 +44,67 @@
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"inlineStyleLanguage": "scss",
"assets": ["src/favicon.ico", "src/assets"],
"styles": ["src/styles.scss"],
"scripts": [],
"vendorChunk": true,
"extractLicenses": false,
"buildOptimizer": false,
"sourceMap": true,
"optimization": false,
"namedChunks": true
"scripts": []
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "500kb",
"maximumError": "1mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "4kb"
}
],
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb",
"maximumError": "10kb"
}
]
"outputHashing": "all"
},
"development": {
"buildOptimizer": false,
"optimization": false,
"vendorChunk": true,
"extractLicenses": false,
"sourceMap": true,
"namedChunks": true
}
},
"defaultConfiguration": ""
"defaultConfiguration": "production"
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "rdt-client:build",
"proxyConfig": "angular-proxy.json"
},
"configurations": {
"production": {
"browserTarget": "rdt-client:build:production"
"browserTarget": "client:build:production"
},
"development": {
"browserTarget": "client:build:development"
}
}
},
"defaultConfiguration": "development"
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "rdt-client:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.spec.json",
"karmaConfig": "karma.conf.js",
"assets": ["src/favicon.ico", "src/assets"],
"styles": ["src/styles.scss"],
"scripts": []
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"tsconfig.app.json",
"tsconfig.spec.json",
"e2e/tsconfig.json"
],
"exclude": ["**/node_modules/**"]
}
},
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "rdt-client:serve"
},
"configurations": {
"production": {
"devServerTarget": "rdt-client:serve:production"
}
"browserTarget": "client:build"
}
}
}
}
},
"defaultProject": "rdt-client"
"defaultProject": "client"
}

View file

@ -1,32 +0,0 @@
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('@angular-devkit/build-angular/plugins/karma')
],
client: {
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
coverageIstanbulReporter: {
dir: require('path').join(__dirname, './coverage/rdt-client'),
reports: ['html', 'lcovonly', 'text-summary'],
fixWebpackSourcePaths: true
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
restartOnFileChange: true
});
};

7714
client/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,29 +1,27 @@
{
"name": "rdt-client",
"name": "client",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"watch": "ng build --watch --configuration development",
"update": "ng update --force --allow-dirty @angular/cli @angular/core"
},
"private": true,
"dependencies": {
"@angular/animations": "~12.2.9",
"@angular/cdk": "^12.2.9",
"@angular/common": "~12.2.9",
"@angular/compiler": "~12.2.9",
"@angular/core": "~12.2.9",
"@angular/animations": "~13.0.2",
"@angular/cdk": "^13.0.2",
"@angular/common": "~13.0.2",
"@angular/compiler": "~13.0.2",
"@angular/core": "~13.0.2",
"@angular/flex-layout": "^12.0.0-beta.35",
"@angular/forms": "~12.2.9",
"@angular/platform-browser": "~12.2.9",
"@angular/platform-browser-dynamic": "~12.2.9",
"@angular/router": "~12.2.9",
"@angular/forms": "~13.0.2",
"@angular/platform-browser": "~13.0.2",
"@angular/platform-browser-dynamic": "~13.0.2",
"@angular/router": "~13.0.2",
"@fortawesome/fontawesome-free": "^5.15.4",
"@microsoft/signalr": "^5.0.10",
"@microsoft/signalr": "^6.0.0",
"bulma": "^0.9.3",
"curray": "^1.0.8",
"file-saver": "^2.0.5",
@ -33,24 +31,12 @@
"zone.js": "~0.11.4"
},
"devDependencies": {
"@angular-devkit/build-angular": "~12.2.9",
"@angular/cli": "~12.2.9",
"@angular/compiler-cli": "~12.2.9",
"@angular/language-service": "~12.2.9",
"@types/node": "^16.10.3",
"@types/jasmine": "~3.9.1",
"@types/jasminewd2": "~2.0.10",
"codelyzer": "^6.0.2",
"jasmine-core": "~3.9.0",
"jasmine-spec-reporter": "~7.0.0",
"karma": "~6.3.4",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage-istanbul-reporter": "~3.0.3",
"karma-jasmine": "~4.0.1",
"karma-jasmine-html-reporter": "^1.7.0",
"protractor": "~7.0.0",
"ts-node": "~10.2.1",
"tslint": "~6.1.0",
"typescript": "~4.3.5"
"@angular-devkit/build-angular": "~13.0.3",
"@angular/cli": "~13.0.3",
"@angular/compiler-cli": "~13.0.0",
"@angular/language-service": "~13.0.2",
"@types/file-saver": "^2.0.4",
"@types/node": "^16.11.9",
"typescript": "~4.4.4"
}
}

View file

@ -88,8 +88,8 @@
<div class="control select is-fullwidth">
<select [(ngModel)]="finishedAction">
<option [ngValue]="0">Do nothing</option>
<option [ngValue]="1">Remove torrent from Real-Debrid and Real-Debrid Client</option>
<option [ngValue]="2">Remove torrent from Real-Debrid</option>
<option [ngValue]="1">Remove torrent from provider and client</option>
<option [ngValue]="2">Remove torrent from provider</option>
</select>
</div>
</div>

View file

@ -348,12 +348,12 @@
<div class="control">
<label class="checkbox">
<input type="checkbox" [(ngModel)]="deleteData" />
Delete Torrent from local Real-Debrid Client
Delete Torrent from client
</label>
<br />
<label class="checkbox">
<input type="checkbox" [(ngModel)]="deleteRdTorrent" />
Delete Torrent from Real-Debrid
Delete Torrent from provider
</label>
<br />
<label class="checkbox">

View file

@ -1,3 +1,3 @@
export const environment = {
production: true,
production: true
};

View file

@ -1,9 +1,9 @@
// This file can be replaced during build by using the `fileReplacements` array.
// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
// `ng build` replaces `environment.ts` with `environment.prod.ts`.
// The list of file replacements can be found in `angular.json`.
export const environment = {
production: false,
production: false
};
/*

View file

@ -7,7 +7,7 @@
<script>
(function () {
window["_app_base"] = "/" + window.location.pathname.split("/")[1];
console.log('setting base href to ' + window["_app_base"])
console.log("setting base href to " + window["_app_base"]);
})();
</script>
<meta name="viewport" content="width=device-width, initial-scale=1" />

View file

@ -8,6 +8,5 @@ if (environment.production) {
enableProdMode();
}
platformBrowserDynamic()
.bootstrapModule(AppModule)
.catch((err) => console.error(err));
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));

View file

@ -8,8 +8,8 @@
* file.
*
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that
* automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
* Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
* automatically update themselves. This includes recent versions of Safari, Chrome (including
* Opera), Edge on the desktop, and iOS and Chrome on mobile.
*
* Learn more in https://angular.io/guide/browser-support
*/
@ -18,16 +18,6 @@
* BROWSER POLYFILLS
*/
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
// import 'classlist.js'; // Run `npm install --save classlist.js`.
/**
* Web Animations `@angular/platform-browser/animations`
* Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
* Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
*/
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
/**
* By default, zone.js will patch all possible macroTask and DomEvents
* user can disable parts of macroTask/DomEvents patch by setting following flags
@ -55,7 +45,8 @@
/***************************************************************************************************
* Zone JS is required by default for Angular itself.
*/
import 'zone.js'; // Included with Angular CLI.
import 'zone.js'; // Included with Angular CLI.
/***************************************************************************************************
* APPLICATION IMPORTS

View file

@ -1,23 +0,0 @@
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
import 'zone.js/testing';
import { getTestBed } from '@angular/core/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
declare const require: {
context(
path: string,
deep?: boolean,
filter?: RegExp
): {
keys(): string[];
<T>(id: string): T;
};
};
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
// Then we find all the tests.
const context = require.context('./', true, /\.spec\.ts$/);
// And load the modules.
context.keys().map(context);

View file

@ -1,3 +1,4 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "./tsconfig.json",
"compilerOptions": {

View file

@ -1,23 +1,33 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"sourceMap": true,
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"module": "es2020",
"moduleResolution": "node",
"importHelpers": true,
"target": "es2015",
"strictNullChecks": false,
"target": "es2017",
"module": "es2020",
"lib": [
"es2018",
"es2020",
"dom"
]
},
"angularCompilerOptions": {
"fullTemplateTypeCheck": true,
"strictInjectionParameters": true
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true
}
}

View file

@ -1,18 +0,0 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/spec",
"types": [
"jasmine",
"node"
]
},
"files": [
"src/test.ts",
"src/polyfills.ts"
],
"include": [
"src/**/*.spec.ts",
"src/**/*.d.ts"
]
}

View file

@ -1,103 +0,0 @@
{
"extends": "tslint:recommended",
"rules": {
"align": {
"options": ["parameters", "statements"]
},
"array-type": false,
"arrow-return-shorthand": true,
"curly": true,
"deprecation": {
"severity": "warning"
},
"component-class-suffix": true,
"contextual-lifecycle": true,
"directive-class-suffix": true,
"directive-selector": [true, "attribute", "app", "camelCase"],
"component-selector": [true, "element", "app", "kebab-case"],
"eofline": true,
"import-blacklist": [true, "rxjs/Rx"],
"import-spacing": true,
"indent": {
"options": ["spaces"]
},
"max-classes-per-file": false,
"max-line-length": [true, 140],
"member-ordering": [
true,
{
"order": [
"static-field",
"instance-field",
"static-method",
"instance-method"
]
}
],
"no-console": [true, "debug", "info", "time", "timeEnd", "trace"],
"no-empty": false,
"no-inferrable-types": [true, "ignore-params"],
"no-non-null-assertion": true,
"no-redundant-jsdoc": true,
"no-switch-case-fall-through": true,
"no-var-requires": false,
"object-literal-key-quotes": [true, "as-needed"],
"quotemark": [true, "single"],
"semicolon": {
"options": ["always"]
},
"space-before-function-paren": {
"options": {
"anonymous": "never",
"asyncArrow": "always",
"constructor": "never",
"method": "never",
"named": "never"
}
},
"typedef-whitespace": {
"options": [
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
},
{
"call-signature": "onespace",
"index-signature": "onespace",
"parameter": "onespace",
"property-declaration": "onespace",
"variable-declaration": "onespace"
}
]
},
"variable-name": {
"options": ["ban-keywords", "check-format", "allow-pascal-case"]
},
"whitespace": {
"options": [
"check-branch",
"check-decl",
"check-operator",
"check-separator",
"check-type",
"check-typecast"
]
},
"no-conflicting-lifecycle": true,
"no-host-metadata-property": true,
"no-input-rename": true,
"no-inputs-metadata-property": true,
"no-output-native": true,
"no-output-on-prefix": true,
"no-output-rename": true,
"no-outputs-metadata-property": true,
"template-banana-in-box": true,
"template-no-negated-async": true,
"use-lifecycle-interface": true,
"use-pipe-transform-interface": true
},
"rulesDirectory": ["codelyzer"]
}

View file

@ -1,6 +1,6 @@
{
"name": "rdt-client",
"version": "1.9.8",
"version": "2.0.0",
"description": "This is a web interface to manage your torrents on Real-Debrid.",
"main": "index.js",
"dependencies": {

39
server/.gitignore vendored Normal file
View file

@ -0,0 +1,39 @@
*.swp
*.*~
project.lock.json
.DS_Store
*.pyc
nupkg/
# Visual Studio Code
.vscode
# Rider
.idea
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
build/
bld/
[Bb]in/
[Oo]bj/
[Oo]ut/
msbuild.log
msbuild.err
msbuild.wrn
# Visual Studio 2015
.vs/
wwwroot/

View file

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Newtonsoft.Json;
using System.Text.Json;
using RdtClient.Data.Enums;
using RdtClient.Data.Models.TorrentClient;
@ -66,7 +66,7 @@ namespace RdtClient.Data.Models.Data
try
{
return JsonConvert.DeserializeObject<List<TorrentClientFile>>(RdFiles);
return JsonSerializer.Deserialize<List<TorrentClientFile>>(RdFiles);
}
catch
{

View file

@ -1,26 +1,26 @@
using System;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace RdtClient.Data.Models.QBittorrent
{
public class AppBuildInfo
{
[JsonProperty("bitness")]
[JsonPropertyName("bitness")]
public Int64 Bitness { get; set; }
[JsonProperty("boost")]
[JsonPropertyName("boost")]
public String Boost { get; set; }
[JsonProperty("libtorrent")]
[JsonPropertyName("libtorrent")]
public String Libtorrent { get; set; }
[JsonProperty("openssl")]
[JsonPropertyName("openssl")]
public String Openssl { get; set; }
[JsonProperty("qt")]
[JsonPropertyName("qt")]
public String Qt { get; set; }
[JsonProperty("zlib")]
[JsonPropertyName("zlib")]
public String Zlib { get; set; }
}
}

View file

@ -1,5 +1,5 @@
using System;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace RdtClient.Data.Models.QBittorrent
{
@ -7,424 +7,424 @@ namespace RdtClient.Data.Models.QBittorrent
{
public class AppPreferences
{
[JsonProperty("add_trackers")]
[JsonPropertyName("add_trackers")]
public String AddTrackers { get; set; }
[JsonProperty("add_trackers_enabled")]
[JsonPropertyName("add_trackers_enabled")]
public Boolean AddTrackersEnabled { get; set; }
[JsonProperty("alt_dl_limit")]
[JsonPropertyName("alt_dl_limit")]
public Int64 AltDlLimit { get; set; }
[JsonProperty("alt_up_limit")]
[JsonPropertyName("alt_up_limit")]
public Int64 AltUpLimit { get; set; }
[JsonProperty("alternative_webui_enabled")]
[JsonPropertyName("alternative_webui_enabled")]
public Boolean AlternativeWebuiEnabled { get; set; }
[JsonProperty("alternative_webui_path")]
[JsonPropertyName("alternative_webui_path")]
public String AlternativeWebuiPath { get; set; }
[JsonProperty("announce_ip")]
[JsonPropertyName("announce_ip")]
public String AnnounceIp { get; set; }
[JsonProperty("announce_to_all_tiers")]
[JsonPropertyName("announce_to_all_tiers")]
public Boolean AnnounceToAllTiers { get; set; }
[JsonProperty("announce_to_all_trackers")]
[JsonPropertyName("announce_to_all_trackers")]
public Boolean AnnounceToAllTrackers { get; set; }
[JsonProperty("anonymous_mode")]
[JsonPropertyName("anonymous_mode")]
public Boolean AnonymousMode { get; set; }
[JsonProperty("async_io_threads")]
[JsonPropertyName("async_io_threads")]
public Int64 AsyncIoThreads { get; set; }
[JsonProperty("auto_delete_mode")]
[JsonPropertyName("auto_delete_mode")]
public Int64 AutoDeleteMode { get; set; }
[JsonProperty("auto_tmm_enabled")]
[JsonPropertyName("auto_tmm_enabled")]
public Boolean AutoTmmEnabled { get; set; }
[JsonProperty("autorun_enabled")]
[JsonPropertyName("autorun_enabled")]
public Boolean AutorunEnabled { get; set; }
[JsonProperty("autorun_program")]
[JsonPropertyName("autorun_program")]
public String AutorunProgram { get; set; }
[JsonProperty("banned_IPs")]
[JsonPropertyName("banned_IPs")]
public String BannedIPs { get; set; }
[JsonProperty("bittorrent_protocol")]
[JsonPropertyName("bittorrent_protocol")]
public Int64 BittorrentProtocol { get; set; }
[JsonProperty("bypass_auth_subnet_whitelist")]
[JsonPropertyName("bypass_auth_subnet_whitelist")]
public String BypassAuthSubnetWhitelist { get; set; }
[JsonProperty("bypass_auth_subnet_whitelist_enabled")]
[JsonPropertyName("bypass_auth_subnet_whitelist_enabled")]
public Boolean BypassAuthSubnetWhitelistEnabled { get; set; }
[JsonProperty("bypass_local_auth")]
[JsonPropertyName("bypass_local_auth")]
public Boolean BypassLocalAuth { get; set; }
[JsonProperty("category_changed_tmm_enabled")]
[JsonPropertyName("category_changed_tmm_enabled")]
public Boolean CategoryChangedTmmEnabled { get; set; }
[JsonProperty("checking_memory_use")]
[JsonPropertyName("checking_memory_use")]
public Int64 CheckingMemoryUse { get; set; }
[JsonProperty("create_subfolder_enabled")]
[JsonPropertyName("create_subfolder_enabled")]
public Boolean CreateSubfolderEnabled { get; set; }
[JsonProperty("current_interface_address")]
[JsonPropertyName("current_interface_address")]
public String CurrentInterfaceAddress { get; set; }
[JsonProperty("current_network_interface")]
[JsonPropertyName("current_network_interface")]
public String CurrentNetworkInterface { get; set; }
[JsonProperty("dht")]
[JsonPropertyName("dht")]
public Boolean Dht { get; set; }
[JsonProperty("disk_cache")]
[JsonPropertyName("disk_cache")]
public Int64 DiskCache { get; set; }
[JsonProperty("disk_cache_ttl")]
[JsonPropertyName("disk_cache_ttl")]
public Int64 DiskCacheTtl { get; set; }
[JsonProperty("dl_limit")]
[JsonPropertyName("dl_limit")]
public Int64 DlLimit { get; set; }
[JsonProperty("dont_count_slow_torrents")]
[JsonPropertyName("dont_count_slow_torrents")]
public Boolean DontCountSlowTorrents { get; set; }
[JsonProperty("dyndns_domain")]
[JsonPropertyName("dyndns_domain")]
public String DyndnsDomain { get; set; }
[JsonProperty("dyndns_enabled")]
[JsonPropertyName("dyndns_enabled")]
public Boolean DyndnsEnabled { get; set; }
[JsonProperty("dyndns_password")]
[JsonPropertyName("dyndns_password")]
public String DyndnsPassword { get; set; }
[JsonProperty("dyndns_service")]
[JsonPropertyName("dyndns_service")]
public Int64 DyndnsService { get; set; }
[JsonProperty("dyndns_username")]
[JsonPropertyName("dyndns_username")]
public String DyndnsUsername { get; set; }
[JsonProperty("embedded_tracker_port")]
[JsonPropertyName("embedded_tracker_port")]
public Int64 EmbeddedTrackerPort { get; set; }
[JsonProperty("enable_coalesce_read_write")]
[JsonPropertyName("enable_coalesce_read_write")]
public Boolean EnableCoalesceReadWrite { get; set; }
[JsonProperty("enable_embedded_tracker")]
[JsonPropertyName("enable_embedded_tracker")]
public Boolean EnableEmbeddedTracker { get; set; }
[JsonProperty("enable_multi_connections_from_same_ip")]
[JsonPropertyName("enable_multi_connections_from_same_ip")]
public Boolean EnableMultiConnectionsFromSameIp { get; set; }
[JsonProperty("enable_os_cache")]
[JsonPropertyName("enable_os_cache")]
public Boolean EnableOsCache { get; set; }
[JsonProperty("enable_piece_extent_affinity")]
[JsonPropertyName("enable_piece_extent_affinity")]
public Boolean EnablePieceExtentAffinity { get; set; }
[JsonProperty("enable_super_seeding")]
[JsonPropertyName("enable_super_seeding")]
public Boolean EnableSuperSeeding { get; set; }
[JsonProperty("enable_upload_suggestions")]
[JsonPropertyName("enable_upload_suggestions")]
public Boolean EnableUploadSuggestions { get; set; }
[JsonProperty("encryption")]
[JsonPropertyName("encryption")]
public Int64 Encryption { get; set; }
[JsonProperty("export_dir")]
[JsonPropertyName("export_dir")]
public String ExportDir { get; set; }
[JsonProperty("export_dir_fin")]
[JsonPropertyName("export_dir_fin")]
public String ExportDirFin { get; set; }
[JsonProperty("file_pool_size")]
[JsonPropertyName("file_pool_size")]
public Int64 FilePoolSize { get; set; }
[JsonProperty("incomplete_files_ext")]
[JsonPropertyName("incomplete_files_ext")]
public Boolean IncompleteFilesExt { get; set; }
[JsonProperty("ip_filter_enabled")]
[JsonPropertyName("ip_filter_enabled")]
public Boolean IpFilterEnabled { get; set; }
[JsonProperty("ip_filter_path")]
[JsonPropertyName("ip_filter_path")]
public String IpFilterPath { get; set; }
[JsonProperty("ip_filter_trackers")]
[JsonPropertyName("ip_filter_trackers")]
public Boolean IpFilterTrackers { get; set; }
[JsonProperty("limit_lan_peers")]
[JsonPropertyName("limit_lan_peers")]
public Boolean LimitLanPeers { get; set; }
[JsonProperty("limit_tcp_overhead")]
[JsonPropertyName("limit_tcp_overhead")]
public Boolean LimitTcpOverhead { get; set; }
[JsonProperty("limit_utp_rate")]
[JsonPropertyName("limit_utp_rate")]
public Boolean LimitUtpRate { get; set; }
[JsonProperty("listen_port")]
[JsonPropertyName("listen_port")]
public Int64 ListenPort { get; set; }
[JsonProperty("locale")]
[JsonPropertyName("locale")]
public String Locale { get; set; }
[JsonProperty("lsd")]
[JsonPropertyName("lsd")]
public Boolean Lsd { get; set; }
[JsonProperty("mail_notification_auth_enabled")]
[JsonPropertyName("mail_notification_auth_enabled")]
public Boolean MailNotificationAuthEnabled { get; set; }
[JsonProperty("mail_notification_email")]
[JsonPropertyName("mail_notification_email")]
public String MailNotificationEmail { get; set; }
[JsonProperty("mail_notification_enabled")]
[JsonPropertyName("mail_notification_enabled")]
public Boolean MailNotificationEnabled { get; set; }
[JsonProperty("mail_notification_password")]
[JsonPropertyName("mail_notification_password")]
public String MailNotificationPassword { get; set; }
[JsonProperty("mail_notification_sender")]
[JsonPropertyName("mail_notification_sender")]
public String MailNotificationSender { get; set; }
[JsonProperty("mail_notification_smtp")]
[JsonPropertyName("mail_notification_smtp")]
public String MailNotificationSmtp { get; set; }
[JsonProperty("mail_notification_ssl_enabled")]
[JsonPropertyName("mail_notification_ssl_enabled")]
public Boolean MailNotificationSslEnabled { get; set; }
[JsonProperty("mail_notification_username")]
[JsonPropertyName("mail_notification_username")]
public String MailNotificationUsername { get; set; }
[JsonProperty("max_active_downloads")]
[JsonPropertyName("max_active_downloads")]
public Int64 MaxActiveDownloads { get; set; }
[JsonProperty("max_active_torrents")]
[JsonPropertyName("max_active_torrents")]
public Int64 MaxActiveTorrents { get; set; }
[JsonProperty("max_active_uploads")]
[JsonPropertyName("max_active_uploads")]
public Int64 MaxActiveUploads { get; set; }
[JsonProperty("max_connec")]
[JsonPropertyName("max_connec")]
public Int64 MaxConnec { get; set; }
[JsonProperty("max_connec_per_torrent")]
[JsonPropertyName("max_connec_per_torrent")]
public Int64 MaxConnecPerTorrent { get; set; }
[JsonProperty("max_ratio")]
[JsonPropertyName("max_ratio")]
public Int64 MaxRatio { get; set; }
[JsonProperty("max_ratio_act")]
[JsonPropertyName("max_ratio_act")]
public Int64 MaxRatioAct { get; set; }
[JsonProperty("max_ratio_enabled")]
[JsonPropertyName("max_ratio_enabled")]
public Boolean MaxRatioEnabled { get; set; }
[JsonProperty("max_seeding_time")]
[JsonPropertyName("max_seeding_time")]
public Int64 MaxSeedingTime { get; set; }
[JsonProperty("max_seeding_time_enabled")]
[JsonPropertyName("max_seeding_time_enabled")]
public Boolean MaxSeedingTimeEnabled { get; set; }
[JsonProperty("max_uploads")]
[JsonPropertyName("max_uploads")]
public Int64 MaxUploads { get; set; }
[JsonProperty("max_uploads_per_torrent")]
[JsonPropertyName("max_uploads_per_torrent")]
public Int64 MaxUploadsPerTorrent { get; set; }
[JsonProperty("outgoing_ports_max")]
[JsonPropertyName("outgoing_ports_max")]
public Int64 OutgoingPortsMax { get; set; }
[JsonProperty("outgoing_ports_min")]
[JsonPropertyName("outgoing_ports_min")]
public Int64 OutgoingPortsMin { get; set; }
[JsonProperty("pex")]
[JsonPropertyName("pex")]
public Boolean Pex { get; set; }
[JsonProperty("preallocate_all")]
[JsonPropertyName("preallocate_all")]
public Boolean PreallocateAll { get; set; }
[JsonProperty("proxy_auth_enabled")]
[JsonPropertyName("proxy_auth_enabled")]
public Boolean ProxyAuthEnabled { get; set; }
[JsonProperty("proxy_ip")]
[JsonPropertyName("proxy_ip")]
public String ProxyIp { get; set; }
[JsonProperty("proxy_password")]
[JsonPropertyName("proxy_password")]
public String ProxyPassword { get; set; }
[JsonProperty("proxy_peer_connections")]
[JsonPropertyName("proxy_peer_connections")]
public Boolean ProxyPeerConnections { get; set; }
[JsonProperty("proxy_port")]
[JsonPropertyName("proxy_port")]
public Int64 ProxyPort { get; set; }
[JsonProperty("proxy_torrents_only")]
[JsonPropertyName("proxy_torrents_only")]
public Boolean ProxyTorrentsOnly { get; set; }
[JsonProperty("proxy_type")]
[JsonPropertyName("proxy_type")]
public Int64 ProxyType { get; set; }
[JsonProperty("proxy_username")]
[JsonPropertyName("proxy_username")]
public String ProxyUsername { get; set; }
[JsonProperty("queueing_enabled")]
[JsonPropertyName("queueing_enabled")]
public Boolean QueueingEnabled { get; set; }
[JsonProperty("random_port")]
[JsonPropertyName("random_port")]
public Boolean RandomPort { get; set; }
[JsonProperty("recheck_completed_torrents")]
[JsonPropertyName("recheck_completed_torrents")]
public Boolean RecheckCompletedTorrents { get; set; }
[JsonProperty("resolve_peer_countries")]
[JsonPropertyName("resolve_peer_countries")]
public Boolean ResolvePeerCountries { get; set; }
[JsonProperty("rss_auto_downloading_enabled")]
[JsonPropertyName("rss_auto_downloading_enabled")]
public Boolean RssAutoDownloadingEnabled { get; set; }
[JsonProperty("rss_max_articles_per_feed")]
[JsonPropertyName("rss_max_articles_per_feed")]
public Int64 RssMaxArticlesPerFeed { get; set; }
[JsonProperty("rss_processing_enabled")]
[JsonPropertyName("rss_processing_enabled")]
public Boolean RssProcessingEnabled { get; set; }
[JsonProperty("rss_refresh_interval")]
[JsonPropertyName("rss_refresh_interval")]
public Int64 RssRefreshInterval { get; set; }
[JsonProperty("save_path")]
[JsonPropertyName("save_path")]
public String SavePath { get; set; }
[JsonProperty("save_path_changed_tmm_enabled")]
[JsonPropertyName("save_path_changed_tmm_enabled")]
public Boolean SavePathChangedTmmEnabled { get; set; }
[JsonProperty("save_resume_data_interval")]
[JsonPropertyName("save_resume_data_interval")]
public Int64 SaveResumeDataInterval { get; set; }
[JsonProperty("scan_dirs")]
[JsonPropertyName("scan_dirs")]
public ScanDirs ScanDirs { get; set; }
[JsonProperty("schedule_from_hour")]
[JsonPropertyName("schedule_from_hour")]
public Int64 ScheduleFromHour { get; set; }
[JsonProperty("schedule_from_min")]
[JsonPropertyName("schedule_from_min")]
public Int64 ScheduleFromMin { get; set; }
[JsonProperty("schedule_to_hour")]
[JsonPropertyName("schedule_to_hour")]
public Int64 ScheduleToHour { get; set; }
[JsonProperty("schedule_to_min")]
[JsonPropertyName("schedule_to_min")]
public Int64 ScheduleToMin { get; set; }
[JsonProperty("scheduler_days")]
[JsonPropertyName("scheduler_days")]
public Int64 SchedulerDays { get; set; }
[JsonProperty("scheduler_enabled")]
[JsonPropertyName("scheduler_enabled")]
public Boolean SchedulerEnabled { get; set; }
[JsonProperty("send_buffer_low_watermark")]
[JsonPropertyName("send_buffer_low_watermark")]
public Int64 SendBufferLowWatermark { get; set; }
[JsonProperty("send_buffer_watermark")]
[JsonPropertyName("send_buffer_watermark")]
public Int64 SendBufferWatermark { get; set; }
[JsonProperty("send_buffer_watermark_factor")]
[JsonPropertyName("send_buffer_watermark_factor")]
public Int64 SendBufferWatermarkFactor { get; set; }
[JsonProperty("slow_torrent_dl_rate_threshold")]
[JsonPropertyName("slow_torrent_dl_rate_threshold")]
public Int64 SlowTorrentDlRateThreshold { get; set; }
[JsonProperty("slow_torrent_inactive_timer")]
[JsonPropertyName("slow_torrent_inactive_timer")]
public Int64 SlowTorrentInactiveTimer { get; set; }
[JsonProperty("slow_torrent_ul_rate_threshold")]
[JsonPropertyName("slow_torrent_ul_rate_threshold")]
public Int64 SlowTorrentUlRateThreshold { get; set; }
[JsonProperty("socket_backlog_size")]
[JsonPropertyName("socket_backlog_size")]
public Int64 SocketBacklogSize { get; set; }
[JsonProperty("start_paused_enabled")]
[JsonPropertyName("start_paused_enabled")]
public Boolean StartPausedEnabled { get; set; }
[JsonProperty("stop_tracker_timeout")]
[JsonPropertyName("stop_tracker_timeout")]
public Int64 StopTrackerTimeout { get; set; }
[JsonProperty("temp_path")]
[JsonPropertyName("temp_path")]
public String TempPath { get; set; }
[JsonProperty("temp_path_enabled")]
[JsonPropertyName("temp_path_enabled")]
public Boolean TempPathEnabled { get; set; }
[JsonProperty("torrent_changed_tmm_enabled")]
[JsonPropertyName("torrent_changed_tmm_enabled")]
public Boolean TorrentChangedTmmEnabled { get; set; }
[JsonProperty("up_limit")]
[JsonPropertyName("up_limit")]
public Int64 UpLimit { get; set; }
[JsonProperty("upload_choking_algorithm")]
[JsonPropertyName("upload_choking_algorithm")]
public Int64 UploadChokingAlgorithm { get; set; }
[JsonProperty("upload_slots_behavior")]
[JsonPropertyName("upload_slots_behavior")]
public Int64 UploadSlotsBehavior { get; set; }
[JsonProperty("upnp")]
[JsonPropertyName("upnp")]
public Boolean Upnp { get; set; }
[JsonProperty("upnp_lease_duration")]
[JsonPropertyName("upnp_lease_duration")]
public Int64 UpnpLeaseDuration { get; set; }
[JsonProperty("use_https")]
[JsonPropertyName("use_https")]
public Boolean UseHttps { get; set; }
[JsonProperty("utp_tcp_mixed_mode")]
[JsonPropertyName("utp_tcp_mixed_mode")]
public Int64 UtpTcpMixedMode { get; set; }
[JsonProperty("web_ui_address")]
[JsonPropertyName("web_ui_address")]
public String WebUiAddress { get; set; }
[JsonProperty("web_ui_ban_duration")]
[JsonPropertyName("web_ui_ban_duration")]
public Int64 WebUiBanDuration { get; set; }
[JsonProperty("web_ui_clickjacking_protection_enabled")]
[JsonPropertyName("web_ui_clickjacking_protection_enabled")]
public Boolean WebUiClickjackingProtectionEnabled { get; set; }
[JsonProperty("web_ui_csrf_protection_enabled")]
[JsonPropertyName("web_ui_csrf_protection_enabled")]
public Boolean WebUiCsrfProtectionEnabled { get; set; }
[JsonProperty("web_ui_domain_list")]
[JsonPropertyName("web_ui_domain_list")]
public String WebUiDomainList { get; set; }
[JsonProperty("web_ui_host_header_validation_enabled")]
[JsonPropertyName("web_ui_host_header_validation_enabled")]
public Boolean WebUiHostHeaderValidationEnabled { get; set; }
[JsonProperty("web_ui_https_cert_path")]
[JsonPropertyName("web_ui_https_cert_path")]
public String WebUiHttpsCertPath { get; set; }
[JsonProperty("web_ui_https_key_path")]
[JsonPropertyName("web_ui_https_key_path")]
public String WebUiHttpsKeyPath { get; set; }
[JsonProperty("web_ui_max_auth_fail_count")]
[JsonPropertyName("web_ui_max_auth_fail_count")]
public Int64 WebUiMaxAuthFailCount { get; set; }
[JsonProperty("web_ui_port")]
[JsonPropertyName("web_ui_port")]
public Int64 WebUiPort { get; set; }
[JsonProperty("web_ui_secure_cookie_enabled")]
[JsonPropertyName("web_ui_secure_cookie_enabled")]
public Boolean WebUiSecureCookieEnabled { get; set; }
[JsonProperty("web_ui_session_timeout")]
[JsonPropertyName("web_ui_session_timeout")]
public Int64 WebUiSessionTimeout { get; set; }
[JsonProperty("web_ui_upnp")]
[JsonPropertyName("web_ui_upnp")]
public Boolean WebUiUpnp { get; set; }
[JsonProperty("web_ui_username")]
[JsonPropertyName("web_ui_username")]
public String WebUiUsername { get; set; }
}

View file

@ -1,14 +1,14 @@
using System;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace RdtClient.Data.Models.QBittorrent
{
public class TorrentCategory
{
[JsonProperty("name")]
[JsonPropertyName("name")]
public String Name { get; set; }
[JsonProperty("savePath")]
[JsonPropertyName("savePath")]
public String SavePath { get; set; }
}
}

View file

@ -1,11 +1,11 @@
using System;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace RdtClient.Data.Models.QBittorrent
{
public class TorrentFileItem
{
[JsonProperty("name")]
[JsonPropertyName("name")]
public String Name { get; set; }
}
}

View file

@ -1,5 +1,5 @@
using System;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace RdtClient.Data.Models.QBittorrent
{
@ -7,136 +7,136 @@ namespace RdtClient.Data.Models.QBittorrent
{
public class TorrentInfo
{
[JsonProperty("added_on")]
[JsonPropertyName("added_on")]
public Int64 AddedOn { get; set; }
[JsonProperty("amount_left")]
[JsonPropertyName("amount_left")]
public Int64 AmountLeft { get; set; }
[JsonProperty("auto_tmm")]
[JsonPropertyName("auto_tmm")]
public Boolean AutoTmm { get; set; }
[JsonProperty("availability")]
[JsonPropertyName("availability")]
public Decimal Availability { get; set; }
[JsonProperty("category")]
[JsonPropertyName("category")]
public String Category { get; set; }
[JsonProperty("completed")]
[JsonPropertyName("completed")]
public Int64 Completed { get; set; }
[JsonProperty("completion_on")]
[JsonPropertyName("completion_on")]
public Int64? CompletionOn { get; set; }
[JsonProperty(PropertyName = "content_path")]
[JsonPropertyName("content_path")]
public String ContentPath { get; set; }
[JsonProperty("dl_limit")]
[JsonPropertyName("dl_limit")]
public Int64 DlLimit { get; set; }
[JsonProperty("dlspeed")]
[JsonPropertyName("dlspeed")]
public Int64 Dlspeed { get; set; }
[JsonProperty("downloaded")]
[JsonPropertyName("downloaded")]
public Int64 Downloaded { get; set; }
[JsonProperty("downloaded_session")]
[JsonPropertyName("downloaded_session")]
public Int64 DownloadedSession { get; set; }
[JsonProperty("eta")]
[JsonPropertyName("eta")]
public Int64 Eta { get; set; }
[JsonProperty("f_l_piece_prio")]
[JsonPropertyName("f_l_piece_prio")]
public Boolean FlPiecePrio { get; set; }
[JsonProperty("force_start")]
[JsonPropertyName("force_start")]
public Boolean ForceStart { get; set; }
[JsonProperty("hash")]
[JsonPropertyName("hash")]
public String Hash { get; set; }
[JsonProperty("last_activity")]
[JsonPropertyName("last_activity")]
public Int64 LastActivity { get; set; }
[JsonProperty("magnet_uri")]
[JsonPropertyName("magnet_uri")]
public String MagnetUri { get; set; }
[JsonProperty("max_ratio")]
[JsonPropertyName("max_ratio")]
public Int64 MaxRatio { get; set; }
[JsonProperty("max_seeding_time")]
[JsonPropertyName("max_seeding_time")]
public Int64 MaxSeedingTime { get; set; }
[JsonProperty("name")]
[JsonPropertyName("name")]
public String Name { get; set; }
[JsonProperty("num_complete")]
[JsonPropertyName("num_complete")]
public Int64 NumComplete { get; set; }
[JsonProperty("num_incomplete")]
[JsonPropertyName("num_incomplete")]
public Int64 NumIncomplete { get; set; }
[JsonProperty("num_leechs")]
[JsonPropertyName("num_leechs")]
public Int64 NumLeechs { get; set; }
[JsonProperty("num_seeds")]
[JsonPropertyName("num_seeds")]
public Int64 NumSeeds { get; set; }
[JsonProperty("priority")]
[JsonPropertyName("priority")]
public Int64 Priority { get; set; }
[JsonProperty("progress")]
[JsonPropertyName("progress")]
public Single Progress { get; set; }
[JsonProperty("ratio")]
[JsonPropertyName("ratio")]
public Int64 Ratio { get; set; }
[JsonProperty("ratio_limit")]
[JsonPropertyName("ratio_limit")]
public Int64 RatioLimit { get; set; }
[JsonProperty("save_path")]
[JsonPropertyName("save_path")]
public String SavePath { get; set; }
[JsonProperty("seeding_time_limit")]
[JsonPropertyName("seeding_time_limit")]
public Int64 SeedingTimeLimit { get; set; }
[JsonProperty("seen_complete")]
[JsonPropertyName("seen_complete")]
public Int64 SeenComplete { get; set; }
[JsonProperty("seq_dl")]
[JsonPropertyName("seq_dl")]
public Boolean SeqDl { get; set; }
[JsonProperty("size")]
[JsonPropertyName("size")]
public Int64 Size { get; set; }
[JsonProperty("state")]
[JsonPropertyName("state")]
public String State { get; set; }
[JsonProperty("super_seeding")]
[JsonPropertyName("super_seeding")]
public Boolean SuperSeeding { get; set; }
[JsonProperty("tags")]
[JsonPropertyName("tags")]
public String Tags { get; set; }
[JsonProperty("time_active")]
[JsonPropertyName("time_active")]
public Int64 TimeActive { get; set; }
[JsonProperty("total_size")]
[JsonPropertyName("total_size")]
public Int64 TotalSize { get; set; }
[JsonProperty("tracker")]
[JsonPropertyName("tracker")]
public String Tracker { get; set; }
[JsonProperty("up_limit")]
[JsonPropertyName("up_limit")]
public Int64 UpLimit { get; set; }
[JsonProperty("uploaded")]
[JsonPropertyName("uploaded")]
public Int64 Uploaded { get; set; }
[JsonProperty("uploaded_session")]
[JsonPropertyName("uploaded_session")]
public Int64 UploadedSession { get; set; }
[JsonProperty("upspeed")]
[JsonPropertyName("upspeed")]
public Int64 Upspeed { get; set; }
}
}

View file

@ -1,107 +1,107 @@
using System;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace RdtClient.Data.Models.QBittorrent
{
public class TorrentProperties
{
[JsonProperty("addition_date")]
[JsonPropertyName("addition_date")]
public Int64 AdditionDate { get; set; }
[JsonProperty("comment")]
[JsonPropertyName("comment")]
public String Comment { get; set; }
[JsonProperty("completion_date")]
[JsonPropertyName("completion_date")]
public Int64 CompletionDate { get; set; }
[JsonProperty("created_by")]
[JsonPropertyName("created_by")]
public String CreatedBy { get; set; }
[JsonProperty("creation_date")]
[JsonPropertyName("creation_date")]
public Int64 CreationDate { get; set; }
[JsonProperty("dl_limit")]
[JsonPropertyName("dl_limit")]
public Int64 DlLimit { get; set; }
[JsonProperty("dl_speed")]
[JsonPropertyName("dl_speed")]
public Int64 DlSpeed { get; set; }
[JsonProperty("dl_speed_avg")]
[JsonPropertyName("dl_speed_avg")]
public Int64 DlSpeedAvg { get; set; }
[JsonProperty("eta")]
[JsonPropertyName("eta")]
public Int64 Eta { get; set; }
[JsonProperty("last_seen")]
[JsonPropertyName("last_seen")]
public Int64 LastSeen { get; set; }
[JsonProperty("nb_connections")]
[JsonPropertyName("nb_connections")]
public Int64 NbConnections { get; set; }
[JsonProperty("nb_connections_limit")]
[JsonPropertyName("nb_connections_limit")]
public Int64 NbConnectionsLimit { get; set; }
[JsonProperty("peers")]
[JsonPropertyName("peers")]
public Int64 Peers { get; set; }
[JsonProperty("peers_total")]
[JsonPropertyName("peers_total")]
public Int64 PeersTotal { get; set; }
[JsonProperty("piece_size")]
[JsonPropertyName("piece_size")]
public Int64 PieceSize { get; set; }
[JsonProperty("pieces_have")]
[JsonPropertyName("pieces_have")]
public Int64 PiecesHave { get; set; }
[JsonProperty("pieces_num")]
[JsonPropertyName("pieces_num")]
public Int64 PiecesNum { get; set; }
[JsonProperty("reannounce")]
[JsonPropertyName("reannounce")]
public Int64 Reannounce { get; set; }
[JsonProperty("save_path")]
[JsonPropertyName("save_path")]
public String SavePath { get; set; }
[JsonProperty("seeding_time")]
[JsonPropertyName("seeding_time")]
public Int64 SeedingTime { get; set; }
[JsonProperty("seeds")]
[JsonPropertyName("seeds")]
public Int64 Seeds { get; set; }
[JsonProperty("seeds_total")]
[JsonPropertyName("seeds_total")]
public Int64 SeedsTotal { get; set; }
[JsonProperty("share_ratio")]
[JsonPropertyName("share_ratio")]
public Int64 ShareRatio { get; set; }
[JsonProperty("time_elapsed")]
[JsonPropertyName("time_elapsed")]
public Int64 TimeElapsed { get; set; }
[JsonProperty("total_downloaded")]
[JsonPropertyName("total_downloaded")]
public Int64 TotalDownloaded { get; set; }
[JsonProperty("total_downloaded_session")]
[JsonPropertyName("total_downloaded_session")]
public Int64 TotalDownloadedSession { get; set; }
[JsonProperty("total_size")]
[JsonPropertyName("total_size")]
public Int64 TotalSize { get; set; }
[JsonProperty("total_uploaded")]
[JsonPropertyName("total_uploaded")]
public Int64 TotalUploaded { get; set; }
[JsonProperty("total_uploaded_session")]
[JsonPropertyName("total_uploaded_session")]
public Int64 TotalUploadedSession { get; set; }
[JsonProperty("total_wasted")]
[JsonPropertyName("total_wasted")]
public Int64 TotalWasted { get; set; }
[JsonProperty("up_limit")]
[JsonPropertyName("up_limit")]
public Int64 UpLimit { get; set; }
[JsonProperty("up_speed")]
[JsonPropertyName("up_speed")]
public Int64 UpSpeed { get; set; }
[JsonProperty("up_speed_avg")]
[JsonPropertyName("up_speed_avg")]
public Int64 UpSpeedAvg { get; set; }
}
}

View file

@ -1,19 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="5.0.11" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="5.0.11" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.11" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="5.0.11" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.11">
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.0" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Serilog" Version="2.10.0" />
</ItemGroup>

View file

@ -1,22 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<OutputType>library</OutputType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AllDebrid.NET" Version="1.0.2" />
<PackageReference Include="Aria2.NET" Version="1.0.4" />
<PackageReference Include="Downloader" Version="2.2.9" />
<PackageReference Include="Downloader" Version="2.3.0" />
<PackageReference Include="MonoTorrent" Version="2.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="RD.NET" Version="2.1.0" />
<PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="Serilog.Exceptions" Version="7.1.0" />
<PackageReference Include="Serilog.Exceptions" Version="8.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="SharpCompress" Version="0.30.0" />
<PackageReference Include="StreamJsonRpc" Version="2.8.28" />
</ItemGroup>
<ItemGroup>

View file

@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Serilog;
@ -30,7 +31,7 @@ namespace RdtClient.Service.Services.Downloaders
public SimpleDownloader(String uri, String filePath)
{
_logger = Log.ForContext<Aria2cDownloader>();
_logger = Log.ForContext<SimpleDownloader>();
_uri = uri;
_filePath = filePath;
@ -64,27 +65,17 @@ namespace RdtClient.Service.Services.Downloaders
_bytesLastUpdate = 0;
_nextUpdate = DateTime.UtcNow.AddSeconds(1);
// Determine the file size
var webRequest = WebRequest.Create(_uri);
webRequest.Method = "HEAD";
webRequest.Timeout = 5000;
Int64 responseLength;
using (var webResponse = await webRequest.GetResponseAsync())
{
responseLength = Int64.Parse(webResponse.Headers.Get("Content-Length"));
}
BytesTotal = await GetContentSize();
var timeout = DateTimeOffset.UtcNow.AddHours(1);
var httpClient = new HttpClient();
while (timeout > DateTimeOffset.UtcNow && !_cancelled)
{
try
{
var request = WebRequest.Create(_uri);
using var response = await request.GetResponseAsync();
await using var responseStream = response.GetResponseStream();
var responseStream = await httpClient.GetStreamAsync(_uri);
if (responseStream == null)
{
@ -112,7 +103,6 @@ namespace RdtClient.Service.Services.Downloaders
await fileStream.WriteAsync(buffer.AsMemory(0, readSize), innerCts.Token);
BytesDone = fileStream.Length;
BytesTotal = responseLength;
if (DateTime.UtcNow > _nextUpdate)
{
@ -165,6 +155,23 @@ namespace RdtClient.Service.Services.Downloaders
}
}
private async Task<Int64> GetContentSize()
{
var httpClient = new HttpClient
{
Timeout = TimeSpan.FromSeconds(5)
};
var responseHeaders = await httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, _uri));
if (!responseHeaders.IsSuccessStatusCode)
{
return -1;
}
return responseHeaders.Content.Headers.ContentLength ?? -1;
}
public Task Pause()
{
return Task.CompletedTask;

View file

@ -246,6 +246,13 @@ namespace RdtClient.Service.Services
speed = (Int32) torrent.Downloads.Average(m => m.Speed);
}
var progress = (bytesDone / (Single)bytesTotal);
if (!Single.IsNormal(progress))
{
progress = 0;
}
var result = new TorrentInfo
{
AddedOn = torrent.Added.ToUnixTimeSeconds(),
@ -274,7 +281,7 @@ namespace RdtClient.Service.Services
NumLeechs = 100,
NumSeeds = 100,
Priority = ++prio,
Progress = bytesDone / (Single) bytesTotal,
Progress = progress,
Ratio = 1,
RatioLimit = 1,
SavePath = downloadPath,

View file

@ -4,11 +4,11 @@ using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;
using System.Web;
using Aria2NET;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using RdtClient.Data.Enums;
using RdtClient.Data.Models.Data;
using RdtClient.Data.Models.Internal;
@ -47,14 +47,14 @@ namespace RdtClient.Service.Services
{
Log("Initializing TorrentRunner");
var settingsCopy = JsonConvert.DeserializeObject<DbSettings>(JsonConvert.SerializeObject(Settings.Get));
var settingsCopy = JsonSerializer.Deserialize<DbSettings>(JsonSerializer.Serialize(Settings.Get));
if (settingsCopy != null)
{
settingsCopy.RealDebridApiKey = "*****";
settingsCopy.Aria2cSecret = "*****";
Log(JsonConvert.SerializeObject(settingsCopy));
Log(JsonSerializer.Serialize(settingsCopy));
}
// When starting up reset any pending downloads or unpackings so that they are restarted.

View file

@ -2,11 +2,12 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using MonoTorrent;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
using RdtClient.Data.Data;
using RdtClient.Data.Models.Internal;
using RdtClient.Data.Models.TorrentClient;
@ -581,19 +582,19 @@ namespace RdtClient.Service.Services
private async Task UpdateTorrentClientData(Torrent torrent, TorrentClientTorrent torrentClientTorrent = null)
{
var originalTorrent = JsonConvert.SerializeObject(torrent,
new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});
var originalTorrent = JsonSerializer.Serialize(torrent,
new JsonSerializerOptions
{
ReferenceHandler = ReferenceHandler.IgnoreCycles
});
await _torrentClient.UpdateData(torrent, torrentClientTorrent);
var newTorrent = JsonConvert.SerializeObject(torrent,
new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});
var newTorrent = JsonSerializer.Serialize(torrent,
new JsonSerializerOptions
{
ReferenceHandler = ReferenceHandler.IgnoreCycles
});
if (originalTorrent != newTorrent)
{

View file

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<OutputType>Exe</OutputType>
<UserSecretsId>94c24cba-f03f-4453-a671-3640b517c573</UserSecretsId>
<Version>1.9.8</Version>
@ -26,18 +26,15 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.11" />
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="5.0.11" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.11" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="5.0.11" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.11">
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="5.0.11" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="NReco.Logging.File" Version="1.1.2" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="6.0.0" />
<PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="Serilog.AspNetCore" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />

View file

@ -35,8 +35,7 @@ namespace RdtClient.Web
var connectionString = $"Data Source={appSettings.Database.Path}";
services.AddDbContext<DataContext>(options => options.UseSqlite(connectionString));
services.AddControllers()
.AddNewtonsoftJson();
services.AddControllers();
services.AddSpaStaticFiles(configuration => { configuration.RootPath = "wwwroot"; });