from flask import Blueprint, render_template, request, jsonify from db import get_db import json from datetime import datetime dashboard = Blueprint('dashboard', __name__) # ------------------------------------------------------------------ # GET / # Serve the dashboard HTML # ------------------------------------------------------------------ @dashboard.route('/') def index(): return render_template('dashboard.html') # ------------------------------------------------------------------ # GET /dashboard/towns # Returns all known towns with their latest state snapshot. # ------------------------------------------------------------------ @dashboard.route('/dashboard/towns', methods=['GET']) def get_towns(): conn = get_db() rows = conn.execute(''' SELECT town_id, town_name, player, world_id, data, updated_at FROM town_state ORDER BY town_name ASC ''').fetchall() conn.close() towns = [] for row in rows: d = json.loads(row['data']) towns.append({ 'town_id': row['town_id'], 'town_name': row['town_name'], 'player': row['player'], 'world_id': row['world_id'], 'updated_at': row['updated_at'], 'resources': { 'wood': d.get('wood', 0), 'stone': d.get('stone', 0), 'iron': d.get('iron', 0), 'population': d.get('population', 0), }, 'buildings': d.get('buildings', {}), 'units': d.get('units', {}), 'points': d.get('points', 0), 'god': d.get('god', None), 'build_queue': d.get('buildingOrder', []), }) return jsonify(towns) # ------------------------------------------------------------------ # GET /dashboard/commands # Returns command history (last 50) for the log panel. # ------------------------------------------------------------------ @dashboard.route('/dashboard/commands', methods=['GET']) def get_commands(): conn = get_db() rows = conn.execute(''' SELECT id, town_id, town_name, type, payload, status, result_msg, created_at, updated_at FROM commands ORDER BY id DESC LIMIT 50 ''').fetchall() conn.close() return jsonify([dict(r) for r in rows]) # ------------------------------------------------------------------ # POST /dashboard/commands # Dashboard sends a new command. # Body: { town_id, town_name, type: 'build'|'recruit', payload: {...} } # ------------------------------------------------------------------ @dashboard.route('/dashboard/commands', methods=['POST']) def create_command(): data = request.get_json(silent=True) if not data: return jsonify({'error': 'no data'}), 400 required = ['town_id', 'type', 'payload'] for field in required: if field not in data: return jsonify({'error': f'missing field: {field}'}), 400 cmd_type = data['type'] if cmd_type not in ('build', 'recruit'): return jsonify({'error': 'type must be build or recruit'}), 400 conn = get_db() c = conn.cursor() c.execute(''' INSERT INTO commands (town_id, town_name, type, payload, status, created_at, updated_at) VALUES (?, ?, ?, ?, 'pending', ?, ?) ''', ( str(data['town_id']), data.get('town_name', ''), cmd_type, json.dumps(data['payload']), datetime.utcnow().isoformat(), datetime.utcnow().isoformat() )) cmd_id = c.lastrowid conn.commit() conn.close() return jsonify({'ok': True, 'id': cmd_id}) # ------------------------------------------------------------------ # DELETE /dashboard/commands/ # Cancel a pending command from the dashboard. # ------------------------------------------------------------------ @dashboard.route('/dashboard/commands/', methods=['DELETE']) def cancel_command(cmd_id): conn = get_db() conn.execute(''' UPDATE commands SET status = 'cancelled', updated_at = ? WHERE id = ? AND status = 'pending' ''', (datetime.utcnow().isoformat(), cmd_id)) conn.commit() conn.close() return jsonify({'ok': True})