import path from 'path'; import { promises as fs } from 'fs'; import express from 'express'; import { createUploadMiddleware, processFiles, listFiles, deleteFile } from './fileHandlers'; const router = express.Router(); // Dynamic routing to handle different content types based on the subfolder router.use('/:subfolder', (req, res, next) => { const { subfolder } = req.params; req.subfolder = subfolder; // Pass the subfolder as part of the request for later use next(); }); // POST: Upload files to a specific subfolder router.post('/:subfolder', createUploadMiddleware(req.subfolder).array('image'), (req, res) => { processFiles(req, res, req.subfolder); }); // GET: List files from a specific subfolder router.get('/:subfolder', (req, res) => { listFiles(req, res, req.subfolder); }); // DELETE: Delete a specific file from a subfolder router.delete('/:subfolder', (req, res) => { deleteFile(req, res, req.subfolder); }); export default router; //handling file uploads import multer from 'multer'; import sharp from 'sharp'; // Generalized Multer configuration export function createUploadMiddleware(folder) { const storage = multer.diskStorage({ destination: (req, file, cb) => { const uploadPath = path.join(process.cwd(), 'public/content', folder); if (!fs.existsSync(uploadPath)) { fs.mkdirSync(uploadPath, { recursive: true }); } cb(null, uploadPath); }, filename: (req, file, cb) => { const prefix = req.body.prefix || path.parse(file.originalname).name; cb(null, `${prefix}${path.extname(file.originalname)}`); } }); return multer({ storage: storage }); } async function processFiles(req, res, folder) { if (!req.files || req.files.length === 0) { return res.status(400).json({ error: 'No files uploaded.' }); } const uploadDir = path.join(process.cwd(), 'public/content', folder); const thumbDir = path.join(uploadDir, "thumb"); if (!fs.existsSync(thumbDir)) { fs.mkdirSync(thumbDir, { recursive: true }); } try { const processedFiles = await Promise.all(req.files.map(async (file) => { const originalPath = path.join(uploadDir, file.filename); const thumbPath = path.join(thumbDir, file.filename); await sharp(file.path) .resize({ width: 1920, fit: sharp.fit.inside, withoutEnlargement: true }) .jpeg({ quality: 80 }) .toFile(originalPath); await sharp(file.path) .resize(320, 320, { fit: sharp.fit.inside, withoutEnlargement: true }) .toFile(thumbPath); fs.unlinkSync(file.path); // Remove temp file return { originalUrl: `/content/${folder}/${file.filename}`, thumbUrl: `/content/${folder}/thumb/${file.filename}` }; })); res.json(processedFiles); } catch (error) { console.error('Error processing files:', error); res.status(500).json({ error: 'Error processing files.' }); } } // List files in a directory async function listFiles(req, res, folder) { const directory = path.join(process.cwd(), 'public/content', folder); try { const files = await fs.promises.readdir(directory); const imageUrls = files.map(file => `${req.protocol}://${req.get('host')}/content/${folder}/${file}`); res.json({ imageUrls }); } catch (err) { console.error('Error reading uploads directory:', err); res.status(500).json({ error: 'Internal Server Error' }); } } // Delete a file async function deleteFile(req, res, folder) { const filename = req.query.file; if (!filename) { return res.status(400).send('Filename is required.'); } try { const filePath = path.join(process.cwd(), 'public/content', folder, filename); await fs.unlink(filePath); res.status(200).send('File deleted successfully.'); } catch (error) { res.status(500).send('Failed to delete the file.'); } }