mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-02-27 18:22:41 -08:00
117 lines
3.6 KiB
TypeScript
117 lines
3.6 KiB
TypeScript
import type { CliArgs } from '../../cli/args';
|
|
|
|
type JellyfinSession = {
|
|
serverUrl: string;
|
|
accessToken: string;
|
|
userId: string;
|
|
username: string;
|
|
};
|
|
|
|
type JellyfinClientInfo = {
|
|
clientName: string;
|
|
clientVersion: string;
|
|
deviceId: string;
|
|
};
|
|
|
|
type JellyfinConfig = {
|
|
defaultLibraryId: string;
|
|
};
|
|
|
|
export function createHandleJellyfinListCommands(deps: {
|
|
listJellyfinLibraries: (
|
|
session: JellyfinSession,
|
|
clientInfo: JellyfinClientInfo,
|
|
) => Promise<Array<{ id: string; name: string; collectionType?: string; type?: string }>>;
|
|
listJellyfinItems: (
|
|
session: JellyfinSession,
|
|
clientInfo: JellyfinClientInfo,
|
|
params: { libraryId: string; searchTerm?: string; limit: number },
|
|
) => Promise<Array<{ id: string; title: string; type: string }>>;
|
|
listJellyfinSubtitleTracks: (
|
|
session: JellyfinSession,
|
|
clientInfo: JellyfinClientInfo,
|
|
itemId: string,
|
|
) => Promise<
|
|
Array<{
|
|
index: number;
|
|
language?: string;
|
|
title?: string;
|
|
deliveryMethod?: string;
|
|
codec?: string;
|
|
isDefault?: boolean;
|
|
isForced?: boolean;
|
|
isExternal?: boolean;
|
|
deliveryUrl?: string | null;
|
|
}>
|
|
>;
|
|
logInfo: (message: string) => void;
|
|
}) {
|
|
return async (params: {
|
|
args: CliArgs;
|
|
session: JellyfinSession;
|
|
clientInfo: JellyfinClientInfo;
|
|
jellyfinConfig: JellyfinConfig;
|
|
}): Promise<boolean> => {
|
|
const { args, session, clientInfo, jellyfinConfig } = params;
|
|
|
|
if (args.jellyfinLibraries) {
|
|
const libraries = await deps.listJellyfinLibraries(session, clientInfo);
|
|
if (libraries.length === 0) {
|
|
deps.logInfo('No Jellyfin libraries found.');
|
|
return true;
|
|
}
|
|
for (const library of libraries) {
|
|
deps.logInfo(
|
|
`Jellyfin library: ${library.name} [${library.id}] (${library.collectionType || library.type || 'unknown'})`,
|
|
);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
if (args.jellyfinItems) {
|
|
const libraryId = args.jellyfinLibraryId || jellyfinConfig.defaultLibraryId;
|
|
if (!libraryId) {
|
|
throw new Error(
|
|
'Missing Jellyfin library id. Use --jellyfin-library-id or set jellyfin.defaultLibraryId.',
|
|
);
|
|
}
|
|
const items = await deps.listJellyfinItems(session, clientInfo, {
|
|
libraryId,
|
|
searchTerm: args.jellyfinSearch,
|
|
limit: args.jellyfinLimit ?? 100,
|
|
});
|
|
if (items.length === 0) {
|
|
deps.logInfo('No Jellyfin items found for the selected library/search.');
|
|
return true;
|
|
}
|
|
for (const item of items) {
|
|
deps.logInfo(`Jellyfin item: ${item.title} [${item.id}] (${item.type})`);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
if (args.jellyfinSubtitles) {
|
|
if (!args.jellyfinItemId) {
|
|
throw new Error('Missing --jellyfin-item-id for --jellyfin-subtitles.');
|
|
}
|
|
const tracks = await deps.listJellyfinSubtitleTracks(session, clientInfo, args.jellyfinItemId);
|
|
if (tracks.length === 0) {
|
|
deps.logInfo('No Jellyfin subtitle tracks found for item.');
|
|
return true;
|
|
}
|
|
for (const track of tracks) {
|
|
if (args.jellyfinSubtitleUrlsOnly) {
|
|
if (track.deliveryUrl) deps.logInfo(track.deliveryUrl);
|
|
continue;
|
|
}
|
|
deps.logInfo(
|
|
`Jellyfin subtitle: index=${track.index} lang=${track.language || 'unknown'} title="${track.title || '-'}" method=${track.deliveryMethod || 'unknown'} codec=${track.codec || 'unknown'} default=${track.isDefault ? 'yes' : 'no'} forced=${track.isForced ? 'yes' : 'no'} external=${track.isExternal ? 'yes' : 'no'} url=${track.deliveryUrl || '-'}`,
|
|
);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
};
|
|
}
|