Upgrade packages

Moved C# code to file scoped namespaces
Merged Startup.cs and Program.cs
This commit is contained in:
Roger Far 2022-04-30 11:22:15 -06:00
parent 2cff8ec0a6
commit cd6002b5d6
69 changed files with 7484 additions and 7591 deletions

1644
client/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -10,33 +10,33 @@
},
"private": true,
"dependencies": {
"@angular/animations": "~13.2.6",
"@angular/cdk": "^13.2.6",
"@angular/common": "~13.2.6",
"@angular/compiler": "~13.2.6",
"@angular/core": "~13.2.6",
"@angular/animations": "~13.3.5",
"@angular/cdk": "^13.3.5",
"@angular/common": "~13.3.5",
"@angular/compiler": "~13.3.5",
"@angular/core": "~13.3.5",
"@angular/flex-layout": "^13.0.0-beta.38",
"@angular/forms": "~13.2.6",
"@angular/platform-browser": "~13.2.6",
"@angular/platform-browser-dynamic": "~13.2.6",
"@angular/router": "~13.2.6",
"@fortawesome/fontawesome-free": "^6.0.0",
"@microsoft/signalr": "^6.0.3",
"@angular/forms": "~13.3.5",
"@angular/platform-browser": "~13.3.5",
"@angular/platform-browser-dynamic": "~13.3.5",
"@angular/router": "~13.3.5",
"@fortawesome/fontawesome-free": "^6.1.1",
"@microsoft/signalr": "^6.0.4",
"bulma": "^0.9.3",
"curray": "^1.0.8",
"file-saver": "^2.0.5",
"ngx-filesize": "^2.0.16",
"rxjs": "~7.5.5",
"tslib": "^2.3.1",
"tslib": "^2.4.0",
"zone.js": "~0.11.5"
},
"devDependencies": {
"@angular-devkit/build-angular": "~13.2.6",
"@angular/cli": "~13.2.6",
"@angular/compiler-cli": "~13.2.6",
"@angular/language-service": "~13.2.6",
"@angular-devkit/build-angular": "~13.3.4",
"@angular/cli": "~13.3.4",
"@angular/compiler-cli": "~13.3.5",
"@angular/language-service": "~13.3.5",
"@types/file-saver": "^2.0.5",
"@types/node": "^17.0.21",
"@types/node": "^17.0.30",
"typescript": "~4.5.5"
}
}

View file

@ -1,12 +1,9 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using RdtClient.Data.Models.Data;
namespace RdtClient.Data.Data
{
namespace RdtClient.Data.Data;
public class DataContext : IdentityDbContext
{
public DataContext(DbContextOptions options) : base(options)
@ -223,4 +220,3 @@ namespace RdtClient.Data.Data
}
}
}
}

View file

@ -1,12 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Download = RdtClient.Data.Models.Data.Download;
namespace RdtClient.Data.Data
{
namespace RdtClient.Data.Data;
public class DownloadData
{
private readonly DataContext _dataContext;
@ -264,4 +260,3 @@ namespace RdtClient.Data.Data
await TorrentData.VoidCache();
}
}
}

View file

@ -1,15 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using RdtClient.Data.Models.Data;
using RdtClient.Data.Models.Internal;
using Serilog;
namespace RdtClient.Data.Data
{
namespace RdtClient.Data.Data;
public class SettingData
{
private static readonly SemaphoreSlim _settingCacheLock = new(1);
@ -135,4 +130,3 @@ namespace RdtClient.Data.Data
}
}
}
}

View file

@ -1,13 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using RdtClient.Data.Models.Data;
namespace RdtClient.Data.Data
{
namespace RdtClient.Data.Data;
public class TorrentData
{
private static IList<Torrent> _torrentCache;
@ -313,4 +308,3 @@ namespace RdtClient.Data.Data
}
}
}
}

View file

@ -1,9 +1,8 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
namespace RdtClient.Data.Data
{
namespace RdtClient.Data.Data;
public class UserData
{
private readonly DataContext _dataContext;
@ -18,4 +17,3 @@ namespace RdtClient.Data.Data
return await _dataContext.Users.FirstOrDefaultAsync();
}
}
}

View file

@ -1,16 +1,20 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using RdtClient.Data.Data;
using RdtClient.Data.Models.Internal;
namespace RdtClient.Data;
namespace RdtClient.Data
{
public static class DiConfig
{
public static void Config(IServiceCollection services)
public static void Config(IServiceCollection services, AppSettings appSettings)
{
var connectionString = $"Data Source={appSettings.Database.Path}";
services.AddDbContext<DataContext>(options => options.UseSqlite(connectionString));
services.AddScoped<DownloadData>();
services.AddScoped<SettingData>();
services.AddScoped<TorrentData>();
services.AddScoped<UserData>();
}
}
}

View file

@ -1,9 +1,8 @@
namespace RdtClient.Data.Enums
{
namespace RdtClient.Data.Enums;
public enum TorrentDownloadAction
{
DownloadAll = 0,
DownloadAvailableFiles = 1,
DownloadManual = 2
}
}

View file

@ -1,9 +1,8 @@
namespace RdtClient.Data.Enums
{
namespace RdtClient.Data.Enums;
public enum TorrentFinishedAction
{
None = 0,
RemoveAllTorrents = 1,
RemoveRealDebrid = 2
}
}

View file

@ -1,5 +1,5 @@
namespace RdtClient.Data.Enums
{
namespace RdtClient.Data.Enums;
public enum TorrentStatus
{
Processing = 0,
@ -10,4 +10,3 @@
Error = 99
}
}

View file

@ -1,9 +1,8 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace RdtClient.Data.Models.Data
{
namespace RdtClient.Data.Models.Data;
public class Download
{
[Key]
@ -41,4 +40,3 @@ namespace RdtClient.Data.Models.Data
[NotMapped]
public Int64 Speed { get; set; }
}
}

View file

@ -1,8 +1,7 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations;
namespace RdtClient.Data.Models.Data;
namespace RdtClient.Data.Models.Data
{
public class Setting
{
[Key]
@ -12,4 +11,3 @@ namespace RdtClient.Data.Models.Data
public String Type { get; set; }
}
}

View file

@ -1,13 +1,11 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json;
using RdtClient.Data.Enums;
using RdtClient.Data.Models.TorrentClient;
namespace RdtClient.Data.Models.Data
{
namespace RdtClient.Data.Models.Data;
public class Torrent
{
[Key]
@ -91,4 +89,3 @@ namespace RdtClient.Data.Models.Data
}
}
}
}

View file

@ -1,14 +1,11 @@
using System;
namespace RdtClient.Data.Models.Internal;
namespace RdtClient.Data.Models.Internal
{
public class AppSettings
{
public AppSettingsLogging Logging { get; set; }
public AppSettingsDatabase Database { get; set; }
public String AllowedHosts { get; set; }
public String HostUrl { get; set; }
public Int32 Port { get; set; }
}
public class AppSettingsLogging
@ -19,7 +16,6 @@ namespace RdtClient.Data.Models.Internal
public class AppSettingsLoggingFile
{
public String Path { get; set; }
public String Append { get; set; }
public Int64 FileSizeLimitBytes { get; set; }
public Int32 MaxRollingFiles { get; set; }
}
@ -28,4 +24,3 @@ namespace RdtClient.Data.Models.Internal
{
public String Path { get; set; }
}
}

View file

@ -1,7 +1,5 @@
using System;
namespace RdtClient.Data.Models.Internal;
namespace RdtClient.Data.Models.Internal
{
public class DbSettings
{
public String Provider { get; set; }
@ -31,4 +29,3 @@ namespace RdtClient.Data.Models.Internal
public String RunOnTorrentCompleteFileName { get; set; }
public String RunOnTorrentCompleteArguments { get; set; }
}
}

View file

@ -1,7 +1,5 @@
using System;
namespace RdtClient.Data.Models.Internal;
namespace RdtClient.Data.Models.Internal
{
public class Profile
{
public String Provider { get; set; }
@ -10,4 +8,3 @@ namespace RdtClient.Data.Models.Internal
public String CurrentVersion { get; set; }
public String LatestVersion { get; set; }
}
}

View file

@ -1,8 +1,7 @@
using System;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization;
namespace RdtClient.Data.Models.QBittorrent;
namespace RdtClient.Data.Models.QBittorrent
{
public class AppBuildInfo
{
[JsonPropertyName("bitness")]
@ -23,4 +22,3 @@ namespace RdtClient.Data.Models.QBittorrent
[JsonPropertyName("zlib")]
public String Zlib { get; set; }
}
}

View file

@ -1,10 +1,7 @@
using System;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization;
namespace RdtClient.Data.Models.QBittorrent;
namespace RdtClient.Data.Models.QBittorrent
{
namespace QuickType
{
public class AppPreferences
{
[JsonPropertyName("add_trackers")]
@ -431,5 +428,3 @@ namespace RdtClient.Data.Models.QBittorrent
public class ScanDirs
{
}
}
}

View file

@ -1,10 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using RdtClient.Data.Models.QBittorrent.QuickType;
using System.Text.Json.Serialization;
namespace RdtClient.Data.Models.QBittorrent;
namespace RdtClient.Data.Models.QBittorrent
{
public class SyncMetaData
{
[JsonPropertyName("categories")]
@ -103,4 +100,3 @@ namespace RdtClient.Data.Models.QBittorrent
[JsonPropertyName("write_cache_overload")]
public String WriteCacheOverload { get; set; }
}
}

View file

@ -1,8 +1,7 @@
using System;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization;
namespace RdtClient.Data.Models.QBittorrent;
namespace RdtClient.Data.Models.QBittorrent
{
public class TorrentCategory
{
[JsonPropertyName("name")]
@ -11,4 +10,3 @@ namespace RdtClient.Data.Models.QBittorrent
[JsonPropertyName("savePath")]
public String SavePath { get; set; }
}
}

View file

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

View file

@ -1,10 +1,7 @@
using System;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization;
namespace RdtClient.Data.Models.QBittorrent;
namespace RdtClient.Data.Models.QBittorrent
{
namespace QuickType
{
public class TorrentInfo
{
[JsonPropertyName("added_on")]
@ -139,5 +136,3 @@ namespace RdtClient.Data.Models.QBittorrent
[JsonPropertyName("upspeed")]
public Int64 Upspeed { get; set; }
}
}
}

View file

@ -1,8 +1,7 @@
using System;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization;
namespace RdtClient.Data.Models.QBittorrent;
namespace RdtClient.Data.Models.QBittorrent
{
public class TorrentProperties
{
[JsonPropertyName("addition_date")]
@ -104,4 +103,3 @@ namespace RdtClient.Data.Models.QBittorrent
[JsonPropertyName("up_speed_avg")]
public Int64 UpSpeedAvg { get; set; }
}
}

View file

@ -1,11 +1,8 @@
using System;
namespace RdtClient.Data.Models.TorrentClient;
namespace RdtClient.Data.Models.TorrentClient
{
public class TorrentClientAvailableFile
{
public String Filename { get; set; }
public Int64 Filesize { get; set; }
}
}

View file

@ -1,7 +1,5 @@
using System;
namespace RdtClient.Data.Models.TorrentClient;
namespace RdtClient.Data.Models.TorrentClient
{
public class TorrentClientFile
{
public Int64 Id { get; set; }
@ -9,4 +7,3 @@ namespace RdtClient.Data.Models.TorrentClient
public Int64 Bytes { get; set; }
public Boolean Selected { get; set; }
}
}

View file

@ -1,8 +1,5 @@
using System;
using System.Collections.Generic;
namespace RdtClient.Data.Models.TorrentClient;
namespace RdtClient.Data.Models.TorrentClient
{
public class TorrentClientTorrent
{
public String Id { get; set; }
@ -23,4 +20,3 @@ namespace RdtClient.Data.Models.TorrentClient
public Int64? Speed { get; set; }
public Int64? Seeders { get; set; }
}
}

View file

@ -1,10 +1,7 @@
using System;
namespace RdtClient.Data.Models.TorrentClient;
namespace RdtClient.Data.Models.TorrentClient
{
public class TorrentClientUser
{
public String Username { get; set; }
public DateTimeOffset? Expiration { get; set; }
}
}

View file

@ -2,18 +2,21 @@
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>disable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.3" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="6.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="6.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.3">
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.4" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="6.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="6.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="Serilog" Version="2.11.0" />
</ItemGroup>
</Project>

View file

@ -2,8 +2,8 @@
using RdtClient.Service.Services;
using RdtClient.Service.Services.TorrentClients;
namespace RdtClient.Service
{
namespace RdtClient.Service;
public static class DiConfig
{
public static void Config(IServiceCollection services)
@ -19,6 +19,7 @@ namespace RdtClient.Service
services.AddScoped<TorrentRunner>();
services.AddHostedService<Startup>();
}
services.AddHostedService<TaskRunner>();
services.AddHostedService<UpdateChecker>();
}
}

View file

@ -1,11 +1,8 @@
using System;
using System.IO;
using System.Linq;
using System.Web;
using System.Web;
using RdtClient.Data.Models.Data;
namespace RdtClient.Service.Helpers
{
namespace RdtClient.Service.Helpers;
public static class DownloadHelper
{
public static String GetDownloadPath(String downloadPath, Torrent torrent, Download download)
@ -34,4 +31,3 @@ namespace RdtClient.Service.Helpers
return filePath;
}
}
}

View file

@ -1,9 +1,5 @@
using System;
using System.IO;
using System.Threading.Tasks;
namespace RdtClient.Service.Helpers;
namespace RdtClient.Service.Helpers
{
public static class FileHelper
{
public static async Task Delete(String path)
@ -42,4 +38,3 @@ namespace RdtClient.Service.Helpers
}
}
}
}

View file

@ -1,9 +1,7 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ModelBinding;
namespace RdtClient.Service.Helpers;
namespace RdtClient.Service.Helpers
{
public class JsonModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
@ -30,4 +28,3 @@ namespace RdtClient.Service.Helpers
return Task.CompletedTask;
}
}
}

View file

@ -1,10 +1,8 @@
using System;
using System.Linq;
using System.Web;
using System.Web;
using RdtClient.Data.Models.Data;
namespace RdtClient.Service.Helpers
{
namespace RdtClient.Service.Helpers;
public static class Logger
{
public static String ToLog(this Download download)
@ -28,4 +26,3 @@ namespace RdtClient.Service.Helpers
return $"for torrent {torrent.RdName} ({torrent.RdId} - {torrent.RdStatusRaw} {torrent.RdProgress}%) ({torrent.TorrentId})";
}
}
}

View file

@ -1,10 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using RdtClient.Data.Models.Data;
using RdtClient.Data.Models.Data;
namespace RdtClient.Service.Helpers;
namespace RdtClient.Service.Helpers
{
public static class SettingsHelper
{
public static String GetString(this IList<Setting> settings, String key)
@ -31,4 +28,3 @@ namespace RdtClient.Service.Helpers
return Int32.Parse(setting.Value);
}
}
}

View file

@ -1,10 +1,8 @@
using System;
using System.Net;
using System.Threading.Tasks;
using System.Net;
using Microsoft.AspNetCore.Http;
namespace RdtClient.Service.Middleware
{
namespace RdtClient.Service.Middleware;
public class AuthorizeMiddleware
{
private readonly RequestDelegate _next;
@ -29,4 +27,3 @@ namespace RdtClient.Service.Middleware
}
}
}
}

View file

@ -1,11 +1,10 @@
using System;
using System.Net;
using System.Net;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Http;
namespace RdtClient.Service.Middleware
{
namespace RdtClient.Service.Middleware;
public static class ExceptionMiddlewareExtensions
{
public static void ConfigureExceptionHandler(this IApplicationBuilder app)
@ -26,4 +25,3 @@ namespace RdtClient.Service.Middleware
});
}
}
}

View file

@ -1,20 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<OutputType>library</OutputType>
<Nullable>disable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="AllDebrid.NET" Version="1.0.7" />
<PackageReference Include="Aria2.NET" Version="1.0.4" />
<PackageReference Include="Downloader" Version="2.3.3" />
<PackageReference Include="MonoTorrent" Version="2.0.4" />
<PackageReference Include="MonoTorrent" Version="2.0.5" />
<PackageReference Include="RD.NET" Version="2.1.2" />
<PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="Serilog" Version="2.11.0" />
<PackageReference Include="Serilog.Exceptions" Version="8.1.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="SharpCompress" Version="0.30.1" />
<PackageReference Include="SharpCompress" Version="0.31.0" />
</ItemGroup>
<ItemGroup>

View file

@ -1,10 +1,8 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity;
using RdtClient.Data.Data;
namespace RdtClient.Service.Services
{
namespace RdtClient.Service.Services;
public class Authentication
{
private readonly SignInManager<IdentityUser> _signInManager;
@ -76,4 +74,3 @@ namespace RdtClient.Service.Services
return IdentityResult.Success;
}
}
}

View file

@ -1,12 +1,10 @@
using System;
using System.Threading.Tasks;
using RdtClient.Data.Models.Data;
using RdtClient.Data.Models.Data;
using RdtClient.Data.Models.Internal;
using RdtClient.Service.Helpers;
using RdtClient.Service.Services.Downloaders;
namespace RdtClient.Service.Services
{
namespace RdtClient.Service.Services;
public class DownloadClient
{
private readonly String _destinationPath;
@ -123,4 +121,3 @@ namespace RdtClient.Service.Services
await Downloader.Resume();
}
}
}

View file

@ -1,15 +1,9 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Aria2NET;
using Aria2NET;
using RdtClient.Data.Models.Internal;
using Serilog;
namespace RdtClient.Service.Services.Downloaders
{
namespace RdtClient.Service.Services.Downloaders;
public class Aria2cDownloader : IDownloader
{
public event EventHandler<DownloadCompleteEventArgs> DownloadComplete;
@ -168,7 +162,7 @@ namespace RdtClient.Service.Services.Downloaders
if (download == null)
{
DownloadComplete?.Invoke(this, new DownloadCompleteEventArgs
DownloadComplete.Invoke(this, new DownloadCompleteEventArgs
{
Error = $"Download was not found in Aria2"
});
@ -178,7 +172,7 @@ namespace RdtClient.Service.Services.Downloaders
if (!String.IsNullOrWhiteSpace(download.ErrorMessage) || download.Status == "error")
{
await Remove();
DownloadComplete?.Invoke(this, new DownloadCompleteEventArgs
DownloadComplete.Invoke(this, new DownloadCompleteEventArgs
{
Error = $"{download.ErrorCode}: {download.ErrorMessage}"
});
@ -196,7 +190,7 @@ namespace RdtClient.Service.Services.Downloaders
{
if (retryCount >= 10)
{
DownloadComplete?.Invoke(this, new DownloadCompleteEventArgs
DownloadComplete.Invoke(this, new DownloadCompleteEventArgs
{
Error = $"File not found at {_filePath}"
});
@ -205,7 +199,7 @@ namespace RdtClient.Service.Services.Downloaders
if (File.Exists(_filePath))
{
DownloadComplete?.Invoke(this, new DownloadCompleteEventArgs());
DownloadComplete.Invoke(this, new DownloadCompleteEventArgs());
break;
}
@ -215,7 +209,7 @@ namespace RdtClient.Service.Services.Downloaders
return;
}
DownloadProgress?.Invoke(this, new DownloadProgressEventArgs
DownloadProgress.Invoke(this, new DownloadProgressEventArgs
{
BytesDone = download.CompletedLength,
BytesTotal = download.TotalLength,
@ -269,4 +263,3 @@ namespace RdtClient.Service.Services.Downloaders
return false;
}
}
}

View file

@ -1,8 +1,5 @@
using System;
using System.Threading.Tasks;
namespace RdtClient.Service.Services.Downloaders;
namespace RdtClient.Service.Services.Downloaders
{
public class DownloadCompleteEventArgs
{
public String Error { get; set; }
@ -24,4 +21,3 @@ namespace RdtClient.Service.Services.Downloaders
Task Pause();
Task Resume();
}
}

View file

@ -1,13 +1,10 @@
using System;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using System.Net;
using Downloader;
using RdtClient.Data.Models.Internal;
using Serilog;
namespace RdtClient.Service.Services.Downloaders
{
namespace RdtClient.Service.Services.Downloaders;
public class MultiDownloader : IDownloader
{
public event EventHandler<DownloadCompleteEventArgs> DownloadComplete;
@ -86,7 +83,7 @@ namespace RdtClient.Service.Services.Downloaders
return;
}
DownloadProgress?.Invoke(this,
DownloadProgress.Invoke(this,
new DownloadProgressEventArgs
{
Speed = (Int64)args.BytesPerSecondSpeed,
@ -144,4 +141,3 @@ namespace RdtClient.Service.Services.Downloaders
return Task.CompletedTask;
}
}
}

View file

@ -1,13 +1,8 @@
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Net;
using Serilog;
namespace RdtClient.Service.Services.Downloaders
{
namespace RdtClient.Service.Services.Downloaders;
public class SimpleDownloader : IDownloader
{
private const Int32 BufferSize = 8 * 1024;
@ -144,11 +139,11 @@ namespace RdtClient.Service.Services.Downloaders
throw new Exception($"Download timed out");
}
DownloadComplete?.Invoke(this, new DownloadCompleteEventArgs());
DownloadComplete.Invoke(this, new DownloadCompleteEventArgs());
}
catch (Exception ex)
{
DownloadComplete?.Invoke(this, new DownloadCompleteEventArgs
DownloadComplete.Invoke(this, new DownloadCompleteEventArgs
{
Error = ex.Message
});
@ -182,4 +177,3 @@ namespace RdtClient.Service.Services.Downloaders
return Task.CompletedTask;
}
}
}

View file

@ -1,11 +1,8 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using RdtClient.Data.Data;
using RdtClient.Data.Data;
using Download = RdtClient.Data.Models.Data.Download;
namespace RdtClient.Service.Services
{
namespace RdtClient.Service.Services;
public class Downloads
{
private readonly DownloadData _downloadData;
@ -95,4 +92,3 @@ namespace RdtClient.Service.Services
await _downloadData.Reset(downloadId);
}
}
}

View file

@ -1,15 +1,9 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using RdtClient.Data.Enums;
using RdtClient.Data.Enums;
using RdtClient.Data.Models.Data;
using RdtClient.Data.Models.QBittorrent;
using RdtClient.Data.Models.QBittorrent.QuickType;
namespace RdtClient.Service.Services
{
namespace RdtClient.Service.Services;
public class QBittorrent
{
private readonly Authentication _authentication;
@ -619,4 +613,3 @@ namespace RdtClient.Service.Services
};
}
}
}

View file

@ -1,11 +1,8 @@
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading.Tasks;
using System.Collections.Concurrent;
using Microsoft.AspNetCore.SignalR;
namespace RdtClient.Service.Services
{
namespace RdtClient.Service.Services;
public class RdtHub : Hub
{
private static readonly ConcurrentDictionary<String, String> Users = new();
@ -24,4 +21,3 @@ namespace RdtClient.Service.Services
await base.OnDisconnectedAsync(exception);
}
}
}

View file

@ -1,10 +1,7 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
using Microsoft.AspNetCore.SignalR;
namespace RdtClient.Service.Services;
namespace RdtClient.Service.Services
{
public class RemoteService
{
private readonly IHubContext<RdtHub> _hub;
@ -33,4 +30,3 @@ namespace RdtClient.Service.Services
});
}
}
}

View file

@ -1,19 +1,18 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
using Aria2NET;
using RdtClient.Data.Data;
using RdtClient.Data.Models.Data;
using RdtClient.Data.Models.Internal;
using RdtClient.Service.Helpers;
using Serilog.Core;
using Serilog.Events;
namespace RdtClient.Service.Services;
namespace RdtClient.Service.Services
{
public class Settings
{
public static readonly LoggingLevelSwitch LoggingLevelSwitch = new(LogEventLevel.Debug);
private readonly SettingData _settingData;
public Settings(SettingData settingData)
@ -179,4 +178,3 @@ namespace RdtClient.Service.Services
await _settingData.ResetCache();
}
}
}

View file

@ -1,11 +1,13 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Reflection;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using RdtClient.Data.Data;
using Serilog;
using Serilog.Events;
namespace RdtClient.Service.Services;
namespace RdtClient.Service.Services
{
public class Startup : IHostedService
{
private readonly IServiceProvider _serviceProvider;
@ -19,6 +21,29 @@ namespace RdtClient.Service.Services
{
using var scope = _serviceProvider.CreateScope();
var dbContext = scope.ServiceProvider.GetRequiredService<DataContext>();
await dbContext.Database.MigrateAsync(cancellationToken);
await dbContext.Seed();
var logLevelSettingDb = await dbContext.Settings.FirstOrDefaultAsync(m => m.SettingId == "LogLevel", cancellationToken);
var logLevelSetting = "Warning";
if (logLevelSettingDb != null)
{
logLevelSetting = logLevelSettingDb.Value;
}
if (!Enum.TryParse<LogEventLevel>(logLevelSetting, out var logLevel))
{
logLevel = LogEventLevel.Warning;
}
Settings.LoggingLevelSwitch.MinimumLevel = logLevel;
var version = Assembly.GetEntryAssembly()?.GetName().Version;
Log.Warning($"Starting host on version {version}");
var settings = scope.ServiceProvider.GetRequiredService<Settings>();
await settings.ResetCache();
@ -28,5 +53,3 @@ namespace RdtClient.Service.Services
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}
}

View file

@ -1,12 +1,9 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace RdtClient.Service.Services
{
namespace RdtClient.Service.Services;
public class TaskRunner : BackgroundService
{
private readonly ILogger<TaskRunner> _logger;
@ -46,4 +43,3 @@ namespace RdtClient.Service.Services
_logger.LogInformation("TaskRunner stopped.");
}
}
}

View file

@ -1,10 +1,5 @@
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace RdtClient.Service.Services;
namespace RdtClient.Service.Services
{
/// <summary>
/// Class for streaming data with throttling support.
/// Taken from Downloader: https://github.com/bezzad/Downloader
@ -208,4 +203,3 @@ namespace RdtClient.Service.Services
Interlocked.Exchange(ref _lastTransferredBytesCount, 0);
}
}
}

View file

@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using AllDebridNET;
using AllDebridNET;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using RDNET;
@ -11,10 +6,11 @@ using RDNET.Exceptions;
using RdtClient.Data.Enums;
using RdtClient.Data.Models.TorrentClient;
using RdtClient.Service.Helpers;
using File = AllDebridNET.File;
using Torrent = RdtClient.Data.Models.Data.Torrent;
namespace RdtClient.Service.Services.TorrentClients
{
namespace RdtClient.Service.Services.TorrentClients;
public class AllDebridTorrentClient : ITorrentClient
{
private readonly ILogger<AllDebridTorrentClient> _logger;
@ -331,4 +327,3 @@ namespace RdtClient.Service.Services.TorrentClients
_logger.LogDebug(message);
}
}
}

View file

@ -1,11 +1,8 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using RdtClient.Data.Models.Data;
using RdtClient.Data.Models.Data;
using RdtClient.Data.Models.TorrentClient;
namespace RdtClient.Service.Services.TorrentClients
{
namespace RdtClient.Service.Services.TorrentClients;
public interface ITorrentClient
{
Task<IList<TorrentClientTorrent>> GetTorrents();
@ -20,4 +17,3 @@ namespace RdtClient.Service.Services.TorrentClients
Task<Torrent> UpdateData(Torrent torrent, TorrentClientTorrent torrentClientTorrent);
Task<IList<String>> GetDownloadLinks(Torrent torrent);
}
}

View file

@ -1,17 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using RDNET;
using RdtClient.Data.Enums;
using RdtClient.Data.Models.TorrentClient;
using RdtClient.Service.Helpers;
namespace RdtClient.Service.Services.TorrentClients
{
namespace RdtClient.Service.Services.TorrentClients;
public class RealDebridTorrentClient : ITorrentClient
{
private readonly ILogger<RealDebridTorrentClient> _logger;
@ -352,4 +347,3 @@ namespace RdtClient.Service.Services.TorrentClients
_logger.LogDebug(message);
}
}
}

View file

@ -1,11 +1,6 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Concurrent;
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;
@ -15,8 +10,8 @@ using RdtClient.Data.Models.Internal;
using RdtClient.Service.Helpers;
using RdtClient.Service.Services.Downloaders;
namespace RdtClient.Service.Services
{
namespace RdtClient.Service.Services;
public class TorrentRunner
{
private static DateTime _nextUpdate = DateTime.UtcNow;
@ -624,4 +619,3 @@ namespace RdtClient.Service.Services
_logger.LogDebug(message);
}
}
}

View file

@ -1,13 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using MonoTorrent;
using System.Text.Json.Serialization;
@ -19,8 +13,8 @@ using RdtClient.Service.Helpers;
using RdtClient.Service.Services.TorrentClients;
using Torrent = RdtClient.Data.Models.Data.Torrent;
namespace RdtClient.Service.Services
{
namespace RdtClient.Service.Services;
public class Torrents
{
private static readonly SemaphoreSlim RealDebridUpdateLock = new(1, 1);
@ -766,4 +760,3 @@ namespace RdtClient.Service.Services
_logger.LogDebug(message);
}
}
}

View file

@ -1,16 +1,11 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using RdtClient.Data.Models.Data;
using RdtClient.Data.Models.Data;
using RdtClient.Service.Helpers;
using SharpCompress.Archives;
using SharpCompress.Archives.Rar;
using SharpCompress.Common;
namespace RdtClient.Service.Services
{
namespace RdtClient.Service.Services;
public class UnpackClient
{
public Boolean Finished { get; private set; }
@ -146,4 +141,3 @@ namespace RdtClient.Service.Services
BytesDone = _rarfileStatus.Sum(m => m.Value);
}
}
}

View file

@ -1,17 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Http.Headers;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
namespace RdtClient.Service.Services
{
namespace RdtClient.Service.Services;
public class UpdateChecker : BackgroundService
{
public static String CurrentVersion { get; private set; }
@ -80,4 +74,3 @@ namespace RdtClient.Service.Services
[JsonProperty("name")]
public String Name { get; set; }
}
}

View file

@ -1,12 +1,9 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using RdtClient.Service.Services;
namespace RdtClient.Web.Controllers
{
namespace RdtClient.Web.Controllers;
[Route("Api/Authentication")]
public class AuthController : Controller
{
@ -117,4 +114,3 @@ namespace RdtClient.Web.Controllers
public String UserName { get; set; }
public String Password { get; set; }
}
}

View file

@ -1,18 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using RdtClient.Data.Models.QBittorrent;
using RdtClient.Data.Models.QBittorrent.QuickType;
using RdtClient.Service.Services;
namespace RdtClient.Web.Controllers
{
namespace RdtClient.Web.Controllers;
/// <summary>
/// This API behaves as a regular QBittorrent 4+ API
/// Documentation is found here: https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)
@ -136,20 +129,24 @@ namespace RdtClient.Web.Controllers
[Route("torrents/info")]
[HttpGet]
[HttpPost]
public async Task<ActionResult<IList<TorrentInfo>>> TorrentsInfo([FromQuery] QBTorrentsHashRequest request)
public async Task<ActionResult<IList<TorrentInfo>>> TorrentsInfo([FromQuery] QBTorrentsInfoRequest request)
{
var results = await _qBittorrent.TorrentInfo();
IList<TorrentInfo> filteredResults = new List<TorrentInfo>();
if (request.Category == null) {
filteredResults = results;
} else if (request.Category == "") {
filteredResults = results.Where(m => m.Category == null).ToList();
} else {
filteredResults = results.Where(m => m.Category == request.Category).ToList();
if (!String.IsNullOrWhiteSpace(request.Category))
{
results = results.Where(m => m.Category == request.Category).ToList();
}
return Ok(filteredResults);
return Ok(results);
}
[Authorize]
[Route("torrents/info")]
[HttpPost]
public async Task<ActionResult<IList<TorrentInfo>>> TorrentsFilesPost([FromForm] QBTorrentsInfoRequest request)
{
return await TorrentsInfo(request);
}
[Authorize]
@ -458,6 +455,11 @@ namespace RdtClient.Web.Controllers
public String Password { get; set; }
}
public class QBTorrentsInfoRequest
{
public String Category { get; set; }
}
public class QBTorrentsHashRequest
{
public String Hash { get; set; }
@ -497,4 +499,3 @@ namespace RdtClient.Web.Controllers
{
public String Hashes { get; set; }
}
}

View file

@ -1,16 +1,12 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using RdtClient.Data.Models.Data;
using RdtClient.Data.Models.Internal;
using RdtClient.Service.Services;
using Serilog.Events;
namespace RdtClient.Web.Controllers
{
namespace RdtClient.Web.Controllers;
[Authorize]
[Route("Api/Settings")]
public class SettingsController : Controller
@ -43,7 +39,7 @@ namespace RdtClient.Web.Controllers
logLevel = LogEventLevel.Information;
}
Program.LoggingLevelSwitch.MinimumLevel = logLevel;
Settings.LoggingLevelSwitch.MinimumLevel = logLevel;
return Ok();
}
@ -108,4 +104,3 @@ namespace RdtClient.Web.Controllers
public String Url { get; set; }
public String Secret { get; set; }
}
}

View file

@ -1,18 +1,12 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using MonoTorrent;
using RdtClient.Service.Helpers;
using RdtClient.Service.Services;
using Torrent = RdtClient.Data.Models.Data.Torrent;
namespace RdtClient.Web.Controllers
{
namespace RdtClient.Web.Controllers;
[Authorize]
[Route("Api/Torrents")]
public class TorrentsController : Controller
@ -217,4 +211,3 @@ namespace RdtClient.Web.Controllers
{
public String MagnetLink { get; set; }
}
}

View file

@ -1,92 +1,38 @@
using System;
using System.Diagnostics;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.Net;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Identity;
using RdtClient.Data.Data;
using RdtClient.Data.Models.Internal;
using RdtClient.Service.Middleware;
using RdtClient.Service.Services;
using Serilog;
using Serilog.Core;
using Serilog.Events;
using Serilog.Exceptions;
namespace RdtClient.Web
{
public class Program
{
public static readonly LoggingLevelSwitch LoggingLevelSwitch = new(LogEventLevel.Debug);
var builder = WebApplication.CreateBuilder(args);
public static async Task Main(String[] args)
{
try
{
var host = CreateHostBuilder(args).Build();
// Perform migrations
using (var scope = host.Services.CreateScope())
{
var dbContext = scope.ServiceProvider.GetRequiredService<DataContext>();
await dbContext.Database.MigrateAsync();
await dbContext.Seed();
var logLevelSettingDb = await dbContext.Settings.FirstOrDefaultAsync(m => m.SettingId == "LogLevel");
var logLevelSetting = "Warning";
if (logLevelSettingDb != null)
{
logLevelSetting = logLevelSettingDb.Value;
}
if (!Enum.TryParse<LogEventLevel>(logLevelSetting, out var logLevel))
{
logLevel = LogEventLevel.Warning;
}
LoggingLevelSwitch.MinimumLevel = logLevel;
}
var version = Assembly.GetEntryAssembly()?.GetName().Version;
Log.Warning($"Starting host on version {version}");
await host.RunAsync();
}
catch (Exception ex)
{
Log.Fatal(ex, "Host terminated unexpectedly");
}
finally
{
Log.CloseAndFlush();
}
}
// ReSharper disable once MemberCanBePrivate.Global
public static IHostBuilder CreateHostBuilder(String[] args)
{
var configuration = new ConfigurationBuilder()
#if DEBUG
.AddJsonFile("appsettings.Development.json", true, false)
#else
.AddJsonFile("appsettings.json", true, false)
#endif
.Build();
// Bind the AppSettings from the appsettings.json files.
builder.Configuration.AddJsonFile("appsettings.json", false, false);
builder.Configuration.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", true, false);
// Bind AppSettings
var appSettings = new AppSettings();
configuration.Bind(appSettings);
builder.Configuration.Bind(appSettings);
builder.Services.AddSingleton(appSettings);
if (String.IsNullOrWhiteSpace(appSettings.HostUrl))
// Configure URLs
if (appSettings.Port <= 0)
{
appSettings.HostUrl = "http://0.0.0.0:6500";
appSettings.Port = 6500;
}
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
builder.WebHost.ConfigureKestrel(options =>
{
options.ListenAnyIP(appSettings.Port);
});
builder.Host.UseSerilog((_, lc) => lc.Enrich.FromLogContext()
.Enrich.WithExceptionDetails()
.WriteTo.File(appSettings.Logging.File.Path,
rollOnFileSizeLimit: true,
@ -94,10 +40,9 @@ namespace RdtClient.Web
retainedFileCountLimit: appSettings.Logging.File.MaxRollingFiles,
outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {SourceContext}: {Message:lj}{NewLine}{Exception}")
.WriteTo.Console()
.MinimumLevel.ControlledBy(LoggingLevelSwitch)
.MinimumLevel.ControlledBy(Settings.LoggingLevelSwitch)
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
.MinimumLevel.Override("System.Net.Http", LogEventLevel.Warning)
.CreateLogger();
.MinimumLevel.Override("System.Net.Http", LogEventLevel.Warning));
Serilog.Debugging.SelfLog.Enable(msg =>
{
@ -107,20 +52,129 @@ namespace RdtClient.Web
Debug.WriteLine(msg);
});
return Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureServices((_, services) =>
Log.Information("Starting RealDebridClient host");
builder.Services.AddControllers();
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
services.AddHostedService<TaskRunner>();
services.AddHostedService<UpdateChecker>();
})
.ConfigureWebHostDefaults(webBuilder =>
options.SlidingExpiration = true;
});
builder.Services.AddAuthorization();
builder.Services.AddIdentity<IdentityUser, IdentityRole>(options =>
{
webBuilder.UseUrls(appSettings.HostUrl)
.UseKestrel()
.UseStartup<Startup>();
options.User.RequireUniqueEmail = false;
options.Password.RequiredLength = 10;
options.Password.RequireUppercase = false;
options.Password.RequireLowercase = false;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequiredUniqueChars = 5;
})
.UseSerilog();
.AddEntityFrameworkStores<DataContext>()
.AddDefaultTokenProviders();
builder.Services.ConfigureApplicationCookie(options =>
{
options.Events.OnRedirectToLogin = context =>
{
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
return Task.CompletedTask;
};
options.Cookie.Name = "SID";
});
// Configure development cors.
builder.Services.AddCors(options =>
{
options.AddPolicy("Dev",
corsBuilder => corsBuilder.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
// Configure misc services.
builder.Services.AddResponseCaching();
builder.Services.AddMemoryCache();
builder.Services.AddDistributedMemoryCache();
builder.Services.AddHttpClient();
builder.Services.AddHttpContextAccessor();
builder.Services.AddSession();
builder.Services.AddSpaStaticFiles(spaBuilder =>
{
spaBuilder.RootPath = "wwwroot";
});
builder.Services.AddSignalR(hubOptions =>
{
hubOptions.EnableDetailedErrors = true;
});
builder.Host.UseWindowsService();
RdtClient.Data.DiConfig.Config(builder.Services, appSettings);
RdtClient.Service.DiConfig.Config(builder.Services);
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
try
{
// Build the app
var app = builder.Build();
if (builder.Environment.IsDevelopment())
{
app.UseCors("Dev");
app.UseDeveloperExceptionPage();
}
app.ConfigureExceptionHandler();
app.UseMiddleware<AuthorizeMiddleware>();
app.Use(async (context, next) =>
{
await next.Invoke();
if (context.Response.StatusCode != 200)
{
Log.Warning("{StatusCode}: {Value}", context.Response.StatusCode, context.Request.Path.Value);
}
});
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<RdtHub>("/hub");
endpoints.MapControllers();
});
app.MapWhen(x => !x.Request.Path.StartsWithSegments("/api"), routeBuilder =>
{
routeBuilder.UseSpaStaticFiles();
routeBuilder.UseSpa(spa =>
{
spa.Options.SourcePath = "wwwroot";
spa.Options.DefaultPage = "/index.html";
});
});
// Run the app
app.Run();
}
catch (Exception ex)
{
Log.Fatal(ex, "Host terminated unexpectedly");
}
finally
{
Log.CloseAndFlush();
}

View file

@ -5,6 +5,9 @@
<OutputType>Exe</OutputType>
<UserSecretsId>94c24cba-f03f-4453-a671-3640b517c573</UserSecretsId>
<Version>2.0.12</Version>
<Nullable>disable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
@ -26,16 +29,16 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="6.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="6.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.3">
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="6.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="6.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="6.0.3" />
<PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="6.0.4" />
<PackageReference Include="Serilog" Version="2.11.0" />
<PackageReference Include="Serilog.AspNetCore" Version="5.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
</ItemGroup>

View file

@ -1,137 +0,0 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using RdtClient.Data.Data;
using RdtClient.Data.Models.Internal;
using RdtClient.Service.Middleware;
using RdtClient.Service.Services;
namespace RdtClient.Web
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
private IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
var appSettings = new AppSettings();
Configuration.Bind(appSettings);
services.AddSingleton(appSettings);
var connectionString = $"Data Source={appSettings.Database.Path}";
services.AddDbContext<DataContext>(options => options.UseSqlite(connectionString));
services.AddControllers();
services.AddSpaStaticFiles(configuration => { configuration.RootPath = "wwwroot"; });
services.AddSignalR(options =>
{
options.EnableDetailedErrors = true;
});
services.AddHttpContextAccessor();
services.AddCors(options =>
{
options.AddPolicy("Dev",
builder =>
{
builder.AllowAnyHeader()
.AllowAnyMethod()
.AllowAnyOrigin();
});
});
services.AddHttpClient();
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options => { options.SlidingExpiration = true; });
services.AddAuthorization();
services.AddIdentity<IdentityUser, IdentityRole>(options =>
{
options.User.RequireUniqueEmail = false;
options.Password.RequiredLength = 10;
options.Password.RequireUppercase = false;
options.Password.RequireLowercase = false;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequiredUniqueChars = 5;
})
.AddEntityFrameworkStores<DataContext>()
.AddDefaultTokenProviders();
services.ConfigureApplicationCookie(options =>
{
options.Events.OnRedirectToLogin = context =>
{
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
return Task.CompletedTask;
};
options.Cookie.Name = "SID";
});
Data.DiConfig.Config(services);
Service.DiConfig.Config(services);
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger)
{
if (env.IsDevelopment())
{
app.UseCors("Dev");
}
app.ConfigureExceptionHandler();
app.UseMiddleware<AuthorizeMiddleware>();
app.Use(async (context, next) =>
{
await next.Invoke();
if (context.Response.StatusCode != 200)
{
logger.LogWarning("{StatusCode}: {Value}", context.Response.StatusCode, context.Request.Path.Value);
}
});
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<RdtHub>("/hub");
endpoints.MapControllers();
});
app.MapWhen(x => !x.Request.Path.Value.StartsWith("/api"), builder =>
{
builder.UseSpaStaticFiles();
builder.UseSpa(spa =>
{
spa.Options.SourcePath = "wwwroot";
spa.Options.DefaultPage = "/index.html";
});
});
}
}
}

View file

@ -2,7 +2,6 @@
"Logging": {
"File": {
"Path": "C:/Temp/rdtclient/rdtclient.log",
"Append": "True",
"FileSizeLimitBytes": 5242880,
"MaxRollingFiles": 5
}
@ -10,6 +9,5 @@
"Database": {
"Path": "C:/Temp/rdtclient/rdtclient.db"
},
"AllowedHosts": "*",
"HostUrl": "http://0.0.0.0:6500"
"Port": "6500"
}

View file

@ -2,7 +2,6 @@
"Logging": {
"File": {
"Path": "/data/db/rdtclient.log",
"Append": "True",
"FileSizeLimitBytes": 5242880,
"MaxRollingFiles": 5
}
@ -10,6 +9,5 @@
"Database": {
"Path": "/data/db/rdtclient.db"
},
"AllowedHosts": "*",
"HostUrl": "http://0.0.0.0:6500"
"Port": "6500"
}

View file

@ -1,7 +1,5 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/Browsers/Enable/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=48FF995D_002DAD14_002D4E41_002DBC69_002D7A144C84E3B6/@EntryIndexedValue">ExplicitlyExcluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=92EF8817_002DAD73_002D4301_002D93BD_002D745D7D61DD74_002Fd_003AMigrations/@EntryIndexedValue">ExplicitlyExcluded</s:String>
<s:String x:Key="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=_002A_002Eappxmanifest/@EntryIndexedValue">*.appxmanifest</s:String>
<s:String x:Key="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=_002A_002Ed_002Ets/@EntryIndexedValue">*.d.ts</s:String>
<s:String x:Key="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=_002A_002Edebug_002Ejs/@EntryIndexedValue">*.debug.js</s:String>
@ -29,6 +27,7 @@
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeLocalFunctionBody/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeMethodOrOperatorBody/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeModifiersOrder/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeNamespaceBody/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeRedundantParentheses/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeThisQualifier/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeTypeMemberModifiers/@EntryIndexedValue">ERROR</s:String>
@ -178,6 +177,7 @@
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=HCP/@EntryIndexedValue">HCP</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=QA/@EntryIndexedValue">QA</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=QB/@EntryIndexedValue">QB</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=US/@EntryIndexedValue">US</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=XML/@EntryIndexedValue">XML</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Constants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=LocalConstants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>