added separate strikes for downloading metadata
This commit is contained in:
@@ -183,15 +183,16 @@ services:
|
||||
- QUEUECLEANER__ENABLED=true
|
||||
- QUEUECLEANER__IGNORED_DOWNLOADS_PATH=/ignored.txt
|
||||
- QUEUECLEANER__RUNSEQUENTIALLY=true
|
||||
- QUEUECLEANER__IMPORT_FAILED_MAX_STRIKES=5
|
||||
- QUEUECLEANER__IMPORT_FAILED_MAX_STRIKES=3
|
||||
- QUEUECLEANER__IMPORT_FAILED_IGNORE_PRIVATE=false
|
||||
- QUEUECLEANER__IMPORT_FAILED_DELETE_PRIVATE=false
|
||||
# - QUEUECLEANER__IMPORT_FAILED_IGNORE_PATTERNS__0=title mismatch
|
||||
# - QUEUECLEANER__IMPORT_FAILED_IGNORE_PATTERNS__1=manual import required
|
||||
- QUEUECLEANER__STALLED_MAX_STRIKES=5
|
||||
- QUEUECLEANER__STALLED_MAX_STRIKES=3
|
||||
- QUEUECLEANER__STALLED_RESET_STRIKES_ON_PROGRESS=false
|
||||
- QUEUECLEANER__STALLED_IGNORE_PRIVATE=false
|
||||
- QUEUECLEANER__STALLED_DELETE_PRIVATE=false
|
||||
- QUEUECLEANER__DOWNLOADING_METADATA_MAX_STRIKES=3
|
||||
|
||||
- CONTENTBLOCKER__ENABLED=true
|
||||
- CONTENTBLOCKER__IGNORED_DOWNLOADS_PATH=/ignored.txt
|
||||
|
||||
@@ -24,7 +24,7 @@ public sealed record QueueCleanerConfig : IJobConfig, IIgnoredDownloadsConfig
|
||||
public bool ImportFailedDeletePrivate { get; init; }
|
||||
|
||||
[ConfigurationKeyName("IMPORT_FAILED_IGNORE_PATTERNS")]
|
||||
public List<string>? ImportFailedIgnorePatterns { get; init; }
|
||||
public IReadOnlyList<string>? ImportFailedIgnorePatterns { get; init; }
|
||||
|
||||
[ConfigurationKeyName("STALLED_MAX_STRIKES")]
|
||||
public ushort StalledMaxStrikes { get; init; }
|
||||
@@ -38,16 +38,24 @@ public sealed record QueueCleanerConfig : IJobConfig, IIgnoredDownloadsConfig
|
||||
[ConfigurationKeyName("STALLED_DELETE_PRIVATE")]
|
||||
public bool StalledDeletePrivate { get; init; }
|
||||
|
||||
[ConfigurationKeyName("DOWNLOADING_METADATA_MAX_STRIKES")]
|
||||
public ushort DownloadingMetadataMaxStrikes { get; init; }
|
||||
|
||||
public void Validate()
|
||||
{
|
||||
if (ImportFailedMaxStrikes is > 0 and < 3)
|
||||
{
|
||||
throw new ValidationException("the minimum value for IMPORT_FAILED_MAX_STRIKES must be 3");
|
||||
throw new ValidationException($"the minimum value for {SectionName.ToUpperInvariant()}__IMPORT_FAILED_MAX_STRIKES must be 3");
|
||||
}
|
||||
|
||||
if (StalledMaxStrikes is > 0 and < 3)
|
||||
{
|
||||
throw new ValidationException("the minimum value for STALLED_MAX_STRIKES must be 3");
|
||||
throw new ValidationException($"the minimum value for {SectionName.ToUpperInvariant()}__STALLED_MAX_STRIKES must be 3");
|
||||
}
|
||||
|
||||
if (DownloadingMetadataMaxStrikes is > 0 and < 3)
|
||||
{
|
||||
throw new ValidationException($"the minimum value for {SectionName.ToUpperInvariant()}__DOWNLOADING_METADATA_MAX_STRIKES must be 3");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Domain.Enums;
|
||||
namespace Domain.Enums;
|
||||
|
||||
public enum DeleteReason
|
||||
{
|
||||
|
||||
@@ -25,16 +25,17 @@
|
||||
"Enabled": true,
|
||||
"RunSequentially": true,
|
||||
"IGNORED_DOWNLOADS_PATH": "../test/data/cleanuperr/ignored_downloads",
|
||||
"IMPORT_FAILED_MAX_STRIKES": 5,
|
||||
"IMPORT_FAILED_MAX_STRIKES": 3,
|
||||
"IMPORT_FAILED_IGNORE_PRIVATE": true,
|
||||
"IMPORT_FAILED_DELETE_PRIVATE": false,
|
||||
"IMPORT_FAILED_IGNORE_PATTERNS": [
|
||||
"file is a sample"
|
||||
],
|
||||
"STALLED_MAX_STRIKES": 5,
|
||||
"STALLED_MAX_STRIKES": 3,
|
||||
"STALLED_RESET_STRIKES_ON_PROGRESS": true,
|
||||
"STALLED_IGNORE_PRIVATE": true,
|
||||
"STALLED_DELETE_PRIVATE": false
|
||||
"STALLED_DELETE_PRIVATE": false,
|
||||
"DOWNLOADING_METADATA_MAX_STRIKES": 3
|
||||
},
|
||||
"DownloadCleaner": {
|
||||
"Enabled": false,
|
||||
|
||||
@@ -31,7 +31,8 @@
|
||||
"STALLED_MAX_STRIKES": 0,
|
||||
"STALLED_RESET_STRIKES_ON_PROGRESS": false,
|
||||
"STALLED_IGNORE_PRIVATE": false,
|
||||
"STALLED_DELETE_PRIVATE": false
|
||||
"STALLED_DELETE_PRIVATE": false,
|
||||
"DOWNLOADING_METADATA_MAX_STRIKES": 0
|
||||
},
|
||||
"DownloadCleaner": {
|
||||
"Enabled": false,
|
||||
|
||||
@@ -335,35 +335,41 @@ public class QBitService : DownloadService, IQBitService
|
||||
|
||||
private async Task<(bool, DeleteReason)> IsItemStuckAndShouldRemove(TorrentInfo torrent, bool isPrivate)
|
||||
{
|
||||
if (_queueCleanerConfig.StalledMaxStrikes is 0)
|
||||
if (_queueCleanerConfig.StalledMaxStrikes is 0 && _queueCleanerConfig.DownloadingMetadataMaxStrikes is 0)
|
||||
{
|
||||
return (false, default);
|
||||
}
|
||||
|
||||
if (_queueCleanerConfig.StalledIgnorePrivate && isPrivate)
|
||||
{
|
||||
// ignore private trackers
|
||||
_logger.LogDebug("skip stalled check | download is private | {name}", torrent.Name);
|
||||
return (false, default);
|
||||
return (false, DeleteReason.None);
|
||||
}
|
||||
|
||||
if (torrent.State is not TorrentState.StalledDownload and not TorrentState.FetchingMetadata
|
||||
and not TorrentState.ForcedFetchingMetadata)
|
||||
{
|
||||
// ignore other states
|
||||
return (false, default);
|
||||
return (false, DeleteReason.None);
|
||||
}
|
||||
|
||||
if (_queueCleanerConfig.StalledMaxStrikes > 0 && torrent.State is TorrentState.StalledDownload)
|
||||
{
|
||||
if (_queueCleanerConfig.StalledIgnorePrivate && isPrivate)
|
||||
{
|
||||
// ignore private trackers
|
||||
_logger.LogDebug("skip stalled check | download is private | {name}", torrent.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ResetStrikesOnProgress(torrent.Hash, torrent.Downloaded ?? 0);
|
||||
|
||||
if (torrent.State is TorrentState.StalledDownload)
|
||||
{
|
||||
return (await StrikeAndCheckLimit(torrent.Hash, torrent.Name, StrikeType.Stalled), DeleteReason.Stalled);
|
||||
}
|
||||
}
|
||||
|
||||
if (_queueCleanerConfig.DownloadingMetadataMaxStrikes > 0)
|
||||
{
|
||||
return (await StrikeAndCheckLimit(torrent.Hash, torrent.Name, StrikeType.DownloadingMetadata), DeleteReason.DownloadingMetadata);
|
||||
}
|
||||
|
||||
return (false, DeleteReason.None);
|
||||
}
|
||||
|
||||
private async Task<IReadOnlyList<TorrentTracker>> GetTrackersAsync(string hash)
|
||||
{
|
||||
return (await _client.GetTorrentTrackersAsync(hash))
|
||||
|
||||
@@ -119,9 +119,9 @@ public sealed class QueueCleaner : GenericHandler
|
||||
|
||||
bool removeFromClient = true;
|
||||
|
||||
if (stalledCheckResult.IsPrivate)
|
||||
if (stalledCheckResult is { IsPrivate: true, DeleteReason: not DeleteReason.DownloadingMetadata })
|
||||
{
|
||||
if (stalledCheckResult.ShouldRemove && !_config.StalledDeletePrivate)
|
||||
if (stalledCheckResult is { ShouldRemove: true, DeleteReason: DeleteReason.Stalled } && !_config.StalledDeletePrivate)
|
||||
{
|
||||
removeFromClient = false;
|
||||
}
|
||||
|
||||
@@ -193,13 +193,14 @@ services:
|
||||
- QUEUECLEANER__ENABLED=true
|
||||
- QUEUECLEANER__IGNORED_DOWNLOADS_PATH=/ignored
|
||||
- QUEUECLEANER__RUNSEQUENTIALLY=true
|
||||
- QUEUECLEANER__IMPORT_FAILED_MAX_STRIKES=5
|
||||
- QUEUECLEANER__IMPORT_FAILED_MAX_STRIKES=3
|
||||
- QUEUECLEANER__IMPORT_FAILED_IGNORE_PRIVATE=true
|
||||
- QUEUECLEANER__IMPORT_FAILED_DELETE_PRIVATE=false
|
||||
- QUEUECLEANER__IMPORT_FAILED_IGNORE_PATTERNS__0=file is a sample
|
||||
- QUEUECLEANER__STALLED_MAX_STRIKES=5
|
||||
- QUEUECLEANER__STALLED_MAX_STRIKES=3
|
||||
- QUEUECLEANER__STALLED_IGNORE_PRIVATE=true
|
||||
- QUEUECLEANER__STALLED_DELETE_PRIVATE=false
|
||||
- QUEUECLEANER__DOWNLOADING_METADATA_MAX_STRIKES=3
|
||||
|
||||
- CONTENTBLOCKER__ENABLED=true
|
||||
- CONTENTBLOCKER__IGNORED_DOWNLOADS_PATH=/ignored
|
||||
|
||||
+15
-2
@@ -152,7 +152,7 @@
|
||||
#### **`QUEUECLEANER__STALLED_MAX_STRIKES`**
|
||||
- Number of strikes before removing a stalled download.
|
||||
- Set to `0` to never remove stalled downloads.
|
||||
- A strike is given when an item is stalled (not downloading) or stuck while downloading metadata.
|
||||
- A strike is given when an item is stalled (not downloading).
|
||||
- Type: Integer
|
||||
- Default: `0`
|
||||
- Required: No.
|
||||
@@ -184,6 +184,19 @@
|
||||
> [!WARNING]
|
||||
> Setting `QUEUECLEANER__STALLED_DELETE_PRIVATE=true` means you don't care about seeding, ratio, H&R and potentially losing your private tracker account.
|
||||
|
||||
#### **`QUEUECLEANER__DOWNLOADING_METADATA_MAX_STRIKES`**
|
||||
- Number of strikes before removing a download stuck while downloading metadata.
|
||||
- Set to `0` to never remove downloads stuck at `downloading metadata`.
|
||||
- A strike is given when an item is stuck while downloading metadata.
|
||||
- Type: Integer
|
||||
- Default: `0`
|
||||
- Required: No.
|
||||
> [!NOTE]
|
||||
> If not set to `0`, the minimum value is `3`.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> `QUEUECLEANER__DOWNLOADING_METADATA_MAX_STRIKES` works only for qBitTorrent.
|
||||
|
||||
#
|
||||
|
||||
### Content Blocker settings
|
||||
@@ -317,7 +330,7 @@
|
||||
>
|
||||
> For Deluge, the category name is the name of the label.
|
||||
>
|
||||
> For Transmission, the category name is the last directory from the save location.
|
||||
> For Transmission, the category name is the last directory from the save location (e.g. `myCategory` from `/downloads/path/myCategory`).
|
||||
|
||||
#### **`DOWNLOADCLEANER__CATEGORIES__0__MAX_RATIO`**
|
||||
- Maximum ratio to reach before removing a download.
|
||||
|
||||
Reference in New Issue
Block a user