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}`); } };