/** * H5P Core Files Setup Script * * This script downloads and sets up the H5P core files required for the editor and player. * It creates the necessary directory structure and downloads essential libraries. */ import fs from 'fs'; import path from 'path'; import https from 'https'; import { fileURLToPath } from 'url'; import { pipeline } from 'stream/promises'; import { createWriteStream } from 'fs'; import { exec } from 'child_process'; import { promisify } from 'util'; const execAsync = promisify(exec); const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const H5P_CORE_VERSION = '1.24'; const H5P_CORE_URL = `https://github.com/h5p/h5p-php-library/archive/refs/tags/${H5P_CORE_VERSION}.zip`; // Create required directories const dirs = [ 'h5p-core', 'h5p-libraries', 'h5p-content', 'h5p-temp' ]; console.log('🎓 Setting up H5P Service...\n'); // Create directories console.log('📁 Creating directories...'); dirs.forEach(dir => { const dirPath = path.join(__dirname, dir); if (!fs.existsSync(dirPath)) { fs.mkdirSync(dirPath, { recursive: true }); console.log(` ✅ Created ${dir}`); } else { console.log(` ⏭️ ${dir} already exists`); } }); // Download H5P core files async function downloadH5PCore() { console.log('\n📦 Downloading H5P Core files...'); console.log(` Version: ${H5P_CORE_VERSION}`); const zipPath = path.join(__dirname, 'h5p-core.zip'); const extractPath = path.join(__dirname, 'h5p-core-temp'); try { // Download core zip await new Promise((resolve, reject) => { https.get(H5P_CORE_URL, (response) => { if (response.statusCode === 302 || response.statusCode === 301) { // Handle redirect https.get(response.headers.location, (redirectResponse) => { const fileStream = createWriteStream(zipPath); redirectResponse.pipe(fileStream); fileStream.on('finish', () => { fileStream.close(); console.log(' ✅ Downloaded H5P core'); resolve(); }); }).on('error', reject); } else { const fileStream = createWriteStream(zipPath); response.pipe(fileStream); fileStream.on('finish', () => { fileStream.close(); console.log(' ✅ Downloaded H5P core'); resolve(); }); } }).on('error', reject); }); // Extract zip console.log(' 📂 Extracting files...'); // Check if unzip is available try { await execAsync(`unzip -q "${zipPath}" -d "${extractPath}"`); } catch (error) { console.log(' ⚠️ unzip not available, trying alternative method...'); // Alternative: use Node.js built-in extraction if available throw new Error('Please install unzip: brew install unzip (macOS) or apt-get install unzip (Linux)'); } // Move core files to h5p-core directory const extractedDir = fs.readdirSync(extractPath)[0]; const coreSrcPath = path.join(extractPath, extractedDir, 'js'); const coreDestPath = path.join(__dirname, 'h5p-core'); if (fs.existsSync(coreSrcPath)) { // Copy js files await execAsync(`cp -r "${coreSrcPath}"/* "${coreDestPath}/"`); console.log(' ✅ H5P core files installed'); } // Copy styles const stylesSrcPath = path.join(extractPath, extractedDir, 'styles'); if (fs.existsSync(stylesSrcPath)) { const stylesDestPath = path.join(__dirname, 'h5p-core', 'styles'); fs.mkdirSync(stylesDestPath, { recursive: true }); await execAsync(`cp -r "${stylesSrcPath}"/* "${stylesDestPath}/"`); console.log(' ✅ H5P styles installed'); } // Cleanup fs.unlinkSync(zipPath); fs.rmSync(extractPath, { recursive: true, force: true }); } catch (error) { console.error(' ❌ Error downloading H5P core:', error.message); console.log('\n 💡 Manual setup:'); console.log(' 1. Download from: https://github.com/h5p/h5p-php-library/releases'); console.log(' 2. Extract to h5p-core/ directory'); } } // Create basic H5P integration files function createIntegrationFiles() { console.log('\n📝 Creating integration files...'); // Create a minimal H5PIntegration.js file const integrationPath = path.join(__dirname, 'h5p-core', 'H5PIntegration.js'); if (!fs.existsSync(integrationPath)) { const integrationContent = ` // H5P Integration // This file is automatically generated by setup-h5p.js var H5PIntegration = H5PIntegration || {}; console.log('H5P Core loaded'); `.trim(); fs.writeFileSync(integrationPath, integrationContent); console.log(' ✅ Created H5PIntegration.js'); } else { console.log(' ⏭️ H5PIntegration.js already exists'); } } // Create README function createReadme() { const readme = `# H5P Service ## Setup erfolgreich! Die folgenden Verzeichnisse wurden erstellt: - \`h5p-core/\` - H5P Core JavaScript und CSS - \`h5p-libraries/\` - Installierte H5P Content Type Libraries - \`h5p-content/\` - Erstellte H5P Contents - \`h5p-temp/\` - Temporäre Dateien ## H5P Content Types installieren Um Content Types (wie Interactive Video, Quiz, etc.) zu verwenden, müssen diese über die H5P Hub API installiert werden. Der Editor zeigt verfügbare Content Types automatisch an. ## Entwicklung \`\`\`bash npm run dev # Start mit nodemon (auto-reload) npm start # Production start \`\`\` ## Endpoints - \`GET /h5p/editor/new\` - Neuen Content erstellen - \`GET /h5p/editor/:id\` - Content bearbeiten - \`POST /h5p/editor/:id\` - Content speichern - \`GET /h5p/play/:id\` - Content abspielen - \`GET /h5p/libraries\` - Installierte Libraries ## Dokumentation - H5P Official: https://h5p.org - @lumieducation/h5p-server: https://github.com/Lumieducation/H5P-Nodejs-library `; fs.writeFileSync(path.join(__dirname, 'H5P-README.md'), readme); console.log(' ✅ Created H5P-README.md'); } // Main setup function async function setup() { try { await downloadH5PCore(); createIntegrationFiles(); createReadme(); console.log('\n✅ H5P Service setup complete!\n'); console.log('📚 Next steps:'); console.log(' 1. Start the service: npm start'); console.log(' 2. Open http://localhost:8080'); console.log(' 3. Create H5P content via /h5p/editor/new'); console.log(''); } catch (error) { console.error('\n❌ Setup failed:', error); process.exit(1); } } setup();