Ajout de la gestion des chemins d'images et amélioration des messages de log dans plusieurs modules
This commit is contained in:
2
db.js
2
db.js
@@ -16,7 +16,7 @@ function connectWithRetry() {
|
||||
console.error('Erreur de connexion à la base de données:', err);
|
||||
setTimeout(connectWithRetry, 30000); // Réessayer après 30 secondes
|
||||
} else {
|
||||
console.log('Connecté à la base de données PostgreSQL.');
|
||||
console.log('[DB] Connecté à la base de données PostgreSQL.');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -60,6 +60,6 @@ app.get('/', (req, res) => {
|
||||
|
||||
// Démarrer le serveur
|
||||
app.listen(port, () => {
|
||||
console.log(`Serveur démarré sur http://localhost:${port}`);
|
||||
console.log(`Swagger documentation disponible sur http://localhost:${port}/api-docs`);
|
||||
console.log(`[SERVER] Serveur démarré sur http://localhost:${port}`);
|
||||
console.log(`[SERVER] Swagger documentation disponible sur http://localhost:${port}/api-docs`);
|
||||
});
|
||||
|
||||
@@ -3,17 +3,20 @@ import path from 'path';
|
||||
import storageManager from '../data/storageManager.js';
|
||||
import fs from 'fs';
|
||||
|
||||
let localCounter = 0;
|
||||
|
||||
async function checkAndRemoveInvalidEntries() {
|
||||
console.log('Checking for invalid entries...');
|
||||
localCounter = 0;
|
||||
console.log('[INFO] Vérification et suppression des entrées invalides...');
|
||||
try {
|
||||
const measurementsRes = await db.query('SELECT id, path FROM measurements');
|
||||
//console.log('Fetched measurements:', measurementsRes.rows);
|
||||
for (const row of measurementsRes.rows) {
|
||||
//console.log('Checking file path:', row.path);
|
||||
if (!fs.existsSync(row.path)) {
|
||||
// Remove invalid entry
|
||||
await db.query('DELETE FROM measurements WHERE id = $1', [row.id]);
|
||||
console.log(`Deleted invalid measurement entry with id: ${row.id}`);
|
||||
localCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,8 +29,14 @@ async function checkAndRemoveInvalidEntries() {
|
||||
// Remove the file if the entry does not exist
|
||||
fs.unlinkSync(imagePath);
|
||||
console.log(`Deleted file at path: ${imagePath} as its database entry does not exist`);
|
||||
localCounter++; // Increment counter if entry is deleted
|
||||
}
|
||||
}
|
||||
if (localCounter > 0) {
|
||||
console.log(`[INFO] ${localCounter} entrées ont été modifiées`);
|
||||
} else {
|
||||
console.log('[INFO] Aucune entrée n\'a été modifiée.');
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error checking and removing invalid entries:', err);
|
||||
}
|
||||
@@ -36,7 +45,8 @@ async function checkAndRemoveInvalidEntries() {
|
||||
|
||||
|
||||
// Run the check periodically
|
||||
setInterval(checkAndRemoveInvalidEntries, 10000); // Every second
|
||||
console.log('[INFO] Activation du FileWatcher pour surveiller les fichiers invalides...')
|
||||
setInterval(checkAndRemoveInvalidEntries, 10000); // Every 10 seconds
|
||||
|
||||
// Initial run
|
||||
checkAndRemoveInvalidEntries();
|
||||
@@ -1,64 +1,80 @@
|
||||
const fs = require('fs');
|
||||
const fs = require('fs').promises;
|
||||
const path = require('path');
|
||||
const PROJECTS_DIR = path.join('.');
|
||||
|
||||
function createFolder(name){
|
||||
async function createFolder(name) {
|
||||
const projectDir = path.join(PROJECTS_DIR, `${name}`);
|
||||
if (!fs.existsSync(projectDir)) {
|
||||
fs.mkdirSync(projectDir, { recursive: true });
|
||||
try {
|
||||
await fs.access(projectDir);
|
||||
} catch (error) {
|
||||
if (error.code === 'ENOENT') {
|
||||
await fs.mkdir(projectDir, { recursive: true });
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return projectDir;
|
||||
}
|
||||
|
||||
function deleteFolder(name){
|
||||
const projectDir = path.join(PROJECTS_DIR, `${name
|
||||
}`);
|
||||
if (fs.existsSync
|
||||
(projectDir)) {
|
||||
fs.rmSync(projectDir, { recursive: true, force: true });
|
||||
async function deleteFolder(name) {
|
||||
const projectDir = path.join(PROJECTS_DIR, `${name}`);
|
||||
try {
|
||||
await fs.access(projectDir);
|
||||
await fs.rm(projectDir, { recursive: true, force: true });
|
||||
} catch (error) {
|
||||
if (error.code !== 'ENOENT') {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function scanAllImages(dir = 'storage') {
|
||||
async function scanAllImages(dir = 'storage') {
|
||||
const projectDir = path.join(PROJECTS_DIR, dir);
|
||||
let results = [];
|
||||
|
||||
function scanDirectory(directory) {
|
||||
const files = fs.readdirSync(directory);
|
||||
files.forEach(file => {
|
||||
|
||||
async function scanDirectory(directory) {
|
||||
const files = await fs.readdir(directory);
|
||||
for (const file of files) {
|
||||
const filePath = path.join(directory, file);
|
||||
const stat = fs.statSync(filePath);
|
||||
const stat = await fs.stat(filePath);
|
||||
if (stat.isDirectory()) {
|
||||
scanDirectory(filePath);
|
||||
await scanDirectory(filePath);
|
||||
} else if (file.endsWith('.jpg')) {
|
||||
results.push(filePath);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
scanDirectory(projectDir);
|
||||
await scanDirectory(projectDir);
|
||||
return results;
|
||||
}
|
||||
|
||||
function saveFile(filePath, content) {
|
||||
// Ensure content is a buffer
|
||||
async function saveFile(filePath, content) {
|
||||
if (Buffer.isBuffer(content)) {
|
||||
fs.writeFileSync(filePath, content);
|
||||
await fs.writeFile(filePath, content);
|
||||
} else {
|
||||
throw new Error('Content must be a buffer');
|
||||
}
|
||||
}
|
||||
|
||||
function getFile(name){
|
||||
async function getFile(name) {
|
||||
const filePath = path.join(PROJECTS_DIR, `${name}`);
|
||||
return fs
|
||||
.readFileSync(filePath);
|
||||
return await fs.readFile(filePath);
|
||||
}
|
||||
|
||||
function deleteFile(name){
|
||||
async function deleteFile(name) {
|
||||
const filePath = path.join(PROJECTS_DIR, `${name}`);
|
||||
if (fs.existsSync(filePath))
|
||||
fs.rmSync(filePath);
|
||||
try {
|
||||
await fs.access(filePath); // Vérifie si le fichier existe
|
||||
await fs.rm(filePath); // Supprime le fichier
|
||||
return `File ${filePath} deleted successfully.`;
|
||||
} catch (error) {
|
||||
if (error.code === 'ENOENT') {
|
||||
return `File ${filePath} does not exist.`;
|
||||
} else {
|
||||
throw error; // Relance l'erreur si ce n'est pas une erreur de fichier introuvable
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
@@ -7,13 +7,14 @@ async function uploadMeasureImage(image, projectId, orderId) {
|
||||
const imagesDir = storageManager.createFolder(path.join(projectDir, 'images'));
|
||||
var imagePath = path.join(imagesDir, `${orderId}.jpg`);
|
||||
storageManager.saveFile(imagePath, image.buffer);
|
||||
|
||||
console.log("[FILE] uploadMeasureImage - Image saved to: " + imagePath);
|
||||
return imagePath;
|
||||
}
|
||||
|
||||
async function getMeasureImage(projectId, orderId) {
|
||||
const projectPath = `${projectId}`;
|
||||
const imagePath = `${projectPath}/${orderId}.jpg`;
|
||||
console.log("[FILE] getMeasureImage - Image path: " + imagePath);
|
||||
return storageManager.getFile(imagePath);
|
||||
}
|
||||
|
||||
@@ -21,6 +22,7 @@ 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;
|
||||
}
|
||||
|
||||
@@ -73,6 +75,13 @@ async function deleteMeasurement(id) {
|
||||
return res.rows[0];
|
||||
}
|
||||
|
||||
async function getPathFromIds(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;
|
||||
}
|
||||
|
||||
export {
|
||||
uploadMeasureImage,
|
||||
addMeasureToProject,
|
||||
@@ -83,5 +92,6 @@ export {
|
||||
deleteMeasurement,
|
||||
getMeasureImage,
|
||||
getMeasurementById,
|
||||
updateMeasurementById
|
||||
updateMeasurementById,
|
||||
getPathFromIds
|
||||
}
|
||||
|
||||
@@ -6,17 +6,19 @@ function createProjectDirectory(projectId) {
|
||||
storageManager.createFolder(projectPath);
|
||||
storageManager.createFolder(`${projectPath}/images`);
|
||||
storageManager.createFolder(`${projectPath}/videos`);
|
||||
console.log("[FILE] createProjectDirectory : " + projectPath);
|
||||
}
|
||||
|
||||
function deleteProjectDirectory(projectId) {
|
||||
const projectPath = `${projectId}`;
|
||||
storageManager.deleteFolder(projectPath);
|
||||
console.log("[FILE] deleteProjectDirectory : " + projectPath);
|
||||
}
|
||||
|
||||
async function getAllProjects() {
|
||||
const query = 'SELECT * FROM public.projects';
|
||||
const res = await db.query(query);
|
||||
console.log('getAllProjects:', res.rows);
|
||||
console.log("[DB] getAllProjects : ", res.rows);
|
||||
return res.rows;
|
||||
}
|
||||
|
||||
@@ -24,6 +26,7 @@ async function getProjectById(projectId) {
|
||||
const query = 'SELECT * FROM public.projects WHERE id = $1';
|
||||
const values = [projectId];
|
||||
const res = await db.query(query, values);
|
||||
console.log("[DB] getProjectById : ", res.rows[0]);
|
||||
return res.rows[0];
|
||||
}
|
||||
|
||||
@@ -31,6 +34,7 @@ async function createProject(name, description, start_date, status) {
|
||||
const query = 'INSERT INTO public.projects (name, description, start_date, status) VALUES ($1, $2, $3, $4) RETURNING *';
|
||||
const values = [name, description, start_date, status];
|
||||
const res = await db.query(query, values);
|
||||
console.log("[DB] createProject : ", res.rows[0]);
|
||||
return res.rows[0];
|
||||
}
|
||||
|
||||
@@ -38,12 +42,14 @@ async function editProjectById(projectID, name, description, startDate, status)
|
||||
const query = 'UPDATE public.projects SET name = $1, description = $2, start_date = $3, status = $4 WHERE id = $5 RETURNING *';
|
||||
const values = [name, description, startDate, status, projectID];
|
||||
const res = await db.query(query, values);
|
||||
console.log("[DB] editProjectById : ", res.rows[0]);
|
||||
return res.rows[0];
|
||||
}
|
||||
|
||||
async function deleteProjectById(projectId) {
|
||||
const query = 'DELETE FROM public.projects WHERE id = $1';
|
||||
const values = [projectId];
|
||||
console.log("[DB] deleteProjectById : ", values);
|
||||
await db.query(query, values);
|
||||
}
|
||||
|
||||
@@ -51,6 +57,7 @@ async function getVideosByProjectId(projectId) {
|
||||
const query = 'SELECT * FROM public.videos WHERE project_id = $1';
|
||||
const values = [projectId];
|
||||
const res = await db.query(query, values);
|
||||
console.log("[DB] getVideosByProjectId : ", res.rows);
|
||||
return res.rows;
|
||||
}
|
||||
|
||||
@@ -58,6 +65,7 @@ async function getMeasurementsByProjectId(projectId) {
|
||||
const query = 'SELECT * FROM public.measurements WHERE project_id = $1';
|
||||
const values = [projectId];
|
||||
const res = await db.query(query, values);
|
||||
console.log("[DB] getMeasurementsByProjectId : ", res.rows);
|
||||
return res.rows;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,59 @@ const serverError = require('../../utils/serverError');
|
||||
const db = require('../../db');
|
||||
const storageManager = require('../data/storageManager');
|
||||
const PROJECTS_DIR = path.join('.');
|
||||
const measureManager = require('../measure/measureManager');
|
||||
|
||||
async function createVideoWithList(projectId, pathList) {
|
||||
//pathList étant la liste des chemins déjà triés
|
||||
const tempFile = path.join('temp.txt');
|
||||
try {
|
||||
// Trouver tous les fichiers image pour le projet donné
|
||||
const workdir = path.join(PROJECTS_DIR, 'storage', `${projectId}`);
|
||||
const dir = path.join(PROJECTS_DIR, 'storage', `${projectId}`, 'images');
|
||||
console.log('dir:', dir);
|
||||
const images = pathList;
|
||||
console.log('images:', images);
|
||||
|
||||
// Trier les images numériquement
|
||||
const sortedImages = images.sort((a, b) => {
|
||||
const numA = parseInt(path.basename(a).match(/\d+/)[0], 10);
|
||||
const numB = parseInt(path.basename(b).match(/\d+/)[0], 10);
|
||||
return numA - numB;
|
||||
});
|
||||
|
||||
// En déduire l'id de la première et dernière image utilisée
|
||||
const firstImageId = parseInt(path.basename(sortedImages[0]).match(/\d+/)[0], 10);
|
||||
const lastImageId = parseInt(path.basename(sortedImages[sortedImages.length - 1]).match(/\d+/)[0], 10);
|
||||
|
||||
console.log('firstImageId:', firstImageId);
|
||||
console.log('lastImageId:', lastImageId);
|
||||
|
||||
// Créer un fichier temporaire pour la liste des images
|
||||
fs.writeFileSync(tempFile, sortedImages.map(image => `file '${image}'`).join('\n'));
|
||||
|
||||
const frameRate = 10;
|
||||
|
||||
// le fichier final prend cette forme : {projectId}_{firstImageId}_{lastImageId}-{timestamp}.mp4
|
||||
const timestamp = new Date().getTime();
|
||||
const outputVideo = path.join(workdir, `${projectId}_${firstImageId}_${lastImageId}-${timestamp}.mp4`);
|
||||
|
||||
// Commande ffmpeg pour créer la vidéo
|
||||
const ffmpegCommand = `ffmpeg -r ${frameRate} -f concat -safe 0 -i ${tempFile} -vsync vfr -pix_fmt yuv420p ${outputVideo}`;
|
||||
console.log('Running ffmpeg command:', ffmpegCommand);
|
||||
execSync(ffmpegCommand);
|
||||
console.log('Video created successfully:', outputVideo);
|
||||
return outputVideo;
|
||||
} catch (error) {
|
||||
console.error('Error creating video:', error);
|
||||
serverError(error);
|
||||
} finally {
|
||||
// Supprimer le fichier temporaire
|
||||
if (fs.existsSync(tempFile)) {
|
||||
fs.unlinkSync(tempFile);
|
||||
console.log('Temporary file deleted:', tempFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function createVideo(projectId) {
|
||||
const tempFile = path.join('temp.txt');
|
||||
@@ -23,6 +76,13 @@ async function createVideo(projectId) {
|
||||
return numA - numB;
|
||||
});
|
||||
|
||||
// En déduire l'id de la première et dernière image utilisée
|
||||
const firstImageId = parseInt(path.basename(sortedImages[0]).match(/\d+/)[0], 10);
|
||||
const lastImageId = parseInt(path.basename(sortedImages[sortedImages.length - 1]).match(/\d+/)[0], 10);
|
||||
|
||||
console.log('firstImageId:', firstImageId);
|
||||
console.log('lastImageId:', lastImageId);
|
||||
|
||||
// Créer un fichier temporaire pour la liste des images
|
||||
fs.writeFileSync(tempFile, sortedImages.map(image => `file '${image}'`).join('\n'));
|
||||
|
||||
@@ -46,4 +106,4 @@ async function createVideo(projectId) {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { createVideo };
|
||||
module.exports = { createVideo, createVideoWithList };
|
||||
|
||||
@@ -1,27 +1,51 @@
|
||||
const storageManager = require('../src/data/storageManager');
|
||||
const videoManager = require('../src/video/videoManager');
|
||||
const measureManager = require('../src/measure/measureManager');
|
||||
const path = require('path');
|
||||
|
||||
console.log('Testing database functions...');
|
||||
// console.log('Testing database functions...');
|
||||
|
||||
try {
|
||||
storageManager.createFolder('test_folder');
|
||||
console.log('1 - Folder created');
|
||||
storageManager.deleteFolder('test_folder');
|
||||
console.log('2 - Folder deleted');
|
||||
} catch (error) {
|
||||
console.error('Error testing database functions:', error);
|
||||
}
|
||||
// try {
|
||||
// storageManager.createFolder('test_folder');
|
||||
// console.log('1 - Folder created');
|
||||
// storageManager.deleteFolder('test_folder');
|
||||
// console.log('2 - Folder deleted');
|
||||
// } catch (error) {
|
||||
// console.error('Error testing database functions:', error);
|
||||
// }
|
||||
|
||||
function getSmileImage() {
|
||||
return path.join(__dirname, '../sample/smile.png');
|
||||
}
|
||||
|
||||
//test de lancement d'une création de vidéo sur le projet 1
|
||||
videoManager.createVideo(1).then(res => {
|
||||
// videoManager.createVideo(1).then(res => {
|
||||
// console.log('3 - Video created:', res);
|
||||
// }).catch(err => {
|
||||
// console.error('Error creating video:', err);
|
||||
// });
|
||||
// async function run() {
|
||||
// var Path = await measureManager.getPathFromIds(1, 1);
|
||||
// console.log(Path);
|
||||
// }
|
||||
|
||||
// run().catch(err => {
|
||||
// console.error('Error:', err);
|
||||
// });
|
||||
|
||||
var pathList = [
|
||||
'storage/1/images/1.jpg',
|
||||
'storage/1/images/10.jpg',
|
||||
'storage/1/images/20.jpg',
|
||||
'storage/1/images/30.jpg',
|
||||
];
|
||||
videoManager.createVideoWithList(1, pathList).then(res => {
|
||||
console.log('3 - Video created:', res);
|
||||
return storageManager.deleteFile(res);
|
||||
}).then(res => {
|
||||
console.log('4 - Video deleted:', res);
|
||||
}).catch(err => {
|
||||
console.error('Error creating video:', err);
|
||||
console.error('Error:', err);
|
||||
});
|
||||
|
||||
exports.getSmileImage = getSmileImage;
|
||||
Reference in New Issue
Block a user