Files
function/routes/home.py
Peter Stockings d4c0c0f262 Add home dashboard and Mithril rendering support
- Create new home route with comprehensive dashboard statistics
- Implement Mithril rendering support with new `mithril_loader.html` template
- Add new routes for home and test pages in `app.py`
- Create `lib/mithril.py` with Mithril rendering and error handling utilities
- Update dashboard template to use new home route
- Add detailed dashboard view with timer and HTTP function statistics
2025-02-20 23:35:46 +11:00

133 lines
5.7 KiB
Python

from flask import Blueprint, render_template, request
from flask_login import login_required, current_user
from extensions import db, htmx, environment
from jinja2_fragments import render_block
home = Blueprint('home', __name__)
@home.route('/')
@login_required
def index():
# Fetch user statistics
stats = db.execute("""
WITH timer_stats AS (
SELECT
COUNT(*) as total_timer_functions,
COUNT(*) FILTER (WHERE enabled = true) as active_timer_functions,
(SELECT COUNT(*) FROM timer_function_invocations tfi
JOIN timer_functions tf ON tf.id = tfi.timer_function_id
WHERE tf.user_id = %s) as timer_invocations,
(SELECT COUNT(*) FROM timer_function_invocations tfi
JOIN timer_functions tf ON tf.id = tfi.timer_function_id
WHERE tf.user_id = %s AND tfi.status = 'SUCCESS') as timer_successful_invocations,
MAX(last_run) as last_timer_invocation
FROM timer_functions
WHERE user_id = %s
),
http_stats AS (
SELECT
COUNT(*) as total_http_functions,
COUNT(*) FILTER (WHERE is_public = true) as public_http_functions,
SUM(invoked_count) as http_invocations,
(SELECT COUNT(*) FROM http_function_invocations hfi
JOIN http_functions hf ON hf.id = hfi.http_function_id
WHERE hf.user_id = %s AND hfi.status = 'SUCCESS') as http_successful_invocations,
(SELECT MAX(invocation_time)
FROM http_function_invocations hfi
JOIN http_functions hf ON hf.id = hfi.http_function_id
WHERE hf.user_id = %s) as last_http_invocation
FROM http_functions
WHERE user_id = %s
)
SELECT
*,
CASE
WHEN timer_invocations > 0 THEN
(timer_successful_invocations * 100.0 / timer_invocations)::numeric(5,1)
ELSE 0.0
END as timer_success_rate,
CASE
WHEN http_invocations > 0 THEN
(http_successful_invocations * 100.0 / http_invocations)::numeric(5,1)
ELSE 0.0
END as http_success_rate
FROM timer_stats, http_stats
""", [current_user.id, current_user.id, current_user.id, current_user.id, current_user.id, current_user.id], one=True)
# Get 24-hour distribution
hour_distribution = db.execute("""
WITH all_invocations AS (
SELECT date_trunc('hour', tfi.invocation_time) as hour_bucket
FROM timer_function_invocations tfi
JOIN timer_functions tf ON tf.id = tfi.timer_function_id
WHERE tf.user_id = %s
AND tfi.invocation_time > NOW() - INTERVAL '24 hours'
UNION ALL
SELECT date_trunc('hour', hfi.invocation_time) as hour_bucket
FROM http_function_invocations hfi
JOIN http_functions hf ON hf.id = hfi.http_function_id
WHERE hf.user_id = %s
AND hfi.invocation_time > NOW() - INTERVAL '24 hours'
)
SELECT
EXTRACT(HOUR FROM hour_bucket) as hour,
COUNT(*) as count
FROM all_invocations
GROUP BY hour
ORDER BY hour
""", [current_user.id, current_user.id])
# Get 7-day success rate trend
success_trend = db.execute("""
WITH daily_stats AS (
WITH timer_daily AS (
SELECT
date_trunc('day', tfi.invocation_time) as day,
COUNT(*) as total,
COUNT(*) FILTER (WHERE tfi.status = 'SUCCESS') as successes
FROM timer_function_invocations tfi
JOIN timer_functions tf ON tf.id = tfi.timer_function_id
WHERE tf.user_id = %s
AND tfi.invocation_time > NOW() - INTERVAL '7 days'
GROUP BY day
),
http_daily AS (
SELECT
date_trunc('day', hfi.invocation_time) as day,
COUNT(*) as total,
COUNT(*) FILTER (WHERE hfi.status = 'SUCCESS') as successes
FROM http_function_invocations hfi
JOIN http_functions hf ON hf.id = hfi.http_function_id
WHERE hf.user_id = %s
AND hfi.invocation_time > NOW() - INTERVAL '7 days'
GROUP BY day
)
SELECT
COALESCE(t.day, h.day) as day,
COALESCE(t.total, 0) + COALESCE(h.total, 0) as total,
COALESCE(t.successes, 0) + COALESCE(h.successes, 0) as successes
FROM timer_daily t
FULL OUTER JOIN http_daily h ON t.day = h.day
)
SELECT
to_char(day, 'Dy') as day_name,
CASE
WHEN total > 0 THEN
(successes * 100.0 / total)::float
ELSE 0.0
END as success_rate
FROM daily_stats
ORDER BY day DESC
LIMIT 7
""", [current_user.id, current_user.id])
if htmx:
return render_block(environment, 'dashboard/home.html', 'page',
stats=stats,
hour_distribution=hour_distribution,
success_trend=success_trend)
return render_template('dashboard/home.html',
stats=stats,
hour_distribution=hour_distribution,
success_trend=success_trend)