Initial commit for eventlens

This commit is contained in:
ecki
2026-04-09 19:00:12 +02:00
commit 51aab152ff
21 changed files with 1862 additions and 0 deletions
+140
View File
@@ -0,0 +1,140 @@
from pathlib import Path
from datetime import datetime
from fastapi import Depends, FastAPI, HTTPException
from fastapi.responses import FileResponse
from fastapi.staticfiles import StaticFiles
from sqlalchemy.orm import Session
from app.config import settings
from app.database import Base, engine, get_db
from app.models import TrackedEvent, WatchItem
from app.scheduler import start_scheduler
from app.schemas import (
NotificationLogRead,
PurchaseUpdate,
SyncResult,
TrackedEventRead,
WatchItemCreate,
WatchItemRead,
WatchItemUpdate,
)
from app.services import list_events, list_notifications, list_watch_items, run_sync
app = FastAPI(
title="eventlens",
version="0.1.0",
description="Beobachtet Kuenstler und Events in Hamburg oder Deutschland.",
)
frontend_dir = Path(__file__).resolve().parent / "frontend"
static_dir = frontend_dir / "static"
app.mount("/static", StaticFiles(directory=static_dir), name="static")
@app.on_event("startup")
def startup():
Base.metadata.create_all(bind=engine)
start_scheduler()
@app.get("/")
def root():
return FileResponse(frontend_dir / "index.html")
@app.get("/api")
def api_info():
return {
"service": settings.app_name,
"status": "running",
"docs": "/docs",
}
@app.get("/health")
def health():
return {"status": "ok"}
@app.get("/watch-items", response_model=list[WatchItemRead])
def get_watch_items(db: Session = Depends(get_db)):
return list_watch_items(db)
@app.post("/watch-items", response_model=WatchItemRead, status_code=201)
def create_watch_item(payload: WatchItemCreate, db: Session = Depends(get_db)):
watch_item = WatchItem(
name=payload.name,
watch_type=payload.watch_type,
region_scope=payload.region_scope,
notes=payload.notes,
)
db.add(watch_item)
db.commit()
db.refresh(watch_item)
return watch_item
@app.patch("/watch-items/{watch_item_id}", response_model=WatchItemRead)
def update_watch_item(
watch_item_id: int,
payload: WatchItemUpdate,
db: Session = Depends(get_db),
):
watch_item = db.get(WatchItem, watch_item_id)
if watch_item is None:
raise HTTPException(status_code=404, detail="Watch item nicht gefunden.")
updates = payload.model_dump(exclude_unset=True)
for field_name, value in updates.items():
setattr(watch_item, field_name, value)
watch_item.updated_at = datetime.utcnow()
db.commit()
db.refresh(watch_item)
return watch_item
@app.delete("/watch-items/{watch_item_id}", status_code=204)
def delete_watch_item(watch_item_id: int, db: Session = Depends(get_db)):
watch_item = db.get(WatchItem, watch_item_id)
if watch_item is None:
raise HTTPException(status_code=404, detail="Watch item nicht gefunden.")
db.delete(watch_item)
db.commit()
@app.get("/events", response_model=list[TrackedEventRead])
def get_events(db: Session = Depends(get_db)):
return list_events(db)
@app.patch("/events/{event_id}/purchase", response_model=TrackedEventRead)
def update_purchase_status(
event_id: int,
payload: PurchaseUpdate,
db: Session = Depends(get_db),
):
tracked_event = db.get(TrackedEvent, event_id)
if tracked_event is None:
raise HTTPException(status_code=404, detail="Event nicht gefunden.")
tracked_event.is_ticket_purchased = payload.is_ticket_purchased
tracked_event.purchased_at = datetime.utcnow() if payload.is_ticket_purchased else None
tracked_event.reminder_notified_at = None
db.commit()
db.refresh(tracked_event)
return tracked_event
@app.get("/notifications", response_model=list[NotificationLogRead])
def get_notifications(db: Session = Depends(get_db)):
return list_notifications(db)
@app.post("/sync", response_model=SyncResult)
def trigger_sync(db: Session = Depends(get_db)):
return run_sync(db)