Spaces:
Sleeping
Sleeping
File size: 11,531 Bytes
3b6bb5e |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 |
const { execFile } = require('child_process');
const http = require('http');
const fs = require('fs');
const path = require('path');
const formidable = require('formidable'); // Ajout de formidable pour analyser les requêtes multipart/form-data
// Importer dotenv pour gérer les variables d'environnement
require('dotenv').config();
const { Storage } = require('@google-cloud/storage');
// Si la variable GOOGLE_APPLICATION_CREDENTIALS n'est pas définie, on la définit ici.
if (!process.env.GOOGLE_APPLICATION_CREDENTIALS) {
process.env.GOOGLE_APPLICATION_CREDENTIALS = path.join(__dirname, 'service-key.json');
}
// Instancier le client Google Cloud Storage
const storage = new Storage();
const bucketName = "test3-2d896.appspot.com";
// Chemin vers le dossier contenant les fichiers statiques
const staticDir = path.join(__dirname, 'public');
// Fonction pour servir les fichiers statiques
function serveStaticFile(req, res) {
let filePath = path.join(staticDir, req.url === '/' ? 'index.html' : req.url);
// Normalisez le chemin pour éviter des caractères relatifs comme "../"
filePath = path.normalize(filePath);
// Vérifiez que le fichier demandé reste dans le dossier `public`
if (!filePath.startsWith(staticDir)) {
res.writeHead(403, { 'Content-Type': 'text/plain' });
res.end('Accès refusé');
return;
}
// Vérifiez si le fichier existe
fs.stat(filePath, (err, stats) => {
if (err || !stats.isFile()) {
res.writeHead(404, { 'Content-Type': 'text/plain' });
res.end('Fichier non trouvé');
return;
}
// Détecte le type MIME basé sur l'extension
const ext = path.extname(filePath).toLowerCase();
const mimeTypes = {
'.html': 'text/html',
'.css': 'text/css',
'.js': 'application/javascript',
'.json': 'application/json',
'.png': 'image/png',
'.jpg': 'image/jpeg',
'.svg': 'image/svg+xml',
'.wasm': 'application/wasm',
};
const contentType = mimeTypes[ext] || 'application/octet-stream';
// Lit et sert le fichier
fs.readFile(filePath, (err, data) => {
if (err) {
res.writeHead(500, { 'Content-Type': 'text/plain' });
res.end('Erreur du serveur');
return;
}
res.writeHead(200, { 'Content-Type': contentType });
res.end(data);
});
});
}
const server = http.createServer((req, res) => {
// Ajouter les en-têtes CORS nécessaires pour toutes les requêtes
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
// Gérer les requêtes OPTIONS (préflight request)
if (req.method === 'OPTIONS') {
res.writeHead(204);
res.end();
return;
}
// Servir les fichiers statiques pour les requêtes GET
if (req.method === 'GET') {
serveStaticFile(req, res);
return;
}
// Endpoint : Création des données JSON pour une visite
if (req.method === 'POST' && req.url === '/create-visite-data') {
const bucketName = "test3-2d896.appspot.com";
const form = new formidable.IncomingForm();
form.parse(req, async (err, fields) => {
if (err) {
console.error('Erreur lors de l\'analyse de la requête :', err);
res.writeHead(400, { 'Content-Type': 'text/plain' });
res.end('Erreur lors de l\'analyse de la requête.');
return;
}
try {
console.log('Métadonnées brutes reçues :', fields.metadata); // Log des données brutes
const metadata = JSON.parse(fields.metadata || '{}'); // Parse en JSON
console.log('Métadonnées analysées :', metadata);
} catch (parseError) {
console.error('Erreur lors du parsing JSON :', parseError);
res.writeHead(400, { 'Content-Type': 'text/plain' });
res.end('Erreur dans le format du JSON envoyé.');
}
});
return;
}
if (req.method === 'POST' && req.url === '/upload-to-gcs') {
let body = '';
req.on('data', chunk => {
body += chunk.toString(); // Convertir les chunks en chaîne
});
req.on('end', () => {
try {
// Analysez le corps de la requête en JSON
const { folderPath, jsonData } = JSON.parse(body);
// Loguer le chemin du dossier et les données pour voir ce qui est reçu
console.log('Chemin du dossier:', folderPath);
console.log('Données JSON:', JSON.stringify(jsonData, null, 2));
// Chemin vers le script local_script.js
const scriptPath = path.resolve(__dirname, 'local_script.js'); // Utilisez path.resolve pour obtenir un chemin absolu
console.log(`Chemin absolu du script : ${scriptPath}`);
// Exécuter le script Node.js avec les paramètres appropriés
const args = [folderPath, JSON.stringify(jsonData)];
console.log(`Commande exécutée : node ${scriptPath} ${args.join(' ')}`); // Affichez la commande exécutée pour vérification
// Augmentez maxBuffer si nécessaire pour éviter les problèmes liés à la taille des logs
execFile('node', [scriptPath, ...args], { maxBuffer: 1024 * 1024 * 50 }, (error, stdout, stderr) => {
if (error) {
console.error(`Erreur lors de l'exécution de local_script.js :`, error);
console.error(`stderr:`, stderr);
res.writeHead(500, { 'Content-Type': 'text/plain' });
res.end('Erreur lors du téléversement.');
return; // Sortir pour éviter un double envoi
} else {
console.log(`Téléversement réussi : ${stdout}`);
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Fichier téléversé avec succès vers Google Cloud Storage.');
}
});
} catch (parseError) {
console.error('Erreur lors de la lecture du corps de la requête:', parseError);
res.writeHead(400, { 'Content-Type': 'text/plain' });
res.end('Erreur de format du corps de la requête.');
}
});
return; // Sortir après avoir traité cette route
}
if (req.method === 'POST' && req.url === '/create-visit') {
const form = new formidable.IncomingForm();
form.multiples = true;
form.uploadDir = './uploads';
if (!fs.existsSync(form.uploadDir)) {
fs.mkdirSync(form.uploadDir, { recursive: true });
}
const bucketName = "test3-2d896.appspot.com";
form.parse(req, async (err, fields, files) => {
if (err) {
console.error('Erreur lors de l\'analyse de la requête :', err);
res.writeHead(400, { 'Content-Type': 'text/plain' });
res.end('Erreur lors de l\'analyse de la requête.');
return;
}
try {
const metadata = JSON.parse(fields.metadata || '{}');
const { jsonData } = metadata;
console.log('Données JSON reçues :', jsonData);
const folderName = jsonData.folderName;
if (!folderName) {
throw new Error("Nom de dossier (folderName) manquant ou incorrect.");
}
console.log('Nom du dossier pour les fichiers téléversés :', folderName);
const uploadedFiles = Array.isArray(files.files) ? files.files : [files.files];
const uploadedUrls = [];
for (const file of uploadedFiles) {
const destinationPath = `${folderName}/${file.originalFilename}`;
console.log(`Téléversement du fichier : ${destinationPath}`);
await storage.bucket(bucketName).upload(file.filepath, {
destination: destinationPath,
metadata: {
contentType: file.mimetype,
},
});
uploadedUrls.push(`https://storage.googleapis.com/${bucketName}/${destinationPath}`);
}
jsonData.mediaUrls = uploadedUrls;
const jsonFilePath = `${folderName}/visit_data.json`;
const jsonBuffer = Buffer.from(JSON.stringify(jsonData, null, 2));
console.log(`Téléversement du fichier JSON : ${jsonFilePath}`);
await storage.bucket(bucketName).file(jsonFilePath).save(jsonBuffer, {
contentType: 'application/json',
});
console.log('Fichiers et données téléversés avec succès.');
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
success: true,
message: 'Données de la visite téléversées avec succès.',
jsonFilePath,
}));
} catch (error) {
console.error('Erreur lors du traitement des données :', error);
res.writeHead(500, { 'Content-Type': 'text/plain' });
res.end('Erreur lors du traitement des données.');
}
});
return;
}
// Route pour générer une URL signée
if (req.method === 'POST' && req.url === '/generate-signed-url') {
let body = '';
req.on('data', chunk => {
body += chunk.toString();
});
req.on('end', async () => {
try {
// Extraire le `dirUrl` du corps de la requête
const { dirUrl } = JSON.parse(body);
if (!dirUrl) {
res.writeHead(400, { 'Content-Type': 'text/plain' });
res.end('dirUrl est manquant');
return;
}
// Nettoyer les segments relatifs du chemin avant de générer l'URL signée
const cleanedDirUrl = dirUrl.replace(/\/?\.\.\//g, '');
const bucketName = 'test3-2d896.appspot.com';
const filePath = `users/visite_3D/${cleanedDirUrl}`; // Utiliser le chemin nettoyé sans encodage
const options = {
version: 'v4',
action: 'read',
expires: Date.now() + 15 * 60 * 1000, // URL valable pour 15 minutes
};
// Générer une URL signée (GCS s'occupe de l'encodage)
const [url] = await storage.bucket(bucketName).file(filePath).getSignedUrl(options);
console.log(`URL signée générée : ${url}`);
// Répondre avec l'URL signée
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ url }));
} catch (error) {
console.error('Erreur lors de la génération de l\'URL signée:', error);
res.writeHead(500, { 'Content-Type': 'text/plain' });
res.end('Erreur lors de la génération de l\'URL signée.');
}
});
return;
}
// Nouvelle route pour obtenir le GCS token
if (req.method === 'GET' && req.url === '/get-gcs-token') {
try {
// Générez ou récupérez le token GCS ici
const gcsToken = '9be5e912-95e8-4e13-841e-8be3bf99505d'; // Remplacez cela par la méthode de génération dynamique si nécessaire
// Répondre avec le token
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ token: gcsToken }));
} catch (error) {
console.error('Erreur lors de la récupération du jeton GCS:', error);
res.writeHead(500, { 'Content-Type': 'text/plain' });
res.end('Erreur lors de la récupération du jeton GCS.');
}
return;
}
// Si aucune des routes n'est trouvée, envoyer une réponse 404
res.writeHead(404, { 'Content-Type': 'text/plain' });
res.end('Route non trouvée');
});
server.listen(7860, () => {
console.log('Serveur en écoute sur le port 7860');
});
|