fix: Restore all files lost during destructive rebase
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>
This commit is contained in:
213
h5p-service/setup-h5p.js
Normal file
213
h5p-service/setup-h5p.js
Normal file
@@ -0,0 +1,213 @@
|
||||
/**
|
||||
* 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();
|
||||
Reference in New Issue
Block a user