Files
grepo-remote/routes/api.py
2026-04-19 19:50:36 +00:00

105 lines
3.2 KiB
Python

from flask import Blueprint, request, jsonify
from db import get_db
import json
from datetime import datetime
api = Blueprint('api', __name__)
# ------------------------------------------------------------------
# POST /api/state
# Tampermonkey pushes a full town snapshot every poll cycle.
# ------------------------------------------------------------------
@api.route('/api/state', methods=['POST'])
def receive_state():
data = request.get_json(silent=True)
if not data:
return jsonify({'error': 'no data'}), 400
towns = data.get('towns', [])
player = data.get('player', '')
world_id = data.get('world_id', '')
conn = get_db()
c = conn.cursor()
for town in towns:
c.execute('''
INSERT INTO town_state (town_id, town_name, player, world_id, data, updated_at)
VALUES (?, ?, ?, ?, ?, ?)
ON CONFLICT(town_id) DO UPDATE SET
town_name = excluded.town_name,
player = excluded.player,
world_id = excluded.world_id,
data = excluded.data,
updated_at = excluded.updated_at
''', (
str(town['town_id']),
town.get('town_name', ''),
player,
world_id,
json.dumps(town),
datetime.utcnow().isoformat()
))
conn.commit()
conn.close()
return jsonify({'ok': True, 'towns_updated': len(towns)})
# ------------------------------------------------------------------
# GET /api/commands/pending
# Tampermonkey polls this to get the next command to execute.
# Returns ONE command at a time, marks it as 'executing'.
# ------------------------------------------------------------------
@api.route('/api/commands/pending', methods=['GET'])
def get_pending_command():
conn = get_db()
c = conn.cursor()
row = c.execute('''
SELECT * FROM commands
WHERE status = 'pending'
ORDER BY id ASC
LIMIT 1
''').fetchone()
if not row:
conn.close()
return jsonify({'command': None})
c.execute('''
UPDATE commands
SET status = 'executing', updated_at = ?
WHERE id = ?
''', (datetime.utcnow().isoformat(), row['id']))
conn.commit()
conn.close()
return jsonify({
'command': {
'id': row['id'],
'town_id': row['town_id'],
'type': row['type'],
'payload': json.loads(row['payload'])
}
})
# ------------------------------------------------------------------
# POST /api/commands/<id>/result
# Tampermonkey reports back whether the command succeeded or failed.
# ------------------------------------------------------------------
@api.route('/api/commands/<int:cmd_id>/result', methods=['POST'])
def command_result(cmd_id):
data = request.get_json(silent=True) or {}
status = data.get('status', 'done') # 'done' | 'failed'
msg = data.get('message', '')
conn = get_db()
conn.execute('''
UPDATE commands
SET status = ?, result_msg = ?, updated_at = ?
WHERE id = ?
''', (status, msg, datetime.utcnow().isoformat(), cmd_id))
conn.commit()
conn.close()
return jsonify({'ok': True})