backend_adaptive_learning/middlewares/uploadExercise.js

126 lines
3.1 KiB
JavaScript
Raw Normal View History

import multer from "multer";
import crypto from "crypto";
import path from "path";
import fs from "fs";
import response from "../response.js";
const memoryStorage = multer.memoryStorage();
const fileFilter = (req, file, cb) => {
const ext = path.extname(file.originalname).toLowerCase();
if (file.fieldname.startsWith("AUDIO")) {
if (ext === ".mp3") {
cb(null, true);
} else {
cb(
new Error("Invalid file type, only .mp3 files are allowed for audio!"),
false
);
}
} else if (file.fieldname.startsWith("IMAGE")) {
if (ext === ".jpg" || ext === ".jpeg" || ext === ".png") {
cb(null, true);
} else {
cb(
new Error(
"Invalid file type, only .jpg, .jpeg, and .png files are allowed for image!"
),
false
);
}
} else {
cb(new Error("Invalid file type!"), false);
}
};
const upload = multer({
storage: memoryStorage,
fileFilter,
limits: {
2024-09-13 13:03:35 +00:00
fileSize: 100 * 1024 * 1024,
},
}).any();
const handleUpload = (req, res, next) => {
upload(req, res, (err) => {
if (err) {
return response(400, null, err.message, res);
}
const files = req.files || [];
req.filesToSave = {};
let validFiles = true;
let errorMessages = [];
files.forEach((file) => {
if (file.fieldname.startsWith("AUDIO")) {
if (file.size > 10 * 1024 * 1024) {
validFiles = false;
errorMessages.push(`Audio file exceeds the size limit of 10MB`);
} else {
req.filesToSave[file.fieldname] = file;
}
} else if (file.fieldname.startsWith("IMAGE")) {
if (file.size > 5 * 1024 * 1024) {
validFiles = false;
errorMessages.push(`Image file exceeds the size limit of 5MB`);
} else {
req.filesToSave[file.fieldname] = file;
}
}
});
if (validFiles) {
next();
} else {
clearFileBuffers(req.filesToSave);
return response(400, null, errorMessages.join("; "), res);
}
});
};
export const clearFileBuffers = (files) => {
for (const file of Object.values(files)) {
if (file && file.buffer) {
file.buffer = null;
}
}
};
2024-09-13 13:03:35 +00:00
export const generateHash = (levelId, filename, bufferLength) => {
return crypto
.createHash("md5")
2024-09-13 13:03:35 +00:00
.update(levelId + filename + bufferLength)
.digest("hex");
};
2024-09-13 13:03:35 +00:00
export const saveFileToDisk = (file, type, levelId, exerciseId) => {
const ext = path.extname(file.originalname);
2024-09-13 13:03:35 +00:00
const hash = generateHash(levelId, file.originalname, file.buffer.length);
const filename = `${type}-${exerciseId}-${hash}${ext}`;
let folderPath;
switch (type) {
case "AUDIO":
2024-11-21 01:14:50 +00:00
folderPath = path.join(process.cwd(), "media/uploads/exercise/audio");
break;
case "IMAGE":
2024-11-21 01:14:50 +00:00
folderPath = path.join(process.cwd(), "media/uploads/exercise/image");
break;
default:
2024-11-21 01:14:50 +00:00
folderPath = path.join(process.cwd(), "media/uploads/exercise");
}
if (!fs.existsSync(folderPath)) {
fs.mkdirSync(folderPath, { recursive: true });
}
const filepath = path.join(folderPath, filename);
fs.writeFileSync(filepath, file.buffer);
return filename;
};
export default handleUpload;