const http = require('http'); const fs = require('fs'); const path = require('path'); const PORT = 3000; const DATA_DIR = process.env.DATA_DIR || '.'; const MIME_TYPES = { '.html': 'text/html', '.css': 'text/css', '.js': 'text/javascript', '.json': 'application/json', '.csv': 'text/csv', }; const server = http.createServer((req, res) => { // API endpoint to list available months if (req.url === '/api/months') { fs.readdir(DATA_DIR, (err, files) => { if (err) { res.writeHead(500, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: 'Failed to read directory' })); return; } // Find CSV files matching altcats-YYYY-MM.csv pattern const monthPattern = /^altcats-(\d{4}-\d{2})\.csv$/; const months = files .map(file => { const match = file.match(monthPattern); return match ? match[1] : null; }) .filter(Boolean) .sort(); res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify(months)); }); return; } // Handle URL let filePath = '.' + req.url; if (filePath === './') { filePath = './index.html'; } else if (filePath.endsWith('.csv')) { filePath = path.join(DATA_DIR, path.basename(filePath)); } const extname = path.extname(filePath); const contentType = MIME_TYPES[extname] || 'application/octet-stream'; fs.readFile(filePath, (err, data) => { if (err) { if (err.code === 'ENOENT') { res.writeHead(404); res.end('File not found'); } else { res.writeHead(500); res.end('Server error: ' + err.code); } return; } res.writeHead(200, { 'Content-Type': contentType }); res.end(data); }); }); server.listen(PORT, () => { console.log(`Server running at http://localhost:${PORT}/`); console.log(`Visualizing spending data with ECharts...`); });