mirror of
https://github.com/Cleanuparr/Cleanuparr.git
synced 2026-01-19 19:28:02 -05:00
124 lines
4.1 KiB
C#
124 lines
4.1 KiB
C#
using System.Collections.Concurrent;
|
|
using System.Text.RegularExpressions;
|
|
using Cleanuparr.Domain.Enums;
|
|
using Cleanuparr.Infrastructure.Extensions;
|
|
using Cleanuparr.Infrastructure.Features.Context;
|
|
using Cleanuparr.Persistence.Models.Configuration.ContentBlocker;
|
|
using Microsoft.Extensions.Logging;
|
|
using QBittorrent.Client;
|
|
|
|
namespace Cleanuparr.Infrastructure.Features.DownloadClient.QBittorrent;
|
|
|
|
public partial class QBitService
|
|
{
|
|
/// <inheritdoc/>
|
|
public override async Task<BlockFilesResult> BlockUnwantedFilesAsync(string hash, IReadOnlyList<string> ignoredDownloads)
|
|
{
|
|
TorrentInfo? download = (await _client.GetTorrentListAsync(new TorrentListQuery { Hashes = [hash] }))
|
|
.FirstOrDefault();
|
|
BlockFilesResult result = new();
|
|
|
|
if (download is null)
|
|
{
|
|
_logger.LogDebug("failed to find torrent {hash} in the download client", hash);
|
|
return result;
|
|
}
|
|
|
|
result.Found = true;
|
|
|
|
IReadOnlyList<TorrentTracker> trackers = await GetTrackersAsync(hash);
|
|
|
|
if (ignoredDownloads.Count > 0 &&
|
|
(download.ShouldIgnore(ignoredDownloads) || trackers.Any(x => x.ShouldIgnore(ignoredDownloads)) is true))
|
|
{
|
|
_logger.LogInformation("skip | download is ignored | {name}", download.Name);
|
|
return result;
|
|
}
|
|
|
|
TorrentProperties? torrentProperties = await _client.GetTorrentPropertiesAsync(hash);
|
|
|
|
if (torrentProperties is null)
|
|
{
|
|
_logger.LogDebug("failed to find torrent properties {hash} in the download client", hash);
|
|
return result;
|
|
}
|
|
|
|
bool isPrivate = torrentProperties.AdditionalData.TryGetValue("is_private", out var dictValue) &&
|
|
bool.TryParse(dictValue?.ToString(), out bool boolValue)
|
|
&& boolValue;
|
|
|
|
result.IsPrivate = isPrivate;
|
|
|
|
var contentBlockerConfig = ContextProvider.Get<ContentBlockerConfig>();
|
|
|
|
if (contentBlockerConfig.IgnorePrivate && isPrivate)
|
|
{
|
|
// ignore private trackers
|
|
_logger.LogDebug("skip files check | download is private | {name}", download.Name);
|
|
return result;
|
|
}
|
|
|
|
IReadOnlyList<TorrentContent>? files = await _client.GetTorrentContentsAsync(hash);
|
|
|
|
if (files is null)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
List<int> unwantedFiles = [];
|
|
long totalFiles = 0;
|
|
long totalUnwantedFiles = 0;
|
|
|
|
InstanceType instanceType = (InstanceType)ContextProvider.Get<object>(nameof(InstanceType));
|
|
BlocklistType blocklistType = _blocklistProvider.GetBlocklistType(instanceType);
|
|
ConcurrentBag<string> patterns = _blocklistProvider.GetPatterns(instanceType);
|
|
ConcurrentBag<Regex> regexes = _blocklistProvider.GetRegexes(instanceType);
|
|
|
|
foreach (TorrentContent file in files)
|
|
{
|
|
if (!file.Index.HasValue)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
totalFiles++;
|
|
|
|
if (file.Priority is TorrentContentPriority.Skip)
|
|
{
|
|
totalUnwantedFiles++;
|
|
continue;
|
|
}
|
|
|
|
if (_filenameEvaluator.IsValid(file.Name, blocklistType, patterns, regexes))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
_logger.LogInformation("unwanted file found | {file}", file.Name);
|
|
unwantedFiles.Add(file.Index.Value);
|
|
totalUnwantedFiles++;
|
|
}
|
|
|
|
if (unwantedFiles.Count is 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
if (totalUnwantedFiles == totalFiles)
|
|
{
|
|
result.ShouldRemove = true;
|
|
}
|
|
|
|
foreach (int fileIndex in unwantedFiles)
|
|
{
|
|
await _dryRunInterceptor.InterceptAsync(MarkFileAsSkipped, hash, fileIndex);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
protected virtual async Task MarkFileAsSkipped(string hash, int fileIndex)
|
|
{
|
|
await _client.SetFilePriorityAsync(hash, fileIndex, TorrentContentPriority.Skip);
|
|
}
|
|
} |