#!/usr/bin/env node const fs = require("node:fs"); const fsPromises = require("node:fs/promises"); const path = require("node:path"); const { ensureBundleExists, promptForBundlePath } = require("./lib/bundles"); const { extractFileTitleFromUrl, fetchWikimediaAsset, downloadFile, } = require("./lib/wikimedia"); const CONTENT_DIR = path.resolve("content"); const TEMPLATE_PATH = path.resolve("data/metadata_template.yaml"); const IMAGES_DIR = "images"; const DATA_IMAGES_DIR = path.join("data", "images"); /** * Affiche l'aide minimale du script. */ function showUsage() { console.error("Usage: node tools/add_wikimedia_image.js [bundle_path]"); } /** * Charge le modèle YAML utilisé pour les métadonnées de pièces jointes. * @returns {Promise} Contenu brut du modèle. */ async function loadMetadataTemplate() { return fsPromises.readFile(TEMPLATE_PATH, "utf8"); } /** * Injecte l'attribution et la description dans le modèle YAML existant. * @param {string} template Modèle brut. * @param {{ attribution: string, description: string }} metadata Valeurs à injecter. * @returns {string} YAML final prêt à être écrit. */ function fillMetadataTemplate(template, metadata) { let output = template; output = output.replace('#attribution: ""', `attribution: ${JSON.stringify(metadata.attribution)}`); output = output.replace('#description: ""', `description: ${JSON.stringify(metadata.description)}`); return output; } /** * Retourne les chemins finaux de l'image et de son fichier de métadonnées. * @param {string} bundlePath Bundle ciblé. * @param {string} fileName Nom de fichier téléchargé. * @returns {{ imagePath: string, metadataPath: string }} */ function buildTargetPaths(bundlePath, fileName) { const extension = path.extname(fileName); const baseName = path.basename(fileName, extension); return { imagePath: path.join(bundlePath, IMAGES_DIR, fileName), metadataPath: path.join(bundlePath, DATA_IMAGES_DIR, `${baseName}.yaml`), }; } /** * Vérifie qu'aucun fichier existant ne sera écrasé. * @param {string} imagePath Chemin final de l'image. * @param {string} metadataPath Chemin final des métadonnées. */ function ensureTargetsDoNotExist(imagePath, metadataPath) { if (fs.existsSync(imagePath)) { throw new Error(`L'image ${imagePath} existe déjà.`); } if (fs.existsSync(metadataPath)) { throw new Error(`Le fichier de métadonnées ${metadataPath} existe déjà.`); } } /** * Assure l'existence des dossiers parents nécessaires. * @param {string} imagePath Chemin final de l'image. * @param {string} metadataPath Chemin final des métadonnées. */ async function ensureTargetDirectories(imagePath, metadataPath) { await fsPromises.mkdir(path.dirname(imagePath), { recursive: true }); await fsPromises.mkdir(path.dirname(metadataPath), { recursive: true }); } /** * Point d'entrée principal du script. */ async function main() { const rawUrl = process.argv[2]; const manualBundlePath = process.argv[3]; if (!rawUrl) { showUsage(); process.exit(1); } const bundlePath = await promptForBundlePath(manualBundlePath, { contentDir: CONTENT_DIR, prompts: { confirmLatest(latest) { return `Utiliser le dernier bundle trouve : ${latest} ? (Y/n) `; }, manualPath: "Saisissez le chemin relatif du bundle : ", }, }); ensureBundleExists(bundlePath); const fileTitle = extractFileTitleFromUrl(rawUrl); console.log(`Recuperation des metadonnees Wikimedia pour ${fileTitle}...`); const asset = await fetchWikimediaAsset(fileTitle); const targets = buildTargetPaths(bundlePath, asset.fileName); ensureTargetsDoNotExist(targets.imagePath, targets.metadataPath); await ensureTargetDirectories(targets.imagePath, targets.metadataPath); console.log(`Telechargement de ${asset.fileName}...`); await downloadFile(asset.imageUrl, targets.imagePath); const template = await loadMetadataTemplate(); const metadataContent = fillMetadataTemplate(template, asset); await fsPromises.writeFile(targets.metadataPath, metadataContent, "utf8"); console.log(`Image enregistree : ${targets.imagePath}`); console.log(`Metadonnees enregistrees : ${targets.metadataPath}`); } main();