mirror of
https://github.com/kikootwo/ReadMeABook.git
synced 2026-06-03 04:40:09 +00:00
Implement file hash-based library matching and remove fuzzy ASIN matching
Adds file hash-based matching for Audiobookshelf library items to ensure 100% accurate ASIN assignment for RMAB-organized content. Removes fuzzy matching from library availability checks, making all matching ASIN-only to eliminate false positives and race conditions. Updates database schema, processors, and matcher utilities; adds new tests and documentation for the new matching strategy. Removes obsolete scripts, Dockerfile, and related tests; updates docker-compose for test environments.
This commit is contained in:
@@ -88,22 +88,29 @@ Where `{baseUrl}` is determined by configured region (e.g., `https://www.audible
|
||||
|
||||
## Unified Matching (`audiobook-matcher.ts`)
|
||||
|
||||
**Status:** ✅ Production Ready
|
||||
**Status:** ✅ Production Ready (ASIN-Only Matching)
|
||||
|
||||
Single matching algorithm used everywhere (search, popular, new-releases, jobs).
|
||||
|
||||
**Process:**
|
||||
1. Query DB candidates: `audibleId` exact match OR partial title+author match
|
||||
2. If exact ASIN match → return immediately
|
||||
3. Fuzzy match: title 70% + author 30% weights, 70% threshold
|
||||
4. Return best match or null
|
||||
**Process (Library Availability Checks):**
|
||||
1. Query DB directly by ASIN (indexed O(1) lookup)
|
||||
2. Check ASIN in dedicated field (100% confidence)
|
||||
3. Check ASIN in plexGuid (backward compatibility)
|
||||
4. Return match or null (no fuzzy fallback)
|
||||
|
||||
**Match Priority:**
|
||||
- `findPlexMatch()`: ASIN (field) → ASIN (GUID) → null
|
||||
- `matchAudiobook()`: ASIN → ISBN → null
|
||||
|
||||
**Benefits:**
|
||||
- Real-time matching at query time (not pre-matched)
|
||||
- Works regardless of job execution order
|
||||
- Prevents duplicate `plexGuid` assignments
|
||||
- 100% confidence matches only (eliminates false positives)
|
||||
- O(1) indexed lookups (faster than fuzzy matching)
|
||||
- Solves race condition with Audiobookshelf ASIN population
|
||||
- Used by all APIs for consistency
|
||||
|
||||
**Note:** Fuzzy matching (70% threshold) is preserved in `ranking-algorithm.ts` for Prowlarr torrent ranking, where it's needed to score multiple release candidates. Library availability checks require exact ASIN matches only.
|
||||
|
||||
## Database-First Approach
|
||||
|
||||
**Status:** ✅ Implemented
|
||||
|
||||
@@ -77,7 +77,7 @@ Anna's Archive uses Cloudflare protection which may block direct scraping reques
|
||||
|
||||
**Method 1: ASIN Search (exact match)**
|
||||
```
|
||||
Search: https://annas-archive.li/search?ext=epub&q="asin:B09TWSRMCB"
|
||||
Search: https://annas-archive.li/search?ext=epub&lang=en&q="asin:B09TWSRMCB"
|
||||
↓
|
||||
MD5 Page: https://annas-archive.li/md5/[md5]
|
||||
↓ (Filter: "slow partner server" links)
|
||||
|
||||
@@ -21,6 +21,7 @@ Connectivity to Plex for OAuth, library management, content detection, and autom
|
||||
**GET {server_url}/library/sections/{id}/refresh** - Trigger async scan
|
||||
**GET {server_url}/library/metadata/{rating_key}** - Item metadata (includes user's personal rating)
|
||||
**GET {server_url}/library/sections/{id}/search?title={query}** - Search
|
||||
**DELETE {server_url}/library/metadata/{rating_key}** - Delete library item (requires deletion enabled in Plex settings)
|
||||
|
||||
Auth: `X-Plex-Token` header
|
||||
Response: XML (requires `xml2js` parsing to JSON)
|
||||
@@ -256,14 +257,41 @@ interface PlexLibrary {
|
||||
- testConnection() only used for: testing connections, initial fetching during setup/settings
|
||||
- Result: Faster authentication, no unnecessary API calls, consistent architecture
|
||||
|
||||
## Library Item Deletion
|
||||
|
||||
**Endpoint:** `DELETE /library/metadata/{ratingKey}`
|
||||
|
||||
**Use Case:** When admin deletes a request, also delete from Plex library to keep in sync
|
||||
|
||||
**Requirements:**
|
||||
- Deletion must be enabled: Settings > Server > Library in Plex webui
|
||||
- Without this setting enabled, DELETE requests will fail
|
||||
|
||||
**Implementation:**
|
||||
- `deleteItem(serverUrl, authToken, ratingKey)` - Deletes library item by ratingKey
|
||||
- Called during request deletion when backend mode is 'plex'
|
||||
- Extracts ratingKey from audiobook.plexGuid (format: `plex://album/{ratingKey}`)
|
||||
- Mirrors ABS deletion behavior for consistency
|
||||
|
||||
**Error Handling:**
|
||||
- 404: Item not found (already deleted) - logged but not thrown
|
||||
- Other errors: Logged but deletion continues (prevents blocking request deletion)
|
||||
|
||||
## Availability Checking
|
||||
|
||||
1. **DB Population:** Plex scan creates/updates records with `plexGuid` + `availabilityStatus: 'available'`
|
||||
2. **Audible Matching:** Refresh job fuzzy matches (85% threshold), sets `availabilityStatus: 'available'` for matches
|
||||
3. **API Enrichment:** Discovery APIs use real-time matching (70% threshold) at query time
|
||||
4. **UI:** `AudiobookCard` shows "In Your Library" if `isAvailable: true`
|
||||
1. **DB Population:** Plex scan creates/updates records with `plexGuid` + ASIN + `availabilityStatus: 'available'`
|
||||
2. **Audible Matching:** Real-time ASIN-only matching (100% confidence, exact matches only)
|
||||
3. **API Enrichment:** Discovery APIs use real-time ASIN matching at query time
|
||||
4. **UI:** `AudiobookCard` shows "In Your Library" if `isAvailable: true` (ASIN exact match)
|
||||
5. **Server Validation:** `/api/requests` returns 409 if `availabilityStatus === 'available'`
|
||||
|
||||
**Match Priority (ASIN-Only):**
|
||||
- ASIN in dedicated field (100% confidence) → Match
|
||||
- ASIN in plexGuid (backward compatibility) → Match
|
||||
- No ASIN match → Return null (no fuzzy fallback)
|
||||
|
||||
**Note:** Fuzzy matching (70% threshold) is preserved in `ranking-algorithm.ts` for Prowlarr torrent selection, but NOT used for library availability checks. This eliminates false positives (e.g., "Foundation" matching "Foundation and Empire").
|
||||
|
||||
## Tech Stack
|
||||
|
||||
- axios/node-fetch
|
||||
|
||||
Reference in New Issue
Block a user