mirror of
https://github.com/Cleanuparr/Cleanuparr.git
synced 2026-10-29 19:40:00 -04:00
179 lines
6.6 KiB
C#
179 lines
6.6 KiB
C#
using Cleanuparr.Domain.Entities;
|
|
using Cleanuparr.Infrastructure.Extensions;
|
|
using Cleanuparr.Persistence.Models.Configuration.DownloadCleaner;
|
|
using Cleanuparr.Shared.Helpers;
|
|
using Microsoft.Extensions.Logging;
|
|
using Transmission.API.RPC.Arguments;
|
|
using Transmission.API.RPC.Entity;
|
|
|
|
namespace Cleanuparr.Infrastructure.Features.DownloadClient.Transmission;
|
|
|
|
public partial class TransmissionService
|
|
{
|
|
public override async Task<List<ITorrentItemWrapper>> GetSeedingDownloads()
|
|
{
|
|
var result = await _client.TorrentGetAsync(Fields);
|
|
return result?.Torrents
|
|
?.Where(x => !string.IsNullOrEmpty(x.HashString))
|
|
.Where(x => x.Status is 5 or 6 || x is { IsFinished: true, Status: 0 })
|
|
.Select(ITorrentItemWrapper (x) => new TransmissionItemWrapper(x))
|
|
.ToList() ?? [];
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public override async Task<List<IDownloadItem>> GetAllDownloadsLite()
|
|
{
|
|
TransmissionTorrents? result = await _client.TorrentGetAsync(Fields);
|
|
if (result?.Torrents is null)
|
|
{
|
|
throw new InvalidOperationException("Transmission returned no torrent list");
|
|
}
|
|
|
|
List<IDownloadItem> torrents = result.Torrents
|
|
.Where(x => !string.IsNullOrEmpty(x.HashString))
|
|
.Select(IDownloadItem (x) => new TransmissionItemWrapper(x))
|
|
.ToList();
|
|
|
|
ThrowIfTorrentListCollapsed(result.Torrents.Length, torrents.Count);
|
|
|
|
return torrents;
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public override Task<IReadOnlyList<string>> GetClaimedPathsAsync(IReadOnlyList<IDownloadItem> downloads) =>
|
|
BuildClaimedPathsAsync(downloads, torrent =>
|
|
{
|
|
IReadOnlyCollection<string> files = torrent is TransmissionItemWrapper { Info.Files.Length: > 0 } wrapper
|
|
? wrapper.Info.Files
|
|
.Select(f => f.Name)
|
|
.Where(name => !string.IsNullOrEmpty(name))
|
|
.ToList()
|
|
: [];
|
|
return Task.FromResult(files);
|
|
});
|
|
|
|
/// <inheritdoc/>
|
|
public override List<ITorrentItemWrapper>? FilterDownloadsToChangeCategoryAsync(List<ITorrentItemWrapper>? downloads, UnlinkedConfig unlinkedConfig)
|
|
{
|
|
return downloads
|
|
?.Where(x => !string.IsNullOrEmpty(x.DownloadId))
|
|
.Where(x => unlinkedConfig.Categories.Any(cat => cat.Equals(x.Category, StringComparison.InvariantCultureIgnoreCase)))
|
|
.Where(x =>
|
|
{
|
|
if (unlinkedConfig.UseTag)
|
|
{
|
|
return !x.Tags.Any(tag =>
|
|
tag.Equals(unlinkedConfig.TargetCategory, StringComparison.InvariantCultureIgnoreCase));
|
|
}
|
|
|
|
return true;
|
|
})
|
|
.ToList();
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public override async Task DeleteDownload(IDownloadItem item, bool deleteSourceFiles)
|
|
{
|
|
var transmissionTorrent = (TransmissionItemWrapper)item;
|
|
await _client.TorrentRemoveAsync([transmissionTorrent.Info.Id], deleteSourceFiles);
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public override async Task StopDownload(IDownloadItem item)
|
|
{
|
|
TransmissionItemWrapper transmissionTorrent = (TransmissionItemWrapper)item;
|
|
await _client.TorrentStopAsync([transmissionTorrent.Info.Id]);
|
|
}
|
|
|
|
/// <inheritdoc cref="IErrorRecoveryCapable.ResumeDownload"/>
|
|
public async Task ResumeDownload(IDownloadItem item)
|
|
{
|
|
TransmissionItemWrapper transmissionTorrent = (TransmissionItemWrapper)item;
|
|
await _client.TorrentStartAsync([transmissionTorrent.Info.Id]);
|
|
}
|
|
|
|
public override async Task CreateCategoryAsync(string name)
|
|
{
|
|
await Task.CompletedTask;
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
protected override Task<IEnumerable<(string FilePath, HardLinkScanAction Action)>?> GetHardLinkScanItemsAsync(ITorrentItemWrapper torrent)
|
|
{
|
|
TransmissionItemWrapper transmissionTorrent = (TransmissionItemWrapper)torrent;
|
|
|
|
if (string.IsNullOrEmpty(transmissionTorrent.Info.DownloadDir))
|
|
{
|
|
return Task.FromResult<IEnumerable<(string FilePath, HardLinkScanAction Action)>?>(null);
|
|
}
|
|
|
|
if (transmissionTorrent.Info.Files is null || transmissionTorrent.Info.FileStats is null)
|
|
{
|
|
_logger.LogDebug("skip | download has no files | {name}", transmissionTorrent.Name);
|
|
return Task.FromResult<IEnumerable<(string FilePath, HardLinkScanAction Action)>?>(null);
|
|
}
|
|
|
|
IEnumerable<(string FilePath, HardLinkScanAction Action)> BuildScanItems()
|
|
{
|
|
for (int i = 0; i < transmissionTorrent.Info.Files.Length; i++)
|
|
{
|
|
TransmissionTorrentFiles file = transmissionTorrent.Info.Files[i];
|
|
TransmissionTorrentFileStats stats = transmissionTorrent.Info.FileStats[i];
|
|
|
|
if (stats.Wanted is null or false || string.IsNullOrEmpty(file.Name))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
string filePath = PathHelper.NormalizeAndRemap(
|
|
Path.Combine(transmissionTorrent.Info.DownloadDir, file.Name),
|
|
_downloadClientConfig.DownloadDirectorySource,
|
|
_downloadClientConfig.DownloadDirectoryTarget);
|
|
|
|
yield return (filePath, HardLinkScanAction.CheckHardLinks);
|
|
}
|
|
}
|
|
|
|
return Task.FromResult<IEnumerable<(string FilePath, HardLinkScanAction Action)>?>(BuildScanItems());
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
protected override bool SupportsTags => true;
|
|
|
|
/// <inheritdoc/>
|
|
protected override async Task ChangeCategoryInClientAsync(ITorrentItemWrapper torrent, string targetCategory, bool useTag)
|
|
{
|
|
TransmissionItemWrapper transmissionTorrent = (TransmissionItemWrapper)torrent;
|
|
|
|
if (useTag)
|
|
{
|
|
string[] newLabels = transmissionTorrent.Tags
|
|
.Append(targetCategory)
|
|
.Distinct(StringComparer.OrdinalIgnoreCase)
|
|
.ToArray();
|
|
|
|
await ChangeLabels(transmissionTorrent.Info.Id, newLabels);
|
|
|
|
return;
|
|
}
|
|
|
|
string newLocation = transmissionTorrent.Info.GetNewLocationByAppend(targetCategory);
|
|
|
|
await ChangeDownloadLocation(transmissionTorrent.Info.Id, newLocation);
|
|
}
|
|
|
|
protected virtual async Task ChangeDownloadLocation(long downloadId, string newLocation)
|
|
{
|
|
await _client.TorrentSetLocationAsync([downloadId], newLocation, true);
|
|
}
|
|
|
|
protected virtual async Task ChangeLabels(long downloadId, string[] labels)
|
|
{
|
|
await _client.TorrentSetAsync(new TorrentSettings
|
|
{
|
|
Ids = [downloadId],
|
|
Labels = labels,
|
|
});
|
|
}
|
|
}
|