Files
function/routes/home.py
2025-11-19 21:15:41 +11:00

207 lines
8.7 KiB
Python

from flask import Blueprint, render_template, request
from flask_login import login_required, current_user
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,
(SELECT AVG(tfi.execution_time) FROM timer_function_invocations tfi
JOIN timer_functions tf ON tf.id = tfi.timer_function_id
WHERE tf.user_id = %s) as avg_timer_execution_time,
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,
(SELECT COUNT(*) FROM http_function_invocations hfi
JOIN http_functions hf ON hf.id = hfi.http_function_id
WHERE hf.user_id = %s) 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 AVG(hfi.execution_time) FROM http_function_invocations hfi
JOIN http_functions hf ON hf.id = hfi.http_function_id
WHERE hf.user_id = %s) as avg_http_execution_time,
(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
*,
(timer_invocations - timer_successful_invocations) as timer_failed_invocations,
(http_invocations - http_successful_invocations) as http_failed_invocations,
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, 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])
# Top 5 Most Invoked Functions
top_functions = db.execute("""
WITH all_functions AS (
SELECT
tf.name,
'Timer' as type,
COUNT(tfi.id) as invocation_count
FROM timer_functions tf
JOIN timer_function_invocations tfi ON tf.id = tfi.timer_function_id
WHERE tf.user_id = %s
GROUP BY tf.name
UNION ALL
SELECT
hf.name,
'HTTP' as type,
COUNT(hfi.id) as invocation_count
FROM http_functions hf
JOIN http_function_invocations hfi ON hf.id = hfi.http_function_id
WHERE hf.user_id = %s
GROUP BY hf.name
)
SELECT * FROM all_functions
ORDER BY invocation_count DESC
LIMIT 5
""", [current_user.id, current_user.id])
# Recent Activity (Last 10)
recent_activity = db.execute("""
WITH all_activity AS (
SELECT
tf.name,
'Timer' as type,
tfi.status,
tfi.invocation_time,
tfi.execution_time
FROM timer_function_invocations tfi
JOIN timer_functions tf ON tf.id = tfi.timer_function_id
WHERE tf.user_id = %s
UNION ALL
SELECT
hf.name,
'HTTP' as type,
hfi.status,
hfi.invocation_time,
hfi.execution_time
FROM http_function_invocations hfi
JOIN http_functions hf ON hf.id = hfi.http_function_id
WHERE hf.user_id = %s
)
SELECT * FROM all_activity
ORDER BY invocation_time DESC
LIMIT 10
""", [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,
top_functions=top_functions,
recent_activity=recent_activity)
return render_template('dashboard/home.html',
stats=stats,
hour_distribution=hour_distribution,
success_trend=success_trend,
top_functions=top_functions,
recent_activity=recent_activity)