refactor (subject): Changing upload file logic
This commit is contained in:
parent
ea0d3f85d7
commit
935232a01d
|
|
@ -1,74 +0,0 @@
|
|||
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 (ext === ".png" || ext === ".jpg" || ext === ".jpeg") {
|
||||
cb(null, true);
|
||||
} else {
|
||||
cb(
|
||||
new Error(
|
||||
"Invalid file type, only .png, .jpg, and .jpeg files are allowed!"
|
||||
),
|
||||
false
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const upload = multer({
|
||||
storage: memoryStorage,
|
||||
fileFilter,
|
||||
limits: { fileSize: 5 * 1024 * 1024 }, // Limit file size to 5MB
|
||||
}).fields([
|
||||
{ name: "icon", maxCount: 1 },
|
||||
{ name: "thumbnail", maxCount: 1 },
|
||||
]);
|
||||
|
||||
const saveFileToDisk = (file) => {
|
||||
const md5sum = crypto
|
||||
.createHash("md5")
|
||||
.update(Date.now().toString())
|
||||
.digest("hex");
|
||||
const ext = path.extname(file.originalname);
|
||||
const filename = `${md5sum}${ext}`;
|
||||
const filepath = path.join("public/uploads", filename);
|
||||
fs.writeFileSync(filepath, file.buffer);
|
||||
return filename;
|
||||
};
|
||||
|
||||
const handleUpload = (req, res, next) => {
|
||||
upload(req, res, (err) => {
|
||||
if (err) {
|
||||
return response(400, null, err.message, res);
|
||||
}
|
||||
|
||||
const files = req.files;
|
||||
const icon = files?.icon ? files.icon[0] : null;
|
||||
const thumbnail = files?.thumbnail ? files.thumbnail[0] : null;
|
||||
|
||||
try {
|
||||
// Validate icon and thumbnail before saving
|
||||
if (icon && thumbnail) {
|
||||
const iconFilename = saveFileToDisk(icon);
|
||||
const thumbnailFilename = saveFileToDisk(thumbnail);
|
||||
|
||||
// Update the filenames in the request object for further processing
|
||||
req.body.icon = iconFilename;
|
||||
req.body.thumbnail = thumbnailFilename;
|
||||
|
||||
next();
|
||||
} else {
|
||||
return response(400, null, "Both icon and thumbnail are required", res);
|
||||
}
|
||||
} catch (error) {
|
||||
return response(500, null, "Internal Server Error", res);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export default handleUpload;
|
||||
101
middlewares/uploadSubject.js
Normal file
101
middlewares/uploadSubject.js
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
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 (ext === ".png" || ext === ".jpg" || ext === ".jpeg") {
|
||||
cb(null, true);
|
||||
} else {
|
||||
cb(
|
||||
new Error(
|
||||
"Invalid file type, only .png, .jpg, and .jpeg files are allowed!"
|
||||
),
|
||||
false
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const upload = multer({
|
||||
storage: memoryStorage,
|
||||
fileFilter,
|
||||
limits: { fileSize: 10 * 1024 * 1024 }, // Limit file size to 5MB
|
||||
}).fields([
|
||||
{ name: "icon", maxCount: 1 },
|
||||
{ name: "thumbnail", maxCount: 1 },
|
||||
]);
|
||||
|
||||
const handleUpload = (req, res, next) => {
|
||||
upload(req, res, (err) => {
|
||||
if (err) {
|
||||
return response(400, null, err.message, res);
|
||||
}
|
||||
|
||||
const files = req.files;
|
||||
const icon = files?.icon ? files.icon[0] : null;
|
||||
const thumbnail = files?.thumbnail ? files.thumbnail[0] : null;
|
||||
|
||||
try {
|
||||
let validFiles = true;
|
||||
let errorMessages = [];
|
||||
|
||||
// Validate file sizes
|
||||
if (icon && icon.size > 5 * 1024 * 1024) {
|
||||
validFiles = false;
|
||||
icon.buffer = null;
|
||||
errorMessages.push("Icon file exceeds the size limit of 5MB");
|
||||
}
|
||||
|
||||
if (thumbnail && thumbnail.size > 5 * 1024 * 1024) {
|
||||
validFiles = false;
|
||||
thumbnail.buffer = null;
|
||||
errorMessages.push("Thumbnail file exceeds the size limit of 5MB");
|
||||
}
|
||||
|
||||
if (validFiles) {
|
||||
req.filesToSave = { icon, thumbnail };
|
||||
next();
|
||||
} else {
|
||||
clearFileBuffers({ icon, thumbnail });
|
||||
return response(400, null, errorMessages.join(", "), res);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
clearFileBuffers({ icon, thumbnail });
|
||||
return response(500, null, "Internal Server Error", res);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const clearFileBuffers = (files) => {
|
||||
for (const file of Object.values(files)) {
|
||||
if (file && file.buffer) {
|
||||
file.buffer = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const saveFileToDisk = (file, fieldName, subjectName) => {
|
||||
const ext = path.extname(file.originalname);
|
||||
const hash = crypto
|
||||
.createHash("md5")
|
||||
.update(subjectName + file.originalname + file.buffer.length.toString())
|
||||
.digest("hex")
|
||||
.slice(0, 8);
|
||||
const filename = `${fieldName}-${hash}${ext}`;
|
||||
const folderPath = path.join("public/uploads/subject");
|
||||
|
||||
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;
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
BIN
public/uploads/subject/Menulis-thumbnail-448b4bd5.jpeg
Normal file
BIN
public/uploads/subject/Menulis-thumbnail-448b4bd5.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.7 KiB |
|
|
@ -1,5 +1,5 @@
|
|||
import express from "express";
|
||||
import handleUpload from '../middlewares/upload.js';
|
||||
import handleUpload from '../middlewares/uploadSubject.js';
|
||||
import { getSubjects, getSubjectById, createSubject, updateSubjectById, deleteSubjectById } from "../controllers/subject.js";
|
||||
import { verifyLoginUser, adminOnly, teacherOnly } from "../middlewares/authUser.js";
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user