Remove deprecated routes and functionalities related to camera, image, measurement, project, upload, and video management. This includes the deletion of route handlers and associated logic to streamline the codebase and improve maintainability.
All checks were successful
SSH Backend Deploy / ssh-deploy (push) Successful in 9s
All checks were successful
SSH Backend Deploy / ssh-deploy (push) Successful in 9s
This commit is contained in:
@@ -1,620 +0,0 @@
|
|||||||
// Routes SWAGGER - Documentation API
|
|
||||||
// Documentation: https://swagger.io/docs/specification/2-0/basic-structure/
|
|
||||||
// Les documentations sont volontairement séparées du code source pour des raisons de lisibilité et de maintenabilité.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @swagger
|
|
||||||
* /projects/{id}:
|
|
||||||
* delete:
|
|
||||||
* summary: Supprimer un projet par son ID
|
|
||||||
* description: Supprime un projet spécifique en utilisant son ID.
|
|
||||||
* parameters:
|
|
||||||
* - in: path
|
|
||||||
* name: id
|
|
||||||
* schema:
|
|
||||||
* type: integer
|
|
||||||
* required: true
|
|
||||||
* description: ID du projet
|
|
||||||
* responses:
|
|
||||||
* 200:
|
|
||||||
* description: Projet supprimé avec succès.
|
|
||||||
* 400:
|
|
||||||
* description: ID de projet invalide.
|
|
||||||
* 500:
|
|
||||||
* description: Erreur serveur.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @swagger
|
|
||||||
* /projects:
|
|
||||||
* get:
|
|
||||||
* summary: Récupérer tous les projets
|
|
||||||
* description: Récupère tous les projets disponibles.
|
|
||||||
* responses:
|
|
||||||
* 200:
|
|
||||||
* description: Une liste de projets.
|
|
||||||
* content:
|
|
||||||
* application/json:
|
|
||||||
* schema:
|
|
||||||
* type: array
|
|
||||||
* items:
|
|
||||||
* type: object
|
|
||||||
* 500:
|
|
||||||
* description: Erreur serveur.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @swagger
|
|
||||||
* /projects/{id}:
|
|
||||||
* get:
|
|
||||||
* summary: Récupérer un projet par ID
|
|
||||||
* description: Récupère un projet spécifique en utilisant son ID.
|
|
||||||
* parameters:
|
|
||||||
* - in: path
|
|
||||||
* name: id
|
|
||||||
* schema:
|
|
||||||
* type: integer
|
|
||||||
* required: true
|
|
||||||
* description: ID du projet
|
|
||||||
* responses:
|
|
||||||
* 200:
|
|
||||||
* description: Un projet.
|
|
||||||
* content:
|
|
||||||
* application/json:
|
|
||||||
* schema:
|
|
||||||
* type: object
|
|
||||||
* 400:
|
|
||||||
* description: ID de projet invalide.
|
|
||||||
* 500:
|
|
||||||
* description: Erreur serveur.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @swagger
|
|
||||||
* /projects/{id}/videos:
|
|
||||||
* get:
|
|
||||||
* summary: Récupérer les vidéos d'un projet par ID
|
|
||||||
* description: Récupère les vidéos associées à un projet spécifique en utilisant son ID.
|
|
||||||
* parameters:
|
|
||||||
* - in: path
|
|
||||||
* name: id
|
|
||||||
* schema:
|
|
||||||
* type: integer
|
|
||||||
* required: true
|
|
||||||
* description: ID du projet
|
|
||||||
* responses:
|
|
||||||
* 200:
|
|
||||||
* description: Une liste de vidéos.
|
|
||||||
* content:
|
|
||||||
* application/json:
|
|
||||||
* schema:
|
|
||||||
* type: array
|
|
||||||
* items:
|
|
||||||
* type: object
|
|
||||||
* 400:
|
|
||||||
* description: ID de projet invalide.
|
|
||||||
* 500:
|
|
||||||
* description: Erreur serveur.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @swagger
|
|
||||||
* /projects/{id}/measurements:
|
|
||||||
* get:
|
|
||||||
* summary: Récupérer les mesures d'un projet par ID
|
|
||||||
* description: Récupère les mesures associées à un projet spécifique en utilisant son ID.
|
|
||||||
* parameters:
|
|
||||||
* - in: path
|
|
||||||
* name: id
|
|
||||||
* schema:
|
|
||||||
* type: integer
|
|
||||||
* required: true
|
|
||||||
* description: ID du projet
|
|
||||||
* responses:
|
|
||||||
* 200:
|
|
||||||
* description: Une liste de mesures.
|
|
||||||
* content:
|
|
||||||
* application/json:
|
|
||||||
* schema:
|
|
||||||
* type: array
|
|
||||||
* items:
|
|
||||||
* type: object
|
|
||||||
* 400:
|
|
||||||
* description: ID de projet invalide.
|
|
||||||
* 500:
|
|
||||||
* description: Erreur serveur.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @swagger
|
|
||||||
* /projects:
|
|
||||||
* post:
|
|
||||||
* summary: Ajouter un nouveau projet
|
|
||||||
* description: Ajoute un nouveau projet à la base de données.
|
|
||||||
* requestBody:
|
|
||||||
* required: true
|
|
||||||
* content:
|
|
||||||
* application/json:
|
|
||||||
* schema:
|
|
||||||
* type: object
|
|
||||||
* properties:
|
|
||||||
* name:
|
|
||||||
* type: string
|
|
||||||
* description:
|
|
||||||
* type: string
|
|
||||||
* responses:
|
|
||||||
* 201:
|
|
||||||
* description: Projet ajouté avec succès.
|
|
||||||
* 400:
|
|
||||||
* description: Le nom et la description sont requis.
|
|
||||||
* 500:
|
|
||||||
* description: Erreur serveur.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @swagger
|
|
||||||
* /smile:
|
|
||||||
* get:
|
|
||||||
* summary: Retrieve a smile image
|
|
||||||
* responses:
|
|
||||||
* 200:
|
|
||||||
* description: A smile image
|
|
||||||
* content:
|
|
||||||
* image/jpeg:
|
|
||||||
* schema:
|
|
||||||
* type: string
|
|
||||||
* format: binary
|
|
||||||
* 404:
|
|
||||||
* description: Image not found
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @swagger
|
|
||||||
* /images/{projectId}/{orderId}:
|
|
||||||
* get:
|
|
||||||
* summary: Retrieve an image by project and order ID
|
|
||||||
* parameters:
|
|
||||||
* - in: path
|
|
||||||
* name: projectId
|
|
||||||
* required: true
|
|
||||||
* schema:
|
|
||||||
* type: string
|
|
||||||
* description: The project ID
|
|
||||||
* - in: path
|
|
||||||
* name: orderId
|
|
||||||
* required: true
|
|
||||||
* schema:
|
|
||||||
* type: string
|
|
||||||
* description: The order ID
|
|
||||||
* responses:
|
|
||||||
* 200:
|
|
||||||
* description: An image file
|
|
||||||
* content:
|
|
||||||
* application/octet-stream:
|
|
||||||
* schema:
|
|
||||||
* type: string
|
|
||||||
* format: binary
|
|
||||||
* 404:
|
|
||||||
* description: Image not found
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @swagger
|
|
||||||
* /images/{measurementId}:
|
|
||||||
* get:
|
|
||||||
* summary: Retrieve an image by measurement ID
|
|
||||||
* parameters:
|
|
||||||
* - in: path
|
|
||||||
* name: measurementId
|
|
||||||
* required: true
|
|
||||||
* schema:
|
|
||||||
* type: string
|
|
||||||
* description: The measurement ID
|
|
||||||
* responses:
|
|
||||||
* 200:
|
|
||||||
* description: An image file
|
|
||||||
* content:
|
|
||||||
* application/octet-stream:
|
|
||||||
* schema:
|
|
||||||
* type: string
|
|
||||||
* format: binary
|
|
||||||
* 404:
|
|
||||||
* description: Image not found
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @swagger
|
|
||||||
* /preview/{projectId}/{orderId}:
|
|
||||||
* get:
|
|
||||||
* summary: Retrieve a preview of an image by project and order ID
|
|
||||||
* parameters:
|
|
||||||
* - in: path
|
|
||||||
* name: projectId
|
|
||||||
* required: true
|
|
||||||
* schema:
|
|
||||||
* type: string
|
|
||||||
* description: The project ID
|
|
||||||
* - in: path
|
|
||||||
* name: orderId
|
|
||||||
* required: true
|
|
||||||
* schema:
|
|
||||||
* type: string
|
|
||||||
* description: The order ID
|
|
||||||
* responses:
|
|
||||||
* 200:
|
|
||||||
* description: A resized preview of the image
|
|
||||||
* content:
|
|
||||||
* image/jpeg:
|
|
||||||
* schema:
|
|
||||||
* type: string
|
|
||||||
* format: binary
|
|
||||||
* 404:
|
|
||||||
* description: Image not found
|
|
||||||
* 500:
|
|
||||||
* description: Internal Server Error
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @swagger
|
|
||||||
* /measurements:
|
|
||||||
* get:
|
|
||||||
* summary: Récupérer toutes les mesures
|
|
||||||
* description: Récupère toutes les mesures de la base de données.
|
|
||||||
* responses:
|
|
||||||
* 200:
|
|
||||||
* description: Une liste de mesures.
|
|
||||||
* content:
|
|
||||||
* application/json:
|
|
||||||
* schema:
|
|
||||||
* type: array
|
|
||||||
* items:
|
|
||||||
* type: object
|
|
||||||
* properties:
|
|
||||||
* id:
|
|
||||||
* type: integer
|
|
||||||
* project_id:
|
|
||||||
* type: integer
|
|
||||||
* timestamp:
|
|
||||||
* type: string
|
|
||||||
* format: date-time
|
|
||||||
* image_path:
|
|
||||||
* type: string
|
|
||||||
* temperature:
|
|
||||||
* type: number
|
|
||||||
* humidity:
|
|
||||||
* type: number
|
|
||||||
* 500:
|
|
||||||
* description: Erreur serveur.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @swagger
|
|
||||||
* /measurements/{id}:
|
|
||||||
* get:
|
|
||||||
* summary: Récupérer une mesure par ID
|
|
||||||
* description: Récupère une mesure spécifique en utilisant son ID.
|
|
||||||
* parameters:
|
|
||||||
* - in: path
|
|
||||||
* name: id
|
|
||||||
* schema:
|
|
||||||
* type: integer
|
|
||||||
* required: true
|
|
||||||
* description: ID de la mesure
|
|
||||||
* responses:
|
|
||||||
* 200:
|
|
||||||
* description: Une mesure.
|
|
||||||
* content:
|
|
||||||
* application/json:
|
|
||||||
* schema:
|
|
||||||
* type: object
|
|
||||||
* properties:
|
|
||||||
* id:
|
|
||||||
* type: integer
|
|
||||||
* project_id:
|
|
||||||
* type: integer
|
|
||||||
* timestamp:
|
|
||||||
* type: string
|
|
||||||
* format: date-time
|
|
||||||
* image_path:
|
|
||||||
* type: string
|
|
||||||
* temperature:
|
|
||||||
* type: number
|
|
||||||
* humidity:
|
|
||||||
* type: number
|
|
||||||
* 400:
|
|
||||||
* description: ID de mesure invalide.
|
|
||||||
* 500:
|
|
||||||
* description: Erreur serveur.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @swagger
|
|
||||||
* /measurements/{projectId}/{orderId}:
|
|
||||||
* get:
|
|
||||||
* summary: Récupérer une mesure par project ID et order ID
|
|
||||||
* description: Récupère une mesure spécifique en utilisant le project ID et order ID.
|
|
||||||
* parameters:
|
|
||||||
* - in: path
|
|
||||||
* name: projectId
|
|
||||||
* schema:
|
|
||||||
* type: integer
|
|
||||||
* required: true
|
|
||||||
* description: ID du projet
|
|
||||||
* - in: path
|
|
||||||
* name: orderId
|
|
||||||
* schema:
|
|
||||||
* type: integer
|
|
||||||
* required: true
|
|
||||||
* description: ID de la commande
|
|
||||||
* responses:
|
|
||||||
* 200:
|
|
||||||
* description: Une mesure.
|
|
||||||
* content:
|
|
||||||
* application/json:
|
|
||||||
* schema:
|
|
||||||
* type: object
|
|
||||||
* properties:
|
|
||||||
* id:
|
|
||||||
* type: integer
|
|
||||||
* project_id:
|
|
||||||
* type: integer
|
|
||||||
* timestamp:
|
|
||||||
* type: string
|
|
||||||
* format: date-time
|
|
||||||
* image_path:
|
|
||||||
* type: string
|
|
||||||
* temperature:
|
|
||||||
* type: number
|
|
||||||
* humidity:
|
|
||||||
* type: number
|
|
||||||
* 400:
|
|
||||||
* description: ID de projet ou de commande invalide.
|
|
||||||
* 500:
|
|
||||||
* description: Erreur serveur.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @swagger
|
|
||||||
* /measurements/{id}:
|
|
||||||
* delete:
|
|
||||||
* summary: Supprimer une mesure par ID
|
|
||||||
* description: Supprime une mesure spécifique en utilisant son ID.
|
|
||||||
* parameters:
|
|
||||||
* - in: path
|
|
||||||
* name: id
|
|
||||||
* schema:
|
|
||||||
* type: integer
|
|
||||||
* required: true
|
|
||||||
* description: ID de la mesure
|
|
||||||
* responses:
|
|
||||||
* 200:
|
|
||||||
* description: Mesure supprimée avec succès.
|
|
||||||
* 400:
|
|
||||||
* description: ID de mesure invalide.
|
|
||||||
* 500:
|
|
||||||
* description: Erreur serveur.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @swagger
|
|
||||||
* /measurements/{projectId}/{orderId}:
|
|
||||||
* delete:
|
|
||||||
* summary: Supprimer une mesure par project ID et order ID
|
|
||||||
* description: Supprime une mesure spécifique en utilisant le project ID et order ID.
|
|
||||||
* parameters:
|
|
||||||
* - in: path
|
|
||||||
* name: projectId
|
|
||||||
* schema:
|
|
||||||
* type: integer
|
|
||||||
* required: true
|
|
||||||
* description: ID du projet
|
|
||||||
* - in: path
|
|
||||||
* name: orderId
|
|
||||||
* schema:
|
|
||||||
* type: integer
|
|
||||||
* required: true
|
|
||||||
* description: ID de la commande
|
|
||||||
* responses:
|
|
||||||
* 200:
|
|
||||||
* description: Mesure supprimée avec succès.
|
|
||||||
* 400:
|
|
||||||
* description: ID de projet ou de commande invalide.
|
|
||||||
* 500:
|
|
||||||
* description: Erreur serveur.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @swagger
|
|
||||||
* /videos:
|
|
||||||
* get:
|
|
||||||
* summary: Récupérer toutes les vidéos
|
|
||||||
* description: Récupère toutes les vidéos de la base de données.
|
|
||||||
* responses:
|
|
||||||
* 200:
|
|
||||||
* description: Une liste de vidéos.
|
|
||||||
* content:
|
|
||||||
* application/json:
|
|
||||||
* schema:
|
|
||||||
* type: array
|
|
||||||
* items:
|
|
||||||
* type: object
|
|
||||||
* properties:
|
|
||||||
* id:
|
|
||||||
* type: integer
|
|
||||||
* project_id:
|
|
||||||
* type: integer
|
|
||||||
* measurement_ids:
|
|
||||||
* type: string
|
|
||||||
* video_path:
|
|
||||||
* type: string
|
|
||||||
* start_timestamp:
|
|
||||||
* type: string
|
|
||||||
* end_timestamp:
|
|
||||||
* type: string
|
|
||||||
* image_count:
|
|
||||||
* type: integer
|
|
||||||
* resolution:
|
|
||||||
* type: string
|
|
||||||
* duration:
|
|
||||||
* type: number
|
|
||||||
* fps:
|
|
||||||
* type: number
|
|
||||||
* status:
|
|
||||||
* type: integer
|
|
||||||
* name:
|
|
||||||
* type: string
|
|
||||||
* 500:
|
|
||||||
* description: Erreur serveur.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @swagger
|
|
||||||
* /videos/{id}:
|
|
||||||
* get:
|
|
||||||
* summary: Récupérer une vidéo par ID
|
|
||||||
* description: Récupère une vidéo spécifique en utilisant son ID.
|
|
||||||
* parameters:
|
|
||||||
* - in: path
|
|
||||||
* name: id
|
|
||||||
* schema:
|
|
||||||
* type: integer
|
|
||||||
* required: true
|
|
||||||
* description: ID de la vidéo
|
|
||||||
* responses:
|
|
||||||
* 200:
|
|
||||||
* description: Une vidéo.
|
|
||||||
* content:
|
|
||||||
* application/json:
|
|
||||||
* schema:
|
|
||||||
* type: object
|
|
||||||
* properties:
|
|
||||||
* id:
|
|
||||||
* type: integer
|
|
||||||
* project_id:
|
|
||||||
* type: integer
|
|
||||||
* measurement_ids:
|
|
||||||
* type: string
|
|
||||||
* video_path:
|
|
||||||
* type: string
|
|
||||||
* start_timestamp:
|
|
||||||
* type: string
|
|
||||||
* end_timestamp:
|
|
||||||
* type: string
|
|
||||||
* image_count:
|
|
||||||
* type: integer
|
|
||||||
* resolution:
|
|
||||||
* type: string
|
|
||||||
* duration:
|
|
||||||
* type: number
|
|
||||||
* fps:
|
|
||||||
* type: number
|
|
||||||
* status:
|
|
||||||
* type: integer
|
|
||||||
* name:
|
|
||||||
* type: string
|
|
||||||
* 400:
|
|
||||||
* description: ID de vidéo invalide.
|
|
||||||
* 500:
|
|
||||||
* description: Erreur serveur.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @swagger
|
|
||||||
* /videos:
|
|
||||||
* post:
|
|
||||||
* summary: Créer une nouvelle vidéo
|
|
||||||
* description: Crée une nouvelle vidéo avec les informations fournies.
|
|
||||||
* requestBody:
|
|
||||||
* required: true
|
|
||||||
* content:
|
|
||||||
* application/json:
|
|
||||||
* schema:
|
|
||||||
* type: object
|
|
||||||
* properties:
|
|
||||||
* project_id:
|
|
||||||
* type: integer
|
|
||||||
* measurement_ids:
|
|
||||||
* type: string
|
|
||||||
* name:
|
|
||||||
* type: string
|
|
||||||
* resolution:
|
|
||||||
* type: string
|
|
||||||
* duration:
|
|
||||||
* type: number
|
|
||||||
* responses:
|
|
||||||
* 200:
|
|
||||||
* description: Vidéo créée avec succès.
|
|
||||||
* content:
|
|
||||||
* application/json:
|
|
||||||
* schema:
|
|
||||||
* type: object
|
|
||||||
* properties:
|
|
||||||
* message:
|
|
||||||
* type: string
|
|
||||||
* video:
|
|
||||||
* type: object
|
|
||||||
* properties:
|
|
||||||
* project_id:
|
|
||||||
* type: integer
|
|
||||||
* measurement_ids:
|
|
||||||
* type: string
|
|
||||||
* name:
|
|
||||||
* type: string
|
|
||||||
* resolution:
|
|
||||||
* type: string
|
|
||||||
* duration:
|
|
||||||
* type: number
|
|
||||||
* 400:
|
|
||||||
* description: Tous les champs sont requis.
|
|
||||||
* 500:
|
|
||||||
* description: Erreur serveur.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @swagger
|
|
||||||
* /videos/{id}:
|
|
||||||
* delete:
|
|
||||||
* summary: Supprimer une vidéo par ID
|
|
||||||
* description: Supprime une vidéo spécifique en utilisant son ID.
|
|
||||||
* parameters:
|
|
||||||
* - in: path
|
|
||||||
* name: id
|
|
||||||
* schema:
|
|
||||||
* type: integer
|
|
||||||
* required: true
|
|
||||||
* description: ID de la vidéo
|
|
||||||
* responses:
|
|
||||||
* 200:
|
|
||||||
* description: Vidéo supprimée avec succès.
|
|
||||||
* 400:
|
|
||||||
* description: ID de vidéo invalide.
|
|
||||||
* 404:
|
|
||||||
* description: Aucune vidéo trouvée avec cet ID.
|
|
||||||
* 500:
|
|
||||||
* description: Erreur serveur.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @swagger
|
|
||||||
* /videos/file/{video_id}:
|
|
||||||
* get:
|
|
||||||
* summary: Retrieve a video by video ID
|
|
||||||
* parameters:
|
|
||||||
* - in: path
|
|
||||||
* name: video_id
|
|
||||||
* required: true
|
|
||||||
* schema:
|
|
||||||
* type: string
|
|
||||||
* description: The video ID
|
|
||||||
* responses:
|
|
||||||
* 200:
|
|
||||||
* description: A video file
|
|
||||||
* content:
|
|
||||||
* application/octet-stream:
|
|
||||||
* schema:
|
|
||||||
* type: string
|
|
||||||
* format: binary
|
|
||||||
* 404:
|
|
||||||
* description: Video not found
|
|
||||||
* 400:
|
|
||||||
* description: Video not yet produced
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @swagger
|
|
||||||
* /cat:
|
|
||||||
* get:
|
|
||||||
* summary: Retrieve a cat video
|
|
||||||
* responses:
|
|
||||||
* 200:
|
|
||||||
* description: A cat video
|
|
||||||
* content:
|
|
||||||
* application/octet-stream:
|
|
||||||
* schema:
|
|
||||||
* type: string
|
|
||||||
* format: binary
|
|
||||||
* 404:
|
|
||||||
* description: Video not found
|
|
||||||
*/
|
|
||||||
@@ -1,260 +0,0 @@
|
|||||||
const express = require('express');
|
|
||||||
const router = express.Router();
|
|
||||||
const serverError = require('../utils/serverError');
|
|
||||||
const database_manager = require('../src/database/database_manager');
|
|
||||||
|
|
||||||
const defaultSettings = {
|
|
||||||
id: 1,
|
|
||||||
interval: null,
|
|
||||||
nb_images: null,
|
|
||||||
maintenance: false,
|
|
||||||
stop_flag: false,
|
|
||||||
idle: true
|
|
||||||
};
|
|
||||||
|
|
||||||
async function camera_initialization() {
|
|
||||||
// si capture.get_camera est vide ou undefined, on l'initialise
|
|
||||||
let current_camera = await database_manager.capture.get_camera();
|
|
||||||
if (!current_camera || current_camera === undefined) {
|
|
||||||
console.log("Initializing camera...");
|
|
||||||
current_camera = await database_manager.capture.init_camera(
|
|
||||||
defaultSettings.id,
|
|
||||||
defaultSettings.interval,
|
|
||||||
defaultSettings.nb_images,
|
|
||||||
defaultSettings.maintenance,
|
|
||||||
defaultSettings.stop_flag,
|
|
||||||
defaultSettings.idle
|
|
||||||
);
|
|
||||||
console.log("Camera initialized:", current_camera);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.log("Camera already initialized:", current_camera);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
camera_initialization()
|
|
||||||
|
|
||||||
async function get_camera_settings() {
|
|
||||||
const settings = await database_manager.capture.get_camera();
|
|
||||||
if (!settings) {
|
|
||||||
// balancer une erreur si la caméra n'est pas initialisée
|
|
||||||
throw new Error("Camera settings not found in the database.");
|
|
||||||
}
|
|
||||||
return settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
router.get('/camera/status', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const settings = await get_camera_settings();
|
|
||||||
res.json(settings);
|
|
||||||
} catch (error) {
|
|
||||||
serverError.sendError('Error getting camera status:', res, error, 500);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
async function stop_procedure() { // côté serveur
|
|
||||||
let new_settings = {
|
|
||||||
stop_flag: true,
|
|
||||||
}
|
|
||||||
await database_manager.capture.edit_camera(1, new_settings);
|
|
||||||
console.log("Stopping camera... en attente de confirmation de la caméra...");
|
|
||||||
}
|
|
||||||
|
|
||||||
async function confirm_stop_procedure() { // côté caméra
|
|
||||||
let new_settings = {
|
|
||||||
interval: null,
|
|
||||||
nb_images: null,
|
|
||||||
stop_flag: false,
|
|
||||||
idle: true,
|
|
||||||
}
|
|
||||||
await database_manager.capture.edit_camera(1, new_settings);
|
|
||||||
let project_settings = {
|
|
||||||
status: 0,
|
|
||||||
}
|
|
||||||
let current_project = await database_manager.project.find_current_rendering_project();
|
|
||||||
if (current_project) {
|
|
||||||
await database_manager.project.edit_project_by_id(current_project.id, project_settings);
|
|
||||||
console.log("Project : " + current_project.id + " stopped.");
|
|
||||||
} else {
|
|
||||||
console.log("No project to stop.");
|
|
||||||
}
|
|
||||||
console.log("Camera stopped.");
|
|
||||||
}
|
|
||||||
|
|
||||||
async function start_procedure(project_id, interval, nb_images) {
|
|
||||||
let new_settings = {
|
|
||||||
interval: interval,
|
|
||||||
nb_images: nb_images,
|
|
||||||
stop_flag: false,
|
|
||||||
idle: false,
|
|
||||||
}
|
|
||||||
console.log("Starting Procedure with settings:", new_settings);
|
|
||||||
await database_manager.capture.edit_camera(1, new_settings);
|
|
||||||
let project_settings = {
|
|
||||||
status: 1,
|
|
||||||
}
|
|
||||||
let existing_project = await database_manager.project.find_current_rendering_project();
|
|
||||||
if (existing_project) {
|
|
||||||
throw new Error("A project is already being rendered. Please stop it before starting a new one.");
|
|
||||||
} else {
|
|
||||||
await database_manager.project.edit_project_by_id(project_id, project_settings);
|
|
||||||
console.log("Project : " + project_id + " started.");
|
|
||||||
}
|
|
||||||
console.log("Camera started.");
|
|
||||||
}
|
|
||||||
|
|
||||||
async function activate_maintenance() {
|
|
||||||
let new_settings = {
|
|
||||||
maintenance: true,
|
|
||||||
}
|
|
||||||
await database_manager.capture.edit_camera(1, new_settings);
|
|
||||||
console.log("Camera in maintenance mode.");
|
|
||||||
}
|
|
||||||
|
|
||||||
async function deactivate_maintenance() {
|
|
||||||
let new_settings = {
|
|
||||||
maintenance: false,
|
|
||||||
}
|
|
||||||
await database_manager.capture.edit_camera(1, new_settings);
|
|
||||||
console.log("Camera out of maintenance mode.");
|
|
||||||
}
|
|
||||||
|
|
||||||
router.post('/procedure/start', async (req, res) => {
|
|
||||||
const { project_id, interval, nb_images } = req.body;
|
|
||||||
if (!interval || !nb_images) {
|
|
||||||
return res.status(400).json({ error: 'Interval and number of images are required' });
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
await start_procedure(project_id, interval, nb_images);
|
|
||||||
res.json({ message: 'Camera started successfully', settings: { interval, nb_images } });
|
|
||||||
} catch (error) {
|
|
||||||
serverError.sendError('Error starting camera procedure:', res, error, 500);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
router.post('/procedure/stop', async (req, res) => {
|
|
||||||
try {
|
|
||||||
await stop_procedure();
|
|
||||||
res.json({ message: 'Camera stop procedure initiated successfully' });
|
|
||||||
} catch (error) {
|
|
||||||
serverError.sendError('Error stopping camera procedure:', res, error, 500);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
router.post('/camera/stop', async (req, res) => {
|
|
||||||
try {
|
|
||||||
await confirm_stop_procedure();
|
|
||||||
res.json({ message: 'Camera stopped successfully' });
|
|
||||||
} catch (error) {
|
|
||||||
serverError.sendError('Error stopping camera:', res, error, 500);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @swagger
|
|
||||||
* /camera/status:
|
|
||||||
* get:
|
|
||||||
* summary: Get the current camera settings
|
|
||||||
* responses:
|
|
||||||
* 200:
|
|
||||||
* description: Successfully retrieved camera settings
|
|
||||||
* content:
|
|
||||||
* application/json:
|
|
||||||
* schema:
|
|
||||||
* type: object
|
|
||||||
* properties:
|
|
||||||
* id:
|
|
||||||
* type: integer
|
|
||||||
* interval:
|
|
||||||
* type: integer
|
|
||||||
* nb_images:
|
|
||||||
* type: integer
|
|
||||||
* maintenance:
|
|
||||||
* type: boolean
|
|
||||||
* stop_flag:
|
|
||||||
* type: boolean
|
|
||||||
* idle:
|
|
||||||
* type: boolean
|
|
||||||
* 500:
|
|
||||||
* description: Error retrieving camera settings
|
|
||||||
*
|
|
||||||
* /procedure/start:
|
|
||||||
* post:
|
|
||||||
* summary: Start the camera procedure
|
|
||||||
* requestBody:
|
|
||||||
* required: true
|
|
||||||
* content:
|
|
||||||
* application/json:
|
|
||||||
* schema:
|
|
||||||
* type: object
|
|
||||||
* properties:
|
|
||||||
* project_id:
|
|
||||||
* type: integer
|
|
||||||
* interval:
|
|
||||||
* type: integer
|
|
||||||
* nb_images:
|
|
||||||
* type: integer
|
|
||||||
* responses:
|
|
||||||
* 200:
|
|
||||||
* description: Camera started successfully
|
|
||||||
* 400:
|
|
||||||
* description: Interval and number of images are required
|
|
||||||
* 500:
|
|
||||||
* description: Error starting camera procedure
|
|
||||||
*
|
|
||||||
* /procedure/stop:
|
|
||||||
* post:
|
|
||||||
* summary: Initiate the camera stop procedure
|
|
||||||
* responses:
|
|
||||||
* 200:
|
|
||||||
* description: Camera stop procedure initiated successfully
|
|
||||||
* 500:
|
|
||||||
* description: Error stopping camera procedure
|
|
||||||
*
|
|
||||||
* /camera/stop:
|
|
||||||
* post:
|
|
||||||
* summary: Confirm the camera stop procedure
|
|
||||||
* responses:
|
|
||||||
* 200:
|
|
||||||
* description: Camera stopped successfully
|
|
||||||
* 500:
|
|
||||||
* description: Error stopping camera
|
|
||||||
*
|
|
||||||
* /camera/maintenance:
|
|
||||||
* post:
|
|
||||||
* summary: Activate maintenance mode for the camera
|
|
||||||
* responses:
|
|
||||||
* 200:
|
|
||||||
* description: Camera in maintenance mode
|
|
||||||
* 500:
|
|
||||||
* description: Error activating maintenance mode
|
|
||||||
*
|
|
||||||
* /camera/maintenance/deactivate:
|
|
||||||
* post:
|
|
||||||
* summary: Deactivate maintenance mode for the camera
|
|
||||||
* responses:
|
|
||||||
* 200:
|
|
||||||
* description: Camera out of maintenance mode
|
|
||||||
* 500:
|
|
||||||
* description: Error deactivating maintenance mode
|
|
||||||
*/
|
|
||||||
router.post('/camera/maintenance', async (req, res) => {
|
|
||||||
try {
|
|
||||||
await activate_maintenance();
|
|
||||||
res.json({ message: 'Camera in maintenance mode' });
|
|
||||||
} catch (error) {
|
|
||||||
serverError.sendError('Error activating maintenance mode:', res, error, 500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
router.post('/camera/maintenance/deactivate', async (req, res) => {
|
|
||||||
try {
|
|
||||||
await deactivate_maintenance();
|
|
||||||
res.json({ message: 'Camera out of maintenance mode' });
|
|
||||||
} catch (error) {
|
|
||||||
serverError.sendError('Error deactivating maintenance mode:', res, error, 500);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = router;
|
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
const express = require('express');
|
|
||||||
const router = express.Router();
|
|
||||||
const sharp = require('sharp');
|
|
||||||
const fs = require('fs');
|
|
||||||
const dbTester = require('../test/tester');
|
|
||||||
const db = require('../db');
|
|
||||||
const serverError = require('../utils/serverError');
|
|
||||||
|
|
||||||
router.get('/smile', (req, res) => {
|
|
||||||
const imagePath = dbTester.getSmileImage();
|
|
||||||
fs.access(imagePath, fs.constants.F_OK, (err) => {
|
|
||||||
if (err) {
|
|
||||||
console.error('Image not found:', err);
|
|
||||||
return res.status(404).json({ error: 'Image not found' });
|
|
||||||
}
|
|
||||||
res.sendFile(imagePath);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
router.get('/images/:projectId/:orderId', (req, res) => {
|
|
||||||
const projectId = req.params.projectId;
|
|
||||||
const orderId = req.params.orderId;
|
|
||||||
const query = 'SELECT path FROM public.measurements WHERE project_id = $1 AND order_id = $2';
|
|
||||||
db.query(query, [projectId, orderId], (err, results) => {
|
|
||||||
if (err) {
|
|
||||||
return serverError.sendError('Error getting image:', res, err, 500);
|
|
||||||
}
|
|
||||||
if (results.rows.length === 0) {
|
|
||||||
return res.status(404).json({ error: 'Image not found' });
|
|
||||||
}
|
|
||||||
const imagePath = results.rows[0].path;
|
|
||||||
fs.access(imagePath, fs.constants.F_OK, (err) => {
|
|
||||||
if (err) {
|
|
||||||
console.error('Image not found:', err);
|
|
||||||
return res.status(404).json({ error: 'Image not found' });
|
|
||||||
}
|
|
||||||
res.download(imagePath);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
router.get('/images/:measurementId', (req, res) => {
|
|
||||||
const measurementId = req.params.measurementId;
|
|
||||||
const query = 'SELECT path FROM public.measurements WHERE id = $1';
|
|
||||||
db.query(query, [measurementId], (err, results) => {
|
|
||||||
if (err) {
|
|
||||||
return serverError.sendError('Error getting image:', res, err, 500);
|
|
||||||
}
|
|
||||||
if (results.rows.length === 0) {
|
|
||||||
return res.status(404).json({ error: 'Image not found' });
|
|
||||||
}
|
|
||||||
const imagePath = results.rows[0].path;
|
|
||||||
fs.access(imagePath, fs.constants.F_OK, (err) => {
|
|
||||||
if (err) {
|
|
||||||
console.error('Image not found:', err);
|
|
||||||
return res.status(404).json({ error: 'Image not found' });
|
|
||||||
}
|
|
||||||
res.download(imagePath);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const getImagePath = async (projectId, orderId) => {
|
|
||||||
const query = 'SELECT path FROM public.measurements WHERE project_id = $1 AND order_id = $2';
|
|
||||||
const result = await db.query(query, [projectId, orderId]);
|
|
||||||
if (result.rows.length === 0) {
|
|
||||||
throw new Error('Image not found');
|
|
||||||
}
|
|
||||||
return result.rows[0].path;
|
|
||||||
};
|
|
||||||
|
|
||||||
const checkImageExists = (imagePath) => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
fs.access(imagePath, fs.constants.F_OK, (err) => {
|
|
||||||
if (err) {
|
|
||||||
reject(new Error('Image not found'));
|
|
||||||
} else {
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const resizeImage = async (imagePath) => {
|
|
||||||
const metadata = await sharp(imagePath).metadata();
|
|
||||||
const width = Math.floor(metadata.width / 7);
|
|
||||||
const height = Math.floor(metadata.height / 7);
|
|
||||||
return sharp(imagePath)
|
|
||||||
.resize(width, height)
|
|
||||||
.jpeg({ quality: 65 })
|
|
||||||
.toBuffer();
|
|
||||||
};
|
|
||||||
|
|
||||||
router.get('/preview/:projectId/:orderId', async (req, res) => {
|
|
||||||
const projectId = req.params.projectId;
|
|
||||||
const orderId = req.params.orderId;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const imagePath = await getImagePath(projectId, orderId);
|
|
||||||
await checkImageExists(imagePath);
|
|
||||||
const resizedImage = await resizeImage(imagePath);
|
|
||||||
|
|
||||||
res.set('Content-Type', 'image/jpeg');
|
|
||||||
res.send(resizedImage);
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Error getting image preview:', err);
|
|
||||||
if (err.message === 'Image not found') {
|
|
||||||
return res.status(404).json({ error: 'Image not found' });
|
|
||||||
}
|
|
||||||
return res.status(500).json({ error: 'Internal Server Error' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = router;
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
const express = require('express');
|
|
||||||
const router = express.Router();
|
|
||||||
const database_manager = require('../src/database/database_manager');
|
|
||||||
|
|
||||||
router.get('/measurements', async (req, res) => {
|
|
||||||
const measurements = await database_manager.measurement.get_all_measurements();
|
|
||||||
if (!measurements) {
|
|
||||||
return res.status(404).json({ error: 'No measurements found' });
|
|
||||||
}
|
|
||||||
res.json(measurements);
|
|
||||||
});
|
|
||||||
|
|
||||||
router.get('/measurements/:id', async (req, res) => {
|
|
||||||
const measurement = await database_manager.measurement.get_measurement_by_id(req.params.id);
|
|
||||||
if (!measurement) {
|
|
||||||
return res.status(404).json({ error: 'Measurement not found' });
|
|
||||||
}
|
|
||||||
res.json(measurement);
|
|
||||||
});
|
|
||||||
|
|
||||||
router.get('/measurements/:projectId/:orderId', async (req, res) => {
|
|
||||||
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.delete('/measurements/:id', async (req, res) => {
|
|
||||||
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 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;
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
const express = require('express');
|
|
||||||
const router = express.Router();
|
|
||||||
const serverError = require('../utils/serverError');
|
|
||||||
const database_manager = require('../src/database/database_manager');
|
|
||||||
const storage_manager = require('../src/data/storage_manager');
|
|
||||||
|
|
||||||
router.get('/projects', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const projects = await database_manager.project.get_all_projects();
|
|
||||||
res.json(projects);
|
|
||||||
} catch (error) {
|
|
||||||
serverError.sendError('Error getting all projects:', res, error, 500);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
router.get('/projects/:id', async (req, res) => {
|
|
||||||
const projectId = req.params.id;
|
|
||||||
if (!projectId || isNaN(projectId)) {
|
|
||||||
return res.status(400).json({ error: 'Invalid project ID' });
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const project = await database_manager.project.get_project_by_id(projectId);
|
|
||||||
res.json(project);
|
|
||||||
} catch (error) {
|
|
||||||
serverError.sendError('Error getting project by ID:', res, error, 500);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
router.get('/projects/:id/videos', async (req, res) => {
|
|
||||||
const projectId = req.params.id;
|
|
||||||
if (!projectId || isNaN(projectId)) {
|
|
||||||
return res.status(400).json({ error: 'Invalid project ID' });
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const videos = await database_manager.video.get_videos_by_project_id(projectId);
|
|
||||||
if (videos.length === 0) {
|
|
||||||
return res.status(404).json({ error: 'No videos found for this project' });
|
|
||||||
}
|
|
||||||
res.json(videos);
|
|
||||||
} catch (error) {
|
|
||||||
serverError.sendError('Error getting videos by project ID:', res, error, 500);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
router.get('/projects/:id/measurements', async (req, res) => {
|
|
||||||
const projectId = req.params.id;
|
|
||||||
if (!projectId || isNaN(projectId)) {
|
|
||||||
return res.status(400).json({ error: 'Invalid project ID' });
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const measurements = await database_manager.measurement.get_measurements_by_project_id(projectId);
|
|
||||||
if (measurements.length === 0) {
|
|
||||||
return res.status(404).json({ error: 'No measurements found for this project' });
|
|
||||||
}
|
|
||||||
res.json(measurements);
|
|
||||||
} catch (error) {
|
|
||||||
serverError.sendError('Error getting measurements by project ID:', res, error, 500);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
router.post('/projects', async (req, res) => {
|
|
||||||
const { name, description } = req.body;
|
|
||||||
if (!name || !description) {
|
|
||||||
return res.status(400).json({ error: 'Name and description are required' });
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const date = new Date();
|
|
||||||
const default_status = 0;
|
|
||||||
const project = await database_manager.project.create_project(name, description, date, default_status);
|
|
||||||
storage_manager.project.createProjectDirectory(project.id);
|
|
||||||
res.status(201).json({ message: 'Project added successfully', id: project.id });
|
|
||||||
} catch (error) {
|
|
||||||
serverError.sendError('Error creating project:', res, error, 500);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
router.delete('/projects/:id', async (req, res) => {
|
|
||||||
const projectId = req.params.id;
|
|
||||||
if (!projectId || isNaN(projectId)) {
|
|
||||||
return res.status(400).json({ error: 'Invalid project ID' });
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
storage_manager.project.deleteProjectDirectory(projectId);
|
|
||||||
await database_manager.project.delete_project_by_id(projectId);
|
|
||||||
res.status(200).json({ message: 'Project deleted successfully', id: projectId });
|
|
||||||
} catch (error) {
|
|
||||||
serverError.sendError('Error deleting project:', res, error, 500);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = router;
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
const express = require('express');
|
|
||||||
const router = express.Router();
|
|
||||||
const multer = require('multer');
|
|
||||||
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() });
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @swagger
|
|
||||||
* /camera/upload:
|
|
||||||
* post:
|
|
||||||
* summary: Télécharger une mesure avec une image
|
|
||||||
* description: Télécharge une mesure avec une image pour un projet spécifique.
|
|
||||||
* requestBody:
|
|
||||||
* content:
|
|
||||||
* multipart/form-data:
|
|
||||||
* schema:
|
|
||||||
* type: object
|
|
||||||
* properties:
|
|
||||||
* image:
|
|
||||||
* type: string
|
|
||||||
* format: binary
|
|
||||||
* description: Fichier image à télécharger
|
|
||||||
* projectId:
|
|
||||||
* type: integer
|
|
||||||
* description: ID du projet
|
|
||||||
* timestamp:
|
|
||||||
* type: string
|
|
||||||
* format: date-time
|
|
||||||
* description: Horodatage de la mesure
|
|
||||||
* temperature:
|
|
||||||
* type: number
|
|
||||||
* description: Température mesurée
|
|
||||||
* humidity:
|
|
||||||
* type: number
|
|
||||||
* description: Humidité mesurée
|
|
||||||
* responses:
|
|
||||||
* 200:
|
|
||||||
* description: Mesure téléchargée avec succès.
|
|
||||||
* content:
|
|
||||||
* application/json:
|
|
||||||
* schema:
|
|
||||||
* type: object
|
|
||||||
* properties:
|
|
||||||
* message:
|
|
||||||
* type: string
|
|
||||||
* path:
|
|
||||||
* type: string
|
|
||||||
* id:
|
|
||||||
* type: integer
|
|
||||||
* 400:
|
|
||||||
* description: Tous les champs sont requis.
|
|
||||||
* 500:
|
|
||||||
* description: Erreur serveur.
|
|
||||||
*/
|
|
||||||
router.post('/camera/upload', upload.single('image'), async (req, res) => {
|
|
||||||
//afficher le body de la requête
|
|
||||||
console.log(req.body);
|
|
||||||
const { projectId, timestamp, temperature, humidity } = req.body;
|
|
||||||
const image = req.file;
|
|
||||||
|
|
||||||
if (!image || !projectId || !timestamp || !temperature || !humidity) {
|
|
||||||
return res.status(400).json({ error: 'All fields are required' });
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
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:', {
|
|
||||||
image: typeof image,
|
|
||||||
projectId: typeof projectId,
|
|
||||||
nextOrderId: typeof 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.create_measurement(projectId, timestamp, imagePath, temperature, humidity, nextOrderId);
|
|
||||||
if (!measurement) {
|
|
||||||
return res.status(500).json({ error: 'Failed to create measurement' });
|
|
||||||
}
|
|
||||||
res.json({ message: 'Measurement uploaded successfully', path: imagePath, id: measurement.id });
|
|
||||||
} catch (error) {
|
|
||||||
serverError.sendError('Error uploading measurement:', res, error, 500);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = router;
|
|
||||||
@@ -1,271 +0,0 @@
|
|||||||
const express = require('express');
|
|
||||||
const router = express.Router();
|
|
||||||
const db = require('../db');
|
|
||||||
const fs = require('fs');
|
|
||||||
const rangeParser = require('range-parser');
|
|
||||||
const serverError = require('../utils/serverError');
|
|
||||||
const videoManager = require('../src/video/videoManager');
|
|
||||||
const database_manager = require('../src/database/database_manager');
|
|
||||||
const storage_manager = require('../src/data/storage_manager');
|
|
||||||
const dbTester = require('../test/tester');
|
|
||||||
|
|
||||||
router.get('/videos', (req, res) => {
|
|
||||||
const query = 'SELECT * FROM public.videos';
|
|
||||||
db.query(query, (err, results) => {
|
|
||||||
if (err) {
|
|
||||||
serverError.sendError('Erreur lors de la récupération des vidéos:', res, err, 500);
|
|
||||||
}
|
|
||||||
res.json(results.rows);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
router.get('/videos/:id', (req, res) => {
|
|
||||||
const videoId = req.params.id;
|
|
||||||
if (!videoId || isNaN(videoId)) {
|
|
||||||
return res.status(400).json({ error: 'Invalid video ID' });
|
|
||||||
}
|
|
||||||
const query = 'SELECT * FROM public.videos WHERE id = $1';
|
|
||||||
db.query(query, [videoId], (err, results) => {
|
|
||||||
if (err) {
|
|
||||||
serverError.sendError('Erreur lors de la récupération de la vidéo:', res, err, 500);
|
|
||||||
}
|
|
||||||
res.json(results.rows);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
router.post('/videos', async (req, res) => {
|
|
||||||
const { project_id, measurement_ids, name, resolution, duration } = req.body;
|
|
||||||
console.log('Creating video:', req.body);
|
|
||||||
if (!project_id || !measurement_ids || !name || !resolution || !duration) {
|
|
||||||
return res.status(400).json({ error: 'Tous les champs sont requis.' });
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('Creating video with measurements:', measurement_ids);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const query = await database_manager.video.create_video(project_id, measurement_ids, name, resolution, duration);
|
|
||||||
const videoId = query.id;
|
|
||||||
if (!videoId) {
|
|
||||||
return res.status(500).json({ error: 'Erreur lors de la création de la vidéo' });
|
|
||||||
}
|
|
||||||
console.log('Vidéo créée avec succès:', videoId);
|
|
||||||
|
|
||||||
// Start rendering the video immediately after creation
|
|
||||||
// const result = await db.query(
|
|
||||||
// 'SELECT measurement_ids, project_id, duration FROM public.videos WHERE id = $1',
|
|
||||||
// [videoId]
|
|
||||||
// );
|
|
||||||
|
|
||||||
// if (result.rows.length === 0) {
|
|
||||||
// return res.status(404).json({ error: 'Vidéo non trouvée' });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// récupérer les informations de la vidéo
|
|
||||||
const result = await database_manager.video.get_video_by_id(videoId);
|
|
||||||
|
|
||||||
if (!result) {
|
|
||||||
return res.status(404).json({ error: 'Vidéo non trouvée' });
|
|
||||||
}
|
|
||||||
|
|
||||||
const videoDuration = result.duration;
|
|
||||||
const videoMeasurementIds = result.measurement_ids;
|
|
||||||
const videoProjectId = result.project_id;
|
|
||||||
|
|
||||||
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);
|
|
||||||
if (isNaN(res_width) || isNaN(res_height)) {
|
|
||||||
return res.status(400).json({ error: 'Invalid resolution format. Use WIDTHxHEIGHT (e.g., 1920x1080)' });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start background processing
|
|
||||||
videoManager.createVideoWithList(videoProjectId, pathList, videoDuration, videoId, res_width, res_height)
|
|
||||||
.then(videoFile => {
|
|
||||||
console.log('Rendu vidéo terminé:', videoFile);
|
|
||||||
return database_manager.video.update_video_file_path_by_id(videoId, videoFile);
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error('Échec du rendu vidéo:', error);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Immediate response
|
|
||||||
res.json({
|
|
||||||
message: 'Vidéo créée avec succès et le rendu a démarré',
|
|
||||||
id: videoId
|
|
||||||
});
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Erreur lors de la création de la vidéo:', err);
|
|
||||||
res.status(500).json({ error: 'Erreur lors de la création de la vidéo' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
router.delete('/videos/:id', (req, res) => {
|
|
||||||
const videoId = req.params.id;
|
|
||||||
if (!videoId || isNaN(videoId)) {
|
|
||||||
return res.status(400).json({ error: 'Invalid video ID' });
|
|
||||||
}
|
|
||||||
|
|
||||||
const query = 'SELECT video_file FROM public.videos WHERE id = $1';
|
|
||||||
db.query(query, [videoId], (err, results) => {
|
|
||||||
if (err) {
|
|
||||||
return serverError.sendError('Error getting video:', res, err, 500);
|
|
||||||
}
|
|
||||||
if (results.rows.length === 0) {
|
|
||||||
return res.status(404).json({ error: 'Video not found' });
|
|
||||||
}
|
|
||||||
|
|
||||||
const videoFile = results.rows[0].video_file;
|
|
||||||
console.log('Deleting video file:', videoFile);
|
|
||||||
|
|
||||||
if(videoFile==null){
|
|
||||||
console.log('No video file to delete');
|
|
||||||
database_manager.video.delete_video_by_id(videoId).then(() => {
|
|
||||||
res.json({ message: 'Vidéo supprimée avec succès' });
|
|
||||||
}).catch(err => {
|
|
||||||
console.error('Erreur lors de la suppression de la vidéo:', err);
|
|
||||||
res.status(500).json({ error: 'Erreur lors de la suppression de la vidéo' });
|
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
|
||||||
fs.unlink(videoFile, (err) => {
|
|
||||||
if (err) {
|
|
||||||
console.error('Error deleting video file:', err);
|
|
||||||
return res.status(500).json({ error: 'Error deleting video file' });
|
|
||||||
}
|
|
||||||
database_manager.video.delete_video_by_id(videoId).then(() => {
|
|
||||||
res.json({ message: 'Vidéo supprimée avec succès' });
|
|
||||||
}).catch(err => {
|
|
||||||
console.error('Erreur lors de la suppression de la vidéo:', err);
|
|
||||||
res.status(500).json({ error: 'Erreur lors de la suppression de la vidéo' });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
router.get('/videos/file/:video_id', (req, res) => {
|
|
||||||
const videoId = req.params.video_id;
|
|
||||||
const query = 'SELECT video_file, status FROM public.videos WHERE id = $1';
|
|
||||||
|
|
||||||
db.query(query, [videoId], (err, results) => {
|
|
||||||
if (err) {
|
|
||||||
console.error('Error getting video:', err);
|
|
||||||
return serveFallbackVideo(res);
|
|
||||||
}
|
|
||||||
if (results.rows.length === 0) {
|
|
||||||
console.error('Video not found');
|
|
||||||
return serveFallbackVideo(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
const video = results.rows[0];
|
|
||||||
if (video.status === 0) {
|
|
||||||
return res.status(400).json({ error: 'Video not yet produced' });
|
|
||||||
}
|
|
||||||
|
|
||||||
let videoPath = video.video_file;
|
|
||||||
|
|
||||||
if (!videoPath) {
|
|
||||||
console.error('Video file path is null or undefined');
|
|
||||||
videoPath = dbTester.getCatVideo();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the video file exists
|
|
||||||
fs.access(videoPath, fs.constants.F_OK, (err) => {
|
|
||||||
if (err) {
|
|
||||||
console.error('Video file not found:', err);
|
|
||||||
videoPath = dbTester.getCatVideo();
|
|
||||||
}
|
|
||||||
|
|
||||||
const stat = fs.statSync(videoPath);
|
|
||||||
const fileSize = stat.size;
|
|
||||||
const range = req.headers.range;
|
|
||||||
|
|
||||||
if (range) {
|
|
||||||
const parts = rangeParser(fileSize, range);
|
|
||||||
const start = parts[0].start;
|
|
||||||
const end = parts[0].end;
|
|
||||||
const chunksize = (end - start) + 1;
|
|
||||||
const file = fs.createReadStream(videoPath, { start, end });
|
|
||||||
const head = {
|
|
||||||
'Content-Range': `bytes ${start}-${end}/${fileSize}`,
|
|
||||||
'Accept-Ranges': 'bytes',
|
|
||||||
'Content-Length': chunksize,
|
|
||||||
'Content-Type': 'video/mp4',
|
|
||||||
};
|
|
||||||
res.writeHead(206, head);
|
|
||||||
file.pipe(res);
|
|
||||||
} else {
|
|
||||||
const head = {
|
|
||||||
'Content-Length': fileSize,
|
|
||||||
'Content-Type': 'video/mp4',
|
|
||||||
};
|
|
||||||
res.writeHead(200, head);
|
|
||||||
fs.createReadStream(videoPath).pipe(res);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function serveFallbackVideo() {
|
|
||||||
return dbTester.getCatVideo();
|
|
||||||
}
|
|
||||||
|
|
||||||
router.get('/videos/progress/:video_id', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const result = await db.query(`
|
|
||||||
SELECT
|
|
||||||
progress,
|
|
||||||
EXTRACT(EPOCH FROM (NOW() - started_at)) as elapsed,
|
|
||||||
eta,
|
|
||||||
status
|
|
||||||
FROM public.videos
|
|
||||||
WHERE id = $1
|
|
||||||
`, [req.params.video_id]);
|
|
||||||
|
|
||||||
if (result.rows.length === 0) {
|
|
||||||
return res.status(404).json({ error: 'Vidéo non trouvée' });
|
|
||||||
}
|
|
||||||
|
|
||||||
const video = result.rows[0];
|
|
||||||
res.json({
|
|
||||||
progress: video.progress,
|
|
||||||
elapsed: video.elapsed,
|
|
||||||
eta: video.eta,
|
|
||||||
status: this.getStatusLabel(video.status)
|
|
||||||
});
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
res.status(500).json({ error: 'Erreur de récupération' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// function getStatusLabel(status) {
|
|
||||||
// const statusMap = {
|
|
||||||
// 0: 'En attente',
|
|
||||||
// 1: 'Terminé',
|
|
||||||
// 2: 'Échec',
|
|
||||||
// 3: 'En cours'
|
|
||||||
// };
|
|
||||||
// return statusMap[status] || 'Inconnu';
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
router.get('/cat', (_, res) => {
|
|
||||||
const videoPath = dbTester.getCatVideo();
|
|
||||||
fs.access(videoPath, fs.constants.F_OK, (err) => {
|
|
||||||
if (err) {
|
|
||||||
console.error('Video not found:', err);
|
|
||||||
return res.status(404).json({ error: 'Video not found' });
|
|
||||||
}
|
|
||||||
res.download(videoPath);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = router;
|
|
||||||
Reference in New Issue
Block a user