mirror of
https://github.com/kikootwo/ReadMeABook.git
synced 2026-06-02 20:30:10 +00:00
ca7cac0c88
Implements remote-to-local path mapping for qBittorrent downloads, allowing the app to handle differing filesystem paths between qBittorrent and the local environment (e.g., remote seedboxes, Docker). Adds UI controls in admin settings and setup wizard, validates mapping configuration, and applies path transformation in download and import processors. Updates documentation, API routes, and data models to support the new feature. Also improves library scan logic to remove stale records and reset orphaned audiobooks and requests. Increases minimum torrent score threshold from 30 to 50 in search and ranking logic, and exposes torrent source URLs in the admin UI.
113 lines
3.9 KiB
Markdown
113 lines
3.9 KiB
Markdown
# Prowlarr Integration
|
|
|
|
**Status:** ✅ Implemented | Manual search, interactive search, automatic search
|
|
|
|
Indexer aggregator for searching multiple torrent/usenet indexers simultaneously. Supports manual search, interactive torrent selection, and automatic RSS feed monitoring.
|
|
|
|
## API
|
|
|
|
**Base:** `http://prowlarr:9696/api/v1`
|
|
**Auth:** `X-Api-Key` header
|
|
|
|
**GET /search?query={q}&categories=3030&indexerIds={ids}** - Search indexers (3030 = audiobooks, ids = comma-separated indexer IDs)
|
|
**GET /indexer** - List configured indexers
|
|
**GET /indexerstats** - Indexer statistics
|
|
**GET /feed/{indexerId}/api?t=search&cat=3030&limit=100** - RSS feed for specific indexer
|
|
|
|
## Search Strategy
|
|
|
|
**Search Query:** Title only (not title + author)
|
|
- Broader search yields more results (e.g., 20 vs 1)
|
|
- Ranking algorithm filters out mismatches using author/narrator
|
|
- Works around indexer limitations with complex queries
|
|
|
|
**Extended Search:** Enabled (`extended=1`) - searches title, tags, labels, and metadata fields
|
|
|
|
**Result Filtering:**
|
|
- Minimum score threshold: 50/100
|
|
- Filters applied after ranking to remove poor matches
|
|
- Ensures at least basic title/author match quality
|
|
- maxResults: 100 (increased from 50 for broader search)
|
|
|
|
**Example:** "Season of Storms" → finds all "Season of Storms" torrents → ranks by author match → filters score < 50
|
|
|
|
```typescript
|
|
interface TorrentResult {
|
|
indexer: string;
|
|
title: string;
|
|
size: number; // bytes
|
|
seeders: number;
|
|
leechers: number;
|
|
publishDate: Date;
|
|
downloadUrl: string; // magnet or .torrent
|
|
infoHash?: string;
|
|
guid: string;
|
|
format?: 'M4B' | 'M4A' | 'MP3';
|
|
bitrate?: string;
|
|
hasChapters?: boolean;
|
|
}
|
|
```
|
|
|
|
## Config
|
|
|
|
- `indexer.prowlarr_url`
|
|
- `indexer.prowlarr_api_key`
|
|
|
|
## Error Handling
|
|
|
|
- 401: Invalid API key
|
|
- 429: Rate limit (exponential backoff, max 3 retries)
|
|
- 503: Service unavailable
|
|
- Timeout: 30s per search
|
|
|
|
## Manual & Interactive Search
|
|
|
|
**Indexer Filtering:** All searches (manual and interactive) only query indexers enabled in settings (`prowlarr_indexers` config). If no indexers are enabled, search will fail with error.
|
|
|
|
**Manual Search** (`POST /api/requests/{id}/manual-search`)
|
|
- Triggers automatic search job for requests with status: pending, failed, awaiting_search
|
|
- Searches only enabled indexers (title only, maxResults: 100)
|
|
- Ranks all results, filters scores < 50
|
|
- Selects best torrent from filtered results
|
|
- Updates request status to 'pending'
|
|
|
|
**Interactive Search** (`POST /api/requests/{id}/interactive-search`)
|
|
- Returns ranked torrent results for user selection
|
|
- Searches only enabled indexers (title only or custom, maxResults: 100)
|
|
- Accepts optional custom search title in request body
|
|
- Ranks all results, filters scores < 50
|
|
- Shows table with: rank, title, size, quality score, seeders, indexer, publish date
|
|
- Editable title field allows search refinement
|
|
- Available for same statuses as manual search
|
|
- User clicks "Download" button to select specific torrent
|
|
|
|
**Select Torrent** (`POST /api/requests/{id}/select-torrent`)
|
|
- Downloads user-selected torrent from interactive search
|
|
- Triggers download_torrent job
|
|
- Updates request status to 'downloading'
|
|
|
|
**UI Integration:**
|
|
- Manual Search button: Triggers automatic search
|
|
- Interactive Search button: Opens modal with torrent results
|
|
- Both buttons shown for requests with status: pending, failed, awaiting_search
|
|
|
|
## RSS Monitoring
|
|
|
|
**Automatic Feed Monitoring:** Enabled per-indexer via setup wizard or settings page
|
|
**Schedule:** Every 15 minutes (default, configurable)
|
|
**Process:**
|
|
1. Fetch RSS feeds from all indexers with RSS enabled
|
|
2. Fuzzy match results against requests in 'awaiting_search' status
|
|
3. Trigger search jobs for matches
|
|
4. Limit: 100 results per feed, 100 missing requests per check
|
|
|
|
**Matching Logic:**
|
|
- Author name must appear in torrent title
|
|
- At least 2 title words (>2 chars) must match
|
|
- First match triggers search job (no duplicates)
|
|
|
|
## Tech Stack
|
|
|
|
- axios
|
|
- bottleneck (rate limiting)
|