web_ui_fix.pyā¢8.64 kB
#!/usr/bin/env python
"""
Web UI to After Effects Connection Fix
This script patches the server to ensure commands from the web UI actually reach After Effects.
"""
import os
import sys
import json
import time
import logging
import shutil
import socket
import asyncio
from pathlib import Path
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.StreamHandler(sys.stdout),
logging.FileHandler("web_ui_fix.log")
]
)
logger = logging.getLogger(__name__)
# Configuration
TEMP_DIR = "C:/ae_temp"
COMMAND_FILE = os.path.join(TEMP_DIR, "command.json")
RESULT_FILE = os.path.join(TEMP_DIR, "result.json")
VERIFICATION_FILE = os.path.join(TEMP_DIR, "verification.json")
def ensure_temp_dir():
"""Ensure the temporary directory exists"""
try:
Path(TEMP_DIR).mkdir(parents=True, exist_ok=True)
logger.info(f"Temp directory ready: {TEMP_DIR}")
# Test write access
test_file = os.path.join(TEMP_DIR, "test_write.txt")
with open(test_file, 'w') as f:
f.write("Testing write access")
os.remove(test_file)
logger.info("Temp directory is writable")
return True
except Exception as e:
logger.error(f"Failed to create or access temp directory: {e}")
return False
def clean_temp_files():
"""Clean up any existing command or result files"""
try:
if os.path.exists(COMMAND_FILE):
os.remove(COMMAND_FILE)
logger.info(f"Removed existing command file")
if os.path.exists(RESULT_FILE):
os.remove(RESULT_FILE)
logger.info(f"Removed existing result file")
return True
except Exception as e:
logger.error(f"Error cleaning temp files: {e}")
return False
def create_verification_file():
"""Create a verification file to confirm commands are being sent"""
try:
verification_data = {
"timestamp": time.time(),
"message": "This file confirms that commands are being sent to After Effects",
"server_info": {
"python_version": sys.version,
"platform": sys.platform,
"temp_dir": TEMP_DIR,
"command_file": COMMAND_FILE,
"result_file": RESULT_FILE
}
}
with open(VERIFICATION_FILE, 'w') as f:
json.dump(verification_data, f, indent=2)
logger.info(f"Verification file created at: {VERIFICATION_FILE}")
return True
except Exception as e:
logger.error(f"Error creating verification file: {e}")
return False
def create_direct_command():
"""Create a direct command file for After Effects"""
try:
# Ensure directory exists
ensure_temp_dir()
# Clean up any existing files
clean_temp_files()
# Create a command object
command = {
"action": "create_text_layer",
"params": {
"text": "Web UI Fix Test",
"fontSize": 72,
"color": "#00AAFF"
}
}
# Create a temporary file first
temp_file = f"{COMMAND_FILE}.tmp"
with open(temp_file, 'w') as f:
json.dump(command, f, indent=2)
# Move to final location (atomic operation)
shutil.move(temp_file, COMMAND_FILE)
logger.info(f"Command file created at: {COMMAND_FILE}")
logger.info(f"Command data: {json.dumps(command)}")
# Create verification file
create_verification_file()
return True
except Exception as e:
logger.error(f"Error creating command file: {e}")
return False
def patch_server_code():
"""Patch the server code to fix the issue"""
try:
# Find the main server file
server_files = [
"server/main.py",
"server/server.py",
"server/app.py"
]
server_file = None
for file in server_files:
if os.path.exists(file):
server_file = file
break
if not server_file:
logger.error("Could not find server file to patch")
return False
logger.info(f"Found server file: {server_file}")
# Create backup of the server file
backup_file = f"{server_file}.bak"
shutil.copy2(server_file, backup_file)
logger.info(f"Created backup of server file: {backup_file}")
# Read the server file
with open(server_file, 'r') as f:
server_code = f.read()
# Check if the file already includes our fix
if "# MCP Web UI Fix" in server_code:
logger.info("Server file already patched")
return True
# Add our fix to the server code
patch_code = """
# MCP Web UI Fix
# This patch ensures commands from the web UI actually reach After Effects
def ensure_command_reaches_ae(command_data):
'''Ensure command reaches After Effects'''
import os
import json
import shutil
import logging
from pathlib import Path
# Configuration
TEMP_DIR = "C:/ae_temp"
COMMAND_FILE = os.path.join(TEMP_DIR, "command.json")
try:
# Ensure directory exists
Path(TEMP_DIR).mkdir(parents=True, exist_ok=True)
# Create a temporary file first
temp_file = f"{COMMAND_FILE}.tmp"
with open(temp_file, 'w') as f:
json.dump(command_data, f, indent=2)
# Move to final location (atomic operation)
shutil.move(temp_file, COMMAND_FILE)
logging.info(f"Command file created at: {COMMAND_FILE}")
return True
except Exception as e:
logging.error(f"Error ensuring command reaches AE: {e}")
return False
"""
# Find the right place to insert the patch
if "import os" in server_code:
server_code = server_code.replace("import os", "import os\nimport shutil")
else:
server_code = "import os\nimport shutil\n" + server_code
# Add the patch function
server_code += "\n" + patch_code
# Find send_command_to_ae function and patch it
if "async def send_command_to_ae" in server_code:
# Find the function and add our fix
lines = server_code.split("\n")
in_function = False
for i, line in enumerate(lines):
if "async def send_command_to_ae" in line:
in_function = True
if in_function and "return response_json" in line:
# Add our fix before returning
lines[i] = " # Ensure command reaches AE\n ensure_command_reaches_ae(command_data)\n" + line
break
server_code = "\n".join(lines)
else:
logger.warning("Could not find send_command_to_ae function to patch")
# Write the patched server file
with open(server_file, 'w') as f:
f.write(server_code)
logger.info(f"Server file patched: {server_file}")
return True
except Exception as e:
logger.error(f"Error patching server code: {e}")
return False
def main():
"""Main function"""
logger.info("=" * 60)
logger.info("Web UI to After Effects Connection Fix")
logger.info("=" * 60)
# Ensure temp directory exists
if not ensure_temp_dir():
logger.error("Failed to create or access temp directory")
return False
# Create a direct command file
if create_direct_command():
logger.info("Command file created successfully")
else:
logger.error("Failed to create command file")
# Patch the server code
if patch_server_code():
logger.info("Server code patched successfully")
logger.info("Please restart the server for the changes to take effect")
else:
logger.error("Failed to patch server code")
logger.info("=" * 60)
logger.info("Fix complete. Please:")
logger.info("1. Click 'Check for Command' in After Effects to process the test command")
logger.info("2. Restart the server to apply the patch")
logger.info("=" * 60)
return True
if __name__ == "__main__":
main()