from flask import Flask, request, jsonify, render_template from influxdb import InfluxDBClient from flask_cors import CORS from config import get_influx_client app = Flask(__name__) CORS(app) client = get_influx_client() def escape_identifier(identifier): """Escapuje identyfikatory dla InfluxDB.""" return f'"{identifier.replace("\\", "\\\\").replace("\"", "\\\"")}"' def escape_value(value): """Escapuje wartości dla zapytań InfluxDB.""" if isinstance(value, str): escaped = value.replace("'", "''") return f"'{escaped}'" return str(value) @app.route('/') def index(): return render_template("index.html") @app.route('/databases', methods=['GET']) def get_databases(): databases = client.get_list_database() return jsonify([db['name'] for db in databases]) @app.route('/series', methods=['GET']) def get_series(): db = request.args.get('db') if not db: return jsonify({'error': 'Baza danych nie została wybrana'}), 400 client.switch_database(db) series_info = [] #print("DEBUG: Pobieram listę measurementów...") measurements = client.query("SHOW MEASUREMENTS") measurement_names = [m['name'] for m in measurements.get_points()] #print("DEBUG: Measurementy:", measurement_names) for measurement in measurement_names: if measurement == "results": print("DEBUG: Pomijam 'results'") continue #print(f"DEBUG: SHOW SERIES FROM \"{measurement}\"") try: result = client.query(f'SHOW SERIES FROM "{measurement}"') for s in result.get_points(): tags = {k: v for k, v in s.items() if k != 'time'} if not tags: continue series_id = f"{measurement},{','.join([f'{k}={v}' for k, v in tags.items()])}" #print(f"DEBUG: Series = {series_id}") series_info.append({ 'series': series_id, 'measurement': measurement, 'tags': tags }) except Exception as e: print(f"DEBUG: Błąd w {measurement}: {str(e)}") print(f"DEBUG: Zwracam do frontu {len(series_info)} serii") return jsonify(series_info) @app.route('/delete', methods=['POST']) def delete_series(): data = request.json db = data.get('db') if not db: return jsonify({'error': 'Baza danych nie została wybrana'}), 400 client.switch_database(db) deleted_count = 0 for series in data['series']: try: parts = series.split(',', 1) measurement = parts[0].strip() tags_part = parts[1] if len(parts) > 1 else '' # Raw tag parsing tags = {} for tag in tags_part.split(','): if '=' in tag: k, v = tag.split('=', 1) tags[k.strip()] = v.strip() # Pobierz tylko tagi dostępne w measurement tag_keys_query = client.query(f'SHOW TAG KEYS FROM "{measurement}"') tag_keys = {row['tagKey'] for row in tag_keys_query.get_points()} # Build WHERE clause tylko z tagów where_parts = [] for k, v in tags.items(): if k not in tag_keys: print(f"Pomijam '{k}', bo nie jest tagiem w '{measurement}'") continue v_escaped = v.replace("'", "\\'") where_parts.append(f'"{k}" = \'{v_escaped}\'') # Escape measurement for InfluxQL measurement_escaped = measurement.replace('"', '\\"') query = f'DROP SERIES FROM "{measurement_escaped}" WHERE {" AND ".join(where_parts)}' print(f"DEBUG: Final query to run: {query}") client.query(query) deleted_count += 1 except Exception as e: print(f"Błąd usuwania serii {series}: {str(e)}") continue return jsonify({'status': 'success', 'deleted': deleted_count}) @app.route('/delete_range', methods=['POST']) def delete_range(): data = request.json db = data.get('db') series = data.get('series') time_from = data.get('from') time_to = data.get('to') if not all([db, series, time_from, time_to]): return jsonify({'error': 'Brakuje wymaganych parametrów'}), 400 client.switch_database(db) try: # Parsowanie measurementu i tagów z serii parts = series.split(',', 1) measurement = parts[0].strip() tags_part = parts[1] if len(parts) > 1 else '' tags = {} for tag in tags_part.split(','): if '=' in tag: k, v = tag.split('=', 1) tags[k.strip()] = v.strip() # Pobierz dozwolone tagi z InfluxDB tag_keys_query = client.query(f'SHOW TAG KEYS FROM "{measurement}"') tag_keys = {row['tagKey'] for row in tag_keys_query.get_points()} # Buduj WHERE tylko z tagów i czasu where_parts = [f"time >= '{time_from}'", f"time <= '{time_to}'"] for k, v in tags.items(): if k not in tag_keys: print(f"Pomijam '{k}', bo nie jest tagiem w '{measurement}'") continue v_escaped = v.replace("'", "\\'") where_parts.append(f'"{k}" = \'{v_escaped}\'') measurement_escaped = measurement.replace('"', '\\"') query = f'DELETE FROM "{measurement_escaped}" WHERE {" AND ".join(where_parts)}' print(f"DEBUG: DELETE query: {query}") client.query(query) return jsonify({'status': 'success'}) except Exception as e: return jsonify({'error': str(e)}), 500 if __name__ == '__main__': app.run(host='0.0.0.0', port=9999, debug=True)