SABnzbd path mapping + ASIN-based request deletion

Add bidirectional path mapping and complete_dir-aware category sync to the SABnzbd integration. Introduces PathMapper usage, complete_dir extraction, calculateCategoryPath(), and ensureCategory() logic to choose empty/relative/absolute category paths; ensureCategory is invoked before adding NZBs. Update singleton factory to load download_dir and path-mapping config from DownloadClientManager and recreate the service when config is not loaded. Make DownloadClientManager pass path-mapping config into the SABnzbd service. Change request deletion to remove plex_library records by ASIN (deleteMany) with a fallback to exact title/author matches so availability checks and deletions are consistent. Update documentation and tests to reflect the new behavior and APIs.
This commit is contained in:
kikootwo
2026-02-03 12:20:44 -05:00
parent 11376b36a2
commit c559f8ebe9
12 changed files with 805 additions and 131 deletions
@@ -13,6 +13,10 @@ const searchByRequestMock = vi.hoisted(() => vi.fn());
const selectTorrentMock = vi.hoisted(() => vi.fn());
const searchByAudiobookMock = vi.hoisted(() => vi.fn());
const requestWithTorrentMock = vi.hoisted(() => vi.fn());
const searchEbooksMock = vi.hoisted(() => vi.fn());
const selectEbookMock = vi.hoisted(() => vi.fn());
const searchEbooksByAsinMock = vi.hoisted(() => vi.fn());
const selectEbookByAsinMock = vi.hoisted(() => vi.fn());
vi.mock('@/lib/hooks/useRequests', () => ({
useInteractiveSearch: () => ({
@@ -35,6 +39,26 @@ vi.mock('@/lib/hooks/useRequests', () => ({
isLoading: false,
error: null,
}),
useInteractiveSearchEbook: () => ({
searchEbooks: searchEbooksMock,
isLoading: false,
error: null,
}),
useSelectEbook: () => ({
selectEbook: selectEbookMock,
isLoading: false,
error: null,
}),
useInteractiveSearchEbookByAsin: () => ({
searchEbooks: searchEbooksByAsinMock,
isLoading: false,
error: null,
}),
useSelectEbookByAsin: () => ({
selectEbook: selectEbookByAsinMock,
isLoading: false,
error: null,
}),
}));
const baseResult = {