import inquirer from 'inquirer'; import path from 'path'; import { fileURLToPath } from 'url'; import dotenv from 'dotenv'; import { loadConfig } from './config.js'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); dotenv.config({ path: path.resolve(__dirname, '..', '..', '.env') }); export const runJobsMenu = async () => { const config = await loadConfig(); const JOBS = [ { name: '🛠 Rebuild site', type: 'curl', urlEnvVar: 'SITE_REBUILD_WEBHOOK', tokenEnvVar: 'DIRECTUS_API_TOKEN', method: 'GET' }, { name: '💿 Scrobble listens from Navidrome', type: 'curl', apiUrl: `${config.url}/api/scrobble.php`, tokenEnvVar: 'NAVIDROME_SCROBBLE_TOKEN', method: 'POST' }, { name: '🎧 Update total plays', type: 'curl', urlEnvVar: 'TOTAL_PLAYS_WEBHOOK', tokenEnvVar: 'DIRECTUS_API_TOKEN', method: 'GET' }, { name: '🐘 Send posts to Mastodon', type: 'curl', apiUrl: `${config.url}/api/mastodon.php`, tokenEnvVar: 'MASTODON_SYNDICATION_TOKEN', method: 'POST' }, { name: '🎤 Import artist from Navidrome', type: 'curl', apiUrl: `${config.url}/api/artist-import.php`, tokenEnvVar: 'ARTIST_IMPORT_TOKEN', method: 'POST', paramsPrompt: [ { type: 'input', name: 'artistId', message: 'Enter the Navidrome artist ID:', validate: (input) => (input ? true : 'Artist ID is required') } ] }, { name: '📖 Import book', type: 'curl', apiUrl: `${config.url}/api/book-import.php`, tokenEnvVar: 'BOOK_IMPORT_TOKEN', method: 'POST', paramsPrompt: [ { type: 'input', name: 'isbn', message: "Enter the book's ISBN:", validate: (input) => (input ? true : 'ISBN is required') } ] }, { name: '📽 Import a movie or tv show', type: 'curl', apiUrl: `${config.url}/api/watching-import.php`, tokenEnvVar: 'WATCHING_IMPORT_TOKEN', method: 'POST', tokenIncludeInParams: true, paramsPrompt: [ { type: 'input', name: 'tmdb_id', message: 'Enter the TMDB ID:', validate: (input) => (/^\d+$/.test(input) ? true : 'Please enter a valid TMDB ID') }, { type: 'list', name: 'media_type', message: 'Is this a movie or tv show?', choices: ['movie', 'tv'] } ] }, { name: '📺 Import upcoming TV seasons', type: 'curl', apiUrl: `${config.url}/api/seasons-import.php`, tokenEnvVar: 'SEASONS_IMPORT_TOKEN', method: 'POST' } ]; const { selectedJob } = await inquirer.prompt([ { type: 'list', name: 'selectedJob', message: 'Select a job to run:', choices: JOBS.map((job, index) => ({ name: job.name, value: index })) } ]); const job = JOBS[selectedJob]; if (job.type === 'curl') { let params = null; if (job.paramsPrompt) { const answers = await inquirer.prompt(job.paramsPrompt); const token = process.env[job.tokenEnvVar]; params = { ...answers, ...(token ? { token } : {}) }; } await runCurl({ ...job, params }); } else { console.warn(`⚠️ Unsupported job type: ${job.type}`); } }; const runCurl = async ({ urlEnvVar, apiUrl = '', tokenEnvVar, method = 'POST', name, params = null }) => { const url = process.env[urlEnvVar] || apiUrl; const token = tokenEnvVar ? process.env[tokenEnvVar] : null; if (!url) { console.error(`❌ Missing URL for job. Check ${urlEnvVar} in your .env`); return; } try { const res = await fetch(url, { method, headers: { 'Content-Type': 'application/json', ...(token && { Authorization: `Bearer ${token}` }) }, ...(params && { body: JSON.stringify(params) }) }); if (!res.ok) { const errText = await res.text(); throw new Error(errText); } console.log(`✅ ${name} ran successfully.`); } catch (err) { console.error(`❌ Request failed: ${err.message}`); } };