398 lines
9.9 KiB
JavaScript
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);
|
||
|
|
}
|
||
|
|
};
|