A previous `git pull --rebase origin main` dropped 177 local commits,
losing 3400+ files across admin-v2, backend, studio-v2, website,
klausur-service, and many other services. The partial restore attempt
(660295e2) only recovered some files.
This commit restores all missing files from pre-rebase ref 98933f5e
while preserving post-rebase additions (night-scheduler, night-mode UI,
NightModeWidget dashboard integration).
Restored features include:
- AI Module Sidebar (FAB), OCR Labeling, OCR Compare
- GPU Dashboard, RAG Pipeline, Magic Help
- Klausur-Korrektur (8 files), Abitur-Archiv (5+ files)
- Companion, Zeugnisse-Crawler, Screen Flow
- Full backend, studio-v2, website, klausur-service
- All compliance SDKs, agent-core, voice-service
- CI/CD configs, documentation, scripts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
214 lines
6.4 KiB
JavaScript
214 lines
6.4 KiB
JavaScript
/**
|
|
* 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();
|