From 6077dfd7167928d9a94a43e4c327d35c3c967d57 Mon Sep 17 00:00:00 2001 From: Kerboul Date: Thu, 3 Apr 2025 11:03:10 +0200 Subject: [PATCH] =?UTF-8?q?Refactor=20la=20gestion=20des=20mesures=20en=20?= =?UTF-8?q?rempla=C3=A7ant=20le=20gestionnaire=20de=20mesures=20par=20le?= =?UTF-8?q?=20gestionnaire=20de=20stockage.=20Ajouter=20des=20fonctions=20?= =?UTF-8?q?pour=20g=C3=A9rer=20les=20images=20et=20les=20chemins=20des=20m?= =?UTF-8?q?esures.=20Am=C3=A9liorer=20la=20gestion=20des=20erreurs=20et=20?= =?UTF-8?q?nettoyer=20le=20code.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- routes/measurementRoutes.js | 84 +++++++------------- routes/uploadRoutes.js | 18 ++++- routes/videoRoutes.js | 7 +- src/data/storage_manager.js | 70 +++++++++++++++-- src/database/database_manager.js | 14 ++++ src/measure/measureManager.js | 130 ------------------------------- 6 files changed, 124 insertions(+), 199 deletions(-) delete mode 100644 src/measure/measureManager.js diff --git a/routes/measurementRoutes.js b/routes/measurementRoutes.js index 2b21911..eb016a6 100644 --- a/routes/measurementRoutes.js +++ b/routes/measurementRoutes.js @@ -1,86 +1,54 @@ const express = require('express'); const router = express.Router(); -const db = require('../db'); -const measureManager = require('../src/measure/measureManager'); -const serverError = require('../utils/serverError'); +const database_manager = require('../src/database/database_manager'); router.get('/measurements', (req, res) => { - const query = 'SELECT * FROM public.measurements'; - db.query(query, (err, results) => { - if (err) { - serverError.sendError('Erreur lors de la récupération des mesures:', res, err, 500); - } - res.json(results.rows); - }); + const measurements = database_manager.measurement.get_all_measurements(); + if (!measurements) { + return res.status(404).json({ error: 'No measurements found' }); + } + res.json(measurements); }); router.get('/measurements/:id', (req, res) => { - const measurementId = req.params.id; - if (!measurementId || isNaN(measurementId)) { - return res.status(400).json({ error: 'Invalid measurement ID' }); + const measurement = database_manager.measurement.get_measurement_by_id(req.params.id); + if (!measurement) { + return res.status(404).json({ error: 'Measurement not found' }); } - const query = 'SELECT * FROM public.measurements WHERE id = $1'; - db.query(query, [measurementId], (err, results) => { - if (err) { - serverError.sendError('Erreur lors de la récupération de la mesure:', res, err, 500); - } - res.json(results.rows); - }); + res.json(measurement); }); router.get('/measurements/:projectId/:orderId', async (req, res) => { - const projectId = req.params.projectId; - const orderId = req.params.orderId; - if (!projectId || isNaN(projectId) || !orderId || isNaN(orderId)) { - return res.status(400).json({ error: 'Invalid project ID or order ID' }); - } - try { - const measurement = await measureManager.getMeasurement(projectId, orderId); - res.json(measurement); - } catch (error) { - serverError.sendError('Error getting measurement:', res, error, 500); + const measurement = await database_manager.measurement.get_measurement_by_project_and_order_id(req.params.projectId, req.params.orderId); + if (!measurement) { + return res.status(404).json({ error: 'Measurement not found' }); } + res.json(measurement); }); router.post('/measurements', (req, res) => { - const { project_id, timestamp, image_path, temperature, humidity } = req.body; - if (!project_id || !timestamp || !image_path || !temperature || !humidity) { + const { projectId, timestamp, imagePath, temperature, humidity, orderId } = req.body; + if (!projectId || !timestamp || !imagePath || !temperature || !humidity || !orderId) { return res.status(400).json({ error: 'All fields are required' }); } - const query = 'INSERT INTO public.measurements (project_id, timestamp, image_path, temperature, humidity) VALUES ($1, $2, $3, $4, $5) RETURNING id'; - db.query(query, [project_id, timestamp, image_path, temperature, humidity], (err, results) => { - if (err) { - serverError.sendError('Erreur lors de l\'ajout de la mesure:', res, err, 500); - } - res.status(201).json({ message: 'Mesure ajoutée avec succès', id: results.rows[0].id }); - }); + const measurement = database_manager.measurement.add_measurement(projectId, timestamp, imagePath, temperature, humidity, orderId); + res.status(201).json(measurement); }); router.delete('/measurements/:id', async (req, res) => { - const measurementId = req.params.id; - if (!measurementId || isNaN(measurementId)) { - return res.status(400).json({ error: 'Invalid measurement ID' }); - } - try { - await measureManager.deleteMeasurement(measurementId); - res.status(200).json({ message: 'Measurement deleted successfully', id: measurementId }); - } catch (error) { - serverError.sendError('Error deleting measurement:', res, error, 500); + const measurement = await database_manager.measurement.delete_measurement_by_id(req.params.id); + if (!measurement) { + return res.status(404).json({ error: 'Measurement not found' }); } + res.json({ message: 'Measurement deleted successfully', id: measurement.id }); }); router.delete('/measurements/:projectId/:orderId', async (req, res) => { - const projectId = req.params.projectId; - const orderId = req.params.orderId; - if (!projectId || isNaN(projectId) || !orderId || isNaN(orderId)) { - return res.status(400).json({ error: 'Invalid project ID or order ID' }); - } - try { - const measurement = await measureManager.deleteMeasurementByOrderId(projectId, orderId); - res.status(200).json({ message: 'Measurement deleted successfully', id: measurement.id }); - } catch (error) { - serverError.sendError('Error deleting measurement:', res, error, 500); + const measurement = await database_manager.measurement.delete_measurement_by_project_and_order_id(req.params.projectId, req.params.orderId); + if (!measurement) { + return res.status(404).json({ error: 'Measurement not found' }); } + res.json({ message: 'Measurement deleted successfully', id: measurement.id }); }); module.exports = router; diff --git a/routes/uploadRoutes.js b/routes/uploadRoutes.js index 2f7e4b8..f39e3db 100644 --- a/routes/uploadRoutes.js +++ b/routes/uploadRoutes.js @@ -1,7 +1,8 @@ const express = require('express'); const router = express.Router(); const multer = require('multer'); -const measureManager = require('../src/measure/measureManager'); +const database_manager = require('../src/database/database_manager'); +const storage_manager = require('../src/data/storage_manager'); const serverError = require('../utils/serverError'); const upload = multer({ storage: multer.memoryStorage() }); @@ -17,7 +18,10 @@ router.post('/uploadmeasurement', upload.single('image'), async (req, res) => { } try { - const nextOrderId = await measureManager.getNextOrderId(projectId); + const nextOrderId = await database_manager.measurement.get_next_order_id(projectId); + if (nextOrderId === null) { + return res.status(404).json({ error: 'Project not found' }); + } // Log types for debugging console.log('Types:', { @@ -26,8 +30,14 @@ router.post('/uploadmeasurement', upload.single('image'), async (req, res) => { nextOrderId: typeof nextOrderId }); - const imagePath = await measureManager.uploadMeasureImage(image, projectId, nextOrderId); - const measurement = await measureManager.addMeasureToProject(projectId, timestamp, imagePath, temperature, humidity, nextOrderId); + const imagePath = await storage_manager.measurement.upload_measurement_image(image, projectId, nextOrderId); + if (!imagePath) { + return res.status(500).json({ error: 'Failed to upload image' }); + } + const measurement = await database_manager.measurement.add_measurement(projectId, timestamp, imagePath, temperature, humidity, nextOrderId); + if (!measurement) { + return res.status(500).json({ error: 'Failed to add measurement' }); + } res.json({ message: 'Measurement uploaded successfully', path: imagePath, id: measurement.id }); } catch (error) { serverError.sendError('Error uploading measurement:', res, error, 500); diff --git a/routes/videoRoutes.js b/routes/videoRoutes.js index 683aa86..bd6f3d9 100644 --- a/routes/videoRoutes.js +++ b/routes/videoRoutes.js @@ -5,7 +5,7 @@ const fs = require('fs'); const rangeParser = require('range-parser'); const serverError = require('../utils/serverError'); const videoManager = require('../src/video/videoManager'); -const measureManager = require('../src/measure/measureManager'); +const storage_manager = require('../src/data/storage_manager'); const dbTester = require('../test/tester'); router.get('/videos', (req, res) => { @@ -55,7 +55,10 @@ router.post('/videos', async (req, res) => { } const { duration: videoDuration, measurement_ids: videoMeasurementIds, project_id: videoProjectId } = result.rows[0]; - const pathList = await measureManager.getPathList(videoMeasurementIds, videoProjectId); + const pathList = await storage_manager.measurement.get_path_list(videoMeasurementIds, project_id); + if (!pathList || pathList.length === 0) { + return res.status(404).json({ error: 'Aucun chemin trouvé pour les mesures' }); + } // parser la résolution (ex: 1920x1080) const [res_width, res_height] = resolution.split('x').map(Number); diff --git a/src/data/storage_manager.js b/src/data/storage_manager.js index 625ecfc..78615a6 100644 --- a/src/data/storage_manager.js +++ b/src/data/storage_manager.js @@ -1,6 +1,7 @@ const fs = require('fs').promises; const path = require('path'); const PROJECTS_DIR = path.join('.'); +const database_manager = require('../database/database_manager.js'); async function createFolder(name) { const projectDir = path.join(PROJECTS_DIR, `${name}`); @@ -89,22 +90,79 @@ async function deleteFile(name) { } } +async function handleFileOperation(operation, ...args) { + try { + return await operation(...args); + } catch (error) { + console.error(`[FILE OPERATION ERROR] ${error.message}`); + throw error; + } +} + const project = { createProjectDirectory: async function (projectId) { const projectPath = `${projectId}`; - await createFolder(projectPath); - await createFolder(`${projectPath}/images`); - await createFolder(`${projectPath}/videos`); + await handleFileOperation(createFolder, projectPath); + await handleFileOperation(createFolder, `${projectPath}/images`); + await handleFileOperation(createFolder, `${projectPath}/videos`); console.log("[FILE] createProjectDirectory : " + projectPath); }, deleteProjectDirectory: async function (projectId) { const projectPath = `${projectId}`; - await deleteFolder(projectPath); + await handleFileOperation(deleteFolder, projectPath); console.log("[FILE] deleteProjectDirectory : " + projectPath); } }; +const measurement = { + get_measurement_image: async function (projectId, orderId) { + const projectPath = `${projectId}`; + const imagePath = `${projectPath}/images/${orderId}.jpg`; + console.log("[FILE] get_measurement_image : " + imagePath); + return await handleFileOperation(getFile, imagePath); + }, + + upload_measurement_image: async function (image, projectId, orderId) { + const projectPath = `${projectId}`; + const imagePath = `${projectPath}/images/${orderId}.jpg`; + console.log("[FILE] upload_measurement_image : " + imagePath); + await handleFileOperation(saveFile, imagePath, image.buffer); + return imagePath; + }, + + get_path_from_id: async function (projectId, orderId) { + const query = database_manager.measurement.get_measurement_by_project_and_order_id(projectId, orderId); + return query.path; + }, + + get_path_list: async function (IdList, projectId) { + let parsedIdList; + try { + parsedIdList = JSON.parse(IdList); + } catch (e) { + console.error("Error parsing IdList:", e); + return []; + } + + const pathList = []; + for (const orderId of parsedIdList) { + const path = await this.get_path_from_id(projectId, orderId); + pathList.push(path); + } + return pathList; + }, +} + +const video = { + get_video: async function (projectId, orderId) { + const projectPath = `${projectId}`; + const videoPath = `${projectPath}/videos/${orderId}.mp4`; + console.log("[FILE] get_video : " + videoPath); + return await handleFileOperation(getFile, videoPath); + } +} + module.exports = { createFolder, deleteFolder, @@ -112,5 +170,7 @@ module.exports = { saveFile, getFile, deleteFile, - project + project, + measurement, + video }; \ No newline at end of file diff --git a/src/database/database_manager.js b/src/database/database_manager.js index c38e0e1..bfc1735 100644 --- a/src/database/database_manager.js +++ b/src/database/database_manager.js @@ -190,9 +190,23 @@ const measurement = { const query = `UPDATE measurements SET ${fields} WHERE id = $1 RETURNING *;`; return (await db.query(query, values)).rows[0]; }), + + edit_measurement_by_project_and_order_id: handleDatabaseOperation(async (project_id, order_id, updates) => { + const fields = Object.keys(updates).map((key, index) => `${key} = $${index + 3}`).join(', '); + const values = [project_id, order_id, ...Object.values(updates)]; + const query = `UPDATE measurements SET ${fields} WHERE project_id = $1 AND order_id = $2 RETURNING *;`; + return (await db.query(query, values)).rows[0]; + }), + delete_measurement_by_id: handleDatabaseOperation(async (id) => { const query = `DELETE FROM measurements WHERE id = $1;`; await db.query(query, [id]); + }), + + get_next_order_id: handleDatabaseOperation(async (project_id) => { + const query = `SELECT COALESCE(MAX(order_id), 0) + 1 AS next_order_id FROM measurements WHERE project_id = $1;`; + const result = await db.query(query, [project_id]); + return result.rows[0].next_order_id; }) }; diff --git a/src/measure/measureManager.js b/src/measure/measureManager.js deleted file mode 100644 index 5e86e51..0000000 --- a/src/measure/measureManager.js +++ /dev/null @@ -1,130 +0,0 @@ -const db = require('../../db.js'); -const path = require('path'); -const storage_manager = require('../data/storage_manager.js'); - -async function uploadMeasureImage(image, projectId, orderId) { - try { - // Ensure that folder creation and file saving are awaited - const projectDir = await storage_manager.createFolder('./storage/' + projectId.toString()); - const imagesDir = await storage_manager.createFolder(path.join(projectDir, 'images')); - const imagePath = path.join(imagesDir, `${orderId}.jpg`); - - // Save the file and await completion - await storage_manager.saveFile(imagePath, image.buffer); - - console.log("[FILE] uploadMeasureImage - Image saved to: " + imagePath); - return imagePath; - } catch (error) { - console.error('Error in uploadMeasureImage:', error); - throw error; - } - } - -async function getMeasureImage(projectId, orderId) { - const projectPath = `${projectId}`; - const imagePath = `${projectPath}/${orderId}.jpg`; - console.log("[FILE] getMeasureImage - Image path: " + imagePath); - return storage_manager.getFile(imagePath); -} - -async function getNextOrderId(projectId) { - const query = 'SELECT MAX(order_id) FROM public.measurements WHERE project_id = $1'; - const values = [projectId]; - const res = await db.query(query, values); - console.log("[DB] getNextOrderId - Max order_id: " + res.rows[0].max); - return res.rows[0].max + 1; -} - -async function addMeasureToProject(projectId, orderId, timestamp, path, temperature, humidity) { - const query = 'INSERT INTO public.measurements (project_id, timestamp, path, temperature, humidity, order_id) VALUES ($1, $2, $3, $4, $5, $6) RETURNING *'; - const values = [projectId, orderId, timestamp, path, temperature, humidity]; - const res = await db.query(query, values); - return res.rows[0]; -} - -async function getMeasurements(projectId) { - const query = 'SELECT * FROM public.measurements WHERE project_id = $1'; - const values = [projectId]; - const res = await db.query(query, values); - return res.rows; -} - -async function getMeasurement(projectId, orderId) { - const query = 'SELECT * FROM public.measurements WHERE project_id = $1 AND order_id = $2'; - const values = [projectId, orderId]; - const res = await db.query(query, values); - return res.rows[0]; -} - -async function getMeasurementById(id) { - const query = 'SELECT * FROM public.measurements WHERE id = $1'; - const values = [id]; - const res = await db.query(query, values); - return res.rows[0]; -} - -async function updateMeasurement(projectId, orderId, timestamp, path, temperature, humidity) { - const query = 'UPDATE public.measurements SET timestamp = $3, path = $4, temperature = $5, humidity = $6 WHERE project_id = $1 AND order_id = $2 RETURNING *'; - const values = [projectId, orderId, timestamp, path, temperature, humidity]; - const res = await db.query(query, values); - return res.rows[0]; -} - -async function updateMeasurementById(id, timestamp, path, temperature, humidity) { - const query = 'UPDATE public.measurements SET timestamp = $2, path = $3, temperature = $4, humidity = $5 WHERE id = $1 RETURNING *'; - const values = [id, timestamp, path, temperature, humidity]; - const res = await db.query(query, values); - return res.rows[0]; -} - -async function deleteMeasurement(id) { - const query = 'DELETE FROM public.measurements WHERE id = $1'; - const values = [id]; - const res = await db.query(query, values); - return res.rows[0]; -} - -async function getPathFromIds(projectId, orderId) { - console.log("Getting path from ids:", projectId, orderId); - const query = 'SELECT path FROM public.measurements WHERE project_id = $1 AND order_id = $2'; - const values = [projectId, orderId]; - const res = await db.query(query, values); - return res.rows[0].path; -} - -async function getPathList(IdList, projectId) { - // Convertir la chaîne de caractères en tableau - let parsedIdList; - try { - parsedIdList = JSON.parse(IdList); - } catch (e) { - console.error("Erreur lors de la conversion de la chaîne en tableau:", e); - return []; - } - - console.log(parsedIdList); - const pathList = []; - for (const orderId of parsedIdList) { - console.log(orderId); - const path = await getPathFromIds(projectId, orderId); - console.log(path); - pathList.push(path); - } - return pathList; -} - - -module.exports = { - uploadMeasureImage, - addMeasureToProject, - getNextOrderId, - getMeasurements, - getMeasurement, - updateMeasurement, - deleteMeasurement, - getMeasureImage, - getMeasurementById, - updateMeasurementById, - getPathFromIds, - getPathList -};