intervall

This commit is contained in:
Bastian Wagner
2026-08-15 21:44:13 +02:00
parent f7b04337ce
commit ff5dab6f0d
10 changed files with 438 additions and 17 deletions

View File

@@ -1,11 +1,11 @@
from fastapi import APIRouter, Form, HTTPException, Request
from fastapi.responses import HTMLResponse
from fastapi.responses import HTMLResponse, RedirectResponse
from sqlalchemy import func, select
from app.auth.admin import require_admin
from app.auth.csrf import ensure_csrf_token, validate_csrf
from app.db.models import Activity
from app.db.repositories import ActivityRepository, SystemLogRepository, UserRepository
from app.db.repositories import ActivityRepository, SchedulerSettingsRepository, SystemLogRepository, UserRepository
from app.sync.manager import SyncAlreadyRunning
from app.web.routes import templates
@@ -104,13 +104,45 @@ def system_page(request: Request):
user_count = len(UserRepository(session).list_all())
activity_count = session.scalar(select(func.count()).select_from(Activity)) or 0
log_entries = SystemLogRepository(session).list_recent(limit=50)
scheduler_settings = SchedulerSettingsRepository(session).get_or_create(
default_minutes=settings.sync_interval_minutes
)
return templates.TemplateResponse(request, "system.html", {
"csrf_token": ensure_csrf_token(request),
"app_version": APP_VERSION,
"sync_interval_minutes": settings.sync_interval_minutes,
"last_tick": scheduler.last_tick,
"next_tick": scheduler.next_tick,
"user_count": user_count,
"activity_count": activity_count,
"log_entries": log_entries,
"scheduler_settings": scheduler_settings,
})
@router.post("/system/scheduler-settings")
def update_scheduler_settings(
request: Request,
csrf_token: str = Form(...),
day_start_hour: int = Form(...),
night_start_hour: int = Form(...),
day_interval_minutes: int = Form(...),
night_interval_minutes: int = Form(...),
):
require_admin(request)
validate_csrf(request, csrf_token)
if not (0 <= day_start_hour <= 23) or not (0 <= night_start_hour <= 23):
raise HTTPException(status_code=400, detail="Hours must be between 0 and 23")
if day_interval_minutes < 1 or night_interval_minutes < 1:
raise HTTPException(status_code=400, detail="Intervals must be at least 1 minute")
settings = request.app.state.settings
with request.app.state.session_factory() as session:
repository = SchedulerSettingsRepository(session)
row = repository.get_or_create(default_minutes=settings.sync_interval_minutes)
repository.update(
row,
day_start_hour=day_start_hour,
night_start_hour=night_start_hour,
day_interval_minutes=day_interval_minutes,
night_interval_minutes=night_interval_minutes,
)
return RedirectResponse("/system", status_code=303)

View File

@@ -10,9 +10,6 @@
<dt>Application version</dt>
<dd>{{ app_version }}</dd>
<dt>Sync interval (minutes)</dt>
<dd>{{ sync_interval_minutes }}</dd>
<dt>Last scheduler tick</dt>
<dd>{{ last_tick or "-" }}</dd>
@@ -32,6 +29,31 @@
<button type="submit">Sync all now</button>
</form>
<h2>Sync scheduling</h2>
<div class="card">
<form method="post" action="/system/scheduler-settings" class="stacked-form">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<label for="day_start_hour">Day starts at (hour, 0-23)</label>
<input type="number" id="day_start_hour" name="day_start_hour" min="0" max="23"
value="{{ scheduler_settings.day_start_hour }}" required>
<label for="day_interval_minutes">Sync interval during the day (minutes)</label>
<input type="number" id="day_interval_minutes" name="day_interval_minutes" min="1"
value="{{ scheduler_settings.day_interval_minutes }}" required>
<label for="night_start_hour">Night starts at (hour, 0-23)</label>
<input type="number" id="night_start_hour" name="night_start_hour" min="0" max="23"
value="{{ scheduler_settings.night_start_hour }}" required>
<label for="night_interval_minutes">Sync interval during the night (minutes)</label>
<input type="number" id="night_interval_minutes" name="night_interval_minutes" min="1"
value="{{ scheduler_settings.night_interval_minutes }}" required>
<button type="submit">Save</button>
</form>
</div>
<h2>System log</h2>
<div class="card">
{% if log_entries %}