// server.js // Usage: // 1) npm init -y // 2) npm install express multer better-sqlite3 // 3) node server.js // // Open: http://localhost:3000 const express = require('express'); const multer = require('multer'); const fs = require('fs'); const path = require('path'); const Database = require('better-sqlite3'); const PORT = process.env.PORT || 3000; const UPLOAD_DIR = path.join(__dirname, 'uploads'); if (!fs.existsSync(UPLOAD_DIR)) fs.mkdirSync(UPLOAD_DIR, { recursive: true }); // Multer storage (safe filename) const storage = multer.diskStorage({ destination: (req, file, cb) => cb(null, UPLOAD_DIR), filename: (req, file, cb) => { const ext = path.extname(file.originalname).toLowerCase(); const safe = Date.now() + '-' + Math.round(Math.random()*1e9) + ext; cb(null, safe); } }); const upload = multer({ storage, limits: { fileSize: 10 * 1024 * 1024 }, // 10 MB max (change if needed) fileFilter: (req, file, cb) => { // accept images only if (file.mimetype && file.mimetype.startsWith('image/')) cb(null, true); else cb(new Error('Seuls les fichiers image sont autorisés')); } }); const app = express(); // Init DB (SQLite) const db = new Database(path.join(__dirname, 'gallery.db')); db.pragma('journal_mode = WAL'); db.prepare(` CREATE TABLE IF NOT EXISTS photos ( id INTEGER PRIMARY KEY AUTOINCREMENT, given_name TEXT, filename TEXT NOT NULL, original_name TEXT, mime TEXT, size INTEGER, created_at TEXT NOT NULL ) `).run(); // Serve uploads statically app.use('/uploads', express.static(UPLOAD_DIR, { extensions: ['jpg','png','jpeg','gif','webp'] })); // Serve the single-page HTML app.get('/', (req, res) => { res.type('html').send(`