#!/usr/bin/env python3 """ Qietuzai Plugin Setup Server 提供图形化界面配置 Figma API Key """ import http.server import socketserver import urllib.parse import json import os import sys from pathlib import Path PORT = 3456 # HTML 页面 HTML_FORM = """ 切图仔 Plugin - 配置向导
🎨

切图仔 Plugin

配置 Figma API Key

📝 第 1 步:获取 Figma API Key
访问 Figma 设置页面, 在 "Personal access tokens" 部分创建一个新的 token。
🔑 第 2 步:输入 API Key
将刚才复制的 token 粘贴到下方输入框中。
💡 您的 API Key 将被安全地存储在插件配置文件中

正在保存配置...

""" SUCCESS_HTML = """ 配置成功

配置成功!

您的 Figma API Key 已成功保存到系统环境变量中。

📋 配置详情

✅ API Key 已保存到插件配置文件 .mcp.json

✅ 备份已添加到: {shell_config}

export FIGMA_API_KEY="****"

🔄 下一步

重启 Claude Code 使配置生效,然后即可开始使用切图仔 Plugin!

⚠️ 注意:请勿将 .mcp.json 提交到 git,以保护您的 API Key 安全

""" class SetupHandler(http.server.SimpleHTTPRequestHandler): def do_GET(self): if self.path == '/' or self.path == '/index.html': self.send_response(200) self.send_header('Content-type', 'text/html; charset=utf-8') self.end_headers() self.wfile.write(HTML_FORM.encode('utf-8')) elif self.path.startswith('/success'): # 解析查询参数 query = urllib.parse.urlparse(self.path).query params = urllib.parse.parse_qs(query) shell = params.get('shell', ['bash'])[0] # 确定配置文件路径 shell_configs = { 'zsh': '~/.zshrc', 'bash': '~/.bashrc', 'fish': '~/.config/fish/config.fish' } shell_config = shell_configs.get(shell, '~/.bashrc') self.send_response(200) self.send_header('Content-type', 'text/html; charset=utf-8') self.end_headers() html = SUCCESS_HTML.replace('{shell_config}', shell_config) self.wfile.write(html.encode('utf-8')) else: self.send_error(404) def do_POST(self): if self.path == '/save': content_length = int(self.headers['Content-Length']) post_data = self.rfile.read(content_length) data = json.loads(post_data.decode('utf-8')) api_key = data.get('apiKey', '').strip() if not api_key: self.send_json_response({'success': False, 'error': 'API Key 不能为空'}) return # 检测 shell 类型 shell = os.environ.get('SHELL', '/bin/bash') if 'zsh' in shell: config_file = Path.home() / '.zshrc' shell_name = 'zsh' elif 'fish' in shell: config_file = Path.home() / '.config' / 'fish' / 'config.fish' shell_name = 'fish' else: config_file = Path.home() / '.bashrc' shell_name = 'bash' try: # 1. 更新 .mcp.json 文件(替换占位符) # 获取插件根目录 script_dir = Path(__file__).parent plugin_root = script_dir.parent mcp_json_path = plugin_root / '.mcp.json' if not mcp_json_path.exists(): raise FileNotFoundError(f'.mcp.json 文件不存在: {mcp_json_path}') # 读取并替换占位符 mcp_content = mcp_json_path.read_text() if '${FIGMA_API_KEY}' in mcp_content: mcp_content = mcp_content.replace('${FIGMA_API_KEY}', api_key) mcp_json_path.write_text(mcp_content) # 2. 同时也保存到 shell 配置文件(作为备份) # 读取现有配置 if config_file.exists(): content = config_file.read_text() else: content = '' # 检查是否已经存在 FIGMA_API_KEY if 'FIGMA_API_KEY' in content: # 更新现有的 import re pattern = r'export FIGMA_API_KEY=.*' if re.search(pattern, content): content = re.sub(pattern, f'export FIGMA_API_KEY="{api_key}"', content) else: content += f'\nexport FIGMA_API_KEY="{api_key}"\n' else: # 添加新的 content += f'\n# Qietuzai Plugin - Figma API Key\nexport FIGMA_API_KEY="{api_key}"\n' # 写入配置文件 config_file.parent.mkdir(parents=True, exist_ok=True) config_file.write_text(content) self.send_json_response({ 'success': True, 'shell': shell_name, 'config_file': str(config_file), 'mcp_json': str(mcp_json_path) }) # 配置成功后,延迟关闭服务器 import threading def shutdown_server(): import time time.sleep(2) print('\n✅ 配置已保存,服务器即将关闭...') os._exit(0) threading.Thread(target=shutdown_server, daemon=True).start() except Exception as e: self.send_json_response({ 'success': False, 'error': str(e) }) else: self.send_error(404) def send_json_response(self, data): self.send_response(200) self.send_header('Content-type', 'application/json') self.end_headers() self.wfile.write(json.dumps(data).encode('utf-8')) def log_message(self, format, *args): # 减少日志输出 pass def main(): try: with socketserver.TCPServer(("", PORT), SetupHandler) as httpd: print(f"✨ 配置服务器已启动: http://localhost:{PORT}") print(f"📝 请在浏览器中完成配置...") print(f"⏹ 完成后服务器会自动关闭\n") httpd.serve_forever() except KeyboardInterrupt: print("\n\n👋 服务器已关闭") sys.exit(0) except OSError as e: if e.errno == 48: # Address already in use print(f"❌ 端口 {PORT} 已被占用,请检查是否有其他配置向导正在运行") sys.exit(1) else: raise if __name__ == '__main__': main()