Add per-indexer ratio-based seeding policy

Introduce a per-indexer ratioLimit alongside seedingTimeMinutes to control torrent cleanup. Updates include: documentation (scheduler and settings pages), types and API (saved indexer config now includes ratioLimit), setup and management UI (new TorrentSeedingFields component, modal wiring, validation and handlers), and processor logic (cleanup-seeded-torrents now requires AND-semantics between time and ratio; 0 disables a criterion, both 0 = never cleaned, undefined client ratio with ratioLimit>0 = not met). Tests were added/updated to cover ratio-only, time+ratio, missing-ratio, and UI interactions. Default behavior: ratioLimit defaults to 0 (no ratio requirement).
This commit is contained in:
kikootwo
2026-05-18 15:07:50 -04:00
parent 01e61f3368
commit 411b5f88a4
13 changed files with 407 additions and 41 deletions
@@ -17,6 +17,7 @@ interface SavedIndexerConfig {
protocol: string;
priority: number;
seedingTimeMinutes?: number; // Torrents only
ratioLimit?: number; // Torrents only (0 = no ratio requirement)
removeAfterProcessing?: boolean; // Usenet only
rssEnabled?: boolean;
audiobookCategories?: number[]; // Array of category IDs for audiobooks (default: [3030])
@@ -79,6 +80,7 @@ export async function GET(request: NextRequest) {
// Add protocol-specific fields
if (isTorrent) {
config.seedingTimeMinutes = saved?.seedingTimeMinutes ?? 0;
config.ratioLimit = saved?.ratioLimit ?? 0;
} else {
config.removeAfterProcessing = saved?.removeAfterProcessing ?? true;
}
@@ -134,6 +136,7 @@ export async function PUT(request: NextRequest) {
const isTorrent = indexer.protocol?.toLowerCase() === 'torrent';
if (isTorrent) {
config.seedingTimeMinutes = indexer.seedingTimeMinutes ?? 0;
config.ratioLimit = indexer.ratioLimit ?? 0;
} else {
config.removeAfterProcessing = indexer.removeAfterProcessing ?? true;
}