Mateusz Gruszczyński e382fab275 first commit
2025-05-18 19:30:50 +02:00

174 lines
5.7 KiB
Python

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)