Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
0987b1f18c
18 changed files with 101 additions and 96 deletions
28
CHANGELOG.md
28
CHANGELOG.md
|
|
@ -4,6 +4,34 @@ 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.86] - 2024-09-03
|
||||
### Changed
|
||||
- Add potential fix for BASE_PATH.
|
||||
- Fixed creation of empty folders.
|
||||
|
||||
## [2.0.85] - 2024-09-03
|
||||
### Changed
|
||||
- Reverted: Prevent the creation of download folders when using symlink.
|
||||
|
||||
## [2.0.84] - 2024-09-02
|
||||
### Changed
|
||||
- Replace docker libssl1.1 with libssl3
|
||||
|
||||
## [2.0.83] - 2024-09-02
|
||||
### Changed
|
||||
- Fixed progress reporting to the qBittorrent API endpoint.
|
||||
- Prevent the creation of download folders when using symlink.
|
||||
|
||||
## [2.0.82] - 2024-09-02
|
||||
### Changed
|
||||
- Update packages and docker alpine version.
|
||||
|
||||
## [2.0.81] - 2024-07-28
|
||||
### Changed
|
||||
- Improved handling of infringed torrents from real debrid.
|
||||
- Force update of torrent data from real-debrid when no filename is found in the local DB.
|
||||
- Fixed real-debrid deserialization issue when checking for instant available files.
|
||||
|
||||
## [2.0.80] - 2024-07-13
|
||||
### Changed
|
||||
- Add rate limiter to retry requests that are rate limited from Real-Debrid.
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ RUN \
|
|||
dotnet restore --no-cache RdtClient.sln && dotnet publish --no-restore -c Release -o out ;
|
||||
|
||||
# Stage 3 - Build runtime image
|
||||
FROM ghcr.io/linuxserver/baseimage-alpine:3.18
|
||||
FROM ghcr.io/linuxserver/baseimage-alpine:3.20
|
||||
ARG TARGETPLATFORM
|
||||
ENV TARGETPLATFORM=${TARGETPLATFORM:-linux/amd64}
|
||||
ARG BUILDPLATFORM
|
||||
|
|
@ -60,7 +60,7 @@ RUN \
|
|||
echo "**** Updating package information ****" && \
|
||||
apk update && \
|
||||
echo "**** Install pre-reqs ****" && \
|
||||
apk add bash icu-libs krb5-libs libgcc libintl libssl1.1 libstdc++ zlib && \
|
||||
apk add bash icu-libs krb5-libs libgcc libintl libssl3 libstdc++ zlib && \
|
||||
echo "**** Installing dotnet ****" && \
|
||||
mkdir -p /usr/share/dotnet
|
||||
|
||||
|
|
|
|||
60
README.md
60
README.md
|
|
@ -20,64 +20,24 @@ This is a web interface to manage your torrents on Real-Debrid, AllDebrid or Pre
|
|||
|
||||
## Docker Setup
|
||||
|
||||
You can run the docker container on Windows, Linux. To get started either use _Docker Run_ or _Docker Compose_.
|
||||
Please see our separate Docker setup Read Me.
|
||||
|
||||
### Docker Run
|
||||
|
||||
```console
|
||||
docker run --pull=always
|
||||
--volume /your/download/path/:/data/downloads \
|
||||
--volume /your/storage/path/:/data/db \
|
||||
--log-driver json-file \
|
||||
--log-opt max-size=10m \
|
||||
-p 6500:6500 \
|
||||
--name rdtclient \
|
||||
rogerfar/rdtclient:latest
|
||||
```
|
||||
|
||||
Replace `/your/download/path/` with your local path to download files to. For Windows i.e. `C:/Downloads`.
|
||||
Replace `/your/storage/path/` with your local path to store persistent database and log files in. For Windows i.e. `C:/Docker/rdt-client`.
|
||||
|
||||
### Docker Compose
|
||||
|
||||
You can use the provided docker compose to run:
|
||||
|
||||
```yaml
|
||||
version: '3.3'
|
||||
services:
|
||||
rdtclient:
|
||||
container_name: rdtclient
|
||||
volumes:
|
||||
- 'D:/Downloads/:/data/downloads'
|
||||
- 'D:/Docker/rdt-client/:/data/db'
|
||||
image: rogerfar/rdtclient
|
||||
restart: always
|
||||
logging:
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: 10m
|
||||
ports:
|
||||
- '6500:6500'
|
||||
```
|
||||
|
||||
And to run:
|
||||
|
||||
```console
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
Replace the paths in `volumes` as in the above step.
|
||||
[Readme for Docker](README-DOCKER.md)
|
||||
|
||||
## Run as a Service
|
||||
|
||||
Instead of running in Docker you can install it as a service in Windows or Linux.
|
||||
|
||||
## Windows Service
|
||||
|
||||
1. Make sure you have the ASP.NET Core Runtime 8 installed: [https://dotnet.microsoft.com/download/dotnet/8.0](https://dotnet.microsoft.com/download/dotnet/8.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.
|
||||
1. When using Windows paths, make sure to escape the slashes. For example: `D:\\RdtClient\\db\\rdtclient.db`
|
||||
2. Get the latest zip file from the Releases page and extract it to your host.
|
||||
3. Open the `appsettings.json` file and replace the `LogLevel` `Path` to a path on your host.
|
||||
4. In `appsettings.json` replace the `Database` `Path` to a path on your host.
|
||||
5. When using Windows paths, make sure to escape the slashes. For example: `D:\\RdtClient\\db\\rdtclient.db`
|
||||
6. Do one of these:
|
||||
* Run `RdtClient.Web.exe` to start the client.
|
||||
* Run `service-install.bat` to install the client as a service. This will install `RdtClient.Web.exe` as a service which make the client start in the backgorund when the computer starts. (You probably want to do this if you are going to use this with Sonarr etc...)
|
||||
|
||||
## Linux Service
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@
|
|||
<a class="navbar-item" routerLink="profile"> Profile </a>
|
||||
<a class="navbar-item" (click)="logout()"> Logout </a>
|
||||
<hr class="navbar-divider" />
|
||||
<a href="https://github.com/rogerfar/rdt-client" target="_blank" class="navbar-item">Version 2.0.80</a>
|
||||
<a href="https://github.com/rogerfar/rdt-client" target="_blank" class="navbar-item">Version 2.0.86</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "rdt-client",
|
||||
"version": "2.0.80",
|
||||
"version": "2.0.86",
|
||||
"description": "This is a web interface to manage your torrents on Real-Debrid.",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -8,15 +8,15 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.7" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="8.0.7" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.7" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="8.0.7" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.7">
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.8">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Serilog" Version="4.0.0" />
|
||||
<PackageReference Include="Serilog" Version="4.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -118,11 +118,6 @@ public static class DownloadHelper
|
|||
}
|
||||
}
|
||||
|
||||
if (!Directory.Exists(torrentPath))
|
||||
{
|
||||
Directory.CreateDirectory(torrentPath);
|
||||
}
|
||||
|
||||
var filePath = Path.Combine(torrentPath, fileName);
|
||||
|
||||
return filePath;
|
||||
|
|
|
|||
|
|
@ -13,15 +13,15 @@
|
|||
<PackageReference Include="Aria2.NET" Version="1.0.5" />
|
||||
<PackageReference Include="Downloader" Version="3.1.2" />
|
||||
<PackageReference Include="Downloader.NET" Version="1.0.12" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="8.0.7" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http.Resilience" Version="8.7.0" />
|
||||
<PackageReference Include="MonoTorrent" Version="2.0.7" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http.Resilience" Version="8.8.0" />
|
||||
<PackageReference Include="MonoTorrent" Version="3.0.2" />
|
||||
<PackageReference Include="Polly" Version="8.4.1" />
|
||||
<PackageReference Include="Premiumize.NET" Version="1.0.4" />
|
||||
<PackageReference Include="RD.NET" Version="2.1.4" />
|
||||
<PackageReference Include="Serilog" Version="4.0.0" />
|
||||
<PackageReference Include="RD.NET" Version="2.1.6" />
|
||||
<PackageReference Include="Serilog" Version="4.0.1" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
|
||||
<PackageReference Include="SharpCompress" Version="0.37.2" />
|
||||
<PackageReference Include="SharpCompress" Version="0.38.0" />
|
||||
<PackageReference Include="TorBox.NET" Version="1.0.0.40" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -39,10 +39,13 @@ public class DownloadClient(Download download, Torrent torrent, String destinati
|
|||
throw new("Invalid download path");
|
||||
}
|
||||
|
||||
await FileHelper.Delete(filePath.Result!);
|
||||
|
||||
Type = torrent.DownloadClient;
|
||||
|
||||
if (Type != Data.Enums.DownloadClient.Symlink)
|
||||
{
|
||||
await FileHelper.Delete(filePath);
|
||||
}
|
||||
|
||||
Downloader = Type switch
|
||||
{
|
||||
Data.Enums.DownloadClient.Internal => new InternalDownloader(download.Link, filePath.Result!),
|
||||
|
|
|
|||
|
|
@ -73,6 +73,8 @@ public class SymlinkDownloader(String uri, String destinationPath, String path)
|
|||
|
||||
potentialFilePaths.Add(fileName);
|
||||
potentialFilePaths.Add(fileNameWithoutExtension);
|
||||
// add an empty path so we can check for the new file in the base directory
|
||||
potentialFilePaths.Add("");
|
||||
|
||||
potentialFilePaths = potentialFilePaths.Distinct().ToList();
|
||||
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ public class QBittorrent(ILogger<QBittorrent> logger, Settings settings, Authent
|
|||
|
||||
var prio = 0;
|
||||
|
||||
Decimal downloadProgress = 0;
|
||||
Double downloadProgress = 0;
|
||||
|
||||
foreach (var torrent in allTorrents)
|
||||
{
|
||||
|
|
@ -214,12 +214,12 @@ public class QBittorrent(ILogger<QBittorrent> logger, Settings settings, Authent
|
|||
Int64 bytesDone = 0;
|
||||
Int64 bytesTotal = 0;
|
||||
Int64 speed = 0;
|
||||
Int64 rdProgress = 0;
|
||||
Double rdProgress = 0;
|
||||
try
|
||||
{
|
||||
rdProgress = (Int64) ((torrent.RdProgress ?? 0) / 100.0m);
|
||||
rdProgress = (torrent.RdProgress ?? 0.0) / 100.0;
|
||||
bytesTotal = torrent.RdSize ?? 1;
|
||||
bytesDone = bytesTotal * rdProgress;
|
||||
bytesDone = (Int64) (bytesTotal * rdProgress);
|
||||
speed = torrent.RdSpeed ?? 0;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
@ -237,10 +237,10 @@ public class QBittorrent(ILogger<QBittorrent> logger, Settings settings, Authent
|
|||
bytesDone = torrent.Downloads.Sum(m => m.BytesDone);
|
||||
bytesTotal = torrent.Downloads.Sum(m => m.BytesTotal);
|
||||
speed = (Int32) torrent.Downloads.Average(m => m.Speed);
|
||||
downloadProgress = bytesTotal > 0 ? (Decimal) bytesDone / bytesTotal : 0;
|
||||
downloadProgress = bytesTotal > 0 ? (Double) bytesDone / bytesTotal : 0;
|
||||
}
|
||||
|
||||
var progress = (Int64) ((rdProgress + downloadProgress) / 2m);
|
||||
var progress = (rdProgress + downloadProgress) / 2.0;
|
||||
|
||||
var result = new TorrentInfo
|
||||
{
|
||||
|
|
|
|||
|
|
@ -287,7 +287,7 @@ public class RealDebridTorrentClient(ILogger<RealDebridTorrentClient> logger, IH
|
|||
return torrent;
|
||||
}
|
||||
|
||||
if (torrentClientTorrent == null || torrentClientTorrent.Ended == null)
|
||||
if (torrentClientTorrent == null || torrentClientTorrent.Ended == null || String.IsNullOrEmpty(torrentClientTorrent.Filename))
|
||||
{
|
||||
torrentClientTorrent = await GetInfo(torrent.RdId) ?? throw new($"Resource not found");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ public class Torrents(
|
|||
|
||||
var id = await TorrentClient.AddMagnet(magnetLink);
|
||||
|
||||
var hash = magnet.InfoHash.ToHex();
|
||||
var hash = magnet.InfoHashes.V1OrV2.ToHex();
|
||||
|
||||
var newTorrent = await Add(id, hash, magnetLink, false, torrent);
|
||||
|
||||
|
|
@ -132,7 +132,7 @@ public class Torrents(
|
|||
Directory.CreateDirectory(Settings.Get.General.CopyAddedTorrents);
|
||||
}
|
||||
|
||||
var copyFileName = Path.Combine(Settings.Get.General.CopyAddedTorrents, $"{FileHelper.RemoveInvalidFileNameChars(magnet.Name)}.magnet");
|
||||
var copyFileName = Path.Combine(Settings.Get.General.CopyAddedTorrents, $"{FileHelper.RemoveInvalidFileNameChars(magnet.Name!)}.magnet");
|
||||
|
||||
if (File.Exists(copyFileName))
|
||||
{
|
||||
|
|
@ -168,7 +168,7 @@ public class Torrents(
|
|||
|
||||
var id = await TorrentClient.AddFile(bytes);
|
||||
|
||||
var hash = monoTorrent.InfoHash.ToHex();
|
||||
var hash = monoTorrent.InfoHashes.V1OrV2.ToHex();
|
||||
|
||||
var newTorrent = await Add(id, hash, fileAsBase64, true, torrent);
|
||||
|
||||
|
|
|
|||
|
|
@ -316,6 +316,7 @@ public class QBittorrentController(ILogger<QBittorrentController> logger, QBitto
|
|||
|
||||
foreach (var url in urls)
|
||||
{
|
||||
try{
|
||||
if (url.StartsWith("magnet"))
|
||||
{
|
||||
await qBittorrent.TorrentsAddMagnet(url.Trim(), request.Category, null);
|
||||
|
|
@ -330,6 +331,15 @@ public class QBittorrentController(ILogger<QBittorrentController> logger, QBitto
|
|||
{
|
||||
return BadRequest($"Invalid torrent link format {url}");
|
||||
}
|
||||
}
|
||||
catch (RDNET.RealDebridException ex)
|
||||
{
|
||||
// Infringing file.
|
||||
if (ex.ErrorCode == 35)
|
||||
{
|
||||
return Ok("Fails.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Ok();
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ public class TorrentsController(ILogger<TorrentsController> logger, Torrents tor
|
|||
|
||||
var torrent = await MonoTorrent.Torrent.LoadAsync(bytes);
|
||||
|
||||
var result = await torrents.GetAvailableFiles(torrent.InfoHash.ToHex());
|
||||
var result = await torrents.GetAvailableFiles(torrent.InfoHashes.V1OrV2.ToHex());
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
|
@ -148,9 +148,14 @@ public class TorrentsController(ILogger<TorrentsController> logger, Torrents tor
|
|||
return BadRequest();
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(request.MagnetLink))
|
||||
{
|
||||
return BadRequest("MagnetLink cannot be null or empty");
|
||||
}
|
||||
|
||||
var magnet = MagnetLink.Parse(request.MagnetLink);
|
||||
|
||||
var result = await torrents.GetAvailableFiles(magnet.InfoHash.ToHex());
|
||||
var result = await torrents.GetAvailableFiles(magnet.InfoHashes.V1OrV2.ToHex());
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
|
@ -226,7 +231,7 @@ public class TorrentsController(ILogger<TorrentsController> logger, Torrents tor
|
|||
{
|
||||
var magnet = MagnetLink.Parse(request.MagnetLink);
|
||||
|
||||
availableFiles = await torrents.GetAvailableFiles(magnet.InfoHash.ToHex());
|
||||
availableFiles = await torrents.GetAvailableFiles(magnet.InfoHashes.V1OrV2.ToHex());
|
||||
}
|
||||
else if (file != null)
|
||||
{
|
||||
|
|
@ -240,7 +245,7 @@ public class TorrentsController(ILogger<TorrentsController> logger, Torrents tor
|
|||
|
||||
var torrent = await MonoTorrent.Torrent.LoadAsync(bytes);
|
||||
|
||||
availableFiles = await torrents.GetAvailableFiles(torrent.InfoHash.ToHex());
|
||||
availableFiles = await torrents.GetAvailableFiles(torrent.InfoHashes.V1OrV2.ToHex());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -168,6 +168,7 @@ try
|
|||
if (basePath != null)
|
||||
{
|
||||
app.UseMiddleware<BaseHrefMiddleware>(basePath);
|
||||
app.UsePathBase($"/{basePath.TrimStart('/').TrimEnd('/')}/");
|
||||
}
|
||||
|
||||
app.UseMiddleware<RequestLoggingMiddleware>();
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@
|
|||
"RdtClient.Web": {
|
||||
"commandName": "Project",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
"ASPNETCORE_ENVIRONMENT": "Development",
|
||||
"BASE_PATH": "test"
|
||||
},
|
||||
"applicationUrl": "http://localhost:6500"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<TargetFramework>net8.0</TargetFramework>
|
||||
<OutputType>Exe</OutputType>
|
||||
<UserSecretsId>94c24cba-f03f-4453-a671-3640b517c573</UserSecretsId>
|
||||
<Version>2.0.80</Version>
|
||||
<Version>2.0.86</Version>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<LangVersion>latest</LangVersion>
|
||||
|
|
@ -29,17 +29,17 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="8.0.7" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.7" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="8.0.7" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.7">
|
||||
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.8">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="8.0.7" />
|
||||
<PackageReference Include="Serilog" Version="4.0.0" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="8.0.8" />
|
||||
<PackageReference Include="Serilog" Version="4.0.1" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="8.0.2" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue