Fix healthchecks: install curl in backend and frontend images
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
const express = require('express');
|
||||
const authenticate = require('../middleware/auth');
|
||||
const multer = require('multer');
|
||||
const { parseString } = require('dxf-parser');
|
||||
const router = express.Router();
|
||||
const upload = multer({ storage: multer.memoryStorage(), limits: { fileSize: 10 * 1024 * 1024 } });
|
||||
|
||||
// Upload DXF file -> parse and return JSON representation (Fabric.js compatible)
|
||||
router.post('/import', authenticate, upload.single('file'), async (req, res) => {
|
||||
try {
|
||||
if (!req.file) {
|
||||
return res.status(400).json({ error: 'No file uploaded' });
|
||||
}
|
||||
const dxfContent = req.file.buffer.toString('utf-8');
|
||||
console.log('DXF file size:', dxfContent.length);
|
||||
const parsed = parseString(dxfContent);
|
||||
// Convert parsed entities to Fabric.js objects (simplified)
|
||||
const fabricObjects = [];
|
||||
if (parsed && parsed.entities) {
|
||||
parsed.entities.forEach(entity => {
|
||||
const type = entity.type;
|
||||
if (type === 'LINE') {
|
||||
fabricObjects.push({
|
||||
type: 'line',
|
||||
x1: entity.start.x, y1: entity.start.y,
|
||||
x2: entity.end.x, y2: entity.end.y,
|
||||
stroke: '#000', strokeWidth: 1,
|
||||
});
|
||||
} else if (type === 'CIRCLE') {
|
||||
fabricObjects.push({
|
||||
type: 'circle',
|
||||
left: entity.center.x - entity.radius,
|
||||
top: entity.center.y - entity.radius,
|
||||
radius: entity.radius,
|
||||
fill: 'transparent', stroke: '#000',
|
||||
});
|
||||
} else if (type === 'ARC') {
|
||||
// simplified arc handling
|
||||
fabricObjects.push({
|
||||
type: 'path',
|
||||
path: `M ${entity.center.x} ${entity.center.y}`, // placeholder
|
||||
stroke: '#000', strokeWidth: 1,
|
||||
});
|
||||
} else if (type === 'POLYLINE' || type === 'LWPOLYLINE') {
|
||||
// convert vertices to polygon
|
||||
if (entity.vertices && entity.vertices.length >= 2) {
|
||||
const points = entity.vertices.map(v => ({ x: v.x, y: v.y }));
|
||||
fabricObjects.push({
|
||||
type: 'polygon',
|
||||
points,
|
||||
stroke: '#000', strokeWidth: 1, fill: 'transparent',
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
res.json({ objects: fabricObjects });
|
||||
} catch (err) {
|
||||
console.error('DXF import error:', err);
|
||||
res.status(500).json({ error: 'Failed to parse DXF file: ' + err.message });
|
||||
}
|
||||
});
|
||||
|
||||
// Export canvas JSON to DXF string
|
||||
router.post('/export', authenticate, (req, res) => {
|
||||
try {
|
||||
const { objects } = req.body;
|
||||
if (!objects || !Array.isArray(objects)) {
|
||||
return res.status(400).json({ error: 'Invalid objects array' });
|
||||
}
|
||||
// Build DXF content
|
||||
let dxf = '0\nSECTION\n2\nHEADER\n0\nENDSEC\n';
|
||||
dxf += '0\nSECTION\n2\nTABLES\n0\nENDSEC\n';
|
||||
dxf += '0\nSECTION\n2\nBLOCKS\n0\nENDSEC\n';
|
||||
dxf += '0\nSECTION\n2\nENTITIES\n';
|
||||
objects.forEach(obj => {
|
||||
if (obj.type === 'line') {
|
||||
dxf += `0\nLINE\n8\n0\n10\n${obj.x1}\n20\n${obj.y1}\n11\n${obj.x2}\n21\n${obj.y2}\n`;
|
||||
} else if (obj.type === 'circle') {
|
||||
const cx = obj.left + obj.radius;
|
||||
const cy = obj.top + obj.radius;
|
||||
dxf += `0\nCIRCLE\n8\n0\n10\n${cx}\n20\n${cy}\n40\n${obj.radius}\n`;
|
||||
} else if (obj.type === 'polygon') {
|
||||
// LWPOLYLINE
|
||||
dxf += `0\nLWPOLYLINE\n8\n0\n90\n${obj.points.length}\n`;
|
||||
obj.points.forEach((pt, i) => {
|
||||
dxf += `10\n${pt.x}\n20\n${pt.y}\n`;
|
||||
});
|
||||
}
|
||||
});
|
||||
dxf += '0\nENDSEC\n0\nEOF\n';
|
||||
res.setHeader('Content-Type', 'application/dxf');
|
||||
res.setHeader('Content-Disposition', 'attachment; filename=drawing.dxf');
|
||||
res.send(dxf);
|
||||
} catch (err) {
|
||||
console.error('DXF export error:', err);
|
||||
res.status(500).json({ error: 'Export failed' });
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
Reference in New Issue
Block a user