backend_adaptive_learning/controllers/level.js

398 lines
9.9 KiB
JavaScript

import response from "../response.js";
import models from "../models/index.js";
import {
clearFileBuffers,
saveFileToDisk,
generateHash,
} from "../middlewares/uploadLevel.js";
import fs from "fs";
import path from "path";
import crypto from "crypto";
export const getAllLevels = async (req, res) => {
try {
const levels = await models.Level.findAll();
response(200, levels, "Success", res);
} catch (error) {
console.log(error);
response(500, null, "Error retrieving levels data!", res);
}
};
export const getAllLevelById = async (req, res) => {
try {
const { id } = req.params;
const level = await models.Level.findByPk(id);
if (!level) {
return response(404, null, "Level not found", res);
}
response(200, level, "Success", res);
} catch (error) {
console.log(error);
res.status(500).json({ message: "Internal Server Error" });
}
};
export const getLevels = async (req, res) => {
try {
const levels = await models.Level.findAll({
attributes: {
exclude: ["route1", "route2", "route3", "route4"],
},
});
response(200, levels, "Success", res);
} catch (error) {
console.log(error);
res.status(500).json({ message: "Internal Server Error" });
}
};
export const getLevelById = async (req, res) => {
try {
const { id } = req.params;
const level = await models.Level.findByPk(id, {
attributes: {
exclude: ["route1", "route2", "route3", "route4"],
},
});
if (!level) {
return response(404, null, "Level not found", res);
}
response(200, level, "Success", res);
} catch (error) {
console.log(error);
res.status(500).json({ message: "Internal Server Error" });
}
};
export const createLevel = async (req, res) => {
const { title, subject_id, topic_id, is_pretest, content, youtube } =
req.body;
// Files to be saved if everything else is okay
const { video, audio, image } = req.filesToSave || {};
// Validate title
if (!title) {
clearFileBuffers({ video, audio, image });
return response(400, null, "Title is required", res);
}
// Validate subject_id
if (!subject_id) {
clearFileBuffers({ video, audio, image });
return response(400, null, "Subject ID is required", res);
}
// Validate topic_id
if (!topic_id) {
clearFileBuffers({ video, audio, image });
return response(400, null, "Topic ID is required", res);
}
try {
// Check if the title already exists under the same topic_id
const existingLevel = await models.Level.findOne({
where: { title, topic_id },
});
if (existingLevel) {
clearFileBuffers({ video, audio, image });
return response(
409,
null,
"A level with this title already exists under this topic",
res
); // 409 Conflict
}
// Save files to disk
const videoFilename = video
? saveFileToDisk(video, "video", title, topic_id, subject_id)
: null;
const audioFilename = audio
? saveFileToDisk(audio, "audio", title, topic_id, subject_id)
: null;
const imageFilename = image
? saveFileToDisk(image, "image", title, topic_id, subject_id)
: null;
// Create the new level
const newLevel = await models.Level.create({
title,
subject_id,
topic_id,
is_pretest: is_pretest || 0,
content,
video: videoFilename,
audio: audioFilename,
image: imageFilename,
youtube,
route1: 0,
route2: 0,
route3: 0,
route4: 0,
});
// Update routes with the newly created level's ID
await newLevel.update({
route1: newLevel.id,
route2: newLevel.id,
route3: newLevel.id,
route4: newLevel.id,
});
response(201, newLevel, "Level created successfully", res);
} catch (error) {
console.log(error);
clearFileBuffers({ video, audio, image });
return response(500, null, "Internal Server Error", res);
}
};
export const updateLevelById = async (req, res) => {
const { id } = req.params;
const { title, subject_id, topic_id, is_pretest, content, youtube } =
req.body;
// Files to be saved if everything else is okay
const { video, audio, image } = req.filesToSave || {};
try {
// Find the existing level by ID
const level = await models.Level.findByPk(id);
if (!level) {
clearFileBuffers({ video, audio, image });
return response(404, null, "Level not found", res);
}
// Check if a level with the same title under the same topic already exists
if (title && topic_id) {
const existingLevel = await models.Level.findOne({
where: {
title,
topic_id,
id: { [models.Sequelize.Op.ne]: id }, // Exclude the current level from the check
},
});
if (existingLevel) {
clearFileBuffers({ video, audio, image });
return response(
409,
null,
"A level with this title already exists under this topic",
res
); // 409 Conflict
}
}
// Update level fields
if (title) level.title = title;
if (subject_id) level.subject_id = subject_id;
if (topic_id) level.topic_id = topic_id;
if (is_pretest !== undefined) level.is_pretest = is_pretest;
if (content) level.content = content;
if (youtube) level.youtube = youtube;
// Handle video update
if (video) {
if (level.video) {
const oldVideoPath = path.join(
"public/uploads/level/video",
level.video
);
if (fs.existsSync(oldVideoPath)) {
fs.unlinkSync(oldVideoPath);
}
}
level.video = saveFileToDisk(
video,
"video",
title || level.title,
topic_id || level.topic_id,
subject_id || level.subject_id
);
}
// Handle audio update
if (audio) {
if (level.audio) {
const oldAudioPath = path.join(
"public/uploads/level/audio",
level.audio
);
if (fs.existsSync(oldAudioPath)) {
fs.unlinkSync(oldAudioPath);
}
}
level.audio = saveFileToDisk(
audio,
"audio",
title || level.title,
topic_id || level.topic_id,
subject_id || level.subject_id
);
}
// Handle image update
if (image) {
if (level.image) {
const oldImagePath = path.join(
"public/uploads/level/image",
level.image
);
if (fs.existsSync(oldImagePath)) {
fs.unlinkSync(oldImagePath);
}
}
level.image = saveFileToDisk(
image,
"image",
title || level.title,
topic_id || level.topic_id,
subject_id || level.subject_id
);
}
await level.save();
response(200, level, "Level updated successfully", res);
} catch (error) {
console.log(error);
clearFileBuffers({ video, audio, image });
return response(500, null, "Internal Server Error", res);
}
};
export const deleteLevelById = async (req, res) => {
const { id } = req.params;
try {
// Find the existing level by ID
const level = await models.Level.findByPk(id);
if (!level) {
return response(404, null, "Level not found", res);
}
// Delete associated files from disk if they exist
const deleteFile = (filePath) => {
if (fs.existsSync(filePath)) {
fs.unlinkSync(filePath);
}
};
if (level.video) {
const videoPath = path.join("public/uploads/level/video", level.video);
deleteFile(videoPath);
}
if (level.audio) {
const audioPath = path.join("public/uploads/level/audio", level.audio);
deleteFile(audioPath);
}
if (level.image) {
const imagePath = path.join("public/uploads/level/image", level.image);
deleteFile(imagePath);
}
// Delete the level from the database
await level.destroy();
response(200, null, "Level deleted successfully", res);
} catch (error) {
console.log(error);
return response(500, null, "Internal Server Error", res);
}
};
export const getRoutes = async (req, res) => {
try {
const levels = await models.Level.findAll({
attributes: {
exclude: [
"subject_id",
"topic_id",
"is_pretest",
"content",
"video",
"audio",
"image",
"youtube",
"ts_entri",
],
},
});
response(200, levels, "Success", res);
} catch (error) {
console.log(error);
res.status(500).json({ message: "Internal Server Error" });
}
};
export const getRouteById = async (req, res) => {
try {
const { id } = req.params;
const level = await models.Level.findByPk(id, {
attributes: {
exclude: [
"subject_id",
"topic_id",
"is_pretest",
"content",
"video",
"audio",
"image",
"youtube",
"ts_entri",
],
},
});
if (!level) {
return response(404, null, "Level not found", res);
}
response(200, level, "Success", res);
} catch (error) {
console.log(error);
res.status(500).json({ message: "Internal Server Error" });
}
};
export const updateRouteById = async (req, res) => {
const { id } = req.params;
const { route1, route2, route3, route4 } = req.body;
try {
// Find the existing level by ID
const level = await models.Level.findByPk(id);
if (!level) {
return response(404, null, "Level not found", res);
}
// Update only the route fields
await level.update({
route1: route1 !== undefined ? route1 : level.route1,
route2: route2 !== undefined ? route2 : level.route2,
route3: route3 !== undefined ? route3 : level.route3,
route4: route4 !== undefined ? route4 : level.route4,
});
response(200, level, "Routes updated successfully", res);
} catch (error) {
console.log(error);
return response(500, null, "Internal Server Error", res);
}
};