99 lines
3.4 KiB
Python
99 lines
3.4 KiB
Python
|
# Web server component for MacroPad
|
||
|
|
||
|
from flask import Flask, render_template_string, request, jsonify, send_file
|
||
|
from waitress import serve
|
||
|
import logging
|
||
|
import os
|
||
|
from web_templates import INDEX_HTML
|
||
|
|
||
|
|
||
|
class WebServer:
|
||
|
def __init__(self, macro_manager, app_dir, port=40000):
|
||
|
self.macro_manager = macro_manager
|
||
|
self.app_dir = app_dir
|
||
|
self.port = port
|
||
|
self.app = None
|
||
|
|
||
|
def create_app(self):
|
||
|
"""Create and configure Flask application"""
|
||
|
app = Flask(__name__)
|
||
|
|
||
|
# Disable Flask's logging except for errors
|
||
|
log = logging.getLogger('werkzeug')
|
||
|
log.setLevel(logging.ERROR)
|
||
|
|
||
|
@app.route('/')
|
||
|
def index():
|
||
|
return render_template_string(INDEX_HTML)
|
||
|
|
||
|
@app.route('/api/tabs')
|
||
|
def get_tabs():
|
||
|
"""Get all available tabs (similar to setup_tabs logic)"""
|
||
|
tabs = ["All"]
|
||
|
|
||
|
# Add tabs based on macro types and custom categories
|
||
|
unique_types = set()
|
||
|
for macro in self.macro_manager.macros.values():
|
||
|
if macro.get("type"):
|
||
|
unique_types.add(macro["type"].title())
|
||
|
# Check for custom category
|
||
|
if macro.get("category"):
|
||
|
unique_types.add(macro["category"])
|
||
|
|
||
|
for tab_type in sorted(unique_types):
|
||
|
if tab_type not in ["All"]:
|
||
|
tabs.append(tab_type)
|
||
|
|
||
|
return jsonify(tabs)
|
||
|
|
||
|
@app.route('/api/macros')
|
||
|
def get_macros():
|
||
|
return jsonify(self.macro_manager.macros)
|
||
|
|
||
|
@app.route('/api/macros/<tab_name>')
|
||
|
def get_macros_by_tab(tab_name):
|
||
|
"""Filter macros by tab (similar to filter_macros_by_tab logic)"""
|
||
|
if tab_name == "All":
|
||
|
return jsonify(self.macro_manager.macros)
|
||
|
|
||
|
filtered_macros = {}
|
||
|
for macro_id, macro in self.macro_manager.macros.items():
|
||
|
# Check type match
|
||
|
if macro.get("type", "").title() == tab_name:
|
||
|
filtered_macros[macro_id] = macro
|
||
|
# Check custom category match
|
||
|
elif macro.get("category") == tab_name:
|
||
|
filtered_macros[macro_id] = macro
|
||
|
|
||
|
return jsonify(filtered_macros)
|
||
|
|
||
|
@app.route('/api/image/<path:image_path>')
|
||
|
def get_image(image_path):
|
||
|
try:
|
||
|
image_path = os.path.join(self.app_dir, image_path)
|
||
|
return send_file(image_path)
|
||
|
except Exception as e:
|
||
|
return str(e), 404
|
||
|
|
||
|
@app.route('/api/execute', methods=['POST'])
|
||
|
def execute_macro():
|
||
|
data = request.get_json()
|
||
|
if not data or 'macro_id' not in data:
|
||
|
return jsonify({"success": False, "error": "Invalid request"})
|
||
|
|
||
|
macro_id = data['macro_id']
|
||
|
success = self.macro_manager.execute_macro(macro_id)
|
||
|
return jsonify({"success": success})
|
||
|
|
||
|
self.app = app
|
||
|
return app
|
||
|
|
||
|
def run(self):
|
||
|
"""Run the web server"""
|
||
|
if not self.app:
|
||
|
self.create_app()
|
||
|
|
||
|
try:
|
||
|
serve(self.app, host='0.0.0.0', port=self.port, threads=4)
|
||
|
except Exception as e:
|
||
|
raise e
|