#!/usr/bin/env python3 from flask import Flask, jsonify, request, send_file from flask_cors import CORS import h5py import json from pathlib import Path import re app = Flask(__name__) CORS(app) H5_DIR = Path('/home/floppyrj45/docker/seismic-nodes-viewer/data/h5') DOCS_DIR = Path('/home/floppyrj45/docker/seismic-nodes-viewer/data/docs') @app.route('/api/h5/files', methods=['GET']) def list_files(): try: files = [] for h5_file in sorted(H5_DIR.glob('*.h5')): match = re.search(r'rsn(\d+)', h5_file.name) node_id = match.group(1) if match else 'unknown' match_date = re.search(r'_(\d{6})_', h5_file.name) date = match_date.group(1) if match_date else '' files.append({ 'filename': h5_file.name, 'nodeId': node_id, 'date': date, 'path': str(h5_file) }) return jsonify({'files': files, 'count': len(files)}) except Exception as e: return jsonify({'error': str(e)}), 500 @app.route('/api/h5/data', methods=['GET']) def get_data(): try: filename = request.args.get('file') channel = int(request.args.get('channel', 1)) start = int(request.args.get('start', 0)) duration = int(request.args.get('duration', 10)) filepath = H5_DIR / filename with h5py.File(filepath, 'r') as f: meta = f['metadata'] sample_rate = meta.attrs['sample_rate_hz'] file_duration = meta.attrs['duration_sec'] total_samples = meta.attrs['n_samples'] dataset = f[f'calibrated_data/channel_{channel}'] start_idx = int(start * sample_rate) if start > 0 else 0 num_samples = int(duration * sample_rate) if duration > 0 else total_samples end_idx = min(start_idx + num_samples, total_samples) samples = dataset[start_idx:end_idx] unit = 'm/s' if channel in [1, 2, 3] else 'Pa' channel_name = f'Geophone {channel}' if channel in [1, 2, 3] else 'Hydrophone' import numpy as np return jsonify({ 'samples': samples.tolist(), 'start_idx': int(start_idx), 'end_idx': int(end_idx), 'total_samples': int(total_samples), 'sample_rate': int(sample_rate), 'duration_sec': float(file_duration), 'channel': channel, 'channel_name': channel_name, 'unit': unit, 'stats': { 'min': float(np.min(samples)), 'max': float(np.max(samples)), 'mean': float(np.mean(samples)), 'std': float(np.std(samples)), 'rms': float(np.sqrt(np.mean(samples**2))) } }) except Exception as e: return jsonify({'error': str(e)}), 500 @app.route('/api/docs/manifest', methods=['GET']) def get_manifest(): try: manifest_file = DOCS_DIR / 'campaign_manifest.json' with open(manifest_file, 'r') as f: return jsonify(json.load(f)) except Exception as e: return jsonify({'error': str(e)}), 500 @app.route('/api/docs/', methods=['GET']) def get_document(filename): try: doc_file = DOCS_DIR / filename if not doc_file.exists(): return jsonify({'error': 'File not found'}), 404 return send_file(str(doc_file)) except Exception as e: return jsonify({'error': str(e)}), 500 # === Endpoints pour la carte === @app.route('/api/nodes', methods=['GET']) def get_nodes(): """Retourne la liste des nodes avec leurs positions""" nodes = [ {'id': '80274', 'lat': 43.40, 'lon': 3.70, 'name': 'Node 80274'}, {'id': '2221', 'lat': 43.41, 'lon': 3.71, 'name': 'Node 2221'}, {'id': '3541', 'lat': 43.39, 'lon': 3.69, 'name': 'Node 3541'}, ] return jsonify(nodes) @app.route('/api/dates', methods=['GET']) def get_dates(): """Retourne les dates disponibles""" return jsonify(['2020-08-08', '2020-08-09', '2020-08-10']) @app.route('/api/migration-status', methods=['GET']) def migration_status(): """Status de migration (désactivé)""" return jsonify({'status': 'complete'}) if __name__ == '__main__': app.run(host='0.0.0.0', port=3004, debug=False)