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, ); 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);