makerstash/server/routes/export.js

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;