create .strm downloader
This commit is contained in:
parent
cb29187f72
commit
f66d1fe197
6 changed files with 100 additions and 6 deletions
|
|
@ -18,4 +18,7 @@ public enum DownloadClient
|
||||||
|
|
||||||
[Description("Synology DownloadStation")]
|
[Description("Synology DownloadStation")]
|
||||||
DownloadStation,
|
DownloadStation,
|
||||||
|
|
||||||
|
[Description("Strm Downloader")]
|
||||||
|
Strm
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
using System.IO.Abstractions;
|
||||||
|
using System.IO.Abstractions.TestingHelpers;
|
||||||
|
using Moq;
|
||||||
|
using RdtClient.Service.Services.Downloaders;
|
||||||
|
|
||||||
|
namespace RdtClient.Service.Test.Services.Downloaders;
|
||||||
|
|
||||||
|
public class StrmDownloaderTest
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public async Task Download_WhenFileCreatedSuccesfully_RaisesDownloadCompleteEvent()
|
||||||
|
{
|
||||||
|
var mockFileSystem = new MockFileSystem();
|
||||||
|
var strmDownloader = new StrmDownloader("http://example.com/video.mp4", "video.mp4", mockFileSystem);
|
||||||
|
|
||||||
|
await Assert.RaisesAsync<DownloadCompleteEventArgs>(a => strmDownloader.DownloadComplete += a,
|
||||||
|
a => strmDownloader.DownloadComplete -= a,
|
||||||
|
strmDownloader.Download);
|
||||||
|
|
||||||
|
Assert.True(mockFileSystem.FileExists("video.mp4.strm"));
|
||||||
|
Assert.Equal(await mockFileSystem.File.ReadAllTextAsync("video.mp4.strm"), "http://example.com/video.mp4");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Download_WhenErrorCreatingFile_RaisesDownloadCompleteEventWithError()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var mockFileSystem = new Mock<IFileSystem>();
|
||||||
|
mockFileSystem.Setup(fs => fs.File.WriteAllTextAsync(It.IsAny<String>(), It.IsAny<String>(), It.IsAny<CancellationToken>()))
|
||||||
|
.ThrowsAsync(new IOException("File write error"));
|
||||||
|
|
||||||
|
var strmDownloader = new StrmDownloader("http://example.com/video.mp4", "video.mp4", mockFileSystem.Object);
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
var raisedEvent = await Assert.RaisesAsync<DownloadCompleteEventArgs>(
|
||||||
|
a => strmDownloader.DownloadComplete += a,
|
||||||
|
a => strmDownloader.DownloadComplete -= a,
|
||||||
|
strmDownloader.Download);
|
||||||
|
|
||||||
|
Assert.NotNull(raisedEvent);
|
||||||
|
Assert.False(String.IsNullOrWhiteSpace(raisedEvent.Arguments.Error));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using RdtClient.Data.Enums;
|
using System.IO.Abstractions;
|
||||||
|
using RdtClient.Data.Enums;
|
||||||
using RdtClient.Data.Models.Data;
|
using RdtClient.Data.Models.Data;
|
||||||
using RdtClient.Service.Helpers;
|
using RdtClient.Service.Helpers;
|
||||||
using RdtClient.Service.Services.Downloaders;
|
using RdtClient.Service.Services.Downloaders;
|
||||||
|
|
@ -6,7 +7,7 @@ using RdtClient.Service.Services.TorrentClients;
|
||||||
|
|
||||||
namespace RdtClient.Service.Services;
|
namespace RdtClient.Service.Services;
|
||||||
|
|
||||||
public class DownloadClient(Download download, Torrent torrent, String destinationPath, String? category)
|
public class DownloadClient(Download download, Torrent torrent, String destinationPath, String? category, IFileSystem fileSystem)
|
||||||
{
|
{
|
||||||
private static Int64 _totalBytesDownloadedThisSession;
|
private static Int64 _totalBytesDownloadedThisSession;
|
||||||
private static readonly Lock TotalBytesDownloadedLock = new();
|
private static readonly Lock TotalBytesDownloadedLock = new();
|
||||||
|
|
@ -70,6 +71,7 @@ public class DownloadClient(Download download, Torrent torrent, String destinati
|
||||||
Data.Enums.DownloadClient.Aria2c => new Aria2cDownloader(download.RemoteId, download.Link, filePath, downloadPath, category),
|
Data.Enums.DownloadClient.Aria2c => new Aria2cDownloader(download.RemoteId, download.Link, filePath, downloadPath, category),
|
||||||
Data.Enums.DownloadClient.Symlink => new SymlinkDownloader(download.Link, filePath, downloadPath, torrent.ClientKind),
|
Data.Enums.DownloadClient.Symlink => new SymlinkDownloader(download.Link, filePath, downloadPath, torrent.ClientKind),
|
||||||
Data.Enums.DownloadClient.DownloadStation => await DownloadStationDownloader.Init(download.RemoteId, download.Link, filePath, downloadPath, category),
|
Data.Enums.DownloadClient.DownloadStation => await DownloadStationDownloader.Init(download.RemoteId, download.Link, filePath, downloadPath, category),
|
||||||
|
Data.Enums.DownloadClient.Strm => new StrmDownloader(download.Link, filePath, fileSystem),
|
||||||
_ => throw new($"Unknown download client {Type}")
|
_ => throw new($"Unknown download client {Type}")
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
using System.IO.Abstractions;
|
||||||
|
|
||||||
|
namespace RdtClient.Service.Services.Downloaders;
|
||||||
|
|
||||||
|
public class StrmDownloader(String downloadLink, String filePath, IFileSystem fileSystem) : IDownloader
|
||||||
|
{
|
||||||
|
public event EventHandler<DownloadCompleteEventArgs>? DownloadComplete;
|
||||||
|
public event EventHandler<DownloadProgressEventArgs>? DownloadProgress;
|
||||||
|
|
||||||
|
public async Task<String> Download()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await fileSystem.File.WriteAllTextAsync(filePath + ".strm", downloadLink);
|
||||||
|
|
||||||
|
DownloadComplete?.Invoke(this, new());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
DownloadComplete?.Invoke(this,
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Error = ex.Message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return Guid.NewGuid().ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task Cancel()
|
||||||
|
{
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task Pause()
|
||||||
|
{
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task Resume()
|
||||||
|
{
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,11 +7,12 @@ using RdtClient.Service.Helpers;
|
||||||
using RdtClient.Service.Services.Downloaders;
|
using RdtClient.Service.Services.Downloaders;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.IO.Abstractions;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace RdtClient.Service.Services;
|
namespace RdtClient.Service.Services;
|
||||||
|
|
||||||
public class TorrentRunner(ILogger<TorrentRunner> logger, Torrents torrents, Downloads downloads)
|
public class TorrentRunner(ILogger<TorrentRunner> logger, Torrents torrents, Downloads downloads, IFileSystem fileSystem)
|
||||||
{
|
{
|
||||||
public static readonly ConcurrentDictionary<Guid, DownloadClient> ActiveDownloadClients = new();
|
public static readonly ConcurrentDictionary<Guid, DownloadClient> ActiveDownloadClients = new();
|
||||||
public static readonly ConcurrentDictionary<Guid, UnpackClient> ActiveUnpackClients = new();
|
public static readonly ConcurrentDictionary<Guid, UnpackClient> ActiveUnpackClients = new();
|
||||||
|
|
@ -428,7 +429,7 @@ public class TorrentRunner(ILogger<TorrentRunner> logger, Torrents torrents, Dow
|
||||||
Log($"Setting download path to {downloadPath}", download, torrent);
|
Log($"Setting download path to {downloadPath}", download, torrent);
|
||||||
|
|
||||||
// Start the download process
|
// Start the download process
|
||||||
var downloadClient = new DownloadClient(download, torrent, downloadPath, torrent.Category);
|
var downloadClient = new DownloadClient(download, torrent, downloadPath, torrent.Category, fileSystem);
|
||||||
|
|
||||||
if (ActiveDownloadClients.TryAdd(download.DownloadId, downloadClient))
|
if (ActiveDownloadClients.TryAdd(download.DownloadId, downloadClient))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.IO.Abstractions;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Aria2NET;
|
using Aria2NET;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
|
@ -14,7 +15,7 @@ namespace RdtClient.Web.Controllers;
|
||||||
|
|
||||||
[Authorize(Policy = "AuthSetting")]
|
[Authorize(Policy = "AuthSetting")]
|
||||||
[Route("Api/Settings")]
|
[Route("Api/Settings")]
|
||||||
public class SettingsController(Settings settings, Torrents torrents) : Controller
|
public class SettingsController(Settings settings, Torrents torrents, IFileSystem fileSystem) : Controller
|
||||||
{
|
{
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("")]
|
[Route("")]
|
||||||
|
|
@ -108,7 +109,7 @@ public class SettingsController(Settings settings, Torrents torrents) : Controll
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var downloadClient = new DownloadClient(download, download.Torrent, downloadPath, null);
|
var downloadClient = new DownloadClient(download, download.Torrent, downloadPath, null, fileSystem);
|
||||||
|
|
||||||
await downloadClient.Start();
|
await downloadClient.Start();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue