Files
netfelix-audio-fix/server/services/sonarr.ts
Felix Förtsch 5ac44b7551 restructure to react spa + hono api, fix missing server/ and lib/
rewrite from monolithic hono jsx to react 19 spa with tanstack router
+ hono json api backend. add scan, review, execute, nodes, and setup
pages. multi-stage dockerfile (node for vite build, bun for runtime).

previously, server/ and src/shared/lib/ were silently excluded by
global gitignore patterns (/server/ from emacs, lib/ from python).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 22:57:40 +01:00

86 lines
1.9 KiB
TypeScript

import { normalizeLanguage } from './jellyfin';
export interface SonarrConfig {
url: string;
apiKey: string;
}
function headers(apiKey: string): Record<string, string> {
return { 'X-Api-Key': apiKey };
}
export async function testConnection(cfg: SonarrConfig): Promise<{ ok: boolean; error?: string }> {
try {
const res = await fetch(`${cfg.url}/api/v3/system/status`, {
headers: headers(cfg.apiKey),
});
if (!res.ok) return { ok: false, error: `HTTP ${res.status}` };
return { ok: true };
} catch (e) {
return { ok: false, error: String(e) };
}
}
interface SonarrSeries {
tvdbId?: number;
originalLanguage?: { name: string };
}
/** Returns ISO 639-2 original language for a series or null. */
export async function getOriginalLanguage(
cfg: SonarrConfig,
tvdbId: string
): Promise<string | null> {
try {
const res = await fetch(`${cfg.url}/api/v3/series?tvdbId=${tvdbId}`, {
headers: headers(cfg.apiKey),
});
if (!res.ok) return null;
const list = (await res.json()) as SonarrSeries[];
const series = list[0];
if (!series?.originalLanguage) return null;
return languageNameToCode(series.originalLanguage.name) ?? null;
} catch {
return null;
}
}
const NAME_TO_639_2: Record<string, string> = {
english: 'eng',
french: 'fra',
german: 'deu',
spanish: 'spa',
italian: 'ita',
portuguese: 'por',
japanese: 'jpn',
korean: 'kor',
chinese: 'zho',
arabic: 'ara',
russian: 'rus',
dutch: 'nld',
swedish: 'swe',
norwegian: 'nor',
danish: 'dan',
finnish: 'fin',
polish: 'pol',
turkish: 'tur',
thai: 'tha',
hindi: 'hin',
hungarian: 'hun',
czech: 'ces',
romanian: 'ron',
greek: 'ell',
hebrew: 'heb',
persian: 'fas',
ukrainian: 'ukr',
indonesian: 'ind',
malay: 'msa',
vietnamese: 'vie',
};
function languageNameToCode(name: string): string | null {
const key = name.toLowerCase().trim();
return NAME_TO_639_2[key] ?? normalizeLanguage(key.slice(0, 3)) ?? null;
}