fix: handle isbn as array from Listenarr search results
This commit is contained in:
@@ -0,0 +1,95 @@
|
|||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
const LISTENARR_URL = process.env.LISTENARR_URL || "";
|
||||||
|
const LISTENARR_API_KEY = process.env.LISTENARR_API_KEY || "";
|
||||||
|
|
||||||
|
const listenarrApi = axios.create({
|
||||||
|
baseURL: LISTENARR_URL,
|
||||||
|
timeout: 15000,
|
||||||
|
headers: {
|
||||||
|
"X-Api-Key": LISTENARR_API_KEY,
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export async function searchAudiobooks(
|
||||||
|
query: string
|
||||||
|
): Promise<any[]> {
|
||||||
|
const resp = await listenarrApi.get("/api/v1/search/audible", {
|
||||||
|
params: { query },
|
||||||
|
});
|
||||||
|
return resp.data?.results || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function addAudiobook(options: {
|
||||||
|
asin: string;
|
||||||
|
title: string;
|
||||||
|
authors: string[];
|
||||||
|
imageUrl?: string;
|
||||||
|
description?: string;
|
||||||
|
monitored?: boolean;
|
||||||
|
autoSearch?: boolean;
|
||||||
|
subtitle?: string;
|
||||||
|
narrators?: string[];
|
||||||
|
publisher?: string;
|
||||||
|
language?: string;
|
||||||
|
releaseDate?: string;
|
||||||
|
runtimeLengthMin?: number;
|
||||||
|
genres?: string[];
|
||||||
|
series?: string;
|
||||||
|
seriesNumber?: string;
|
||||||
|
isbn?: string;
|
||||||
|
explicit?: boolean;
|
||||||
|
abridged?: boolean;
|
||||||
|
}): Promise<any> {
|
||||||
|
// Defensive: ensure series/seriesNumber are always strings, not arrays
|
||||||
|
const series = typeof options.series === "string" ? options.series : "";
|
||||||
|
const seriesNumber = typeof options.seriesNumber === "string" ? options.seriesNumber : "";
|
||||||
|
|
||||||
|
const body: any = {
|
||||||
|
metadata: {
|
||||||
|
asin: options.asin,
|
||||||
|
title: options.title,
|
||||||
|
subtitle: options.subtitle || "",
|
||||||
|
source: "audible",
|
||||||
|
authors: options.authors || [],
|
||||||
|
narrators: options.narrators || [],
|
||||||
|
imageUrl: options.imageUrl || "",
|
||||||
|
description: options.description || "",
|
||||||
|
publisher: options.publisher || "",
|
||||||
|
language: options.language || "",
|
||||||
|
releaseDate: options.releaseDate || "",
|
||||||
|
runtime: options.runtimeLengthMin ? options.runtimeLengthMin * 60 : 0,
|
||||||
|
genres: options.genres || [],
|
||||||
|
series: series,
|
||||||
|
seriesNumber: seriesNumber,
|
||||||
|
isbn: Array.isArray(options.isbn) ? options.isbn : (typeof options.isbn === "string" && options.isbn ? options.isbn.split(",") : []),
|
||||||
|
explicit: options.explicit || false,
|
||||||
|
abridged: options.abridged || false,
|
||||||
|
},
|
||||||
|
autoSearch: options.autoSearch !== false,
|
||||||
|
monitored: options.monitored !== false,
|
||||||
|
qualityProfileId: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
const resp = await listenarrApi.post("/api/v1/library/add", body);
|
||||||
|
return resp.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getListenarrStatus(): Promise<{
|
||||||
|
connected: boolean;
|
||||||
|
data?: any;
|
||||||
|
error?: string;
|
||||||
|
}> {
|
||||||
|
try {
|
||||||
|
const resp = await listenarrApi.get("/api/v1/system/info", {
|
||||||
|
timeout: 5000,
|
||||||
|
});
|
||||||
|
return { connected: true, data: resp.data };
|
||||||
|
} catch (error: any) {
|
||||||
|
return {
|
||||||
|
connected: false,
|
||||||
|
error: error?.message || "Failed to connect to Listenarr",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user