125 lines
3.6 KiB
JavaScript
125 lines
3.6 KiB
JavaScript
import express from 'express';
|
|
import archiver from 'archiver';
|
|
import db from '../database.js';
|
|
import { authenticateToken } from '../middleware/auth.js';
|
|
import fs from 'fs';
|
|
import path from 'path';
|
|
|
|
const router = express.Router();
|
|
|
|
// Export all models as ZIP
|
|
router.get('/all', authenticateToken, (req, res) => {
|
|
// Get all user's models
|
|
db.all(
|
|
'SELECT * FROM models WHERE user_id = ?',
|
|
[req.user.id],
|
|
(err, models) => {
|
|
if (err) {
|
|
return res.status(500).json({ error: err.message });
|
|
}
|
|
|
|
if (models.length === 0) {
|
|
return res.status(404).json({ error: 'No models to export' });
|
|
}
|
|
|
|
// Set headers for ZIP download
|
|
res.setHeader('Content-Type', 'application/zip');
|
|
res.setHeader('Content-Disposition', `attachment; filename="makerstash-export-${Date.now()}.zip"`);
|
|
|
|
// Create ZIP archive
|
|
const archive = archiver('zip', {
|
|
zlib: { level: 9 }
|
|
});
|
|
|
|
archive.on('error', (err) => {
|
|
res.status(500).send({ error: err.message });
|
|
});
|
|
|
|
// Pipe archive to response
|
|
archive.pipe(res);
|
|
|
|
// Add models to archive
|
|
models.forEach(model => {
|
|
if (model.file_path && fs.existsSync(model.file_path)) {
|
|
const fileName = `${model.name.replace(/[^a-z0-9]/gi, '_')}${model.file_type}`;
|
|
archive.file(model.file_path, { name: `models/${fileName}` });
|
|
}
|
|
|
|
if (model.preview_image && fs.existsSync(model.preview_image)) {
|
|
const thumbName = `${model.name.replace(/[^a-z0-9]/gi, '_')}_thumb.png`;
|
|
archive.file(model.preview_image, { name: `thumbnails/${thumbName}` });
|
|
}
|
|
});
|
|
|
|
// Add metadata JSON
|
|
const metadata = models.map(m => ({
|
|
name: m.name,
|
|
description: m.description,
|
|
creator: m.creator,
|
|
source_url: m.source_url,
|
|
file_name: m.file_name,
|
|
file_type: m.file_type,
|
|
notes: m.notes,
|
|
is_supported: m.is_supported,
|
|
created_at: m.created_at
|
|
}));
|
|
archive.append(JSON.stringify(metadata, null, 2), { name: 'metadata.json' });
|
|
|
|
// Finalize archive
|
|
archive.finalize();
|
|
}
|
|
);
|
|
});
|
|
|
|
// Export specific models as ZIP
|
|
router.post('/models', authenticateToken, (req, res) => {
|
|
const { modelIds } = req.body;
|
|
|
|
if (!modelIds || !Array.isArray(modelIds) || modelIds.length === 0) {
|
|
return res.status(400).json({ error: 'Model IDs array is required' });
|
|
}
|
|
|
|
const placeholders = modelIds.map(() => '?').join(',');
|
|
db.all(
|
|
`SELECT * FROM models WHERE id IN (${placeholders}) AND user_id = ?`,
|
|
[...modelIds, req.user.id],
|
|
(err, models) => {
|
|
if (err) {
|
|
return res.status(500).json({ error: err.message });
|
|
}
|
|
|
|
if (models.length === 0) {
|
|
return res.status(404).json({ error: 'No models found' });
|
|
}
|
|
|
|
// Set headers for ZIP download
|
|
res.setHeader('Content-Type', 'application/zip');
|
|
res.setHeader('Content-Disposition', `attachment; filename="makerstash-models-${Date.now()}.zip"`);
|
|
|
|
// Create ZIP archive
|
|
const archive = archiver('zip', {
|
|
zlib: { level: 9 }
|
|
});
|
|
|
|
archive.on('error', (err) => {
|
|
res.status(500).send({ error: err.message });
|
|
});
|
|
|
|
// Pipe archive to response
|
|
archive.pipe(res);
|
|
|
|
// Add models to archive
|
|
models.forEach(model => {
|
|
if (model.file_path && fs.existsSync(model.file_path)) {
|
|
const fileName = `${model.name.replace(/[^a-z0-9]/gi, '_')}${model.file_type}`;
|
|
archive.file(model.file_path, { name: fileName });
|
|
}
|
|
});
|
|
|
|
// Finalize archive
|
|
archive.finalize();
|
|
}
|
|
);
|
|
});
|
|
|
|
export default router;
|