jellyfin-to-m3u/index.ts

79 lines
2.4 KiB
TypeScript
Raw Normal View History

2024-08-20 06:19:59 +00:00
import { Command } from 'commander';
import { checkbox } from '@inquirer/prompts';
import { getAllPlaylists, getSonglistForPlaylist } from './lib/services/jellyfin.ts';
import type { Playlist, SongMeta } from './lib/services/jellyfin.ts';
import { downloadSongs } from './lib/fileDownloader.ts';
import { writeM3UFile } from './lib/m3uWriter.ts';
import 'dotenv/config';
const program = new Command();
const { JF_SERVER, JF_USERNAME, JF_PASSWORD, DEST_FOLDER, PLAYLISTS } = process.env;
program
.name('')
.description('CLI to download Jellyfin Playlists to mp3 player m3u format.')
.version('0.0.1');
program
.command('wizard')
.description('Start the CLI wizzard to select playlists and start the downloads')
.action(async (str, options) => {
console.log('Fetching playlist information...');
if (!JF_SERVER) {
console.error('Missing required env var JF_SERVER. Exiting...');
process.exit();
}
if (!JF_USERNAME) {
console.error('Missing required env var JF_USERNAME. Exiting...');
process.exit();
}
if (!JF_PASSWORD) {
console.error('Missing required env var JF_PASSWORD. Exiting...');
process.exit();
}
if (!DEST_FOLDER) {
console.error('Missing required env var DEST_FOLDER. Exiting...');
process.exit();
}
const creds = {
server: JF_SERVER,
user: JF_USERNAME,
password: JF_PASSWORD,
};
const playlistMetas = await getAllPlaylists(creds);
const answer = await checkbox({
message: 'Which playlists would you like to download?',
choices: playlistMetas.map((pl: Playlist) => ({ name: pl.Name, value: pl.Id })),
});
const playlists = await Promise.all(
answer.map(async id => {
const pl = {
...playlistMetas.find(p => p.Id === id),
};
pl.songlist = await getSonglistForPlaylist(creds, id);
return pl;
}),
);
const allSongs = playlists.reduce(
(songs, pl) => {
console.log('PLAYLIST: ', pl);
pl.songlist?.forEach(song => {
songs[song.Id] = song;
});
return songs;
},
{} as Record<string, SongMeta>,
);
await downloadSongs(creds, Object.values(allSongs), DEST_FOLDER);
await Promise.all(
playlists.map((pl, i) =>
writeM3UFile(DEST_FOLDER, pl.Name || `playlist${i}`, pl.songlist as SongMeta[]),
),
);
});
await program.parseAsync(process.argv);