diff --git a/app.py b/app.py
index d4833195..2e1dbeb0 100644
--- a/app.py
+++ b/app.py
@@ -14,7 +14,7 @@ async def main():
# 启动 HTTP 配置服务器
http_runner = None
- if config['server'].get('http', {}).get('enabled', False):
+ if config['manager'].get('enabled', False):
config_server = ConfigServer(config)
try:
http_runner = await config_server.start()
diff --git a/config.yaml b/config.yaml
index a4bd0e02..0ed2084d 100644
--- a/config.yaml
+++ b/config.yaml
@@ -17,11 +17,11 @@ server:
# 可选:设备白名单,如果设置了白名单,那么白名单的机器无论是什么token都可以连接。
#allowed_devices:
# - "24:0A:C4:1D:3B:F0" # MAC地址列表
- http:
- enabled: false
- ip: 0.0.0.0
- port: 8001
- token: password
+manager:
+ enabled: false
+ ip: 0.0.0.0
+ port: 8001
+ token: password
xiaozhi:
type: hello
diff --git a/core/http_server.py b/core/http_server.py
index 1cee536b..185de82e 100644
--- a/core/http_server.py
+++ b/core/http_server.py
@@ -1,135 +1,51 @@
import logging
-import yaml
+import os
from aiohttp import web
-from core.utils.util import get_project_dir
+from core.utils.util import get_local_ip, get_project_dir
+from manager.api.prompt import PromptHandler
logger = logging.getLogger(__name__)
+
+async def handle_options(request):
+ headers = {
+ 'Access-Control-Allow-Origin': '*',
+ 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
+ 'Access-Control-Allow-Headers': 'Content-Type, Authorization'
+ }
+ return web.Response(headers=headers)
+
+
class ConfigServer:
def __init__(self, config: dict):
self.config = config
self.app = web.Application()
+
+ # 初始化接口处理器
+ self.prompt_handler = PromptHandler(config)
self.setup_routes()
def setup_routes(self):
- self.app.router.add_get('/', self.index)
- self.app.router.add_get('/api/prompt', self.get_prompt)
- self.app.router.add_post('/api/prompt', self.update_prompt)
- self.app.router.add_options('/api/prompt', self.handle_options)
+ # 注册prompt接口
+ self.app.router.add_get('/api/prompt', self.prompt_handler.get_prompt)
+ self.app.router.add_post('/api/prompt', self.prompt_handler.update_prompt)
+ self.app.router.add_options('/api/prompt', handle_options)
- async def index(self, request):
- html = '''
-
-
-
- 小智提示词配置
-
-
-
-
- 小智提示词配置
-
-
-
-
-
-
-
-
- '''
- return web.Response(text=html, content_type='text/html')
-
- async def handle_options(self, request):
- headers = {
- 'Access-Control-Allow-Origin': '*',
- 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
- 'Access-Control-Allow-Headers': 'Content-Type, Authorization'
- }
- return web.Response(headers=headers)
-
- async def verify_token(self, request):
- if 'token' not in self.config['server']['http']:
- return True
-
- expected_token = self.config['server']['http']['token']
- token = request.headers.get('Authorization', '').replace('Bearer ', '')
-
- if not token or token != expected_token:
- return False
- return True
-
- async def get_prompt(self, request):
- if not await self.verify_token(request):
- return web.json_response({'error': 'Unauthorized'}, status=401)
-
- headers = {'Access-Control-Allow-Origin': '*'}
- return web.json_response({
- 'prompt': self.config['prompt']
- }, headers=headers)
-
- async def update_prompt(self, request):
- if not await self.verify_token(request):
- return web.json_response({'error': 'Unauthorized'}, status=401)
-
- try:
- data = await request.json()
- if 'prompt' not in data:
- return web.json_response({'error': 'Missing prompt field'}, status=400)
-
- # 更新内存中的配置
- self.config['prompt'] = data['prompt']
-
- # 更新配置文件
- config_path = get_project_dir() + 'config.yaml'
- with open(config_path, 'w', encoding='utf-8') as f:
- yaml.dump(self.config, f, allow_unicode=True)
-
- headers = {'Access-Control-Allow-Origin': '*'}
- return web.json_response({'success': True}, headers=headers)
-
- except Exception as e:
- logger.error(f"Failed to update prompt: {e}")
- return web.json_response({'error': str(e)}, status=500)
+ async def redirect_to_index(self, _):
+ raise web.HTTPFound('/manager/')
async def start(self):
try:
- http_config = self.config['server']['http']
+ http_config = self.config['manager']
if not http_config.get('enabled', False):
logger.info("HTTP server is disabled")
return
@@ -138,7 +54,8 @@ class ConfigServer:
await runner.setup()
site = web.TCPSite(runner, http_config['ip'], http_config['port'])
await site.start()
- logger.info(f"Config HTTP server is running at http://{http_config['ip']}:{http_config['port']}")
+ logger.info(
+ f"Config HTTP server is running at http://{get_local_ip()}:{http_config['port']}/manager/index.html")
return runner # 返回runner以便后续清理
except Exception as e:
logger.error(f"Failed to start HTTP server: {e}")
diff --git a/manager/api/auth.py b/manager/api/auth.py
new file mode 100644
index 00000000..96f303b2
--- /dev/null
+++ b/manager/api/auth.py
@@ -0,0 +1,10 @@
+async def verify_token(config, request):
+ if 'token' not in config['manager']:
+ return True
+
+ expected_token = config['manager']['token']
+ token = request.headers.get('Authorization', '').replace('Bearer ', '')
+
+ if not token or token != expected_token:
+ return False
+ return True
diff --git a/manager/api/prompt.py b/manager/api/prompt.py
new file mode 100644
index 00000000..25b28c35
--- /dev/null
+++ b/manager/api/prompt.py
@@ -0,0 +1,36 @@
+import logging
+from aiohttp import web
+from manager.api.auth import verify_token
+
+logger = logging.getLogger(__name__)
+
+
+class PromptHandler:
+ def __init__(self, config):
+ self.config = config
+
+ async def get_prompt(self, request):
+ if not await verify_token(self.config, request):
+ return web.json_response({'error': 'Unauthorized'}, status=401)
+
+ return web.json_response({
+ 'prompt': self.config['prompt'],
+ 'Access-Control-Allow-Origin': '*'
+ })
+
+ async def update_prompt(self, request):
+ if not await verify_token(self.config, request):
+ return web.json_response({'error': 'Unauthorized'}, status=401)
+
+ try:
+ data = await request.json()
+ if 'prompt' not in data:
+ return web.json_response({'error': 'Missing prompt field'}, status=400)
+
+ # 通过config参数回传修改能力
+ self.config['prompt'] = data['prompt']
+ return web.json_response({'success': True}, headers={'Access-Control-Allow-Origin': '*'})
+
+ except Exception as e:
+ logger.error(f"Failed to update prompt: {e}")
+ return web.json_response({'error': str(e)}, status=500)
diff --git a/manager/static/index.html b/manager/static/index.html
new file mode 100644
index 00000000..8c32c57c
--- /dev/null
+++ b/manager/static/index.html
@@ -0,0 +1,53 @@
+
+
+
+ 小智提示词配置
+
+
+
+
+ 小智提示词配置
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/manager/static/login.html b/manager/static/login.html
new file mode 100644
index 00000000..9f6d80d9
--- /dev/null
+++ b/manager/static/login.html
@@ -0,0 +1,13 @@
+
+
+
+ login
+
+
+
+
+login
+
+
\ No newline at end of file
diff --git a/static/index.html b/static/index.html
new file mode 100644
index 00000000..8c32c57c
--- /dev/null
+++ b/static/index.html
@@ -0,0 +1,53 @@
+
+
+
+ 小智提示词配置
+
+
+
+
+ 小智提示词配置
+
+
+
+
+
+
+
+
\ No newline at end of file