Initial commit of my folder
This commit is contained in:
188
backend/index.js
Normal file
188
backend/index.js
Normal file
@ -0,0 +1,188 @@
|
||||
const express = require('express');
|
||||
const { Client } = require('node-osc');
|
||||
const http = require('http');
|
||||
const { Server } = require('socket.io');
|
||||
|
||||
const { exec } = require('child_process');
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const multer = require('multer');
|
||||
|
||||
const app = express();
|
||||
app.use(express.json()); // Allow parsing JSON body
|
||||
app.use(express.static(path.join(__dirname, '../frontend/dist')));
|
||||
|
||||
const si = require('systeminformation');
|
||||
|
||||
// System Monitoring API
|
||||
app.get('/system/stats', async (req, res) => {
|
||||
try {
|
||||
const cpu = await si.currentLoad();
|
||||
const mem = await si.mem();
|
||||
const temp = await si.cpuTemperature();
|
||||
res.json({
|
||||
cpu: cpu.currentLoad.toFixed(1),
|
||||
mem: {
|
||||
total: (mem.total / 1024 / 1024).toFixed(0),
|
||||
used: (mem.used / 1024 / 1024).toFixed(0),
|
||||
free: (mem.free / 1024 / 1024).toFixed(0)
|
||||
},
|
||||
temp: temp.main
|
||||
});
|
||||
} catch (err) {
|
||||
res.status(500).json({ error: 'Failed to fetch system stats' });
|
||||
}
|
||||
});
|
||||
|
||||
// Media Directory Configuration
|
||||
const MEDIA_DIR = process.env.MEDIA_DIR || '/home/pi/media';
|
||||
if (!fs.existsSync(MEDIA_DIR)) {
|
||||
fs.mkdirSync(MEDIA_DIR, { recursive: true });
|
||||
}
|
||||
|
||||
// Multer Setup for File Uploads
|
||||
const storage = multer.diskStorage({
|
||||
destination: (req, file, cb) => {
|
||||
cb(null, MEDIA_DIR);
|
||||
},
|
||||
filename: (req, file, cb) => {
|
||||
cb(null, file.originalname);
|
||||
}
|
||||
});
|
||||
const upload = multer({ storage: storage });
|
||||
|
||||
// Media API Endpoints
|
||||
app.get('/media', (req, res) => {
|
||||
fs.readdir(MEDIA_DIR, (err, files) => {
|
||||
if (err) return res.status(500).json({ error: 'Failed to read media directory' });
|
||||
res.json({ files });
|
||||
});
|
||||
});
|
||||
|
||||
app.post('/media/upload', upload.single('file'), (req, res) => {
|
||||
if (!req.file) return res.status(400).json({ error: 'No file uploaded' });
|
||||
res.json({ status: 'uploaded', file: req.file.filename });
|
||||
});
|
||||
|
||||
app.delete('/media/:filename', (req, res) => {
|
||||
const filePath = path.join(MEDIA_DIR, req.params.filename);
|
||||
fs.unlink(filePath, (err) => {
|
||||
if (err) return res.status(500).json({ error: 'Failed to delete file' });
|
||||
res.json({ status: 'deleted' });
|
||||
});
|
||||
});
|
||||
|
||||
app.post('/media/assign', (req, res) => {
|
||||
const { surfaceIndex, filename } = req.body;
|
||||
oscClient.send('/ofxPiMapper/source/set', surfaceIndex, filename);
|
||||
res.json({ status: 'assigned', surfaceIndex, filename });
|
||||
});
|
||||
|
||||
// Networking API
|
||||
app.post('/network/ap', (req, res) => {
|
||||
exec('bash scripts/switch-to-ap.sh', (err, stdout) => {
|
||||
if (err) return res.status(500).json({ error: err.message });
|
||||
res.json({ status: 'switching to ap', output: stdout });
|
||||
});
|
||||
});
|
||||
|
||||
app.post('/network/client', (req, res) => {
|
||||
exec('bash scripts/switch-to-client.sh', (err, stdout) => {
|
||||
if (err) return res.status(500).json({ error: err.message });
|
||||
res.json({ status: 'switching to client', output: stdout });
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/network/scan', (req, res) => {
|
||||
// Mock scan for WiFi networks
|
||||
res.json({
|
||||
networks: [
|
||||
{ ssid: 'Venue-WiFi', strength: -60, encrypted: true },
|
||||
{ ssid: 'Artist-Hotspot', strength: -45, encrypted: true },
|
||||
{ ssid: 'Free-Internet-Coffee', strength: -80, encrypted: false }
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
// Process management for ofxPiMapper
|
||||
app.post('/mapper/start', (req, res) => {
|
||||
exec('ofxPiMapper -f', (error) => {
|
||||
if (error) {
|
||||
console.error(`Error starting ofxPiMapper: ${error.message}`);
|
||||
return res.status(500).json({ error: 'Failed to start mapper' });
|
||||
}
|
||||
});
|
||||
res.json({ status: 'starting' });
|
||||
});
|
||||
|
||||
app.post('/mapper/stop', (req, res) => {
|
||||
exec('pkill ofxPiMapper', (error) => {
|
||||
if (error) {
|
||||
console.error(`Error stopping ofxPiMapper: ${error.message}`);
|
||||
return res.status(500).json({ error: 'Failed to stop mapper' });
|
||||
}
|
||||
res.json({ status: 'stopped' });
|
||||
});
|
||||
});
|
||||
|
||||
app.post('/mapper/restart', (req, res) => {
|
||||
exec('pkill ofxPiMapper', () => {
|
||||
setTimeout(() => {
|
||||
exec('ofxPiMapper -f');
|
||||
res.json({ status: 'restarting' });
|
||||
}, 1000);
|
||||
});
|
||||
});
|
||||
|
||||
const server = http.createServer(app);
|
||||
const io = new Server(server, {
|
||||
cors: {
|
||||
origin: "*",
|
||||
}
|
||||
});
|
||||
|
||||
// OSC Client for ofxPiMapper
|
||||
const oscClient = new Client('127.0.0.1', 9999);
|
||||
|
||||
io.on('connection', (socket) => {
|
||||
console.log('Client connected:', socket.id);
|
||||
|
||||
// Vertex Movement: Sends (surfaceIndex, vertexIndex, x, y)
|
||||
socket.on('vertex:move', (data) => {
|
||||
const { surfaceIndex, vertexIndex, x, y } = data;
|
||||
oscClient.send('/ofxPiMapper/vertex/move', surfaceIndex, vertexIndex, x, y);
|
||||
});
|
||||
|
||||
// Surface Selection
|
||||
socket.on('surface:select', (data) => {
|
||||
const { surfaceIndex } = data;
|
||||
oscClient.send('/ofxPiMapper/surface/select', surfaceIndex);
|
||||
});
|
||||
|
||||
// Add Surface (Quad or Triangle)
|
||||
socket.on('surface:add', (data) => {
|
||||
const { type } = data; // 'quad' or 'triangle'
|
||||
oscClient.send('/ofxPiMapper/surface/add', type);
|
||||
});
|
||||
|
||||
// Delete Surface
|
||||
socket.on('surface:delete', (data) => {
|
||||
const { surfaceIndex } = data;
|
||||
oscClient.send('/ofxPiMapper/surface/delete', surfaceIndex);
|
||||
});
|
||||
|
||||
socket.on('disconnect', () => {
|
||||
console.log('Client disconnected:', socket.id);
|
||||
});
|
||||
});
|
||||
|
||||
const PORT = process.env.PORT || 3000;
|
||||
|
||||
app.get('/', (req, res) => {
|
||||
res.send('MPVJ Backend is running.');
|
||||
});
|
||||
|
||||
server.listen(PORT, () => {
|
||||
console.log(`Backend listening on port ${PORT}`);
|
||||
});
|
||||
Reference in New Issue
Block a user