- 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
83 lines
2.9 KiB
Python
83 lines
2.9 KiB
Python
from flask import render_template, jsonify, request, session
|
|
from functools import wraps
|
|
import time
|
|
|
|
class MithrilError(Exception):
|
|
def __init__(self, message, code=400):
|
|
self.message = message
|
|
self.code = code
|
|
|
|
class Mithril:
|
|
_shared_data = {}
|
|
|
|
@classmethod
|
|
def share(cls, key, value):
|
|
"""Add shared data that will be available to all components"""
|
|
cls._shared_data[key] = value
|
|
|
|
@staticmethod
|
|
def render(component_name, props=None):
|
|
"""Render a Mithril component"""
|
|
instance = Mithril(component_name, props or {})
|
|
return instance()
|
|
|
|
@classmethod
|
|
def error_handler(cls, error_handler):
|
|
"""Decorator to register a global error handler"""
|
|
cls._error_handler = error_handler
|
|
return error_handler
|
|
|
|
def __init__(self, component_name, props=None):
|
|
self.component_name = component_name
|
|
self.props = props or {}
|
|
self.version = int(time.time()) # Simple asset versioning
|
|
|
|
def _prepare_response_data(self):
|
|
"""Prepare the data to be sent to the frontend"""
|
|
return {
|
|
'component': self.component_name,
|
|
'props': self.props,
|
|
'shared': self._shared_data,
|
|
'version': self.version,
|
|
'errors': session.get('errors', {}), # Flash-style errors
|
|
'flash': session.get('flash', []) # Flash messages
|
|
}
|
|
|
|
def __call__(self):
|
|
try:
|
|
response_data = self._prepare_response_data()
|
|
|
|
# Clear flash data after preparing response
|
|
session.pop('errors', None)
|
|
session.pop('flash', None)
|
|
|
|
if request.headers.get('X-Mithril-Request'):
|
|
return jsonify(response_data)
|
|
|
|
return render_template('mithril_loader.html', **response_data)
|
|
|
|
except Exception as e:
|
|
if hasattr(self, '_error_handler'):
|
|
return self._error_handler(e)
|
|
raise
|
|
|
|
@classmethod
|
|
def form(cls, route):
|
|
"""Decorator for handling form submissions"""
|
|
def decorator(f):
|
|
@wraps(f)
|
|
def wrapped(*args, **kwargs):
|
|
try:
|
|
if request.headers.get('X-Mithril-Request'):
|
|
form_data = request.get_json()
|
|
else:
|
|
form_data = request.form
|
|
|
|
return f(form_data, *args, **kwargs)
|
|
except MithrilError as e:
|
|
session['errors'] = {'message': e.message}
|
|
if request.headers.get('X-Mithril-Request'):
|
|
return jsonify({'errors': {'message': e.message}}), e.code
|
|
return cls.redirect_back()
|
|
return wrapped
|
|
return decorator |