Files

106 lines
4.2 KiB
Python

# lead-engine/trading_twins/debug_calendar.py
import os
import requests
import json
from datetime import datetime, timedelta
from zoneinfo import ZoneInfo
from threading import Thread, Lock
import uvicorn
from fastapi import FastAPI, Response, BackgroundTasks
import msal
from dotenv import load_dotenv
# Load environment variables from /app/.env
load_dotenv(dotenv_path="/app/.env", override=True)
# --- Zeitzonen-Konfiguration ---
TZ_BERLIN = ZoneInfo("Europe/Berlin")
# --- Konfiguration ---
# Credentials für die Kalender-Lese-App (e.melcer)
CAL_APPID = os.getenv("CAL_APPID")
CAL_SECRET = os.getenv("CAL_SECRET")
CAL_TENNANT_ID = os.getenv("CAL_TENNANT_ID")
TARGET_EMAIL = "e.melcer@robo-planet.de"
GRAPH_API_ENDPOINT = "https://graph.microsoft.com/v1.0"
def get_access_token(client_id, client_secret, tenant_id):
if not all([client_id, client_secret, tenant_id]):
print("❌ Credentials missing in .env for Calendar Access")
return None
authority = f"https://login.microsoftonline.com/{tenant_id}"
app = msal.ConfidentialClientApplication(client_id=client_id, authority=authority, client_credential=client_secret)
# Scopes for Calendar.Read
scopes = ["https://graph.microsoft.com/.default"]
result = app.acquire_token_silent(scopes, account=None)
if not result:
result = app.acquire_token_for_client(scopes=scopes)
if "access_token" in result:
print("✅ Successfully acquired Access Token for Calendar.")
return result["access_token"]
else:
print(f"❌ Failed to acquire Access Token: {result.get('error_description')}")
return None
def check_calendar_availability():
print(f"--- Checking Calendar for {TARGET_EMAIL} ---")
token = get_access_token(CAL_APPID, CAL_SECRET, CAL_TENNANT_ID)
if not token:
print("❌ Cannot proceed without Access Token.")
return None
headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json", "Prefer": 'outlook.timezone="Europe/Berlin"'}
# Get next 5 events starting from now
start_time = datetime.now(TZ_BERLIN).replace(minute=0, second=0, microsecond=0)
if start_time.hour >= 17: start_time += timedelta(days=1); start_time = start_time.replace(hour=8)
end_time = start_time + timedelta(days=3)
payload = {
"schedules": [TARGET_EMAIL],
"startTime": {"dateTime": start_time.isoformat(), "timeZone": "Europe/Berlin"},
"endTime": {"dateTime": end_time.isoformat(), "timeZone": "Europe/Berlin"},
"availabilityViewInterval": 60 # Check availability in 1-hour blocks
}
url = f"{GRAPH_API_ENDPOINT}/users/{TARGET_EMAIL}/calendarView"
params = {
"startDateTime": start_time.isoformat(),
"endDateTime": end_time.isoformat(),
"$top": 5
}
try:
response = requests.get(url, headers=headers, params=params)
if response.status_code == 200:
events = response.json().get("value", [])
if not events:
print("✅ API call successful, but no upcoming events found.")
return []
print("\n--- Next 5 Upcoming Events ---")
for event in events:
subject = event.get('subject', 'No Subject')
start = event.get('start', {}).get('dateTime')
if start:
# Fix for 7-digit microseconds from Graph API (e.g. 2026-03-09T17:00:00.0000000)
if "." in start:
main_part, frac_part = start.split(".")
# Truncate to 6 digits max or remove if empty
start = f"{main_part}.{frac_part[:6]}"
dt_obj = datetime.fromisoformat(start.replace('Z', '+00:00')).astimezone(TZ_BERLIN)
start_formatted = dt_obj.strftime('%A, %d.%m.%Y um %H:%M Uhr')
else: start_formatted = "N/A"
print(f"🗓️ {subject} -> {start_formatted}")
return events
else:
print(f"❌ HTTP Error: {response.status_code} - {response.text}")
return None
except Exception as e:
print(f"❌ An unexpected error occurred: {e}")
return None
if __name__ == "__main__":
check_calendar_availability()