modified: app.py
new file: templates/itemeditor_command_storage.html modified: versions/version.json
This commit is contained in:
87
app.py
87
app.py
@@ -1,10 +1,26 @@
|
||||
import os
|
||||
import json
|
||||
import uuid
|
||||
from pathlib import Path
|
||||
from flask import Flask, render_template, jsonify, send_from_directory
|
||||
from datetime import datetime, timedelta
|
||||
from threading import Lock
|
||||
from flask import Flask, render_template, jsonify, send_from_directory, request
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
# In-memory storage for commands (thread-safe)
|
||||
command_storage = {}
|
||||
storage_lock = Lock()
|
||||
|
||||
def cleanup_expired_commands():
|
||||
"""Remove expired commands from storage"""
|
||||
with storage_lock:
|
||||
now = datetime.now()
|
||||
expired_keys = [key for key, value in command_storage.items()
|
||||
if datetime.fromisoformat(value['expires_at']) < now]
|
||||
for key in expired_keys:
|
||||
del command_storage[key]
|
||||
|
||||
# Load projects from version.json
|
||||
def load_projects():
|
||||
"""Load all projects from version.json"""
|
||||
@@ -228,6 +244,75 @@ def project_detail(project_id):
|
||||
|
||||
return render_template('project_detail.html', project=project)
|
||||
|
||||
# Item Editor Command Storage
|
||||
@app.route('/projects/itemeditor/storage')
|
||||
def itemeditor_command_storage():
|
||||
"""Item Editor Command Storage page"""
|
||||
return render_template('itemeditor_command_storage.html')
|
||||
|
||||
@app.route('/projects/itemeditor/storage', methods=['POST'])
|
||||
def store_command():
|
||||
"""Store a command and return UUID link"""
|
||||
cleanup_expired_commands()
|
||||
|
||||
try:
|
||||
data = request.get_json()
|
||||
command = data.get('command', '').strip()
|
||||
|
||||
if not command:
|
||||
return jsonify({'success': False, 'error': 'Command is required'}), 400
|
||||
|
||||
if len(command) > 10000:
|
||||
return jsonify({'success': False, 'error': 'Command exceeds maximum length of 10,000 characters'}), 400
|
||||
|
||||
# Generate UUID
|
||||
command_uuid = str(uuid.uuid4())
|
||||
|
||||
# Calculate expiry (30 minutes)
|
||||
created_at = datetime.now()
|
||||
expires_at = created_at + timedelta(minutes=30)
|
||||
|
||||
# Store command
|
||||
with storage_lock:
|
||||
command_storage[command_uuid] = {
|
||||
'command': command,
|
||||
'created_at': created_at.isoformat(),
|
||||
'expires_at': expires_at.isoformat()
|
||||
}
|
||||
|
||||
# Generate URL
|
||||
base_url = request.host_url.rstrip('/')
|
||||
retrieval_url = f"{base_url}/projects/itemeditor/storage/{command_uuid}"
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'uuid': command_uuid,
|
||||
'url': retrieval_url,
|
||||
'expires_at': expires_at.isoformat()
|
||||
}), 201
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({'success': False, 'error': str(e)}), 500
|
||||
|
||||
@app.route('/projects/itemeditor/storage/<command_uuid>')
|
||||
def retrieve_command(command_uuid):
|
||||
"""Retrieve stored command by UUID (JSON response for plugin)"""
|
||||
cleanup_expired_commands()
|
||||
|
||||
with storage_lock:
|
||||
command_data = command_storage.get(command_uuid)
|
||||
|
||||
if not command_data:
|
||||
return jsonify({'error': 'Command not found or expired'}), 404
|
||||
|
||||
# Check if expired
|
||||
if datetime.fromisoformat(command_data['expires_at']) < datetime.now():
|
||||
with storage_lock:
|
||||
del command_storage[command_uuid]
|
||||
return jsonify({'error': 'Command expired'}), 410
|
||||
|
||||
return jsonify(command_data), 200
|
||||
|
||||
# Serve /versions as JSON
|
||||
@app.route('/versions')
|
||||
def versions():
|
||||
|
||||
Reference in New Issue
Block a user