diff --git a/api.js b/api.js index 4469765..1a82e09 100644 --- a/api.js +++ b/api.js @@ -7,6 +7,8 @@ const videoRoutes = require('./routes/videoRoutes'); const imageRoutes = require('./routes/imageRoutes'); const cameraRoutes = require('./routes/cameraRoutes'); const uploadRoutes = require('./routes/uploadRoutes'); +const FileWatcher = require('./src/data/filewatcher'); +const database_manager = require('./src/database/database_manager'); router.use(cors({ origin: ['http://127.0.0.1:5500', 'http://localhost:5500', 'http://localhost:3000'], diff --git a/db.js b/db.js index 10b2f75..89adcac 100644 --- a/db.js +++ b/db.js @@ -1,6 +1,8 @@ const { Client } = require('pg'); -const client = new Client({ +let dev = true; + +let client = new Client({ host: '192.168.192.3', port: 5432, user: 'timelapse', @@ -8,11 +10,23 @@ const client = new Client({ database: 'timelapse' }); +if (dev) { + client = new Client({ + host: 'mikoshi', + port: 54322, + user: 'timelapse', + password: 'timelapse', + database: 'timelapse_dev' + }); +} + + function init_database() { + console.log('[DB] Initialisation de la base de données PostgreSQL...'); client.connect(err => { if (err) { console.error('Erreur de connexion à la base de données:', err); - setTimeout(init_database, 30000); + setTimeout(init_database, 3000); } else { console.log('[DB] Connecté à la base de données PostgreSQL.'); } diff --git a/routes/cameraRoutes.js b/routes/cameraRoutes.js index a0c235c..c5d488d 100644 --- a/routes/cameraRoutes.js +++ b/routes/cameraRoutes.js @@ -2,6 +2,7 @@ const express = require('express'); const router = express.Router(); const db = require('../db'); const serverError = require('../utils/serverError'); +const { start } = require('repl'); //const minInterval = 3; // Minutes //const maxInterval = 60; // Minutes @@ -67,7 +68,7 @@ async function getCamera() { } async function printCameraStatus() { - let camera = getCamera(); + let camera = await getCamera(); console.log('Statut de la caméra:'); console.log('Intervalle de capture:', camera.captureInterval, 'minutes'); console.log('Maintenance:', camera.maintenance === 1 ? 'En cours' : 'Aucune'); @@ -173,8 +174,15 @@ async function changeProjectStatus(projectId, status) { } } -initCamera(); -printCameraStatus(); +async function startup() { + await initCamera(); + await printCameraStatus(); +} + +startup() + .catch(err => { + console.error('Erreur lors de l\'initialisation de la caméra:', err); + }); /** * @swagger diff --git a/src/data/storageManager.js b/src/data/storageManager.js index 9a03d52..1825230 100644 --- a/src/data/storageManager.js +++ b/src/data/storageManager.js @@ -32,6 +32,17 @@ async function scanAllImages(dir = 'storage') { const projectDir = path.join(PROJECTS_DIR, dir); let results = []; + // check if the directory exists and create it if not + try { + await fs.access(projectDir); + } catch (error) { + if (error.code === 'ENOENT') { + await fs.mkdir(projectDir, { recursive: true }); + } else { + throw error; + } + } + async function scanDirectory(directory) { const files = await fs.readdir(directory); for (const file of files) { diff --git a/src/database/database_manager.js b/src/database/database_manager.js new file mode 100644 index 0000000..370a9e2 --- /dev/null +++ b/src/database/database_manager.js @@ -0,0 +1,144 @@ +const db = require('../../db.js'); + +// Fonctions de gestion de la base de données interne + +async function create_database() { + const queries = [ + `CREATE TABLE IF NOT EXISTS projects ( + id SERIAL PRIMARY KEY, + name VARCHAR(255) NOT NULL, + description TEXT, + start_date DATE, + status INTEGER NOT NULL CHECK (status = ANY (ARRAY [0, 1, 2, 3])) + );`, + `ALTER TABLE projects OWNER TO timelapse;`, + `CREATE TABLE IF NOT EXISTS measurements ( + id SERIAL PRIMARY KEY, + project_id INTEGER REFERENCES projects ON DELETE CASCADE, + timestamp TIMESTAMP NOT NULL, + path VARCHAR(255), + temperature DOUBLE PRECISION, + humidity DOUBLE PRECISION, + order_id INTEGER NOT NULL, + CONSTRAINT unique_project_photo_order UNIQUE (project_id, order_id) + );`, + `ALTER TABLE measurements OWNER TO timelapse;`, + `CREATE TABLE IF NOT EXISTS videos ( + id SERIAL PRIMARY KEY, + project_id INTEGER REFERENCES projects ON DELETE CASCADE, + measurement_ids TEXT NOT NULL, + video_file VARCHAR(255), + resolution VARCHAR(255), + duration INTEGER, + status INTEGER NOT NULL CHECK (status = ANY (ARRAY [0, 1, 2, 3])), + name VARCHAR(255), + progress DOUBLE PRECISION, + started_at TIMESTAMP, + updated_at TIMESTAMP, + eta DOUBLE PRECISION + );`, + `ALTER TABLE videos OWNER TO timelapse;`, + `CREATE TABLE IF NOT EXISTS camera ( + id SERIAL PRIMARY KEY, + interval INTEGER NOT NULL, + maintenance INTEGER NOT NULL, + active INTEGER DEFAULT 0 NOT NULL + );`, + `ALTER TABLE camera OWNER TO timelapse;` + ]; + + try { + for (const query of queries) { + await db.query(query); + } + console.log('Database tables created or verified successfully.'); + } catch (err) { + console.error('Error creating database tables:', err); + throw err; + } +} + +async function check_database_existence() { + const query = ` + SELECT table_name + FROM information_schema.tables + WHERE table_schema = 'public' + AND table_name IN ('projects', 'measurements', 'videos', 'camera'); + `; + + try { + const result = await db.query(query); + const existingTables = result.rows.map(row => row.table_name); + + const requiredTables = ['projects', 'measurements', 'videos', 'camera']; + const missingTables = requiredTables.filter(table => !existingTables.includes(table)); + + if (missingTables.length > 0) { + console.error('Missing or improperly constructed tables:', missingTables); + throw new Error(`The following tables are missing or not properly constructed: ${missingTables.join(', ')}`); + } else { + console.log('All required tables exist and are properly constructed.'); + } + } catch (err) { + console.error('Error checking database tables:', err); + throw err; + } +} + +async function delete_database() { + const queries = [ + `DROP TABLE IF EXISTS videos;`, + `DROP TABLE IF EXISTS measurements;`, + `DROP TABLE IF EXISTS projects;`, + `DROP TABLE IF EXISTS camera;` + ]; + + try { + for (const query of queries) { + await db.query(query); + } + console.log('Database tables deleted successfully.'); + } catch (err) { + console.error('Error deleting database tables:', err); + throw err; + } +} + +async function init_function() { + try { + await check_database_existence(); + } catch (err) { + console.error('Database check failed:', err); + try { + await delete_database(); + await create_database(); + console.log('Database initialized successfully.'); + } catch (err) { + console.error('Error initializing database:', err); + throw err; + } + } finally { + console.log('Database initialization process completed.'); + } +} + +init_function() + .then(() => console.log('Database initialization completed.')) + .catch(err => console.error('Error during database initialization:', err)); + + +const database_manager = { + createVideoProject: async (project_id, measurement_ids, name, resolution, duration) => { + const query = `INSERT INTO public.videos (project_id, measurement_ids, name, resolution, duration) VALUES ($1, $2, $3, $4, $5) RETURNING id`; + const values = [project_id, measurement_ids, name, resolution, duration]; + try { + const result = await db.query(query, values); + return result.rows[0].id; + } catch (err) { + console.error('Error creating video project:', err); + throw err; + } + }, +}; + +module.exports = database_manager; \ No newline at end of file diff --git a/test/tester.js b/test/tester.js index ca2a15c..61a32d4 100644 --- a/test/tester.js +++ b/test/tester.js @@ -1,6 +1,7 @@ -const path = require('path'); +import path from 'path'; +import { fileURLToPath } from 'url'; -const __dirname = path.resolve(); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); function getSmileImage() { return path.join(__dirname, '../sample/smile.png'); @@ -10,5 +11,4 @@ function getCatVideo() { return path.join(__dirname, '../sample/cat.mp4'); } -exports.getSmileImage = getSmileImage; -exports.getCatVideo = getCatVideo; \ No newline at end of file +export { getSmileImage, getCatVideo }; \ No newline at end of file