import csv from io import StringIO import os from django.http import HttpResponse from django.shortcuts import render from django.http import JsonResponse from django.views.decorators.csrf import ensure_csrf_cookie, csrf_protect import json from utils.influx import InfluxDBHelper from dotenv import load_dotenv from django.views.decorators.http import require_http_methods from django.views.decorators.csrf import csrf_exempt from django.contrib.auth import authenticate, login, logout from .forms import CreateUserForm """old functions not used by django ninja""" @ensure_csrf_cookie @require_http_methods(["GET"]) def set_csrf_token(request): """ We set the CSRF cookie on the frontend. """ return JsonResponse({"message": "CSRF cookie set"}) @require_http_methods(["POST"]) def login_view(request): try: data = json.loads(request.body.decode("utf-8")) email = data["email"] password = data["password"] except json.JSONDecodeError: return JsonResponse({"success": False, "message": "Invalid JSON"}, status=400) user = authenticate(request, username=email, password=password) if user: login(request, user) # also creates a session in the browser return JsonResponse({"success": True}) return JsonResponse({"success": False, "message": "Invalid credentials"}, status=401) def logout_view(request): logout(request) return JsonResponse({"message": "Logged out"}) @require_http_methods(["GET"]) def user(request): if request.user.is_authenticated: return JsonResponse({"username": request.user.username, "email": request.user.email}) return JsonResponse({"message": "Not logged in"}, status=401) @require_http_methods(["POST"]) def register(request): data = json.loads(request.body.decode("utf-8")) form = CreateUserForm(data) if form.is_valid(): form.save() return JsonResponse({"success": "User registered successfully"}, status=201) else: errors = form.errors.as_json() return JsonResponse({"error": errors}, status=400) @require_http_methods(["GET"]) def room_data_range(request): try: room = request.GET.get("room") start = request.GET.get("start", "-30d") stop = request.GET.get("stop", "now()") if not room: return JsonResponse({"error": "Missing 'room' parameter"}, status=400) load_dotenv() client = InfluxDBHelper( url=os.getenv("INFLUXDB_URL"), token=os.getenv("INFLUXDB_TOKEN"), org=os.getenv("INFLUXDB_ORG"), bucket=os.getenv("INFLUXDB_BUCKET"), ) tables = client.get_room_data_in_range(room, start, stop) data_by_time = {} for table in tables: for record in table.records: timestamp = str(record.get_time()) field = record.get_field() value = record.get_value() if timestamp not in data_by_time: data_by_time[timestamp] = {} data_by_time[timestamp][field] = value return JsonResponse({"room": room, "data": data_by_time}, status=200) except json.JSONDecodeError: return JsonResponse({"success": False, "message": "Invalid JSON"}, status=400) @require_http_methods(["GET"]) def get_rooms(request): client = InfluxDBHelper( url=os.getenv("INFLUXDB_URL"), token=os.getenv("INFLUXDB_TOKEN"), org=os.getenv("INFLUXDB_ORG"), bucket=os.getenv("INFLUXDB_BUCKET"), ) tables = client.list_rooms() rooms = set() for table in tables: for record in table.records: rooms.add(record.get_value()) return JsonResponse({"rooms": sorted(rooms)}) @require_http_methods(["GET"]) def get_rooms_from_building(request): building = request.GET.get("building") if not building: return JsonResponse({"error": "Missing 'building' parameter"}, status=400) client = InfluxDBHelper( url=os.getenv("INFLUXDB_URL"), token=os.getenv("INFLUXDB_TOKEN"), org=os.getenv("INFLUXDB_ORG"), bucket=os.getenv("INFLUXDB_BUCKET"), ) tables = client.list_rooms() rooms = set() for table in tables: for record in table.records: room = record.get_value() if isinstance(room, str) and room.startswith(f"{building}/"): rooms.add(room) return JsonResponse({"building": building, "rooms": sorted(rooms)}) @require_http_methods(["GET"]) def get_bau(request): client = InfluxDBHelper( url=os.getenv("INFLUXDB_URL"), token=os.getenv("INFLUXDB_TOKEN"), org=os.getenv("INFLUXDB_ORG"), bucket=os.getenv("INFLUXDB_BUCKET"), ) tables = client.list_rooms() baus = set() for table in tables: for record in table.records: room = record.get_value() if isinstance(room, str) and "/" in room: bau = room.split("/")[0] baus.add(bau) return JsonResponse({"baus": sorted(baus)}) @require_http_methods(["GET"]) def room_data_csv_view(request): room = request.GET.get("room") start = request.GET.get("start", "-30d") stop = request.GET.get("stop", "now()") if not room: return JsonResponse({"error": "Missing 'room' parameter"}, status=400) client = InfluxDBHelper( url=os.getenv("INFLUXDB_URL"), token=os.getenv("INFLUXDB_TOKEN"), org=os.getenv("INFLUXDB_ORG"), bucket=os.getenv("INFLUXDB_BUCKET"), ) csv_stream = client.get_room_data_csv(room_id=room, start=start, stop=stop) decoded = csv_stream.decode("utf-8") f = StringIO(decoded) reader = csv.DictReader(f) results = [] for row in reader: # optional: nur Datenzeilen filtern if row.get("_field") and row.get("_value"): results.append( { "time": row["_time"], "field": row["_field"], "value": row["_value"], } ) return JsonResponse({"room": room, "data": results}) @require_http_methods(["GET"]) def room_data_csv_download(request): room = request.GET.get("room") start = request.GET.get("start", "-30d") stop = request.GET.get("stop", "now()") if not room: return JsonResponse({"error": "Missing 'room' parameter"}, status=400) client = InfluxDBHelper( url=os.getenv("INFLUXDB_URL"), token=os.getenv("INFLUXDB_TOKEN"), org=os.getenv("INFLUXDB_ORG"), bucket=os.getenv("INFLUXDB_BUCKET"), ) csv_data = client.get_room_data_csv(room, start, stop) response = HttpResponse(csv_data, content_type="text/csv") response["Content-Disposition"] = f'attachment; filename="{room}_data.csv"' return response @require_http_methods(["GET"]) def room_availability(request): room = request.GET.get("room") start = request.GET.get("start", "-30d") stop = request.GET.get("stop", "now()") if not room: return JsonResponse({"error": "Missing 'room' parameter"}, status=400) client = InfluxDBHelper( url=os.getenv("INFLUXDB_URL"), token=os.getenv("INFLUXDB_TOKEN"), org=os.getenv("INFLUXDB_ORG"), bucket=os.getenv("INFLUXDB_BUCKET"), ) availability = client.has_room_sent_data(room, start, stop) return JsonResponse({"room": room, "available": availability}, status=200) @require_http_methods(["GET"]) def sensor_availability(request): sensor_mac = request.GET.get("mac") start = request.GET.get("start", "-30d") stop = request.GET.get("stop", "now()") if not sensor_mac: return JsonResponse({"error": "Missing 'mac' parameter"}, status=400) client = InfluxDBHelper( url=os.getenv("INFLUXDB_URL"), token=os.getenv("INFLUXDB_TOKEN"), org=os.getenv("INFLUXDB_ORG"), bucket=os.getenv("INFLUXDB_BUCKET"), ) availability = client.has_sensor_sent_data(sensor_mac, start, stop) return JsonResponse({"sensor_mac": sensor_mac, "available": availability}, status=200) @require_http_methods(["GET"]) def all_rooms_availability(request): start = request.GET.get("start", "-30d") stop = request.GET.get("stop", "now()") client = InfluxDBHelper( url=os.getenv("INFLUXDB_URL"), token=os.getenv("INFLUXDB_TOKEN"), org=os.getenv("INFLUXDB_ORG"), bucket=os.getenv("INFLUXDB_BUCKET"), ) rooms_available = client.rooms_with_available_data(start, stop) return JsonResponse({"available_rooms": rooms_available}, status=200) @require_http_methods(["GET"]) def all_sensors_availability(request): start = request.GET.get("start", "-30d") stop = request.GET.get("stop", "now()") client = InfluxDBHelper( url=os.getenv("INFLUXDB_URL"), token=os.getenv("INFLUXDB_TOKEN"), org=os.getenv("INFLUXDB_ORG"), bucket=os.getenv("INFLUXDB_BUCKET"), ) sensors_available = client.sensors_with_available_data(start, stop) return JsonResponse({"available_sensors": sensors_available}, status=200)